From 395a6c1f12514a3ef115ebf811dcbc2425e87bd4 Mon Sep 17 00:00:00 2001
From: cvs2svn <cvs2svn@cern.ch>
Date: Mon, 9 Feb 2009 18:56:17 +0000
Subject: [PATCH] This commit was manufactured by cvs2svn to create tag
 'COOL_2_7_0'.

git-svn-id: file:///git/lcgcool.svndb/cool/tags/COOL_2_7_0@15592 4525493e-7705-40b1-a816-d608a930855b
---
 RelationalCool/cmt/requirements               |  144 +
 RelationalCool/cmt/version.cmt                |    1 +
 RelationalCool/doc/BugReports.txt             |    8 +
 RelationalCool/doc/CLEANUP_PLAN.txt           |  130 +
 RelationalCool/doc/RAL_feedback.txt           |  332 +
 RelationalCool/doc/README.CLOB                |  215 +
 RelationalCool/doc/README.gmt                 |   44 +
 RelationalCool/doc/README.standalone          |  221 +
 RelationalCool/doc/TODO.txt                   |  182 +
 RelationalCool/doc/hvsTagsSpec.txt            |   15 +
 RelationalCool/doc/release.notes              | 3019 +++++++++
 RelationalCool/doc/unit_test_log.txt          |   68 +
 RelationalCool/doc/userTagsImpl.txt           |  451 ++
 RelationalCool/doc/userTagsImpl2.txt          |  467 ++
 RelationalCool/doc/userTagsImpl3.txt          |   70 +
 RelationalCool/doc/userTagsSpec.txt           |  158 +
 RelationalCool/doc/userTagsSpec2.txt          |  196 +
 RelationalCool/doc/userTagsSpec3.txt          |  335 +
 .../python/CoolAuthentication/__init__.py     |   87 +
 .../python/CoolDescribeTable/__init__.py      |  218 +
 .../sql/oracleShowCreateTable.sql             |   26 +
 .../python/CoolGatherSchemaStats/__init__.py  |   36 +
 .../sql/oracleGatherSchemaStats.sql           |    2 +
 .../python/CoolGatherTableStats/__init__.py   |   55 +
 .../sql/oracleGatherTableStats.sql            |    2 +
 .../python/CoolQueryManager/__init__.py       |  192 +
 .../python/CoolShowTables/__init__.py         |  128 +
 .../CoolShowTables/sql/oracleShowTables.sql   |   14 +
 RelationalCool/scripts/coolAuthentication.py  |   31 +
 RelationalCool/scripts/coolDescribeTable.py   |   53 +
 RelationalCool/scripts/coolExecuteSql.csh     |  189 +
 .../scripts/coolGatherSchemaStats.py          |   24 +
 .../scripts/coolGatherTableStats.py           |   31 +
 RelationalCool/scripts/coolQueryManager.py    |   33 +
 RelationalCool/scripts/coolShowTables.py      |   22 +
 RelationalCool/scripts/coolSqlplus.sh         |   19 +
 RelationalCool/scripts/scramShowUses          |    2 +
 RelationalCool/scripts/scramShowUses.awk      |  450 ++
 .../scripts/sql/oraclePurgeRecycleBin.sql     |    2 +
 .../scripts/sql/oracleShowTables.sql          |    3 +
 RelationalCool/scripts/wineWrap.sh            |  123 +
 RelationalCool/src/AttributeTable.h           |   94 +
 .../src/ConstRelationalObjectAdapter.cpp      |  223 +
 .../src/ConstRelationalObjectAdapter.h        |  142 +
 RelationalCool/src/ConstTimeAdapter.cpp       |   94 +
 RelationalCool/src/ConstTimeAdapter.h         |   82 +
 RelationalCool/src/CoolChrono.cpp             |   64 +
 RelationalCool/src/CoolChrono.h               |   57 +
 RelationalCool/src/CoralApplication.cpp       |  401 ++
 RelationalCool/src/CoralApplication.h         |   84 +
 .../src/CoralConnectionServiceProxy.cpp       |   48 +
 .../src/CoralConnectionServiceProxy.h         |  122 +
 RelationalCool/src/DummyTransactionMgr.cpp    |   22 +
 RelationalCool/src/DummyTransactionMgr.h      |   74 +
 RelationalCool/src/HvsPathHandler.cpp         |  160 +
 RelationalCool/src/HvsPathHandler.h           |  102 +
 RelationalCool/src/HvsPathHandlerException.h  |   33 +
 RelationalCool/src/HvsTagRecord.h             |  131 +
 RelationalCool/src/IHvsTagMgr.h               |  207 +
 RelationalCool/src/IHvsTagRecord.h            |   70 +
 RelationalCool/src/IRelationalBulkOperation.h |   28 +
 RelationalCool/src/IRelationalCursor.h        |   37 +
 .../src/IRelationalQueryDefinition.h          |  135 +
 .../src/IRelationalTransactionMgr.h           |   46 +
 RelationalCool/src/IteratorException.h        |  150 +
 RelationalCool/src/ManualTransaction.cpp      |   61 +
 RelationalCool/src/ManualTransaction.h        |   58 +
 RelationalCool/src/ObjectId.cpp               |   94 +
 RelationalCool/src/ObjectId.h                 |   95 +
 RelationalCool/src/ObjectIteratorCounter.cpp  |  150 +
 RelationalCool/src/ObjectIteratorCounter.h    |   58 +
 RelationalCool/src/ObjectVectorIterator.cpp   |   92 +
 RelationalCool/src/ObjectVectorIterator.h     |   85 +
 RelationalCool/src/ProcMemory.h               |  197 +
 RelationalCool/src/RalBulkOperation.h         |   56 +
 RelationalCool/src/RalCursor.h                |   71 +
 RelationalCool/src/RalDatabase.cpp            | 1479 +++++
 RelationalCool/src/RalDatabase.h              |  285 +
 RelationalCool/src/RalDatabaseSvc.cpp         |  169 +
 RelationalCool/src/RalDatabaseSvc.h           |   96 +
 RelationalCool/src/RalQueryMgr.cpp            |  804 +++
 RelationalCool/src/RalQueryMgr.h              |  210 +
 RelationalCool/src/RalSchemaMgr.cpp           | 1033 +++
 RelationalCool/src/RalSchemaMgr.h             |  184 +
 RelationalCool/src/RalSequenceMgr.cpp         |  142 +
 RelationalCool/src/RalSequenceMgr.h           |   81 +
 RelationalCool/src/RalSessionMgr.cpp          |  349 +
 RelationalCool/src/RalSessionMgr.h            |  135 +
 RelationalCool/src/RalTransactionMgr.cpp      |  114 +
 RelationalCool/src/RalTransactionMgr.h        |   78 +
 RelationalCool/src/RelationalChannelTable.cpp |  188 +
 RelationalCool/src/RelationalChannelTable.h   |  114 +
 .../src/RelationalChannelTablesTable.cpp      |   41 +
 .../src/RelationalChannelTablesTable.h        |   82 +
 RelationalCool/src/RelationalDatabase.cpp     | 1300 ++++
 RelationalCool/src/RelationalDatabase.h       |  512 ++
 RelationalCool/src/RelationalDatabaseId.cpp   |  334 +
 RelationalCool/src/RelationalDatabaseId.h     |  175 +
 RelationalCool/src/RelationalDatabasePtr.h    |   19 +
 .../src/RelationalDatabaseTable.cpp           |   26 +
 RelationalCool/src/RelationalDatabaseTable.h  |  110 +
 RelationalCool/src/RelationalException.cpp    |   38 +
 RelationalCool/src/RelationalException.h      |  446 ++
 RelationalCool/src/RelationalFolder.cpp       | 1731 +++++
 RelationalCool/src/RelationalFolder.h         |  539 ++
 RelationalCool/src/RelationalFolderSet.cpp    |   91 +
 RelationalCool/src/RelationalFolderSet.h      |  111 +
 .../src/RelationalFolderSetUnsupported.cpp    |   62 +
 .../src/RelationalFolderSetUnsupported.h      |  124 +
 .../src/RelationalFolderUnsupported.cpp       |   59 +
 .../src/RelationalFolderUnsupported.h         |  388 ++
 .../src/RelationalGlobalHeadTagTable.cpp      |   29 +
 .../src/RelationalGlobalHeadTagTable.h        |   61 +
 .../src/RelationalGlobalTagTable.cpp          |   40 +
 RelationalCool/src/RelationalGlobalTagTable.h |   78 +
 .../src/RelationalGlobalUserTagTable.cpp      |   29 +
 .../src/RelationalGlobalUserTagTable.h        |   61 +
 RelationalCool/src/RelationalHvsNode.cpp      |  170 +
 RelationalCool/src/RelationalHvsNode.h        |  156 +
 .../src/RelationalHvsNodeRecord.cpp           |  116 +
 RelationalCool/src/RelationalHvsNodeRecord.h  |  115 +
 RelationalCool/src/RelationalHvsTagRecord.cpp |   93 +
 RelationalCool/src/RelationalHvsTagRecord.h   |   79 +
 .../src/RelationalIovSharedSequenceTable.h    |   30 +
 .../src/RelationalIovTablesTable.cpp          |   44 +
 RelationalCool/src/RelationalIovTablesTable.h |   87 +
 RelationalCool/src/RelationalNodeMgr.cpp      |  324 +
 RelationalCool/src/RelationalNodeMgr.h        |  114 +
 RelationalCool/src/RelationalNodeTable.cpp    |  114 +
 RelationalCool/src/RelationalNodeTable.h      |  172 +
 RelationalCool/src/RelationalObject.cpp       |  284 +
 RelationalCool/src/RelationalObject.h         |  155 +
 .../src/RelationalObject2TagTable.cpp         |   35 +
 .../src/RelationalObject2TagTable.h           |   71 +
 .../src/RelationalObjectIterator.cpp          |  457 ++
 RelationalCool/src/RelationalObjectIterator.h |  198 +
 RelationalCool/src/RelationalObjectMgr.cpp    | 1895 ++++++
 RelationalCool/src/RelationalObjectMgr.h      |  288 +
 RelationalCool/src/RelationalObjectPtr.h      |   19 +
 RelationalCool/src/RelationalObjectTable.cpp  | 1509 +++++
 RelationalCool/src/RelationalObjectTable.h    |  327 +
 .../src/RelationalObjectTableRow.cpp          |  237 +
 RelationalCool/src/RelationalObjectTableRow.h |  177 +
 RelationalCool/src/RelationalPayloadQuery.cpp |  315 +
 RelationalCool/src/RelationalPayloadQuery.h   |  129 +
 .../src/RelationalQueryDefinition.cpp         |  445 ++
 .../src/RelationalQueryDefinition.h           |  226 +
 RelationalCool/src/RelationalQueryMgr.cpp     |  106 +
 RelationalCool/src/RelationalQueryMgr.h       |  314 +
 RelationalCool/src/RelationalSchemaMgr.cpp    |   63 +
 RelationalCool/src/RelationalSchemaMgr.h      |  208 +
 RelationalCool/src/RelationalSequence.cpp     |  128 +
 RelationalCool/src/RelationalSequence.h       |  112 +
 RelationalCool/src/RelationalSequenceMgr.cpp  |   40 +
 RelationalCool/src/RelationalSequenceMgr.h    |   92 +
 .../src/RelationalSequenceTable.cpp           |   36 +
 RelationalCool/src/RelationalSequenceTable.h  |   49 +
 .../src/RelationalSharedSequenceTable.cpp     |   43 +
 .../src/RelationalSharedSequenceTable.h       |   60 +
 RelationalCool/src/RelationalTableRow.cpp     |   46 +
 RelationalCool/src/RelationalTableRow.h       |   53 +
 RelationalCool/src/RelationalTableRowBase.cpp |   46 +
 RelationalCool/src/RelationalTableRowBase.h   |   97 +
 RelationalCool/src/RelationalTag2TagTable.cpp |   30 +
 RelationalCool/src/RelationalTag2TagTable.h   |   69 +
 RelationalCool/src/RelationalTagMgr.cpp       | 1440 +++++
 RelationalCool/src/RelationalTagMgr.h         |  318 +
 RelationalCool/src/RelationalTagSequence.h    |   30 +
 .../src/RelationalTagSharedSequenceTable.h    |   30 +
 RelationalCool/src/RelationalTagTable.cpp     |   32 +
 RelationalCool/src/RelationalTagTable.h       |   64 +
 RelationalCool/src/RelationalTransaction.cpp  |   56 +
 RelationalCool/src/RelationalTransaction.h    |   66 +
 RelationalCool/src/SealBase_TimeInfo.cpp      |  413 ++
 RelationalCool/src/SealBase_TimeInfo.h        |  135 +
 RelationalCool/src/SealBase_sysapi_TimeInfo.h |   97 +
 RelationalCool/src/SealBase_sysapi_Windows.h  |   92 +
 RelationalCool/src/SealUtil_BaseSealChrono.h  |   46 +
 RelationalCool/src/SealUtil_SealTimer.cpp     |  101 +
 RelationalCool/src/SealUtil_SealTimer.h       |   99 +
 RelationalCool/src/SealUtil_TimingItem.cpp    |  101 +
 RelationalCool/src/SealUtil_TimingItem.h      |   92 +
 RelationalCool/src/SimpleObject.h             |  128 +
 RelationalCool/src/TimingReport.cpp           |  126 +
 RelationalCool/src/TimingReport.h             |  110 +
 RelationalCool/src/TimingReportMgr.cpp        |  118 +
 RelationalCool/src/TimingReportMgr.h          |   48 +
 RelationalCool/src/VersionInfo.h              |   28 +
 RelationalCool/src/VersionNumber.h            |  116 +
 RelationalCool/src/attributeListToString.h    |   23 +
 RelationalCool/src/new/IHvsNodeMgr.h          |   69 +
 RelationalCool/src/new/IHvsNodeRecordMgr.h    |   61 +
 RelationalCool/src/new/IHvsTag.h              |   43 +
 .../src/new/RelationalHvsTagMgr.cpp           |   84 +
 RelationalCool/src/new/RelationalHvsTagMgr.h  |  107 +
 RelationalCool/src/sigsegv.cpp                |  296 +
 RelationalCool/src/sigsegv.h                  |   12 +
 RelationalCool/src/sleep.h                    |   19 +
 RelationalCool/src/timeToString.h             |   92 +
 RelationalCool/src/uppercaseString.h          |   21 +
 .../AttributeList/test_AttributeList.cpp      |  124 +
 .../test_AttributeListDump.cpp                |   22 +
 .../tests/BoolIO/authentication.xml           |   14 +
 RelationalCool/tests/BoolIO/boolIO.cpp        |  225 +
 RelationalCool/tests/BoolIO/boolIO.txt.MySQL  |   25 +
 RelationalCool/tests/BoolIO/boolIO.txt.Oracle |   25 +
 RelationalCool/tests/BuildFile                |   31 +
 RelationalCool/tests/CMS_ECAL/README.CMS_ECAL |    3 +
 RelationalCool/tests/CMS_ECAL/testCmsEcal.cpp |  254 +
 RelationalCool/tests/CMS_extRef/extraSQL.sql  |   41 +
 .../tests/CMS_extRef/testCmsExtRef.cpp        |  267 +
 .../test_ChannelSelection.cpp                 |  356 ++
 .../tests/Channels/test_Channels.cpp          |  685 ++
 .../tests/ClobIO/authentication.xml           |   14 +
 .../tests/ClobIO/clobInputOutput.cpp          |  211 +
 RelationalCool/tests/Common/CoolDBUnitTest.h  |  157 +
 RelationalCool/tests/Common/CoolUnitTest.h    |  367 ++
 RelationalCool/tests/Common/CppUnit_headers.h |   45 +
 .../tests/Common/CppUnit_testdriver.icpp      |    4 +
 .../tests/Common/cppunit/TestListener.h       |   23 +
 RelationalCool/tests/Common/releaser.h        |   18 +
 .../tests/CoolCppUnitTestDriver.cpp           |   72 +
 .../tests/CreateDatabase/createDatabase.cpp   |  446 ++
 .../HvsPathHandler/test_HvsPathHandler.cpp    |  230 +
 RelationalCool/tests/HvsTags/test_HvsTags.cpp | 2738 ++++++++
 .../tests/Int64IO/Int64InputOutput.cpp        |  275 +
 .../tests/Int64IO/Int64InputOutput.txt        |   43 +
 .../tests/MemoryConsumption/execTest.sh       |   25 +
 .../test_MemoryConsumption.cpp                |  729 +++
 ...nalCool_MemoryConsumption.out.osx103_gcc33 |  127 +
 ...ool_MemoryConsumption.out.slc3_ia32_gcc323 |  151 +
 RelationalCool/tests/MyODBCBulkTest/README    |  128 +
 .../MyODBCBulkTest/test_MyODBCBulkOp.cpp      |  213 +
 RelationalCool/tests/MyTest/DO_NOT_DELETE_ME  |    0
 .../tests/ObjectId/test_ObjectId.cpp          |  306 +
 .../test_PayloadSpecification.cpp             |  474 ++
 RelationalCool/tests/Performance/Benchmark.h  |   52 +
 .../tests/Performance/performance_test.txt    |   67 +
 .../tests/Performance/test_Performance.cpp    |  998 +++
 .../tests/PerformanceAV/README.Performance    |  242 +
 .../tests/PerformanceAV/README.sqlTrace       |    5 +
 .../ServerCache/100k-my-cool-first.out        |   91 +
 .../ServerCache/100k-my-cool-next.out         |   91 +
 .../ServerCache/100k-ora-benthic-first.prf    |  680 ++
 .../ServerCache/100k-ora-benthic-next.prf     |  164 +
 .../ServerCache/100k-ora-cool-first.out       |   82 +
 .../ServerCache/100k-ora-cool-first.prf       |  898 +++
 .../ServerCache/100k-ora-cool-next.out        |   82 +
 .../ServerCache/100k-ora-cool-next.prf        |  246 +
 .../tests/PerformanceAV/TODO.Performance      |   38 +
 ...ssor-memory.rh73.501MB.oracle.out.ANALYZED |  109 +
 ...cessor-time.rh73.501MB.oracle.out.ANALYZED |   87 +
 ...lueAccessor.rh73.501MB.oracle.out.ANALYZED |    4 +
 ...ssor-memory.rh73.501MB.oracle.out.ANALYZED |  109 +
 ...cessor-time.rh73.501MB.oracle.out.ANALYZED |   87 +
 .../execTestNewCopy.rh73.1006MB.out           |    5 +
 .../execTestNewCopy.rh73.501MB.out            |    5 +
 .../execTestNewCopy.slc3.2006MB.out           |    5 +
 .../newCopy-memory.rh73.1006MB.out            |  102 +
 .../TestNewCopy/newCopy-memory.rh73.501MB.out |  102 +
 .../newCopy-memory.slc3.2006MB.out            |  102 +
 .../TestNewCopy/newCopy-time.rh73.1006MB.out  |   82 +
 .../TestNewCopy/newCopy-time.rh73.501MB.out   |   82 +
 .../TestNewCopy/newCopy-time.slc3.2006MB.out  |   82 +
 .../oldCopy-memory.rh73.1006MB.out            |  102 +
 .../TestNewCopy/oldCopy-memory.rh73.501MB.out |  102 +
 .../oldCopy-memory.slc3.2006MB.out            |  102 +
 .../TestNewCopy/oldCopy-time.rh73.1006MB.out  |   82 +
 .../TestNewCopy/oldCopy-time.rh73.501MB.out   |   82 +
 .../TestNewCopy/oldCopy-time.slc3.2006MB.out  |   82 +
 .../execTestRalOnly.rh73.501MB.oracle.out     |    4 +
 ...TestRalOnly.rh73.501MB.oracle.out.ANALYZED |    3 +
 .../ralOnly-memory.rh73.501MB.oracle.out      |  103 +
 .../ralOnly-time.rh73.501MB.oracle.out        |   83 +
 ...alOnly-time.rh73.501MB.oracle.out.ANALYZED |   83 +
 .../ralOnly-time.rh73.501MB.oracle.prf        |  239 +
 ...alOnly-time.rh73.501MB.oracle.prf.ANALYZED |  239 +
 .../withCool-memory.rh73.501MB.oracle.out     |  103 +
 .../withCool-time.rh73.501MB.oracle.out       |   83 +
 ...thCool-time.rh73.501MB.oracle.out.ANALYZED |   83 +
 .../withCool-time.rh73.501MB.oracle.prf       |  241 +
 ...thCool-time.rh73.501MB.oracle.prf.ANALYZED |  239 +
 ...ableCursor.rh73.1006MB.oracle.out.ANALYZED |    5 +
 ...ble-memory.rh73.1006MB.oracle.out.ANALYZED |  110 +
 ...lable-time.rh73.1006MB.oracle.out.ANALYZED |   88 +
 ...lable-time.rh73.1006MB.oracle.prf.ANALYZED |  239 +
 ...ble-memory.rh73.1006MB.oracle.out.ANALYZED |  110 +
 ...lable-time.rh73.1006MB.oracle.out.ANALYZED |   88 +
 ...lable-time.rh73.1006MB.oracle.prf.ANALYZED |  239 +
 ...Data-memory.rh73.501MB.oracle.out.ANALYZED |  112 +
 ...reData-time.rh73.501MB.oracle.out.ANALYZED |   90 +
 ...reData-time.rh73.501MB.oracle.prf.ANALYZED |  239 +
 ...areData.out.rh73.501MB.oracle.out.ANALYZED |    5 +
 ...Data-memory.rh73.501MB.oracle.out.ANALYZED |  112 +
 ...reData-time.rh73.501MB.oracle.out.ANALYZED |   90 +
 ...reData-time.rh73.501MB.oracle.prf.ANALYZED |  239 +
 .../execTestAttributeValueAccessor.csh        |   53 +
 .../tests/PerformanceAV/execTestNewCopy.csh   |   38 +
 .../tests/PerformanceAV/execTestRalOnly.csh   |   46 +
 .../execTestScrollableCursor.csh              |   59 +
 .../tests/PerformanceAV/execTestShareData.csh |   55 +
 .../tests/PerformanceAV/mySetupMySQL.csh      |    2 +
 .../tests/PerformanceAV/mySetupOracle.csh     |    2 +
 .../tests/PerformanceAV/scaling_mixed.txt     |   82 +
 .../tests/PerformanceAV/scaling_mixed_2.txt   |   98 +
 .../PerformanceAV/test_PerformanceAV.cpp      |  477 ++
 .../Privileges/out.oracle.slc3_ia32_gcc323    |  186 +
 .../tests/Privileges/test_Privileges.cpp      |  954 +++
 .../tests/ProcMemory/test_ProcMemory.cpp      |   51 +
 .../tests/RalDatabase/README.threads          |   51 +
 .../dropDatabaseTest.out.OCI_DEFAULT          |  229 +
 .../dropDatabaseTest.out.OCI_THREADED         |  306 +
 .../tests/RalDatabase/test_RalDatabase.cpp    | 3496 ++++++++++
 .../RalDatabaseSvc/test_RalDatabaseSvc.cpp    |  137 +
 .../test_RalDatabase_extendedSpec.cpp         | 1181 ++++
 .../README.segmentationFault                  |  653 ++
 .../tests/RalSequence/test_RalSequence.cpp    |  136 +
 .../test_RelationalDatabaseId.cpp             |  195 +
 .../tests/RelationalFolder/README.tests       |   40 +
 .../out.Windows.doNotAdjustTimeZone           |  183 +
 .../out.Windows.m1.adjustTimeZone             |   74 +
 .../out.Windows.noTest.adjustTimeZone         |  183 +
 .../out.Windows.p1.adjustTimeZone             |   29 +
 .../test_RelationalFolder.cpp                 | 5604 +++++++++++++++++
 .../test_RelationalFolder.cpp.gmtime          | 1738 +++++
 .../test_RelationalFolderSet.cpp              |  332 +
 .../test_RelationalObjectIterator.cpp         |  585 ++
 .../test_RelationalObjectMgr.cpp              | 4938 +++++++++++++++
 .../test_RelationalObjectSet.cpp              |  244 +
 .../test_RelationalObjectTable.cpp            | 3002 +++++++++
 .../tests/SchemaDump/coolSchemaDump.csh       |  150 +
 .../tests/SchemaDump/oracleRefSchema.html     | 2377 +++++++
 .../tests/SchemaDump/schemaDump.cpp           |  169 +
 .../tests/SchemaDump/sql/oracleDescTable.sql  |    7 +
 .../SchemaDump/sql/oracleDumpConstraints.sql  |   15 +
 .../SchemaDump/sql/oracleDumpFKColumns.sql    |   29 +
 .../SchemaDump/sql/oracleDumpIndColumns.sql   |   20 +
 .../SchemaDump/sql/oracleDumpIndexes.sql      |   18 +
 .../tests/SchemaDump/sql/oracleDumpTables.sql |   12 +
 .../tests/SchemaDump/sql/oracleSchemaDump.sql |   35 +
 .../tests/SchemaDump/sql/oracleShowTables.sql |    6 +
 .../tests/Skeleton/test_Skeleton.cpp          |   52 +
 .../tests/Skeleton/test_SkeletonDb.cpp        |   51 +
 .../tests/StressTest/stressTest.cpp           |  245 +
 .../test_TransactionHandling.cpp              |  282 +
 .../VersionNumber/test_VersionNumber.cpp      |  114 +
 RelationalCool/tests/authentication.xml       |   16 +
 RelationalCool/tests/dblookup.xml             |  124 +
 RelationalCool/tests/seal.opts                |   19 +
 RelationalCool/tests/seal.opts.error          |   19 +
 RelationalCool/tests/seal.opts.info           |   19 +
 RelationalCool/tests/seal.opts.verbose        |   19 +
 RelationalCool/tests/seal.opts.warning        |   19 +
 RelationalCool/tests/setupLocalTns.csh        |    1 +
 RelationalCool/tests/sqlnet.ora               |    2 +
 RelationalCool/tests/test_SealPluginDump.sh   |  183 +
 RelationalCool/tests/tnsnames.ora             |   24 +
 .../tests/utility_methods/test_utilities.cpp  |  347 +
 .../DBA/oracleCreateGenericReader.sql         |   38 +
 .../utilities/DBA/oracleCreateSchemaOwner.sql |  105 +
 .../coolAuthentication/coolAuthentication.cpp |  389 ++
 .../utilities/coolDropDB/coolDropDB.cpp       |  233 +
 .../coolDumpSchema/coolDumpSchema.cpp         |  110 +
 .../coolEvolveSchema/RalSchemaEvolution.cpp   | 2263 +++++++
 .../coolEvolveSchema/RalSchemaEvolution.h     |  162 +
 .../coolEvolveSchema/coolEvolveSchema.cpp     |   96 +
 .../coolPrivileges/RalPrivilegeManager.cpp    |  510 ++
 .../coolPrivileges/RalPrivilegeManager.h      |  121 +
 .../coolPrivileges/coolPrivileges.cpp         |  156 +
 .../coolPrivileges/logs/grantAll-details.txt  |   91 +
 .../coolPrivileges/logs/grantAll.txt          |  616 ++
 .../coolPrivileges/logs/grantReader.txt       |  203 +
 .../coolPrivileges/logs/grantTagger.txt       |  498 ++
 .../coolPrivileges/logs/grantWriter.txt       |  321 +
 .../coolPrivileges/logs/revokeAll.txt         |  616 ++
 .../coolPrivileges/logs/revokeReader.txt      |  202 +
 .../coolPrivileges/logs/revokeTagger.txt      |  372 ++
 .../coolPrivileges/logs/revokeWriter.txt      |  195 +
 .../coolPrivileges/logs/showTables.txt        |   35 +
 .../utilities/coolReplicateDB/Replication.cpp | 1038 +++
 .../utilities/coolReplicateDB/Replication.h   |  190 +
 .../coolReplicateDB/coolReplicateDb.cpp       |   73 +
 .../utilities/coolStat/coolStat.cpp           |   57 +
 RelationalCool/utilities/coolStat/coolStat.py |   41 +
 .../utilities/coolStat/testBug30859.py        |   19 +
 .../RalSchemaValidation.cpp                   |  512 ++
 .../coolValidateSchema/RalSchemaValidation.h  |  101 +
 .../coolValidateSchema/coolValidateSchema.cpp |   95 +
 .../coolValidateSchema/test_missingTables.py  |   73 +
 .../test_missingTables_roles.py               |  119 +
 390 files changed, 94905 insertions(+)
 create mode 100755 RelationalCool/cmt/requirements
 create mode 100644 RelationalCool/cmt/version.cmt
 create mode 100644 RelationalCool/doc/BugReports.txt
 create mode 100644 RelationalCool/doc/CLEANUP_PLAN.txt
 create mode 100644 RelationalCool/doc/RAL_feedback.txt
 create mode 100644 RelationalCool/doc/README.CLOB
 create mode 100644 RelationalCool/doc/README.gmt
 create mode 100644 RelationalCool/doc/README.standalone
 create mode 100644 RelationalCool/doc/TODO.txt
 create mode 100644 RelationalCool/doc/hvsTagsSpec.txt
 create mode 100755 RelationalCool/doc/release.notes
 create mode 100644 RelationalCool/doc/unit_test_log.txt
 create mode 100755 RelationalCool/doc/userTagsImpl.txt
 create mode 100644 RelationalCool/doc/userTagsImpl2.txt
 create mode 100644 RelationalCool/doc/userTagsImpl3.txt
 create mode 100644 RelationalCool/doc/userTagsSpec.txt
 create mode 100644 RelationalCool/doc/userTagsSpec2.txt
 create mode 100644 RelationalCool/doc/userTagsSpec3.txt
 create mode 100644 RelationalCool/python/CoolAuthentication/__init__.py
 create mode 100644 RelationalCool/python/CoolDescribeTable/__init__.py
 create mode 100644 RelationalCool/python/CoolDescribeTable/sql/oracleShowCreateTable.sql
 create mode 100644 RelationalCool/python/CoolGatherSchemaStats/__init__.py
 create mode 100644 RelationalCool/python/CoolGatherSchemaStats/sql/oracleGatherSchemaStats.sql
 create mode 100644 RelationalCool/python/CoolGatherTableStats/__init__.py
 create mode 100644 RelationalCool/python/CoolGatherTableStats/sql/oracleGatherTableStats.sql
 create mode 100644 RelationalCool/python/CoolQueryManager/__init__.py
 create mode 100644 RelationalCool/python/CoolShowTables/__init__.py
 create mode 100644 RelationalCool/python/CoolShowTables/sql/oracleShowTables.sql
 create mode 100755 RelationalCool/scripts/coolAuthentication.py
 create mode 100755 RelationalCool/scripts/coolDescribeTable.py
 create mode 100755 RelationalCool/scripts/coolExecuteSql.csh
 create mode 100755 RelationalCool/scripts/coolGatherSchemaStats.py
 create mode 100755 RelationalCool/scripts/coolGatherTableStats.py
 create mode 100755 RelationalCool/scripts/coolQueryManager.py
 create mode 100755 RelationalCool/scripts/coolShowTables.py
 create mode 100755 RelationalCool/scripts/coolSqlplus.sh
 create mode 100755 RelationalCool/scripts/scramShowUses
 create mode 100644 RelationalCool/scripts/scramShowUses.awk
 create mode 100644 RelationalCool/scripts/sql/oraclePurgeRecycleBin.sql
 create mode 100644 RelationalCool/scripts/sql/oracleShowTables.sql
 create mode 100755 RelationalCool/scripts/wineWrap.sh
 create mode 100644 RelationalCool/src/AttributeTable.h
 create mode 100644 RelationalCool/src/ConstRelationalObjectAdapter.cpp
 create mode 100644 RelationalCool/src/ConstRelationalObjectAdapter.h
 create mode 100644 RelationalCool/src/ConstTimeAdapter.cpp
 create mode 100644 RelationalCool/src/ConstTimeAdapter.h
 create mode 100644 RelationalCool/src/CoolChrono.cpp
 create mode 100644 RelationalCool/src/CoolChrono.h
 create mode 100644 RelationalCool/src/CoralApplication.cpp
 create mode 100644 RelationalCool/src/CoralApplication.h
 create mode 100644 RelationalCool/src/CoralConnectionServiceProxy.cpp
 create mode 100644 RelationalCool/src/CoralConnectionServiceProxy.h
 create mode 100644 RelationalCool/src/DummyTransactionMgr.cpp
 create mode 100644 RelationalCool/src/DummyTransactionMgr.h
 create mode 100644 RelationalCool/src/HvsPathHandler.cpp
 create mode 100644 RelationalCool/src/HvsPathHandler.h
 create mode 100644 RelationalCool/src/HvsPathHandlerException.h
 create mode 100644 RelationalCool/src/HvsTagRecord.h
 create mode 100644 RelationalCool/src/IHvsTagMgr.h
 create mode 100644 RelationalCool/src/IHvsTagRecord.h
 create mode 100644 RelationalCool/src/IRelationalBulkOperation.h
 create mode 100644 RelationalCool/src/IRelationalCursor.h
 create mode 100644 RelationalCool/src/IRelationalQueryDefinition.h
 create mode 100644 RelationalCool/src/IRelationalTransactionMgr.h
 create mode 100644 RelationalCool/src/IteratorException.h
 create mode 100644 RelationalCool/src/ManualTransaction.cpp
 create mode 100644 RelationalCool/src/ManualTransaction.h
 create mode 100644 RelationalCool/src/ObjectId.cpp
 create mode 100644 RelationalCool/src/ObjectId.h
 create mode 100644 RelationalCool/src/ObjectIteratorCounter.cpp
 create mode 100644 RelationalCool/src/ObjectIteratorCounter.h
 create mode 100644 RelationalCool/src/ObjectVectorIterator.cpp
 create mode 100644 RelationalCool/src/ObjectVectorIterator.h
 create mode 100644 RelationalCool/src/ProcMemory.h
 create mode 100644 RelationalCool/src/RalBulkOperation.h
 create mode 100644 RelationalCool/src/RalCursor.h
 create mode 100644 RelationalCool/src/RalDatabase.cpp
 create mode 100644 RelationalCool/src/RalDatabase.h
 create mode 100644 RelationalCool/src/RalDatabaseSvc.cpp
 create mode 100644 RelationalCool/src/RalDatabaseSvc.h
 create mode 100644 RelationalCool/src/RalQueryMgr.cpp
 create mode 100644 RelationalCool/src/RalQueryMgr.h
 create mode 100644 RelationalCool/src/RalSchemaMgr.cpp
 create mode 100644 RelationalCool/src/RalSchemaMgr.h
 create mode 100644 RelationalCool/src/RalSequenceMgr.cpp
 create mode 100644 RelationalCool/src/RalSequenceMgr.h
 create mode 100644 RelationalCool/src/RalSessionMgr.cpp
 create mode 100644 RelationalCool/src/RalSessionMgr.h
 create mode 100644 RelationalCool/src/RalTransactionMgr.cpp
 create mode 100644 RelationalCool/src/RalTransactionMgr.h
 create mode 100644 RelationalCool/src/RelationalChannelTable.cpp
 create mode 100644 RelationalCool/src/RelationalChannelTable.h
 create mode 100644 RelationalCool/src/RelationalChannelTablesTable.cpp
 create mode 100644 RelationalCool/src/RelationalChannelTablesTable.h
 create mode 100644 RelationalCool/src/RelationalDatabase.cpp
 create mode 100644 RelationalCool/src/RelationalDatabase.h
 create mode 100644 RelationalCool/src/RelationalDatabaseId.cpp
 create mode 100644 RelationalCool/src/RelationalDatabaseId.h
 create mode 100644 RelationalCool/src/RelationalDatabasePtr.h
 create mode 100644 RelationalCool/src/RelationalDatabaseTable.cpp
 create mode 100644 RelationalCool/src/RelationalDatabaseTable.h
 create mode 100644 RelationalCool/src/RelationalException.cpp
 create mode 100644 RelationalCool/src/RelationalException.h
 create mode 100644 RelationalCool/src/RelationalFolder.cpp
 create mode 100644 RelationalCool/src/RelationalFolder.h
 create mode 100644 RelationalCool/src/RelationalFolderSet.cpp
 create mode 100644 RelationalCool/src/RelationalFolderSet.h
 create mode 100644 RelationalCool/src/RelationalFolderSetUnsupported.cpp
 create mode 100644 RelationalCool/src/RelationalFolderSetUnsupported.h
 create mode 100644 RelationalCool/src/RelationalFolderUnsupported.cpp
 create mode 100644 RelationalCool/src/RelationalFolderUnsupported.h
 create mode 100644 RelationalCool/src/RelationalGlobalHeadTagTable.cpp
 create mode 100644 RelationalCool/src/RelationalGlobalHeadTagTable.h
 create mode 100644 RelationalCool/src/RelationalGlobalTagTable.cpp
 create mode 100644 RelationalCool/src/RelationalGlobalTagTable.h
 create mode 100644 RelationalCool/src/RelationalGlobalUserTagTable.cpp
 create mode 100644 RelationalCool/src/RelationalGlobalUserTagTable.h
 create mode 100644 RelationalCool/src/RelationalHvsNode.cpp
 create mode 100644 RelationalCool/src/RelationalHvsNode.h
 create mode 100644 RelationalCool/src/RelationalHvsNodeRecord.cpp
 create mode 100644 RelationalCool/src/RelationalHvsNodeRecord.h
 create mode 100644 RelationalCool/src/RelationalHvsTagRecord.cpp
 create mode 100644 RelationalCool/src/RelationalHvsTagRecord.h
 create mode 100644 RelationalCool/src/RelationalIovSharedSequenceTable.h
 create mode 100644 RelationalCool/src/RelationalIovTablesTable.cpp
 create mode 100644 RelationalCool/src/RelationalIovTablesTable.h
 create mode 100644 RelationalCool/src/RelationalNodeMgr.cpp
 create mode 100644 RelationalCool/src/RelationalNodeMgr.h
 create mode 100644 RelationalCool/src/RelationalNodeTable.cpp
 create mode 100644 RelationalCool/src/RelationalNodeTable.h
 create mode 100644 RelationalCool/src/RelationalObject.cpp
 create mode 100644 RelationalCool/src/RelationalObject.h
 create mode 100644 RelationalCool/src/RelationalObject2TagTable.cpp
 create mode 100644 RelationalCool/src/RelationalObject2TagTable.h
 create mode 100644 RelationalCool/src/RelationalObjectIterator.cpp
 create mode 100644 RelationalCool/src/RelationalObjectIterator.h
 create mode 100644 RelationalCool/src/RelationalObjectMgr.cpp
 create mode 100644 RelationalCool/src/RelationalObjectMgr.h
 create mode 100644 RelationalCool/src/RelationalObjectPtr.h
 create mode 100644 RelationalCool/src/RelationalObjectTable.cpp
 create mode 100644 RelationalCool/src/RelationalObjectTable.h
 create mode 100644 RelationalCool/src/RelationalObjectTableRow.cpp
 create mode 100644 RelationalCool/src/RelationalObjectTableRow.h
 create mode 100644 RelationalCool/src/RelationalPayloadQuery.cpp
 create mode 100644 RelationalCool/src/RelationalPayloadQuery.h
 create mode 100644 RelationalCool/src/RelationalQueryDefinition.cpp
 create mode 100644 RelationalCool/src/RelationalQueryDefinition.h
 create mode 100644 RelationalCool/src/RelationalQueryMgr.cpp
 create mode 100644 RelationalCool/src/RelationalQueryMgr.h
 create mode 100644 RelationalCool/src/RelationalSchemaMgr.cpp
 create mode 100644 RelationalCool/src/RelationalSchemaMgr.h
 create mode 100644 RelationalCool/src/RelationalSequence.cpp
 create mode 100644 RelationalCool/src/RelationalSequence.h
 create mode 100644 RelationalCool/src/RelationalSequenceMgr.cpp
 create mode 100644 RelationalCool/src/RelationalSequenceMgr.h
 create mode 100644 RelationalCool/src/RelationalSequenceTable.cpp
 create mode 100644 RelationalCool/src/RelationalSequenceTable.h
 create mode 100644 RelationalCool/src/RelationalSharedSequenceTable.cpp
 create mode 100644 RelationalCool/src/RelationalSharedSequenceTable.h
 create mode 100644 RelationalCool/src/RelationalTableRow.cpp
 create mode 100644 RelationalCool/src/RelationalTableRow.h
 create mode 100644 RelationalCool/src/RelationalTableRowBase.cpp
 create mode 100644 RelationalCool/src/RelationalTableRowBase.h
 create mode 100644 RelationalCool/src/RelationalTag2TagTable.cpp
 create mode 100644 RelationalCool/src/RelationalTag2TagTable.h
 create mode 100644 RelationalCool/src/RelationalTagMgr.cpp
 create mode 100644 RelationalCool/src/RelationalTagMgr.h
 create mode 100644 RelationalCool/src/RelationalTagSequence.h
 create mode 100644 RelationalCool/src/RelationalTagSharedSequenceTable.h
 create mode 100644 RelationalCool/src/RelationalTagTable.cpp
 create mode 100644 RelationalCool/src/RelationalTagTable.h
 create mode 100644 RelationalCool/src/RelationalTransaction.cpp
 create mode 100644 RelationalCool/src/RelationalTransaction.h
 create mode 100644 RelationalCool/src/SealBase_TimeInfo.cpp
 create mode 100644 RelationalCool/src/SealBase_TimeInfo.h
 create mode 100644 RelationalCool/src/SealBase_sysapi_TimeInfo.h
 create mode 100644 RelationalCool/src/SealBase_sysapi_Windows.h
 create mode 100644 RelationalCool/src/SealUtil_BaseSealChrono.h
 create mode 100644 RelationalCool/src/SealUtil_SealTimer.cpp
 create mode 100644 RelationalCool/src/SealUtil_SealTimer.h
 create mode 100644 RelationalCool/src/SealUtil_TimingItem.cpp
 create mode 100644 RelationalCool/src/SealUtil_TimingItem.h
 create mode 100644 RelationalCool/src/SimpleObject.h
 create mode 100644 RelationalCool/src/TimingReport.cpp
 create mode 100644 RelationalCool/src/TimingReport.h
 create mode 100644 RelationalCool/src/TimingReportMgr.cpp
 create mode 100644 RelationalCool/src/TimingReportMgr.h
 create mode 100644 RelationalCool/src/VersionInfo.h
 create mode 100644 RelationalCool/src/VersionNumber.h
 create mode 100644 RelationalCool/src/attributeListToString.h
 create mode 100644 RelationalCool/src/new/IHvsNodeMgr.h
 create mode 100644 RelationalCool/src/new/IHvsNodeRecordMgr.h
 create mode 100644 RelationalCool/src/new/IHvsTag.h
 create mode 100644 RelationalCool/src/new/RelationalHvsTagMgr.cpp
 create mode 100644 RelationalCool/src/new/RelationalHvsTagMgr.h
 create mode 100644 RelationalCool/src/sigsegv.cpp
 create mode 100644 RelationalCool/src/sigsegv.h
 create mode 100644 RelationalCool/src/sleep.h
 create mode 100644 RelationalCool/src/timeToString.h
 create mode 100644 RelationalCool/src/uppercaseString.h
 create mode 100644 RelationalCool/tests/AttributeList/test_AttributeList.cpp
 create mode 100644 RelationalCool/tests/AttributeListDump/test_AttributeListDump.cpp
 create mode 100755 RelationalCool/tests/BoolIO/authentication.xml
 create mode 100644 RelationalCool/tests/BoolIO/boolIO.cpp
 create mode 100644 RelationalCool/tests/BoolIO/boolIO.txt.MySQL
 create mode 100644 RelationalCool/tests/BoolIO/boolIO.txt.Oracle
 create mode 100644 RelationalCool/tests/BuildFile
 create mode 100644 RelationalCool/tests/CMS_ECAL/README.CMS_ECAL
 create mode 100644 RelationalCool/tests/CMS_ECAL/testCmsEcal.cpp
 create mode 100644 RelationalCool/tests/CMS_extRef/extraSQL.sql
 create mode 100644 RelationalCool/tests/CMS_extRef/testCmsExtRef.cpp
 create mode 100644 RelationalCool/tests/ChannelSelection/test_ChannelSelection.cpp
 create mode 100644 RelationalCool/tests/Channels/test_Channels.cpp
 create mode 100755 RelationalCool/tests/ClobIO/authentication.xml
 create mode 100755 RelationalCool/tests/ClobIO/clobInputOutput.cpp
 create mode 100644 RelationalCool/tests/Common/CoolDBUnitTest.h
 create mode 100644 RelationalCool/tests/Common/CoolUnitTest.h
 create mode 100644 RelationalCool/tests/Common/CppUnit_headers.h
 create mode 100644 RelationalCool/tests/Common/CppUnit_testdriver.icpp
 create mode 100644 RelationalCool/tests/Common/cppunit/TestListener.h
 create mode 100644 RelationalCool/tests/Common/releaser.h
 create mode 100644 RelationalCool/tests/CoolCppUnitTestDriver.cpp
 create mode 100644 RelationalCool/tests/CreateDatabase/createDatabase.cpp
 create mode 100644 RelationalCool/tests/HvsPathHandler/test_HvsPathHandler.cpp
 create mode 100644 RelationalCool/tests/HvsTags/test_HvsTags.cpp
 create mode 100755 RelationalCool/tests/Int64IO/Int64InputOutput.cpp
 create mode 100644 RelationalCool/tests/Int64IO/Int64InputOutput.txt
 create mode 100755 RelationalCool/tests/MemoryConsumption/execTest.sh
 create mode 100755 RelationalCool/tests/MemoryConsumption/test_MemoryConsumption.cpp
 create mode 100644 RelationalCool/tests/MemoryConsumption/unitTest_RelationalCool_MemoryConsumption.out.osx103_gcc33
 create mode 100644 RelationalCool/tests/MemoryConsumption/unitTest_RelationalCool_MemoryConsumption.out.slc3_ia32_gcc323
 create mode 100644 RelationalCool/tests/MyODBCBulkTest/README
 create mode 100755 RelationalCool/tests/MyODBCBulkTest/test_MyODBCBulkOp.cpp
 create mode 100644 RelationalCool/tests/MyTest/DO_NOT_DELETE_ME
 create mode 100644 RelationalCool/tests/ObjectId/test_ObjectId.cpp
 create mode 100644 RelationalCool/tests/PayloadSpecification/test_PayloadSpecification.cpp
 create mode 100644 RelationalCool/tests/Performance/Benchmark.h
 create mode 100644 RelationalCool/tests/Performance/performance_test.txt
 create mode 100644 RelationalCool/tests/Performance/test_Performance.cpp
 create mode 100644 RelationalCool/tests/PerformanceAV/README.Performance
 create mode 100644 RelationalCool/tests/PerformanceAV/README.sqlTrace
 create mode 100644 RelationalCool/tests/PerformanceAV/ServerCache/100k-my-cool-first.out
 create mode 100644 RelationalCool/tests/PerformanceAV/ServerCache/100k-my-cool-next.out
 create mode 100644 RelationalCool/tests/PerformanceAV/ServerCache/100k-ora-benthic-first.prf
 create mode 100644 RelationalCool/tests/PerformanceAV/ServerCache/100k-ora-benthic-next.prf
 create mode 100644 RelationalCool/tests/PerformanceAV/ServerCache/100k-ora-cool-first.out
 create mode 100644 RelationalCool/tests/PerformanceAV/ServerCache/100k-ora-cool-first.prf
 create mode 100644 RelationalCool/tests/PerformanceAV/ServerCache/100k-ora-cool-next.out
 create mode 100644 RelationalCool/tests/PerformanceAV/ServerCache/100k-ora-cool-next.prf
 create mode 100644 RelationalCool/tests/PerformanceAV/TODO.Performance
 create mode 100644 RelationalCool/tests/PerformanceAV/TestAttributeValueAccessor/doNotUseAccessor-memory.rh73.501MB.oracle.out.ANALYZED
 create mode 100644 RelationalCool/tests/PerformanceAV/TestAttributeValueAccessor/doNotUseAccessor-time.rh73.501MB.oracle.out.ANALYZED
 create mode 100644 RelationalCool/tests/PerformanceAV/TestAttributeValueAccessor/execTestAttributeValueAccessor.rh73.501MB.oracle.out.ANALYZED
 create mode 100644 RelationalCool/tests/PerformanceAV/TestAttributeValueAccessor/useAccessor-memory.rh73.501MB.oracle.out.ANALYZED
 create mode 100644 RelationalCool/tests/PerformanceAV/TestAttributeValueAccessor/useAccessor-time.rh73.501MB.oracle.out.ANALYZED
 create mode 100644 RelationalCool/tests/PerformanceAV/TestNewCopy/execTestNewCopy.rh73.1006MB.out
 create mode 100644 RelationalCool/tests/PerformanceAV/TestNewCopy/execTestNewCopy.rh73.501MB.out
 create mode 100644 RelationalCool/tests/PerformanceAV/TestNewCopy/execTestNewCopy.slc3.2006MB.out
 create mode 100644 RelationalCool/tests/PerformanceAV/TestNewCopy/newCopy-memory.rh73.1006MB.out
 create mode 100644 RelationalCool/tests/PerformanceAV/TestNewCopy/newCopy-memory.rh73.501MB.out
 create mode 100644 RelationalCool/tests/PerformanceAV/TestNewCopy/newCopy-memory.slc3.2006MB.out
 create mode 100644 RelationalCool/tests/PerformanceAV/TestNewCopy/newCopy-time.rh73.1006MB.out
 create mode 100644 RelationalCool/tests/PerformanceAV/TestNewCopy/newCopy-time.rh73.501MB.out
 create mode 100644 RelationalCool/tests/PerformanceAV/TestNewCopy/newCopy-time.slc3.2006MB.out
 create mode 100644 RelationalCool/tests/PerformanceAV/TestNewCopy/oldCopy-memory.rh73.1006MB.out
 create mode 100644 RelationalCool/tests/PerformanceAV/TestNewCopy/oldCopy-memory.rh73.501MB.out
 create mode 100644 RelationalCool/tests/PerformanceAV/TestNewCopy/oldCopy-memory.slc3.2006MB.out
 create mode 100644 RelationalCool/tests/PerformanceAV/TestNewCopy/oldCopy-time.rh73.1006MB.out
 create mode 100644 RelationalCool/tests/PerformanceAV/TestNewCopy/oldCopy-time.rh73.501MB.out
 create mode 100644 RelationalCool/tests/PerformanceAV/TestNewCopy/oldCopy-time.slc3.2006MB.out
 create mode 100644 RelationalCool/tests/PerformanceAV/TestRalOnly/execTestRalOnly.rh73.501MB.oracle.out
 create mode 100644 RelationalCool/tests/PerformanceAV/TestRalOnly/execTestRalOnly.rh73.501MB.oracle.out.ANALYZED
 create mode 100644 RelationalCool/tests/PerformanceAV/TestRalOnly/ralOnly-memory.rh73.501MB.oracle.out
 create mode 100644 RelationalCool/tests/PerformanceAV/TestRalOnly/ralOnly-time.rh73.501MB.oracle.out
 create mode 100644 RelationalCool/tests/PerformanceAV/TestRalOnly/ralOnly-time.rh73.501MB.oracle.out.ANALYZED
 create mode 100644 RelationalCool/tests/PerformanceAV/TestRalOnly/ralOnly-time.rh73.501MB.oracle.prf
 create mode 100644 RelationalCool/tests/PerformanceAV/TestRalOnly/ralOnly-time.rh73.501MB.oracle.prf.ANALYZED
 create mode 100644 RelationalCool/tests/PerformanceAV/TestRalOnly/withCool-memory.rh73.501MB.oracle.out
 create mode 100644 RelationalCool/tests/PerformanceAV/TestRalOnly/withCool-time.rh73.501MB.oracle.out
 create mode 100644 RelationalCool/tests/PerformanceAV/TestRalOnly/withCool-time.rh73.501MB.oracle.out.ANALYZED
 create mode 100644 RelationalCool/tests/PerformanceAV/TestRalOnly/withCool-time.rh73.501MB.oracle.prf
 create mode 100644 RelationalCool/tests/PerformanceAV/TestRalOnly/withCool-time.rh73.501MB.oracle.prf.ANALYZED
 create mode 100644 RelationalCool/tests/PerformanceAV/TestScrollableCursor/execTestScrollableCursor.rh73.1006MB.oracle.out.ANALYZED
 create mode 100644 RelationalCool/tests/PerformanceAV/TestScrollableCursor/notScrollable-memory.rh73.1006MB.oracle.out.ANALYZED
 create mode 100644 RelationalCool/tests/PerformanceAV/TestScrollableCursor/notScrollable-time.rh73.1006MB.oracle.out.ANALYZED
 create mode 100644 RelationalCool/tests/PerformanceAV/TestScrollableCursor/notScrollable-time.rh73.1006MB.oracle.prf.ANALYZED
 create mode 100644 RelationalCool/tests/PerformanceAV/TestScrollableCursor/scrollable-memory.rh73.1006MB.oracle.out.ANALYZED
 create mode 100644 RelationalCool/tests/PerformanceAV/TestScrollableCursor/scrollable-time.rh73.1006MB.oracle.out.ANALYZED
 create mode 100644 RelationalCool/tests/PerformanceAV/TestScrollableCursor/scrollable-time.rh73.1006MB.oracle.prf.ANALYZED
 create mode 100644 RelationalCool/tests/PerformanceAV/TestShareData/doNotShareData-memory.rh73.501MB.oracle.out.ANALYZED
 create mode 100644 RelationalCool/tests/PerformanceAV/TestShareData/doNotShareData-time.rh73.501MB.oracle.out.ANALYZED
 create mode 100644 RelationalCool/tests/PerformanceAV/TestShareData/doNotShareData-time.rh73.501MB.oracle.prf.ANALYZED
 create mode 100644 RelationalCool/tests/PerformanceAV/TestShareData/execTestShareData.out.rh73.501MB.oracle.out.ANALYZED
 create mode 100644 RelationalCool/tests/PerformanceAV/TestShareData/shareData-memory.rh73.501MB.oracle.out.ANALYZED
 create mode 100644 RelationalCool/tests/PerformanceAV/TestShareData/shareData-time.rh73.501MB.oracle.out.ANALYZED
 create mode 100644 RelationalCool/tests/PerformanceAV/TestShareData/shareData-time.rh73.501MB.oracle.prf.ANALYZED
 create mode 100755 RelationalCool/tests/PerformanceAV/execTestAttributeValueAccessor.csh
 create mode 100755 RelationalCool/tests/PerformanceAV/execTestNewCopy.csh
 create mode 100755 RelationalCool/tests/PerformanceAV/execTestRalOnly.csh
 create mode 100755 RelationalCool/tests/PerformanceAV/execTestScrollableCursor.csh
 create mode 100755 RelationalCool/tests/PerformanceAV/execTestShareData.csh
 create mode 100644 RelationalCool/tests/PerformanceAV/mySetupMySQL.csh
 create mode 100644 RelationalCool/tests/PerformanceAV/mySetupOracle.csh
 create mode 100644 RelationalCool/tests/PerformanceAV/scaling_mixed.txt
 create mode 100644 RelationalCool/tests/PerformanceAV/scaling_mixed_2.txt
 create mode 100644 RelationalCool/tests/PerformanceAV/test_PerformanceAV.cpp
 create mode 100644 RelationalCool/tests/Privileges/out.oracle.slc3_ia32_gcc323
 create mode 100644 RelationalCool/tests/Privileges/test_Privileges.cpp
 create mode 100644 RelationalCool/tests/ProcMemory/test_ProcMemory.cpp
 create mode 100644 RelationalCool/tests/RalDatabase/README.threads
 create mode 100644 RelationalCool/tests/RalDatabase/dropDatabaseTest.out.OCI_DEFAULT
 create mode 100644 RelationalCool/tests/RalDatabase/dropDatabaseTest.out.OCI_THREADED
 create mode 100644 RelationalCool/tests/RalDatabase/test_RalDatabase.cpp
 create mode 100644 RelationalCool/tests/RalDatabaseSvc/test_RalDatabaseSvc.cpp
 create mode 100644 RelationalCool/tests/RalDatabase_extendedSpec/test_RalDatabase_extendedSpec.cpp
 create mode 100644 RelationalCool/tests/RalDatabase_versioning/README.segmentationFault
 create mode 100644 RelationalCool/tests/RalSequence/test_RalSequence.cpp
 create mode 100644 RelationalCool/tests/RelationalDatabaseId/test_RelationalDatabaseId.cpp
 create mode 100755 RelationalCool/tests/RelationalFolder/README.tests
 create mode 100755 RelationalCool/tests/RelationalFolder/out.Windows.doNotAdjustTimeZone
 create mode 100755 RelationalCool/tests/RelationalFolder/out.Windows.m1.adjustTimeZone
 create mode 100755 RelationalCool/tests/RelationalFolder/out.Windows.noTest.adjustTimeZone
 create mode 100755 RelationalCool/tests/RelationalFolder/out.Windows.p1.adjustTimeZone
 create mode 100644 RelationalCool/tests/RelationalFolder/test_RelationalFolder.cpp
 create mode 100755 RelationalCool/tests/RelationalFolder/test_RelationalFolder.cpp.gmtime
 create mode 100644 RelationalCool/tests/RelationalFolderSet/test_RelationalFolderSet.cpp
 create mode 100644 RelationalCool/tests/RelationalObjectIterator/test_RelationalObjectIterator.cpp
 create mode 100644 RelationalCool/tests/RelationalObjectMgr/test_RelationalObjectMgr.cpp
 create mode 100644 RelationalCool/tests/RelationalObjectSet/test_RelationalObjectSet.cpp
 create mode 100644 RelationalCool/tests/RelationalObjectTable/test_RelationalObjectTable.cpp
 create mode 100755 RelationalCool/tests/SchemaDump/coolSchemaDump.csh
 create mode 100644 RelationalCool/tests/SchemaDump/oracleRefSchema.html
 create mode 100644 RelationalCool/tests/SchemaDump/schemaDump.cpp
 create mode 100644 RelationalCool/tests/SchemaDump/sql/oracleDescTable.sql
 create mode 100755 RelationalCool/tests/SchemaDump/sql/oracleDumpConstraints.sql
 create mode 100755 RelationalCool/tests/SchemaDump/sql/oracleDumpFKColumns.sql
 create mode 100755 RelationalCool/tests/SchemaDump/sql/oracleDumpIndColumns.sql
 create mode 100755 RelationalCool/tests/SchemaDump/sql/oracleDumpIndexes.sql
 create mode 100755 RelationalCool/tests/SchemaDump/sql/oracleDumpTables.sql
 create mode 100644 RelationalCool/tests/SchemaDump/sql/oracleSchemaDump.sql
 create mode 100644 RelationalCool/tests/SchemaDump/sql/oracleShowTables.sql
 create mode 100644 RelationalCool/tests/Skeleton/test_Skeleton.cpp
 create mode 100644 RelationalCool/tests/Skeleton/test_SkeletonDb.cpp
 create mode 100644 RelationalCool/tests/StressTest/stressTest.cpp
 create mode 100644 RelationalCool/tests/TransactionHandling/test_TransactionHandling.cpp
 create mode 100644 RelationalCool/tests/VersionNumber/test_VersionNumber.cpp
 create mode 100755 RelationalCool/tests/authentication.xml
 create mode 100644 RelationalCool/tests/dblookup.xml
 create mode 100644 RelationalCool/tests/seal.opts
 create mode 100644 RelationalCool/tests/seal.opts.error
 create mode 100644 RelationalCool/tests/seal.opts.info
 create mode 100644 RelationalCool/tests/seal.opts.verbose
 create mode 100644 RelationalCool/tests/seal.opts.warning
 create mode 100644 RelationalCool/tests/setupLocalTns.csh
 create mode 100644 RelationalCool/tests/sqlnet.ora
 create mode 100755 RelationalCool/tests/test_SealPluginDump.sh
 create mode 100644 RelationalCool/tests/tnsnames.ora
 create mode 100644 RelationalCool/tests/utility_methods/test_utilities.cpp
 create mode 100644 RelationalCool/utilities/DBA/oracleCreateGenericReader.sql
 create mode 100644 RelationalCool/utilities/DBA/oracleCreateSchemaOwner.sql
 create mode 100644 RelationalCool/utilities/coolAuthentication/coolAuthentication.cpp
 create mode 100644 RelationalCool/utilities/coolDropDB/coolDropDB.cpp
 create mode 100755 RelationalCool/utilities/coolDumpSchema/coolDumpSchema.cpp
 create mode 100644 RelationalCool/utilities/coolEvolveSchema/RalSchemaEvolution.cpp
 create mode 100644 RelationalCool/utilities/coolEvolveSchema/RalSchemaEvolution.h
 create mode 100644 RelationalCool/utilities/coolEvolveSchema/coolEvolveSchema.cpp
 create mode 100644 RelationalCool/utilities/coolPrivileges/RalPrivilegeManager.cpp
 create mode 100644 RelationalCool/utilities/coolPrivileges/RalPrivilegeManager.h
 create mode 100644 RelationalCool/utilities/coolPrivileges/coolPrivileges.cpp
 create mode 100644 RelationalCool/utilities/coolPrivileges/logs/grantAll-details.txt
 create mode 100644 RelationalCool/utilities/coolPrivileges/logs/grantAll.txt
 create mode 100644 RelationalCool/utilities/coolPrivileges/logs/grantReader.txt
 create mode 100644 RelationalCool/utilities/coolPrivileges/logs/grantTagger.txt
 create mode 100644 RelationalCool/utilities/coolPrivileges/logs/grantWriter.txt
 create mode 100644 RelationalCool/utilities/coolPrivileges/logs/revokeAll.txt
 create mode 100644 RelationalCool/utilities/coolPrivileges/logs/revokeReader.txt
 create mode 100644 RelationalCool/utilities/coolPrivileges/logs/revokeTagger.txt
 create mode 100644 RelationalCool/utilities/coolPrivileges/logs/revokeWriter.txt
 create mode 100644 RelationalCool/utilities/coolPrivileges/logs/showTables.txt
 create mode 100644 RelationalCool/utilities/coolReplicateDB/Replication.cpp
 create mode 100644 RelationalCool/utilities/coolReplicateDB/Replication.h
 create mode 100644 RelationalCool/utilities/coolReplicateDB/coolReplicateDb.cpp
 create mode 100644 RelationalCool/utilities/coolStat/coolStat.cpp
 create mode 100644 RelationalCool/utilities/coolStat/coolStat.py
 create mode 100644 RelationalCool/utilities/coolStat/testBug30859.py
 create mode 100644 RelationalCool/utilities/coolValidateSchema/RalSchemaValidation.cpp
 create mode 100644 RelationalCool/utilities/coolValidateSchema/RalSchemaValidation.h
 create mode 100644 RelationalCool/utilities/coolValidateSchema/coolValidateSchema.cpp
 create mode 100644 RelationalCool/utilities/coolValidateSchema/test_missingTables.py
 create mode 100644 RelationalCool/utilities/coolValidateSchema/test_missingTables_roles.py

diff --git a/RelationalCool/cmt/requirements b/RelationalCool/cmt/requirements
new file mode 100755
index 000000000..8c80e79aa
--- /dev/null
+++ b/RelationalCool/cmt/requirements
@@ -0,0 +1,144 @@
+#============================================================================
+# $ Id: requirements,v 1.4 2005/08/24 17:31:07 marcocle Exp $
+#============================================================================
+package RelationalCool
+#============================================================================
+
+#============================================================================
+# Public dependencies
+#============================================================================
+
+use CoolKernel v*
+
+#============================================================================
+# Build rules
+#============================================================================
+
+# Use lcg_plugin_library and add 'use Reflex' to make this a Reflex plugin
+# Use lcg_module_library to make this a SEAL plugin (not linked by default)
+apply_pattern lcg_shared_library
+
+include_path none
+
+#============================================================================
+private
+#============================================================================
+
+# Link the CORAL relational libraries
+apply_tag NEEDS_CORAL_RELATIONAL_ACCESS
+
+macro_append lcg_RelationalCool_shlibflags ' $(Boost_linkopts_thread)'
+macro_append lcg_RelationalCool_shlibflags '' \
+             WIN32 ' $(Boost_linkopts_date_time)'
+macro_append lcg_RelationalCool_shlibflags '' \
+             WIN32 ' PowrProf.lib '
+
+#============================================================================
+# Tests and utilities
+#============================================================================
+
+use CppUnit v* LCG_Interfaces -no_auto_imports
+
+# For the SEAL signal handler
+###use SEAL v* LCG_Interfaces
+
+#============================================================================
+# Setup the build options for the tests
+
+# RelationalCool test linkopts
+macro_append RelationalCool_testlinkopts " -llcg_RelationalCool " \
+             WIN32 " /libpath:../$(CMTCONFIG)/lib lcg_RelationalCool.lib "
+macro_append RelationalCool_testlinkopts '' \
+             WIN32 ' $(Boost_linkopts_date_time)'
+
+# RelationalCool utility linkopts
+macro_append RelationalCool_utilitylinkopts " -llcg_RelationalCool " \
+             WIN32 " /libpath:../$(CMTCONFIG)/lib lcg_RelationalCool.lib"
+macro_append RelationalCool_utilitylinkopts '' \
+             WIN32 ' $(Boost_linkopts_date_time)'
+
+#============================================================================
+# Local patterns
+
+pattern cool_no_db_test \
+  apply_pattern lcg_unit_test_application name=<package>_<name> \
+    files=../tests/<name>/*.cpp ; \
+  macro_append test_<package>_<name>_cppflags ' $(ppcmd)"../tests/Common"' ;\
+  macro_remove test_<package>_<name>linkopts '' Darwin '-L$(CMTINSTALLAREA)/$(CMTCONFIG)/tests/lib'
+
+pattern cool_db_test \
+  apply_pattern lcg_unit_test_application name=<package>_<name> \
+    files=../tests/<name>/*.cpp ;\
+  macro_append test_<package>_<name>_cppflags ' $(ppcmd)"../tests/Common"' ;\
+  macro_append test_<package>_<name>linkopts ' $(Boost_linkopts_thread)' ;\
+  macro_remove test_<package>_<name>linkopts '' Darwin '-L$(CMTINSTALLAREA)/$(CMTCONFIG)/tests/lib'
+
+pattern cool_utility \
+  application <name> ../utilities/<name>/*.cpp ;\
+  macro_append <name>linkopts ' $(RelationalCool_utilitylinkopts) $(Boost_linkopts_thread)' ;\
+  macro <name>_dependencies ' lcg_RelationalCool '
+
+#============================================================================
+# The tests
+
+apply_pattern cool_no_db_test name=ChannelSelection
+apply_pattern cool_no_db_test name=PayloadSpecification
+apply_pattern cool_no_db_test name=VersionNumber
+apply_pattern cool_no_db_test name=HvsPathHandler
+apply_pattern cool_no_db_test name=RelationalDatabaseId
+apply_pattern cool_no_db_test name=ObjectId
+apply_pattern cool_no_db_test name=utility_methods
+
+apply_pattern cool_db_test name=Channels
+apply_pattern cool_db_test name=HvsTags
+apply_pattern cool_db_test name=RalDatabase
+apply_pattern cool_db_test name=RalDatabase_extendedSpec
+apply_pattern cool_db_test name=RalDatabaseSvc
+apply_pattern cool_db_test name=RalSequence
+apply_pattern cool_db_test name=RelationalFolder
+apply_pattern cool_db_test name=RelationalFolderSet
+apply_pattern cool_db_test name=RelationalObjectIterator
+apply_pattern cool_db_test name=RelationalObjectMgr
+apply_pattern cool_db_test name=RelationalObjectSet
+apply_pattern cool_db_test name=RelationalObjectTable
+
+# Private tests - not to be installed in the release area
+###apply_pattern cool_db_test name=bug30858
+###macro_remove tests_constituents test_RelationalCool_bug30858
+###apply_pattern cool_db_test name=bug33578
+###macro_remove tests_constituents test_RelationalCool_bug33578
+
+#============================================================================
+# The utilities
+
+apply_pattern cool_utility name=coolAuthentication
+apply_pattern cool_utility name=coolDropDB
+apply_pattern cool_utility name=coolDumpSchema
+apply_pattern cool_utility name=coolEvolveSchema
+apply_pattern cool_utility name=coolPrivileges
+apply_pattern cool_utility name=coolReplicateDB
+apply_pattern cool_utility name=coolStat
+apply_pattern cool_utility name=coolValidateSchema
+
+#============================================================================
+# Install the scripts
+#============================================================================
+
+macro  scrdir "$(CMTINSTALLAREA)/$(tag)/bin" \
+       WIN32  "$(CMTINSTALLAREA)\$(tag)\bin"
+action install_scripts "mkdir -p $(scrdir); cp -r ../scripts/* $(scrdir)/." \
+       WIN32           "xcopy /I/S/Y/Q ..\scripts\*.* $(scrdir)\."
+
+# Append to 'constituents' to execute an action in 'cmt make'
+# (append to 'all_constituents' to execute it only in 'cmt make all').
+# Remove the action from cmt_actions_constituents so that the action 
+# is not executed twice in 'cmt make all_groups' (it executes all actions).
+macro_append constituents "install_scripts"
+macro_remove cmt_actions_constituents "install_scripts"
+
+# Fake target for examples
+action examples "echo No examples in this package"
+macro_remove cmt_actions_constituents "examples"
+
+# Do not install the header files 
+macro_remove constituents 'install_includes'
diff --git a/RelationalCool/cmt/version.cmt b/RelationalCool/cmt/version.cmt
new file mode 100644
index 000000000..626799f0f
--- /dev/null
+++ b/RelationalCool/cmt/version.cmt
@@ -0,0 +1 @@
+v1
diff --git a/RelationalCool/doc/BugReports.txt b/RelationalCool/doc/BugReports.txt
new file mode 100644
index 000000000..eff71dadf
--- /dev/null
+++ b/RelationalCool/doc/BugReports.txt
@@ -0,0 +1,8 @@
+2005.02.03 Schema evolution (AV, MC)
+
+The new software does not allow to delete the old tables.
+Long term solutions: provide schema evolution.
+Short term solution: provide scripts to clean the schema.
+
+
+
diff --git a/RelationalCool/doc/CLEANUP_PLAN.txt b/RelationalCool/doc/CLEANUP_PLAN.txt
new file mode 100644
index 000000000..c344d5e3e
--- /dev/null
+++ b/RelationalCool/doc/CLEANUP_PLAN.txt
@@ -0,0 +1,130 @@
+------------------------------------------------
+AV's plan for cleaning up the code - 14.12.2004
+------------------------------------------------
+
+General ideas:
+- Need three or more types of classes, Relational, Ral, Hvs;
+  for the moment they can stay all in RelationalCool, then we can move them
+- Hvs for the moment is only needed to model transient HVS entities
+  and factor out functionality that is implemented by CondDB stuff too
+  (eg HvsNode should be - again - a base clas for RelationalFolder)
+- Relational classes should contain all the table and column names
+  and all the algorithmic logic of the relational implementation
+- Ral classes should contain only the code that really does table
+  creation/dropping and row insertion/update/select/delete: the idea 
+  is that one can provide a MySQL or OCCI direct implementation of 
+  the Relational conddb by JUST replacing the Ral classes
+==> Main emphasis of this round of cleanup should be to extract out of
+    the Ral classes the functionality that belongs to Relational
+
+Specific points for Ral classes
+
+- RalDatabaseSvc: OK should remain
+
+- RalDatabaseSvcFactory: OK for now... eventually may be replaced
+  by a more general DatabaseSvcFactory, which should understand
+  IDs of the form "ral::mysql:/" or "mysql::mysql:/" and instantiate
+  a Ralor MySQL database service to handle the same mysql database....
+
+- RalTransaction: should disappear, it should become RelationalTransaction.
+  The idea is that the user does not manipulate transactions.
+  All methoids called by the user are encapsulated within a transaction.
+  Typically, these methods have the form { 1.startTransaction
+  2.doSomethingInDb 3.commitTransaction }. Such methods should
+  go to the Relational classes. In particular, startTransaction and
+  commitTransaction should be achieved withRelationalTransaction, eg
+    RelationalFolder::findObject(...){
+      RelationalTransaction transaction( m_db );
+      m_db->fetchRow(...);
+      transaction.commit();
+      ... interpret the row and return the object ...
+    }
+    RelationalTransaction( RelationalDatabase* db ) {
+      db->startTransaction( this );
+    }
+  The RalDatabase, ie the only Ral aware class, is the one that both
+  fetches the object and actually starts the transaction:
+    virtual RelationalDatabase startTransaction( RelationalTransaction t ) = 0;
+    virtual RelationalDatabase fetchRow(...) = 0;
+    RalDatabase::startTransaction( RelationalTransaction t ) {
+      m_session->startTransaction(...);
+      t.setStarted(); // JUST SETS A FLAG...
+    }
+    RalDatabase::fetchRow(...) {
+      m_session->getCursorForTheQuery.....
+    }
+  Forcing the startTransaction method to accept a RelationalTransaction
+  argument binds the startTransaction to a particular transaction instance,
+  so that one is not just tempted to call startTransaction instead
+  of writing "RelationalTransaction t" in the method where t is started.
+  Eventually, note that RDBMS offer the possibility to start transacions
+  with a name, so as to have several concurrent isolated transactions
+  in the same session... passing the argument can just pass the name...
+
+- RalSequence: this should also change as RelationalSequence.
+  Again, RalDatabase should take care of doing the actual insert/delete
+  and so on in the database....
+  I would keep this for quite a while, because I am not sure when
+  RAL will support native sequences, or provide SYSDATE support.
+  Eventually one may think of having all sequences in the same table,
+  each sequence in a separate row, to have fewer tables.
+
+- RalDatabase: this should be the ONLY Ral class (apart from the
+  databasesvc and its factory) that remains.
+  NB: for the moment, the methods it is answeriung are of the form
+  'fetch object from object table with that order'...
+  Eventually, this could be refactored slightly so that it offers
+  much higher level services, eg generic table handling, BUT
+  - we dont want to reinvent RAL
+  - somewhere the specific choices of how to write the queries in SQL 
+    (eg the order of inserting the arguments) must be made,
+    and it should be in the RAL specific class
+
+Other points:
+
+- Should make much more uniform the treatment of the various tables
+  in the code, have a uniform look and feel for defining the column
+  names and column types. We may think of using typedefs for the
+  column types (in the static declarations), so that the code is not
+  forced to make assumptions in setValue/getValue (eg if IValidityKey
+  is declared as long long but the iovSince column is typedefed
+  temporarily as long, the code can be written without knowing
+  that the iovSince is long... it will just force a conversion
+  from IValidityKey to/from iovSince type, whatever that is)
+
+- It may be (??) useful to have a table class, and derive all 
+  tables that are present in our code from that class.
+  But not sure, what would this gain exactly?
+  Maybe we can let RalDatabase handle the base table, and then automatically
+  all derived tables by inheritance?
+  
+- Instead/in any case, it may be useful to split out the various
+  'namespaces' RelationalObjectTable, RelationalFolderTable and so on
+  as real classes RelationalObjectTable, RelationalFolderTable, and so on.
+  Definitely (again!), the look and feel should be more harmonious,
+  eg column definitions for RelationalObjectTable in file
+  RelationalObject.h, or RelationalObjectTable.h, not moving
+  from RalDatabase.h to RelationalDatabase.h and so on...
+
+AOB
+
+- Iterators
+  Eventually these should become real iterators which retrieve rows in bulk,
+  say 1000 by 1000, but not N millions rows all together if this is what is 
+  in the table and in the iteration loop. For this reason it should
+  only have forward iteration. "Freezing" of the database
+  can be achived by only selecting rows whose insertion time,
+  or update time, is less than the time at which the iterator
+  was created....
+  The number of rows fetched in each roundtrip may be set by the user, 
+  but it may also be an internal detail at the beginning.
+  That is to say: the initial implementation of the iterator
+  now returns an ObjectVectorIterator, but eventually
+  it should return something more complex!
+
+- Update time
+  The feature outlined above needs an extra "update time" column
+  that should be changed when for instance the online columns
+  has +infinity transformed into a real time.
+  Note that also in the versioning mode you will have the need
+  for updating the rows (eg "HEAD unti objectId..." column).
diff --git a/RelationalCool/doc/RAL_feedback.txt b/RelationalCool/doc/RAL_feedback.txt
new file mode 100644
index 000000000..6ecbe14ae
--- /dev/null
+++ b/RelationalCool/doc/RAL_feedback.txt
@@ -0,0 +1,332 @@
+// $Id: RAL_feedback.txt,v 1.17 2005-03-18 21:33:44 avalassi Exp $
+==============================================================================
+PENDING PROBLEMS
+==============================================================================
+* Altering table to add foreign key constraint should be possible a posteriori
+
+The functionality needs to be added to IRelationalTableSchemaEditor
+(or should be moved from IEditableTableDescription).
+
+------------------------------------------------------------------------------
+* Need option to switch off /tmp/pool.sql.log
+
+This huge file is extremely useful for debugging.
+But it may decrease performance. Is it possible to switch it off?
+
+------------------------------------------------------------------------------
+* POOL_2_0_1 does not translate correctly unsigned long for MyODBC
+
+In POOL_2_0_0 I got the table created with UNSIGNED BIGINT.
+In POOL_2_0_1 the type is missing and SQL fails.
+
+------------------------------------------------------------------------------
+* Tablespace definition via the API
+
+This is presently only possible via the job options or environment
+variables at the domain level. This should be possible ALSO at the table
+level (and at the session level) through the API.
+
+------------------------------------------------------------------------------
+* Support for insert/select statements
+
+Support 'insert into xxx select * from yyy'.
+Needed by Sven for simpler tagging.
+
+------------------------------------------------------------------------------
+* MySQL plugin internal emulation of bulk retrieval
+
+The MySQL performance should be better understood and optimized.
+If there is a problem with missing bulk operations (so that the choice
+is either to go one by one or retrieve ALL rows in a query), it may be
+useful to improve the emulation by doing the following
+- allow the users to specify a prefetch buffer, eg 10k
+- issue a read only transaction
+- issue the select statement using an order by clause (either the one
+  provided by the user, or one on the PK of the table, or throw an
+  exception if none exists and a prefetch buffer is specified)
+- retrieve the first 10k rows
+- retrieve the next 10k rows and so on
+The read only transaction and order by clause are to be screened behind
+the implementation and ensure that the fetching order is reproducible.
+
+------------------------------------------------------------------------------
+* MySQL API direct implementation
+
+Priority low. May be a useful alternative to ODBC eventually.
+
+------------------------------------------------------------------------------
+* Switch to non-scrollable cursors in the MySQL plugin
+
+Internal change: the default MySQL plugin impleentation should use 
+forward-only cursors. Although this is not guaranteed to cause a major
+performance improvement, this should be tested as it had a major
+impact for Oracle (an dthe MySQL implementation is still relatively slow).
+
+------------------------------------------------------------------------------
+* BLOB support in AttributeList and RAL
+
+The user should be able to store/retrieve as a database BLOB a raw binary 
+memory buffer of a given size.
+
+------------------------------------------------------------------------------
+* Query output type definition
+
+The defineOutput() method should not require that the size of the 
+AttributeListSpecification is the same as the one of the output list 
+as defined with the successive calls to the addToOutput() method.
+It should be enough to specify via defineOutput an AttributeListSpecification
+that is a superset (ie larger) than all columns queried.
+
+------------------------------------------------------------------------------
+* MySQL plugin messaging
+
+In DEBUG mode it should print out the statement that was prepared
+in prepareStatement(), just like for Oracle.
+
+------------------------------------------------------------------------------
+* MySQL plugin support for Windows.
+
+Presently it is only available under Linux.
+
+------------------------------------------------------------------------------
+* NULL value insertion.
+
+Inserting NULL values should be done explicitly.
+
+The best solution would be to modify AttributeList so that each
+attribute in the list has the optionof being NULL/undefined. This 
+could then be used transaparently in RAL for both insertion and retrieval.
+
+------------------------------------------------------------------------------
+* String size specification
+
+The user should be able to specify (and retrieve in the table description) 
+for a string column its maximum size and whether the latter is variable 
+or fixed. 
+
+Additionally, RAL should automatically store strings as CLOBs if they are
+larger than the maximum VARCHAR size.
+
+------------------------------------------------------------------------------
+* MySQL plugin handling of multiply-bound variables
+
+The user should be able to use the same syntax "where xx < :a and :a < yy"
+as for Oracle, with a bind variable appearing twice. RAL should take care
+of binding the variable twice.
+
+------------------------------------------------------------------------------
+* MySQL plugin handling of bind variable names
+
+The user should be able to use the same syntax "where :a<yy" as for Oracle.
+Presently this does not work because this is replaced by "?", interpreting
+this as the binding of a variable called "a<yy" (ie presently one has to 
+write ":a <yy" instead of ":a<yy", taking care to leave a space).
+RAL should interpret as the bind variable name only letters, numbers and 
+the "_" character. Any character other than these (eg +,-,<,>,=) should 
+indicate that the bind variable name is over.
+
+------------------------------------------------------------------------------
+* MySQL plugin handling of bind variable order
+
+Presently the MySQL plugin assumes that the order in which attributes
+are specified in the AttrinbuteList for a WHERE clause is the same as
+the order in which the variables are bound. This should be changed
+as it leads to errors that are difficult to trace and debug and
+may go unnoticed. The MYSQL plugin should behave like Oracle OCI
+and crosscheck names of variables (this would also solve the problem
+of doubly dound variable names).
+
+------------------------------------------------------------------------------
+* SQL_TRACE
+
+The user should be able to enable SQL_TRACE in a session.
+For Oracle, this should issue
+  alter session set events '10046 trace name context forever, level 12'
+Ideally this should be a session property (method of IRelationalSession).
+Initially, this can be a domain property, set via the seal opts or
+one of the 'hidden' environment variables, eg POOL_ORA_SQL_TRACE.
+
+------------------------------------------------------------------------------
+* Support for SYSDATE date computed by the server
+
+1. The user should be able to retrieve into C++ the date on the server.
+There should be a simple method to retrieve only the date. This would issue: 
+  Oracle (systimestamp has higher precision - microseconds instead of seconds)
+    select sysdate from dual;
+    select systimestamp from dual;
+    select current_timestamp from dual;
+  MySQL
+    select current_timestamp;
+The ANSI version current_timestamp works for both but gives different results.
+For instance, add a method serverCurrentTimestamp() in the IRelationalSession?
+Priority: high.
+
+2. The user should be able to retrieve the date when retrieving data 
+from any table. This would issue for instance
+  Oracle
+    select [user columns], current_timestamp from [user table];
+  MySQL
+    select [user columns], current_timestamp from [user table];
+For instance, define a reserved keyword CURRENT_TIMESTAMP which can be used
+in the IRelationalQuery::addToOutputList() method, without executing the
+cross-check whether this exists in the table because it does not?
+Priority: lower (if you can at least get the serverCurrentTimestamp
+into C++, you can always do this in two steps).
+
+3. The user should be able to insert the date into a column of a table.
+This would issue for instance
+    insert [user values], current_timestamp into ...;
+Priority: lower (if you can at least get the serverCurrentTimestamp
+into C++, you can always do this in two steps).
+
+PS: actually the priority may be a bit higher.
+We need to COMPARE date values, presently we are comparing strings...
+
+Note: presently COOL is working around this problem by using the UPDATE
+clause, the only place where free SQL can be used: for instance,
+- insert a dummy value into a table
+- update the table with the system date
+- read it back from the table to know what is the time on the server
+
+------------------------------------------------------------------------------
+* Support for seal::Time and native Oracle DATE
+
+The user should be able to create table with DATE columns.
+If possible, seal::Time should also be supported in 
+AttributeList and mapped to DATE SQL types by default.
+
+------------------------------------------------------------------------------
+* ANALYZE TABLE
+
+The user should be able to analyze a table from the C++.
+Although this is an administration level operation, it is essential 
+for fast tests where one wants to create a table, insert data and 
+select from the table at the same time. The table must be analyzed 
+after data have been inserted and before issuing the select query.
+
+For instance, add a method analyzeTable to IRelationalTable?
+This would issue
+  analyze table xxx compute statistics (Oracle)
+  analyze table (MySQL)
+
+------------------------------------------------------------------------------
+* ORA-01466
+
+Oracle readonly transaction uses READ ONLY rather than SERIALIZABLE.
+If a table is created and immediately queried, this causes an ORA-01466 error.
+This was reported to Oracle, but their answer is that this is a feature
+that needs to be better documented, not a bug that will be fixed,
+and the workaround is to wait for a few seconds.
+
+Given this situation, I would suggest the following workaround to apply 
+within RAL, which would at least prevent the problem from happening within
+the same active session: an active OracleSession instance should keep
+track of the last date at which it issued any kind of DDL statements.
+Whenever a read-only transaction is issued, RAL itself should check 
+whether at least N seconds have elapsed since the last DDL: if not,
+
+------------------------------------------------------------------------------
+* Read only transactions (more generally)
+
+We should review whether Oracle READ ONLY transactions are really
+what we need for "read only" mode. SERIALIZABLE transactions look 
+safer and better than readonly, but they may block
+concurrent users from running at the same time.
+
+------------------------------------------------------------------------------
+* AttributeList copy constructor and assignment operator
+
+AttributeLists behave differently depending on whether they were built
+from a reference or a boost shared pointer specification.
+The assignment operator is reliable only in the second case. 
+The copy constructor gives problems for both.
+This was notified to Kuba, Ioannis and Rado.
+
+------------------------------------------------------------------------------
+* Multi-threading problems with MySQL/ODBC
+
+I had to disable the -pthread switch on RelationalCool because 
+the application hangs (only for MySQL). The circumstances are
+difficult to explain exactly: it happens in RalSequence when
+I try to drop a table and then recreate it again. It does not 
+happen if the table had been dropped using TOra.
+
+The problem had already been mentioned to Rado long ago.
+Has this been solved in the meantime (by RAL or by the next ODBC driver)?
+[In COOL a workaround is presently used in RelationalCoool/BuildFile]
+
+------------------------------------------------------------------------------
+* Problem inserting rows where all values are NULL
+
+Bug: when inserting rows where all values are null, this is translated 
+into non-valid SQL:
+  INSERT INTO "CONDDB_TEST"."COOLTEST_FOLDERS_SEQ" () VALUES ();
+Maybe this has already been fixed?
+
+------------------------------------------------------------------------------
+* Partitioning and local indexes
+
+The user should be able to specify that a table should be created
+as partitioned and indexese are local. Priority: low.
+
+==============================================================================
+PROBLEMS SOLVED
+==============================================================================
+* Support for 64-bit integer
+
+This type could not be defined in an AttributeList or stored using RAL.
+
+------------------------------------------------------------------------------
+* Set clause syntax for MySQL/ODBC in IRelationalTableDataEditor::updateRows
+
+The Oracle plugin required ":bindvariable", MySQL/ODBC required "?".
+Now both use ":bindvariable".
+
+------------------------------------------------------------------------------
+* Feature with columnNamesAndTypes()
+
+If you insert a column via insertColumn( columnName, typeName )
+and then retrieve columnNamesAndTypes(), the types are not guaranteed 
+to be the same. For instance, insertColumn for "unsigned long" will 
+return an "unsigned long" on MySQL (as the native type can be mapped), 
+while it will return "long" on Oracle because this maps to NUMBER(38).
+This causes problems if you try to then insert an attribute value via
+setValue<type> into the attribute list, pool::attribute_bad_type
+will be thrown.
+
+=> Solution: when filling in the table, do not rely on columnNamesAndTypes():
+instead, keep a local copy of the C++ mapping in the tables or in the
+C++ code! This solves the setValue() problem.
+
+------------------------------------------------------------------------------
+* Feature with IRelationalCursor::currentRow()
+
+Also in this case the same problem appears: the attribute list returned 
+has a specification that is read from the table description, ie exactly
+the same returned by columnNamesAndTypes(). If the previous problem
+appeared for setValue(), this appears for getValue(): it is a priory
+impossible to know which C++ should be used for getValue(). The only 
+safe one is string, but this is not satisfactory!
+
+=> Solution: you must use defineOutput() to specify the required format!
+
+------------------------------------------------------------------------------
+* NULL values inserted in MySQL third column (POOL_1_8_0)
+
+This is fixed in the HEAD of ODBCAccess since december 3.
+There was a bug with the use of STL vectors: push_back changes
+the internal memory addresses of all vector elements.
+
+------------------------------------------------------------------------------
+* MyODBC bulk inserter inserts \0-terminated strings
+
+Check by selecting 
+  select s, length(s) from COOLTEST_F0001_IOVS;
+
+These two queries gave different results (and only the second works fine!):
+  select * from COOLTEST_F0001_IOVS where s='Object 1'; 
+  select * from COOLTEST_F0001_IOVS where s='Object 1\0'; 
+Fixed in POOL_2_0_2.
+
+------------------------------------------------------------------------------
+
diff --git a/RelationalCool/doc/README.CLOB b/RelationalCool/doc/README.CLOB
new file mode 100644
index 000000000..70dfa80c8
--- /dev/null
+++ b/RelationalCool/doc/README.CLOB
@@ -0,0 +1,215 @@
+Various problems with CLOB. Let's start with the most important.
+
+-----------------------------------------------------------------------------
+Problem #1: segmentation fault in reading back CLOB from Oracle (08.04.2005)
+-----------------------------------------------------------------------------
+
+The problem initially appeared in COOL after changing the folder payload spec
+column to CLOB. In Oracle, I got a segmentation fault when reading from this table.
+
+I initially thought this was because I was mixing CLOB and non-CLOB columns
+and thought of testing this. So I downloaded the standard clobInputOutput.cpp
+test from the POOL OracleAccess test suite. However I realised that even the 
+standard POOL test failed. I went on to investigate this.
+
+I thought that this could be an environment problem (the COOL environment mixes 
+some debug and non-debug libraries, it ALWAYS uses POOL in debug mode to avoid
+segmentation faults discovered elsewhere in the code).
+I downloaded POOL into a separate project area than COOL.
+Using the POOL standard environment everything works fine:
+the test executes successfully in non-debug mode.
+
+  cd ~/myLCG/
+  rm -rf POOL_2_0_3
+  setenv SCRAM_ARCH rh73_gcc323
+  scram project POOL POOL_2_0_3
+  cd POOL_2_0_3/
+  setenv CVSROOT :kserver:pool.cvs.cern.ch:/cvs/POOL
+  cvs co -r POOL_2_0_3 OracleAccess
+  cd OracleAccess/tests/CLOBInputOutput/
+  mv clobInputOutput.cpp clobInputOutput.cpp.OLD
+  mv authentication.xml authentication.xml.OLD
+  cp ~/myLCG/COOL_HEAD/src/RelationalCool/tests/ClobIO/clobInputOutput.cpp . 
+  cp ~/myLCG/COOL_HEAD/src/RelationalCool/tests/ClobIO/authentication.xml .
+  scram b
+  which unitTest_OracleAccess_CLOBInputOutput
+  unitTest_OracleAccess_CLOBInputOutput
+
+I try again using the debug version. This one causes a segmentation fault! 
+The POOL debug library causes a segmentation fault when using CLOBs in Oracle.
+[Note: scram setup is probably not needed, it does nothing.]
+
+  setenv SCRAM_ARCH rh73_gcc323_dbg
+  cd ~/myLCG/POOL_2_0_3/src/OracleAccess/tests/CLOBInputOutput > 
+  scram setup
+  scram b
+  eval `scram runtime -csh`
+  which unitTest_OracleAccess_CLOBInputOutput
+  unitTest_OracleAccess_CLOBInputOutput
+
+Note that my own modifications to the test only change the debug level and the schema.
+I need to change the schema because the POOL default test uses an unknown database.
+I tested in any case that changing the message level from Info to Debug is not
+what causes the problem. The segmentation fault appears also if the level is Info.
+
+Changes between the POOL standard test and my test:
+==> diff clobInputOutput.cpp clobInputOutput.cpp.OLD 
+179,180c179
+<     //pool::POOLContext::setMessageVerbosityLevel( seal::Msg::Info );
+<     pool::POOLContext::setMessageVerbosityLevel( seal::Msg::Verbose );
+---
+>     pool::POOLContext::setMessageVerbosityLevel( seal::Msg::Info );
+183,184c182
+<     // std::string connectionString = "oracle://test10g/ioannis";
+<     std::string connectionString = "oracle://devdb/conddb_test";
+---
+>     std::string connectionString = "oracle://test10g/ioannis";
+==> diff authentication.xml authentication.xml.OLD
+14,17d13
+< <connection name="oracle://devdb/conddb_test">
+<   <parameter name="user" value="conddb_test" />
+<   <parameter name="password" value="lcg" />
+< </connection>
+
+Output from the program (within gdb):
+==> gdb unitTest_OracleAccess_CLOBInputOutput
+GNU gdb Red Hat Linux (5.2-2)
+Copyright 2002 Free Software Foundation, Inc.
+GDB is free software, covered by the GNU General Public License, and you are
+welcome to change it and/or distribute copies of it under certain conditions.
+Type "show copying" to see the conditions.
+There is absolutely no warranty for GDB.  Type "show warranty" for details.
+This GDB was configured as "i386-redhat-linux"...
+(gdb) r
+Starting program: /afs/cern.ch/user/a/avalassi/myLCG/POOL_2_0_3/rh73_gcc323_dbg/tests/bin/unitTest_OracleAccess_CLOBInputOutput 
+LOCALRT: /afs/cern.ch/user/a/avalassi/myLCG/POOL_2_0_3
+ORACLE_HOME not set
+[New Thread 1024 (LWP 21112)]
+POOL/Services/RelationalService     Info Found plugin for RDBMS technology "mysql" with implementation "odbc"
+POOL/Services/RelationalService     Info Found plugin for RDBMS technology "oracle" with native implementation
+POOL/Services/RelationalService     Info Found plugin for RDBMS technology "sqlite" with native implementation
+POOL/Services/RelationalService     Info Default implementation for RDBMS technology "mysql" is "odbc"
+POOL/Services/RelationalService     Info Default implementation for RDBMS technology "oracle" is native
+POOL/Services/RelationalService     Info Default implementation for RDBMS technology "sqlite" is native
+Connecting...
+POOL/RelationalPlugins/oracle     Info Connected to a server running Oracle version 9.2.0.6.0
+Starting a new transaction
+POOL/RelationalPlugins/oracle    Debug Prepared statement : "SELECT TABLE_NAME FROM ALL_TABLES WHERE OWNER = 'CONDDB_TEST'"
+Deleting table "DataTable"
+POOL/RelationalPlugins/oracle    Debug Prepared statement : "DROP TABLE "CONDDB_TEST"."DataTable""
+Creating table "DataTable"
+POOL/RelationalPlugins/oracle    Debug Prepared statement : "CREATE TABLE "CONDDB_TEST"."DataTable" ( "id" NUMBER(10), "data" CLOB )"
+Adding a row into the table
+POOL/RelationalPlugins/oracle    Debug Prepared statement : "INSERT INTO "CONDDB_TEST"."DataTable" ("id","data") VALUES (:"id",:"data")"
+Adding a second row into the table
+POOL/RelationalPlugins/oracle    Debug Prepared statement : "INSERT INTO "CONDDB_TEST"."DataTable" ("id","data") VALUES (:"id",:"data")"
+Committing...
+Disconnecting...
+Connecting...
+POOL/RelationalPlugins/oracle     Info Connected to a server running Oracle version 9.2.0.6.0
+Starting a new transaction
+POOL/RelationalPlugins/oracle    Debug Prepared statement : "SELECT TABLE_NAME FROM ALL_TABLES WHERE OWNER = 'CONDDB_TEST'"
+POOL/RelationalPlugins/oracle    Debug Prepared statement : "SELECT "id", "data" FROM "CONDDB_TEST"."DataTable""
+Program received signal SIGSEGV, Segmentation fault.
+[Switching to Thread 1024 (LWP 20859)]
+0x407ef2cf in kpccld2i ()
+   from /afs/cern.ch/sw/lcg/external/oracle/10.1.0.3-1/rh73_gcc323/lib/libclntsh.so.10.1
+
+Stack trace from gdb at this point:
+==> (gdb) bt
+#0  0x407ef2cf in kpccld2i ()
+   from /afs/cern.ch/sw/lcg/external/oracle/10.1.0.3-1/rh73_gcc323/lib/libclntsh.so.10.1
+#1  0x407da72b in ttccfpg ()
+   from /afs/cern.ch/sw/lcg/external/oracle/10.1.0.3-1/rh73_gcc323/lib/libclntsh.so.10.1
+#2  0x407d95b6 in ttcfour ()
+   from /afs/cern.ch/sw/lcg/external/oracle/10.1.0.3-1/rh73_gcc323/lib/libclntsh.so.10.1
+#3  0x407ceab7 in ttcdrv ()
+   from /afs/cern.ch/sw/lcg/external/oracle/10.1.0.3-1/rh73_gcc323/lib/libclntsh.so.10.1
+#4  0x4066590d in nioqwa ()
+   from /afs/cern.ch/sw/lcg/external/oracle/10.1.0.3-1/rh73_gcc323/lib/libclntsh.so.10.1
+#5  0x404e1366 in upirtrc ()
+   from /afs/cern.ch/sw/lcg/external/oracle/10.1.0.3-1/rh73_gcc323/lib/libclntsh.so.10.1
+#6  0x4047801d in kpurcsc ()
+   from /afs/cern.ch/sw/lcg/external/oracle/10.1.0.3-1/rh73_gcc323/lib/libclntsh.so.10.1
+#7  0x405824a8 in kpufch0 ()
+   from /afs/cern.ch/sw/lcg/external/oracle/10.1.0.3-1/rh73_gcc323/lib/libclntsh.so.10.1
+#8  0x405832fb in kpufch ()
+   from /afs/cern.ch/sw/lcg/external/oracle/10.1.0.3-1/rh73_gcc323/lib/libclntsh.so.10.1
+#9  0x404ab067 in OCIStmtFetch2 ()
+   from /afs/cern.ch/sw/lcg/external/oracle/10.1.0.3-1/rh73_gcc323/lib/libclntsh.so.10.1
+#10 0x400b57fc in pool::OracleAccess::OracleStatement::fetchNext() (this=0x80f4878)
+    at /afs/cern.ch/sw/lcg/app/releases/POOL/POOL_2_0_3/src/OracleAccess/src/OracleStatement.cpp:635
+#11 0x4008e8be in pool::OracleAccess::OracleCursor::next() (this=0x8082af8)
+    at /afs/cern.ch/sw/lcg/app/releases/POOL/POOL_2_0_3/src/OracleAccess/src/OracleCursor.cpp:117
+#12 0x0804f281 in readClob(std::string const&) (connectionString=@0xbfffc0c0)
+    at /afs/cern.ch/user/a/avalassi/myLCG/POOL_2_0_3/src/OracleAccess/tests/CLOBInputOutput/clobInputOutput.cpp:140
+#13 0x0804faef in main ()
+    at /afs/cern.ch/user/a/avalassi/myLCG/POOL_2_0_3/src/OracleAccess/tests/CLOBInputOutput/clobInputOutput.cpp:189
+#14 0x42017589 in __libc_start_main () from /lib/i686/libc.so.6
+
+-----------------------------------------------------------------------------
+Problem #2: Feedback about the RAL API (07.04.2005)
+-----------------------------------------------------------------------------
+
+The present RAL interface has some limitations in handling tables where 
+columns with the same C++ type are stored using different SQL types.
+Presently non-default SQL types can only be set at the session level
+using the type converter, not on individual table columns.
+The present workaround is that columns must be individually altered, or dropped
+and recreated using a new SQL type mapping temporarily set at the session level.
+A new RAL API is being designed to overcome this problem.
+
+Feedback for the new RAL design:
+1. The RAL interface should allow to specify some kind of SQL-type 'hint'
+for individual columns already when creating the table.
+2. The "size" of the SQL type should be a part of the hint. For strings, for 
+instance, RAL should automatically decide that 255-size strings can use VARCHAR2(255)
+on Oracle and VARCHAR(255) BINARY on MySQL,  but 4000-size strings can use
+VARCHAR2(4000) on Oracle and need TEXT on MySQL.
+3. The "size" alone is not enough. Strings can be mapped to DATE, for instance.
+The RAL interface for creating a table should allow users to specify that a 
+string is stored as DATE. reserving a special size value for this seems awkward.
+Other examples may include CHAR vs VARCHAR2, for instance, with the same size.
+4. The "size" should not only be used in creating the table, but also in inserting 
+(and reading back?) data: for instance, if the type is specified as 4000-size 
+maximum but is stored as TEXT in MySQL, a 5000-size string could be stored in MySQL. 
+RAL should throw an exception. This should make sure that data can safely be 
+transferred to Oracle, where VARCHAR2(4000) would be used. This also means that
+an SQL-type hint alone is also not enough (one may indicate TEXT or CLOB but may
+also want to indicate a maximum size).
+5. The "size" (and eventually maybe also the DATEness or CHAR/VARCHAR) of 
+each attribute is presently being added in COOL to a wrapper for the POOL
+AttributeListSpecification class. It may be useful to review this class
+so that an extended AttributeListSpecification with size or other SQL-related
+information can be derived from the POOL AttributeListSpecification
+and included in POOL. Or maybe this information can simply be added to the
+new POOL AttributeListSpecification.
+
+-----------------------------------------------------------------------------
+Problem #3: ALTER TABLE constraints in Oracle (07.04.2005)
+-----------------------------------------------------------------------------
+
+The initial implementation I tried to change the payload specification
+column from the RAL default to CLOB was using the ALTER TABLE statement
+(via the RAL modifyColumn interface).
+
+However, changing a VARCHAR to CLOB is not possible (ORA-22858).
+Similarly, changing a CLOB to VARCHAR to CLOB is also not possible (ORA-22859).
+
+Solution: the COOL implementation now drops and recreates columns.
+In order not to change the column order, all columns following the first 
+column whose SQL type needs to be changed are also dropped and recreated.
+
+-----------------------------------------------------------------------------
+Problem #4: modifying column types did not seem to work in MySQL (07.04.2005)
+-----------------------------------------------------------------------------
+
+Both the alter table and the drop/recreate column solution seemed to give 
+problems also in MySQL. Using DESC table in TOra, the old schema was printed.
+
+Solution: thanks to Rado, I found out that the reason is that TOra has a schema 
+cache that it does not refresh. One should use the TOra schema browser for the
+specified table to make sure the table schema is refreshed. Another possibility
+is to use the SHOW CREATE TABLE statement in MySQL, which is guaranteed
+to print out the full correct schema of a table.
+
diff --git a/RelationalCool/doc/README.gmt b/RelationalCool/doc/README.gmt
new file mode 100644
index 000000000..283346141
--- /dev/null
+++ b/RelationalCool/doc/README.gmt
@@ -0,0 +1,44 @@
+Brief summary of the problem with GMT times which caused Windows 
+unit tests to fail on the first attempted release of COOL_1-2_0.
+
+An IOV is stored with a string '13:38 GMT' in the table.
+The problem is that tagAsOfDate tries to use the string '12:38 GMT'.
+
+Let's look at what happens at retrieval after insertion.
+1. findObject calls findSingleVersionObject where 
+   - fetchObjectTableRowAtTimeSV retrieves the string in an AttributeList
+   - RelationalObjectTable::decodeRow transforms AttributeList into IObject
+2. RelationalObjectTable::decodeRow
+   - transforms the string into a seal::Time using stringToTime
+   - calls the RelationalObject constructor with a seal::Time argument
+3. RelationalObject constructor
+   - transforms seal::Time into nanosec (no 'local' argument needed)
+   - calls seal::Time constructor from nanosec argument (no 'local' argument)
+   - stores the date as a seal::Time
+4. RelationalObject::insertionTime()
+   - returns a reference to the seal::Time
+5. tag( asOfDate )
+   - takes a seal::Time argument
+     (prints it out to screen using timeToString)
+   - calls fetchObjectTableRowsForTagging with the same seal::Time argument
+     (prints it out to screen using timeToString)
+6. fetchObjectTableRowsForTagging 
+   - binds the argument as string using timeToString
+
+In summary, this is what happens:
+  "13:38 GMT" (stored in IOV)
+  -> convert to seal::Time by stringToTime in RelationalObjectTable::decodeRow
+  -> convert to int64 by ns() in RelationalObject constructor
+  -> convert to seal::Time by constructor in RelationalObject constructor
+  -> convert to string by timeToString in fetchObjectTableRowsForTagging 
+
+The problem must be either
+- in seal::Time::ns() and seal::Time( ns )
+- in timeToString and stringToTime
+
+PS The bug was identified in the seal::Time constructor.
+When converting using GMT times, tm_isdst should be set to 0.
+Note that gmtime(timegm(tm)) is always equal to tm on Windows
+only if isdst=0: if isdst=+1/-1, a one hour difference is observed 
+for instance in January/April. Note also that calling timegm
+alters the value of the original tm.
diff --git a/RelationalCool/doc/README.standalone b/RelationalCool/doc/README.standalone
new file mode 100644
index 000000000..e0c4b84f3
--- /dev/null
+++ b/RelationalCool/doc/README.standalone
@@ -0,0 +1,221 @@
+------------------------------------------------
+Standalone installation on Windows (20.04.2005)
+------------------------------------------------
+
+Login a bash shell under cywgin.
+
+  bash
+
+Follow the instructions in
+
+  http://spi.cern.ch/workbook/howto/HowTo-Install-locally-lcg-software.html
+
+Create a directory /opt/sw/lcg in cygwin.
+[In my case, first do 'ln -sf /cygdrive/l /opt' to create it on the L: disk]
+
+  mkdir -p /opt/sw/lcg
+
+Download the installation script
+Change the python version from 2.2 to 2.4
+
+  cd /opt/sw
+  wget http://service-spi.web.cern.ch/service-spi/external/distribution//lcg-installation-manager.py
+  cat lcg-installation-manager.py | sed 's/python2.2/python2.4/' > lcg-installation-manager.py.NEW
+  \mv lcg-installation-manager.py.NEW lcg-installation-manager.py
+  chmod +x ./lcg-installation-manager.py 
+
+Download the required packages
+
+  ./lcg-installation-manager.py --project=POOL_2_0_4 \
+     --arch=win32_vc71_dbg --prefix=/opt/sw/lcg download
+
+This does not work! 
+
+  fetching file: 
+    /opt/sw/lcg/external/distribution//POOL_2_0_4__LCG_win32_vc71_dbg.info
+  ERROR: could not download the file : POOL_2_0_4__LCG_win32_vc71_dbg.info
+  fetching file: /opt/sw/lcg/external/distribution//POOL_2_0_4.scram_output
+  ERROR: could not download the file : POOL_2_0_4.scram_output
+  Most probably POOL_2_0_4  is not available in the LCG software repository...
+  Please report this to LCG SPI
+
+Andreas confirms that there are some known problems on Windows.
+The installation via the python script does not work on Linux,
+but other /afs/cern.ch/sw/lcg/app/spi/tools/latest/scripts/
+solutions are possible, for instance one can look at
+/afs/cern.ch/sw/lcg/app/spi/tools/latest/scripts/lcg-mirror-externals.bat
+
+...to be continued...
+
+------------------------------------------------
+Standalone installation on Windows (21.06.2005)
+------------------------------------------------
+
+Tried again the same as above, it does not work again.
+
+Try using the lcg-mirror-externals.bat script.
+I tried by myself but failed miserably.
+
+Finally found some useful doc from SEAL on
+http://seal.web.cern.ch/seal/snapshot/workbook/howtorelease.html
+
+1. Add environment variable AFS with value \\afs in MyComputer->Properties.
+
+2. Create directory  "C:\Documents and Settings\avalassi\mycmt"
+as this is needed by CMT.
+
+3. Copied lcg-mirror-externals.bat and lcg-mirror-externals.py
+from /afs/cern.ch/sw/lcg/app/spi/tools/latest/scripts/
+to L:\sw and made them more verbose to debug them.
+
+4. From a command prompt in L:\sw I execute
+  lcg-mirror-externals -v 35 -p win32_vc71_dbg -o L:\sw\lcg\external
+
+But this only copies the LCGCMT package...
+
+Andreas proposed
+/afs/cern.ch/user/p/pfeiffer/public/scripts/syncWinTree.py
+but in the meantime I had done my own solution (see below).
+
+Removed AFS variable from MyComputer at the end.
+
+------------------------------------------------
+Standalone installation on Windows (21.06.2005)
+------------------------------------------------
+
+Developed my own script.
+This creates a script on Windows,
+executed on Linux to create a tar file of AFS,
+the tar is then shipped back to Windows.
+This is to avoid file copying over AFS on Windows.
+
+I also use a little script to download POOL locally,
+rather than using CVS from Windows directly.
+There seems to be a problem with CVS (or the SCRAM
+installer using CVS) on Windows, it gets stuck.
+Note also that I had to do (like on Mac!)
+  cp /afs/cern.ch/user/a/avalassi/.cvspass /tmp/79125CVSmodule/.cvspass
+(where id gives 79125 for avalassi on cygwin), but this was not enough.
+
+1. On Windows (cygwin) ~ 1 minute
+
+From the standard COOL_HEAD using SITENAME=CERN:
+
+cd ~/myLCG/COOL_HEAD/config
+coolMirrorExternals.csh
+
+2. On lxb0675 ~ 6 + 2 minutes
+
+cd ~/myLCG/COOL_HEAD/config
+./coolMirrorExternals-win32_vc71_dbg.csh
+scp /opt/avalassi/coolKit-win32_vc71_dbg/sw/lcg-win32_vc71_dbg.tar \
+  avalassi@pcitdb38:/opt/sw
+
+(NB The archive is ~950 MB if it includes POOL and ~590 MB if it does not)
+
+3. On Windows (cygwin) ~ 4 minutes
+
+date
+cd /opt/sw
+rm -rf /opt/sw/lcg
+tar -xvf lcg-win32_vc71_dbg.tar > lcg-win32_vc71_dbg-tar.txt
+date
+
+4. On lxb0675 ~ 2 minutes
+
+cd ~/myLCG/COOL_HEAD/config
+./coolInstallPool.csh
+scp /opt/avalassi/poolKit/sw/lcg-POOL_2_1_0.tar \
+  avalassi@pcitdb38:/opt/sw
+
+(NB The archive is ~3 MB)
+
+5. On Windows (cygwin) ~ few seconds
+
+cd /opt/sw
+rm -rf /opt/sw/lcg/app/releases/POOL
+tar -xvf lcg-POOL_2_1_0.tar > lcg-POOL_2_1_0-tar.txt
+
+6. On Windows (cygwin)
+
+Stop the AFS service and start a new cygwin window.
+
+cd /opt/sw/lcg/app/releases/POOL/POOL_2_1_0/
+export SITENAME=STANDALONE
+export PATH=/opt/sw/lcg/app/spi/scram:$PATH
+scram setup
+
+cd /opt/sw/lcg/app/releases/POOL/POOL_2_1_0/src
+export SITENAME=STANDALONE
+export PATH=/opt/sw/lcg/app/spi/scram:$PATH
+date
+scram b
+date
+
+This is in any case rather slow (~35-40 minutes),
+but at least it does work standalone and is faster than with AFS.
+The CPU consumption is always around ~50% spread across two CPUs (25% each).
+The largest CPU consupmption comes from python (peaks of 40% on one CPU).
+Also perl shows up but never with as high CPU peaks as python.
+One problem may be that there is not a single python process,
+but rather very many python processes that start and finish.
+With AFS, a lot of CPU was eaten up by the AFS daemons.
+
+-----------------------------------------------------
+Standalone COOL installation on Windows (21.06.2005)
+-----------------------------------------------------
+
+1. On lxb0675
+
+This uses a siple private script to create a tar of the COOL_HEAD.
+
+cd ~/myLCG
+./installCoolHead-local.csh
+scp ~/myLCG/coolKit/COOL_HEAD.tar avalassi@pcitdb38:/opt
+
+2. On Windows (cygwin)
+
+cd /opt/
+rm -rf /opt/COOL_HEAD
+tar -xvf COOL_HEAD.tar > COOL_HEAD-tar.txt
+
+3. On Windows (cygwin)
+
+Stop the AFS service and start a new cygwin window.
+
+cd /opt/COOL_HEAD
+export SITENAME=STANDALONE
+export PATH=/opt/sw/lcg/app/spi/scram:$PATH
+scram setup
+
+cd /opt/COOL_HEAD/src
+export SITENAME=STANDALONE
+export PATH=/opt/sw/lcg/app/spi/scram:$PATH
+date
+scram b
+date
+
+This is a factor ~5 faster than with AFS,
+but it is still very slow (~50 minutes!).
+Definitely scram is extremely slow (especially) on Windows.
+With the CMT VisualStudio plugin things were MUCH faster.
+Note that perl shows up more than for POOL,
+but still python seems to be the bottleneck.
+
+NB: HOW TO IMPROVE?
+It looks like python is the bottleneck (but maybe not the only one -
+perl also shows up significantly in no-op mode on a prebuilt COOL).
+1. One idea could be to try to precompile all .py files from the config
+area into .pyc files (but should Python not compile them automatically?).
+The only file that appears to be compiled as .pyc is unixToWinPath.py,
+however other files are used too (I tried to remove all .py and execute
+"scram b", the first errors were from other py modules missing.
+However I gave a first quick try at this and it does not seem to help
+(try also 'python unixToWinPath.py xxx' or 'python unixToWinPath.pyc xxx',
+they are both very slow and not very different from each other).
+2. Another possibility is to get rid of python and use instead precompiled 
+C++ programs or even just bash scripts inside the makefile fragments
+(for unixToWinPath.py this should be rather easy).
+3. However also perl and possibly other problems may show up.
+It may be useful to do a no-o dry run of scram and measure where 
+the time is actually spent.
diff --git a/RelationalCool/doc/TODO.txt b/RelationalCool/doc/TODO.txt
new file mode 100644
index 000000000..ff83a6407
--- /dev/null
+++ b/RelationalCool/doc/TODO.txt
@@ -0,0 +1,182 @@
+Dec 2004
+
+* Tablespaces
+- Set default data and index tablespaces for all data
+
+Dec 2004
+
+* Folder sets, folders, HVS nodes
+- Main/Only priority: method to list children of a specific folder set,
+  possibly with recursion, possibly distibguish folder and folder sets within
+- Add various list methods to HvsNode, inherited by folderset:
+  listChildren, listLeafChildren, listBranchChildren.
+  Or have a flag to show only leaves/branches?
+  Flag for recursive listing (or # nested directories to show)?
+- Use protected inheritance for RelationalFolder : HvsNode?
+  For instance can be useful to just rename listLeafChildren 
+  as listFolders...
+- Add method getRootFolderSet() to IDatabase: note that listFolders
+  can then be delegated to this alone
+- I would not delegate create/get folder to folder sets though:
+  use only full paths, no relative paths? Or allow relative paths
+  to make renaming eventually easier?
+- CreateFolder and createFolderSet have a lot in common,
+  can be factored out
+- Better definition of Folder and FolderSet classes: need a separate
+  IFolderSet or use IFolder to indicate both? I would definitely
+  use two separate classes, folder handles IOVs, while folderset
+  handles folders within itself.
+
+------------------------------------------------------------------------------
+Nov 2004
+
+* DatabaseId
+- Remove, replace by string in the createDatabase signature
+
+* RalDatabaseId
+- Move to public API of RelationalCool?
+- Add constructor from parameters?
+- Add url() method to return a string?
+- Add automatic conversion to a string 
+  so that it can be passed to createDatabase?
+
+* Relational vs Ral or MySQL
+- Prefix "Relational" for classes that may be both Ral or MySQL?
+- Four levels of inheritance (IDatabase, Database, RelationalDatabase,
+  RalDatabase/MySQLDatabase)?
+  --> sas: why Database?
+
+* Group typedefs in types.h?
++ Or rather keep in separate files? eg XXXPtr in XXX.h
+  --> added types.h. Not intended to be manually included by API clients
+      (documented accordingly)
+
+* Define ValidityKey as seal::LongLong typedef
++ sas: done.
+
+* Add schema version to the management table
+
+* IOV table schema
+- system-inserted IOV id
++ done. channelID, since, until, payload
+- system-inserted insertion time
+
+* Define base Exception class in CoolKernel
++ sas: done. derived from seal::Exception
++ sas: done. derive RelationalException from cool::Exception
+
+* Clean up the hierarchy and loading of libraries
+- RAL hierarchy
+  0. Top: IRelationalService -> one singleton (in RelationalAccess) 
+       "POOL/Services/RelationalService" - RelationalService
+    1. IRelationalDomain -> three singletons (in three packages)
+         "POOL/RelationalPlugins/mysql/odbc" - MySqlODBCDomain
+         "POOL/RelationalPlugins/oracle" - OracleDomain
+         "POOL/RelationalPlugins/sqlite" - SQLiteDomain        
+     2. IRelationalSession -> one instance per open session
+- in RAL a string only specifies where the data is (different drivers
+  can exist for MySQL, but the data is always the same, a table with
+  a given name in MySQL)... for COOL, different implementations may 
+  imply completely different schemas for the data, it is not the same
+  ==> we should make the names specify the plugin (as Sven was saying)
+  ==> one possibility: use "ral::oracle::", "ral::mysql::", "mysql::"... 
+      (in this example, ral and mysql would be two plugins)
+- for comparison: RAL technology-dependent switch is in RelationalService.cpp
+  (technology name is directly translated to plugin name by adding a suffix,
+   e.g. 'oracle' -> IRelationalDomain 'POOL/RelationalPlugins/oracle' )
+
+* PROPOSAL
+  0. Top: IDatabaseService -> one singleton (in CoolKernel or CoolBase) 
+       "COOL/Services/DatabaseService" - DatabaseService
+    1. IDatabaseService -> one singleton per implementation
+         "COOL/KernelServicePlugins/ral" - RalDatabaseService
+         "COOL/KernelServicePlugins/mysql" - MySQLDatabaseService
+     2. IDatabase -> one instance per open session (i.e. per open database)
+
+* Centralise all SQL implementation in the database, nothing in the folders
+- Session is only needed in the database
+
+* Replace IDatabase boost pointers by references
+- Place ownership of the instances in the RalDatabaseSvc
+
+* Beware of catch 22 in schema upgrades (sas, 2004-12-10)
+- I've just encountered the following situation:
+In preparation of the foldersets, the folder table schema changed. Now, when 
+dropDatabase executes, it uses the folder table to get the object table names.
+Due to the schema change, this access failed and the dropDatabase chokes and
+returns without dropping any tables. Admittedly, this is a very special case
+typically encountered during the early development stages, but we've seen the 
+problem of dropDatabase not working successfully because it could not delete a
+table before. It would be useful in general to make dropDatabase a bit more
+robust, i.e. not dependent on obtaining all the management information to
+do its job.
+
+I think dropDatabase should at least assert that the management tables are
+dropped, so that a subsequent createDatabase is successful(*). It should report 
+if it cannot delete the object tables (e.g. due to a read failure in the folder
+table) to make the user aware that there are data tables left.
+
+Folder creation then has to be looked at to decide what to do if a new object
+table name clashes with an existing one. The options are: drop and recreate
+the table or try with the next ID in the sequence. I think we should aim for
+option 2.
+
+(*) This is what the drop database test currently checks for.
+
+
+* The seal configuration file env variable does not seem to work. The msg
+output level is only taken from the file it is in the current working
+directory.
+
+
+* [sas 2004-12-13: I wrote the following on the train before finding out that 
+Andrea had impemented option #2]
+sas, 2004-12-10:
+Rollback warning. Due do our transaction class doing an automatic rollback
+in the destructor, we now get a warning from RAL each time a RalTransaction
+goes out of scope:
+  POOL/RelationalPlugins/oracle  Warning No active transaction to roll back
+[edit: We still do get some warnings even though Andrea's changes make sure 
+it's not from our Transaction destructor when there has been a commit. We 
+get one commit warning per test, so it seems this occurs when the session
+object goes out of scope (or something along that line).]
+  
+Even if it doesn't incur a performance penalty it does not look pretty.
+Perhaps we should add the following changes:
+
+RalTransaction::commit() {
+  m_session->commit();
+  m_autocommit = true;
+}
+
+RalTransaction::~RalTransaction() {
+  if ( m_autocommit ) {
+    m_session->commit();
+  } else {
+    m_session->rollback();
+}
+
+or
+
+RalTransaction::commit() {
+  m_session->commit();
+  m_closed = true;
+}
+
+RalTransaction::~RalTransaction() {
+  if ( ! m_closed ) {
+    m_session->rollback();
+}
+
+The second option has the drawback that we lose the guarantee of not leaving
+open transactions, which was the primary purpose of the class. I would go
+with the first option, where the RalTransaction is practically switched to
+autocommit mode after the first commit by the user.
+
+Basically the class is intended for single commits, you instantiate it 
+once, do a commit once and scope it in a way that there's no other SQL handled 
+by the transaction anyway. It still does provide the safeguard of rollback 
+should an exception occur before the transaction.commit().
+
+
+
diff --git a/RelationalCool/doc/hvsTagsSpec.txt b/RelationalCool/doc/hvsTagsSpec.txt
new file mode 100644
index 000000000..6e8a1d0ab
--- /dev/null
+++ b/RelationalCool/doc/hvsTagsSpec.txt
@@ -0,0 +1,15 @@
+------------------------------------------------------------------------------
+
+References:
+- http://atlas.web.cern.ch/Atlas/GROUPS/DATABASE/project/doc/HVS.doc
+- http://atlas.web.cern.ch/Atlas/GROUPS/DATABASE/detector_description/RALaccess
+- http://atlassw1.phy.bnl.gov/cgi-bin/cvsweb.cgi/offline/Database/AthenaPOOL/RDBAccessSvc/src
+
+Download of Atlas software:
+- setenv CVSROOT :kserver:atlas-sw.cern.ch:/atlascvs
+  cvs co -d RDBAccessSvc offline/Database/AthenaPOOL/RDBAccessSvc
+  cvs co -d RDBAccessTest offline/AtlasTest/DatabaseTest/RDBAccessTest
+- Alternative CVS repository:
+  /afs/usatlas.bnl.gov/software/cvs/offline/Database/AthenaPOOL/RDBAccessSvc
+
+------------------------------------------------------------------------------
diff --git a/RelationalCool/doc/release.notes b/RelationalCool/doc/release.notes
new file mode 100755
index 000000000..ccf98293d
--- /dev/null
+++ b/RelationalCool/doc/release.notes
@@ -0,0 +1,3019 @@
+Package RelationalCool
+Package managers: Andrea Valassi, Sven A. Schmidt and Marco Clemencic
+Package contributors: Uli Moosbrugger, Romain Basset.
+
+==============================================================================
+TODO
+- Remove RelationalTableRow (replace it by Record)
+- Rename defaultSpecification as metadataSpecification
+- Rename fetchLastRowXXX as fetchLastRowMetadataXXX
+- Add option to select only certain payload columns
+
+==============================================================================
+!2008.11.10 - Andrea
+
+Internal doc for tag COOL_2_6_0.
+
+Summary of changes in RelationalCool with respect to COOL_2_6_0-pre6:
+- Change API and implementation to replace 'const int f()' by 'int f()' 
+  and get rid of gcc43 compilation warnings (bug #42584, aka task #8261).
+- Fix bug #43622 (slow performance: countObjects must not call browseObjects).
+- Use the new CORAL API ISession::remoteProperties (sr #103545) to determine 
+  the remote database technology even when forwarded through a CORAL server.
+
+==============================================================================
+!2008.10.21 - Andrea
+
+*** BRANCH RELEASE NOTES ***
+
+Tag COOL_2_4_0b. Rebuild of the 2.4.0a release for the LCG_54h configuration.
+Add support for Oracle on MacOSX. Bug fixes in CORAL and frontier_client.
+No change in the source code. Software version remains "2.4.0".
+
+NB: None of the _code_ changes in COOL_2_4-branch are released in COOL_2_4_0b!
+NB: [there is one minor exception, RelationalCool/tests/RelationalDatabaseId]
+NB: Only the _config_ branch changes are released in COOL_2_4_0b!
+
+Actually, some of the implementation files tagged as COOL_2_4_0b have a
+different version number than those tagged as COOL_2_4_0a: they were committed 
+unchanged to the COOL_2_4_x branch and then retagged as CORAL_2_4_0b.
+
+==============================================================================
+!2008.10.16 - Andrea
+
+Internal tag COOL_2_6_0-pre5-bis ('2008/10/16 10:00:00').
+
+Changes in RelationalCool with respect to COOL_2_6_0-pre5:
+- Performance optimization: issue COUNT(*) queries only on demand (task #7971).
+  This implies a minor backward-incompatible change in the CoolKernel API: 
+  remove const qualifier from IObjectIterator methods size, isEmpty, hasNext.
+- Remove '(forcereload=short)' from the aliases in dblookup.xml.
+  Use the environment variable FRONTIER_FORCERELOAD in QMTEST
+  to force the immediate refresh of Frontier short-lived cached queries.
+- Define CORAL linkopts using the NEEDS_CORAL_BASE macro
+  (fix for LCGCMT bug #41579: link RelationalAccess only if needed).
+- Start the port to gcc4.3. 
+  Add missing STL headers to the implementation code.
+  Add gcc43 to all .cvsignore files.
+
+==============================================================================
+!2008.09.27 - Andrea
+
+Internal tag COOL_2_6_0-pre5 (-D '2008/09/27 10:00:00').
+
+Changes in RelationalCool with respect to COOL_2_6_0-pre4:
+- Major internal cleanup of 'Ral' (CORAL) and 'Relational' (generic) classes.
+  > Add a generic cool::IRelationalCursor to handle relational queries.
+    This is returned by new method RelationalQueryMgr::prepareAndExecuteQuery.
+    Implement it as a RalCursor (wrapper for a CORAL ICursor).
+    Use it to replace RalObjectIterator by a generic RelationalObjectIterator. 
+    Remove the old commened out COOL210 RalObjectIterator implementation.
+    Remove the registerIterator method (already commented out).
+    Replace the RalObjectIterator test by a RelationalObjectIterator test.
+  > Add static qualifier for RalQueryMgr methods 
+    cursorNext and executeQuery (for TimingReport).</li>
+    Identify COOL sessions by their IRelationalTransactionMgr
+    (rather than the RalSessionMgr) in ObjectIteratorCounter.
+    Add a RelationalQueryMgr::clone() method.
+    Use a RelationalQueryMgr instead of a RalSessionMgr
+    in the RelationalObjectIterator constructor.
+  > Replace RalObjectMgr by generic RelationalObjectMgr. 
+    The browseObjects method now returns a generic RelationalObjectIterator.
+    Remove the session method (not used).
+    Remove the sessionMgr method (inline it in implementation).
+    Remove the objectIdSequence method (inline it in implementation and tests).
+    Remove the unused storeObjects method (move it to the test);
+    keep the __storeObjects method (which does not start a transaction).
+    Replace the RalObjectMgr test by a RelationalObjectMgr test.
+  > Add RelationalQueryMgr::bulkUpdateTableRows for bulk updates.
+    Use the cool::RelationalQueryMgr bulk inserter and updater
+    in the implementation of RelationalObjectMgr.
+  > Replace RalObjectTable by generic RelationalObjectTable. 
+    Replace the RalObjectTable test by a RelationalObjectTable test.
+
+==============================================================================
+!2008.09.25 - Andrea
+
+Internal tag COOL_2_6_0-pre4.
+
+Summary of changes in RelationalCool with respect to COOL_2_6_0-pre3:
+- Fix bug #40812 (insertionTimeOfLastObjectInTag for user tags). Add tests.
+- Fix bug #41735 (add missing sequence tables to the coolPrivileges tool).
+- Fix bug #42101 ("HEAD" tag not accepted for browsing SV folders). Add a test.
+- Fix message printouts in log() for RalObjectMgr and RelationalObjectTable.
+- Partial fix for bug #17903 (bulk insertion for MV [key,key+1] uses single 
+  row insertion). Alg can be tuned using COOL_MVINSERTION_PREFETCH_MAXROWS.
+  Better performance observed when inserting over void. Abother improvement
+  (missing bulk updates) is needed for inserting over existing IOVs.
+  Add QMTEST tests for both the old and new algorithm.
+- Add coolPrivileges logfiles to document the granted privileges (task #7825). 
+
+==============================================================================
+!2008.09.11 - Andrea
+
+Internal tag COOL_2_6_0-pre3.
+
+Summary of changes in RelationalCool with respect to COOL_2_6_0-pre2:
+- Check for any missing tables in the coolValidateSchema tool (task #7691).
+  Differentiate between warnings, errors and fatal errors in the final dump.
+  Add a standalone test (using brute force to manually drop a table).
+- Add a test for bug #36646 (metadata fields are visible in IObject::payload).
+- Remove COOL workaround for CORAL bug #40315, aka COOL bug #40295 (rows not 
+  deleted from coral_sqlite_fk when tables are dropped). Now fixed in CORAL.
+- Add link options for Boost date_time after adding /DBOOST_ALL_NO_LIB for vc9.
+- Drop inheritance of RelationalTransaction on ITransaction (#ifdef COOL270).
+- Include in RelationalCool/tests/dblookup.xml the lcgnight entries from 
+  /afs/cern.ch/sw/lcg/app/pool/db/dblookup.xml, for consistency.
+
+==============================================================================
+!2008.09.01 - Andrea
+
+Internal tag COOL_2_6_0-pre2.
+
+Summary of changes in RelationalCool with respect to COOL_2_6_0-pre1:
+- Implement addition of IOVs to partially locked tags (task #6541), add tests.
+- Fix bug #40353 (do not modify verbosity if COOL_MSGLEVEL is not set).
+- Remove the dependency of RelationalCool on CoolApplication.
+  Keep the dependency of RelationalCool on CoolKernel.
+  Keep the dependency of CoolApplication on RelationalCool.
+  Adapt all implementation code and tests.
+- Change '#ifdef COOL260' into '#ifdef COOL270'.
+- Disable the internal manual transaction handling if COOL270 is not defined.
+- Add infrastructure for tests of the Frontier Squid cache (task #3440).
+  > Update the dblookup.xml file using the complex frontier URL syntax.
+- Move RelationalObjectTable methods fetchRowsInTag, fetchRowsInHead, 
+  fetchRowsInPastHead out of src into RalObjectTableTest (task #7646).
+
+==============================================================================
+!2008.08.27 - Andrea
+
+Internal tag COOL_2_6_0-pre1.
+
+Summary of changes in RelationalCool with respect to COOL_2_5_0:
+- Upgrade software version to COOL 2.6.0.
+- Implement payload queries (server-side for FieldSelection and
+  CompositeSelection, client-side for any other IRecordSelection).
+  This functionality is protected behind#ifdef COOL260.
+  > Add class RelationalPayloadQuery.
+  > Add functional tests for server-side and client-side payload queries
+    (using a SelectionWrapper test class for the latter).
+- Implement manual transaction handling and add test for several use cases.
+  This functionality is protected behind #ifdef COOL260.
+  > RelationalTransaction implements ITransaction if COOL260 is defined.
+  > Add RelationalFolder::maxBufferSize().
+  > Add RelationalObjectMgr::__storeObjects.
+  > Add RalObjectMgr::__storeSingle/MultiVersionObjects.
+  > Modify the internal transaction manager interface and classes.
+- Add virtual destructor for RelationalTransaction. 
+- Fix bug #22474 (bulk insertion is split across many transactions). Add test.
+- Fix bug #38251 (hints ignored in COUNT(*) queries).
+- Fix performance for 'SELECT COUNT(*) FROM ( subquery )' queries
+  by including again the list of selected columns in the subquery,
+  which had been removed between COOL 2.4.0 and COOL 2.5.0 (task #6482)
+- Use the new goToNext API instead of the obsolete hasNext API
+  in the internal implementation of RalObjectIterator2.
+- Enhance the coolAuthentication tool to display all CORAL replicas.
+  > Add option to display only 1st replica (R/O or R/W) or 1st R/W replica.
+  > Fix a small memory leak (related to CORAL bug #40507).
+  > Port the new features to the CoolAuthentication python package too
+- Workaround for Windows VC9 bug #40142: #undef symbols 'DELETE' and 'ERROR'
+- Workaround for Windows VC9 bug #40143: specify namespace in cool::MSG.
+- Remove workaround in the replication tool for SQLiteAccess bug #24867 
+  (workaround was to avoid dropping and recreating FKs during replication)
+  > But the SQLiteAccess bug is not fully fixed and COOL tests fail
+    (see also CORAL bug #40315 and COOL bug #40327)
+- Add workaround for CORAL bug #40315 (coral_sqlite_fk not updated when 
+  tables are dropped), aka COOL bug #40295 (error messages for sqlite)
+- Implement RelationalObjectTable::fetchRowsInHead using 
+  queryDefinitionGeneric insted of whereDataHead and whereClauseHead.
+- Rename RelationalObjectTable::fetchLastRow as fetchLastRowSV and comment 
+  it out (it is only present, commented out, in test_RalObjectTable).
+- Remove RelationalObjectTable::fetchRowAtTimeInTag. This was already not 
+  used, except in one test (which has been kept with inlined implementation).
+- Remove RelationalObjectTable methods whereClauseHead, whereDataHead, 
+  whereClauseTag, whereDataTag. These were already not used, except in tests.
+- Add empty skeleton for RelationalFolder::truncateObjectValidity().
+- Small fix in the schema evolution tool using CORAL msgVerbosity().
+- Temporary workaround for Boost 1.35.0 bug (warnings from Boost headers).
+- Get rid of cool::Sleep (use cool::sleep everywhere).
+- Add cmt/version.cmt to prepare support for the latest CMT version.
+- Remove the old test infrastructure using bash scripts.
+- Remove SCRAM configuration fragments.
+- Remove SeaUtil_SealTimer.h (keep SealUtil_SealTimer.h).
+
+==============================================================================
+!2008.07.16 - Andrea
+
+Copy back COOL_2_4_0a code into COOL_2_4-branch.
+
+This removes a useful bug fix but also some performance improvements we 
+were not really sure about. Make the COOL_2_4-branch clean to be released.
+
+==============================================================================
+!2008.07.16 - Andrea
+
+Add workaround for LCGCMT bug #38934 (python module installation is broken 
+by LCGCMT_55a). This was removed immediately after the LCGCMT bug fix.
+
+[Changes included by Andrea in COOL_2_4-branch on 2008.07.16]
+
+==============================================================================
+!2008.06.10 - Andrea
+
+Tag COOL_2_5_0. Production release with API semantic changes, API extensions
+and package structure changes to remove the dependency on SEAL.
+Upgrade to LCG_55 using the 'de-SEALed' CORAL_2_0_0.
+
+Summary of changes in RelationalCool with respect to COOL_2_4_0a
+(refer to the web release notes for more details):
+- CMT package structure changes.
+- Remove internal dependency on SEAL
+  > De-SEAL all tests and utilities.
+  > Replace seal::TimeInfo::sleep with a sleep function based on Boost.
+  > Import the SealUtil timing classes (after removing what is not needed).
+- Add new internal class CoralConnectionServiceProxy.
+- Performance improvements (many many changes).
+- There may be more changes that are only documented in the web release notes!
+
+==============================================================================
+!2008.06.04 - Andrea
+
+*** BRANCH RELEASE NOTES ***
+
+Tag COOL_2_4_0a. Rebuild of the 2.4.0 release for the LCG_54g configuration.
+Port to osx105 and .so shared lib names on MacOSX. Changes in CORAL and ROOT.
+No change in the source code. Software version remains "2.4.0".
+
+NB: None of the _code_ changes in COOL_2_4-branch are released in COOL_2_4_0a!
+NB: Only the (osx105) _config_ branch changes are released in COOL_2_4_0a!
+
+==============================================================================
+!2008.05.21 - Marco
+
+Added a COOL specific implementation of coral::IMsgReporter.
+It is activated setting the environment variable USE_COOL_MSGREPORTER, and the
+level can be tuned with COOL_MSGLEVEL (by default it is "ERROR").
+
+==============================================================================
+!2008.04.18 - Marco
+
+Fixed bug #35734: compilation error on Windows after removeal of SEAL.
+
+==============================================================================
+!2008.04.11 - Marco
+
+Removed dependency on SEAL.
+- De-SEAL all tests and utilities.
+- Replace seal::TimeInfo::sleep with a sleep function implemented using Boost.
+- Import the SealUtil timing classes (after removing what is not needed).
+
+==============================================================================
+!2008.04.09 - Andrea
+
+Algorithmic fix: the internal implementation classes exchange a shared pointer 
+to a connection service proxy (CoralConnectionServiceProxy) rather than a 
+service reference. The proxy contains a pointer that is reset to null when the 
+COOL database service is deleted (the CORAL connection service may or may not 
+continue to exist, but is declared to be unusable). Adapt utilities and tests.
+
+==============================================================================
+!2008.04.10 - Andrea
+
+Include a modified version of Jaco Kroon's signal handler.
+See http://www.tlug.org.za/wiki/index.php/Obtaining_a_stack_trace_in_C_upon_SIGSEGV 
+and http://cool.cvs.cern.ch/cgi-bin/cool.cgi/cool/contrib/ExternalTests/SignalHandler/src/sigsegv.cpp
+
+This is enabled only if environment variable COOL_ENABLE_COOLSIGNALHANDLER 
+is set (this replaces COOL_ENABLE_SEALSIGNALHANDLER and the SEAL handler).
+
+==============================================================================
+!2008.04.09 - Andrea
+
+Modify some of Marco's changes to remove SEAL.
+- In COOL_2_4_0, RalDatabaseSvc could be loaded as a SEAL plugin
+  (either through CoolApplication or directly from a seal Context).
+- In Marco's code, RalDatabaseSvc could be loaded as a Reflex plugin.
+- In the present code, RalDatabaseSvc is linked directly to CoolApplication.
+
+Method IApplication::connectionSvc returns a reference (rather than
+a shared pointer) to the coral::IConnectionService. This reference
+is exchanged internally between all relevant RelationalCool classes.
+
+Class Application is implemented by instantiating a CoralApplication
+from the RelationalCool library. Class CoralApplication is needed in
+RelationalCool to implement tests and utilities: it cannot be in
+CoolApplication as otherwise there would be a circular dependency.
+
+Modify all tests and utilities so that they bootstrap COOL using the
+CoralApplication class from RelationalCool rather than the Application
+or DatabaseSvcFactory classes from package CoolApplication.
+Package CoolApplication is now built after RelationalCool.
+
+Remove the infrastructure to load RalDatabaseSvc as a Reflex plugin.
+
+Remove RalDatabaseSvcLabel.h (modules.cpp had already been removed)
+because RalDatabaseSvc is not a SEAL plugin anymore.
+
+Internally replace seal::MessageStream by coral::MessageStream.
+- WARNING: changing message verbosity has no effect yet. 
+- WARNING: retrieving message verbosity is not possible yet. 
+- WARNING: changing or retrieving message verbosity of an individual 
+  cool::IApplication affects all COOL and CORAL applications because 
+  this is implemented in coral::MessageStreams using static methods. 
+
+Remove the dependency on Reflex, add a (temporary!) dependency on SEAL.
+Remove the private dependency of RelationalCool on CoolApplication:
+this would imply a circular dependency because now it is CoolApplication
+that links the RelationalCool library (which is not a plugin anymore).
+
+Keep a dependency on CoolApplication headers only (class CoralApplication
+implements the IApplication interface defined in package CoolApplication).
+
+Build the RelationalCool library as an LCG CMT 'shared' library
+(not a Reflex 'plugin' library nor a SEAL 'module' library).
+
+Add build directives to mkdir the bin directory if it does not exist
+(else scripts cannot be copied there).
+
+==============================================================================
+!2008.04.03 - Andrea
+
+Remove lines containing 'Invalid folder node path' from the qmtest XML report.
+This is needed in the SEAL-less HEAD version where Error messages 
+are not filtered out by the new message reporting infrastructure: 
+line 'ralDb->createFolderSet( "/my\folderset" )' triggers an error
+printout with a binary character that fails the XML parsing.
+This is not needed in COOL_2_4-branch but it is included for consistency.
+
+[Changes included by Andrea in COOL_2_4-branch on 2008.04.03]
+
+==============================================================================
+!2008.04.03 - Andrea
+
+Improve summarizeAll.csh to accept one or more CMTCONFIG values as arguments
+when building the qmtest result summaries.
+
+[Changes included by Andrea in COOL_2_4-branch on 2008.04.03]
+
+==============================================================================
+!2008.04.02 - Andrea
+
+Created a COOL_2_4 branch off COOL_2_4_1-pre1 for the whole of COOL:
+  cvs rtag -r COOL_2_4_1-pre1 -b COOL_2_4-branch cool
+
+==============================================================================
+!2008.04.02 - Marco
+
+Re-enabled LFC support in utilities.
+
+==============================================================================
+!2008.03.20 - Marco
+
+Removed seal::Context.
+cool::RalDatabase can be loaded as a Reflex plug-in.
+All the references to seal::MessagesService have been removed and now only
+coral::MessageStream is used.
+
+The tests have been updated, but the utilities are not yet ready.
+
+==============================================================================
+!2008.03.03 - Andrea
+
+Internal tag COOL_2_4_1-pre1 (bug fixes).
+The only changes wrt COOL_2_4_0 are in RelationalCool.
+
+==============================================================================
+!2008.02.29 - Andrea
+
+Test the parsing of middleTier() in the RelationalDatabaseId class.
+
+==============================================================================
+!2008.02.29 - Andrea
+
+Remove a few compilation warnings from cppunit the hard way
+(remove all uses of CPPUNIT_TEST_EXCEPTION).
+
+==============================================================================
+!2008.02.29 - Sven
+
+Fix for bug #33989 (setTagDescription should fail if called from wrong node).
+
+==============================================================================
+!2008.02.29 - Andrea
+
+Test for bug #33989 (setTagDescription should fail if called from wrong node).
+
+==============================================================================
+!2008.02.28 - Andrea
+
+Tag COOL_2_4_0. Production release with backward compatible API extensions.
+Upgrade to LCG_54b using CORAL_1_9_5.
+
+==============================================================================
+!2008.02.27 - Andrea
+
+Add a test for CORAL bug #33401 as reported by Richard for COOL (ORA-00904).
+
+==============================================================================
+!2008.02.26 - Sven
+
+Implement IHvsNode::setTagDescription. 
+This modifies only the global tag table (not the local one).
+It can be used to set the description of both IOV and HVS tags.
+Add several tests for setTagDescription under various use cases.
+
+==============================================================================
+!2008.02.26 - Andrea
+
+Prototype support for coralxxx://host:port&... URLs (CORAL server backend).
+Add a few tests.
+
+==============================================================================
+!2008.02.25 - Andrea
+
+Implement userTagOnly argument to IFolder::storeObject (task #6153), to allow 
+users to avoid the duplication of MV data in the global and user tag HEADs.
+Add a few tests.
+
+==============================================================================
+!2008.02.20 - Andrea (changes committed before COOL_2_3_1 but not tagged)
+
+Change the config: do not install the RelationalCool headers directory
+even if it is found (this may happen if cvs co -P is not used).
+
+==============================================================================
+!2008.02.19 - Andrea (changes committed before COOL_2_3_1 but not tagged)
+
+Upgrade software version to 2.4.0.
+
+Add two API extensions to be released as COOL_2_4_0:
+- add IHvsNode::setTagDescription (task #6394), to allow users to first
+  create a tag (also as a user tag or HVS tag) and then set its description
+- add userTagOnly argument to IFolder::storeObject (task #6153), to allow
+  users to avoid the duplication of MV data in the global and user tag HEADs
+
+Remove Sven's IFolder::setTagDescription from the API.
+Keep the implementation, but comment it out: this should be moved to 
+RelationalHvsNode and should not modify the local tag table (to be ignored).
+Comment out Sven's tests for setTagDescription.
+The implementation of setTagDescription presently throws an exception.
+No tests exist to check that this is the case.
+
+The implementation of storeObject( userTagOnly=true ) throws an exception.
+Add a test for storeObject( userTagOnly=true ), checking that it throws.
+
+==============================================================================
+!2008.02.18 - Sven (changes committed before COOL_2_3_1 but not tagged)
+
+Implement IFolder::setTagDescription.
+This modifies both the global and local tag tables.
+It cannot be used to set the description of HVS tags for folder sets.
+Add several tests for setTagDescription under various use cases.
+
+==============================================================================
+!2008.02.21 - Andrea
+
+Tag COOL_2_3_1. Bug-fix production release (binary compatible with 2.3.0) 
+with performance optimizations for multi-version retrieval and insertion.
+Upgrade to LCG_54a including bug fixes in ROOT 5.18.00a. 
+
+==============================================================================
+!2008.02.13 - Andrea (-D '2008/02/13 19:30:00')
+
+Internal tag COOL_2_3_1-pre2 (bug fixes and performance optimizations).
+Use the default LCG_54 (including ROOT 5.18) on all platforms.
+
+==============================================================================
+!2008.02.13 - Romain and Andrea
+
+Performance optimization in MV insertion of IOVs with user tags (task #6086).
+Part 2 of the optimization: performance improvement for the UPDATE statement.
+
+When new IOVs are inserted in MV mode, they may overlap with older IOVS that 
+were previously part of the HEAD: these IOVs need to be updated to mark that 
+they are not part of the HEAD any longer. The new UPDATE implementation uses 
+the same 'SELECT MAX(IOV_SINCE)' subquery used in most retrieval use cases 
+to speed up the lookup of which IOVS need to be updated.
+
+The latest implementation is enabled by default and reuses almost the same
+SQL code that is defined in RelationalObjectTable::queryDefinitionGeneric
+(originally developed for MV tag retrieval, task #5820). 
+
+The old COOL_2_3_0 implementation is used by default for MySQL because of 
+an intrinsic limitation of MySQL (an UPDATE statement cannot update a table 
+which is also SELECTed from in a subquery of the UPDATE statement).
+The old COOL_2_3_0 implementation can also be reenabled for the other
+backends if the environment variable COOL_TASK6086_DISABLERBUPDATE is set.
+
+Limitation of the current implementation: a better SQL statement has been
+designed for Oracle, but it cannot be implemented because of missing
+support for hints in UPDATE statements in CORAL (sr #103420).
+
+==============================================================================
+!2008.02.08 - Andrea
+
+Performance optimization in MV insertion of IOVs with user tags (task #5820).
+All subqueries which can be rewritten ("merged") as multi-table joins (and 
+which the Oracle optimizer internally does merge this way) are now 
+consistently rewritten explicitly as multi-table joins.
+
+==============================================================================
+!2008.02.08 - Andrea
+
+Performance optimization in MV insertion of IOVs with user tags (task #5820).
+A consistent approach is used for naming SQL query blocks and table aliases 
+in different use cases, making the code much more readable and easier to 
+maintain and improve. Add several hooks for changing the default query hints 
+using environment variables for faster performance tests.
+
+==============================================================================
+!2008.02.08 - Andrea
+
+Performance optimization in MV insertion of IOVs with user tags (task #5820).
+When browsing for IOVS between times t1 and t2, the COALESCE function in SQL 
+is now used consistently (instead of OR or UNION ALL clauses) to concatenate 
+the IOVS valid at time t1 (since <= t1 < until) with the IOVS starting 
+between t1 and t2 (t1 < since < t2).
+
+==============================================================================
+!2008.02.05 - Andrea
+
+Enable the RelationalObjectTable::queryDefinitionGeneric method also for 
+MV retrieval from standard tags (task #5820). This was previously handled 
+by method queryDefinitionTag, which now delegates most of its functionality 
+to the generic method (also used for user tags - task #6086).
+
+The same method is designed to also handle the SV case (but is not used in 
+production yet). It can also be adapted for MV HEAD retrieval.
+
+==============================================================================
+!2008.02.05 - Romain and Andrea
+
+Performance optimization in MV insertion of IOVs with user tags (task #6086).
+Part 1 of the optimization: performance improvement for the SELECT statement.
+
+==============================================================================
+!2008.02.04 - Andrea
+
+Internal tag COOL_2_3_1-pre1 (bug fixes and performance optimizations).
+Upgrade COOL software version to 2.3.1.
+
+==============================================================================
+!2008.02.04 - Sven
+
+Fix for bug #32976 in the replication tool.
+
+==============================================================================
+!2008.01.29 - Andrea
+
+Performance optimization for MV retrieval from standard HEAD tags (task #5820).
+Main change: query the IOV2TAG table instead of the IOV table!
+The new strategy is in RelationalObjectTable::queryDefinitionTag.
+
+==============================================================================
+!2008.01.21 - Andrea
+
+Tag COOL_2_3_0. Production release with backward compatible API extensions.
+Upgrade to LCG_54 using Python 2.5, ROOT 5.18 and several other new externals.
+
+PyCool is not supported on MacOSX because of bug #32770 in ROOT 5.18.00.
+The COOL nightlies are all green (except for the PyCool tests on MacOSX).
+
+==============================================================================
+!2008.01.17 - Andrea
+
+Undo the attempt at performance optimization for task #6086.
+There was no clear performance benefit, and some penalty instead.
+Keep the new code to be used in the future, but comment it out.
+
+==============================================================================
+!2008.01.17 - Andrea
+
+Ensure that RelationalCool scripts are installed by 'cmt make all' 
+and not only by 'cmt make all_groups' (task #5835).
+
+==============================================================================
+!2007.01.16 - Sven
+
+Fix bug #32610 in the replication tool when replicating databases
+where renamePayload or extendPayloadSpecification has been used.
+
+==============================================================================
+!2007.01.15 - Andrea
+
+Attempt at performance optimization for MV user tag insertion (task #6086).
+
+Add new RelationalObjectTable::queryDefinitionGeneric method that supports
+both the SV and MV user tag cases, with improved queries on since/until.
+Use this method in production also for the SV case (remove queryDefinitionSV).
+Eventually this can be used in a more general reimplementation of all queries.
+
+==============================================================================
+!2007.01.09 - Andrea
+
+New signature (record) for IFolder::extendPayloadSpecification (task #5742).
+This allows users to add more than one columns at once and to specify 
+a non-null default value for the additional column of all existing rows. 
+Remove the old signature (name, type). Add tests for non-null default values.
+
+Warning: the replication tool has not yet been ported to support the new
+IFolder::extendPayloadSpecification functionality (bug #32610).
+
+==============================================================================
+!2008.01.08 - Andrea
+
+Disable CppUnit header warnings from gcc41 nightlies (task #5837).
+
+==============================================================================
+!2007.12.19 - Andrea
+
+Internal tag COOL_2_3_0-pre1 (new COOL API extensions on standard LCG_53f).
+All CMT tests successful, bash tests not updated. Software version is 2.3.0.
+
+==============================================================================
+!2007.12.17 - Sven
+
+Complete task #4327 by adding a few new tests in test_RelationalFolder:
+
+	CPPUNIT_TEST( test_findObjects_channelName_SV ); 
+	CPPUNIT_TEST( test_findObjects_channelName_MV ); 
+  CPPUNIT_TEST( test_findObjects_channelName_MV_tag ); 
+  CPPUNIT_TEST( test_findObjects_channelName_MV_userTag );
+  CPPUNIT_TEST( test_countObjects_channelName_SV_all ); 
+  CPPUNIT_TEST( test_countObjects_channelName_SV_range ); 
+  CPPUNIT_TEST( test_countObjects_channelName_MV_all ); 
+  CPPUNIT_TEST( test_countObjects_channelName_MV_tag ); 
+  CPPUNIT_TEST( test_countObjects_channelName_MV_userTag );
+
+==============================================================================
+!2007.12.17 - Andrea
+
+Centrally maintain credentials for the nightly builds (user lcgspi) in 
+/afs/cern.ch/sw/lcg/app/pool/db. Files authentication.xml and dblookup.xml 
+are automatically copied to the private directories on MacOSX and Windows
+using Samba. Set CORAL_AUTH_PATH and CORAL_DBLOOKUP_PATH equal to
+- /afs/cern.ch/sw/lcg/app/pool/db on Linux
+- $HOME/private on MacOSX
+- %USERPROFILE%\private on Windows
+
+Remove dblookup entries for users roiser and pkolet 
+(the nightly tests are only executed as user lcgspi). 
+
+==============================================================================
+!2007.12.16 - Sven
+
+Implemented channelName based ChannelSelection support for
+browseObjects methods. Relevant tests are in test_RelationalFolder:
+
+  CPPUNIT_TEST( test_browseObjects_channelName_SV_all );
+  CPPUNIT_TEST( test_browseObjects_channelName_SV_range );
+  CPPUNIT_TEST( test_browseObjects_channelName_MV_all );
+  CPPUNIT_TEST( test_browseObjects_channelName_MV_tag );
+  CPPUNIT_TEST( test_browseObjects_channelName_MV_userTag );
+
+These should cover all possible where clauses used by browseObjects code.
+The calls findObjects and countObjects also go through browseObjects.
+
+These changes almost complete task #4327.
+
+==============================================================================
+!2007.12.14 - Andrea
+
+Upgrade COOL software version to 2.3.0.
+
+==============================================================================
+!2007.12.13 - Andrea
+
+Split RelationalFolder and Channel tests. Workaround for COOL bug #27650 
+(CORAL bug #28547): long tests fail because SQLite file descriptors are not 
+released (SQLite feature) and the maximum cannot be increased beyond 1024.
+
+==============================================================================
+!2007.12.13 - Andrea
+
+Added enum value HvsTagLock::PARTIALLYLOCKED (task #4606).
+
+A PARTIALLYLOCKED tag behaves like a LOCKED tag except in the following cases:
+1. It is possible to add a tag relation from a partially locked parent HVS tag
+to a tag in a child HVS node (if no tag relation exists for that child node).
+
+Eventually, one or both of the following functionalities may also be added
+(but for the moment, neither of them is implemented yet):
+2. It is possible to add IOVs to a partially locked user tag, only if the 
+newly inserted IOVS have no overlap to those already existing in the user tag.
+3. It is possible to retag the HEAD of a folder with a partially locked tag,
+only if the retag operation only results in adding new IOVS to the tag.
+
+==============================================================================
+!2007.12.13 - Andrea
+
+Disable the CORAL connection pool automatic cleanup if the environment
+variable COOL_DISABLE_CORALCONNECTIONPOOLCLEANUP is set (bug #30435).
+Disable it by default in COOL tests by modifying config/cmt/requirements.
+
+==============================================================================
+!2007.12.13 - Andrea
+
+Added method IFolder::listChannelsWithNames (task #5868).
+Added two tests in the RelationalFolder and RalDatabase test suites.
+
+Aborted attempts to add method IObject::channelName. The functionality 
+required by Atlas is provided by IFolder::listChannelsWithNames instead.
+
+==============================================================================
+!2007.12.12 - Andrea
+
+Added method IFolder::extendPayloadSpecification (task #5742).
+Added two tests in the RelationalFolder and RalDatabase test suites.
+
+==============================================================================
+!2007.12.12 - Andrea
+
+Moved exception DatabaseOpenInReadOnlyMode to the public API (task #5743).
+This was previously defined as a RelationalException in RelationalCool.
+
+==============================================================================
+!2007.12.03 - Marco
+
+Added dblookup entries for uses pkolet and lcgspi for the SPI nightly tests.
+
+==============================================================================
+!2007.11.26 - Sven
+
+Added channel selection by channel name in the ChannelSelection class.
+Implemented channel selection by channel name in RelationalObjectTable.cpp.
+Added four tests for the new selections to the ChannelSelection test suite.
+Added test_browseObjects_channelName to the RelationalFolder test suite.
+
+==============================================================================
+!2007.11.13 - Andrea
+
+Tag COOL_2_2_2. Production release (binary compatible with 2.2.0) with many
+performance and configuration improvements and bug fixes. New versions of 
+CORAL and Frontier server (fixing all pending problems in the tests) and ROOT.
+This is the first COOL release built by the SPI team (and no SCRAM config).
+
+==============================================================================
+!2007.11.09 - Andrea/Romain
+
+Reimplement user tags queries using the new RelationalQueryDefinition.
+This is needed to implement hints to use the 5d index for task #4381.
+
+Add the following hint to try and stabilize the execution plan:
+/*+ ALL_ROWS FULL(T) INDEX(O (USER_TAG_ID)) LEADING(T O) USE_NL(O)*/.
+
+==============================================================================
+!2007.11.08 - Andrea
+
+Internal tag COOL_2_2_2-pre2 (using private CORAL192 build and SEAL193 copy).
+All CMT tests successful, bash tests not updated. Software version is 2.2.2.
+
+==============================================================================
+!2007.11.07 - Andrea
+
+Upgrade software version to 2.2.2.
+
+==============================================================================
+!2007.11.07 - Andrea
+
+Internal tag COOL_2_2_2-pre1 (using private CORAL192 build and SEAL193 copy).
+All CMT tests successful (no pending Frontier failures).
+Bash tests not updated (Wine failures are expected).
+
+==============================================================================
+!2007.11.06 - Andrea
+
+Add tests for string and templated methods payloadValue (task #2859).
+These methods were not tested anywhere in the C++ test suite before.
+Test also FieldIsNull and FieldCppWrong from the templated method.
+
+==============================================================================
+!2007.10.25 - Romain
+
+Performance improvement in IOV insertion by stabilizing the execution plan 
+for the 'select last IOV' query (in RalObjectMgr::fetchLastRowsWithNewData,
+add hint "/*+ INDEX(C) INDEX_RS_ASC(O) LEADING(C O) USE_NL(C O) */",
+replacing the previous "/*+INDEX(O)*/" hint that was not appropriate).
+
+==============================================================================
+!2007.10.30 - Andrea
+
+Added a fake make target "examples" to please nmake (task #5414).
+
+==============================================================================
+!2007.10.26 - Andrea
+
+Implement constraints on allowed characters in a node name (task #4371).
+
+Modified tests for bug #30751 and task #4371:
+- test that creation of folder[set] with a trailing space in its name fails
+- remove test of creation of two folder[set]s with almost the same name
+
+All tests are now successful (including MySQL).
+
+==============================================================================
+!2007.10.26 - Andrea/Sven
+
+Added tests for bug #30751 and task #4371:
+- test that creation of folder[set] with a trailing space in its name succeeds
+- test creation of two folder[set]s with the same name but for a trailing space
+
+The second set of tests fails for MySQL because of an intrinsic limitation
+of the MySQL 5.0 server ("x" and "x " are indistinguishable, for instance
+in enforcing primary keys and in where clauses).
+
+==============================================================================
+!2007.10.26 - Andrea
+
+Fix schema evolution tool so that UK/FK errors from CORAL are not printed
+when the corresponding exception is caught in the normal program flow.
+
+==============================================================================
+!2007.10.26 - Andrea
+
+Fix in enforcing "folders with schema version 2.0.0 are no longer supported".
+Method listAllTables should not fail (we know all tables), else we may
+get failures in schema evolution (MySQL was indeed failing... not Oracle?).
+
+Extend exceptions UnsupportedFolder[Set]Schema to accept any message.
+Move UnsupportedFolder[Set]Schema exceptions to file RelationalException.h.
+
+Add a PanicException for all PANIC situations (asserts).
+
+Add tests for listAllTables with node schema versions 1.9.9, 2.0.9, 2.9.0
+(panic, success, fail) and with folder schema version 2.0.0 (success).
+
+==============================================================================
+!2007.10.25 - Romain
+
+Performance improvement in IOV insertion (to be cross-checked)
+by stabilizing the execution plan for the 'select last IOV' query
+(add the "/*+INDEX(O)*/" hint in RalObjectMgr::fetchLastRowsWithNewData).
+
+==============================================================================
+!2007.10.25 - Andrea
+
+Fix for performance and functional bug #30431 in MV folders: 
+in RelationalFolder.cpp, use the channels table for MV existsChannel.
+
+Fix for functional bug #30443 and performance bug #24448 in MV folders: 
+in RelationalFolder.cpp, use the channels table for MV listChannels.
+
+Remove all workarounds for bug #23755, including:
+- in RelationalFolder.cpp, remove the old fixes for 
+  bug #24445 (MV setChannelName fails without createChannel),
+  bug #24449 (MV existsChannel fails without createChannel),
+  bug #24461 (MV setChannelDesc fails without createChannel) and
+  bug #24463 (MV channelName fails without createChannel);
+- in RalObjectMgr, make channel table manipulation private again;
+- in RelationalObjectMgr, dropChannel continues to check also the IOV table
+  (because this is the semantics: throw if the channel has some IOVs);
+- in RelationalObjectTable, remove listChannels (but keep existsChannel).
+
+These changes complete the fix for bug #23755.
+
+All RelationalCool and PyCoolUtilities tests are now successful.
+
+==============================================================================
+!2007.10.25 - Andrea
+
+Folders with schema version 2.0.0 are no longer supported.
+This ensures that folders have been evolved to 2.0.1 or higher (i.e. that FK 
+constraints exist between each IOV table and the corresponding channel table).
+
+Add tests that using or dropping a 2.0.0 folder fails.
+Add tests that dropping a database containing a 2.0.0 folder also fails.
+
+Rename RelationalFolderNew as RelationalFolderUnsupported.
+Rename RelationalFolderSetNew as RelationalFolderSetUnsupported.
+
+==============================================================================
+!2007.10.24 - Andrea
+
+Add new tool coolValidateSchema to check internal consistency of databases.
+Presently this only investigates possible data corruption due to bug #23755,
+e.g. due to unenforced FK constraints in sqlite (checks that channels in all
+IOV tables are listed in the corresponding channel tables, both MV and SV).
+
+==============================================================================
+!2007.10.24 - Andrea
+
+Use RelationalQueryDefinition in RalObjectMgr::fetchLastRowsWithNewData
+(task #5282 - also see task #5654, will rewrite this query to fix the plan).
+
+Add the option to define a hint in an IRelationalQueryDefinition
+(thanks to Romain for the suggestion - e.g. can be useful for task #5654).
+
+Clean up result set specification handling for queries executed from an 
+IRelationalQueryDefinition: the spec is in the query definition,
+no need to specify it as an argument to fetchOrderedRows.
+
+==============================================================================
+!2007.10.23 - Andrea
+
+Add pure virtual methods to RelationalQueryMgr for selecting or counting rows
+from a query defined using an IRelationalQueryDefinition (task #5282).
+
+==============================================================================
+!2007.10.23 - Andrea
+
+Add a new test_SealPluginDump.sh test to the bash test suite (task #5678).
+Running the test also makes sure that the COOL plugins are loaded for SCRAM.
+The same machinery was implemented by Marco for CMT and QMTEST.
+
+==============================================================================
+!2007.10.23 - Andrea
+
+Use the MySQL integration cluster itrac424 instead of Marco's pclhcb55
+for Andrea's private tests (task #5412). Not yet done for the nightlies.
+
+==============================================================================
+!2007.10.23 - Andrea
+
+Fix bug #30500 (wrong exception thrown when attempting to update a database
+that is open in read-only mode): add new exception DatabaseOpenInReadOnlyMode,
+thrown by both transaction managers and also by RalObjectMgr::storeObjects.
+
+Add a test for bug #30500 (check that DatabaseOpenInReadOnlyMode is thrown
+when attempting to update a database that is open in read-only mode).
+
+==============================================================================
+!2007.10.20 - Sven
+
+Fix bug #30578 in the replication tool.
+
+==============================================================================
+!2007.10.16 - Andrea
+
+Add tests for bug #30431 (MV existsChannel) and bug #30443 (MV listChannels).
+
+==============================================================================
+!2007.10.16 - Andrea
+
+Fix bug #30361 in the schema evolution tool.
+
+==============================================================================
+!2007.10.11 - Andrea
+
+Tag COOL_2_2_1. Production release (binary compatible with 2.2.0) with many
+configuration improvements, feature enhancements and bug fixes. New versions 
+of CORAL (with important bug fixes for SQLite and Frontier), ROOT and SEAL.
+This is the first COOL release with support for MacOSX/Intel platforms.
+
+==============================================================================
+!2007.10.09 - Andrea
+
+Drop SEAL package granularity in SCRAM as there is no .SCRAM in SEAL_1_9_3.
+CoolKernel depends on SEAL and adds link libraries SealBase, PluginManager 
+and SealKernel by default. SealUtil and SealServices are added where needed.
+
+==============================================================================
+!2007.10.08 - Andrea
+
+Internal tag COOL_2_2_1-pre5. Last private tag before COOL_2_2_1.
+All CMT/SCRAM tests successful on all platforms using a private CORAL191
+(except for the last pending failure RO_02b1 - bug #23368 in FrontierAccess),
+including MacOSX/PPC (last build) and gcc41 (not built for official COOL221).
+Non-debug osx104_ia32_gcc401 not built, test results copied from debug version.
+
+Changes in RelationalCool code, tests and test results (none in config):
+- Allow back-insertion of non-overlapping IOVS in SV folders (task #3138).
+  > Add several tests for task #3138, all successful.
+- Avoid a few warnings in Windows.
+- Reenable tests for sqlite bug #22485, now fixed.
+- Add a few timing reports for task #4672.
+- Software version is now 2.2.1
+- Update test results for cygwin (.NT) again..
+
+==============================================================================
+!2007.09.29 - Sven
+
+Partial implementation of task #3138: allow back-insertion of IOVS 
+in SV folders as long as there are no IOV overlaps.
+
+Use case #3 is implemented: back-insertion is possible 
+if IOVs are inserted one at a time (no bulk insertion).
+
+Use case #2 is implemented: back-insertion is possible with bulk insertion,
+if any back-inserted IOV is the only IOV inserted in its channel (while
+many IOVs can be inserted at a time in channels with no back-insertion).
+
+Use case #3 is not yet implemented: back-insertion is not possible with 
+bulk insertion if several IOVs are inserted at a time in a channel where
+at least one IOV is back-inserted.
+
+==============================================================================
+!2007.09.18 - Marco
+
+Minor changes to avoid a few warnings on Windows
+in RelationalQueryDefinition.cpp and RalQueryMgr.cpp.
+
+==============================================================================
+!2007.09.02 - Andrea
+
+Add a few more timing reports for task #4672.
+
+==============================================================================
+!2007.08.29 - Andrea (-D '2007/08/29 13:30:00')
+
+Internal tag COOL_2_2_1-pre4.
+First version with successful tests of slc4_ia32_gcc41 on SCRAM/BASH,
+including SQLite and Frontier support and complete private config for CMT.
+
+No changes in RelationalCool code or config.
+
+Changes in bash test results:
+- All OK for slc4_ia32_gcc41 (after enabling SQLite/Frontier).
+- Replace 'Skip test' by 'Skip' in existing logfiles for mergeTestOutput.
+
+==============================================================================
+!2007.08.24 - Andrea (-D '2007/08/24 17:15:00')
+
+Internal tag COOL_2_2_1-pre3.
+First version with successful tests of MacOSX Intel on both CMT/QMTEST 
+and SCRAM/BASH, including PyCool (but still no Oracle support).
+First version with successful tests of slc4_ia32_gcc41 on SCRAM/BASH
+(but CMT is badly configured, and still no SQLite or Frontier support).
+
+Implementation bug fixes:
+- Fix bug #28189 (missing quotes around table alias in new Oracle queries)
+- Fix bug #28787 (segfault if 'live' iterator is not closed)
+  > fixed by using RalSessionMgr instead of IDatabase to keep track of how many
+    iterators are open (now allow at most one open iterator per RalSessionMgr)
+
+Add a test for MySQL bug #24646 (storing 11 blobs with 1000 characters fails). 
+The test is disabled for MySQL, for the moment it only prints a warning. 
+
+Changes in bash test results:
+- New test_payloadSpecOver8000Bytes for bug #24646 is OK (disabled for MySQL).
+- Added logfile for slc4_ia32_gcc41 (all tests OK using SCRAM).
+
+==============================================================================
+!2007.08.07 - Andrea (-D '2007/08/07 16:02:00')
+
+Internal tag COOL_2_2_1-pre2.
+First version with all QMTEST tests as successful as bash tests.
+
+Test config improvements:
+- Fix bug #28553 (duplicate entry in dblookup.xml for tests).
+
+No changes in RelationalCool code or bash test results.
+
+==============================================================================
+!2007.08.02 - Andrea (-D '2007/08/03 14:05:00')
+
+Internal tag COOL_2_2_1-pre1. 
+
+Changes in bash test results:
+- OSX PPC tests for SQLite succeed after adding workaround for bug #27650.
+- Added results for OSX Intel (all ok except Oracle that is not supported).
+
+C++ bug fixes:
+- RelationalFolderSetNew inheritance from IFolderSet must be virtual.
+
+Tool improvements:
+- Port CoolQueryManager to Windows (task #5255).
+- Improved usage messages from various scripts.
+
+CMT config improvements:
+- Fixes for OSX link warnings.
+
+==============================================================================
+!2007.07.13 - Andrea
+
+Tag COOL_2_2_0. Production release with many performance optimizations and bug 
+fixes, also including backward-compatible API extensions and schema changes.
+New versions of CMT, CORAL, ROOT/Reflex, oracle, sqlite, frontier_client
+and LFC using LCG_53 (with respect to COOL 2.1.1 using LCG_51).
+
+Main API changes in CoolKernel:
+- Added support for Blob16M (task #2197).
+- Added reverse order object iterator from browseObjects (task #3430).
+- Added goToNext() and currentRef() methods to IObjectIterator to improve the 
+  C++ client performance by avoiding copies of CORAL currentRow (task #4672).
+- Removed unnecessary virtual class inheritance from final classes and 
+  unnecessary virtual method inheritance from final methods (task #4879).
+- Added IDatabase::databaseName() method (sr #101807).
+- Added IFolder::dropChannel() method to delete/drop an existing channel.
+
+Main schema changes (all included in the coolEvolveSchema tool):
+- Fill the channels table for MV folders (fix for bug #23755).
+- Added a FK on the IOV table referencing channelId in the channels table:
+  this is part of the fix for bug #23755 (MV channels table was not filled).
+  > Note that FKs are parsed but not enforced on SQLite.
+- Folder schema is now 2.0.1 (database schema remains 2.0.0).
+  > For the moment, the code is still able to read the older 2.0.0 schema
+    (i.e. it does not rely on the fact that the MV channels table is filled).
+    In other words, schema evolution is recommended but is not necessary.
+  > Eventually, a future COOL release will require schema evolution, so
+    that it can assume that the MV channels table is filled. 
+  > Older releases 210 and 211 are able to read/write data in the new 2.0.1
+    folders: however, on Oracle and MySQL, where FKs are enforced, IOVs cannot
+    be inserted into new channels unless these are first manually created using
+    createChannel (or they have been created using storeObjects on COOL_2_2_0).
+  > *** WARNING *** Even if COOL210/211 can be used to insert data into
+    the 2.0.1 folders created by COOL_2_2_0, this is discouraged on SQLite
+    files as it may lead to data corruption (a 2.0.1 sqlite folder has a
+    non-enforced FK, so an IOV may exist for a channel that is not registered
+    in the channels table). This may be solved in the future if FKs are 
+    enforced using triggers in the CORAL SQLIteAccess (sr #102114).
+- String255 columns on MySQL are VARCHAR(255) BINARY instead of VARCHAR(255)
+  > This change is due to the fix in CORAL190 for bug #26484, which was
+    responsible in COOL for bug #24393 (tag queries were case insensitive).
+  > Warning: strings longer than 255 characters are still TEXT instead of 
+    BINARY TEXT, hence they are still queried/sorted in a case-insensitive way.
+- Schema evolution database attribute is now called "SE_2_2_0".
+
+Additional implementation improvements over COOL 2_1_1:
+- Performance improvements for SV queries (task #4402).
+  > The query time for all-channel queries is now flat across IOVs.
+  > SV queries are now handled through a join of the channels and IOV tables.
+  > New class IRelationalQueryDefinition to encapsulate a generic query
+    description that can be reused as part of a subquery, eg for COUNT(*).
+  > Adapt the RelationalQueryMgr to the new IRelationalQueryDefinition.
+    Table row count is now possible using SELECT COUNT(*) FROM (SELECT...)
+    where the subquery is the same as the query used to fetch individual rows.
+  > Add schemaName() and databaseTechnology() to RelationalQueryMgr to handle 
+    backend-dependent SQL injection in subqueries not supported by CORAL.
+- Performance improvement for multi-channel bulk insertion (task #2009).
+  > Also clean up a bit the storeMultiVersionObjects method.
+- Performance improvement for SV listChannels (bug #24448): use channels table.
+- Drop support for the old RalObjectIterator (use only RalObjectIterator2).
+- Progress in cleanup of inheritance.
+  > Removed unnecessary virtual class inheritance from final classes and 
+    unnecessary virtual method inheritance from final methods (task #4879).
+  > Renamed RelationalBulkOperation as IRelationalBulkOperation.
+  > Renamed RelationalTransactionMgr as IRelationalTransactionMgr.
+  > Remove RalNodeMgr and RalTagMgr (Relational versions are enough).
+  > Separate getSequence and instantiateSequence metods in sequence manager.
+  > Bug fix: remove '=0' qualifier from the RelationalObjectTable destructor.
+- Fix bug in RalDatabaseSvc (variable redefined in internal {} block)
+- Removed workaround for CORAL bug #22453 for BLOB handling
+  (this is part of the implementation for the Blob16M storage type).
+- Fix bug in RelationalNodeTable::tableSpecification() for many COOL releases.
+
+Additional tool improvements over COOL 2.1.1:
+- Support evolution from either 1.3.0 (required) or 2.0.0 schemas (optional).
+  > The evolution from 2.0.0 schemas always checks all folders, upgrading them
+    from 2.0.0 to 2.0.1, while leaving the database schema version as 2.0.0.
+  > The evolution from 2.0.0 schemas also adds the 5d index for user tags
+    (which was introduced to solve task #4381 in COOL_2_1_1), if not yet there.
+  > Use two separate tests for evolution from 130 and 200 (in PyCoolUtilities).
+- Enable schema evolution from 1.3.0 databases on AMD64.
+  > On AMD64, use the 32bit mode to create a 1.3.0 schema for evolution tests.
+- Fix bug #26509 (coolReplicateDB fails on large databases - out of memory).
+- Fix bug in coolPrivileges (add channels table: frontier tests were failing).
+- Fix bug #23438 in CoolDescribeTable (invert single/double quotes on Windows).
+- Fix bug in CoolDescribeTable (COLLATE syntax was not parsed for MySQL).
+- Adapt coolReplicateDB after fixing bug #23755 (MV channel table not filled).
+- Adapt coolReplicateDB and coolEvolveSchema to the new channelId FK.
+- Add support for LFC to the coolAuthentication, coolDBDiscovery, coolDropDB, 
+  coolDumpSchema, coolEvolveSchema, coolMiniClient, coolPrivileges and 
+  coolReplicateDB tools (task #4326).
+- Disabled the CORAL automatic pool clean up thread in coolDropDB and 
+  coolReplicateDB (fix bug #27844 - nightly tests were hanging).
+- Add COOLREPLICATION_TIMEOUT environment variable for coolReplicateDB tests.
+- Add documentation for the coolReplicateDB tool (task #4328).
+- Add support for 'select *' queries in the coolExecuteSql.csh script.
+- Add CoolQueryManager python package to issue arbitrary 'select' queries
+  against a COOL database: this is used in regression and schema evolution 
+  tests to check at the database level that the MV channels table is filled.
+
+==============================================================================
+!2007.07.06 - Marco
+
+Disabled the CORAL connection pool clean up thread in coolDropDB and
+coolReplicateDB (fix for nightly test failures reported as bug #27844).
+
+==============================================================================
+!2007.04.16 - Marco
+
+Tag COOL_2_1_1. Bug-fix production release (binary compatible with 2.1.0).
+New versions of CORAL, ROOT and frontier_client using LCGCMT_51.
+
+Main bug fixes and improvements over COOL 2.1.0:
+- Implement cross-check that only one 'live' iterator can be open at a time.
+  > This was always claimed in the past, but not yet enforced.
+  > Added exception TooManyIterators.
+  > Fix for bug #25151 (abort in concurrent use of iterators).
+  > Fix for bug #25817 (segfault introduced by new iterator checks).
+  > Fix for bug #25256 (MySQL test failure introduced by new iterator checks).
+  > Added tests for read concurrency with live iterators.
+- Performance improvements in the C++ client.
+  > Copy data only once in browseObjects using new RalObjectIterator2
+    (can be disabled using COOL_210ITERATOR env variable).
+  > Construct RelationalObject from coral AttributeList 
+    (rather than from RelationalObjectTableRow). 
+  > Private hacks for PDB stress tests in RalObjectIterator
+    (controlled by env variable COOL_PDBSTRESSTEST_NBYTES).
+- Resurrect TimingReport for performance studies (disabled by default).
+  > Fix a memory leak (related to bug #9253).
+  > Can be enabled by COOL_TIMINGREPORT env variable.
+  > Keep track of time spent in CORAL alone.
+- Start a single read-only transaction and preload the nodes table at the 
+  start of read-only connections (task #2816).
+  > Can be disabled by COOL_READONLYSESSION_MANYTRANSACTIONS env variable.
+  > New bug (memory leak): the database is never deleted.
+  > Add methods to read all nodes from the nodes table.
+  > Use a bool flag always (no more strings) to indicate read-only sessions.
+  > Added new class DummyTransactionMgr for read-only connections.
+- Added goToNext() and currentRef() methods to IObjectIterator API.
+  > These are presently disabled (#ifdef'ed out)and will be enabled in 2.2.0 
+    (improve C++ client performance by avoiding copies of CORAL currentRow).
+  > Added new classes ConstTimeAdapter and ConstRelationalObjectAdapter.
+- Fix for bug #24999 in the replication tools.
+- Fixes for gcc4.0 in RelationalObjectTableRow.
+- Fixes for gcc4.1 in CppUnit tests.
+- Fix in coolAuthentication for aliases in frontier (ignore missing password).
+- Added test for case sensitivity of tag names in MySQL (bug #24393).
+  > Bug introduced in COOL2.0.0 by removing BINARY for strings in CORAL.
+  > Improved tests for special characters such as umlauts.
+
+==============================================================================
+!2007.04.04 - Marco
+
+Fixed bug #25256. RalObjectIterator2 was registered even if the construction 
+fails with an exception in the initialization part (before the constructor 
+body), but in that case was never unregistered. Now it is registered in the 
+body of the constructor, so an exception in the initialization part will not 
+cause a mis-balance. Added the class ObjectIteratorCounterWatchDog to spot 
+when an iterator is not correctly unregistered.
+
+==============================================================================
+!2007.03.26 - Andrea
+
+C++ performance improvement in RalObjectIterator and RelationalObject: 
+copy data only once in browseObjects, while previously it was copied twice.
+A query time reduction from 0.31s to 0.27s was observed on slc3_ia32_gcc323
+for the benchmark Atlas prompt reconstruction query (retrieve in total
+100MB and 100k rows from 100 folders with 1k channels each).
+
+==============================================================================
+!2007.03.24 - Sven
+
+Fixed replication bug #24999.
+
+==============================================================================
+!2007.03.24 - Andrea
+
+Tag COOL_2_1_0. Production release with backward-compatible API extensions 
+and schema changes. New versions of CORAL and ROOT using LCGCMT_50c.
+
+Summary of backward-compatible API changes in CoolKernel:
+- Tag locking functionality (task #3709)
+  > add IHvsTag::setTagLockStatus and IHvs::tagLockStatus methods
+  > add TagIsLocked exception
+- Fix for bug #23751 in the IFolder::folderSpecification() method.
+- Fixes to allow compilation on MacOSX.
+- Define int64 as long long also on AMD64, as in CORAL_1_7_2 (task #4357).
+
+Backward-compatible schema changes:
+- Added a 5D index to IOV tables to improve user tag performance (task #4381).
+
+Configuration changes:
+- Prepared infrastructure for private SCRAM builds in parallel to CMT.
+
+Other improvements and bug fixes in COOL:
+- SQL performance improvement for SV SC browseObjects (task #3675).
+- Forward compatibility with 2.0.x folder and folder set schemas. 
+- Added replication test to the PyCoolUtilities test suite (task #4348).
+- Completed integration with LFCReplicaSvc and added an example (task #4326).
+- Fix for bug #23597 in PyCoolCopy with sqlite files.
+- Fix for bug #23610 in RelationalTagMgr::fetchGlobalTagTableRowForInnerNode.
+- Fixes for coolReplicateDB bug #23662 (drop/recreate FKs when needed).
+- Partial fix for bug #23716 in PyCoolCopy handling of BLOBs. 
+- Fix for bug #23754 (IFolder::setChannelName should accept current name).
+- Fix for bug #24248 in schema evolution test infrastructure for sqlite.
+- Partial fix for bug #24392 (missing try/catch in an example).
+- Fixes for bug #24445, bug #24449, bug #24461 and bug #24463 in MV channel 
+  management: actually, these are all workarounds for bug #23755 (channels 
+  table is not filled for MV folders).
+- Fix for bug #24464 (storeObject should accept payload with fewer fields 
+  than those defined in the folder payload specification).
+- Fix for a bug in IFolder::existsUserTag(): the transaction was started twice.
+- Fixes in the authentication and statistics tools (moved from C++ to python).
+- Fixes for bug #24480, bug #24481 and bug #24555 in C++ test infrastructure.
+- Start internal preparation for 3.0.0 schema (task #4307 and task #4396).
+- Improvements in PyCool (some of which related to the LFCReplicaSvc).
+- Added tool PyCoolDiff to extract the difference between two DBs.
+
+Improvements from the upgrade to CORAL_1_7_2 (from CORAL_1_7_0):
+- Fix for bug #23412 in MySQLAccess SQL syntax for PK creation.
+- Fix for bug #24103 in SQLiteAccess handling of unsigned int on AMD64.
+- Fix for bug #24642 in MySQLAccess SQL syntax for FK creation.
+
+Improvements from the upgrade to ROOT 5.14.00d (from 5.14.00b):
+- Fix for bug #23807 (abort in boost::shared_ptr<IObject>).
+- Fix for bug #24100 in unsigned long long handling in python for AMD64.
+
+Improvements from the upgrade to LCGCMT_50c (from LCGCMT_50):
+- Fix for bug #24052 (missing oracle/mysql binaries in PATH).
+
+==============================================================================
+!2007.03.22 - Marco
+
+Fixed a bug observed by Richard: the transaction was started twice when
+calling RelationalFolder::existsUserTag().
+
+==============================================================================
+!2007.02.21 - Andrea
+
+Added TestListener.h replacing the corresponding cppunit header file.
+This seemed to be the only way to get rid of compilation warnings with -O2.
+
+==============================================================================
+!2007.02.20 - Andrea
+
+Apply the performance patch for SV SC browseObjects(key,key+10,chId) that
+had been developed by Kristoffer Dahl in 2006. This completes task #3675.
+
+==============================================================================
+!2007.02.19 - Andrea
+
+Fixes for the tools to gather table and schema statistics.
+Move them from csh to py scripts (with associated python packages).
+
+Minor fix in the CoolAuthentication python package.
+
+==============================================================================
+!2007.02.16 - Andrea
+
+Add 5d index to IOV tables to improve user tag performance (task #4381).
+
+Change s/w release version to 2.0.1 (keep db schema version at 2.0.0).
+
+Change folder schema version to 2.0.1 (mark the existence of the new index).
+The 2.0.1 RelationalFolder class can still read (with lower performance)
+any 2.0.0 folder where this index is not defined. The 2.0.0 software 
+release is now forbidden from reading the new 2.0.1 folders to encourage
+users to move to 2.0.1 (even if the 2.0.0 code could actually read data 
+from the new folder with the extra index - even with better performance!).
+
+Cleanup assigning and checking of folder and folder set schema versions.
+
+==============================================================================
+!2007.02.16 - Andrea
+
+Added infrastructure to create new tables in 3.0.0 database schema:
+- IOVTABLES and CHANNELTABLES tables (task #4307)
+- USERTAGS and HEADTAGS tables (tag #4396)
+The code has been committed, but must be kept commented out until 3.0.0.
+
+In order to complete the 3.0.0 db schema, CHECK constraints are needed.
+Filed CORAL sr#101506 asking support for this feature.
+
+Removed schema manipulation methods from RelationalDatabase
+(they were already delegated to the schema manager anyway).
+
+==============================================================================
+!2007.02.16 - Andrea
+
+Adopt for SCRAM the same naming convention used by CMT:
+- rename unitTest as test
+- rename exampleCool as example_Cool
+
+==============================================================================
+!2007.02.14 - Andrea
+
+Added a C++ test for CORAL bug #22485 (empty blobs in sqlite).
+We now have a failing test in the RelationalCool test suite.
+
+==============================================================================
+!2007.02.14 - Marco
+
+Fixed bug #23751: "IFolder::folderSpecification() does not work".
+
+The fix required a fix in IFolder.h (return const IRecordSpecification instead
+of const RecordSpecification). It is "semantically" compatible, and should not
+break compilation, but it is not strictly the same API. Also added a test.
+
+==============================================================================
+!2007.02.12 - Sven
+
+Various fixes for the dynamic replication tool. Still not fully functional.
+
+==============================================================================
+!2007.02.08 - Marco
+
+Fixed bug #23610: rename RelationalTagMgr::fetchGlobalTagTableRowForInnerNode
+as fetchGlobalTagTableRowForNode and change all comments accordingly.
+
+==============================================================================
+!2007.02.08 - Andrea
+
+Minor changes in RelationalTagMgr to remove a warning on MacOSX
+(control reaches end of non-void function) - see task #2062.
+
+==============================================================================
+!2007.01.31 - Andrea
+
+Tag COOL_2_0_0. Major production release with backward-incompatible
+API and schema changes. New versions of SEAL, CORAL and frontier_client. 
+
+Summary of main API changes in CoolKernel and CoolApplication:
+- Changes in folder specification, payload specification and payload data API
+  > new StorageType::TypeId enum with associated new typedefs (eg Int64)
+  > new RecordSpecification class
+  > new Record and Field classes with validation of storage constraints
+  > temporary extensions use coral AttributeList for backward compatibility 
+  > new FolderSpecification class accepted by createFolder
+  > treat empty string "" as NULL
+- Stripped API of all SEAL classes
+  > integer type definitions not based on seal::IntBits
+  > new class cool::Time replaces seal::Time.
+  > new SEAL-free API for class cool::Application
+- Changes in the support for user-defined payload fields
+  > added support for BLOB and signed int64 payload data
+  > constraints on numbers and names of user-defined payload fields
+  > added cool::IFolder::renamePayload (to change unsupported payload names)
+  > string payload cannot contain character "\0" (only BLOBs can contain it)
+- Renamed methods and removed default channel arguments in IFolder:
+- Removed obsolete IDatabaseSvc::dropDatabase(dbId,throwIfDoesNotExist)
+- Added the possibility of specifying a CORAL role in the connection string
+- Changed default mode for openDatabase from read/write to read/only
+
+==============================================================================
+!2006.01.18 - Marco
+
+Added the possibility of specifying a CORAL role in the connection string.
+The format is now one of:
+ - alias/DBNAME
+ - alias(role)/DBNAME
+
+==============================================================================
+!2007.01.17 - Marco
+
+*** BRANCH RELEASE NOTES ***
+
+Tag COOL_1_3_4. Production release (backward-compatible bug-fix, 
+functionality enhancement and LCG_50 configuration upgrade release). 
+Important fixes in SEAL (component model and multithreading), CORAL and ROOT.
+
+==============================================================================
+!2006.12.12 - Marco
+
+Removed explicit (hardcoded) reference to XMLAuthenticationService 
+(let CORAL decide which authentication service should be used).
+
+Added a warning message if explicit credentials are used (deprecated).
+
+Small fix in database Id parsing: the separator between coral ID
+and cool db name has to be the last '/', not the first.
+
+[Changes included by Marco in COOL_1_3-branch on 2006.12.12]
+
+==============================================================================
+!2006.12.08 - Andrea
+
+Remove all default channel=0 or channels=all arguments
+from all methods to store, find, browse or count objects.
+
+Rename browseObjects(time,channelsel) as findObjects,
+as otherwise the old browseObjects(5,10) would change 
+semantics (t=5,ch=10 instead of s=5,u=10,ch=0)!
+
+Keep the implicit ChannelSelection(id) constructor.
+Note that ChannelSelection(id) must be given explicitly in PyCool
+(the implicit constructor from an integer does not seem to work).
+
+These changes represent a fix for bug #14759.
+
+==============================================================================
+!2006.12.07 - Andrea
+
+Completed internal port to new IRecord and IField API.
+
+Eased backward compatibility for users by keeping the old 
+storeObject(..AttributeList&..) method signature in parallel 
+to the new storeObject(..IRecord&..), for writing,
+and via the IRecord::attributeList()method, for reading.
+
+PyCool still uses only the AttributeList interface
+(Marco will port it to the new Record interface).
+
+All C++ and python tests pass.
+
+==============================================================================
+!2006.11.26 - Andrea
+
+Moved ReferenceDb tool from RelationalCool tests to PyCoolUtilities as 
+new package PyCoolReferenceDb (this is a python package based on PyCool).
+This ensures that the python package is compiled in the platform-dependent 
+area, avoiding interference between 32 and 64bit Linux (fix for bug #21391).
+
+Moved execution of the regression tests based on ReferenceDb tool from 
+PyCool to PyCoolUtilities. This includes the Frontier regression test.
+
+[Changes included by Andrea in COOL_1_3-branch on 2006.11.26]
+
+==============================================================================
+!2006.11.24 - Andrea
+
+Added two python packages CoolAuthentication and CoolDescribeTable
+to dump the list of column names and SQL types of any table.
+This will be needed for regression tests of column SQL types.
+
+Added two corresponding tests in RelationalCool/tests/python.
+
+[Changes included by Andrea in COOL_1_3-branch on 2006.11.26]
+
+==============================================================================
+!2006.11.13 - Marco
+
+Clean up in RelationalCool test source code (prepare to QMTest).
+
+==============================================================================
+!2006.11.06 - Marco
+
+Add a check for active transactions in RalSessionMgr::disconnect (bug #21344).
+
+==============================================================================
+!2006.10.30 - Andrea
+
+*** BRANCH RELEASE NOTES ***
+
+Tag COOL_1_3_3c. Rebuild of the 1.3.3 release for the LCG_48 configuration.
+Important fixes in SEAL (component model and multithreading), CORAL and ROOT.
+No change in the source code. Software version remains "1.3.3".
+
+==============================================================================
+!2006.10.16 - Marco
+
+*** BRANCH RELEASE NOTES ***
+
+Tag COOL_1_3_3b. Rebuild of the 1.3.3 release for the LCG_47b configuration.
+New version of ROOT. Pending bugs in SEAL and ROOT. 
+Partial support for MySQL on Windows (pending PyCoolUtilities bug #20780). 
+No change in the source code. Software version remains "1.3.3".
+
+===============================================================================
+!2006.10.09 - Marco
+
+Added support (and tests) for coral::Blob.
+
+==============================================================================
+!2006.09.29 - Andrea
+
+*** BRANCH RELEASE NOTES ***
+
+Tag COOL_1_3_3a. Rebuild release (bug fixes in CORAL and frontier_client).
+Pending bugs in SEAL, new bugs in ROOT. Same source code as COOL_1_3_3. 
+Only added two Frontier regression tests. Software version remains "1.3.3".
+
+Upgrade to CORAL_1_6_0 (from CORAL_1_5_4), including the following bug 
+fixes and enhancements relevant to COOL.
+- CORAL bug #19758 (segfault in Frontier QueryDefinition::process)
+- CORAL bug #19777 (COOL bug #19753) in Frontier lowercase table aliases
+- CORAL sr #101135 (authentication credentials for different roles)
+
+Upgrade to frontier_client 2.6.0_cms (from 2.5.1_cms): 
+- Fix frontier_client bug #18359 (COOL bug #18390) in AMD64 data compression
+
+Upgrade to ROOT 5.13.02 (from ROOT 5.12.00c). This has triggered 
+the appearance of a new bug that prevents PyCool support on Windows:
+- ROOT bug #20133 (COOL bug #20216) for python ROOT on Windows
+
+No upgrade from SEAL_1_8_1 yet. Pending bugs and thread unsafety 
+in SEAL component model causing segfaults, assertions and aborts.
+
+==============================================================================
+!2006.09.26 - Andrea
+
+Fix for bug #20073 - no need to select payload columns for inserting IOVS.
+Bug observed in COOL133 but fixed only for COOL200 (as the code has changed).
+Bug fixed by adding the option to select only metadata columns in method 
+RelationalObjectTable::fetchRowForId, which is called by fetchLastRowForTagId
+(this was also called by fetchLastRow in COOL133). Also related to task #2266
+(allow users to specify which payload columns should be retrieved).
+The problem is not present in RalObjectMgr::fetchLastRowsWithNewData.
+
+Comment out RelationalObjectTable::fetchLastRow and its RalObjectTable test: 
+this is not used in the internal implementation as it has been replaced by 
+fetchLastRowsWithNewData (instead of querying the IOV table for the last 
+objectid, this is now read off the channels table). Note that fetchLastRow 
+is still used in COOL133 instead.
+
+==============================================================================
+!2006.09.14 - Andrea
+
+Added MV retrieval tests to the Regression test suite.
+Reproduces FrontierAccess bug #19753 for COOL_1_3_3.
+
+[Changes included by Andrea in COOL_1_3-branch on 2006.09.13]
+
+==============================================================================
+!2006.08.29 - Andrea
+
+*** BRANCH RELEASE NOTES ***
+
+Tag COOL_1_3_3. Production release (backward-compatible bug-fix, 
+functionality enhancement and configuration upgrade release).
+Many important fixes in CORAL and Frontier; pending critical bugs in SEAL.
+
+Eight supported platforms: win32_vc71_dbg_wine, slc4_ia32_gcc345(_dbg),
+slc3_ia32_gcc323(_dbg/_gcov) and slc3_ia32_gcc344(_dbg).
+No MySQL support on Windows (no support in CORAL).
+No Frontier support on Windows (no client library from FNAL).
+
+Two AMD64 test platforms: slc4_amd64_gcc345(_dbg). The only pending problem 
+with AMD64 is the 'long' type ambiguity on 32/64 bit platforms (task #2227);
+this is fixed in the new COOL HEAD API, which will be released as COOL140.
+
+Release built using LCG_46e_2 (upgrade from LCG_46_2). 
+May become available as LCG_46f_3 (the only difference 
+with LCG_46e_3 being COOL133 instead of COOL132c).
+
+Upgrade to ROOT 5.12.00c (from ROOT 5.12.00).
+
+Upgrade to CORAL_1_5_3 (from CORAL_1_5_1), including the following bug 
+fixes and enhancements relevant to COOL. In CORAL_1_5_3:
+- CORAL bug #19000 (disable OCI_THREADED to prevent OracleAccess hanging)
+- CORAL bug #19003 (fix for Oracle 'select from SYS.DUAL')
+- CORAL sr #101074 (fix for value returned by updateRows on MySQL)
+Already in CORAL_1_5_2:
+- CORAL bug #18275 (mismatch between output buffer and result set metadata in 
+  FrontierAccess) - patch contributed by the COOL team (this was responsible 
+  for both COOL bug #18270 and COOL bug #16995) 
+- CORAL bug #18292 (added plugin checks in case of misconfiguration)
+- Added ConnectionService property "PoolCleanUpPeriod"
+- Bug fixes in OracleAccess multi-threading (prevent deadlock)
+- CORAL sr #100958 (print out the values of SQLite bind variables)
+- CORAL bug #18316 (missing double quotes in some SQLite operations)
+- Improvements in SQLite file and directory handling
+
+Upgrade to frontier_client 2.5.1_cms (from 2.4.5_cms): 
+- Fix frontier_client bug #18359 (COOL bug #18390) in AMD64 data compression
+
+Upgrade to Frontier server version 3.2 and additional bug fixes:
+- Data compression in Frontier server 3.1 (required in 2.4.5_cms client)
+- Fix for Frontier server bug #18191 (not yet released)
+
+No upgrade from SEAL_1_8_1 yet. Pending bugs and thread unsafety 
+in SEAL component model (workarounds developed by the COOL team exist
+for some but not all of these issues):
+- SEAL bugs #19019 and #18908): segmentation fault in MessageStream
+- SEAL bug #19005 (COOL bug #18910): assertion 'pos != m_children.end ()'
+- SEAL bug #18909 (COOL bug #18440): abort (pure virtual method called)
+- SEAL bug #18914: segmentation fault in seal::intrusive_ptr_release
+- SEAL bug #19360: ConfigurationService is never deleted
+- SEAL bug #19004 (COOL bug #18396): assertion 's_trampolines[sig]'
+- COOL bug #18225: unhandled/unknown exceptions on Windows
+
+Enhancements in COOL_1_3_3 with respect to COOL_1_3_2c: 
+- Change the message level verbosity in PyCool/CoolApplication interactively
+- Implement forward compatibility with future releases (task #3426)
+- PyCoolUtilities enhancements for HVS
+- Warning messages in CoolApplication in case of problems loading plugins. 
+
+Bug fixes in COOL_1_3_3 with respect to COOL_1_3_2c: 
+- Bug #18116 in RalSequence test (segfault when the password is invalid) 
+- Bug #18284 in privilege manager (open database in update mode, add tag2tag)
+- Bug #18145 in PyCool on AMD64 (no attribute 'data').
+- Bugs in four RelationalCool tests: check connection service in tearDown()
+- Bugs in PyCoolCopy tool (preserve payload data type precision in the copy)
+- Possible segfault in the use of SEAL components in CoolApplication
+
+==============================================================================
+!2006.08.28 - Andrea
+
+*** BRANCH RELEASE NOTES ***
+
+Preparing for COOL_1_3_3.
+
+Aborted present attempts to fix or workaround bugs in SEAL_1_8_1
+causing random assertions, segmentation faults and aborts.
+
+Developed fixes and workarounds for several independent bugs in the 
+SEAL component model, but could not workaround the intrinsic thread 
+unsafety of SEAL handles based on boost intrusive pointers.
+
+==============================================================================
+!2006.08.23 - Andrea
+
+Added test for CORAL sr#101074 in RalDatabase test.
+Verified that the fix works (will be released in CORAL_1_5_3).
+
+Remove workaround for CORAL sr#101074 (return value of updateRows 
+on MySQL is different from Oracle/SQLite) in RalDatabase test.
+
+[Changes included by Andrea in COOL_1_3-branch on 2006.08.23]
+
+==============================================================================
+!2006.08.22 - Andrea
+
+Minor bug fix in the RalDatabase_extendedSpec, RalObjectIterator,
+RalObjectTable and RelationalFolder tests: check that the connection 
+service is still alive in tearDown() before using it to purge the pool.
+
+This prevents a boost shared pointer assertion if RalSessionMgr is changed
+to load the ConnectionService in the local database service context.
+
+[Changes included by Andrea in COOL_1_3-branch on 2006.08.13]
+
+==============================================================================
+!2006.08.15 - Andrea
+
+Added script wineWrap.sh for running individual commands on Wine (task #3495).
+
+[Changes included by Andrea in COOL_1_3-branch on 2006.08.15]
+
+==============================================================================
+!2006.07.27 - Andrea
+
+Implement forward compatibility with future releases using the same schema:
+compare data and software schema versions if data release number is newer 
+than software release number (task #3426). Added the relevant tests.
+
+[Changes included by Andrea in COOL_1_3-branch on 2006.07.27]
+
+==============================================================================
+!2006.07.27 - Andrea
+
+Bug fix in common CoolDBUnitTest (check availability of CORAL 
+connection service in forceDisconnect to prevent program abort).
+
+[Changes included by Andrea in COOL_1_3-branch on 2006.07.27]
+
+==============================================================================
+!2006.07.24 - Andrea
+
+*** BRANCH RELEASE NOTES ***
+
+Prepare for tag COOL_1_3_3 (non-HEAD branch off COOL_1_3_2).
+Backward-compatible production release.
+A few bug fixes and enhancements with respect to 1.3.2
+for CoolApplication, RelationalCool and PyCool.
+Commit PyCoolUtilities logfiles to the new branch too.
+Same code as 1.3.2 for CoolKernel, Examples and Utilities.
+
+Created branch COOL_1_3-branch off COOL_1_3_2.
+Initially (2006.05.18) branched all of config, CoolKernel and RelationalCool:
+  cvs rtag -r COOL_1_3_2 -b COOL_1_3-branch cool/config
+  cvs rtag -r COOL_1_3_2 -b COOL_1_3-branch cool/CoolKernel
+  cvs rtag -r COOL_1_3_2 -b COOL_1_3-branch cool/RelationalCool
+Later on (2006.05.18) realised it was not necessary to modify CoolKernel:
+  cvs rtag -d -B COOL_1_3-branch cool/CoolKernel
+
+Later on still (2006.07.24) realised it was not necessary to modify config, 
+while it was necessary to branch off also CoolApplication and PyCool.
+Eventually branched off also PyCoolUtilities for simpler logfile commits.
+  cvs rtag -d -B COOL_1_3-branch cool/config
+  cvs rtag -r COOL_1_3_2 -b COOL_1_3-branch cool/CoolApplication
+  cvs rtag -r COOL_1_3_2 -b COOL_1_3-branch cool/PyCool
+  cvs rtag -r COOL_1_3_2 -b COOL_1_3-branch cool/PyCoolUtilities
+Note that cool/config COOL_1_3-branch contained a single file
+doc/release.notes different from COOL_1_3_2. Untagging cool/config 
+detached the COOL_1_3-branch from this file but did not delete it.
+
+==============================================================================
+!2006.07.21 - Andrea
+
+Added handler of SEAL PluginManager feedback to cool::Application.
+This will print out warning messages if there are problems loading plugins.
+
+If environment variable COOL_PLUGINMANAGER_DEBUG is set, 
+debug information will be printed about the modules being loaded 
+(otherwise only warnings will be displayed).
+
+This must be done in package CoolApplication and not in RelationalCool
+(so that problems loading the RelationalCool plugin can be disaplayed).
+
+[Changes included by Andrea in COOL_1_3-branch on 2006.07.24]
+
+==============================================================================
+!2006.07.20 - Andrea
+
+Set the CORAL connection service pool cleanup period to 1 second 
+in the seal.opts files. These files should be in config!
+
+[Changes included by Andrea in COOL_1_3-branch on 2006.07.25]
+
+==============================================================================
+!2006.07.19 - Andrea
+
+Use Marco's MySQL server instead of Radovan's for Andrea's tests.
+This file should be in config!
+
+[Changes included by Andrea in COOL_1_3-branch on 2006.07.24]
+
+==============================================================================
+!2006.07.18 - Andrea
+
+Fix for bug #18284: add HVS tag2tag table to privilege manager.
+
+[Changes included by Andrea in COOL_1_3-branch on 2006.08.29]
+
+==============================================================================
+!2006.07.18 - Andrea
+
+Added listChannels tests to the Regression test suite
+(needed to reproduce FrontierAccess bug #16995).
+
+[Changes included by Andrea in COOL_1_3-branch on 2006.09.14]
+
+==============================================================================
+!2006.07.14 - Marco
+
+Enable the usage of dblookup.xml for tests for all users.
+Enable frontier tests for Marco. This file should be in config!
+
+[Changes included by Andrea in COOL_1_3-branch on 2006.07.24]
+
+==============================================================================
+!2006.07.14 - Marco
+
+Added function cool::IFolder::renamePayloadColumn and tests (task #3609).
+
+==============================================================================
+!2006.07.12 - Marco
+
+*** BRANCH RELEASE NOTES ***
+
+Tag COOL_1_3_2c. Rebuild of COOL_1_3_2 for the LCG_46 configuration.
+No change in the source code. Software version remains "1.3.2".
+
+Upgrade to ROOT 5.12.00 (from ROOT 5.11.06a), 
+including the following fixes for bugs relevant to COOL: 
+- ROOT bug #17255 (COOL bug #17254) for exception handling on AMD64
+- ROOT bug #17592 for enums in PyCintex
+- ROOT bug #18062 for namespaces in PyCintex
+
+Upgrade to CORAL_1_5_1 (from CORAL_1_5_0), 
+including the following bug fixes (the first three contributed by the 
+COOL team) and connection service improvements relevant to COOL: 
+- CORAL bug #17651 (COOL bug #17624) for missing quotes in SQL on MySQL
+- CORAL bugs #14688 and #17787 for SQLite data types on AMD64
+- CORAL bugs #14688 and #17761 for MySQL data types on AMD64
+- CORAL bug #17757 (COOL bug #17755) for Oracle bulk operations on >65k rows
+- CORAL bug #17791 for Oracle SELECT FROM DUAL
+- CORAL bug #15933 for SQLite named binding
+- implementation of automatic purging of the connection pool 
+- switch to Oracle multi-threaded OCI mode with no mutex locks 
+
+Upgrade to frontier_client 2.4.5_cms (from frontier_client 2.4.4_cms).
+COOL_1_3_2b had been tagged and installed before LCG_45 
+was redefined to use frontier_client 2.4.5_cms.
+
+Six supported platforms: win32_vc71_dbg_wine, 
+slc4_ia32_gcc345(_dbg) and slc3_ia32_gcc323(_dbg/_gcov).
+No MySQL support on Windows (no support in CORAL).
+No Frontier support on Windows (no client library from FNAL).
+
+Two test platforms: slc4_amd64_gcc345(_dbg).
+A few problems in COOL are still pending on AMD64 
+after the ROOT and CORAL bug fixes for this platform.
+
+Dropped support for slc3_ia32_gcc344(_dbg)
+and test builds on slc3_amd64_gcc344(_dbg).
+
+==============================================================================
+!2006.07.11 - Marco
+
+Add check to prevent segmentation fault in RalSequence test when the 
+connection fails, e.g. because of wrong username/password (bug #18116).
+
+[Changes included by Andrea in COOL_1_3-branch on 2006.07.24]
+
+==============================================================================
+!2006.07.11 - Marco
+
+Added check on the payload column names:
+only alphanumeric chars and '_' are allowed. 
+Throw cool::BadPayloadColumnName if the case of a name like "is-a".
+The test in RelationalFolderTest has been updated accordingly.
+Still need to add a method to allow users to rename payload columns.
+
+==============================================================================
+!2006.06.29 - Andrea
+
+Fix for bug in coolPrivileges: open the database in update mode.
+
+[Changes included by Andrea in COOL_1_3-branch on 2006.08.29]
+
+==============================================================================
+!2006.06.26 - Sven
+
+Brought back double query strategy using maxIovAtTime() for findObject
+in the SV case as it was in COOL 1.3.0 (maxIovAtTime was only used in
+SV even then). This required the following minor changes.
+- RelationalObjectTable::whereClauseSV now takes since, until parameters
+to determine if a 'point in time' (since == until) query is issued.
+- RelationalObjectTable::whereDataSV is now non-static, because it needs
+to access the non-static methods objectTableName() and maxIovAtTime().
+It was not used in any static contexts anyway.
+- In general, the 'old', optimized SV query will be used if since == until
+and channels.firstChannel() == channels.lastChannel().
+- Bug fix #16179 is still in place, because it concerns user tags (and
+therefore MV code).
+
+[Changes included by Andrea in COOL_1_3-branch on 2006.07.24]
+
+==============================================================================
+!2006.06.19 - Andrea
+
+Added a call to purgeConnectionPool inside RalSessionMgr::disconnect().
+This should ensure that closeDatabase() physically drops the connection
+if the connection service timeout has been pre-set to 0. To be tested.
+This is related to task #3546. [NB NOT committed to COOL_1_3-branch].
+
+==============================================================================
+!2006.06.19 - Marco
+
+*** BRANCH RELEASE NOTES ***
+
+Tag COOL_1_3_2b. Rebuild of COOL_1_3_2 for the LCG_45 configuration.
+Upgrade to ROOT/Reflex 5.11.06a and CORAL_1_5_0 using LCG_45 
+(from ROOT/Reflex 5.11.02 and CORAL_1_4_3 using LCG_44).
+Also implies upgrade to oracle 10.2.0.2 (from 10.2.0.1),
+sqlite 3.3.5 (from 3.2.8) and cppunit 1.10.2_p2 (from 1.10.2_p1).
+
+Upgrade to frontier_client 2.4.4_cms (from frontier_client 2.4.1_cms_p1).
+Note that COOL_1_3_2b was tagged and installed before LCG_45 
+was redefined to use frontier_client 2.4.5_cms.
+
+No change in the source code. Software version remains "1.3.2".
+
+Support for slc4_ia32_gcc323 and slc4_ia32_gcc323_dbg.
+
+Eight supported platforms: win32_vc71_dbg_wine, slc4_ia32_gcc345(_dbg),
+slc3_ia32_gcc323(_dbg/_gcov) and slc3_ia32_gcc344(_dbg).
+No MySQL support on Windows (no support in CORAL).
+No Frontier support on Windows (no client library from FNAL).
+
+Four test platforms: slc3_amd64_gcc344(_dbg) and slc4_amd64_gcc345(_dbg).
+Pending problems with AMD64 mainly due to 32bit/64bit integer types.
+
+==============================================================================
+!2006.06.16 - Marco
+
+Added tests for Int64 in RalDatabase_extendedSpec
+(UInt64 is ready, but commented out).
+
+==============================================================================
+!2006.06.13 - Sven
+
+Added LASTMOD_DATE to RelationalObjectTable. Field is updated for SV and MV 
+storage in RalObjectMgr and accessible through RelationalObjectTableRow.
+Added the corresponding tests as well.
+
+==============================================================================
+!2006.06.13 - Marco
+
+Removed extra transaction in RalObjectMgr.cpp (bug #17376).
+
+[Changes included by Andrea in COOL_1_3-branch on 2006.07.24]
+
+==============================================================================
+!2006.05.28 - Sven
+
+API changes. First prototype of channel metadata (channel name and number).
+
+==============================================================================
+!2006.05.19 - Marco (comments by Andrea)
+
+API changes. First prototype of PayloadSpecification API. No AMD64 port yet.
+
+TO DO (amongst other things):
+- check/validate the changes in the Oracle schema
+- in particular, check what happens with Oracle version numbers 8, 9, 10?
+- can we really let CORAL choose the SQL types? (else renable the tests!)
+- add an enum value for some unsupported types to be supported later?
+
+Implies changes in the test structure:
+[*Note: since a few releases, obsolete tests have been removed using 
+an "#ifdef NOPORT". A better solution would be to cvs delete the tests.]
+- added PayloadSpecification tests
+- removed(*) all RelationalDatabase tests, moved to PayloadSpecification tests
+  > encode/decode spec description
+  > decode bad specifications (empty spec, no colon, trailing comma)
+  > decodeOnlyOneColon test removed - new spec expects one colon instead of two
+- removed(*) all RelationalTypeConverter tests, obsoleted
+  > remove all tests to control SQL types (the new implementation lets CORAL 
+    choose SQL types, instead of choosing 9i/10g-dependent SQL types in COOL)
+  > oracleMajorVersionNumber test removed - use CORAL SQL types
+  > sqlTypeForCppType_oracle/mysql/sqlite tests removed - use CORAL SQL types
+  > checkStorageHintCompliance tests removed - no type/hint pairs
+    (this test was NOT testing that actual attribute values were compliant to
+    a hint, it was only testing that a given hint was valid for a given type)
+- removed some RalDatabase_extended tests, obsoleted
+  > test_unsupportedTypesXXX - obsolete, it is not possible to specify 
+    an unsupported type, simply because there is no enum value for it
+
+==============================================================================
+!2006.05.19 - Andrea
+
+Fixed bug #16903 in maxIovAtTime: this was not strictly necessary, as this
+is only called by fetchRowAtTimeSV, which is never used by the public API. 
+Later on, removed both unused methods fetchRowAtTimeSV and maxIovAtTime.
+
+[Changes included by Andrea in COOL_1_3-branch on 2006.05.19]
+
+==============================================================================
+!2006.05.18 - Andrea
+
+Created branch COOL_1_3-branch to fix pending bugs in COOL_1_3_2 if required.
+  cvs rtag -r COOL_1_3_2 -b COOL_1_3-branch cool/config
+  cvs rtag -r COOL_1_3_2 -b COOL_1_3-branch cool/RelationalCool
+
+==============================================================================
+!2006.05.17 - Sven
+
+First prototype of channel table to implement multi channel bulk insertion.
+No channel metadata yet. 
+
+No API changes.
+
+==============================================================================
+!2006.05.14 - Andrea
+
+Tag COOL_1_3_2a. Rebuild of the 1.3.2 release for the LCG_44 configuration.
+Upgrade to ROOT 5.11.02 using LCG_44 (from ROOT 5.10.00d using LCG_43b_2).
+
+No change in the source code. Software version remains "1.3.2".
+
+Six supported platforms: win32_vc71_dbg_wine,
+slc3_ia32_gcc323(_dbg/_gcov) and slc3_ia32_gcc344(_dbg).
+No MySQL support on Windows (no support in CORAL).
+No Frontier support on Windows (no client library from FNAL).
+
+Six test platforms: slc3_amd64_gcc344(_dbg),
+slc4_ia32_gcc345(_dbg) and slc4_amd64_gcc345(_dbg).
+Pending problems with slc4_ia32_gcc345(_dbg) only for SQLite.
+Pending problems with four AMD64 platforms mainly due to intrinsic 
+COOL problems with 32bit/64bit integer types (to be solved in COOL_1_4_0).
+
+==============================================================================
+!2006.05.10 - Andrea
+
+Tag COOL_1_3_2. Production release (backward-compatible 
+bug-fix and Frontier support release in the 1.3 series).
+
+Six supported platforms: win32_vc71_dbg_wine,
+slc3_ia32_gcc323(_dbg/_gcov) and slc3_ia32_gcc344(_dbg).
+
+Six test platforms: slc3_amd64_gcc344(_dbg),
+slc4_ia32_gcc345(_dbg) and slc4_amd64_gcc345(_dbg).
+Pending problems with AMD64 mainly due to 32bit/64bit integer types.
+Pending problems with SLC4 mainly due to wrong OracleAccess configuration.
+
+Upgrade to ROOT 5.10.00d and CORAL_1_4_3 using LCG_43b_2.
+Upgrade to ROOT 5.11.02 postponed to LCG44 because not yet requested
+(Atlas will build its release 12 using the LCG43 configuration).
+
+Add David Front's VerificationClient to the COOL release installation.
+Keep VerificationClient in its original CVS repository in the contrib area
+and install it as a subdirectory of the Utilities package at boostrap time.
+The only executable installed in the public PATH is coolVerificationClient.
+
+==============================================================================
+!2006.05.03 - Andrea, Marco, Sven 
+
+Bug fixes in COOL:
+- #16566 - IHvsNode::resolveTag() does not work for "local" tags
+- #16567 - IHvsNode::listTags() does not work for inner nodes
+- bugs in transaction handling (split findTagRecord from __findTagRecord)
+
+Added basic Frontier support:
+- Added frontier_client tool to the SCRAM configuration
+- Filed CORAL bug #16617 - authentication.xml user used as Oracle schema owner
+- Filed CORAL bug #16621 - success with "COUNT(*)" but failure with "count(*)
+- Implemented workarounds in COOL for both CORAL bugs    
+- SimpleRead example works successfully!
+[NB: remember to grant read privileges to PUBLIC from the Oracle account!]
+
+Prepare for API changes in COOL_1_4_0:
+- Prepared tests and examples to switch to read-only default in openDatabase.
+  Keep read-write as default in API until COOL_1_4_0 (backward compatibility).
+
+Internal cleanup:
+- Move many object-related methods from RalDatabase to RelationalObjectMgr.
+
+==============================================================================
+!2006.04.25 - Andrea, Marco, Sven
+
+Tag COOL_1_3_1. Production release (backward-compatible 
+COOL and CORAL bug-fix release in the 1.3 series).
+
+Bug fixes in COOL_1_3_1:
+- #16337 - PyCool assertions on Win (workaround for ROOT bug fixed in 5.11.02)
+- #16315 - exceptions not caught in coolDropDb (resulting in Win runtime error)
+- #16257 - folderset tag sequence table not created for createParents=true
+- #16179 - findObject does not find user tagged objects
+- fixed a feature in PyCoolTool that was preventing the use of aliases
+
+Bug fixes in CORAL_1_4_2 (binary compatible with CORAL_1_4_0):
+- #16189 - missing quotes around "order" column name in SQLite table creation
+
+Minor modifications to transaction handling (split createFolderSet with
+transactions from __createFolderSet without transactions).
+
+Maintained dependency on ROOT 5.10.00c (no upgrade to 5.11.02 yet).
+Added configuration infrastructure for SLC4.
+
+==============================================================================
+!2006.04.06 - Andrea
+
+Tag COOL_1_3_0. Functionality enhancement production release (first 
+release in the 1.3 series: backward incompatible API and schema changes).
+
+Main features with respect to COOL_1_2_8 and COOL_1_2_9:
+- upgrade to CORAL_1_4_0 using LCG_43_2
+- CORAL-based API, drop all POOL dependencies
+- user tags functionality according to spec #1
+- HVS functionality (limitation: the same tag cannot be used for >1 folders) 
+- schema evolution tool for user tag and HVS schema modifications
+- CORAL connection service (including use of connection aliases)
+- internal code cleanup (profound changes to the internal class structure)
+- performance improvements for SV folders (remove non-uniformity)
+- cool::Exception derived from std::exception instead of seal::Exception
+- PyCool rewritten from scratch
+
+Summary of API changes:
+- HVS functionality
+  > new IHvsNode methods: create/delete/findTagRelation and resolveTag
+  > new HVS exceptions Node/Tag[Relation]NotFound and NodeIsSingleVersion
+  > split IHvsNodeRecord from IHvsNode 
+  > limitation: the same tag name still cannot be used for more than one folder
+- prepare for further HVS features (reuse same tag name for several folders)
+  > changed std::string tagScope() to IHvsNode::Type tagNameScope()
+  > added std::vector<std::string> taggedNodes()
+- CORAL connection service (URLs can be specified using aliases)
+- user tags (storeObject accepts an optional tag name argument)
+  > added existsUserTag()
+- drop all POOL dependencies (API now based on coral::AttributeList)
+- cool::Exception derived from std::exception instead of seal::Exception
+- const qualifyers added to many methods (not yet complete)
+
+Summary of schema changes:
+- new userTagId column added to all IOV tables (both SV and MV)
+- new tag sequence table added for all folder sets
+- new global tag2tag table and sequence
+- schema evolution rows may exist in the main database table
+
+Summary of internal changes:
+- changes affected well over 50% of the total number of lines of code
+- new session manager class for session management
+- new query manager class for query and update management
+- new schema manager class for schema manipulations
+- new sequence manager class for sequence management
+- new transaction manager class for sequence management
+- new tag and node manager classes for HVS node and tag management
+- 50% of RalDatabase code and functionality moved elsewhere
+- significantly reduced ratio of CORAL specific Ral to generic Relational code
+- progress in clean separation of generic HVS to specific CondDB code
+- progress in adding const qualifyers wherever possible
+- progress in simplifying forward/backward pointers/references between mgrs
+- progress in separating record information (table rows) from active managers
+- tool-specific authentication and privilege managers moved to utilities
+
+==============================================================================
+!2006.04.06 - Andrea
+
+Summary of problems for Windows:
+- unknown exception thrown (workaround by Andrea)
+- MySQL still not supported by CORAL (COOL script workaround by Andrea)
+- os.sysconf not defined in Python (fixed by Marco)
+- ROOT window still pops up for Python (pending)
+
+==============================================================================
+!2006.03.22 - Andrea
+
+Internal tag COOL_1_3_0-pre1 (stable state before COOL_1_3_0).
+All C++, PyCool and PyCoolUtilities tests pass for slc3_ia32_gcc323_dbg.
+
+Main features with respect to COOL_1_2_8 and COOL_1_2_9:
+- tests executed using (private version of) CORAL_1_3_1
+- user tags functionality according to spec #1
+- schema evolution tool for user tag schema modifications
+- CORAL connection service
+- cleanup well advanced: profound changes to the internal class structure
+- performance improvements for SV folders (remove non-uniformity)
+- std exception
+- new PyCool
+- CORAL-based API, drop all POOL dependencies
+More complete details will follow in the COOL_1_3_0 release notes.
+
+Still missing on the way to COOL_1_3_0:
+- waiting for CORAL_1_4_0 release with ISessionProxy::serverFlavor()
+- use CORAL cross-backend connection aliases (dynamically retrieve flavor)
+- HVS
+- schema evolution tool for HVS
+
+==============================================================================
+!2006.03.03 - Andrea
+
+Backward-incompatible API change (start adding HVS functionality).
+
+Change the semantics of the tagScope method in IDatabase: it now returns 
+whether a tag can be used for inner nodes (folder sets) or leaf nodes
+(folders), rather than returning the node name it is used for. In HVS 
+(following a request from LHCb), the same tag name can be used for only 
+one folder set or for several folders. There is not anymore a unique node
+each tag can be attached to. Also, a tag can be reserved for inner nodes
+or leaf nodes without being actually attached to any specific nodes yet.
+
+No change in relational schema yet. 
+The schema still forces tags to be assigned to only one folder or folder 
+set, even if the API assumes that a tag can be assigned to several folders.
+
+==============================================================================
+!2006.03.02 - Uli
+
+Removed non-uniformity in IOV retrieval for SV folders by implementing
+Andrea's proposal for a two-step query strategy - query max(since)
+followed by query for since=max(since).
+
+==============================================================================
+!2006.03.01 - Andrea
+
+Completed internal formal cleanup of IOV table queries.
+All IOV table queries have now been moved from RalObjectTable to 
+RelationalObjectTable and proceed through generic (non-CORAL specific) 
+methods in RelationalQueryMgr (implemented via CORAL in RalQueryMgr).
+
+==============================================================================
+!2006.03.08 - Marco
+
+*** BRANCH RELEASE NOTES ***
+
+Tag COOL_1_2_9 (non-HEAD branch after COOL_1_2_8).
+Backward-compatible production release.
+Same code as 1.2.8, but compiled against LCG_42_4.
+
+==============================================================================
+!2006.01.27 - Andrea
+
+Tag COOL_1_2_8. Backward-compatible production release (internal migration 
+from SEAL Reflex to ROOT Reflex; port to gcc344; attempted port to AMD64).
+
+Minor API changes ("long" -> "int") to attempt AMD64 port, should be
+backward compatible for users on 32bit machines. No added functionalities. 
+
+==============================================================================
+!2006.01.27 - Andrea
+
+Note about the port from Reflection to Reflex: workarounds have been added 
+because SEAL exceptions are not caught from Cintex. This was already an 
+issue in COOL_1_2_7 (SEAL Cintex) and remains in COOL_1_2_8 (ROOT Cintex).
+This was possible in PyLCGDict2/Reflection but was removed from Cintex/Reflex.
+- Bug report (bug #14685): cintex does not catch seal exceptions
+- Could be solved by deriving seal::Exception from std::exception (sr #100955)
+
+==============================================================================
+!2006.01.27 - Sven
+
+Changes in handling of count(*) return type to ensure compatibility with MySQL
+server 5.0 : essentially use the default CORAL return type (thanks to Ioannis).
+
+==============================================================================
+!2006.01.27 - Andrea
+
+Many changes towards completing the AMD64 port (Uli, Sven, Marco, Andrea).
+Got rid of "long" wherever possible, replaced by "int".
+
+Used many #ifdef to disable parts of the code on AMD64 
+(essentially the storage of "long", keeping only "int" and "long long"),
+but this is not a valid solution: all three types must be analysed,
+the solution should be to throw an exception when storing "long".
+This should be for 32bit platforms too for portability and will break the 
+current API for 32bit platforms (users should only store "int", not "long").
+
+AMD64 port not completed because of pending bugs in CORAL and POOL:
+- AttributeList in CORAL and POOL must analyse all three integers
+  (segmentation fault for missing integer type - bug #14684)
+- MySQLAccess and SQLiteAccess return 4294967295 when 9223372036854775807 
+  was stored (bug #14688)
+
+Before completing the AMD64 port, a SEAL feature may also be changed:
+- IntBits<64> is long long on 32bit, long on 64bit platforms (bug #14671)
+
+After solving all problems in SEAL, CORAL and POOL for AMD64,
+a few pending issues in COOL also need to be addressed:
+- Bug in COOL, at first incorrectly identified as a bug in ROOT (bug #14681)
+
+==============================================================================
+!2006.01.16 - Andrea
+
+Tag COOL_1_2_7. Backward-compatible production release
+(internal migration from RAL to CORAL and from Reflection to seal Reflex).
+
+All tests successful against Oracle, MySQL and SQLite using CORAL_1_2_1
+(including many CORAL bug fixes contributed by the COOL team).
+
+Workarounds for problems in PyCool and PyCoolUtilities after Reflex migration:
+- disabled tests with mutex lock in boost/PyROOT (all platforms and backends)
+- hacked config to have SEAL before ROOT (different/incompatible PyCintex.py)
+- manually minimize windows during Windows test execution (ROOT window popup)
+
+Workaround in Examples for minor MySQLAccess bug (insertion of "'" character).
+
+First release with MySQL support on Windows (thanks to CORAL migration).
+
+==============================================================================
+!2006.01.11 - Marco
+
+Complete migration of PyCool from seal Reflection to seal Reflex.
+New mutex lock problem observed from boost/PyROOT/Reflex interaction.
+
+==============================================================================
+!2005.12.16 - Marco
+
+First release candidate for COOL_1_2_7 based on CORAL_1_2_0.
+MySQL and SQLite tests still fail.
+
+==============================================================================
+!2005.12.09 - Marco
+
+Added thin layer to make the public API backward compatible.
+Methods returning new CORAL AttributeList 
+kept as temporary extension, with suffix _new.
+
+Fixed gcc 3.4.4 compilation (bug #13395)
+
+==============================================================================
+!2005.12.08 - Sven
+
+Internal reimplementation based on CORAL. 
+Oracle tests successful. MySQL and SQLite tests fail.
+
+API not backward compatible: POOL AttributeList 
+replaced by CORAL AttributeLists in the API.
+
+==============================================================================
+!2005.11.15 - Andrea, Sven
+
+Internal tag COOL_1_2_7-pre1 (prepare for the CORAL migration).
+All C++, PyCool and PyCoolUtilities tests pass for slc3_ia32_gcc323_dbg.
+
+Fix eight bugs in transaction handling (read-write transactions instead of 
+read-only transactions were started in RalDatabase).
+
+New IteratorIsClosed exception. Rename IteratorHasStarted as IteratorIsActive.
+
+Added IObjectIterator::close() API and implementation.
+
+==============================================================================
+!2005.11.15 - Marco
+
+Tag COOL_1_2_6. Production release (backward-compatible 
+SEAL_1_7_6 and POOL_2_2_4 upgrade release in the 1.2 series).
+
+==============================================================================
+!2005.11.09 - Marco
+
+Change the definition of int64 min/max value constants in types.h.
+After upgrading to SEAL_1_7_6, seal::IntTraits<>::Min/Max fail at link time 
+on Windows. Temporary (?) workaround: use in COOL the same values that are 
+used in the SEAL IntTraits.cpp implementation (taken from SealBase/LongLong.h).
+
+==============================================================================
+!2005.11.02 - Sven, Andrea
+
+Added IDatabase::openDatabase() and closeDatabase() API and implemntation.
+
+Added ObjectNotFound exception to the API.
+
+Added implicit ChannelSelection constructor from a ChannelId to the API.
+Removed IFolder::browseObjects for a single channel (user code is not 
+broken as it can now use the implicit conversion to ChannelSelection).
+
+Added IFolder::countObjects API and implementation.
+
+Added live browsing functionalities for object iteration.
+Added IFolder::setPrefetchAll() API and implementation (to choose 
+whether the browse methods should return a vector or live iterator).
+
+Added IObjectVector and IObjectVectorPtr type definitions to the API.
+Added IObjectIterator::fetchAllAsVector API and implementation
+(to retrieve all objects in the iterator as an STL vector).
+
+First prototype of STL-like iterator interface for object browsing.
+Removed from public API, may be reintroduced later on.
+
+Clean up RalDatabase implementation using session() instead of m_session.
+
+Start internal reimplementation using new classes Ral/RelationalQueryMgr
+and RelationalTableRow to remove some responsibilities from RalDatabase.
+
+==============================================================================
+!2005.10.24 - Andrea, Marco
+
+Tag COOL_1_2_5. Production release (backward-compatible 
+SEAL_1_7_5 and POOL_2_2_3 upgrade release in the 1.2 series).
+
+Retag COOL_1_2_4 code as COOL_1_2_5. 
+Do not include changes other than those in VersionInfo and related tests. 
+
+==============================================================================
+!2005.10.05 - Andrea
+
+Add scripts for gathering Oracle table/schema statistics.
+
+==============================================================================
+!2005.09.29 - Andrea, Sven, Marco, David, Uli
+
+Tag COOL_1_2_4. Production release (backward-compatible 
+bug-fix and POOL_2_2_1 upgrade release in the 1.2 series).
+
+VersionInfo:
+- Release number = 1.2.4
+- Schema version = 1.2.0
+Backward compatibility with data written 
+using previous releases 1.2.3, 1.2.2, 1.2.1 and 1.2.0.
+
+All tests pass on all four supported platforms: slc3_ia32_gcc323, 
+slc3_ia32_gcc323_dbg slc3_ia32_gcc323_gcov and win32_vc71_dbg.
+
+- Upgrade to POOL_2_2_1 and SEAL_1_7_3 using LCG_37_2a
+
+- Identified and fixed outstanding memory leaks in COOL and POOL
+  (in close collaboration between the COOL and POOL teams for POOL)
+  > memory leak in all three flavours of RAL queries fixed in POOL_2_2_1 
+    (destructor for Oracle/MySQL/SQLite cursor was not called - note that 
+    protected virtual destructor for IRelationalCursor is still missing)
+  > memory leak in AttributeList (only observed for osx103) fixed in 
+    POOL_2_2_1 (missing destructors for Attribute[List][Specification])
+  > memory leak in COOL fixed by disabling cool::TimingReport
+    (workaround: the real leak still needs to be identified and removed)
+  > ported ProcMemory utility class to osx103 and Windows for memory leak 
+    analysis on Mac and Windows
+
+- Internal implementation changes
+  > move large fraction of RalDatabase.cpp to new class RelationalObjectTable
+
+==============================================================================
+!2005.08.29 - Andrea, Sven and Marco
+
+Tag COOL_1_2_3. Production release (backward-compatible 
+API enhancement and bug-fix release in the 1.2 series).
+
+VersionInfo:
+- Release number = 1.2.3
+- Schema version = 1.2.0
+Backward compatibility with data written 
+using previous releases 1.2.2, 1.2.1 and 1.2.0.
+
+All tests pass on all four supported platforms: slc3_ia32_gcc323, 
+slc3_ia32_gcc323_dbg slc3_ia32_gcc323_gcov and win32_vc71_dbg.
+
+==============================================================================
+!2005.08.26 - Andrea and Sven
+
+- Move current mechanism for CLOB support from private to TEMPORARY public API
+  > document it as a TEMPORARY API extension that may be removed in COOL_1_3_0
+
+==============================================================================
+!2005.08.18 - Andrea and Sven
+
+- Added IDatabase::tagScope( tagName ) to get the scope of a tag (Andrea)
+  > returns the name of the node where the tag is defined
+  > throws TagNotFound if not found and ReservedHeadTag for HEAD tags
+
+- Added IDatabaseSvc::serviceVersion() to get library release tag (Andrea)
+
+==============================================================================
+!2005.08.10 - Andrea and Sven
+
+- Added IFolder::folderAttributes() to get backend-specific properties (Andrea)
+  > for MV folders (3): the names of the IOV, tag and IOV2tag tables
+  > for SV folders (1): the name of the IOV table
+
+- Progress in understanding of problems with MyODBC bulk insertion (Marco)
+  > introduced workaround in COOL to disable MyODBC bulk insertions for all
+    tables with over 8kb data volume in each row (summed over all columns):
+    the problem does not affect only CLOBs, for instance bulk insertion into
+    three characters of 3000 characters would also generate a runtime error
+  > also understood that "bulk insertion" in MyODBC does not use bind 
+    variables: this may imply a potentially large performance penalty 
+    (which may be enough to motivate a switch from MyODBC to native MySQL API)
+
+- Internal support for CLOBs - not yet exposed in the public API (Marco)
+  > enable 'storage hints' for 64K and 16M CLOBs
+  > add tests of CLOB storage and retrieval using orivate API
+
+- Bug fixes in tag handling (Andrea)
+  > deleteGlobalTagTableRow was taking only one tagId argument, but the
+    PK for the global tag table also includes nodeId
+  > also correct error message printed out by deleteGlobalTagTableRow
+
+- API extensions for multi-channel bulk retrieval (Sven)
+  
+- First prototype of infrastructure to create doxygen-based user guide (Andrea)
+
+==============================================================================
+!2005.07.27 - Andrea and Sven
+
+Tag COOL_1_2_2. Production release (upgrade to SEAL_1_7_1 bug fix release).
+
+VersionInfo:
+- Release number = 1.2.2
+- Schema version = 1.2.0
+Backward compatibility with data written 
+using previous releases 1.2.1 and 1.2.0.
+
+All tests pass on all four supported platforms: slc3_ia32_gcc323, 
+slc3_ia32_gcc323_dbg slc3_ia32_gcc323_gcov and win32_vc71_dbg.
+
+- Upgrade to POOL_2_1_2 and SEAL_1_7_1 using LCG_36_2a.
+  No change in the COOL code.
+
+- Upgrade to POOL_2_1_2 includes bug fix proposed by Marco for CLOBs 
+  in OracleAccess (with extra improvements by Ioannis).
+
+==============================================================================
+!2005.07.20 - Andrea and Sven
+
+Tag COOL_1_2_1. Production release (backward-compatible 
+API enhancement and bug-fix release in the 1.2 series).
+
+VersionInfo:
+- Release number = 1.2.1
+- Schema version = 1.2.0
+Backward compatibility with data written using previous release 1.2.0.
+
+All tests pass on all four supported platforms: slc3_ia32_gcc323, 
+slc3_ia32_gcc323_dbg slc3_ia32_gcc323_gcov and win32_vc71_dbg.
+
+- Privilege management
+  > completed API and tools to grant reader, writer and tagger privileges:
+    added coolPrivilege command line utility to implemente them;
+    completed test suite in tests/Privileges (only tested on Oracle!)
+  > added private relational exceptions TableNotDropped, RowNotUpdated, 
+    RowNotDeleted, RowNotInserted to test exceptions thrown because 
+    of missing database privileges
+  > still missing for a future release (if needed): test on MySQL
+
+- Bug fixes in POOL
+  [available in POOL_HEAD two weeks ago but not included in COOL_1_2_1-pre1]
+  > "max# of open cursors exceeded" reported by David in Oracle,
+    identified by Sven in bulk insertion and fixed by Ioannis
+    [unfortunately this does not help much with memory leak reported by David]
+  > "pthread_mutex_lock" fixed by Ioannis using Andrea's suggestion to
+    disable Oracle multithreading (replace OCI_THREADED by OCI_DEFAULT)
+    [pthread_mutex_lock is indeed solved by removing OCI_THREADED:
+     cross-checked by running the same test with the ONLY difference
+     of enabling/disabling OCI_THREADED in a custom private version of POOL]
+
+- First production release with support for SQLite.
+  All unit tests pass for SQLite (after upgrade to POOL_2_1_1).
+
+- Extensive API cleanup for tag handling for HEAD and single-version folders
+  > add FolderIsSingleVersion exception: this is thrown for SV folders 
+    by IFolder::tag() and internally by RelationalFolder::tagTableName() 
+    and RelationalFolder::object2TagTableName()
+  > add ReservedHeadTag exception: this is thrown when trying to tag a node
+    using the "" or "HEAD" tags or trying to delete the "" or "HEAD" tags
+  > treat "" and "HEAD" (or any case insensitive variant such as "head" or
+    "Head") as equivalent in all methods: add method IHvsNode::isHeadTag()
+    method to test if a tag name is a reserved HEAD tag
+  > except for "HEAD", all other tag names are case sensitive
+  > IDatabase::existsTag() now returns true for both "" and "HEAD"
+  > IFolder::findObject() and IFolder::browseObjects() now accept both ""
+    and "HEAD" to indicate the HEAD tag; for all other tag names, throws 
+    TagNotFound if tag does not exist or folder is a single version folder
+  > IFolder::tag() throws ReservedHeadTag for "" and "HEAD"; for all other 
+    tag names, throws FolderIsSingleVersion for single version folders 
+    and TagExists if the tag already exists for multi-version folders
+  > IFolder::deleteTag() throws ReservedHeadTag for "" and "HEAD"; for all 
+    other tag names, throws TagNotFound if tag does not exist or folder is 
+    a single version folder
+  > IHvsNode::listTags() does NOT list "" or "HEAD"; 
+    it returns an empty list for folder sets and SV folders
+  > IHvsNode::tagDescription() returns default "HEAD tag" for "" and "HEAD";
+    it throws TagNotFound for all other tags in folder sets and SV folders
+  > IHvsNode::tagInsertionTime() returns node insertion time for "" and "HEAD";
+    it throws TagNotFound for all other tags in folder sets and SV folders
+
+- Further improvements in API for tagging methods
+  > declare the two tag() methods obsolete (to be removed in COOL_1_3_0) 
+    in IFolder, rename them as tagCurrentHead and tagAsOfDate
+    [very dangerous in RalDatabase: tag() method with asOfDate argument was
+    called instead of tag() method with asOfObjectId argument if the latter
+    was commented out - implicit conversion of unsigned long to seal::Time!]
+  > add IFolder::tagLastObjectTime method
+  > use a string reference argument instead of a string argument
+    in IHvsNode::tagDescription and IHvsNode::tagInsertionTime
+
+- Internal cleanup of HvsNode, RelationalFolder and RelationalFolderSet
+  > renamed HvsNode as RelationalHvsNode
+  > RelationalFolder[Set] derived class inheriting from RelationalHvsNode
+    (modified listTags, tagDescription and tagInsertionTime accordingly):
+    this implied some debugging of 'inheritance by dominance' on Windows
+    and forced the use of inlined constructors for RelationalFolder[Set]
+
+- Bug fixes
+  > deleteTag() throws an exception if the number of rows deleted from the 
+    object2tag table is different from the selected COUNT(*) for such rows 
+    (computed using new method countObject2TagTableRows)
+  > IDatabase::dropNode also deletes any tags associated to the node
+    (and throws a RelationalException if such tags cannot be deleted)
+
+- Unit test coverage reports
+  > added support for slc3_ia32_gcc323_gcov: unit test coverage reports 
+    will be built by the SPI team (thanks to Johanne!)
+
+==============================================================================
+!2005.07.07 - Andrea and Sven
+
+Tag COOL_1_2_1-pre1. Internal tag.
+
+- Bug fixes in COOL:
+  > bug in dropping MV tables (reported by Federico, fixed by Sven)
+  > uninitialized variable in RelationalTypeConverter (Sven/Andrea)
+
+- API improvements
+  > added method IFolder::deleteTag (Sven)
+  > clarified exceptions thrown by dropDatabase and dropFolder methods,
+    throwIfDoesNotExist flag in dropDatabase and dropNode declared obsolete:
+    kept for backward compatibility, will be removed in COOL_1_3_0 (Andrea)
+  > add isFolderSet/isFolder flag to Folder/FolderSetNotFound exceptions
+
+- Internal refactoring
+  > new implementation of fetchObjectTableRows (Sven)
+  > gmtime tests moved to test_utilities, now included in test suite (Sven)
+  > add private NodeTableRowNotFound exception to fix inconsistencies (Andrea)
+  > extensive cleanup of dropDatabase and dropNode (Andrea)
+
+- Started work on privilege management (Andrea)
+  > added private class RalPrivilegeManager
+  > added tests to access database as owner/reader/writer/tagger/nopriv role
+
+- Bug fixes in POOL (see COOL_1_2_1) available in POOL_HEAD but not yet 
+  included (tests for COOL_1_2_1-pre1 executed using POOL_2_1_0)
+
+==============================================================================
+!2005.06.28 - Andrea and Sven
+
+Tag COOL_1_2_0. Production release (first release in the 1.2 series).
+
+VersionInfo:
+- Release number = 1.2.0
+- Schema version = 1.2.0
+Backward compatibility with data written using NO previous release.
+
+All tests pass on all three supported platforms:
+slc3_ia32_gcc323, slc3_ia32_gcc323_dbg and win32_vc71_dbg.
+
+All tests executed also on all RH73 platforms using private POOL_2_1_0
+(this was actually done using the code as of June 20, before some last fixes).
+Last release with unit tests run on RH73 (not supported anymore by POOL/AF).
+All tests pass on rh73_gcc323, rh73_gcc32 and rh73_gcc32_dbg, but the
+RalDatabase unit test HANGS (__pthread_mutex_lock) on rh73_gcc323_dbg.
+Commit the log file with failure (after Ctrl-C) fo reference.
+Do not attempt to debug the problem, as RH73 is not supported anymore.
+
+PS: A __pthread_mutex_lock was also observed on SLC (in the same method
+as RH73, the first time the unit tests were executed. The problem 
+disappeared when the unit tests were rerun on another SLC host.
+It is likely that the source of the problem has been identified as the use 
+of multi-threaded OCI in RAL and will be removed in the next release of POOL.
+
+==============================================================================
+!2005.06.28 - Andrea and Sven
+
+- Workaround for a bug in the seal::Time constructor.
+  > The bug affected unit tests on Windows (which may or may not fail 
+    depending on local environment such as the summer time clock setting).
+
+- API enhancements
+  > Add the setDescription() method to change folder/folderset descriptions
+
+- Bug fix
+  > Fix bug reported by Federico: when inserting [20,+inf) over [30,+inf)
+    in single version mode, the latter was modified to [30,20]
+
+==============================================================================
+!2005.06.17 - Andrea and Sven
+
+- Payload type handling improvements
+  > restrict uInt64 user payload to same 63-bit range as IOVs [0, 2^63-1]
+
+- Internal code cleanup
+  > tidy up (a bit, not complete!) the fetching of rows from the IOV table
+
+==============================================================================
+!2005.06.13 - Andrea and Sven (with useful contributions from MANY people!)
+
+Tag COOL_1_2_0-pre1. Internal tag.
+
+- API changes (backward-incompatible)
+  > add IFolderSet interface and related methods in IDatabase
+  > changed IDatabase::dropFolder to dropNode
+  > removed IDatabase::listFolders 
+  > implementation code has been changed accordingly
+
+- Performance improvements (pbs reported by DirkD)
+  > SV insertion: better scalability of query for last IOV by querying max(Id)
+  > findObject(): factor 2 improvement by removing useless node table lookup
+
+- Schema improvements (schema changed to 1.1.1)
+  > store insertion times as GMT with " GMT" appended (pb reported by Torre)
+  > change name of unique constraint on tag name
+  > changed index on node full path to unique (pb reported by DavidF)
+  > prepared simple utility to dump the COOL Oracle schema
+
+- DatabaseId and authentication improvements
+  > support POOL XMLAuthenticationService (also support COOL URL syntax)
+  > hide passwords from all printouts in the implementation code
+  > support the "host:port[/service]" syntax for Oracle and MySQL 
+
+- Payload type improvements (thanks to Rado and Ioannis for RAL fixes)
+  > reenabled bool and unsigned char user payload (fixed in POOL HEAD)
+  > internally replaced maxSizeForCpp by checkStorageHintCompliance
+
+- Work on SQLite support (thanks to MarcoC and Zhen for many patches)
+
+All tests pass on rh73_gcc323 (using privately built POOL libraries
+from POOL HEAD at -D "2005/06/15 12:00:00", later than POOL_2_1_0-zeta).
+
+==============================================================================
+!2005.05.25 - Andrea and Sven
+
+Tag COOL_1_1_0. Production release (first release in the 1.1 series).
+
+VersionInfo:
+- Release number = 1.1.0
+- Schema version = 1.0.1
+Backward compatibility with data written using releases 1.0.2 and 1.0.1.
+
+All tests pass on all seven supported platforms.
+
+==============================================================================
+!2005.05.23 - Andrea and Sven
+
+Tag COOL_1_1_0-pre1. Internal tag.
+
+Major code repackaging and API changes
+- RelationalCool is a plugin with no public header file
+- move technology-independent exceptions from RelationalCool to CoolKernel
+- move database service factory (and dependency on SealServices) from 
+  RelationalCool to new package CoolApplication: there are now four tagged 
+  packages in src (CoolKernel, RelationalCool, CoolApplication, Utilities)
+
+Functionality and performance improvements
+- simultaneous bulk insertion into many channels does not throw an exception 
+  any more (but more complete performance optimization will come in later tags)
+- internally refactor store[Single/Multi]VersionObjects to use common code
+
+All tests pass on rh73_gcc323.
+
+==============================================================================
+!2005.05.09 - Andrea and Sven
+
+Tag COOL_1_0_2. Production release (backward-compatible 
+API enhancement and bug-fix release in the 1.0 series).
+
+API enhancements:
+- IFolder::listChannels
+- IHvsNode::listTags and two related methods
+
+Bug fixes:
+- prevent creation of two folders with the same name from two concurrent jobs
+
+VersionInfo:
+- Release number = 1.0.2
+- Schema version = 1.0.1
+Backward compatibility with data written using release 1.0.1.
+
+All tests pass on all seven supported platforms.
+
+First production release using the new COOL CVS repository.
+
+==============================================================================
+!2005.05.02 - Andrea and Sven
+
+Tag COOL_1_0_2-pre1. 
+
+Internal tag: same code as COOL_1_0_1, using the new COOL CVS repository.
+
+==============================================================================
+!2005.04.25 - Andrea and Sven
+
+Tag COOL_1_0_1. Production release (bug fix release in the 1.0 series).
+
+Bug fix: ValidityKey range checks added for MultiVersion folders.
+
+VersionInfo:
+- Release number = 1.0.1
+- Schema version = 1.0.1
+Backward compatibility with data written using NO previous release.
+
+All tests pass on all seven supported platforms.
+
+ValidityKey type definition and allowed range unchanged: unsigned int64 
+in [0, +9223372036854775807]. Schema version number changed to 1.0.1
+just to enforce that ValidityKey's > +9223372036854775807 are excluded.
+
+Support for unsigned int64 in user defined folder payload is unchanged.
+Users can store also values in [+9223372036854775808, +18446744073709551615],
+as long as they are aware how MySQL would interpret any queries on them.
+In any case, it is not the responsibility of COOL to implement such queries.
+
+==============================================================================
+!2005.04.22 - Andrea and Sven
+
+Tag COOL_1_0_0. FIRST PRODUCTION RELEASE!
+
+Minor change in SQL types: hack to change "RAL default" to NUMBER(10)
+for long and unsigned long, and to NUMBER(20) for unsigned long long.
+
+Small bug fix in the unit tests (check on ValidityKeyMin hardcoded value).
+
+VersionInfo:
+- Release number = 1.0.0
+- Schema version = 1.0.0
+
+All tests pass on all seven supported platforms 
+(rh73_gcc323, rh73_gcc323_dbg, rh73_gcc32, rh73_gcc32_dbg, 
+slc3_ia32_gcc323, slc3_ia32_gcc323_dbg, win32_vc71_dbg).
+
+Dropped the idea of reviewing PK, UK and FK constraints and indexes as 
+it might take too much time. This can still be done in the next release.
+Scripts can be provided to upgrade the schema, to add a few missing columns 
+(e.g. node_id with a fixed value in all folder-specific tables, usertag_id 
+in the IOV table...) and to drop and recreate indexes and constraints.
+
+Dropped the idea of providing Mac support and/or of providing scripts
+for standalone local installations. These issues will be addressed later.
+
+==============================================================================
+!2005.04.21 - Andrea and Sven
+
+Tag COOL_1_0_0-pre3 (production release 1.0.0 third internal prerelease).
+
+Extensive checks of SQL types. 
+Forced to introduce many workarounds for bugs and features in RAL and Oracle.
+
+- Problem with signed long long
+  (OCI-22053 when retrieving LLONG_MIN = -9223372036854775808).
+  This could be cured by limiting long long to >= -9223372036854775807.
+  TEMPORARY? More radical approach: get rid of signed long long for now.
+  Declare that long long in user payload is not supported.
+  *** Change ValidityKey to unsigned long long, but use only 63 bits      ***
+  *** Change ValidityKeyMin to 0, keep ValidityKeyMax=9223372036854775807 ***
+  Eventually: rediscuss with the users if they want a signed or unsigned key.
+  Eventually: implement C++ check that user payload long long >= sInt64Min+1.
+
+- Problem with bool
+  (bug in RAL bulk insertion for both Oracle/MySQL, false=0 stored as true=1).
+  TEMPORARY! Declare that bool is not supported in user payload.
+  Eventually: bug fixed in OracleAccess-1-5-4 and ODBCAccess-1-1-14.
+
+- Problem with unsigned char
+  (no default SQL type in RAL OracleAccess).
+  TEMPORARY! Declare that unsigned char is not supported in user payload.
+  Eventually: bug fixed in OracleAccess-1-5-5.
+
+- Problem with long double
+  (no default SQL type in RAL MyODBCAccess).
+  TEMPORARY! Declare that long double is not supported in user payload.
+  Eventually: bug should be fixed in new MyODBCAccess.
+
+- Problems with char
+  (MySql error "String data, right truncated" in reading back 'a' or 'Z')
+  (Oracle stores and retrieves different values for binary data CHAR_MIN/MAX)
+  TEMPORARY! Declare that char is not supported in user payload.
+  Eventually: investigate and fix/workaround the two bugs
+  (should there be also a check that char is used only for character data?).
+  
+==============================================================================
+!2005.04.20 - Andrea and Sven
+
+Tag COOL_1_0_0-pre2 (production release 1.0.0 second internal prerelease).
+
+Final bug fixes. All tests pass on all seven supported platforms.
+
+==============================================================================
+!2005.04.16 - Andrea and Sven
+
+Tag COOL_1_0_0-pre1 (production release 1.0.0 first internal prerelease).
+
+Code tested on rh73_gcc323 using the current configuration (one failure).
+To do before the production release:
+- fix the test that failed
+- update to latest SEAL/POOL releases
+- run tests on all four platforms
+
+Latest features added:
+- Added ExtendedAttributeListSpecification adding one "hint" for each 
+  attribute. This is used to create tables with non-default SQL types
+  (such as 4000-characters string instead of 255-character). Size
+  compliance checks are implemented everywhere. Hints (strings) replace the
+  previous implementation based on unsigned long sizes.
+
+Updated TODO list of functionalities to add in backward compatible way
+(AFTER THE PRODUCTION RELEASE AND ITS DOCUMENTATION!):
+- Add tests that folder description and tag description are limited in size
+- Expose non-default hint functionality in public API to allow
+  storage of 4000 character strings
+- The same functionality may be extended to store NUMBERS instead
+  of native BINARY_FLOAT in Oracle if requested for PVSS
+- Once the problems with CLOB in Oracle are solved, add CLOB support 
+- Add methods to browse through the folder set hierarchy
+- Add methods to add references to external tables
+- Add user tags (this will require adding some columns)
+- Review indexes, UK, FK in the relational schemas (this will require
+  creating methods and/or scripts to drop all indexes and FKs and
+  recreate new ones)
+
+==============================================================================
+!2005.04.09 - Andrea and Sven
+
+Intermediate changes towards the production release:
+- Renumber object_id encoding schema from 3N+0,1,2 to 6N+0,1,2,3,4,5
+  to foresee the future implementation of user tags
+- Implement string size checks in some of the tables
+- Implement non-default string SQL types for some columns of some tables
+
+==============================================================================
+!2005.04.05 - Andrea and Sven
+
+Intermediate changes towards production release (up to and including April 5):
+- Renumber object_id to keep objects ordered with respect to version 'layers'
+  (also introduce internal tagAsOfObjectId functionality and unit tests for it)
+- Introduce release number comparison (start addressing schema evolution)
+- Internal name changes XXX_FOLDERS to XXX_NODES, folderId to nodeId, 
+  FolderTable to NodeTable, FolderExistsException to NodeExistsException etc...
+- Various bug fixes (browsing, MV-processing...)
+
+==============================================================================
+!2005.03.20 - Andrea and Sven
+
+Intermediate tags towards the production release.
+
+Tag COOL_0_2_0-pre4:
+- Final step in int64 IOV implementation: change ValidityKeyMin/Max
+  to LONG_LONG_MIN/MAX [-9223372036854775808, +9223372036854775807].
+
+Tag COOL_0_2_0-pre3:
+- Implemented since/until IOV storage type as signed int64. All tests pass.
+  No change in the accepted min/max boundaries for IOVs yet.
+- Bug fix in RelationalFolder: clear storage buffer when storing fails
+- This tag requires RelationalAccess-1-5-0 and OracleAccess-1-5-1 or later 
+  (POOL tag does not exist yet, COOL config will be modified and retagged)
+
+Tag COOL_0_2_0-pre2:
+- Name change: rename IValidityKey as ValidityKey and IChannelId as ChannelId 
+  and check that all tests still pass. No change in stored type yet.
+
+Tag COOL_0_2_0-pre1:
+- Minimal change: replace seal::LongLong by seal::IntBits<64>::SLeast
+  and check that all tests still pass. No change in stored type yet.
+
+==============================================================================
+!2005.03.19 - Andrea and Sven
+
+Intermediate tags towards the production release.
+
+Tag COOL_0_1_1-pre2:
+- Bypassed segmentation fault and mutex lock by using debug libraries
+  also on non-debug platforms
+- Reenabled all test in RalDatabase_versioning test
+- All tests from execUnitTests pass for both Oracle and MySQL on all of
+  rh73_gcc323, rh73_gcc323_dbg, rh73_gcc32, slc3_ia32_gcc323
+- Last stable tag before starting the implementation of int64 and CLOBs
+
+Tag COOL_0_1_1-pre1:
+- Fixed the problem with tagging in MySQL 
+  (change COOL usage of bind variables to bypass RAL problem)
+- Changed online/offline to single/multi version
+- Changed till to until consistently
+- Changed getters consistently
+- Consistently removed NULL values from all database tables
+  (copying AttributeList's will not work with NULL result sets from RAL)
+- Fixed bugs in COOL with MySQL date (%i format and second granularity) and 
+  MySQL bind variables (they need to be in the same order in the AttrList)
+  and fixed bugs in RAL (as of POOL_2_0_2) with MyODBC '\0' strings
+- Move description() method for folders to IHvsNode and return 
+  a string reference consistently to other IHvsNode string methods.
+- Add a method to declare that some payload columns reference external payload.
+  Dummy implementation for the moment.
+- Identified a workaround for the segmentation faults and mutex locks found 
+  in RalDatabase_versioning test. Will become default as of next tag.
+
+==============================================================================
+!2005.03.03 - Andrea and Sven
+
+First complete prototype with the versioning and tagging functionalities.
+Tagged as prerelease COOL_0_1_0-pre1.
+Tagged as prerelease COOL_0_1_0-pre2 (only configuration changes).
+
+This pre-release suffers from a known problem with MySQL in RAL 
+("since < :a and :a < until" will not work): use it only for Oracle.
+
+==============================================================================
+!2005.02.02 - Andrea and Sven
+
+First version made publicly available for feedback.
+Tagged as prerelease COOL_0_0_3-pre1.
+Tagged as prerelease COOL_0_0_3-pre2 with Windows support added.
+
+==============================================================================
+!2004.11.21 - Andrea and Sven
+
+New package. 
+
+This package contains the implementation of the Cool kernel component
+using the POOL RelationalAccess layer (RAL).
+
+==============================================================================
diff --git a/RelationalCool/doc/unit_test_log.txt b/RelationalCool/doc/unit_test_log.txt
new file mode 100644
index 000000000..35e426799
--- /dev/null
+++ b/RelationalCool/doc/unit_test_log.txt
@@ -0,0 +1,68 @@
+Passing tests on a given date. Failures in square brackets.
+
+                     2004-11-30  2004-12-01  2004-12-02  2004-12-05
+RalDatabase               4           5           9          12
+RalDatabaseSvc            2           2           2           3
+RelationalDatabase        1           1           1           1
+RelationalFolder          1           2           2           2
+
+                     2004-12-13  2004-12-15  2004-12-15
+RalDatabase              12          15          19
+RalDatabaseSvc            2           3           3
+RelationalDatabase        1           1           1
+RelationalFolder          1           4           6
+
+                     2005-01-03  2005-01-14  2005-01-20  2005-01-26
+RalDatabase              20          23          23          23
+RalDatabaseSvc            3           4           4           4
+RelationalDatabase        1           1           1           1
+RelationalFolder          6           6           7           7
+
+                     2005-02-02  COOL_0_0_3-pre1  2005-02-04
+RalDatabase              29          29               29
+RalDatabaseSvc            4           4                4
+RelationalDatabase        1           1                1
+RelationalFolder          8           8                8
+HvsPathHandler            5           5                5
+
+                     2005-02-13  2005-02-15  2005-02-21  2005-03-01
+RalDatabase              59          32          32          32
+RalDatabase_versioning               29          29          51
+RalDatabaseSvc            4           4           4           4
+RelationalDatabase        1           1           1           1
+RelationalFolder          8           8           8           8
+HvsPathHandler            5           5           5           5
+
+                     2005-03-08  2005-03-17  2005-03-27  2005-04-04
+RalDatabase              32          33          33          36
+RalDatabase_versioning   51          51          58          60
+RalDatabaseSvc            4           4           4           4
+RelationalDatabase        1           1           1           1
+RelationalFolder          8          12          17          17
+HvsPathHandler            5           5           5           5
+
+                     2005-05-06
+RalDatabase              52    
+RalDatabase_versioning   61
+RalDatabase_extendedSpec 12    
+RalDatabaseSvc            4  
+RelationalDatabase        6 
+RelationalFolder         23
+HvsPathHandler            5
+ObjectId                 11
+
+                     2005-07-05
+RalDatabase              57
+RalDatabase_versioning   66
+RalDatabase_extendedSpec 11    
+RalDatabaseSvc            4  
+RelationalDatabase        6 
+RelationalFolder         30
+RelationalFolderSet       4
+RelationalTypeConverter   1
+HvsPathHandler            5
+ObjectId                 11
+utility_methods           6
+----------------------------
+total                   201
+
diff --git a/RelationalCool/doc/userTagsImpl.txt b/RelationalCool/doc/userTagsImpl.txt
new file mode 100755
index 000000000..2d82331af
--- /dev/null
+++ b/RelationalCool/doc/userTagsImpl.txt
@@ -0,0 +1,451 @@
+===============================================
+User tag example specification (AV 06.04.2005)
+===============================================
+
+General idea: an IOV can be inserted with one (or more?) associated user tags. 
+This means that a consistent HEAD version must be kept (within the folder
+and the channel) not only for ALL IOVS, but also for EACH subset of IOVS
+associated to any given user tag.
+
+Let's consider two scenarios:
+1. Each IOV can be inserted with ZERO or ONE user tags.
+2. Each IOV can be inserted with any number of associated tags.
+
+NB Each tag is independent of each other: it is NOT foreseen that one can 
+ask for "the HEAD for tag A AND tag B, or the HEAD for tag A OR tag B".
+Such a functionality can be implemented in scenario 2 by attaching ALSO 
+tag A_or_B to any IOV satisfying either tagA or tagB, for instance (any 
+such operation would be left to the user).
+
+Example 1 (scenario 1)
+----------------------
+1. User inserts P1 payload in [  0, 100] with NO user tags
+2. User inserts P2 payload in [ 10,  50] with user tag #1
+3. User inserts P3 payload in [ 30,  80] with user tag #2
+4. User inserts P4 payload in [ 20,  40] with user tag #1
+5. User inserts P5 payload in [ 30,  70] with user tag #2
+
+HEAD versions after last insertion:
+
+All IOVS (irrespective of tags):
+  P1 in [  0,  10]
+  P2 in [ 10,  20]
+  P4 in [ 20,  30]
+  P5 in [ 30,  70]
+  P3 in [ 70,  80]
+  P1 in [ 80, 100]
+
+User tag #1:
+  P2 in [ 10,  20]
+  P4 in [ 20,  40]
+  P2 in [ 40,  50]
+
+User tag #2:
+  P5 in [ 30,  70]
+  P3 in [ 70,  80]
+
+Example 2 (scenario 2)
+----------------------
+1. User inserts P1 payload in [  0, 100] with NO user tags
+2. User inserts P2 payload in [ 10,  50] with user tag #1
+3. User inserts P3 payload in [ 30,  80] with user tag #2
+4. User inserts P4 payload in [ 20,  40] with user tags #1 and #2 
+5. User inserts P5 payload in [ 30,  70] with user tag #2
+
+The ONLY difference with example 1 is that P4 is ALSO associated to tag #2.
+
+HEAD versions after last insertion:
+
+All IOVS (irrespective of tags): - no difference with example 1
+  P1 in [  0,  10]
+  P2 in [ 10,  20]
+  P4 in [ 20,  30]
+  P5 in [ 30,  70]
+  P3 in [ 70,  80]
+  P1 in [ 80, 100]
+
+User tag #1: - no difference with example 1
+  P2 in [ 10,  20]
+  P4 in [ 20,  40]
+  P2 in [ 40,  50]
+
+User tag #2:
+  P4 in [ 20,  30] - ONLY difference with respect to example 1
+  P5 in [ 30,  70]
+  P3 in [ 70,  80]
+
+================================================
+User tag example implementation (AV 06.04.2005)
+================================================
+
+* Unique identifiers
+
+The second scenario is more complex to implement than the first one.
+The reason is that the unique identifier of each IOV/row is more complex.
+
+In scenario 1, each IOV is uniquely identified by
+- UserId (Andrea's terminology) or 'layer number' (Sven's terminology):
+  the order in which objects are inserted by the user (irrespective of whether
+  they are associated to tags or not)
+- SystemId which can take exactly one of FIVE values, for instance
+  > 0: user-inserted
+  > 1: left system-inserted for the ALL-tag HEAD
+  > 2: right system-inserted for the ALL-tag HEAD
+  > 3: left system-inserted for the HEAD of THE user tag
+  > 4: right system-inserted for the HEAD of THE user tag
+
+Also, in scenario 1, the IOV table only needs ONE extra column to identify
+the user tag associated to each IOV (0 if no tag, tag# if there is one user tag).
+
+In scenario 2, each IOV is uniquely identified by
+- UserId (Andrea's terminology) or 'layer number' (Sven's terminology):
+  the order in which objects are inserted by the user (irrespective of whether
+  they are associated to tags or not) - as in scenario 1
+- SystemId which can take exactly one of 3+2*Ntag values (for ntag tags), for instance
+  > 0: user-inserted
+  > 1: left system-inserted for the ALL-tag HEAD
+  > 2: right system-inserted for the ALL-tag HEAD
+  > 3: left system-inserted for the HEAD of user tag #1
+  > 4: right system-inserted for the HEAD of user tag #1
+  > 5: left system-inserted for the HEAD of user tag #2
+  > 6: right system-inserted for the HEAD of user tag #2
+
+Also, in scenario 2, a more complex mechanism is needed to map each IOV to the MANY
+possible user tags associated to it.
+
+* Possible implementations
+
+As a consequence, the possible implementations of the two scenarios imply the 
+following modifications to the IOV table schema and storage pattern.
+
+In scenario 1 (implementation 1a):
+- Add one column in the IOV table to hold the user tag ID
+  Type 0 (user inserted objects) have 0 in this column if no user tag is specified,
+  or they have the tagID in this column if a user tag is specified.
+  Type 1/2 (system inserted for ALL TAG) have always 0 in this column.
+  Type 3/4 (system inserted for the USER TAG) have the user tag in this column.
+- SystemId is between 0 and 4 as explained above.
+- Unique identifier is layer number + systemId from 0 to 4.
+  This can also be used to encode (or randomly assign) a surrogate key.
+- Disadvantage of the model: assume that usertag must be 0 for sysId=1,2 and it 
+  must be >0 for sysId=3,4 (but this can easily be enforced with a check constraint)
+
+START - Sven, read this part only if you really have nothing better to do!
+
+In scenario 2:
+- The easiest (not the cleanest) option seems to be to add a single user tag column 
+  (like in the previous case) and duplicate the rows for each user tag. 
+  If an IOV is stored with no user tag, it is stored once with usertag=0 (sysid=0).
+  If an IOV is stored with user tag #3, it is stored twice, once with usertag=0
+  and once with usertag=3 (sysid=0 in both cases).
+- SystemId is only 0 (user), 1 (left system), 2 (right system).
+- Unique identifier has three pieces, layer number, sysId from 0 to 2, user tag.
+  This can also be used to encode (or randomly assign) a surrogate key.
+- Essentially each usertag is treated as a special "channel".
+- Disadvantage: storage overhead, each user object is stored N+1 times if it
+  has N tags associated. Also (more important): model assumes that all objects with
+  the same layer number and sysId=0 are identical even if they have different usertags.
+- Advantage: everything is contained in the IOV table, no need for a separate
+  iov2usertag table.
+
+We do not really care about scenario 2 because users acepted that only scenario 1
+is important. However scenario 2 is interesting as it points out possible
+different implementations of scenario 1.
+
+In scenario 1 (implementation 1b):
+- Add one column in the IOV table to hold the user tag ID
+  Type 0 (user inserted objects) have 0 in this column if no user tag is specified,
+  or they have the tagID in this column if a user tag is specified.
+  Type 1/2 (system inserted for ALL TAG) have always 0 in this column.
+  Type 3/4 (system inserted for the USER TAG) have the user tag in this column.
+  All as in implementation 1a.
+- SystemId is only 0 (user), 1 (left system), 2 (right system).
+- Unique identifier has three pieces, layer number, sysId from 0 to 2, user tag.
+  This can also be used to encode (or randomly assign) a surrogate key.
+- Disadvantage of the model: need to enforce (very difficult!) the extra constraint
+  that layer number is a unique key for rows with sysId=0 (you do not want to 
+  have rows that have the same layer number and sysId=0 but different userTag
+  values - either a user IOV had a user tag or it id not)
+
+In scenario 1 (implementation 1c):
+- Add one column in the IOV table to hold the user tag ID
+  Type 0 (user inserted objects) are stoored once (with userTag=0) if no user tag
+  is specified and are stored twice (once also with userTag not 0) if a user tag
+  is specified. Type 1/2 (system inserted for ALL TAG) have always 0 in this column.
+  Type 3/4 (system inserted for the USER TAG) have the user tag in this column.
+- SystemId is only 0 (user), 1 (left system), 2 (right system).
+- Unique identifier has three pieces, layer number, sysId from 0 to 2, user tag.
+  This can also be used to encode (or randomly assign) a surrogate key.
+- Disadvantage: storage overhead, each user object is stored two times if it
+  has one tag associated. Also (more important): model assumes that all objects with
+  the same layer number and sysId=0 are identical even if they have different usertags.
+
+All in all, the implementation of scenario 1 that seems easiest and safest is 1a.
+
+END - End of ranting ;-)
+
+* Possible implementation of example 1
+
+Using implementation 1a, example 1 translates to the following table.
+
+Note that I use the following encoding algorithm for the surrogate key:
+  objectId = 1 + (layer#-1) * 5 + systemId (0,1,2,3 or 4)
+This is similar to the present encoding without user tags,
+  objectId = 1 + (layer#-1) * 3 + systemId (0,1 or 2)
+
+Colum explanation:
+- ObjectId = 5 * UserId + SystemId (surrogate PK)
+- UserId = layer number (first of two fields in PK)
+- SytemId = between 0 and 4 (second of two fields in PK)
+- UserTag = 0 (no tag) or tagId
+- Since, Until = IOV boundaries
+- Payload = example payload
+- OrigId = originalId as ObjectId and as (UserId, SystemId)
+- NewHeadId = newHeadId as ObjectId and as (UserId, SystemId)
+
+1. User inserts P1 payload in [  0, 100] with NO user tags
+2. User inserts P2 payload in [ 10,  50] with user tag #1
+3. User inserts P3 payload in [ 30,  80] with user tag #2
+4. User inserts P4 payload in [ 20,  40] with user tag #1
+5. User inserts P5 payload in [ 30,  70] with user tag #2
+
+ObjId   UserId  SysId   UserTag Since   Until   Payload OrigId          NewHeadId
+(5u+s)  (layer) (0to4)                                  o(u,s)          o(u,s)  
+
+1       1       0       0       0       100     P1      0(0,0)          6(2,0)
+
+6       2       0       1       10      50      P2      0(0,0)          11(3,0)
+7       2       1       0       0       10      P1      1(1,0)          0(0,0)
+8       2       2       0       50      100     P1      1(1,0)          11(3,0)
+
+11      3       0       2       30      80      P3      0(0,0)          0(0,0)
+12      3       1       0       10      30      P2      6(2,0)          0(0,0)
+13      3       2       0       80      100     P1      8(2,2)          0(0,0)
+
+16      4       0       1       20      40      P4      0(0,0)          0(0,0)
+17      4       1       0       10      20      P2      12(3,1)         ARGHHHH
+18      4       2       0       40      80      P3      11(3,0)         
+19      4       3       1       10      20      P2      6(2,0)          
+20      4       4       1       40      50      P2      6(2,0)          
+
+21      5       0       2       30      70      P5      0(0,0)          0(0,0)
+22      5       1       0       20      30      P4      16(4,0)
+23      5       2       0       70      80      P3      18(4,2) 
+25      5       4       2       70      80      P3      11(3,0)
+
+Still other missing constraints:
+- originalId points to null if sysId=0 (check constraint)
+- newHeadId is always a user object (any u, s=0)
+- newHeadId if userTag>0 points to an object with the same userTag
+- originalId if sysId>0 and userTag>0 points to an object with the same userTag
+         
+HEAD versions after last insertion:
+All IOVS (irrespective of tags):
+  P1 in [  0,  10]
+  P2 in [ 10,  20]
+  P4 in [ 20,  30]
+  P5 in [ 30,  70]
+  P3 in [ 70,  80]
+  P1 in [ 80, 100]
+User tag #1:
+  P2 in [ 10,  20]
+  P4 in [ 20,  40]
+  P2 in [ 40,  50]
+User tag #2:
+  P5 in [ 30,  70]
+  P3 in [ 70,  80]
+
+.............................. INTERRUPT .................................
+
+This thinking was very useful: there are many problems pending.
+
+Problem 1 (user tags)
+----------------------
+
+Implementation 1a is not enough.
+
+ONE newHeadId column, which is needed for the tag as of id functionality,
+is not enough for user tags. User objects (sysId=0) with a tag 
+need TWO new heads: one for the no tag case, one for the tag case.
+
+It looks as if implementation 1c is better than implementation 1a.
+
+This means that the unique identifier (WITHIN EACH CHANNEL)
+must span the layer number, the system id and the user tag.
+
+Note that in this case we can even accept scenario 2.
+
+Problem 2 (channels)
+---------------------
+
+The objectId surrogate key now is unique across channels.
+There is no possible sensible encoding (unless we limit the number 
+of channels to a certain number) to decode into a surrogate ObjectId
+unique across channels the totality of (channelId,userTag,layer,sysId).
+
+PS
+
+I like implementation 1c better because
++ there is a single newheadid column and 
++ you may remove a user tag (remove all data associated to a user tag)
++ you may fit scenario 2
+- disadvantage: storage overhead                            
+
+==============================================================================
+
+Re: URGENT: and the channelId? 
+From: Andrea Valassi <Andrea.Valassi@cern.ch> 
+To: Sven A. Schmidt <sas@abstracture.de> 
+Reply-To: Andrea Valassi <Andrea.Valassi@cern.ch> 
+Date: Apr 7 2005 - 9:51am  
+
+Hi Sven,
+
+I will call you on the phone to discuss this, anyway here's my new morning 
+rants...
+
+3. ChannelId holes
+
+You mention that this is not a problem.
+In the end I agree, I do not care, for the moment, and not sure I would 
+care later. I just hope we can at least keep without holes the "this is 
+the insertionId order in this folder - across different channels".
+
+Just incidentally, we wuld not have an inflation in the number of sequence 
+tables. I think the best would be to have a single seqiene table per 
+folder, with one line per channel. By the way, eventually I think we need 
+a channel table per folder anyway. But this is FOR MUCH LATER.
+
+=> Conclusion: ok to keep the holes in each channel.
+
+2. ObjectId across channelId
+
+I made such a fuss about it, but in the end I am not sure what changes. I 
+agree it was good I at least realised that, so that we know the meaning of 
+the quantities (eg the insertionId we need to know that it spans several 
+channels). But maybe the queries are correct in the end. We should add 
+some tests using different channels, thats true. And I think eventually we 
+should add the possibility to selectively tag only the IOVS in a folder 
+which belong to a certain channel: in this case the queries should contain 
+the channelId, but otherwise maybe they would work anyway?
+
+=> Conclusion: probably not a problem.
+We should add some tests across channels and see.
+
+1. ObjectId and UK.
+
+As I said, the schema will change with user tags. And having two separate
+columns with insertionId and sysId is probably safer.
+
+NEVERTHELESS: 
+- I have already quite a good idea bout the schema for user tags
+- I would like to change as little as possible now
+- I believe we can still keep some encoding (connected to insertionId 
+unique across channels)
+- IF at some oint we change the schema radically, nothing would make sense 
+anymore anyway: so better plan for now for the minimal changes
+that would still be backward compatible
+
+The schema I propose (I will send you the details) foresees that user tags 
+"reserve" 3 (or maybe 2, but lets keep 3 for safety) extra ids for the 
+IOVS related to user tags (2 are the left and right inserted IOV, the 
+extra third one is the original user inserted iov, that I believe may be 
+safer to duplicate with a different id - once with usertag=0, once with 
+usertag=tag#). I would propose to simply keep the same algorithmic we have 
+now, both for encoding objectIds and obtaining the correct insertionId,
+but just change the encoding from 3N+0,1,2 to 6N+0,1,2,3,4,5. For you, 
+this mainly means you need to "reserve" 5 holes instead of 2.
+I think this is the fastest... and it is not so bad, I also keep some 
+encoding. IF at some point we change things radically, well it will not be 
+backward compatible anyway. But this intermediate solution leaves us some 
+space for manuevring. On top, we can ALSO add the two columns, provided 
+the insertionId makes sense like now, "the order of insertion in the 
+folder, across different channels": this is what is needed in the queries 
+anyway.
+
+By the way, IF we keep this encoding, this allows us to postpone the 
+addition of the two columns. We can always insert the extra columns later 
+and just derive them from the objectid.
+
+=> Conclusions: 
+- change "reserve 2 holes" to "reserve 5 holes" (Sven)
+- change "3N+0,1,2" to "6N+0,1,2,3,4,5" in ObjectId (Sven or Andrea)
+- add (but this is less urgent) two extra columns
+
+4. Tests
+
+Yes definitely needed
+
+=> Conclusion: Sven, plese try to devise some tests across channels.
+
+5. Was this useful?
+
+Well... I think it was useful thinking. But maybe there is not so much 
+that needs to be done or that would have caused a disaster, even having 
+forgotten channels. Or am I stil missing something?
+
+a.
+
+
+On Wed, 6 Apr 2005, Sven A. Schmidt wrote:
+> 
+> On 06.04.2005, at 18:10, Andrea Valassi wrote:
+> 
+> > To summarise:
+> >
+> > 1. Please go ahead and add a layer number (I would call it insertionId
+> > or userObjectId, see later) and a quantity systemId equal to 0,1,2 for
+> > the IOV table. The tagAsOfObjectId should only rely on these columns
+> > and not on the surrogate PK. I would keep the present encoding because
+> > it does not harm, but we must take into account that things may change
+> > in the future. Adding a user tag will mean either that an extra column
+> > userTag (on top of channelId, insertionId, systemId) is needed to make
+> > up a unique identifier (you may have data with the same ch=15,
+> > insId=44 and sysId=1 meaning it is on the left, but different userTag
+> > meaning that it was left inserted in the HEAD of ALL HEAD, tag=0, or a
+> > specific tag>0), or it will mean that we change the meaning and
+> > spectrum of systemId (for instance, sysId=3,4 for system inserted
+> > associated to THE user tag). I would say: since it is not clear what
+> > the objectId will be in the future, it is dangerous to give it a
+> > meaning now. Better to rely on other columns starting now.
+> 
+> Ok, will do.
+> 
+> > 2. Please be aware that the "layer number" we discussed this morning
+> > DOES HAVE HOLES. This is because there are several channels in the
+> > same folder. This is why I am thinking it is maybe better to call it
+> > "insertionId": it is just like an insertion time, but it is a number.
+> > Like a ticket when you go to the supermarket and queue up at the
+> > cheese shop... The meaning should be "this is the order - with no
+> > holes - in which objects were inserted into this folder, to different
+> > channels". Any other name suggestion? Calling it layer to me suggests
+> > too much an order with no holes.
+> 
+> Yes, ok.
+> 
+> > 3. If you want to get rid of the previous problem, we would need to
+> > have one sequence per channel. We could do that eventually... but not
+> > now I think.
+> 
+> I don't think it's a problem to have holes with respect to a channel. 
+> In any case it's much better than having sequence table inflation. The
+> code reviewers would flog us around the LEP tunnel if they found out
+> that we create an extra table per channel ;)
+> 
+> > 4. It would be good indeed to think of introducing more tests where
+> > several channels are mixed. Just to see if our logic works or not.
+> > Maybe you can think of some weird cases?
+> 
+> Yes, I'll add more.
+> 
+> > 5. All this said, it seems to me I wasted one day of work. Not sure at
+> > all we can keep some schema compatibility with the next schema... even
+> > if of course we can try.
+> 
+> I think it was very good you have spotted this. While the mutliversion
+> code was not wrong in itself, it did not support the features you had in
+> mind (tag atomicity). Had we released like this we'd definitely have to
+> introduce backward incompatible changes. I think we still have a chance
+> to pull this off.
+> 
+
diff --git a/RelationalCool/doc/userTagsImpl2.txt b/RelationalCool/doc/userTagsImpl2.txt
new file mode 100644
index 000000000..7e58d3132
--- /dev/null
+++ b/RelationalCool/doc/userTagsImpl2.txt
@@ -0,0 +1,467 @@
+===============================================
+User tag example specification (AV 28.02.2006)
+===============================================
+
+General idea: an IOV can be inserted with AT MOST ONE associated user tag. 
+This means that a consistent HEAD version must be kept (within the folder
+and the channel) not only for ALL IOVS, but also for EACH subset of IOVS
+associated to any given user tag.
+
+Two specifications are discussed:
+- In the 'old' (April 2005) specification, 'user tags' (those specified 
+  when inserting a new IOV) are different from 'standard tags' (those 
+  specified when tagging the HEAD of existing IOVs) and can NOT be mixed.
+- In the 'new' (February 2006) specification, 'user tags' (those specified 
+  when inserting a new IOV) are NOT different from 'standard tags (those 
+  specified when tagging the HEAD of existing IOVs) and can be mixed.
+
+[NB Each tag is independent of each other: it is NOT foreseen that one can 
+ask for "the HEAD for tag A AND tag B, or the HEAD for tag A OR tag B".]
+
+Example 1
+----------
+1. User inserts P1 payload in [  0, 100] with NO (user) tags
+2. User inserts P2 payload in [ 10,  50] with (user) tag #1
+3. User inserts P3 payload in [ 30,  80] with (user) tag #2
+4. User inserts P4 payload in [ 20,  40] with (user) tag #1
+5. User inserts P5 payload in [ 30,  70] with (user) tag #2
+
+The following applies both to the old and new specifications.
+The only difference is in terminology: in the old specification, 
+these tags are 'user' tags (different type from 'standard' tags),
+while in the new specification they are just 'tags'.
+
+HEAD versions after last insertion:
+
+All IOVS (irrespective of tags):
+  P1 in [  0,  10]
+  P2 in [ 10,  20]
+  P4 in [ 20,  30]
+  P5 in [ 30,  70]
+  P3 in [ 70,  80]
+  P1 in [ 80, 100]
+
+(User) tag #1:
+  P2 in [ 10,  20]
+  P4 in [ 20,  40]
+  P2 in [ 40,  50]
+
+(User) tag #2:
+  P5 in [ 30,  70]
+  P3 in [ 70,  80]
+
+Example 2 (old specification)
+------------------------------
+1. User inserts P1 payload in [  0,  50] with NO user tags
+2. User inserts P2 payload in [ 50, 100] with NO user tags
+3. User tags HEAD of folder with tag #2
+4. User inserts P4 payload in [ 10,  50] with user tag #1
+5. User inserts P5 payload in [ 30,  80] with user tag #2 - EXCEPTION
+6. User inserts P6 payload in [ 20,  40] with user tag #1
+7. User inserts P7 payload in [ 30,  70] with user tag #2 - EXCEPTION
+
+In the old specification, step 5 and 7 here throw an exception: tag #2 is 
+already reserved as a 'standard' tag and cannot be used as a 'user' tag.
+
+HEAD versions after last insertion (ignoring step 5 and 7):
+
+All IOVS (irrespective of tags):
+  P1 in [  0,  10]
+  P4 in [ 10,  20]
+  P6 in [ 20,  30]
+  P7 in [ 30,  70]
+  P5 in [ 70,  80]
+  P2 in [ 80, 100]
+
+Tag #1:
+  P4 in [ 10,  20]
+  P6 in [ 20,  40]
+  P4 in [ 40,  50]
+
+User tag #2:
+  P1 in [  0,  50]
+  P2 in [ 50, 100]
+
+Example 2 (new specification)
+------------------------------
+1. User inserts P1 payload in [  0,  50] with NO user tags
+2. User inserts P2 payload in [ 50, 100] with NO user tags
+3. User tags HEAD of folder with tag #2
+4. User inserts P4 payload in [ 10,  50] with user tag #1
+5. User inserts P5 payload in [ 30,  80] with user tag #2
+6. User inserts P6 payload in [ 20,  40] with user tag #1
+7. User inserts P7 payload in [ 30,  70] with user tag #2
+
+In the new specification, no exceptions are thrown.
+
+HEAD versions after last insertion:
+
+All IOVS (irrespective of tags):
+  P1 in [  0,  10]
+  P4 in [ 10,  20]
+  P6 in [ 20,  30]
+  P7 in [ 30,  70]
+  P5 in [ 70,  80]
+  P2 in [ 80, 100]
+
+Tag #1:
+  P4 in [ 10,  20]
+  P6 in [ 20,  40]
+  P4 in [ 40,  50]
+
+Tag #2:
+  P1 in [  0,  30]
+  P7 in [ 30,  70]
+  P5 in [ 70,  80]
+  P2 in [ 80, 100]
+
+Example 3 (new specification)
+------------------------------
+ 1. User inserts P1  payload in [  0,  50] with NO user tags
+ 2. User inserts P2  payload in [ 50, 100] with NO user tags
+ 3. User tags HEAD of folder with tag #2
+ 4. User inserts P4  payload in [ 10,  50] with user tag #1
+ 5. User inserts P5  payload in [ 30,  80] with user tag #2
+ 6. User inserts P6  payload in [ 20,  40] with user tag #1
+ 7. User inserts P7  payload in [ 30,  70] with user tag #2
+ 8. User tags HEAD of folder with tag #2
+ 9. User inserts P9  payload in [ 30,  80] with user tag #2
+10. User inserts P10 payload in [ 20,  40] with user tag #1
+
+In the new specification, no exceptions are thrown.
+
+HEAD versions after last insertion:
+
+All IOVS (irrespective of tags):
+  P1  in [  0,  10]
+  P4  in [ 10,  20]
+  P10 in [ 20,  40]
+  P9  in [ 40,  80]
+  P2  in [ 80, 100]
+
+Tag #1:
+  P4  in [ 10,  20]
+  P10 in [ 20,  40]
+  P4  in [ 40,  50]
+
+Tag #2:
+  P1 in [  0,  10]
+  P4 in [ 10,  20]
+  P6 in [ 20,  30]
+  P9 in [ 30,  80]
+  P2 in [ 80, 100]
+
+Essentially, tagging the HEAD (in step 8) with the same tag name 
+previously used for inserting IOVs with attached tags (e.g. step 5)
+logically erases all tag-to-IOV relations defined when inserting 
+IOVs with attached tags (e.g. the tag attached in step 5 loses meaning).
+
+===============================================
+User tag implementation (AV 28.02.2006)
+===============================================
+
+IOV table
+----------
+
+Each IOV is uniquely identified by an ObjectId that can be built 
+from three variables:
+
+- UserId or 'layer number': the order in which objects are inserted by 
+  the user (irrespective of whether they are associated to tags or not)
+
+- SystemId3 which can take exactly one of THREE values, for instance
+  > 0: user-inserted
+  > 1: left system-inserted for the (user tag or global) HEAD
+  > 2: right system-inserted for the (user tag or global) HEAD
+
+- HasTagId which can be 0 (not associated to user tag) or 1
+  (associated to user tag)
+
+The combination of SystemId3 and HasTagId gives SystemId6 
+  SystemId6 = 3*(HasTagId-1) + SystemId3
+which can take exactly one of SIX values, for instance
+  > 0: user-inserted (NOT marked as belonging to a user tag)
+  > 1: left system-inserted for the global HEAD (IOVs with any tag or none)
+  > 2: right system-inserted for the global HEAD (IOVs with any tag or none)
+  > 3: copy of the user-inserted IOV (marked as belonging to a user tag)
+  > 4: left system-inserted for the HEAD of the user tag
+  > 5: right system-inserted for the HEAD of the user tag
+
+The ObjectId column already exists (COOL128) and the value is
+  ObjectId = 6*(UserId-1) + 3*(HasTagId-1) + SystemId3
+i.e.
+  ObjectId = 6*(UserId-1) + SystemId6
+
+Instead of a HasTagId column, it is better to add to the IOV table 
+a TagId column, containing either 0 (no tag) or >0 (the tag id
+of the user tag specified at insertion).
+
+To sum up the implementation:
+- Add three columns ObjIdSys3, ObjIdUser and ObjIdTag.
+- The ObjIdTag column references as FK the tagId column in the tag table.
+- The ObjectId column (surrogate PK) is kept and is equal to 
+  ObjectId = 6*(ObjIdUser-1) + 3*((is ObjIdTag>0?)-1) + ObjIdSys3
+  A check constraint can/should be added to impose this. 
+- ObjIdUser is assigned from an internal sequence-like object.
+  Note that this corresponds to the global order id 
+  for the insertion into the IOV table, across all channels.
+- User inserted IOVs with no associated user tag are inserted only once
+  with ObjIdSys=0 and ObjIdTag=0.
+- User inserted IOVs with an associated user tag tagId are inserted twice:
+  once with ObjIdSys=0 and ObjIdTag=0, once with ObjIdSys=0 and ObjIdTag=tagId.
+  This represents a modest storage overhead but simplifies the algorithm.
+- System inserted IOVs are inserted with ObjIdSys=1 or 2 and with
+  ObjIdTag=0 if they refer to the global HEAD, or ObjIdTag=tagId
+  if they refer to the HEAD within the subset of IOVs tagged as tagId.
+
+Note that the payload is presently stored inline and is copied 
+within the IOV table in up to 6 identical copies.
+Eventually, when the payload is split from the IOV table,
+only a FK reference to a separate payload table needs 
+to be copied in up to 6 identical copies.
+
+Note that more complex constraints across separate rows
+are imposed by the C++ algorithm but are not imposed on the database.
+For instance, pairs of objects with the same ObjUserId and with ObjSysId3=0
+are identical even if one has ObjIdTag=0 and one has ObjIdTag>0.
+
+IOV2TAG table
+--------------
+
+1. Old specifcation
+
+In the 'old' specification, user tags and standard HEAD tags are two 
+different kinds of tags: all IOV data associated to user tags is 
+contained in the IOV table, all IOV data associated to standard tags 
+is contained in the IOV2TAG table. The two types of tags cannot be mixed.
+
+When storeObject(IOV,tag) is called, rows are inserted and updated 
+in the IOV table. In order to find/browse IOVs within a user tag,
+only the IOV table must be queried.
+
+When tag(tag) is called, rows are inserted and deleted in the IOV2TAG table. 
+In order to find/browse IOVs within a standard tag, only the IOV2TAG table 
+must be queried (joined with the IOV table to retrieve the actual payload).
+
+As all IOV data associated to user tags is in the IOV table, where rows
+can only be inserted or updated but never deleted, note that in the 
+'old' specification the IOV table may be used to preserve the history
+log of all transactions associated to a given user tag. Rows in the
+IOV2TAG table, conversely, are deleted and reinserted whenever a
+new HEAD tag operation is performed, and the history log associated
+to 'standard' tags is lost: only the tag-to-IOV associations defined
+by the last tag operation are preserved persistently.
+
+2. New specification
+
+In the 'new' specification, the two types of tags can be mixed
+and are actually a single type of tag. The IOV data associated
+to tags is maintained both in the IOV and IOV2TAG tables.
+
+For simplicity, and because no user requirement to preserve
+the history log of tag modifications has been expressed, the
+design will assume that the history log of tag modifications
+can be scratched. This implies that rows can/should also be deleted
+from the IOV table.
+
+The IOV2TAG table is in any case maintained always up to date:
+in order to find/browse IOVs within a standard tag, only the IOV2TAG table 
+must be queried (joined with the IOV table to retrieve the actual payload).
+
+When storeObject(IOV,tag) is called, rows are inserted and updated 
+in the IOV table. No rows are deleted from the IOV table, they are
+only updated. The iov-to-tag associations relevant to the given tag
+are ALSO stored by inserting and deleting rows in the IOV2TAG table.
+
+When tag(tag) is called, rows are inserted and deleted in the IOV2TAG table. 
+If the tag already existed and had been used to store IOVs in the IOV table
+via the storeObject(IOV,tag) method, ALL rows associated to the given tag
+(i.e. with ObjIdTag=tagId) are DELETED from the IOV table. This erases
+all history of the given tag previous to the last tag(tag) call.
+
+Note that it is possible to design amn implementation to keep track
+of all previous tag modifications. This can be done by never deleting
+rows from either the IOV or the IOV2TAG table, and only updating rows
+marking them as old (a new column is required in the IOV2TAG table).
+But this was not required and will not be implemented.
+
+Roles and privileges
+---------------------
+
+In the scenario where obsolete tag data is deleted from the IOV table,
+the 'retag' role must be granted the privilege to delete rows from
+the IOV table.
+
+Eventually this role should be improved so that the privilege is only 
+granted on the appropriate view, for instance on the view selecting
+from the IOV table where ObjIdTag>0. This may imply however that also 
+the C++ code manipulates the same view rather than the underlying table.
+
+Note also that other roles also need to be improved. For instance
+the 'insert' role currently has privileges to update the IOV table,
+but it would be safer to restrict this privilege to updating
+only the relevant columns in the table. Unless this is done,
+granting the delete on IOV table via a view is meaningless
+(a nasty person could update the IOV table to set tagId>0
+and then delete the row, or in any case corrupt the IOV table
+by randomly updating all rows).
+Schema evolution tools
+-----------------------
+
+Schema evolution tools are needed to add the new columns and fill them
+with appropriate data.
+
+Regression tests across different schema/software versions are also needed.
+
+===============================================
+User tag example implementation (AV 28.02.2006)
+===============================================
+
+Example 1
+----------
+
+1. User inserts P1 payload in [  0, 100] with NO (user) tags
+2. User inserts P2 payload in [ 10,  50] with (user) tag #1
+3. User inserts P3 payload in [ 30,  80] with (user) tag #2
+4. User inserts P4 payload in [ 20,  40] with (user) tag #1
+5. User inserts P5 payload in [ 30,  70] with (user) tag #2
+
+IOV table:
+
+ObjId ObjIdUs ObjIdS3 ObjIdTag Since Until Payload OrigId    NewHeadId
+o     u       s                                    o(u,s)    o(u,s)  
+
+1     1       0       0        0     100   P1      0(0,0)    7(2,0)
+
+7     2       0       0        10    50    P2      0(0,0)    13(3,0)
+8     2       1       0        0     10    P1      1(1,0)    0(0,0)
+9     2       2       0        50    100   P1      1(1,0)    13(3,0)
+10    2       0       1        10    50    P2      0(0,0)    19(4,0)
+
+13    3       0       0        30    80    P3      0(0,0)    19(4,0)
+14    3       1       0        10    30    P2      7(2,0)    19(4,0)
+15    3       2       0        80    100   P1      9(2,2)    0(0,0)
+16    3       0       2        30    80    P3      0(0,0)    25(5,0)
+
+19    4       0       0        20    40    P4      0(0,0)    25(5,0)
+20    4       1       0        10    20    P2      14(3,1)   0(0,0)
+21    4       2       0        40    80    P3      13(3,0)   25(5,0)      
+22    4       0       1        20    40    P4      0(0,0)    0(0,0)
+23    4       1       1        10    20    P2      10(2,0)   0(0,0)       
+24    4       2       1        40    50    P2      10(2,0)   0(0,0)       
+
+25    5       0       0        30    70    P5      0(0,0)    0(0,0)
+26    5       1       0        20    30    P4      19(4,0)   0(0,0)
+27    5       2       0        70    80    P3      21(4,2)   0(0,0)
+28    5       0       2        30    70    P5      0(0,0)    0(0,0)
+29    5       2       2        70    80    P3      16(3,0)   0(0,0)
+
+IOV2TAG table:
+
+TagId ObjId Since Until
+1     23    10    20
+1     22    20    40
+1     24    40    50
+2     28    30    70
+2     25    70    80
+
+Example 2 (new specification)
+------------------------------
+1. User inserts P1 payload in [  0,  50] with NO user tags
+2. User inserts P2 payload in [ 50, 100] with NO user tags
+3. User tags HEAD of folder with tag #2
+4. User inserts P4 payload in [ 10,  50] with user tag #1
+5. User inserts P5 payload in [ 30,  80] with user tag #2
+6. User inserts P6 payload in [ 20,  40] with user tag #1
+7. User inserts P7 payload in [ 30,  70] with user tag #2
+
+ObjId ObjIdUs ObjIdS3 ObjIdTag Since Until Payload OrigId    NewHeadId
+o     u       s                                    o(u,s)    o(u,s)  
+
+1     1       0       0        0     50    P1      0(0,0)    13(3,0)
+
+7     2       0       0        50    100   P2      0(0,0)    19(4,0)
+
+  --HEAD tagged as tag 2--
+
+13    3       0       0        10    50    P4      0(0,0)    19(4,0)
+14    3       1       0        0     10    P1      1(1,0)    0(0,0)
+16    3       0       1        10    50    P4      0(0,0)    0(0,0)
+
+19    4       0       0        30    80    P5      0(0,0)    25(5,0)
+20    4       1       0        10    30    P4      13(3,0)   25(5,0)
+21    4       2       0        80    100   P2      7(2,0)    0(0,0)
+22    4       0       2        30    80    P5      0(0,0)    31(6,0)
+23    4       1       2        0     30    P1      0(0,0)    0(0,0)
+24    4       2       2        80    100   P2      0(0,0)    0(0,0)
+
+25    5       0       0        20    40    P6      0(0,0)    31(6,0)
+26    5       1       0        10    20    P4      20(4,1)   0(0,0)
+27    5       2       0        40    80    P5      19(4,0)   31(6,0)
+28    5       0       1        20    40    P6      0(0,0)    0(0,0)
+29    5       1       1        10    20    P4      16(3,0)   0(0,0)
+30    5       2       1        40    50    P4      16(3,0)   0(0,0)
+
+31    6       0       0        30    70    P7      0(0,0)    0(0,0)
+32    6       1       0        20    30    P6      25(5,0)   0(0,0)
+33    6       2       0        70    80    P5      27(5,2)   0(0,0)
+34    6       0       2        30    70    P7      0(0,0)    0(0,0)
+36    6       2       2        70    80    P5      22(4,0)   0(0,0)
+
+IOV2TAG table:
+
+TagId ObjId Since Until
+1     29    10    20
+1     28    20    40
+1     30    40    50
+2     23    0     30
+2     34    30    70
+2     36    70    80
+2     24    80    100
+
+COMMENT 1
+----------
+
+The IOV2TAG table is badly needed for performance reasons
+in the retrieval of tagged MV data.
+[Note that the HEAD tag instead is retrieved directly from the IOV table.]
+
+Nevertheless, it would be possible in principle to rebuild the
+IOV2TAG table starting from the IOV table alone, provided that
+for each tag the TAG table stores the value of the last inserted IOV id
+at the moment when the last HEAD tag operation was performed.
+
+In the example above:
+  tagId  headTaggedAsOfId
+  1      7 
+  2      0 (tag exists but was not used to tag the HEAD so far)  
+
+This value cannot be simply used in a relational query to find/browse
+all IOVs in a given tag, but could be used to trigger a C++ verification
+of the contents of the IOV2TAG table.
+
+COMMENT 2
+----------
+
+The performance of the standard HEAD query is under investigation.
+If this proved to be too slow, it is possible to envisage adding 
+all HEAD IOVs to the IOV2TAG table too with a reserved tagId of 0.
+This would indicate the global HEAD tag.
+
+This may actually be required in any case if the FK constraint
+between the IOV table (ObjIdTag) and the TAG table is imposed,
+unless ObjIdTag is left as NULL rather than equal to 0.
+
+COMMENT 3
+----------
+
+In the proposal above the ObjectId column is encripted as
+  ObjectId = 6*(ObjIdUser-1) + 3*((is ObjIdTag>0?)-1) + ObjIdSys3
+This is consistent with the present (COOL128) numbering,
+where user-inserted IOVs are numbered 1,7,13,19...
+
+An alternative possibility would be to use the encription
+  ObjectId = 10*(ObjIdUser-1) + 3*((is ObjIdTag>0?)-1) + ObjIdSys3
+so that user-inserted IOVs would be numbered 1,11,21,31...
+The advantage would only be that the numbering is more intuitive.
+
diff --git a/RelationalCool/doc/userTagsImpl3.txt b/RelationalCool/doc/userTagsImpl3.txt
new file mode 100644
index 000000000..c7892b70c
--- /dev/null
+++ b/RelationalCool/doc/userTagsImpl3.txt
@@ -0,0 +1,70 @@
+===============================================
+User tag implementation (AV 01.03.2006)
+===============================================
+
+Just a few brief notes to complement userTagsSpec3.txt and userTagsImpl2.txt.
+
+With respect to the implementation proposed in userTagsImpl2.txt:
+- Drop the constraint that objectId is a function of userId and sysId.
+  For every userId, more than one tag can be associated, hence there
+  would be no good constraining scheme. Simply use a sequence with no 
+  holes, describing the order in which rows are inserted in the table.
+- This means that more than one user tag can be specified on insertion.
+- The newHeadId column must reference the userId column instead
+  of the objectId column.
+- For each tag, a __complete__ parallel branch of IOV HEAD is maintained.
+  When a HEAD tag is defined, all IOVs are re-inserted into the IOV table
+  with a new userId (originalId is the old userId) and the relevant tagId.
+- The full history of tags is maintained in the IOV table.
+  This may become very very large. Payloads should be stored externally.
+  Note that userId could be used as FK reference to the external payload
+  table: you do not actually need a separate FK column
+  (one userId <-> one payload).
+- The IOV2TAG table is simply a snapshot of the IOV table for the
+  IOVs currently associated to tags. It does not hold additional
+  information that cannot be retrieved from the IOV table via simple queries.
+- A table (the tag table?) must maintain the history of when HEAD tags
+  where defined (at which objectId).
+
+=======================================================
+Additional notes after Richard's reply (AV 02.03.2006)
+=======================================================
+
+Richard suggests that we could just implement scenario 2.
+
+I think in any case that it would be safer to implement this using the same 
+implementation as scenario 3, with all relevant information in the IOV table, 
+but throwing away rows from the IOV table as they become obsolete.
+This seems safer in the sense that it would in any case allow us to
+switch on history logging if required by the users and/or for our own
+internal debugging, while the removal of obsolete rows would prevent
+the IOV table from growing too big.
+
+The duplication of information across the IOV and IOV2TAG tables however
+should be avoided. One possibility would be to add the extra tagged rows
+to the IOV table (ALL associations of IOVs to tags), as suggested for
+scenario 3, and get rid of the IOV2TAG table as the IOV table alone
+could be enough (and not too large if old data are purged). The alternative
+possibility (better?) is to add to the IOV2TAG table ALL columns from the
+IOV table (except the payload) and actually have the tagged rows ONLY
+in the IOV2TAG table instead of the IOV table, but with the same logic
+used in the IOV table. 
+
+In any case, the splitting of payload from IOV table seems unavoidable.
+Note that my previous comment was wrong: it is not enough to keep userId
+as reference to the payload, because current userId for system inserted
+objects is the userId of the new IOV triggering system insertion, while
+the originalId for these system objects may be another system inserted
+object. One possibility is to add a new column originalUserId which 
+actually points to the very first user inserted object, i.e. the one which
+indeed was inserted with a payload.
+
+It would be useful to implement an internal 'purge' method taking as
+argument a date/objectId before which all obsolete rows can be erased. 
+The implementation could use this internally periodically, or after
+each insertion, in spec#2. To implement spec#3 it would be enough to
+switch off its automatic use, and only offer it to users as an
+additional functionality.
+
+
+
diff --git a/RelationalCool/doc/userTagsSpec.txt b/RelationalCool/doc/userTagsSpec.txt
new file mode 100644
index 000000000..891a4c451
--- /dev/null
+++ b/RelationalCool/doc/userTagsSpec.txt
@@ -0,0 +1,158 @@
+From Andrea.Valassi@cern.ch Wed Apr  6 15:22:28 2005
+Date: Wed, 6 Apr 2005 13:07:43 +0200 (CEST)
+From: Andrea Valassi <Andrea.Valassi@cern.ch>
+To: David Malon <malon@anl.gov>
+Cc: Sven Schmidt <sas@abstracture.de>,
+     LCG ConditionsDB developers
+    <project-lcg-peb-conditionsdb-developers@cern.ch>
+Subject: ~URGENT: user tags
+
+Hi David,
+
+a (hopefully) quick question. We are not going to implement the "user tag" 
+functionality you requested in the production release. Nevertheless, I 
+would like to be sure already that I understand EXACTLY what you require,
+also because I'd like to foresee in advance the changes this implies to 
+the IOV table schema, so that the IOV table schema in the production 
+release is not radically incompatible with that required for implementing 
+user tags.
+
+I am including below two simple examples that, in my understanding,
+demonstrate your requirement. I am actually including TWO examples for two
+slightly different scenarios: 1. when a user can specify AT MOST ONE user
+tag with each inserted IOV, and 2. when a user can specify ANY number of
+user tags with each inserted IOV. I think that the simpler scenario 1
+should satisfy your needs. I am rather reluctant to go to scenario 2
+because it implies a more complex implementation (which I would solve by
+increasing the storage overhead) and especially because it opens the door
+to a potential unnecessary inflation in the number of user tags ("I'll
+attach 15 different tags to this IOV, just in case I MAY need them
+later"), with serious consequences on performance and scalability.
+Of course user requirements come first, but I would invite users to ask 
+for the requirements that are really required :-)
+
+This is only meant to get a quick reply to get a feeling what you need: 
+can you please have a quick look and confirm
+- whether one of the two scenarios fulfills your requirements, or whether
+  you actually had in mind something RADICALLY different
+- if the first answer is yes, whether the first scenario is indeed
+  enough or you would need the functionality of the second
+Thanks a lot!
+
+Feedback from anyone else (especially Atlas, since this where the 
+requirement came from... Richard and Torre, for instance) is of course 
+welcome! Please answer asap with a first quick feedback (today if you 
+can?).
+
+It's not a catastrophe if we dont converge now... but at least I'll 
+give it a try to get a better idea before the production release.
+
+	Cheers
+
+		Andrea
+
+Ps Sven, can you please prepare a picture for the two?
+
+===============================================
+User tag example specification (AV 06.04.2005)
+===============================================
+
+General idea: an IOV can be inserted with one (or more?) associated user tags. 
+This means that a consistent HEAD version must be kept (within the folder
+and the channel) not only for ALL IOVS, but also for EACH subset of IOVS
+associated to any given user tag.
+
+Let's consider two scenarios:
+1. Each IOV can be inserted with ZERO or ONE user tags.
+2. Each IOV can be inserted with any number of associated tags.
+
+NB Each tag is independent of each other: it is NOT foreseen that one can 
+ask for "the HEAD for tag A AND tag B, or the HEAD for tag A OR tag B".
+Such a functionality can be implemented in scenario 2 by attaching ALSO 
+tag A_or_B to any IOV satisfying either tagA or tagB, for instance (any 
+such operation would be left to the user).
+
+Example 1 (scenario 1)
+----------------------
+1. User inserts P1 payload in [  0, 100] with NO user tags
+2. User inserts P2 payload in [ 10,  50] with user tag #1
+3. User inserts P3 payload in [ 30,  80] with user tag #2
+4. User inserts P4 payload in [ 20,  40] with user tag #1
+5. User inserts P5 payload in [ 30,  70] with user tag #2
+
+HEAD versions after last insertion:
+
+All IOVS (irrespective of tags):
+  P1 in [  0,  10]
+  P2 in [ 10,  20]
+  P4 in [ 20,  30]
+  P5 in [ 30,  70]
+  P3 in [ 70,  80]
+  P1 in [ 80, 100]
+
+User tag #1:
+  P2 in [ 10,  20]
+  P4 in [ 20,  40]
+  P2 in [ 40,  50]
+
+User tag #2:
+  P5 in [ 30,  70]
+  P3 in [ 70,  80]
+
+Example 2 (scenario 2)
+----------------------
+1. User inserts P1 payload in [  0, 100] with NO user tags
+2. User inserts P2 payload in [ 10,  50] with user tag #1
+3. User inserts P3 payload in [ 30,  80] with user tag #2
+4. User inserts P4 payload in [ 20,  40] with user tags #1 and #2 
+5. User inserts P5 payload in [ 30,  70] with user tag #2
+
+The ONLY difference with example 1 is that P4 is ALSO associated to tag #2.
+
+HEAD versions after last insertion:
+
+All IOVS (irrespective of tags): - no difference with example 1
+  P1 in [  0,  10]
+  P2 in [ 10,  20]
+  P4 in [ 20,  30]
+  P5 in [ 30,  70]
+  P3 in [ 70,  80]
+  P1 in [ 80, 100]
+
+User tag #1: - no difference with example 1
+  P2 in [ 10,  20]
+  P4 in [ 20,  40]
+  P2 in [ 40,  50]
+
+User tag #2:
+  P4 in [ 20,  30] - ONLY difference with respect to example 1
+  P5 in [ 30,  70]
+  P3 in [ 70,  80]
+
+-------------------------------------------------------------------------------
+
+From: RD Schaffer <R.D.Schaffer@cern.ch> 
+To: Sven A. Schmidt <sas@abstracture.de> 
+CC: Marco Clemencic <Marco.Clemencic@cern.ch>, 
+    Andrea Valassi <Andrea.Valassi@cern.ch>, 
+    Antoine Pérus <perus@lal.in2p3.fr>, 
+    Richard Hawkings <rhawking@mail.cern.ch> 
+Date: May 19 2005 - 5:04pm 
+
+Hi there,
+
+  Andrea should respond here. But I believe that his thoughts about 
+David M.'s request is to provide user tags which are different than 
+the regular tag. So one could insert with a user tag, and then later 
+based on a particular user tag, tag a set of objects. This would resolve 
+the problem of the 'in between' object - it would have a different user 
+tag if so desired.
+
+                        see you, RD
+
+-------------------------------------------------------------------------------
+
+For reference: David Malon presented his use case in the presentation 
+at the 2003 CondDB Workshop: http://agenda.cern.ch/fullAgenda.php?ida=a036470
+
+
diff --git a/RelationalCool/doc/userTagsSpec2.txt b/RelationalCool/doc/userTagsSpec2.txt
new file mode 100644
index 000000000..4c10ec74c
--- /dev/null
+++ b/RelationalCool/doc/userTagsSpec2.txt
@@ -0,0 +1,196 @@
+Dear all,
+
+following yesterday's discussion with Sven and Richard at the Monday 
+meeting about the new 'user tag' functionality required for COOL_1_3_0,
+I would like to propose to you the following slightly different 
+(improved) specification and implementation design.
+
+For reference: the original specification is the one I proposed 
+in an e-mail message in April last year, which you can also find in
+the COOL CVS doc repository in 
+  http://cool.cvs.cern.ch/cgi-bin/cool.cgi/cool/RelationalCool/doc/userTagsSpec.txt
+
+For the development team: the initial implementation design (later 
+complemented by more email exchanges with Sven, not included) is also in 
+  http://cool.cvs.cern.ch/cgi-bin/cool.cgi/cool/RelationalCool/doc/userTagsImpl.txt
+
+Basically, last year's agreement was that users can specify AT MOST ONE
+user tag when inserted a new IOV. From yesterday's discussion, I think
+we still agree on this point.
+
+However, last year's proposal also assumed that 'user tags' (those
+specified when inserting a new IOV) are different from 'standard tags'
+(those specified when tagging the HEAD of existing IOVs). From 
+yesterday's discussion, this is the point which could still be improved.
+
+I propose below a new functionality specification that goes in this 
+direction. I split this in two parts: a summary of last year's proposal, 
+plus a possible extension. The reason is that I am not sure we can 
+implement the full picture for COOL_1_3_0.
+
+Cheers
+
+Andrea
+
+===============================================
+User tag example specification (AV 28.02.2006)
+===============================================
+
+General idea: an IOV can be inserted with AT MOST ONE associated user tag. 
+This means that a consistent HEAD version must be kept (within the folder
+and the channel) not only for ALL IOVS, but also for EACH subset of IOVS
+associated to any given user tag.
+
+Two specifications are discussed:
+- In the 'old' (April 2005) specification, 'user tags' (those specified 
+  when inserting a new IOV) are different from 'standard tags' (those 
+  specified when tagging the HEAD of existing IOVs) and can NOT be mixed.
+- In the 'new' (February 2006) specification, 'user tags' (those specified 
+  when inserting a new IOV) are NOT different from 'standard tags (those 
+  specified when tagging the HEAD of existing IOVs) and can be mixed.
+
+[NB Each tag is independent of each other: it is NOT foreseen that one can 
+ask for "the HEAD for tag A AND tag B, or the HEAD for tag A OR tag B".]
+
+Example 1
+----------
+1. User inserts P1 payload in [  0, 100] with NO (user) tags
+2. User inserts P2 payload in [ 10,  50] with (user) tag #1
+3. User inserts P3 payload in [ 30,  80] with (user) tag #2
+4. User inserts P4 payload in [ 20,  40] with (user) tag #1
+5. User inserts P5 payload in [ 30,  70] with (user) tag #2
+
+The following applies both to the old and new specifications.
+The only difference is in terminology: in the old specification, 
+these tags are 'user' tags (different type from 'standard' tags),
+while in the new specification they are just 'tags'.
+
+HEAD versions after last insertion:
+
+All IOVS (irrespective of tags):
+  P1 in [  0,  10]
+  P2 in [ 10,  20]
+  P4 in [ 20,  30]
+  P5 in [ 30,  70]
+  P3 in [ 70,  80]
+  P1 in [ 80, 100]
+
+(User) tag #1:
+  P2 in [ 10,  20]
+  P4 in [ 20,  40]
+  P2 in [ 40,  50]
+
+(User) tag #2:
+  P5 in [ 30,  70]
+  P3 in [ 70,  80]
+
+Example 2 (old specification)
+------------------------------
+1. User inserts P1 payload in [  0,  50] with NO user tags
+2. User inserts P2 payload in [ 50, 100] with NO user tags
+3. User tags HEAD of folder with tag #2
+4. User inserts P4 payload in [ 10,  50] with user tag #1
+5. User inserts P5 payload in [ 30,  80] with user tag #2 - EXCEPTION
+6. User inserts P6 payload in [ 20,  40] with user tag #1
+7. User inserts P7 payload in [ 30,  70] with user tag #2 - EXCEPTION
+
+In the old specification, step 5 and 7 here throw an exception: tag #2 is 
+already reserved as a 'standard' tag and cannot be used as a 'user' tag.
+
+HEAD versions after last insertion (ignoring step 5 and 7):
+
+All IOVS (irrespective of tags):
+  P1 in [  0,  10]
+  P4 in [ 10,  20]
+  P6 in [ 20,  30]
+  P7 in [ 30,  70]
+  P5 in [ 70,  80]
+  P2 in [ 80, 100]
+
+Tag #1:
+  P4 in [ 10,  20]
+  P6 in [ 20,  40]
+  P4 in [ 40,  50]
+
+User tag #2:
+  P1 in [  0,  50]
+  P2 in [ 50, 100]
+
+Example 2 (new specification)
+------------------------------
+1. User inserts P1 payload in [  0,  50] with NO user tags
+2. User inserts P2 payload in [ 50, 100] with NO user tags
+3. User tags HEAD of folder with tag #2
+4. User inserts P4 payload in [ 10,  50] with user tag #1
+5. User inserts P5 payload in [ 30,  80] with user tag #2
+6. User inserts P6 payload in [ 20,  40] with user tag #1
+7. User inserts P7 payload in [ 30,  70] with user tag #2
+
+In the new specification, no exceptions are thrown.
+
+HEAD versions after last insertion:
+
+All IOVS (irrespective of tags):
+  P1 in [  0,  10]
+  P4 in [ 10,  20]
+  P6 in [ 20,  30]
+  P7 in [ 30,  70]
+  P5 in [ 70,  80]
+  P2 in [ 80, 100]
+
+Tag #1:
+  P4 in [ 10,  20]
+  P6 in [ 20,  40]
+  P4 in [ 40,  50]
+
+Tag #2:
+  P1 in [  0,  30]
+  P7 in [ 30,  70]
+  P5 in [ 70,  80]
+  P2 in [ 80, 100]
+
+Example 3 (new specification)
+------------------------------
+ 1. User inserts P1  payload in [  0,  50] with NO user tags
+ 2. User inserts P2  payload in [ 50, 100] with NO user tags
+ 3. User tags HEAD of folder with tag #2
+ 4. User inserts P4  payload in [ 10,  50] with user tag #1
+ 5. User inserts P5  payload in [ 30,  80] with user tag #2
+ 6. User inserts P6  payload in [ 20,  40] with user tag #1
+ 7. User inserts P7  payload in [ 30,  70] with user tag #2
+ 8. User tags HEAD of folder with tag #2
+ 9. User inserts P9  payload in [ 30,  80] with user tag #2
+10. User inserts P10 payload in [ 20,  40] with user tag #1
+
+In the new specification, no exceptions are thrown.
+
+HEAD versions after last insertion:
+
+All IOVS (irrespective of tags):
+  P1  in [  0,  10]
+  P4  in [ 10,  20]
+  P10 in [ 20,  40]
+  P9  in [ 40,  80]
+  P2  in [ 80, 100]
+
+Tag #1:
+  P4  in [ 10,  20]
+  P10 in [ 20,  40]
+  P4  in [ 40,  50]
+
+Tag #2:
+  P1 in [  0,  10]
+  P4 in [ 10,  20]
+  P6 in [ 20,  30]
+  P9 in [ 30,  80]
+  P2 in [ 80, 100]
+
+Essentially, tagging the HEAD (in step 8) with the same tag name 
+previously used for inserting IOVs with attached tags (e.g. step 5)
+logically erases all tag-to-IOV relations defined when inserting 
+IOVs with attached tags (e.g. the tag attached in step 5 loses meaning).
+
+-------------------------------------------------------------------------------
+
+For reference: David Malon presented his use case in the presentation 
+at the 2003 CondDB Workshop: http://agenda.cern.ch/fullAgenda.php?ida=a036470
diff --git a/RelationalCool/doc/userTagsSpec3.txt b/RelationalCool/doc/userTagsSpec3.txt
new file mode 100644
index 000000000..e13358fae
--- /dev/null
+++ b/RelationalCool/doc/userTagsSpec3.txt
@@ -0,0 +1,335 @@
+From Andrea.Valassi@cern.ch Wed Mar  1 17:46:57 2006
+Date: Wed, 1 Mar 2006 17:46:17 +0100 (CET)
+From: Andrea Valassi <Andrea.Valassi@cern.ch>
+To: LCG ConditionsDB developers
+    <project-lcg-peb-conditionsdb-developers@cern.ch>
+Subject: User tag functionality specification
+
+Dear all,
+
+following Monday's discussion with Sven and Richard at the weekly COOL 
+meeting about the new 'user tag' functionality required for COOL_1_3_0,
+we had some discussion in the development team about the possibility
+to extend the specification proposed last year to meet the new requirements
+discussed at the meeting. We also discussed the possible implementation
+of the additional requirements.
+
+To cut a long story short: we are working on the additional requirements
+presented, and it seems feasible that we could be able to implement
+them eventually. However, the planned timescale for user tag implementation
+in COOL_1_3_0 by March 21 is too tight to complete the specification
+and implementation design. I would therefore propose that we only provide
+an implementation of the 'old' specification (spec#1 below) in COOL130.
+We can then converge on the discussion of an extended specification
+and of its implementation, if required.
+
+Would this be acceptable, or is it useless to have an implementation
+of the 'old' user tag requirement specification (spec#1), and you would 
+rather wait to have one of the two 'extended' specifications (spec#2 and 
+spec#3) implemented later on?
+
+Extensive details of the proposed specification spec#1 for COOL130,
+and of its possible future extensions spec#2 and spec#3, follow below.
+
+The main difference is that in spec#1 standard tags and user tags
+are different types of tags that cannot be mixed, while in spec#2
+and spec#3 they are the same single type of tags and can be mixed.
+The difference between spec#2 and spec#3 is on the issue whether
+the system should/can erase all memory of tag manipulations (spec#2)
+or should preserve it (spec#3).
+
+Please let us know...
+
+Thanks
+Andrea
+
+===============================================
+User tag specification (AV 01.03.2006)
+===============================================
+
+For reference: the original specification is the one I proposed 
+in an e-mail message in April last year, which you may find in
+the COOL CVS doc repository in http://cool.cvs.cern.ch/cgi-bin/cool.cgi/cool/RelationalCool/doc/userTagsSpec.txt
+
+Details of the specifications we are discussing:
+
+Spec#1 (April 2005)
+--------------------
+- Users may attach a (standard) tag to the current HEAD (already in COOL128).
+- Users may attach a (standard) tag to the HEAD as it was at a given time 
+  in the past (already in COOL128).
+- NEW: Users may attach AT MOST ONE (user) tag to any IOV they are inserting.
+- User tags (attached on IOV insertion) and standard tags (attached by
+  tagging the current or past HEAD) are of two different types and they 
+  cannot be mixed. There are methods to check what type of tag is
+  a given tag name. If a tag already exists as standard/user tag,
+  then an exception is thrown on any attempt to use it as the
+  opposite type user/standard.
+- A method to 'tag as tagB all IOVs that were tagged as tagA at time t0 in
+  the past' has not been explicitly requested and will NOT be implemented,
+  neither for HEAD tags (as in COOL128), nor in the new user tags.
+  Nevertheless, the proposed implementation for spec#1 could (to be 
+  confirmed) allow this extra functionality to be added without major
+  schema changes, both for standard tags and user tags.
+
+More details about the last point (history of retags, i.e. changes of tags):
+- Whenever a current/past HEAD is attached a tag, any memory of previously
+  assigned tags is erased (this is what happens in COOL128). This is very
+  clear as the 'retag' functionality is only available to users by first
+  deleting the tag and then reassigning it. In principle, however, it is 
+  always possible to recover a previously assigned HEAD tag, as long
+  as one knows the time at which the relevant IOVs were the HEAD.
+- User tags are different from standard tags and are implemented in
+  a different way. The insertion of new IOVs with a user tag attached to
+  them implies a continuous modification of the set of IOVs with the
+  user tag attached. However, the proposed implementation of user tags 
+  is a clone of that used for the global HEAD tag, on a separate branch:
+  in principle, it should be possible to recover the set of IOVs that
+  were in a certain user tag at a specified time in the past, just like 
+  this is possible for the global HEAD.
+
+Implementation notes:
+- Tag to IOV associations are stored in a separate IOV2TAG table.
+  The contents of this table, however, are largely redundant with
+  the IOV table and could easily be rebuilt via simple queries
+  on the IOV table (as in COOL128).
+
+Spec#2 (February 2006)
+-----------------------
+- Users may attach a (standard) tag to the current HEAD (already in COOL128).
+- Users may attach a (standard) tag to the HEAD as it was at a given time 
+  in the past (already in COOL128).
+- NEW: Users may attach AT MOST ONE (user) tag to any IOV they are inserting.
+- User tags (attached on IOV insertion) and standard tags (attached by
+  tagging the current or past HEAD) are not two different types of tags.
+  Users can tag a current global HEAD or past global HEAD with a given tag, 
+  then insert a new IOV and attach it to the existing tag. They can also tag 
+  a current global HEAD or past global HEAD with a tag after having inserted
+  an IOV with that same tag attached.
+- The system has NO MEMORY whatsoever of tag manipulations.
+  A method to 'tag as tagB all IOVs that were tagged as tagA at time t0 in
+  the past' has not been explicitly requested and CANNOT be implemented.
+  Whenever the contents of a tag are changed, whether through tagged
+  IOV insertion or through current/past HEAD tag, all previous associations
+  of IOVs to tags are ERASED. If users make a mistake in tagging... too bad.
+  In particular, if a user inserts an IOV with MYTAG, but later tags
+  a new HEAD as MYTAG, that IOV is kept in the system (and is used in the
+  determination of the global HEAD), but the information that it had been 
+  inserted with tag MYTAG is ERASED.
+
+Implementation notes:
+- The proposed implementation might (to be confirmed) also make it possible 
+  to attach any number of tags on insertion. This is because an IOV may
+  in any case be attached to any number of tags via the current/past HEAD
+  tag functionality. The system is thus forced to maintain as many
+  separate IOV branches as there are tags defined, whether these were
+  attached as HEAD tags or on IOV insertion.
+- Tag to IOV associations are stored in a separate IOV2TAG table.
+  The contents of this table CANNOT easily be recovered from simple queries
+  on the IOV table, because the memory of tag manipulations is missing.
+  The IOV2TAG table provides a lot of extra information with respect
+  to that contained in the IOV table. Note that the payload is stored
+  in the IOV table.
+
+Spec#3 (March 2006)
+--------------------
+- Users may attach a (standard) tag to the current HEAD (already in COOL128).
+- Users may attach a (standard) tag to the HEAD as it was at a given time 
+  in the past (already in COOL128).
+- NEW: Users may attach AT MOST ONE (user) tag to any IOV they are inserting.
+- User tags (attached on IOV insertion) and standard tags (attached by
+  tagging the current or past HEAD) are not two different types of tags.
+  Users can tag a current global HEAD or past global HEAD with a given tag, 
+  then insert a new IOV and attach it to the existing tag. They can also tag 
+  a current global HEAD or past global HEAD with a tag after having inserted
+  an IOV with that same tag attached.
+- The system maintains the full memory of tag manipulations.
+  A method to 'tag as tagB all IOVs that were tagged as tagA at time t0 in
+  the past' can be implemented. Whenever the contents of a tag are changed, 
+  whether through tagged IOV insertion or through current/past HEAD tag, 
+  tag-to-IOV associations are updated and new ones are inserted,
+  but none are deleted. Methods are provided to allow users to
+  erase (or simply archive?) obsolete data from the IOV table if required.
+
+Implementation notes:
+- The proposed implementation might (to be confirmed) also make it possible 
+  to attach any number of tags on insertion. This is because an IOV may
+  in any case be attached to any number of tags via the current/past HEAD
+  tag functionality. The system is thus forced to maintain as many
+  separate IOV branches as there are tags defined, whether these were
+  attached as HEAD tags or on IOV insertion.
+- Tag to IOV associations and their history are stored in the IOV table. 
+  A snapshot of this table containing only the currently tagged IOVs
+  is stored in the IOV2TAG table for performance reasons.
+- The number of rows in the IOV table is roughly proportional to the
+  number of tags applied, because the full history of tag manipulations
+  is retained. The need to move the payload to a separate table
+  becomes much more pressing.
+
+===============================================
+User tag example specification (AV 01.03.2006)
+===============================================
+
+Main points of spec#1:
+- An IOV can be inserted with AT MOST ONE associated user tag. 
+  This means that a consistent HEAD version must be kept (within the folder
+  and the channel) not only for ALL IOVS, but also for EACH subset of IOVS
+  associated to any given user tag.
+- Two types of tags exist: 'user tags' (those specified when inserting a 
+  new IOV) are different from 'standard tags' (those specified when tagging 
+  the HEAD of existing IOVs) and can NOT be mixed.
+
+[NB Each tag is independent of each other: it is NOT foreseen that one can 
+ask for "the HEAD for tag A AND tag B, or the HEAD for tag A OR tag B".]
+
+Example 1
+----------
+1. User inserts P1 payload in [  0, 100] with NO (user) tags
+2. User inserts P2 payload in [ 10,  50] with (user) tag #1
+3. User inserts P3 payload in [ 30,  80] with (user) tag #2
+4. User inserts P4 payload in [ 20,  40] with (user) tag #1
+5. User inserts P5 payload in [ 30,  70] with (user) tag #2
+
+Note that this example is the same for all of spec#1, spec#2 and spec#3. 
+The only difference is in terminology: in spec#1
+these tags are 'user' tags (different type from 'standard' tags),
+while in spec#2 and spec#3 they are just 'tags'.
+
+HEAD versions after last insertion:
+
+All IOVS (irrespective of tags):
+  P1 in [  0,  10]
+  P2 in [ 10,  20]
+  P4 in [ 20,  30]
+  P5 in [ 30,  70]
+  P3 in [ 70,  80]
+  P1 in [ 80, 100]
+
+(User) tag #1:
+  P2 in [ 10,  20]
+  P4 in [ 20,  40]
+  P2 in [ 40,  50]
+
+(User) tag #2:
+  P5 in [ 30,  70]
+  P3 in [ 70,  80]
+
+Example 2 (spec #1)
+--------------------
+1. User inserts P1 payload in [  0,  50] with NO user tags
+2. User inserts P2 payload in [ 50, 100] with NO user tags
+3. User tags HEAD of folder with tag #2
+4. User inserts P4 payload in [ 10,  50] with user tag #1
+5. User inserts P5 payload in [ 30,  80] with user tag #2 - EXCEPTION
+6. User inserts P6 payload in [ 20,  40] with user tag #1
+7. User inserts P7 payload in [ 30,  70] with user tag #2 - EXCEPTION
+
+In spec#1, step 5 and 7 here throw an exception: tag #2 is already reserved 
+as a 'standard' tag and cannot be used as a 'user' tag.
+
+HEAD versions after last insertion (ignoring step 5 and 7):
+
+All IOVS (irrespective of tags):
+  P1 in [  0,  10]
+  P4 in [ 10,  20]
+  P6 in [ 20,  30]
+  P7 in [ 30,  70]
+  P5 in [ 70,  80]
+  P2 in [ 80, 100]
+
+Tag #1:
+  P4 in [ 10,  20]
+  P6 in [ 20,  40]
+  P4 in [ 40,  50]
+
+User tag #2:
+  P1 in [  0,  50]
+  P2 in [ 50, 100]
+
+Example 2 (spec#2 and spec#3)
+------------------------------
+1. User inserts P1 payload in [  0,  50] with NO user tags
+2. User inserts P2 payload in [ 50, 100] with NO user tags
+3. User tags HEAD of folder with tag #2
+4. User inserts P4 payload in [ 10,  50] with user tag #1
+5. User inserts P5 payload in [ 30,  80] with user tag #2
+6. User inserts P6 payload in [ 20,  40] with user tag #1
+7. User inserts P7 payload in [ 30,  70] with user tag #2
+
+In specifications spec#2 and spec#3, no exceptions are thrown.
+
+HEAD versions after last insertion:
+
+All IOVS (irrespective of tags):
+  P1 in [  0,  10]
+  P4 in [ 10,  20]
+  P6 in [ 20,  30]
+  P7 in [ 30,  70]
+  P5 in [ 70,  80]
+  P2 in [ 80, 100]
+
+Tag #1:
+  P4 in [ 10,  20]
+  P6 in [ 20,  40]
+  P4 in [ 40,  50]
+
+Tag #2:
+  P1 in [  0,  30]
+  P7 in [ 30,  70]
+  P5 in [ 70,  80]
+  P2 in [ 80, 100]
+
+Example 3 (spec#2 and spec#3)
+------------------------------
+ 1. User inserts P1  payload in [  0,  50] with NO user tags
+ 2. User inserts P2  payload in [ 50, 100] with NO user tags
+ 3. User tags HEAD of folder with tag #2
+ 4. User inserts P4  payload in [ 10,  50] with user tag #1
+ 5. User inserts P5  payload in [ 30,  80] with user tag #2
+ 6. User inserts P6  payload in [ 20,  40] with user tag #1
+ 7. User inserts P7  payload in [ 30,  70] with user tag #2
+ 8. User tags HEAD of folder with tag #2
+ 9. User inserts P9  payload in [ 30,  80] with user tag #2
+10. User inserts P10 payload in [ 20,  40] with user tag #1
+
+In specification spec#1, step 5 throws an exception.
+This example mainly shows the differemce between spec#2 and spec#3.
+
+In spec#2 and spec#3, no exceptions are thrown.
+In both specifications the tags after the last insertions are the same:
+
+HEAD versions after last insertion:
+
+All IOVS (irrespective of tags):
+  P1  in [  0,  10]
+  P4  in [ 10,  20]
+  P10 in [ 20,  40]
+  P9  in [ 40,  80]
+  P2  in [ 80, 100]
+
+Tag #1:
+  P4  in [ 10,  20]
+  P10 in [ 20,  40]
+  P4  in [ 40,  50]
+
+Tag #2:
+  P1 in [  0,  10]
+  P4 in [ 10,  20]
+  P6 in [ 20,  30]
+  P9 in [ 30,  80]
+  P2 in [ 80, 100]
+
+In spec#2, tagging the HEAD (in step 8) with the same tag name 
+previously used for inserting IOVs with attached tags (e.g. step 5)
+logically erases all tag-to-IOV relations defined when inserting 
+IOVs with attached tags (e.g. the tag attached in step 5 loses meaning).
+That is to say, the memory that P5 and P7 were inserted with tag#2 is lost.
+The memory that a HEAD tag was applied at the time of step 3 is also lost.
+
+In spec#3, the full memory of tag manipulations is retained.
+
+-------------------------------------------------------------------------------
+
+For reference: David Malon presented his use case in the presentation 
+at the 2003 CondDB Workshop: http://agenda.cern.ch/fullAgenda.php?ida=a036470
+
diff --git a/RelationalCool/python/CoolAuthentication/__init__.py b/RelationalCool/python/CoolAuthentication/__init__.py
new file mode 100644
index 000000000..7bfa861ac
--- /dev/null
+++ b/RelationalCool/python/CoolAuthentication/__init__.py
@@ -0,0 +1,87 @@
+#!/usr/bin/env python
+import os, sys
+
+def setNewValueFromTag( oldValue, line, tag ):
+    if line.startswith( tag ) :
+        return line[len(tag):len(line)-1].strip(' ').strip('=').strip(' ')
+    else :
+        return oldValue
+
+def getDbIdProperties( dbId, rwOnly=False, debug=False ) :
+    if rwOnly:
+        cmd = 'coolAuthentication -1RW "' + dbId + '"'
+    else:
+        cmd = 'coolAuthentication -1 "' + dbId + '"'        
+    f = os.popen(cmd)
+    theCorA = ""
+    theCorR = ""
+    theCorM = ""
+    theTech = ""
+    theSrvr = ""
+    theSchm = ""
+    theUser = ""
+    thePswd = ""
+    theDbNm = ""
+    line = f.readline()
+    while line :
+        ###print line
+        theCorA = setNewValueFromTag( theCorA, line, "==> coralAlias" )
+        theCorR = setNewValueFromTag( theCorR, line, "==> coralReplica" )
+        theCorM = setNewValueFromTag( theCorM, line, "==> coralMode" )
+        theTech = setNewValueFromTag( theTech, line, "==> technology" )
+        theSrvr = setNewValueFromTag( theSrvr, line, "==> server" )
+        theSchm = setNewValueFromTag( theSchm, line, "==> schema" )
+        theUser = setNewValueFromTag( theUser, line, "==> user" )
+        thePswd = setNewValueFromTag( thePswd, line, "==> password" )
+        theDbNm = setNewValueFromTag( theDbNm, line, "==> dbname" ) #COOL13x
+        theDbNm = setNewValueFromTag( theDbNm, line, "==> dbName" ) #COOL20x
+        line = f.readline()
+    status = f.close()
+    if status :
+        # Fix bug #24248: do not fail for sqlite/frontier if there are no
+        # username/password in authentication.xml (they are dummy anyway!).
+        # NB: this bug has been fixed in coolAuthentication in COOL200, but
+        # the schema evolution test uses coolAuthentication from COOL133c.
+        if theTech == "sqlite" :            
+            ###print "WARNING! Command '" + cmd + "' failed! Status:", status
+            if theUser == "" : theUser = "DUMMY"
+            if thePswd == "" : thePswd = "DUMMY"
+        elif theTech == "frontier" :            
+            ###print "WARNING! Command '" + cmd + "' failed! Status:", status
+            if theUser == "" :
+                if theSchm != "" : theUser = theSchm
+                else : theUser = "DUMMY"
+            if thePswd == "" : thePswd = "DUMMY"
+        else :
+            print "ERROR! Command '" + cmd + "' failed! Status:", status
+            sys.exit(status)
+    if debug :
+        print "CoralAlias: '" + theCorA + "'"
+        print "CoralReplica: '" + theCorR + "'"
+        print "CoralMode: '" + theCorM + "'"
+        print "Technology: '" + theTech + "'"
+        print "Server: '" + theSrvr + "'"
+        print "Schema: '" + theSchm + "'"
+        print "User: '" + theUser + "'"
+        print "Password: '" + thePswd + "'"
+        print "DbName: '" + theDbNm + "'"
+    return [ theTech, theSrvr, theSchm, theUser, thePswd, theDbNm, theCorA, theCorR, theCorM ]
+    
+def technology( dbIdProperties ) : return dbIdProperties[0]
+
+def server( dbIdProperties ) : return dbIdProperties[1]
+
+def schema( dbIdProperties ) : return dbIdProperties[2]
+
+def user( dbIdProperties ) : return dbIdProperties[3]
+
+def password( dbIdProperties ) : return dbIdProperties[4]
+
+def dbName( dbIdProperties ) : return dbIdProperties[5]
+
+def coralAlias( dbIdProperties ) : return dbIdProperties[6]
+
+def coralReplica( dbIdProperties ) : return dbIdProperties[7]
+
+def coralMode( dbIdProperties ) : return dbIdProperties[8]
+    
diff --git a/RelationalCool/python/CoolDescribeTable/__init__.py b/RelationalCool/python/CoolDescribeTable/__init__.py
new file mode 100644
index 000000000..b1d8f7016
--- /dev/null
+++ b/RelationalCool/python/CoolDescribeTable/__init__.py
@@ -0,0 +1,218 @@
+#!/usr/bin/env python
+# See http://docs.python.org/lib/string-methods.html
+import os, sys
+import CoolAuthentication
+
+def myLPartition( text, sep ):
+    index = text.find(sep)
+    if index==-1 : return text
+    else : return text[(index+1):].strip(' ')
+
+def myRPartition( text, sep ):
+    index = text.rfind(sep)
+    if index==-1 : return text
+    else : return text[:index].strip(' ')
+
+def mySplit( text ):
+    nl = text.count('(')
+    nr = text.count(')')
+    if nl!=nr :
+        print "ERROR! Count mismatch for '(' and ')'", nl, nr
+        sys.exit(-1)
+    flds = []
+    newFld = ""
+    for fld in text.split(','):
+        if ( newFld != "" ) : newFld = newFld+","
+        newFld = newFld+fld
+        if newFld.count('(') == newFld.count(')') :
+            flds.append(newFld)
+            newFld = ""
+    return flds
+
+# See http://dev.mysql.com/doc/refman/4.1/en/create-table.html
+def parseCreateTable( txt, debug=False ):
+    if debug : print "1 - Parse:", txt
+    # Remove newline characters
+    txt = txt.replace('\n','')
+    # Remove actual newline characters
+    txt = txt.replace('\\n','')
+    # Parse only the text until the first ";"
+    while txt != myRPartition(txt,';') : txt = myRPartition(txt,';')
+    # Assume that the current text is a CREATE TABLE statement
+    # Parse only the column definition list "( ... , ... )"
+    txt = myLPartition(txt,'(')
+    txt = myRPartition(txt,')')
+    if debug : print "2 - Parse:", txt
+    # Split the comma-separated fields of "( ... , ... )"
+    # Do not split a field that contains a comma enclosed by parentheses
+    columns = []
+    for fld in mySplit(txt):
+        fld = fld.strip(' ').rstrip(' ').split(' ') 
+        if debug : print "3 - Parse:", fld
+        # Check that there is at least one word in this field
+        if len(fld)<=1 : break
+        # Word #0 is a column name if it does not define a constraint
+        if fld[0] == "CONSTRAINT" : break
+        if fld[0] == "KEY" : break
+        if fld[0] == "INDEX" : break
+        if fld[0] == "PRIMARY" : break
+        if fld[0] == "FOREIGN" : break
+        if fld[0] == "UNIQUE" : break
+        if fld[0] == "FULLTEXT" : break
+        if fld[0] == "SPATIAL" : break
+        if fld[0] == "CHECK" : break
+        name = fld[0]
+        # Strip off '`' (mysql)
+        name = name.strip('`').rstrip('`')
+        # Strip off '"' (sqlite)
+        name = name.strip('"').rstrip('"')
+        # Word #1 defines the type
+        type = fld[1].upper()
+        # Word #2 may be an UNSIGNED qualifier 
+        if len(fld)>2 \
+               and fld[2].upper() == "UNSIGNED" :
+            type=type+" UNSIGNED"
+        # Else word #2 may be a BINARY qualifier
+        elif len(fld)>2 \
+                 and fld[2].upper() == "BINARY" :
+            type=type+" BINARY"
+        # Else words #2-3 may define BINARY as "COLLATE xxx_bin"
+        elif len(fld)>3 \
+                 and fld[2].upper() == "COLLATE" \
+                 and fld[3].upper().endswith('_BIN') :
+            type=type+" BINARY"
+        # Else words #5-6 may define BINARY as "COLLATE xxx_bin"
+        elif len(fld)>6 \
+                 and fld[2].upper() == "CHARACTER" \
+                 and fld[3].upper() == "SET" \
+                 and fld[5].upper() == "COLLATE" \
+                 and fld[6].upper().endswith('_BIN') :
+            type=type+" BINARY"
+        column = [ name, type ]
+        columns.append(column)
+    return columns
+
+def oracleDescribeTable( dbIdProp, table, debug=False ) :
+    if debug : print "0 - Describe table: " + table
+    server = CoolAuthentication.server( dbIdProp )
+    schema = CoolAuthentication.schema( dbIdProp ).upper()
+    user = CoolAuthentication.user( dbIdProp )
+    password = CoolAuthentication.password( dbIdProp )
+    dbName = CoolAuthentication.dbName( dbIdProp )
+    sqlDir = __path__[0] + os.sep + 'sql'
+    sqlFile = sqlDir  + os.sep + "oracleShowCreateTable.sql"
+    if not os.path.exists( sqlFile ) :
+        print "ERROR! SQL file not found:", sqlFile
+        sys.exit(-1)
+    sql = "@" + sqlFile + " " + schema + " " + table
+    cmd = "sqlplus -S -L " + user + "/" + password + "@" + server + " " + sql
+    cmd_no_passwd = "sqlplus -S -L " + user + "/" + "***" + "@" + server + " " + sql
+    columns = []
+    ###return columns
+    f = os.popen(cmd)
+    line = f.readline()
+    while line :
+        if debug : print "1 - Parse: " + line
+        line = line.replace('\n','')
+        line = line.replace('\t','')
+        line = line.strip(' ').rstrip(' ').split() 
+        # There should be exactly two words in this field
+        if len(line)==1 and line[0]!='':
+            print "PANIC! Unexpected number of words:", line
+            sys.exit(-1)
+        elif len(line)==2 :
+            name = line[0]
+            type = line[1].upper()
+            column = [ name, type ]
+            columns.append(column)
+        elif len(line)>2 :
+            print "PANIC! Unexpected number of words:", line
+            sys.exit(-1)
+        line = f.readline()
+    status = f.close()
+    if status :
+        print "ERROR! Command '" + cmd_no_passwd + "' failed! Status code:", status
+        sys.exit(status)
+    return columns
+
+def mysqlDescribeTable( dbIdProp, table, debug=False ) :
+    if debug : print "0 - Describe table: " + table
+    server = CoolAuthentication.server( dbIdProp )
+    schema = CoolAuthentication.schema( dbIdProp )
+    user = CoolAuthentication.user( dbIdProp )
+    password = CoolAuthentication.password( dbIdProp )
+    dbName = CoolAuthentication.dbName( dbIdProp )
+    # A special treatment is needed for the host:port syntax: 
+    # the port number must be parsed out and passed explicitly
+    index = server.find(':')
+    if index!=-1 :
+        host = server[:index]
+        port = server[index+1:]
+        server = " -h" + host + " -P" + port
+    else:
+        server = " -h" + server        
+    ###sql = "describe " + schema + "." + table
+    ###sql = "show columns from " + schema + "." + table
+    sql = "show create table " + schema + "." + table
+    # This does not work on Windows... (bug #23438)
+    if os.environ["OS"] != "Windows_NT" :
+        cmd = "mysql -u"+user + " -p"+password + server + " -B -N -e '"+sql + "'"
+        cmd_no_passwd = "mysql -u"+user + " -p"+"***" + server + " -B -N -e '"+sql + "'"
+    # This works on Windows... but it might also work elsewhere
+    else :
+        cmd = 'mysql -u'+user + ' -p'+password + server + ' -B -N -e "'+sql + '"'
+        cmd_no_passwd = 'mysql -u'+user + ' -p'+'***' + server + ' -B -N -e "'+sql + '"'
+    f = os.popen(cmd)
+    text = ""
+    line = f.readline()
+    while line :
+        text = text + line + " "
+        line = f.readline()
+    status = f.close()
+    if status :
+        print "ERROR! Command '" + cmd_no_passwd + "' failed! Status code:", status
+        sys.exit(status)
+    return parseCreateTable( text, debug )
+
+def sqliteDescribeTable( dbIdProp, table, debug=False ) :
+    if debug : print "0 - Describe table: " + table
+    schema = CoolAuthentication.schema( dbIdProp )
+    dbName = CoolAuthentication.dbName( dbIdProp )
+    if not os.path.exists( schema ) :
+        print "ERROR! SQLite database file not found:", schema
+        sys.exit(-1)
+    sql = ".schema " + table
+    # This does not work on Windows... (bug #23438)
+    if os.environ["OS"] != "Windows_NT" :
+        cmd = "sqlite3 " + schema + " '" + sql + "'"
+    # This works on Windows... but it might also work elsewhere
+    else :
+        cmd = 'sqlite3 ' + schema + ' "' + sql + '"'
+    f = os.popen(cmd)
+    text = ""
+    line = f.readline()
+    while line :
+        text = text + line + " "
+        line = f.readline()
+    status = f.close()
+    if status :
+        print "ERROR! Command '" + cmd + "' failed! Status code:", status
+        sys.exit(status)
+    return parseCreateTable( text, debug )
+
+def describeTable( dbId, table, debug=False ) :
+    if debug : print "COOL dbId: '" + dbId + "'"
+    dbIdProp = CoolAuthentication.getDbIdProperties( dbId, debug )
+    tech = CoolAuthentication.technology( dbIdProp )
+    if debug : print "Technology: '" + tech + "'"
+    if debug : print "Describe table: '" + table + "'"
+    if tech == "oracle" :
+        columns = oracleDescribeTable( dbIdProp, table, debug )
+    elif tech == "mysql" :
+        columns = mysqlDescribeTable( dbIdProp, table, debug )
+    elif tech == "sqlite" :
+        columns = sqliteDescribeTable( dbIdProp, table, debug )
+    else :
+        print "ERROR! Technology '" + tech + "' is not supported"
+        sys.exit(-1)
+    return columns
diff --git a/RelationalCool/python/CoolDescribeTable/sql/oracleShowCreateTable.sql b/RelationalCool/python/CoolDescribeTable/sql/oracleShowCreateTable.sql
new file mode 100644
index 000000000..9870530a4
--- /dev/null
+++ b/RelationalCool/python/CoolDescribeTable/sql/oracleShowCreateTable.sql
@@ -0,0 +1,26 @@
+-- NB An interesting alternative could be
+-- select dbms_metadata.get_ddl('TABLE','&2','&1') from dual;
+-- But this gives ORA-00904 for lcg_cool@cooldev (while it works for
+-- avalassi@cooldev or lcg_cool@devdb10: missing privs? old s/w version?)
+
+-- SELECT shows column values without column names
+set heading off;
+-- Suppress the display of each line before and after substitution
+set verify off;
+-- Suppress the display of the number of rows selected
+set feedback off;
+-- Make sure each table row fits in a single output line
+set linesize 10000;
+-- Make sure all table rows fit in a single page
+set pagesize 1000;
+-- Issue the SELECT statement
+select name, replace(replace(type,',)',')'),'()') type from (
+select column_name as name, 
+data_type||'('||
+decode(data_precision, null, null, 0, null, data_precision||',')||
+decode(data_scale, null, null, 0, null, data_scale||',')||
+decode(char_length, null, null, 0, null, char_length)||')' as type
+from all_tab_columns where owner='&1' and table_name='&2')
+order by name;
+-- Exit
+exit;
diff --git a/RelationalCool/python/CoolGatherSchemaStats/__init__.py b/RelationalCool/python/CoolGatherSchemaStats/__init__.py
new file mode 100644
index 000000000..104fe940d
--- /dev/null
+++ b/RelationalCool/python/CoolGatherSchemaStats/__init__.py
@@ -0,0 +1,36 @@
+#!/usr/bin/env python
+import os, sys
+import CoolAuthentication
+
+def oracleGatherSchemaStats( dbIdProp, debug=False ) :
+    server = CoolAuthentication.server( dbIdProp )
+    schema = CoolAuthentication.schema( dbIdProp ).upper()
+    user = CoolAuthentication.user( dbIdProp )
+    password = CoolAuthentication.password( dbIdProp )
+    dbName = CoolAuthentication.dbName( dbIdProp )
+    sqlDir = __path__[0] + os.sep + 'sql'
+    sqlFile = sqlDir  + os.sep + "oracleGatherSchemaStats.sql"
+    if not os.path.exists( sqlFile ) :
+        print "ERROR! SQL file not found:", sqlFile
+        sys.exit(-1)
+    sql = "@" + sqlFile + " " + schema
+    cmd = "sqlplus -S -L " + user + "/" + password + "@" + server + " " + sql
+    f = os.system(cmd)
+    return
+
+def gatherSchemaStats( dbId, debug=False ) :
+    print "Gather statistics for schema hosting database '"+dbId+"'"
+    dbIdProp = CoolAuthentication.getDbIdProperties( dbId, debug )
+    tech = CoolAuthentication.technology( dbIdProp )
+    dbName = CoolAuthentication.dbName( dbIdProp )
+    if debug : print "Technology: '" + tech + "'"
+    if tech == "oracle" :
+        columns = oracleGatherSchemaStats( dbIdProp, debug )
+    elif tech == "mysql" :
+        print "WARNING! Statistics tools not implemented for technology "+tech
+    elif tech == "sqlite" :
+        print "WARNING! Statistics tools not implemented for technology "+tech
+    else :
+        print "ERROR! Technology '" + tech + "' is not supported"
+        sys.exit(-1)
+    return
diff --git a/RelationalCool/python/CoolGatherSchemaStats/sql/oracleGatherSchemaStats.sql b/RelationalCool/python/CoolGatherSchemaStats/sql/oracleGatherSchemaStats.sql
new file mode 100644
index 000000000..b32f6f2df
--- /dev/null
+++ b/RelationalCool/python/CoolGatherSchemaStats/sql/oracleGatherSchemaStats.sql
@@ -0,0 +1,2 @@
+execute DBMS_STATS.GATHER_SCHEMA_STATS( '&1', no_invalidate=>FALSE );
+exit;
diff --git a/RelationalCool/python/CoolGatherTableStats/__init__.py b/RelationalCool/python/CoolGatherTableStats/__init__.py
new file mode 100644
index 000000000..6881c49a7
--- /dev/null
+++ b/RelationalCool/python/CoolGatherTableStats/__init__.py
@@ -0,0 +1,55 @@
+#!/usr/bin/env python
+import os, sys
+import CoolAuthentication
+from CoolShowTables import showTables
+
+def oracleGatherTableStats( dbIdProp, tableName, debug=False ) :
+    server = CoolAuthentication.server( dbIdProp )
+    schema = CoolAuthentication.schema( dbIdProp ).upper()
+    user = CoolAuthentication.user( dbIdProp )
+    password = CoolAuthentication.password( dbIdProp )
+    dbName = CoolAuthentication.dbName( dbIdProp )
+    sqlDir = __path__[0] + os.sep + 'sql'
+    sqlFile = sqlDir  + os.sep + "oracleGatherTableStats.sql"
+    if not os.path.exists( sqlFile ) :
+        print "ERROR! SQL file not found:", sqlFile
+        sys.exit(-1)
+    sql = "@" + sqlFile + " " + schema + " " + tableName
+    cmd = "sqlplus -S -L " + user + "/" + password + "@" + server + " " + sql
+    f = os.system(cmd)
+    return
+
+def gatherSingleTableStats( dbIdProp, tableName, debug=False ) :
+    if tableName=="":
+        print "ERROR! Table name not specified"
+        sys.exit(-1)
+    print "Gather statistics for table '"+tableName+"'"
+    tech = CoolAuthentication.technology( dbIdProp )
+    if tech == "oracle" :
+        columns = oracleGatherTableStats( dbIdProp, tableName, debug )
+    else :
+        print "ERROR! Technology '" + tech + "' is not supported"
+        sys.exit(-1)
+    return
+
+def gatherTableStats( dbId, tableName, debug=False ) :
+    dbIdProp = CoolAuthentication.getDbIdProperties( dbId, debug )
+    tech = CoolAuthentication.technology( dbIdProp )
+    if debug : print "Technology: '" + tech + "'"
+    if tech == "oracle" :
+        if tableName=="":
+            print "Gather statistics for ALL tables in database '" + dbId + "'"
+            for table in showTables( dbId, debug ):
+                gatherSingleTableStats( dbIdProp, table, debug )
+        else:        
+            print "Gather statistics for table '" + tableName + \
+                  "' in database '" + dbId + "'"
+            gatherSingleTableStats( dbIdProp, tableName, debug )
+    elif tech == "mysql" :
+        print "WARNING! Statistics tools not implemented for technology "+tech
+    elif tech == "sqlite" :
+        print "WARNING! Statistics tools not implemented for technology "+tech
+    else :
+        print "ERROR! Technology '" + tech + "' is not supported"
+        sys.exit(-1)
+
diff --git a/RelationalCool/python/CoolGatherTableStats/sql/oracleGatherTableStats.sql b/RelationalCool/python/CoolGatherTableStats/sql/oracleGatherTableStats.sql
new file mode 100644
index 000000000..03cbf1d2d
--- /dev/null
+++ b/RelationalCool/python/CoolGatherTableStats/sql/oracleGatherTableStats.sql
@@ -0,0 +1,2 @@
+execute DBMS_STATS.GATHER_TABLE_STATS( '&1', '&2', no_invalidate=>FALSE );
+exit;
diff --git a/RelationalCool/python/CoolQueryManager/__init__.py b/RelationalCool/python/CoolQueryManager/__init__.py
new file mode 100644
index 000000000..81e13044d
--- /dev/null
+++ b/RelationalCool/python/CoolQueryManager/__init__.py
@@ -0,0 +1,192 @@
+#!/usr/bin/env python
+# See http://docs.python.org/lib/string-methods.html
+import os, sys
+import CoolAuthentication
+
+def myLPartition( text, sep ):
+    index = text.find(sep)
+    if index==-1 : return text
+    else : return text[(index+1):].strip(' ')
+
+def myRPartition( text, sep ):
+    index = text.rfind(sep)
+    if index==-1 : return text
+    else : return text[:index].strip(' ')
+
+def parseSelect( text, uppercase, debug=False ):
+    ###if debug : print "0bis - Parse:", text
+    # Remove newline characters
+    text = text.replace('\n','')
+    # Remove actual newline characters
+    text = text.replace('\\n','')
+    # Remove tab characters
+    text = text.replace('\t','')
+    if debug : print "1 - Parse:", text
+    if uppercase :
+        ltr = '<TR>'
+        rtr = '</TR>'
+        ltd = '<TD>'
+        rtd = '</TD>'
+    else :
+        ltr = '<tr>'
+        rtr = '</tr>'
+        ltd = '<td>'
+        rtd = '</td>'
+    ###if debug : print "2a - Parse:", text
+    text=text.replace(ltr+ltr,ltr) # MySQL has a <TR><TR> for the first row...
+    text=text.replace(' align="right"','') # Oracle may use <td align="right">
+    ###if debug : print "2b - Parse:", text
+    nl = text.count( ltr )
+    nr = text.count( rtr )
+    if nl!=nr :
+        print "ERROR! Count mismatch for '"+ltr+"' and '"+rtr + "' (",\
+              nl, nr, ") in '"+text+"'" 
+        sys.exit(-1)
+    nl = text.count( ltd )
+    nr = text.count( rtd )
+    if nl!=nr :
+        print "ERROR! Count mismatch for '"+ltd+"' and '"+rtd + "' (",\
+              nl, nr, ") in '"+text+"'" 
+        sys.exit(-1)
+    rows = []
+    for row in text.split( ltr ):
+        newRow = myRPartition( row, rtr )
+        if debug : print "3 - Parse:", newRow
+        nl = newRow.count( ltd )
+        nr = newRow.count( rtd )
+        if nl!=nr :
+            print "ERROR! Count mismatch for '"+ltd+"' and '"+rtd + "' (",\
+                  nl, nr, ") in '"+newRow+"'" 
+            sys.exit(-1)
+        elif nl!=0 :
+            flds = []
+            ifld = 0
+            for fld in newRow.split( ltd ):
+                ifld=ifld+1
+                if ifld > 1 :
+                    newFld = myRPartition( fld, rtd )
+                    if debug : print "4 - Parse:", newFld
+                    flds.append( newFld )
+            rows.append( flds )
+    if debug : print "5 - End parsing"
+    return rows
+
+def oracleSelect( dbIdProp, sql, debug=False ) :
+    if debug : print "0 - Executing SQL: '" + sql + "'"
+    #if os.environ["OS"] == "Windows_NT" :
+    #    print "ERROR! CoolQueryManager is not supported for technology 'oracle' on OS '" + os.environ["OS"] + "' (on OSTYPE '" + os.environ["OSTYPE"] + "')"
+    #    sys.exit(-1)    
+    server = CoolAuthentication.server( dbIdProp )
+    schema = CoolAuthentication.schema( dbIdProp ).upper()
+    user = CoolAuthentication.user( dbIdProp )
+    password = CoolAuthentication.password( dbIdProp )
+    dbName = CoolAuthentication.dbName( dbIdProp )
+    if os.environ["OS"] != "Windows_NT" :
+        cmd = 'echo "' + sql + '" | sqlplus -S -L -M "HTML ON" ' + user + '/' + password + '@' + server
+        cmd_no_passwd = 'echo "' + sql + '" | sqlplus -S -L -M "HTML ON" ' + user + '/***' + '@' + server
+        ###columns = []
+        ###os.system(cmd)
+        ###return columns
+        fout = os.popen(cmd)
+    else :
+        cmd = 'sqlplus -S -L -M "HTML ON" ' + user + '/' + password + '@' + server
+        cmd_no_passwd = 'sqlplus -S -L -M "HTML ON" ' + user + '/***' + '@' + server
+        if debug : print "0 - Open pipe for command: '" + cmd_no_passwd + "'"
+        index = sql.find('\*')
+        if index!=-1 :
+            if debug : print "0 - Replace '\*' by '*' in SQL"
+        if debug : print "0 - Input to pipe is SQL statement: '" + sql.replace('\*','*') + "'"
+        # See for instance http://effbot.org/librarybook/popen2.htm
+        pipe = os.popen2(cmd)
+        fin=pipe[0]
+        fout=pipe[1]
+        fin.write(sql.replace('\*','*')+'\n')
+        fin.flush()
+        fin.close()
+    text = ""
+    line = fout.readline()
+    while line :
+        text = text + line + " "
+        line = fout.readline()
+    status = fout.close()
+    if status :
+        print "ERROR! Command '" + cmd_no_passwd + "' failed! Status code:", status
+        sys.exit(status)
+    uppercase = False
+    return parseSelect( text, uppercase, debug )
+
+def mysqlSelect( dbIdProp, sql, debug=False ) :
+    if debug : print "0 - Executing SQL: '" + sql + "'"
+    server = CoolAuthentication.server( dbIdProp )
+    schema = CoolAuthentication.schema( dbIdProp )
+    user = CoolAuthentication.user( dbIdProp )
+    password = CoolAuthentication.password( dbIdProp )
+    dbName = CoolAuthentication.dbName( dbIdProp )
+    # A special treatment is needed for the host:port syntax: 
+    # the port number must be parsed out and passed explicitly
+    index = server.find(':')
+    if index!=-1 :
+        host = server[:index]
+        port = server[index+1:]
+        server = " -h" + host + " -P" + port
+    else:
+        server = " -h" + server        
+    cmd = 'mysql --html -u'+user + ' -p'+password + server + ' ' + schema + ' -B -N -e "'+sql + '"'
+    ###print cmd
+    cmd_no_passwd = 'mysql --html -u'+user + ' -p***' + server + ' ' + schema + ' -B -N -e "'+sql + '"'
+    f = os.popen(cmd)
+    text = ""
+    line = f.readline()
+    while line :
+        text = text + line + " "
+        line = f.readline()
+    status = f.close()
+    if status :
+        print "ERROR! Command '" + cmd_no_passwd + "' failed! Status code:", status
+        sys.exit(status)
+    uppercase = True
+    return parseSelect( text, uppercase, debug )
+
+def sqliteSelect( dbIdProp, sql, debug=False ) :
+    if debug : print "0 - Executing SQL: '" + sql + "'"
+    schema = CoolAuthentication.schema( dbIdProp )
+    dbName = CoolAuthentication.dbName( dbIdProp )
+    if not os.path.exists( schema ) :
+        print "ERROR! SQLite database file not found:", schema
+        sys.exit(-1)
+    cmd = 'sqlite3 -html ' + schema + ' "' + sql + '"'
+    f = os.popen(cmd)
+    text = ""
+    line = f.readline()
+    while line :
+        text = text + line + " "
+        line = f.readline()
+    status = f.close()
+    if status :
+        print "ERROR! Command '" + cmd + "' failed! Status code:", status
+        sys.exit(status)
+    uppercase = True
+    return parseSelect( text, uppercase, debug )
+
+def executeSqlSelect( dbId, sql, debug=False ) :
+    if debug : print "Executing SQL statement: '" + sql + "'"
+    index = sql.find('select')
+    if index!=0 :
+        index = sql.find('SELECT')
+        if index!=0 :
+            print "ERROR! Only 'SELECT' SQL statements are supported"
+            sys.exit(-1)
+    if debug : print "COOL dbId: '" + dbId + "'"
+    dbIdProp = CoolAuthentication.getDbIdProperties( dbId, debug )
+    tech = CoolAuthentication.technology( dbIdProp )
+    if debug : print "Technology: '" + tech + "'"
+    if tech == "oracle" :
+        columns = oracleSelect( dbIdProp, sql, debug )
+    elif tech == "mysql" :
+        columns = mysqlSelect( dbIdProp, sql, debug )
+    elif tech == "sqlite" :
+        columns = sqliteSelect( dbIdProp, sql, debug )
+    else :
+        print "ERROR! CoolQueryManager is not supported for technology '" + tech + "'"
+        sys.exit(-1)
+    return columns
diff --git a/RelationalCool/python/CoolShowTables/__init__.py b/RelationalCool/python/CoolShowTables/__init__.py
new file mode 100644
index 000000000..e31bd3264
--- /dev/null
+++ b/RelationalCool/python/CoolShowTables/__init__.py
@@ -0,0 +1,128 @@
+#!/usr/bin/env python
+# See http://docs.python.org/lib/string-methods.html
+import os, sys
+import CoolAuthentication
+
+def oracleShowTables( dbIdProp, debug=False ) :
+    server = CoolAuthentication.server( dbIdProp )
+    schema = CoolAuthentication.schema( dbIdProp ).upper()
+    user = CoolAuthentication.user( dbIdProp )
+    password = CoolAuthentication.password( dbIdProp )
+    dbName = CoolAuthentication.dbName( dbIdProp )
+    if debug : print "0 - Show tables in database name: " + dbName
+    sqlDir = __path__[0] + os.sep + 'sql'
+    sqlFile = sqlDir  + os.sep + "oracleShowTables.sql"
+    if not os.path.exists( sqlFile ) :
+        print "ERROR! SQL file not found:", sqlFile
+        sys.exit(-1)
+    sql = "@" + sqlFile + " " + schema + " " + dbName
+    cmd = "sqlplus -S -L " + user + "/" + password + "@" + server + " " + sql
+    tables = []
+    ###f = os.system(cmd)
+    ###return tables
+    f = os.popen(cmd)
+    line = f.readline()
+    while line :
+        if debug : print "1 - Parse: " + line
+        line = line.replace('\n','')
+        line = line.replace('\t','')
+        line = line.strip(' ').rstrip(' ').split() 
+        # There should be only one field (ignore lines with 0 fields)
+        if len(line)==1 :
+            table = line[0]
+            tables.append(table)
+        elif len(line)>1 :
+            print "PANIC! Unexpected number of words:", line
+            sys.exit(-1)
+        line = f.readline()
+    status = f.close()
+    if status :
+        print "ERROR! Command '" + cmd + "' failed! Status code:", status
+        sys.exit(status)
+    return tables
+
+def mysqlShowTables( dbIdProp, debug=False ) :
+    server = CoolAuthentication.server( dbIdProp )
+    schema = CoolAuthentication.schema( dbIdProp )
+    user = CoolAuthentication.user( dbIdProp )
+    password = CoolAuthentication.password( dbIdProp )
+    dbName = CoolAuthentication.dbName( dbIdProp )
+    if debug : print "0 - Show tables in database name: " + dbName
+    # A special treatment is needed for the host:port syntax: 
+    # the port number must be parsed out and passed explicitly
+    index = server.find(':')
+    if index!=-1 :
+        host = server[:index]
+        port = server[index+1:]
+        server = " -h" + host + " -P" + port
+    else:
+        server = " -h" + server        
+    sql = "show tables like \'" + dbName + "%\'"
+    cmd = "mysql -u"+user + " -p"+password + server + " " + schema \
+          + " -B -N -e \"" + sql + "\""
+    tables = []
+    ###f = os.system(cmd)
+    ###return tables
+    f = os.popen(cmd)
+    line = f.readline()
+    while line :
+        if debug : print "1 - Parse: " + line
+        line = line.replace('\n','')
+        line = line.replace('\t','')
+        line = line.strip(' ').rstrip(' ').split() 
+        for table in line :
+            tables.append(table)
+        line = f.readline()
+    status = f.close()
+    if status :
+        print "ERROR! Command '" + cmd + "' failed! Status code:", status
+        sys.exit(status)
+    tables.sort()
+    return tables
+
+def sqliteShowTables( dbIdProp, debug=False ) :
+    schema = CoolAuthentication.schema( dbIdProp )
+    dbName = CoolAuthentication.dbName( dbIdProp )
+    if debug : print "0 - Show tables in database name: " + dbName
+    if not os.path.exists( schema ) :
+        print "ERROR! SQLite database file not found:", schema
+        sys.exit(-1)
+    sql = ".tables " + dbName
+    cmd = "sqlite3 " + schema + " '" + sql + "'"
+    tables = []
+    ###f = os.system(cmd)
+    ###return tables
+    f = os.popen(cmd)
+    line = f.readline()
+    while line :
+        if debug : print "1 - Parse: " + line
+        line = line.replace('\n','')
+        line = line.replace('\t','')
+        line = line.strip(' ').rstrip(' ').split() 
+        for table in line :
+            tables.append(table)
+        line = f.readline()
+    status = f.close()
+    if status :
+        print "ERROR! Command '" + cmd + "' failed! Status code:", status
+        sys.exit(status)
+    tables.sort()
+    return tables
+
+def showTables( dbId, debug=False ) :
+    if debug : print "COOL dbId: '" + dbId + "'"
+    dbIdProp = CoolAuthentication.getDbIdProperties( dbId, debug )
+    tech = CoolAuthentication.technology( dbIdProp )
+    dbName = CoolAuthentication.dbName( dbIdProp )
+    if debug : print "Technology: '" + tech + "'"
+    if debug : print "Show tables for database name: '" + dbName + "'"
+    if tech == "oracle" :
+        columns = oracleShowTables( dbIdProp, debug )
+    elif tech == "mysql" :
+        columns = mysqlShowTables( dbIdProp, debug )
+    elif tech == "sqlite" :
+        columns = sqliteShowTables( dbIdProp, debug )
+    else :
+        print "ERROR! Technology '" + tech + "' is not supported"
+        sys.exit(-1)
+    return columns
diff --git a/RelationalCool/python/CoolShowTables/sql/oracleShowTables.sql b/RelationalCool/python/CoolShowTables/sql/oracleShowTables.sql
new file mode 100644
index 000000000..eee6461b5
--- /dev/null
+++ b/RelationalCool/python/CoolShowTables/sql/oracleShowTables.sql
@@ -0,0 +1,14 @@
+-- SELECT shows column values without column names
+set heading off;
+-- Suppress the display of each line before and after substitution
+set verify off;
+-- Suppress the display of the number of rows selected
+set feedback off;
+-- Make sure each table row fits in a single output line
+set linesize 10000;
+-- Make sure all table rows fit in a single page
+set pagesize 1000;
+-- Issue the SELECT statement
+select table_name from all_tables where owner='&1' and table_name like '&2%';
+-- Exit
+exit;
diff --git a/RelationalCool/scripts/coolAuthentication.py b/RelationalCool/scripts/coolAuthentication.py
new file mode 100755
index 000000000..019e47db1
--- /dev/null
+++ b/RelationalCool/scripts/coolAuthentication.py
@@ -0,0 +1,31 @@
+#!/usr/bin/env python
+import os, sys
+from CoolAuthentication import *
+    
+def usage() :
+    print "Usage: " + os.path.split(sys.argv[0])[1] + " [-RW] dbId"
+    print "[Option -RW: display only the first R/W replica]"
+    sys.exit(-1)
+    
+##############################################################################
+
+if __name__ == '__main__':
+    if len(sys.argv) == 2 :
+        rwOnly = False
+        dbId = sys.argv[1]
+    elif len(sys.argv) == 3 and sys.argv[1] == "-RW" :
+        rwOnly = True
+        dbId = sys.argv[2]
+    else:
+        usage()
+    print "COOL dbId:", dbId
+    dbIdProp = getDbIdProperties( dbId, rwOnly )
+    print "CoralAlias: '" + coralAlias( dbIdProp ) + "'"
+    print "CoralReplica: '" + coralReplica( dbIdProp ) + "'"
+    print "CoralMode: '" + coralMode( dbIdProp ) + "'"
+    print "Technology: '" + technology( dbIdProp ) + "'"
+    print "Server: '" + server( dbIdProp ) + "'"
+    print "Schema: '" + schema( dbIdProp ) + "'"
+    print "User: '" + user( dbIdProp ) + "'"
+    print "Password: '" + password( dbIdProp ) + "'"
+    print "DbName: '" + dbName( dbIdProp ) + "'"
diff --git a/RelationalCool/scripts/coolDescribeTable.py b/RelationalCool/scripts/coolDescribeTable.py
new file mode 100755
index 000000000..21203d27c
--- /dev/null
+++ b/RelationalCool/scripts/coolDescribeTable.py
@@ -0,0 +1,53 @@
+#!/usr/bin/env python
+import os, sys
+from CoolDescribeTable import *
+
+def myTest1():
+    print 'Test myLPartition and myRPartition'
+    txt = 'abc( def )ghi'
+    print 'Partition "' + txt + '"'
+    print '"' + myLPartition(txt,'(') + '"'
+    print '"' + myLPartition(txt,'z') + '"'
+    print '"' + myRPartition(txt,')') + '"'
+    print '"' + myRPartition(txt,'z') + '"'
+    txt = 'abc(( def ))ghi'
+    print 'Partition "' + txt + '"'
+    print '"' + myLPartition(txt,'(') + '"'
+    print '"' + myLPartition(txt,'z') + '"'
+    print '"' + myRPartition(txt,')') + '"'
+    print '"' + myRPartition(txt,'z') + '"'
+    txt = 'z'
+    print 'Partition "' + txt + '"'
+    print '"' + myLPartition(txt,'(') + '"'
+    print '"' + myLPartition(txt,'z') + '"'
+    print '"' + myRPartition(txt,')') + '"'
+    print '"' + myRPartition(txt,'z') + '"'
+    sys.exit(0)
+
+def usage() :
+    if os.environ["OS"] != "Windows_NT" :
+        cmd = os.path.split(sys.argv[0])[1]
+        print "Usage: " + cmd + " [-debug] dbId table"
+    else :
+        cmd = "wineWrap.sh python " + sys.argv[0]
+        print "Usage: " + cmd + " [-debug] dbId table"
+        # Example: wineWrap.sh python ../../RelationalCool/scripts/coolDescribeTable.py -debug \"$COOLTESTDB\" COOLTEST_F0006_IOVS
+        print "Example: " + cmd + " -debug \\\"$COOLTESTDB\\\" COOLTEST_F0006_IOVS"
+    sys.exit(-1)
+    
+##############################################################################
+
+if __name__ == '__main__':
+    ###myTest1()
+    if len(sys.argv)<3 : usage()
+    if sys.argv[1]=="-debug" :
+        if len(sys.argv)<4 : usage()
+        debug=True
+        dbId = sys.argv[2]
+        table = sys.argv[3]
+    else:
+        debug=False
+        dbId = sys.argv[1]
+        table = sys.argv[2]
+    columns = describeTable( dbId, table, debug )
+    for column in columns : print column
diff --git a/RelationalCool/scripts/coolExecuteSql.csh b/RelationalCool/scripts/coolExecuteSql.csh
new file mode 100755
index 000000000..f856d3fbd
--- /dev/null
+++ b/RelationalCool/scripts/coolExecuteSql.csh
@@ -0,0 +1,189 @@
+#!/bin/csh -f
+
+if ( "$1" != "-html" ) then
+  set theHtml = OFF
+  set theArg1 = "$1"
+  set theArg2 = "$2"
+  set theArg3 = "$3"
+else
+  set theHtml = ON
+  set theArg1 = "$2"
+  set theArg2 = "$3"
+  set theArg3 = "$4"
+endif
+
+if ( "$theArg2" == "-e" || "$theArg2" == "-eb" ) then
+  if ( "$theArg2" == "-e" ) then 
+    set theCmd = ON
+  else
+    set theCmd = BATCH
+  endif
+  set theConnStr = "$theArg1"
+  set theSqlFile = "$theArg3"
+else
+  set theCmd = OFF
+  set theConnStr = "$theArg1"
+  set theSqlFile = "$theArg2"
+endif
+
+#echo "theHtml    = $theHtml"
+#echo "theCmd     = $theCmd"
+#echo "theConnStr = $theConnStr"
+#echo "theSqlFile = $theSqlFile"
+
+if ( "$theConnStr" == "" || "$theSqlFile" == "" ) then
+  echo "Usage: $0 '[-html]' dbId { file.sql | -e 'command' | -eb 'command' }"
+  echo Example: $0 '"oracle://SERVER;schema=SCHEMA;dbname=DB"' file.sql
+  echo Example: $0 -html '"oracle://SERVER;schema=SCHEMA;dbname=DB"' file.sql
+  echo Example: $0 '"mysql://SERVER;schema=SCHEMA;dbname=DB"' -e 'cmd'
+  echo Example: $0 '"mysql://SERVER;schema=SCHEMA;dbname=DB"' -eb 'cmd'
+  echo Example: $0 -html '"mysql://SERVER;schema=SCHEMA;dbname=DB"' -eb 'cmd'
+  exit 1
+endif
+
+set theAuth = `coolAuthentication "$theConnStr" | & grep '==>'`
+set theAuth = `echo "$theAuth ==>"`
+#echo "theAuth   = $theAuth"
+
+set theUrl = `echo "$theAuth" | awk '{str=$0; sep="==> urlHidePswd = "; ind=index(str,sep)+length(sep); str=substr(str,ind); sep=" ==>"; ind=index(str,sep)-1; str=substr(str,1,ind); l=length(str); cr=substr(str,l); if (cr=="\r") print substr(str,1,l-1); else print str;}'`
+#echo "theUrl    = $theUrl"
+
+if ( "$theUrl" == "" ) then
+  echo "ERROR! Could not execute SQL script $theSqlFile against COOL database "\""$theConnStr"\"
+  echo "ERROR! Invalid COOL databaseId or missing authentication credentials"
+  exit 1
+endif
+
+if ( "${theHtml}" != ON && "${theCmd}" != BATCH ) then
+  echo Execute SQL script \""$theSqlFile"\" against COOL database \""$theUrl"\"
+endif
+
+set theTech = `echo "$theAuth" | awk '{str=$0; sep="==> technology = "; ind=index(str,sep)+length(sep); str=substr(str,ind); sep=" ==>"; ind=index(str,sep)-1; str=substr(str,1,ind); l=length(str); cr=substr(str,l); if (cr=="\r") print substr(str,1,l-1); else print str;}'`
+set theHost = `echo "$theAuth" | awk '{str=$0; sep="==> server = "; ind=index(str,sep)+length(sep); str=substr(str,ind); sep=" ==>"; ind=index(str,sep)-1; str=substr(str,1,ind); l=length(str); cr=substr(str,l); if (cr=="\r") print substr(str,1,l-1); else print str;}'`
+set theSchema = `echo "$theAuth" | awk '{str=$0; sep="==> schema = "; ind=index(str,sep)+length(sep); str=substr(str,ind); sep=" ==>"; ind=index(str,sep)-1; str=substr(str,1,ind); l=length(str); cr=substr(str,l); if (cr=="\r") print substr(str,1,l-1); else print str;}'`
+set theUser = `echo "$theAuth" | awk '{str=$0; sep="==> user = "; ind=index(str,sep)+length(sep); str=substr(str,ind); sep=" ==>"; ind=index(str,sep)-1; str=substr(str,1,ind); l=length(str); cr=substr(str,l); if (cr=="\r") print substr(str,1,l-1); else print str;}'`
+set thePswd = `echo "$theAuth" | awk '{str=$0; sep="==> password = "; ind=index(str,sep)+length(sep); str=substr(str,ind); sep=" ==>"; ind=index(str,sep)-1; str=substr(str,1,ind); l=length(str); cr=substr(str,l); if (cr=="\r") print substr(str,1,l-1); else print str;}'`
+set theDbName = `echo "$theAuth" | awk '{str=$0; sep="==> dbname = "; ind=index(str,sep)+length(sep); str=substr(str,ind); sep=" ==>"; ind=index(str,sep)-1; str=substr(str,1,ind); l=length(str); cr=substr(str,l); if (cr=="\r") print substr(str,1,l-1); else print str;}'`
+#echo "theTech   = $theTech"
+#echo "theHost   = $theHost"
+#echo "theSchema = $theSchema"
+#echo "theUser   = $theUser"
+#echo "thePswd   = $thePswd"
+#echo "theDbName = $theDbName"
+#exit
+
+# 2005.06.22 
+# Here was a CHARMING bug (introduced by upgrading version of cygwin?).
+# For theTech="oracle", on Windows this was actually equal to "oracle\r".
+# All of the following returned (7,7) on Windows and (6,0) on SLC.
+# echo a | awk -v s=$theTech '{print length(s), index(s,"\15")}'
+# echo a | awk -v s=$theTech '{print length(s), index(s,"\015")}'
+# echo a | awk -v s=$theTech '{print length(s), index(s,"\r")}'
+# As a consequence ( "$theTech" == "oracle" ) was false on Windows.
+# Now fixed by explicitly removing "\r" in awk above. 
+# For Oracle both Windows and SLC return (6,0).
+
+if ( "$theCmd" == "OFF" ) then
+  if ( ! -e "$theSqlFile" ) then
+    echo "ERROR! File not found: '$theSqlFile'"
+    exit 1
+  endif
+  set theSqlScript = `basename $theSqlFile`
+  set theSqlDir = `dirname $theSqlFile`
+  #echo "theSqlScript = $theSqlScript"
+  #echo "theSqlDir = $theSqlDir"
+else
+  set theSqlDir = .  
+endif
+
+# HACK on Windows (limit to the size of file names)
+pushd $theSqlDir > /dev/null
+set theSqlDir = .
+#echo "theSqlDir = $theSqlDir"
+
+#--------
+# Oracle
+#--------
+if ( "$theTech" == "oracle" ) then
+
+  set theSilent="-S"
+  ###set theSilent=""
+
+  if ( "${theHtml}" == ON ) then
+
+    if ( "$theCmd" == "OFF" ) then
+      # This format requires "quit;" at the end of the script...
+      #sqlplus ${theSilent} -L -M "HTML ON" ${theUser}/${thePswd}@${theHost} @${theSqlDir}/${theSqlScript}
+      # This format does NOT requires "quit;" at the end of the script!
+      cat ${theSqlDir}/${theSqlScript} | sqlplus ${theSilent} -L -M "HTML ON" ${theUser}/${thePswd}@${theHost}
+    else
+      # This format does NOT requires "quit;" at the end of the script!
+      # Enclose it in quotes to be able to 'select * from table'...!
+      echo "${theSqlFile}" | sqlplus ${theSilent} -L -M "HTML ON" ${theUser}/${thePswd}@${theHost}
+    endif
+
+  else
+
+    if ( "$theCmd" == "OFF" ) then
+      # This format requires "quit;" at the end of the script...
+      #sqlplus ${theSilent} -L ${theUser}/${thePswd}@${theHost} @${theSqlDir}/${theSqlScript}
+      # This format does NOT requires "quit;" at the end of the script!
+      cat ${theSqlDir}/${theSqlScript} | sqlplus ${theSilent} -L ${theUser}/${thePswd}@${theHost}
+    else
+      # This format does NOT requires "quit;" at the end of the script!
+      # Enclose it in quotes to be able to 'select * from table'...!
+      echo "${theSqlFile}" | sqlplus ${theSilent} -L ${theUser}/${thePswd}@${theHost}
+    endif
+
+  endif
+
+#-------
+# MySQL
+#-------
+else if ( "$theTech" == "mysql" ) then
+
+  if ( "${theHtml}" == ON ) then
+    set theHtml = "--html"
+  else
+    set theHtml = ""
+  endif
+
+  # A special treatment is needed for the host:port syntax: 
+  # the port number must be parsed out and passed explicitly
+  set thePort = `echo "$theHost" | awk '{str=$0; sep=":"; ind=index(str,sep); if (ind>0) print "-P" substr(str,ind+length(sep)); else print "";};'`
+  set theHost = `echo "$theHost" | awk '{str=$0; sep=":"; ind=index(str,sep); if (ind>0) print substr(str,0,ind-length(sep)); else print str;};'`
+  #echo "theHost   = $theHost"
+  #echo "thePort   = $thePort"
+
+  if ( "$theCmd" == "OFF" ) then
+    mysql ${theHtml} -u${theUser} -p${thePswd} -h${theHost} ${thePort} ${theSchema} < ${theSqlDir}/${theSqlScript}
+  else
+    if ( "$theCmd" == "BATCH" ) then
+      mysql ${theHtml} -u${theUser} -p${thePswd} -h${theHost} ${thePort} ${theSchema} -B -N -e "${theSqlFile}"
+    else
+      mysql ${theHtml} -u${theUser} -p${thePswd} -h${theHost} ${thePort} ${theSchema} -e "${theSqlFile}"
+    endif
+  endif
+
+#--------
+# SQLite
+#--------
+else if ( "$theTech" == "sqlite" ) then
+
+  if ( "${theHtml}" == ON ) then
+    set theHtml = "-html"
+  else
+    set theHtml = ""
+  endif
+
+  if ( "$theCmd" == "OFF" ) then
+    sqlite3 ${theHtml} ${theSchema} ".read ${theSqlDir}/${theSqlScript}"
+  else
+    sqlite3 ${theHtml} ${theSchema} "${theSqlFile}"
+  endif
+
+endif
+
+# HACK on Windows 
+popd > /dev/null
+
diff --git a/RelationalCool/scripts/coolGatherSchemaStats.py b/RelationalCool/scripts/coolGatherSchemaStats.py
new file mode 100755
index 000000000..e72b0907a
--- /dev/null
+++ b/RelationalCool/scripts/coolGatherSchemaStats.py
@@ -0,0 +1,24 @@
+#!/usr/bin/env python
+import os, sys
+from CoolGatherSchemaStats import *
+
+def usage() :
+    cmd = os.path.split(sys.argv[0])[1]
+    #print "Usage: " + cmd + " [-debug] dbId"
+    print "Usage: " + cmd + " dbId"
+    sys.exit(-1)
+    
+##############################################################################
+
+if __name__ == '__main__':
+    if len(sys.argv)==2:
+        debug=False
+        dbId = sys.argv[1]
+        gatherSchemaStats( dbId, debug )
+    #elif len(sys.argv)==3:
+    #    if sys.argv[1]!="-debug": usage()
+    #    debug=True
+    #    dbId = sys.argv[2]
+    #    gatherSchemaStats( dbId, debug )
+    else:
+        usage()
diff --git a/RelationalCool/scripts/coolGatherTableStats.py b/RelationalCool/scripts/coolGatherTableStats.py
new file mode 100755
index 000000000..efc8d2e6f
--- /dev/null
+++ b/RelationalCool/scripts/coolGatherTableStats.py
@@ -0,0 +1,31 @@
+#!/usr/bin/env python
+import os, sys
+from CoolGatherTableStats import *
+
+def usage() :
+    cmd = os.path.split(sys.argv[0])[1]
+    #print "Usage: " + cmd + " [-debug] dbId [tableName]"
+    print "Usage: " + cmd + " dbId [tableName]"
+    sys.exit(-1)
+    
+##############################################################################
+
+if __name__ == '__main__':
+    if len(sys.argv)==2:
+        debug=False
+        dbId = sys.argv[1]
+        tableName = ""
+        gatherTableStats( dbId, tableName, debug )
+    elif len(sys.argv)==3:
+        debug=False
+        dbId = sys.argv[1]
+        tableName = sys.argv[2]
+        gatherTableStats( dbId, tableName, debug )
+    #elif len(sys.argv)==4:
+    #    if sys.argv[1]!="-debug": usage()
+    #    debug=True
+    #    dbId = sys.argv[2]
+    #    tableName = sys.argv[3]
+    #    gatherTableStats( dbId, tableName, debug )
+    else:
+        usage()
diff --git a/RelationalCool/scripts/coolQueryManager.py b/RelationalCool/scripts/coolQueryManager.py
new file mode 100755
index 000000000..032561d9f
--- /dev/null
+++ b/RelationalCool/scripts/coolQueryManager.py
@@ -0,0 +1,33 @@
+#!/usr/bin/env python
+import os, sys
+from CoolQueryManager import *
+
+def usage() :
+    if os.environ["OS"] != "Windows_NT" :
+        cmd = os.path.split(sys.argv[0])[1]
+        print "Usage: " + cmd + " [-debug] dbId \"select... from... where x='y';\""
+    else :
+        cmd = "wineWrap.sh python " + sys.argv[0]
+        print "Usage: " + cmd + " [-debug] dbId \"select... from... where x='y';\""
+        # Example: wineWrap.sh python ../../RelationalCool/scripts/coolQueryManager.py -debug \"$COOLTESTDB\" \""select OBJECT_ID from COOLTEST_F0006_IOVS;"\"
+        print "Example: " + cmd + " -debug \\\"$COOLTESTDB\\\" \\\"\"select OBJECT_ID from COOLTEST_F0006_IOVS;\"\\\""
+        # Example: wineWrap.sh python ../../RelationalCool/scripts/coolQueryManager.py -debug \"$COOLTESTDB\" \""select \* from COOLTEST_DB_ATTRIBUTES;"\"
+        print "Example: " + cmd + " -debug \\\"$COOLTESTDB\\\" \\\"\"select \\* from COOLTEST_DB_ATTRIBUTES;\"\\\""
+    sys.exit(-1)
+    
+##############################################################################
+
+if __name__ == '__main__':
+    ###myTest1()
+    if len(sys.argv)<3 : usage()
+    if sys.argv[1]=="-debug" :
+        if len(sys.argv)<4 : usage()
+        debug=True
+        dbId = sys.argv[2]
+        sql = sys.argv[3]
+    else:
+        debug=False
+        dbId = sys.argv[1]
+        sql = sys.argv[2]
+    columns = executeSqlSelect( dbId, sql, debug )
+    for column in columns : print column
diff --git a/RelationalCool/scripts/coolShowTables.py b/RelationalCool/scripts/coolShowTables.py
new file mode 100755
index 000000000..18ceef894
--- /dev/null
+++ b/RelationalCool/scripts/coolShowTables.py
@@ -0,0 +1,22 @@
+#!/usr/bin/env python
+import os, sys
+from CoolShowTables import *
+
+def usage() :
+    cmd = os.path.split(sys.argv[0])[1]
+    print "Usage: " + cmd + " [-debug] dbId"
+    sys.exit(-1)
+    
+##############################################################################
+
+if __name__ == '__main__':
+    if len(sys.argv)<2 : usage()
+    if sys.argv[1]=="-debug" :
+        if len(sys.argv)<3 : usage()
+        debug=True
+        dbId = sys.argv[2]
+    else:
+        debug=False
+        dbId = sys.argv[1]
+    tables = showTables( dbId, debug )
+    for table in tables : print table
diff --git a/RelationalCool/scripts/coolSqlplus.sh b/RelationalCool/scripts/coolSqlplus.sh
new file mode 100755
index 000000000..8b568d176
--- /dev/null
+++ b/RelationalCool/scripts/coolSqlplus.sh
@@ -0,0 +1,19 @@
+#!/bin/bash
+# See https://twiki.cern.ch/twiki/bin/view/PSSGroup/RlWrap
+if [ "${SCRAM_ARCH:0:5}" = "win32" ]; then
+    cmd=`basename $0`
+    echo "ERROR! $cmd is not supported for $SCRAM_ARCH: use sqlplus instead"
+    exit 1
+elif [ "${CMTCONFIG:0:5}" = "win32" ]; then
+    cmd=`basename $0`
+    echo "ERROR! $cmd is not supported for $CMTCONFIG: use sqlplus instead"
+    exit 1
+else
+    rlwrap -h > /dev/null 2&>1
+    if [ $? == 0 ]; then
+        rlwrap \sqlplus $@
+    else
+        \sqlplus $@
+    fi
+fi
+
diff --git a/RelationalCool/scripts/scramShowUses b/RelationalCool/scripts/scramShowUses
new file mode 100755
index 000000000..b9ffdb620
--- /dev/null
+++ b/RelationalCool/scripts/scramShowUses
@@ -0,0 +1,2 @@
+#!/bin/tcsh -f
+scram -debug b echo_INCLUDE | awk -f `dirname $0`/scramShowUses.awk
diff --git a/RelationalCool/scripts/scramShowUses.awk b/RelationalCool/scripts/scramShowUses.awk
new file mode 100644
index 000000000..61e04e8e0
--- /dev/null
+++ b/RelationalCool/scripts/scramShowUses.awk
@@ -0,0 +1,450 @@
+#----------------------------------------------------------------------------
+#
+# Title: "scramShowUses.awk" 
+# Author: Andrea Valassi (Andrea.Valassi@cern.ch)
+# Date: 26-MAR-2004
+#
+# Purpose: This AWK script is a 'CMT show uses' emulator for SCRAM.
+#
+# Usage: 'scram -debug b echo_INCLUDE | awk -f scramShowUses.awk'
+#
+# This command should be issued from a directory where one and only package
+# would be built, i.e. a single package BuildFile is parsed by SCRAM.
+# Error messages are printed if no package would be built, or if scram 
+# would process many packages recursively ('About to process:'...).
+# The dependency analysis is based from a (almost) dry run of scram
+# in debug mode, letting scram parse BuildFiles recursively and feeding
+# the resulting output to AWK. Write access to the local release top is 
+# needed as 'scram b' will rebuild .mk file fragments in tmp.
+#
+#----------------------------------------------------------------------------
+BEGIN { 
+  status = 0;
+  # Local top level project and package
+  thisProjName = "";
+  thisLocalRTop = ""; 
+  thisReleaseTop = ""; 
+  thisPkg = ""; 
+  # External tools on which this package depends
+  nExtTools = 0;
+  delete extToolVersMap; #vers[name] for all selected tools (even not ref'ed)
+  delete extToolNameVec; #name[1..n]
+  extToolRef = "ext"     #my alternatives: 'ref' or 'ext' (keep 'use' for pkgs)
+  # External projects on which this package depends
+  nExtProjs = 0;
+  delete extProjPathVec; #path[1..n]
+  delete extProjNameMap; #name[path]
+  # External packages on which this package depends
+  nExtPkgs = 0;
+  delete extPkgNameVec;  #name[1..n]
+  delete extPkgProjMap;  #proj[name]
+  # Current nesting level of dependencies
+  currLevel = 0;
+  currPkg = "";
+  delete bfHashVec;  #hash[level]  
+  delete bfHashMap;  #level[hash]  
+  bfHashVec[0] = "";
+  ###print "BEGIN: LEVEL=" currLevel;
+}
+#----------------------------------------------------------------------------
+{
+  if ( $1 == "About" && $2 == "to" && $3 == "process" ) {
+    print $0;
+    print "****************************************************************";
+    print "* ERROR!                                                       *";
+    print "* 1. Do not feed 'scram -debug b' to this script:              *";
+    print "* feed the output of 'scram -debug b echo_INCLUDE' instead!    *";
+    print "* 2. You cannot process multiple packages using this script:   *";
+    print "* change directory so that 'scram b' sees a single BuildFile!  *";
+    print "****************************************************************";
+    status=1; exit status;
+  }
+}
+#----------------------------------------------------------------------------
+{
+  if ( $1 == "Parse" && $2 == "Error" ) {
+    print $0;
+    getline;
+    print $0;
+    status=1; exit status;
+  }
+}
+#----------------------------------------------------------------------------
+{
+  # Analysis of nesting level of dependencies proceeds via buildfile hash
+  # Initially I thought of parsing the BuildFiles but that is error prone!
+  if (index($1,">BuildSystem::BuildFile(BuildSystem::BuildFile=HASH(")==1) { 
+    if ( bfHashVec[currLevel] != $1 ) {
+      hash = $1;
+      # First time a hash value is found - level 0
+      if ( currLevel == 0 && bfHashVec[0] == "" ) {
+	bfHashVec[0] = hash;
+	bfHashMap[hash] = 0;
+      }
+      # Hash value of a previous build file - decrease level accordingly
+      else if ( hash in bfHashMap ) {
+        # Decrease until currLevel = bfHashMap[hash]
+	while ( currLevel != bfHashMap[hash] ) {
+	  delete bfHashMap[bfHashVec[currLevel]];
+	  delete bfHashVec[currLevel];
+	  currLevel--;
+	}
+      }
+      # Hash value of a new build file - increase level by 1
+      else {
+	currLevel++;
+	bfHashVec[currLevel] = hash;
+	bfHashMap[hash] = currLevel;
+	# Print the package names as dependencies for levels>=1
+	# Leave two extra spaces for all levels>1
+	space = "";
+	for ( i=1; i<currLevel; i++ ) { space = space ". "; }	
+	currProjName = extProjNameMap[extPkgProjMap[currPkg]];
+	print "# "space"use "currProjName"::"currPkg;
+	###print "# "space"use "currProjName"::"currPkg" (LEVEL="currLevel")";
+      }
+      ###print "LEVEL=" currLevel;
+    }  
+  }
+}
+#----------------------------------------------------------------------------
+{
+  # Local and global release top for the project of the top level package
+  if ( $1 == "->Found" && $2 == "top" ) {
+    if ( $3 == "" ) { print "ERROR! Null `top`!"; status=1; exit status; }
+    # Read the project name from its Environment
+    projEnv = $3 "/.SCRAM/Environment";
+    projName = "";
+    while ( projName == "" ) {
+      get = getline record < projEnv;
+      if ( get == -1 ) {
+	print "ERROR! Environment not found for project " $3
+	  status = 1; exit status;
+      }
+      else if ( get == 0 ) {
+	break; #EOF
+      }
+      key = "SCRAM_PROJECTNAME";
+      i = index( record, key );
+      if ( i != 0 ) { projName = substr( record, i+length(key) ); }
+      while( index(projName," ") == 1 || index(projName,"=") ) { 
+	projName = substr( projName, 2 ); 
+      }
+    }
+    # Is this the local or remote release top?
+    if ( thisLocalRTop == "" ) { 
+      thisLocalRTop = $3;
+      thisProjName = projName;
+      print "###############################################################";
+      print "# *** PROJECT_NAME:       " projName;
+      print "# *** PROJECT_RTOP_LOCAL: " thisLocalRTop;
+      extProjNameMap[thisLocalRTop] = thisProjName; 
+    } 
+    else if ( thisReleaseTop == "" ) { 
+      if ( projName != thisProjName ) {
+	print "ERROR! Project name mismatch!";
+	status = 1; exit status;
+      }
+      thisReleaseTop = $3; 
+      print "# *** PROJECT_RTOP:       " thisReleaseTop;
+      extProjNameMap[thisReleaseTop] = thisProjName; 
+    }
+    else { 
+      print "ERROR! Too many release tops!"; 
+      status = 1; exit status; 
+    }    
+  }
+}
+#----------------------------------------------------------------------------
+{
+  # Top level package
+  if ( $2 == "ParseBuildFile:" ) {
+    pkg = substr( $4, 1, index($4,"/BuildFile")-1 );
+    # Project and release area for this package 
+    if ( index(pkg,thisLocalRTop) == 1 ) { 
+      pkg = substr( pkg, length(thisLocalRTop)+1 ); 
+    }
+    else {
+      print "PANIC! ParseBuildFile invoked outside local release top? " $4; 
+      status = 1; exit status; 
+    }
+    # Package name
+    while ( index(pkg,"/") == 1 ) { pkg = substr( pkg, 2 ); }
+    while ( index(pkg,"./") == 1 ) { pkg = substr( pkg, 3 ); }
+    while ( index(pkg,"/") == 1 ) { pkg = substr( pkg, 2 ); }
+    while ( index(pkg,"./") == 1 ) { pkg = substr( pkg, 3 ); }
+    if ( index(pkg,"src/") == 1 ) { pkg = substr( pkg, 5 ); }
+    while ( index(pkg,"/") == 1 ) { pkg = substr( pkg, 2 ); }
+    if ( pkg == "" ) { 
+      print "ERROR! Null package! BuildFile: " $4; 
+      status = 1; exit status; 
+    }
+    # Two BuildFile's are expected here: from config and from the top level pkg
+    # (AV March 2007: $LOCALRT/config can now be in $LOCALRT/src/config/scram) 
+    # NB The same HASH value defines the environment for both BuildFile's
+    if ( thisPkg == "" ) {
+      if ( pkg != "config" && pkg != "config/scram" ) { 
+	print "PANIC! Unknown package (expecting config or config/scram): " $4;
+	status = 1; exit status; 
+      }
+      thisPkg = pkg; 
+      print "###############################################################";
+      print "# *** PROJECT_CONFIG:     " thisPkg;
+      #print "#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++";
+      currPkg = pkg;
+    } 
+    else if ( thisPkg == "config" ) {
+      thisPkg = pkg; 
+      print "###############################################################";
+      print "# *** PACKAGE_NAME:       " thisProjName"::"thisPkg;
+      #print "#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++";
+      currPkg = pkg;
+    }
+    else { 
+      ###print "PANIC! Unknown package (expecting external ref): " $4; 
+      ###print "PANIC! thisPkg = " thisPkg; 
+      ###status = 1; exit status; 
+      thisPkg = pkg; 
+      print "###############################################################";
+      print "# *** SUBPACKAGE_NAME:    " thisProjName"::"thisPkg;
+      #print "#++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++";
+      currPkg = pkg;
+    }
+  } 
+}
+#----------------------------------------------------------------------------
+{
+  # Dependency on an external tool (project-wide)
+  if ( $3 == "being" && $4 == "Initialised" ) {
+    toolName = substr($1,3);
+    toolVers = $2;
+    print "# select " toolName " " toolVers;
+    if ( ! ( toolName in extToolVersMap ) ) {
+      extToolVersMap[toolName] = toolVers;      
+    }
+    else {
+      if ( extToolVersMap[toolName] != toolVers ) {
+	print "ERROR! Tool " toolName " " \
+	  extToolVersMap[toolName] " already selected!";
+	status=1; exit status;
+      }      
+      print "WARNING! Tool " toolName " " toolVers " already selected!";
+    }    
+  }
+}
+#----------------------------------------------------------------------------
+{
+  # Dependency on an external tool (package-specific)
+  # !!! This requires a modified version of scram !!!
+  if ( $2 == "External_StartTag:" && $3 == "select" && $4 == "Tool" ) {
+    toolName = $5;
+    # Print the tool names as dependencies for levels>=1
+    # Leave two extra spaces for all levels>1
+    space = "";
+    for ( i=1; i<currLevel; i++ ) { space = space ". "; }	
+    # External tool is ALWAYS one level below the current BuildFile!
+    if ( currLevel>=1 ) space = space ". ";
+    print "# " space extToolRef " " toolName;
+    ###print "# " space extToolRef " " toolName " (LEVEL=" currLevel+1 ")";
+    # Update tool dependency vector
+    found = 0;
+    for ( i=1; i<=nExtTools; i++ ) {
+      if ( toolName == extToolNameVec[i] ) found = 1;      
+    }
+    if ( found == 0 ) {
+      nExtTools++;
+      extToolNameVec[nExtTools] = toolName;
+    }    
+  }
+}
+#----------------------------------------------------------------------------
+{
+  # Dependency on an external SCRAM project
+  if ( $2 == "_pushremoteproject:" ) {
+    # Handle verbose output from my enhanced test version of SCRAM 
+    # (where an external project can have both a localtop and a releasetop)
+    # Expect a colon-separated list of paths from _pushremoteproject: this is 
+    # 'backward'-compatible to SCRAM V0_20_0 as it can handle a single path too
+    npaths = split ( $4, paths, ":" );
+    delete projs;
+    proj = "";
+    projEnv = "";
+    for ( i=1; i<=npaths; i++ ) {
+      if ( paths[i] == "" ) {
+	projs[i] = "";
+      }
+      else {
+	aProj = paths[i];
+	while ( substr(aProj,length(aProj)) == "/" ) { 
+	  aProj = substr(aProj,1,length(aProj)-1);
+	}
+	if ( substr(aProj,length(aProj)-3) == "/src" ) { 
+	  aProj = substr(aProj,1,length(aProj)-4);
+	}
+	while ( substr(aProj,length(aProj)) == "/" ) { 
+	  aProj = substr(aProj,1,length(aProj)-1);
+	}
+	projs[i] = aProj;
+	aProjEnv = aProj "/.SCRAM/Environment";
+	if ( system("ls " aProjEnv " >& /dev/null") == 0 ) {
+	  ###print "FOUND " aProjEnv;
+	  if ( projEnv == "" ) {
+	    projEnv = aProjEnv;
+	    proj = aProj;
+	  }
+	} 
+	else {
+	  ###print "NOT FOUND " aProjEnv;
+	  if ( projEnv == "" ) {
+	    proj = aProj;
+	  }
+	};
+      }
+    }
+    # Read the project name from its Environment
+    projName = "";
+    while ( projName == "" ) {
+      if ( projEnv == "" ) {
+	print "ERROR! Environment not found for project " proj;
+	status = 1; exit status;
+      }
+      getStatus = getline record < projEnv;
+      if ( getStatus == -1 ) {
+	print "ERROR! Environment not found for project " proj;
+	status = 1; exit status;
+      }
+      else if ( getStatus == 0 ) {
+	break; #EOF
+      }
+      key = "SCRAM_PROJECTNAME";
+      i = index( record, key );
+      if ( i != 0 ) { projName = substr( record, i+length(key) ); }
+      while( index(projName," ") == 1 || index(projName,"=") ) { 
+	projName = substr( projName, 2 ); 
+      }
+    }
+    # Is this a new project?
+    for ( i=1; i<=npaths; i++ ) {
+      aProj = projs[i];
+      if ( aProj != "" && ( ! ( aProj in extProjNameMap ) ) ) { 
+	if ( aProj == thisLocalRTop ) {
+	  print "ERROR! Circular dependency on this project (localRT)?";
+	  status = 1; exit status;
+	}
+	if ( aProj == thisReleaseTop ) {
+	  print "ERROR! Circular dependency on this project (releaseTop)?";
+	  status = 1; exit status;
+	}    
+        # Add the project to the list
+	nExtProjs++;
+	extProjPathVec[nExtProjs] = aProj;
+	extProjNameMap[aProj] = projName; 
+	###print "# *** EXTERNAL_PROJECT("nExtProjs"): "projName" (" aProj ")";
+      }
+    }
+  }
+}
+#----------------------------------------------------------------------------
+{
+  # Dependency on an external SCRAM package
+  if ( $2 == "ParseBuildFile_Export:" ) {
+    pkg = substr( $4, 1, index($4,"/BuildFile")-1 );
+    # Project and release area for this package 
+    pkgProj = "";
+    if ( index(pkg,thisLocalRTop) == 1 ) { 
+      pkg = substr( pkg, length(thisLocalRTop)+1 ); 
+      pkgProj = thisLocalRTop;
+    }
+    else if ( thisReleaseTop != "" && index(pkg,thisReleaseTop) == 1 ) { 
+      pkg = substr( pkg, length(thisReleaseTop)+1 ); 
+      pkgProj = thisReleaseTop;
+    }
+    else {
+      for ( proj in extProjNameMap ) {
+	if ( index(pkg,proj) == 1 ) { 
+	  pkg = substr( pkg, length(proj)+1 ); 
+	  pkgProj = proj;
+	}
+      }
+    }
+    if ( pkgProj == "" ) { 
+      print "ERROR! No project associated to package: " $4; 
+      status = 1; exit status; 
+    }
+    # Package name
+    while ( index(pkg,"/") == 1 ) { pkg = substr( pkg, 2 ); }
+    if ( index(pkg,"src/") == 1 ) { pkg = substr( pkg, 5 ); }
+    while ( index(pkg,"/") == 1 ) { pkg = substr( pkg, 2 ); }
+    if ( pkg == "" ) { 
+      print "ERROR! Null package! BuildFile: " $4; 
+      status = 1; exit status; 
+    }
+    ####### Analyse the dependencies of this package
+    ######system( "cat " $4 "| grep -i use" ); print "";
+    # Add the package to the list if this is a new package
+    if ( ! ( pkg in extPkgProjMap ) ) {
+      nExtPkgs ++;
+      extPkgNameVec[nExtPkgs] = pkg;      
+      extPkgProjMap[pkg] = pkgProj;
+    }
+    # Pass the package name to be printed out with its level of nesting
+    currPkg = pkg;
+    ###print "# " pkg; #THIS LINE IS USEFUL FOR DEBUGGING      
+  } 
+}
+#----------------------------------------------------------------------------
+END {
+  if ( status == 0 ) {    
+    if ( thisPkg != "" && thisPkg != "config" ) {
+      #print "#";
+      print "###############################################################";
+      print "#";
+      print "#--------------------";
+      print "# TOOL DEPENDENCIES:";  
+      print "#--------------------";
+      if ( nExtTools > 0 ) {	
+	for ( i=1; i<=nExtTools; i++ ) {
+	  toolName = extToolNameVec[i];
+	  toolVers = extToolVersMap[toolName];
+	  print extToolRef " " toolName " " toolVers;
+	}  
+      }      
+      else {
+	print "*** NONE ***";
+      }      
+      print "#";
+      print "#-----------------------";
+      print "# PACKAGE DEPENDENCIES:";  
+      print "#-----------------------";
+      if ( nExtPkgs > 0 ) {	
+	for ( i=1; i<=nExtPkgs; i++ ) {
+	  pkg = extPkgNameVec[i];
+	  pkgProj = extPkgProjMap[pkg];
+	  pkgProjName = extProjNameMap[pkgProj];
+          ###print "use " pkgProjName "::" pkg " (" pkgProj ")"; #CMT-like
+	  print "use " pkgProjName "::" pkg;
+	  print "    (" pkgProj ")";
+	}  
+      }  
+      else {
+	print "*** NONE ***";
+      }      
+      ###print "END: LEVEL=" currLevel;
+    }
+    else {
+      print "****************************************************************";
+      print "* ERROR!                                                       *";
+      print "* 1. You cannot process multiple packages using this script:   *";
+      print "* change directory so that 'scram b' sees a single BuildFile!  *";
+      print "* 2. Or maybe, 'scram b' does not see ANY BuildFile from here? *";
+      print "****************************************************************";
+    }  
+  }  
+}
+#----------------------------------------------------------------------------
+{
+  # Print out debug messages from my modifcations to SCRAM
+  if ( $1 == "__scramShowUses" ) print $0;
+} 
+#----------------------------------------------------------------------------
+
diff --git a/RelationalCool/scripts/sql/oraclePurgeRecycleBin.sql b/RelationalCool/scripts/sql/oraclePurgeRecycleBin.sql
new file mode 100644
index 000000000..9bfa8c257
--- /dev/null
+++ b/RelationalCool/scripts/sql/oraclePurgeRecycleBin.sql
@@ -0,0 +1,2 @@
+purge recyclebin;
+exit;
diff --git a/RelationalCool/scripts/sql/oracleShowTables.sql b/RelationalCool/scripts/sql/oracleShowTables.sql
new file mode 100644
index 000000000..878608f79
--- /dev/null
+++ b/RelationalCool/scripts/sql/oracleShowTables.sql
@@ -0,0 +1,3 @@
+set pagesize 1000;
+select table_name from all_tables where owner='&1' and table_name like '&2%';
+exit;
diff --git a/RelationalCool/scripts/wineWrap.sh b/RelationalCool/scripts/wineWrap.sh
new file mode 100755
index 000000000..621b10ac9
--- /dev/null
+++ b/RelationalCool/scripts/wineWrap.sh
@@ -0,0 +1,123 @@
+#! /bin/bash
+
+# Check command line arguments
+if [ "$1" = "" ]; then
+    cmd=`basename $0`
+    echo "Usage: $cmd command [arguments]"
+    exit 1
+fi
+
+# Print out the environment?
+if [ "$WINE_WRAP_PRINTENV" != "on" ]; then
+    export WINE_WRAP_PRINTENV=off
+fi 
+
+# Check O/S
+if [ "$OS" = "Windows_NT" ]; then
+    if [ "${SCRAM_ARCH:0:5}" != "win32" ]; then
+        echo "ERROR! Invalid SCRAM_ARCH $SCRAM_ARCH on $OS for $0"
+        exit 1
+    fi
+    if [ "$WINE_WRAP_DEBUG" != "" ]; then
+        debug=1
+    else
+        debug=0
+    fi
+else
+    debug=0
+fi
+
+# Make sure LOCALRT is defined
+export LOCALRT=
+export PATH=/afs/cern.ch/sw/lcg/app/spi/scram:"${PATH}"
+eval `scram runtime -sh`
+if [ "$LOCALRT" = "" ] ; then
+    echo "ERROR! Cannot define LOCALRT - are you in a valid SCRAM directory?"
+    exit 1
+fi
+
+# Keep the current SEAL options file if already defined
+export SEAL_CONFIGURATION_FILE_OLD=${SEAL_CONFIGURATION_FILE}
+
+# Load common functions
+###echo "DEBUG: load common test functions..."
+if [ -r $LOCALRT/config/test_functions.sh ] ; then
+    . $LOCALRT/config/test_functions.sh
+elif [ -r $LOCALRT/src/config/scram/test_functions.sh ] ; then
+    . $LOCALRT/src/config/scram/test_functions.sh
+else
+    echo "ERROR! Cannot find common test functions"
+    exit 1
+fi
+###echo "DEBUG: load common test functions... DONE"
+
+## NB: Make sure $HOME/private/authentication.xml contains YOUR credentials!
+check_authfile
+set_preliminar_env
+
+## By default ORACLE_HOME is unset
+# keepORACLE_HOME=yes
+prepare_env
+
+# Fix the PATHs for specific systems (only if needed)
+fix_win_paths
+
+# Disable POOL trace files
+#unset POOL_ORA_SQL_TRACE_ON 
+#unset POOL_ORA_CERNTRACE_ON 
+
+# Keep the current SEAL options file if already defined
+if [ "$SEAL_CONFIGURATION_FILE_OLD" != "" ] ; then
+    export SEAL_CONFIGURATION_FILE=$SEAL_CONFIGURATION_FILE_OLD
+fi
+
+#----------------------------------------------------------------------------
+# Analyse SCRAM_ARCH and CMTCONFIG to determine if we should use WIN32
+#----------------------------------------------------------------------------
+echo "SCRAM_ARCH: $SCRAM_ARCH"
+echo "CMTCONFIG:  $CMTCONFIG"
+useWin32=0
+if [ "${SCRAM_ARCH:0:5}" = "win32" ]; then
+    useWin32=1
+elif [ "$SCRAM_ARCH" = "" ] && [ "${CMTCONFIG:0:5}" = "win32" ]; then
+    useWin32=1
+fi
+
+#----------------------------------------------------------------------------
+# Unix platform
+#----------------------------------------------------------------------------
+if [ "$useWin32" = "0" ]; then
+
+    ###echo "__UNIX Current environment variables: "; env
+    echo "__UNIX Execute command: " $@
+    $@
+    
+#----------------------------------------------------------------------------
+# Win32 platform
+#----------------------------------------------------------------------------
+else
+
+    # Debugging information
+    ###echo "__WINE Current environment variables: "; env
+    if [ "$OS" = "Windows_NT" ]; then
+        echo "__WINE.NT Execute command: " $@
+    else
+        echo "__WINE.WINE Execute command: " $@
+    fi
+
+    # Execute the command under Wine
+    if [ "$debug" = "0" ]; then
+        cmd_wrapper $@
+        status=${?}
+    else
+        debug $@
+        status=${?}
+    fi
+    ###echo status=$status
+    exit $status
+    
+#----------------------------------------------------------------------------
+# End check on platform
+#----------------------------------------------------------------------------
+fi
+
diff --git a/RelationalCool/src/AttributeTable.h b/RelationalCool/src/AttributeTable.h
new file mode 100644
index 000000000..c114f3b1f
--- /dev/null
+++ b/RelationalCool/src/AttributeTable.h
@@ -0,0 +1,94 @@
+// $Id: AttributeTable.h,v 1.6 2008-11-04 11:52:10 avalassi Exp $
+#ifndef RELATIONALCOOL_ATTRIBUTETABLE_H 
+#define RELATIONALCOOL_ATTRIBUTETABLE_H 1
+
+// Include files
+#include "AttributeList/AttributeList.h"
+#include "AttributeList/AttributeListSpecification.h"
+
+namespace cool {
+
+  /** @class AttributeTable AttributeTable.h
+   *  
+   *  Implementation of a vector of AttributeList's 
+   *  with a single AttributeListSpecification.
+   *
+   *  Each AttributeList is available to the user only as a reference.
+   *  The lifetime of the references coincides with that of the AttributeTable.
+   *
+   *  @author Andrea Valassi
+   *  @date   2005-02-01
+   */
+  
+  class AttributeTable {
+
+  public: 
+
+    /// Constructor from an AttributeListSpecification reference
+    AttributeTable( const coral::AttributeListSpecification& spec ) {
+      m_spec = new coral::AttributeListSpecification();
+      coral::AttributeListSpecification::const_iterator itSpec;
+      for ( itSpec = spec.begin(); itSpec != spec.end(); ++itSpec ) {
+        m_spec->push_back( itSpec->name(), itSpec->type_name() );
+      }
+    }
+    
+    /// Destructor
+    virtual ~AttributeTable() {
+      std::vector< coral::AttributeList* >::const_iterator itList;
+      for ( itList = m_lists.begin();
+            itList != m_lists.end();
+            itList++ ) {
+        delete (*itList);
+      }
+      delete m_spec;
+    }
+
+    /// Insert a new row from an AttributeList reference
+    /// Throws a RelationalException if a specification is invalid.
+    void push_back( const coral::AttributeList& list ) {      
+      if ( list.attributeListSpecification() != *m_spec )
+        throw RelationalException 
+          ( "Invalid specification", "AttributeTable" );    
+      coral::AttributeList* newList( new coral::AttributeList( *m_spec ) );
+      coral::AttributeList::const_iterator itList;
+      for ( itList=list.begin(); itList!=list.end(); ++itList ) {
+        (*newList)[ itList->spec().name() ].shareData( *itList );
+      }
+      return m_lists.size();
+    }
+
+    /// Retrieve a row as an AttributeList reference
+    coral::AttributeList& operator[] ( unsigned int iRow ) {      
+      return *(m_lists[iRow]);
+    }
+
+    /// Number of rows in the table (number of AttributeList's)
+    unsigned int size() const {
+      return m_lists.size();
+    }
+
+  private:
+
+    /// Standard constructor is private
+    AttributeTable();
+
+    /// Copy constructor is private
+    AttributeTable( const AttributeTable& rhs );
+
+    /// Assignment operator is private
+    AttributeTable& operator=( const AttributeTable& rhs );
+
+  private:
+
+    /// The attributeListSpecification for the AttributeTable
+    const coral::AttributeListSpecification* m_spec;
+
+    /// The vector of AttributeList's
+    std::vector< coral::AttributeList* > m_lists;
+
+  };
+
+}
+
+#endif // RELATIONALCOOL_ATTRIBUTETABLE_H
diff --git a/RelationalCool/src/ConstRelationalObjectAdapter.cpp b/RelationalCool/src/ConstRelationalObjectAdapter.cpp
new file mode 100644
index 000000000..8ef479a46
--- /dev/null
+++ b/RelationalCool/src/ConstRelationalObjectAdapter.cpp
@@ -0,0 +1,223 @@
+// $Id: ConstRelationalObjectAdapter.cpp,v 1.11 2009-02-09 17:53:28 avalassi Exp $
+
+// Local include files
+//#include "attributeListToString.h"
+#include "ConstRelationalObjectAdapter.h"
+#include "RelationalException.h"
+#include "RelationalObject.h"
+#include "RelationalObjectTable.h"
+#include "RelationalObjectTableRow.h"
+#include "TimingReportMgr.h"
+#include "timeToString.h"
+
+// Namespace
+using namespace cool;
+
+//-----------------------------------------------------------------------------
+
+ConstRelationalObjectAdapter::ConstRelationalObjectAdapter
+( const coral::AttributeList& aList,
+  const IRecordSpecification& payloadSpec )
+  : m_isTimingActive( isTimingActive() )
+  , m_aList( aList )
+  , m_payloadSpec( payloadSpec )
+  , m_since( aList[RelationalObjectTable::columnNames::iovSince()]
+             .data<ValidityKey>() )
+  , m_until( aList[RelationalObjectTable::columnNames::iovUntil()]
+             .data<ValidityKey>() )
+  , m_payload( payloadSpec, aList )
+  , m_channelId( aList[RelationalObjectTable::columnNames::channelId()]
+                 .data<ChannelId>() )
+  , m_insertionTime( aList[RelationalObjectTable::columnNames::sysInsTime()]
+                     .data<std::string>() )
+  , m_objectId( aList[RelationalObjectTable::columnNames::objectId()]
+                .data<unsigned int>() )
+{
+
+  // This is used for READING back data __WITHOUT ANY DEEP COPY__!
+
+  // Assuming that the RelationalObjectTableRow is a wrapper around
+  // a reference to a temporary CORAL buffer, this instance can only be
+  // used as long as the temporary CORAL buffer contains the right data!
+
+  if ( m_isTimingActive )
+    TimingReportMgr::stopTimer
+      ( "cool::ConstRelationalObjectAdapter::ctor" );
+
+}
+
+//-----------------------------------------------------------------------------
+
+ConstRelationalObjectAdapter::~ConstRelationalObjectAdapter()
+{
+  //if ( m_isTimingActive ) 
+  //  TimingReportMgr::stopTimer
+  //    ( "cool::ConstRelationalObjectAdapter [LIFETIME]" );
+}
+
+//-----------------------------------------------------------------------------
+
+bool ConstRelationalObjectAdapter::isTimingActive() const 
+{
+  if ( TimingReportMgr::isActive() ) 
+  {
+    TimingReportMgr::startTimer
+      ( "cool::ConstRelationalObjectAdapter::ctor" );
+    //TimingReportMgr::startTimer
+    //  ( "cool::ConstRelationalObjectAdapter [LIFETIME]" );
+    return true;
+  }
+  else return false;
+}
+
+//-----------------------------------------------------------------------------
+
+IObject* ConstRelationalObjectAdapter::clone() const 
+{
+  //std::cout << "ConstRelationalObjectAdapter::clone" << std::endl;
+  //std::cout << "DATA: " << attributeListToString(m_aList) << std::endl;  
+  //std::cout << "SPEC: " << Record(m_payloadSpec) << std::endl;
+  return new RelationalObject( m_aList, m_payloadSpec );
+}
+
+//-----------------------------------------------------------------------------
+
+const ValidityKey& ConstRelationalObjectAdapter::since() const 
+{
+  return m_since;
+}
+
+//-----------------------------------------------------------------------------
+
+const ValidityKey& ConstRelationalObjectAdapter::until() const 
+{
+  return m_until;
+}
+
+//-----------------------------------------------------------------------------
+
+const IRecord& ConstRelationalObjectAdapter::payload() const 
+{
+  return m_payload;
+}
+
+//-----------------------------------------------------------------------------
+
+const ChannelId& ConstRelationalObjectAdapter::channelId() const 
+{
+  return m_channelId;
+}
+
+//-----------------------------------------------------------------------------
+
+/*
+const std::string& ConstRelationalObjectAdapter::channelName() const 
+{
+  throw RelationalException
+    ( "ConstRelationalObjectAdapter::channelName is not implemented yet" );
+}
+*/
+
+//-----------------------------------------------------------------------------
+
+bool ConstRelationalObjectAdapter::isStored() const 
+{
+  return true;
+}
+
+//-----------------------------------------------------------------------------
+
+unsigned int ConstRelationalObjectAdapter::objectId() const 
+{
+  return m_objectId;
+}
+
+//-----------------------------------------------------------------------------
+
+const ITime& ConstRelationalObjectAdapter::insertionTime() const 
+{
+  return m_insertionTime;
+}
+
+//-----------------------------------------------------------------------------
+/*
+const ValidityKey& ConstRelationalObjectAdapter::sinceOriginal() const 
+{
+  return m_sinceOriginal;
+}
+
+//-----------------------------------------------------------------------------
+
+const ValidityKey& ConstRelationalObjectAdapter::untilOriginal() const 
+{
+  return m_untilOriginal;
+}
+
+//-----------------------------------------------------------------------------
+
+const ITime& ConstRelationalObjectAdapter::insertionTimeOriginal() const 
+{
+  return m_insertionTimeOriginal;
+}
+*/
+//-----------------------------------------------------------------------------
+
+std::ostream& ConstRelationalObjectAdapter::print( std::ostream& s ) const 
+{  
+  s << "Object: ";
+  { 
+    unsigned int maxSize = 3;
+    s << std::setw(maxSize) << objectId();
+  }
+  
+  s << " ";
+  
+  { 
+    unsigned int maxSize = 2;
+    s << "(" << std::setw(maxSize) << channelId() << ")";
+  }
+  
+  { // assemble IOV
+    std::stringstream iov;
+    iov << " [" << since() << "," ;
+    if ( until() == ValidityKeyMax ) {
+      iov << "+inf";
+    } else {
+      iov << until();
+    }
+    iov << "[";
+    unsigned int maxSize = 10;
+    s << std::setiosflags(std::ios::left) << std::setw(maxSize);
+    s << iov.str();
+    s << std::resetiosflags(std::ios::left);
+  }
+  
+  s << " ";
+  
+  { // assemble payload
+    std::stringstream p;
+    p << "[";
+    bool first = true;
+    const IRecordSpecification& spec = payload().specification();
+    for ( unsigned int i = 0; i < spec.size(); i++ ) {
+      if ( first ) {
+        first = false;
+        p << payload()[i];
+      } else {
+        p << "|" << payload()[i];
+      }
+    }
+    p << "] ";
+
+    unsigned int maxSize = 20;
+    s << std::setiosflags(std::ios::left) << std::setw(maxSize);
+    s << p.str();
+    s << std::resetiosflags(std::ios::left);
+  }
+  
+  s << timeToString( insertionTime() );
+  return s;
+}
+
+//-----------------------------------------------------------------------------
+
diff --git a/RelationalCool/src/ConstRelationalObjectAdapter.h b/RelationalCool/src/ConstRelationalObjectAdapter.h
new file mode 100644
index 000000000..10afea8af
--- /dev/null
+++ b/RelationalCool/src/ConstRelationalObjectAdapter.h
@@ -0,0 +1,142 @@
+// $Id: ConstRelationalObjectAdapter.h,v 1.11 2008-11-04 10:56:38 avalassi Exp $
+#ifndef RELATIONALCOOL_CONSTRELATIONALOBJECTADAPTER_H
+#define RELATIONALCOOL_CONSTRELATIONALOBJECTADAPTER_H
+
+// Include files
+#include "CoolKernel/ConstRecordAdapter.h"
+#include "CoolKernel/IObject.h"
+#include "CoolKernel/IRecordSpecification.h"
+#include "CoolKernel/Record.h"
+#include "CoolKernel/Time.h"
+
+// Local include files
+#include "ConstTimeAdapter.h"
+
+namespace cool {
+  
+  // Forward declarations
+  class RelationalObjectTableRow;
+
+  /** @class ConstRelationalObjectAdapter ConstRelationalObjectAdapter.h
+   *  
+   *  Read-only wrapper of a constant coral::AttributeList reference,
+   *  implementing the cool::IObject interface. The adapter can only be
+   *  used as long as the AttributeList is alive. The adapter creates
+   *  its own RecordSpecification from one specified at construction time.
+   *
+   *  @author Andrea Valassi
+   *  @date   2007-03-09
+   */
+  
+  class ConstRelationalObjectAdapter : public IObject {
+
+  public:
+    
+    /// Constructor from a record spec and a _const_ AttributeList reference.
+    ConstRelationalObjectAdapter( const coral::AttributeList& aList,
+                                  const IRecordSpecification& payloadSpec );
+    
+    /// Destructor
+    virtual ~ConstRelationalObjectAdapter();
+
+    /// Clone this IObject by performing a deep copy
+    virtual IObject* clone() const;
+    
+    /// Channel identifier
+    const ChannelId& channelId() const;
+    
+    /// Channel name
+    //const std::string& channelName() const;
+    
+    /// Start of validity interval
+    /// For stored objects this refers to the visible validity interval
+    const ValidityKey& since() const;
+    
+    /// End of validity interval
+    /// For stored objects this refers to the visible validity interval
+    const ValidityKey& until() const;
+    
+    /// Data payload
+    const IRecord& payload() const;
+
+    /// Has the object been stored into the database?
+    bool isStored() const;
+    
+    /// System-assigned object ID
+    /// Throws an exception if the object has not been stored yet
+    unsigned int objectId() const;
+    
+    /// Insertion time into the database
+    /// Throws an exception if the object has not been stored yet
+    const ITime& insertionTime() const;
+    
+    /// Start of original validity interval
+    /// Throws an exception if the object has not been stored yet
+    //const ValidityKey& sinceOriginal() const;
+    
+    /// End of original validity interval
+    /// Throws an exception if the object has not been stored yet
+    //const ValidityKey& untilOriginal() const;
+    
+    /// Insertion time of the original object into the database
+    /// Throws an exception if the object has not been stored yet
+    //const ITime& insertionTimeOriginal() const;
+    
+    /// Pretty print to an output stream
+    std::ostream& print( std::ostream& s ) const;
+    
+  private:
+    
+    ConstRelationalObjectAdapter();
+
+    ConstRelationalObjectAdapter( const ConstRelationalObjectAdapter& rhs );
+
+    ConstRelationalObjectAdapter& 
+    operator=( const ConstRelationalObjectAdapter& rhs );
+    
+    /// Is timing active? (hack to activate it at the beginning of the ctor)
+    bool isTimingActive() const;
+
+  private:
+
+    /// Is timing active? (hack to activate it at the beginning of the ctor)
+    bool m_isTimingActive;
+
+    /// The input coral::AttributeList const reference
+    const coral::AttributeList& m_aList;
+    
+    /// The input record specification const reference
+    const IRecordSpecification& m_payloadSpec;
+    
+    /// Beginning of the interval of validity
+    const ValidityKey& m_since;
+    
+    /// End of the interval of validity
+    const ValidityKey& m_until;
+    
+    /// Object payload
+    const ConstRecordAdapter m_payload;
+
+    /// Channel id
+    const ChannelId& m_channelId;
+    
+    /// Insertion time
+    const ConstTimeAdapter m_insertionTime;
+
+    /// Object id
+    const unsigned int& m_objectId;
+    
+    /// Beginning of the original interval of validity
+    //const ValidityKey& m_sinceOriginal;
+    
+    /// End of the original interval of validity
+    //const ValidityKey& m_untilOriginal;
+    
+    /// Original insertion time
+    //const Time& m_insertionTimeOriginal;
+
+  };  
+
+}
+
+#endif
diff --git a/RelationalCool/src/ConstTimeAdapter.cpp b/RelationalCool/src/ConstTimeAdapter.cpp
new file mode 100644
index 000000000..42d7ac841
--- /dev/null
+++ b/RelationalCool/src/ConstTimeAdapter.cpp
@@ -0,0 +1,94 @@
+// $Id: ConstTimeAdapter.cpp,v 1.2 2008-11-04 10:56:38 avalassi Exp $
+
+// Local include files
+#include "ConstTimeAdapter.h"
+#include "timeToString.h"
+
+// Namespace
+using namespace cool;
+
+//-----------------------------------------------------------------------------
+
+ConstTimeAdapter::~ConstTimeAdapter()
+{
+}
+
+//-----------------------------------------------------------------------------
+
+ConstTimeAdapter::ConstTimeAdapter( const std::string& time )
+  : m_time( time ) 
+{
+}
+
+//-----------------------------------------------------------------------------
+
+int ConstTimeAdapter::year() const
+{
+  return stringToTime( m_time ).year();
+}
+
+//-----------------------------------------------------------------------------
+
+int ConstTimeAdapter::month() const
+{
+  return stringToTime( m_time ).month();
+}
+
+//-----------------------------------------------------------------------------
+
+int ConstTimeAdapter::day() const
+{
+  return stringToTime( m_time ).day();
+}
+
+//-----------------------------------------------------------------------------
+
+int ConstTimeAdapter::hour() const
+{
+  return stringToTime( m_time ).hour();
+}
+
+//-----------------------------------------------------------------------------
+
+int ConstTimeAdapter::minute() const
+{
+  return stringToTime( m_time ).minute();
+}
+
+//-----------------------------------------------------------------------------
+
+int ConstTimeAdapter::second() const
+{
+  return stringToTime( m_time ).second();
+}
+
+//-----------------------------------------------------------------------------
+
+long ConstTimeAdapter::nanosecond() const
+{
+  return stringToTime( m_time ).nanosecond();
+}
+
+//-----------------------------------------------------------------------------
+
+std::ostream& ConstTimeAdapter::print( std::ostream& os ) const
+{
+  return stringToTime( m_time ).print( os );
+}
+
+//-----------------------------------------------------------------------------
+
+bool ConstTimeAdapter::operator==( const ITime& rhs ) const
+{
+  return stringToTime( m_time ) == rhs;
+}
+
+//-----------------------------------------------------------------------------
+
+bool ConstTimeAdapter::operator>( const ITime& rhs ) const
+{
+  return stringToTime( m_time ) > rhs;
+}    
+
+//-----------------------------------------------------------------------------
+
diff --git a/RelationalCool/src/ConstTimeAdapter.h b/RelationalCool/src/ConstTimeAdapter.h
new file mode 100644
index 000000000..9daa31757
--- /dev/null
+++ b/RelationalCool/src/ConstTimeAdapter.h
@@ -0,0 +1,82 @@
+#ifndef RELATIONALCOOL_CONSTTIMEADAPTER_H
+#define RELATIONALCOOL_CONSTTIMEADAPTER_H
+
+// Include files
+#include "CoolKernel/ITime.h"
+
+namespace cool
+{
+
+  /** @class ConstTimeAdapter ConstTimeAdapter.h
+   *
+   *  Wrapper of a std::string to the cool::ITime interface.
+   *
+   *  NB Every method call triggers a string-to-time conversion:
+   *  this is because it is assumed that the string may change
+   *  during the lifetime of the adapter, hence nothing is cached!
+   *
+   *  @author Andrea Valassi
+   *  @date   2007-03-29
+   */ 
+
+  class ConstTimeAdapter : public ITime
+  {
+
+  public:
+
+    /// Destructor.
+    virtual ~ConstTimeAdapter();
+    
+    /// Constructor from a const std::string reference.
+    ConstTimeAdapter( const std::string& time );
+
+    /// Returns the year.
+    int year() const;
+
+    /// Returns the month [1-12].
+    int month() const;
+
+    /// Returns the day [1-31].
+    int day() const;
+
+    /// Returns the hour [0-23].
+    int hour() const;
+
+    /// Returns the minute [0-59].
+    int minute() const;
+
+    /// Returns the second [0-59].
+    int second() const;
+
+    /// Returns the nanosecond [0-999999999].
+    long nanosecond() const;
+
+    /// Print to an output stream.
+    std::ostream& print( std::ostream& os ) const;
+
+    /// Comparison operator.
+    bool operator==( const ITime& rhs ) const;
+
+    /// Comparison operator.
+    bool operator>( const ITime& rhs ) const;
+
+  private:
+
+    /// Standard constructor
+    ConstTimeAdapter();
+
+    /// Copy constructor from another ConstTimeAdapter.
+    ConstTimeAdapter( const ConstTimeAdapter& rhs );
+
+    /// Assignment operator from another ConstTimeAdapter.
+    ConstTimeAdapter& operator=( const ConstTimeAdapter& rhs );
+
+  private:
+
+    const std::string& m_time;
+    
+  };
+
+}
+
+#endif // COOLKERNEL_TIME_H
diff --git a/RelationalCool/src/CoolChrono.cpp b/RelationalCool/src/CoolChrono.cpp
new file mode 100644
index 000000000..e03b06e16
--- /dev/null
+++ b/RelationalCool/src/CoolChrono.cpp
@@ -0,0 +1,64 @@
+// Include files
+#include <cstdlib> // for getenv
+
+// Local include files
+#include "CoolChrono.h"
+#include "ProcMemory.h"
+#include "SealBase_TimeInfo.h"
+
+// Namespace
+using namespace cool;
+
+CoolChrono::CoolChrono() :
+  m_names(n), 
+  m_values(n),
+  m_started(false)
+{
+  
+  // construct vector of names 
+  m_names[realTime] = "Real Time"; 
+  m_names[userTime] = "User Time"; 
+  m_names[systemTime] = "System Time"; 
+  m_names[cpuTime] = "Cpu Time"; 
+  m_names[idleTime] = "Idle Time"; 
+  m_names[vmSize] = "VmSize incr"; 
+  m_names[vmRss] = "VmRSS incr"; 
+}
+
+void CoolChrono::start() 
+{ 						    
+  // reset vector 
+  m_values.assign(nTypes(),0);
+  m_started=true; 
+  // get initial values 
+  seal::TimeInfo::init(); 
+  seal::TimeInfo::processTimes(m_userTime, m_sysTime, m_realTime); 
+  m_cpuTime = seal::TimeInfo::processCpuTime (); 
+  m_idleTime = seal::TimeInfo::processIdleTime (); 
+  // WARNING! Memory monitoring slows down time performance by factors!
+  if ( getenv ( "COOL_COOLCHRONO_PROCMEMORY" ) ) {
+    ProcMemory mem;
+    m_vmSize = mem.getVsz();
+    m_vmRss = mem.getRss();  
+  }
+}
+
+void  CoolChrono::stop() 
+{ 
+  if (!m_started) return;   // need to start first 
+  // calculate time differences
+  m_values[realTime]   = seal::TimeInfo::processRealTime() - m_realTime; 
+  m_values[userTime]   = seal::TimeInfo::processUserTime() - m_userTime; 
+  m_values[systemTime] = seal::TimeInfo::processSystemTime() - m_sysTime; 
+  m_values[cpuTime]    = seal::TimeInfo::processCpuTime() - m_cpuTime; 
+  m_values[idleTime]   = seal::TimeInfo::processIdleTime() - m_idleTime;  
+  // WARNING! Memory monitoring slows down time performance by factors!
+  if ( getenv ( "COOL_COOLCHRONO_PROCMEMORY" ) ) {
+    // Multiply by 1E9 (no need to go from seconds to nanoseconds! back to kB)
+    // Divide by 1E3 (from kB to MB)
+    ProcMemory mem;
+    m_values[vmSize]     = (mem.getVsz() - m_vmSize) * 1000000.; // MB
+    m_values[vmRss]      = (mem.getRss() - m_vmRss) * 1000000.; // MB
+  }
+}
+
diff --git a/RelationalCool/src/CoolChrono.h b/RelationalCool/src/CoolChrono.h
new file mode 100644
index 000000000..5a82e130c
--- /dev/null
+++ b/RelationalCool/src/CoolChrono.h
@@ -0,0 +1,57 @@
+#ifndef RELATIONALCOOL_COOLCHRONO_H
+#define RELATIONALCOOL_COOLCHRONO_H 1
+
+// Include files
+#include <string>
+#include <vector>
+#include "SealUtil_BaseSealChrono.h"
+
+namespace cool
+{ 
+
+  /**
+   * Time measurement performed using TimeInfo: 
+   *   measured Real, CPU (separated by User and System) and idle time 
+   */
+  class CoolChrono : public seal::BaseSealChrono
+  {
+    
+  public: 
+    
+    CoolChrono(); 
+    virtual ~CoolChrono() { /* no op */ } 
+    
+    typedef double TimeUnit; 
+    
+    enum  { realTime, userTime, systemTime, cpuTime, idleTime, 
+            vmSize, vmRss, n };
+    
+    std::vector<std::string> names() const { return m_names; } 
+    
+    // return measured value 
+    std::vector<double> values() const { return m_values; } 
+    
+    unsigned int nTypes() const { return n; }
+    
+    void start(); 
+    void stop(); 
+    
+  private:
+    
+    std::vector<std::string> m_names; 
+    std::vector<double> m_values; 
+    bool m_started;    
+    
+    // initial values 
+    TimeUnit m_realTime; 
+    TimeUnit m_userTime; 
+    TimeUnit m_sysTime;
+    TimeUnit m_cpuTime; 
+    TimeUnit m_idleTime;
+    long m_vmSize;
+    long m_vmRss;
+    
+  }; 
+
+} 
+#endif 
diff --git a/RelationalCool/src/CoralApplication.cpp b/RelationalCool/src/CoralApplication.cpp
new file mode 100644
index 000000000..e1d9c25ad
--- /dev/null
+++ b/RelationalCool/src/CoralApplication.cpp
@@ -0,0 +1,401 @@
+// $Id: CoralApplication.cpp,v 1.25 2009-01-06 11:52:12 avalassi Exp $
+
+// Include files
+#include <iostream>
+#include "CoolKernel/Exception.h"
+#include "CoolKernel/IDatabaseSvc.h"
+//#include "SealBase/Signal.h"
+//#include "SealBase/ProcessInfo.h"
+#include "RelationalAccess/ConnectionService.h"
+
+// Local include files
+#include "CoralApplication.h"
+#include "RalDatabaseSvc.h"
+#ifndef __APPLE__
+#ifndef WIN32
+#include "sigsegv.h"
+#endif
+#endif
+
+// Message output
+#define COUT std::cout << "__cool::CoralApplication "
+#define ENDL std::endl
+
+// Workaround for Windows (win32_vc9_dbg)
+// ERROR seems to be defined in a Windows VC9 header
+// See also CoolKernel/CoolKernel/MessageLevels.h
+// See also RelationalCool/utilities/coolPrivileges/RalPrivilegeManager.cpp
+#ifdef WIN32
+#ifdef ERROR
+#undef ERROR
+#pragma message ("WARN!NG: in RelationalCool/src/CoralApplication.cpp")
+#pragma message ("WARN!NG: 'ERROR' was defined and has been undefined")
+#endif
+#endif
+
+//-----------------------------------------------------------------------------
+
+namespace cool 
+{
+  class MessageReporter: virtual public coral::IMsgReporter 
+  {
+
+  public:
+
+    /// Default constructor
+    MessageReporter( coral::MsgLevel dummyLvl = coral::Info ):
+      m_level( dummyLvl ) {} // dummy as it will be changed by setMsgVerbosity
+
+    /// Destructor (called only by sub-classes)
+    virtual ~MessageReporter() {}
+
+    /// Release reference to reporter
+    void release() 
+    {
+      delete this; // only one instance...
+    } 
+
+    /// Access output level
+    coral::MsgLevel outputLevel() const { return m_level; }
+
+    /// Modify output level
+    void setOutputLevel( coral::MsgLevel lvl ) { m_level = lvl; }
+
+    /// Report a message
+    void report( int level, const std::string& src, const std::string& msg ) 
+    {
+      if ( level >= m_level ) 
+      {
+        std::ostream& out = std::cout;
+        const std::string::size_type src_name_maxsize = 36;
+        if ( src.size() <= src_name_maxsize )
+        {
+          out << src << std::string( src_name_maxsize-src.size(), ' ' );
+        } 
+        else 
+        {
+          out << src.substr( 0, src_name_maxsize-3 ) << "...";
+        }
+        switch ( level ) 
+        {
+        case 0:  out << " Nil      "; break;
+        case 1:  out << " Verbose  "; break;
+        case 2:  out << " Debug    "; break;
+        case 3:  out << " Info     "; break;
+        case 4:  out << " Warning  "; break;
+        case 5:  out << " Error    "; break;
+        case 6:  out << " Fatal    "; break;
+        case 7:  out << " Always   "; break;
+        default: out << " Unknown  "; break;
+        }
+        out << msg << std::endl;
+      }
+    }
+    
+  private:
+
+    coral::MsgLevel m_level; //< threshold for the messages
+
+  };
+}
+
+//-----------------------------------------------------------------------------
+
+// Namespace
+using namespace cool;
+
+//-----------------------------------------------------------------------------
+
+CoralApplication::CoralApplication( coral::IConnectionService* connSvc )
+{
+  
+  //COUT << "CoralApplication(): ** START **" << ENDL;  
+
+  try 
+  {
+    
+    //--------------------------------------------
+    // 1. Create a message stream
+    //--------------------------------------------
+    
+    // Install the COOL implementation of the message reporter
+    if ( getenv( "COOL_ENABLE_COOLMSGREPORTER" ) ) 
+    {
+      coral::MessageStream::installMsgReporter( new cool::MessageReporter() );
+    }
+
+    // Set the verbosity for COOL and CORAL if COOL_MSGLEVEL is set
+    if ( getenv( "COOL_MSGLEVEL" ) ) 
+    {
+      // Use MSG::ERROR if COOL_MSGLEVEL is set to an invalid value
+      cool::MSG::Level level = cool::MSG::ERROR;
+
+      // Check only the first char of the environment variable
+      switch ( *getenv( "COOL_MSGLEVEL" ) ) 
+      {
+      case '0':
+      case 'n':
+      case 'N': level = cool::MSG::NIL; break;
+        
+      case '1':
+      case 'v':
+      case 'V': level = cool::MSG::VERBOSE; break;
+        
+      case '2':
+      case 'd':
+      case 'D': level = cool::MSG::DEBUG; break;
+        
+      case '3':
+      case 'i':
+      case 'I': level = cool::MSG::INFO; break;
+        
+      case '4':
+      case 'w':
+      case 'W': level = cool::MSG::WARNING; break;
+        
+      case '5':
+      case 'e':
+      case 'E': level = cool::MSG::ERROR; break;
+        
+      case '6':
+      case 'f':
+      case 'F': level = cool::MSG::FATAL; break;
+        
+      case '7':
+      case 'a':
+      case 'A': level = cool::MSG::ALWAYS; break;
+        
+      default : break; // keep cool::MSG::ERROR by default
+      }
+
+      setOutputLevel( level );
+    }
+    else
+    {
+      // Do not modify the verbosity if COOL_MSGLEVEL is not set (bug #40353)
+    }
+
+    // Create a message stream
+    m_log.reset( new coral::MessageStream( "CoralApplication" ) );
+    log() << coral::Info << "Create a cool::CoralApplication..."
+          << coral::MessageStream::endmsg;  
+
+    //--------------------------------------------
+    // 2. Install the COOL signal handler
+    //--------------------------------------------
+
+#ifndef WIN32
+    // Install the COOL signal handler 
+    if ( getenv( "COOL_ENABLE_COOLSIGNALHANDLER" ) )
+    {
+      log() << coral::Info << "Enable the COOL signal handler"
+            << coral::MessageStream::endmsg;  
+#ifndef __APPLE__
+      setup_sigsegv();      
+#endif
+      //seal::Signal::handleFatal ( seal::ProcessInfo::argv()[0] );
+      //COUT << "CoralApplication(): SignalHandler ok" << ENDL;
+    }
+#endif
+    
+    //--------------------------------------------
+    // 3. Create the CORAL connection service
+    //--------------------------------------------
+  
+    if ( connSvc )
+    {
+      log() << coral::Info << "Use the user-provided CORAL connection service" 
+            << coral::MessageStream::endmsg;  
+      m_connSvc = connSvc;
+      m_ownConnSvc = false;
+    }
+    else 
+    {
+      log() << coral::Info << "Create a new own CORAL connection service" 
+            << coral::MessageStream::endmsg;  
+      m_connSvc = new coral::ConnectionService();
+      m_ownConnSvc = true;
+    }
+    
+    //--------------------------------------------
+    // 4. Create the COOL database service
+    //--------------------------------------------
+
+    log() << coral::Info << "Create the COOL database service" 
+          << coral::MessageStream::endmsg;  
+    m_dbSvc = new RalDatabaseSvc( *m_connSvc );
+
+    //--------------------------------------------
+
+    log() << coral::Info << "Create a cool::CoralApplication... DONE"
+          << coral::MessageStream::endmsg;  
+
+  }
+  
+  catch( std::exception& e ) 
+  {
+    COUT << "ERROR! Standard exception: '" << e.what() << "'" << ENDL;
+    throw e;
+  }
+  
+  catch( ... ) 
+  {
+    COUT << "ERROR! Unknown exception caught" << ENDL;
+    throw;
+  }
+
+  //COUT << "CoralApplication(): *** END ***" << ENDL;
+    
+}
+
+//-----------------------------------------------------------------------------
+
+CoralApplication::~CoralApplication() 
+{
+  log() << coral::Info << "Delete the COOL CoralApplication..." 
+        << coral::MessageStream::endmsg;  
+  log() << coral::Info << "Delete the COOL database service" 
+        << coral::MessageStream::endmsg;  
+  delete m_dbSvc;
+  m_dbSvc = 0;
+  //log() << coral::Info << "Purge the CORAL connection pool" 
+  //      << coral::MessageStream::endmsg;  
+  //m_connSvc->purgeConnectionPool();
+  if ( m_ownConnSvc )
+  {
+    log() << coral::Info << "Delete the CORAL connection service" 
+          << coral::MessageStream::endmsg;  
+    coral::ConnectionService* connSvc = 
+      dynamic_cast< coral::ConnectionService* >( m_connSvc );
+    if ( connSvc ) 
+    {
+      // Hack: ~IConnectionService is protected
+      delete connSvc;
+    }
+    else 
+    {
+      // This can never happen! We know the type of the own m_connSvc!
+      std::string msg = "PANIC! m_connSvc is not a coral::ConnectionService!";
+      log() << coral::Fatal << msg << coral::MessageStream::endmsg;  
+      throw Exception( msg, "CoralApplication::~CoralApplication" );
+    }
+  }  
+  m_connSvc = 0;
+  log() << coral::Info << "Delete the COOL CoralApplication... DONE" 
+        << coral::MessageStream::endmsg;  
+}
+
+//-----------------------------------------------------------------------------
+
+IDatabaseSvc& CoralApplication::databaseService() 
+{
+  return *m_dbSvc;
+}
+
+//-----------------------------------------------------------------------------
+
+cool::MSG::Level CoralApplication::outputLevel()
+{
+  coral::MsgLevel coralLevel = coral::MessageStream::msgVerbosity();
+  switch ( coralLevel ) {
+  case coral::Nil:       return cool::MSG::NIL;        break;
+  case coral::Fatal:     return cool::MSG::FATAL;      break;
+  case coral::Error:     return cool::MSG::ERROR;      break;
+  case coral::Warning:   return cool::MSG::WARNING;    break;
+  case coral::Info:      return cool::MSG::INFO;       break;
+  case coral::Debug:     return cool::MSG::DEBUG;      break;
+  case coral::Verbose:   return cool::MSG::VERBOSE;    break;
+  case coral::Always:    return cool::MSG::ALWAYS;     break;
+  case coral::NumLevels: return cool::MSG::NUM_LEVELS; break;
+  }
+  throw Exception( "PANIC! Unknown CORAL MsgLevel value", "CoralApplication" );
+}
+
+//-----------------------------------------------------------------------------
+
+void CoralApplication::setOutputLevel( const cool::MSG::Level level )
+{
+  coral::MsgLevel coralLevel;
+  switch ( level ) {
+  case cool::MSG::NIL:        coralLevel=coral::Nil;       break;
+  case cool::MSG::FATAL:      coralLevel=coral::Fatal;     break;
+  case cool::MSG::ERROR:      coralLevel=coral::Error;     break;
+  case cool::MSG::WARNING:    coralLevel=coral::Warning;   break;
+  case cool::MSG::INFO:       coralLevel=coral::Info;      break;
+  case cool::MSG::DEBUG:      coralLevel=coral::Debug;     break;
+  case cool::MSG::VERBOSE:    coralLevel=coral::Verbose;   break;
+  case cool::MSG::ALWAYS:     coralLevel=coral::Always;    break;
+  case cool::MSG::NUM_LEVELS: coralLevel=coral::NumLevels; break;
+  default:
+    throw Exception( "PANIC! Unknown cool::MSG::Level value", 
+                     "CoralApplication" );
+  } 
+  coral::MessageStream::setMsgVerbosity( coralLevel );
+}
+
+//-----------------------------------------------------------------------------
+
+seal::Context* CoralApplication::context() const
+{
+  std::stringstream msg;
+  msg << "COOL is not based on SEAL any longer: please upgrade your user code";
+  throw Exception( msg.str(), "CoralApplication" );
+}
+
+//-----------------------------------------------------------------------------
+
+coral::IConnectionService& CoralApplication::connectionSvc() const
+{
+  return *m_connSvc;
+}
+
+//-----------------------------------------------------------------------------
+
+coral::MessageStream& CoralApplication::log() 
+{
+  *m_log << coral::Info;
+  return *m_log;
+}
+
+//-----------------------------------------------------------------------------
+
+/*
+// Implementation copied from SEAL Foundation/PluginRefresh/src/main.cpp
+void CoralApplication::feedback ( seal::PluginManager::FeedbackData data ) 
+{
+  std::string explanation;
+  if ( data.error )
+    explanation = 
+      seal::StringOps::replace( data.error->explain (), '\n', "\n\t" );
+
+  if ( getenv ( "COOL_PLUGINMANAGER_DEBUG" ) ) {
+    if ( data.code == seal::PluginManager::StatusLoading )
+      COUT << "INFO: Loading module '" << data.scope << "'" << ENDL;
+  }
+       
+  if ( data.code == seal::PluginManager::ErrorLoadFailure )
+    COUT << "WARNING! Module '" << data.scope
+         << "' failed to load for the following reason: \""
+         << explanation << "\"" << ENDL;
+  
+  else if ( data.code == seal::PluginManager::ErrorBadModule )
+    COUT << "WARNING! Module '" << data.scope
+         << "' ignored until problems with it are fixed" << ENDL;
+  
+  else if ( data.code == seal::PluginManager::ErrorBadCacheFile )
+    COUT << "WARNING! Cache file '" << data.scope
+         << "' is corrupted" << ENDL;
+  
+  else if ( data.code == seal::PluginManager::ErrorEntryFailure )
+    COUT << "WARNING! Module '" << data.scope
+         << "' does not have the required entry point: \""
+         << explanation << "\"" << ENDL;  
+
+  else if ( data.code == seal::PluginManager::ErrorNoFactory )
+    COUT << "WARNING! Module '" << data.scope
+         << "' missing one or more factories for plug-ins" << ENDL;  
+}
+*/
+
+//-----------------------------------------------------------------------------
+
diff --git a/RelationalCool/src/CoralApplication.h b/RelationalCool/src/CoralApplication.h
new file mode 100644
index 000000000..be9cb89a8
--- /dev/null
+++ b/RelationalCool/src/CoralApplication.h
@@ -0,0 +1,84 @@
+// $Id: CoralApplication.h,v 1.9 2008-11-04 11:52:10 avalassi Exp $
+#ifndef RELATIONALCOOL_CORALAPPLICATION_H 
+#define RELATIONALCOOL_CORALAPPLICATION_H 1
+
+// Include files
+#include <memory>
+#include "CoolKernel/IApplication.h"
+#include "CoralBase/MessageStream.h"
+
+namespace cool 
+{
+
+  /** @class CoralApplication CoralApplication.h
+   *
+   *  CORAL-based implementation of a COOL application class.
+   *
+   *  This class provides a concrete implementation of the public Application 
+   *  class, while hiding from the public API all CORAL-based details. 
+   *
+   *  @author Andrea Valassi
+   *  @date   2007-04-08
+   *
+   */ 
+ 
+  class CoralApplication : public IApplication {
+    
+  public:
+
+    /// Constructor from a CORAL ConnectionService (if one is provided, 
+    /// the user is responsible to keep it alive until the application is
+    /// alive; if none is provided, a new own one is created if necessary).
+    CoralApplication( coral::IConnectionService* connSvc = 0 );
+
+    /// Destructor
+    virtual ~CoralApplication();
+
+    /// Retrieve a reference to the COOL database service.
+    IDatabaseSvc& databaseService();
+
+    /// Get the output level threshold for the message service.
+    /// *** WARNING: this may actually return a shared (static) value. ***
+    MSG::Level outputLevel();
+
+    /// Set the output level threshold for the message service.
+    /// *** WARNING: this may actually change a shared (static) value. ***
+    void setOutputLevel( MSG::Level level );
+
+    /// Get the SEAL context (if any) associated with this application.
+    /// *** WARNING: throws an exception for applications not using SEAL. ***
+    seal::Context* context() const;
+
+    /// Get the CORAL connection service (if any) used in this application.
+    /// *** WARNING: throws an exception for applications not using CORAL. ***
+    coral::IConnectionService& connectionSvc() const;
+    
+  private:
+
+    /// Get a CORAL MessageStream
+    coral::MessageStream& log();
+
+    /// Handler of SEAL PluginManager feedback
+    //static void feedback ( seal::PluginManager::FeedbackData data );
+
+    /// Plugin label for the technology-independent top-level DatabaseService
+    //static const std::string& databaseServiceLabel();
+    
+  private:
+    
+    /// CORAL MessageStream
+    std::auto_ptr<coral::MessageStream> m_log;
+
+    /// CORAL connection service
+    coral::IConnectionService* m_connSvc;
+
+    /// Own CORAL connection service?
+    bool m_ownConnSvc;
+
+    /// COOL database service
+    cool::IDatabaseSvc* m_dbSvc;
+
+  };
+
+}
+#endif // RELATIONALCOOL_CORALAPPLICATION_H
diff --git a/RelationalCool/src/CoralConnectionServiceProxy.cpp b/RelationalCool/src/CoralConnectionServiceProxy.cpp
new file mode 100644
index 000000000..918adf6c3
--- /dev/null
+++ b/RelationalCool/src/CoralConnectionServiceProxy.cpp
@@ -0,0 +1,48 @@
+// $Id: CoralConnectionServiceProxy.cpp,v 1.3 2008-04-14 15:26:06 avalassi Exp $
+
+// Local include files
+#include "CoralConnectionServiceProxy.h"
+#include "RelationalException.h"
+
+// Namespace
+using namespace cool;
+
+//-----------------------------------------------------------------------------
+
+CoralConnectionServiceProxy::CoralConnectionServiceProxy( coral::IConnectionService* pConnSvc )
+  : m_pConnSvc( pConnSvc )
+  , m_mutex()
+{
+  //std::cout << "Create CoralConnectionServiceProxy " << this 
+  //          << " -> " << m_pConnSvc << " ***" << std::endl;
+}
+
+//-----------------------------------------------------------------------------
+
+CoralConnectionServiceProxy::~CoralConnectionServiceProxy()
+{
+  //std::cout << "Delete CoralConnectionServiceProxy " << this 
+  //          << " -> " << m_pConnSvc << " ***" << std::endl;
+}
+
+//-----------------------------------------------------------------------------
+
+const coral::IConnectionService* CoralConnectionServiceProxy::getICS() const
+{
+  if ( m_pConnSvc == 0 ) throw RelationalException( "Null pointer in CoralConnectionServiceProxy",
+                                                    "CoralConnectionServiceProxy::getICS()" );
+  //std::cout << "CoralConnectionServiceProxy::getICS " << m_pConnSvc << std::endl;
+  return m_pConnSvc;
+}
+
+//-----------------------------------------------------------------------------
+
+coral::IConnectionService* CoralConnectionServiceProxy::getICS()
+{
+  if ( m_pConnSvc == 0 ) throw RelationalException( "Null pointer in CoralConnectionServiceProxy",
+                                                    "CoralConnectionServiceProxy::getICS()" );
+  //std::cout << "CoralConnectionServiceProxy::getICS " << m_pConnSvc << std::endl;
+  return m_pConnSvc;
+}
+
+//-----------------------------------------------------------------------------
diff --git a/RelationalCool/src/CoralConnectionServiceProxy.h b/RelationalCool/src/CoralConnectionServiceProxy.h
new file mode 100644
index 000000000..d0e9404e6
--- /dev/null
+++ b/RelationalCool/src/CoralConnectionServiceProxy.h
@@ -0,0 +1,122 @@
+// $Id: CoralConnectionServiceProxy.h,v 1.4 2009-01-14 18:57:29 avalassi Exp $
+#ifndef CORALCONNECTIONSERVICEPROXY_H 
+#define CORALCONNECTIONSERVICEPROXY_H 1
+
+// Include files
+#include <iostream>
+#include <boost/shared_ptr.hpp>
+#include <boost/thread.hpp>
+#include "RelationalAccess/IConnectionService.h"
+
+namespace cool
+{
+  
+  /** @class CoralConnectionServicePtr CoralConnectionServicePtr.h
+   *  
+   *  Sharable thread-safe proxy to a coral::IConnectionService.
+   *
+   *  @author Andrea Valassi
+   *  @date   2008-04-10
+   */
+
+  class CoralConnectionServiceProxy : virtual public coral::IConnectionService
+  {
+
+  public: 
+
+    /// Constructor
+    CoralConnectionServiceProxy( coral::IConnectionService* pConnSvc = 0 );
+
+    /// Destructor
+    virtual ~CoralConnectionServiceProxy();
+
+    /// Get the pointer - throws if the pointer is 0.
+    const coral::IConnectionService* getICS() const;
+
+    /// Get the pointer - throws if the pointer is 0.
+    coral::IConnectionService* getICS();
+
+    /// Reset the pointer.
+    void resetICS( coral::IConnectionService* pConnSvc = 0 )
+    {
+      //std::cout << "CoralConnectionServiceProxy::resetICS" << std::endl;
+      boost::mutex::scoped_lock lock( m_mutex );
+      m_pConnSvc = pConnSvc;
+    }
+
+    /**
+     * Returns a session proxy object for the specified connection string
+     * and access mode.
+     */
+    coral::ISessionProxy* connect( const std::string& connectionName,
+                                   coral::AccessMode accessMode = coral::Update )
+    {
+      boost::mutex::scoped_lock lock( m_mutex );
+      return getICS()->connect( connectionName, accessMode );;
+    }    
+
+    /**
+     * Returns a session proxy object for the specified connection string, role
+     * and access mode.
+     */
+    coral::ISessionProxy* connect( const std::string& connectionName,
+                                   const std::string& asRole,
+                                   coral::AccessMode accessMode = coral::Update )
+    {
+      boost::mutex::scoped_lock lock( m_mutex );
+      return getICS()->connect( connectionName, asRole, accessMode );
+    }    
+
+    /**
+     * Returns the configuration object for the service.
+     */
+    coral::IConnectionServiceConfiguration& configuration()
+    {
+      boost::mutex::scoped_lock lock( m_mutex );
+      return getICS()->configuration();
+    }    
+
+    /**
+     * Cleans up the connection pool from the unused connection, according to
+     * the policy defined in the configuration.
+     */
+    void purgeConnectionPool()
+    {
+      //std::cout << "CoralConnectionServiceProxy::purgeConnectionPool" << std::endl;
+      boost::mutex::scoped_lock lock( m_mutex );
+      return getICS()->purgeConnectionPool();
+    }    
+
+    /**
+     * Returns the monitoring reporter
+     */
+    const coral::IMonitoringReporter& monitoringReporter() const
+    {
+      boost::mutex::scoped_lock lock( m_mutex );
+      return getICS()->monitoringReporter();
+    }    
+
+    /**
+     * Returns the object which controls the web cache
+     */
+    coral::IWebCacheControl& webCacheControl()
+    {
+      boost::mutex::scoped_lock lock( m_mutex );
+      return getICS()->webCacheControl();
+    }    
+
+  private:
+
+    /// The coral::IConnectionService pointer.
+    coral::IConnectionService* m_pConnSvc;
+
+    /// The mutex lock (mutable because it must be modified in const methods).
+    mutable boost::mutex m_mutex;
+
+  };
+
+  // Type definition
+  typedef boost::shared_ptr<CoralConnectionServiceProxy> CoralConnectionServiceProxyPtr;
+
+}
+#endif // CORALCONNECTIONSERVICEPTR_H
diff --git a/RelationalCool/src/DummyTransactionMgr.cpp b/RelationalCool/src/DummyTransactionMgr.cpp
new file mode 100644
index 000000000..305a12aa0
--- /dev/null
+++ b/RelationalCool/src/DummyTransactionMgr.cpp
@@ -0,0 +1,22 @@
+// $Id: DummyTransactionMgr.cpp,v 1.1 2007-03-28 11:35:40 avalassi Exp $
+
+// Local include files
+#include "DummyTransactionMgr.h"
+
+// Namespace
+using namespace cool;
+
+//-----------------------------------------------------------------------------
+
+DummyTransactionMgr::DummyTransactionMgr()
+{
+}
+
+//-----------------------------------------------------------------------------
+
+DummyTransactionMgr::~DummyTransactionMgr() 
+{
+}
+
+//-----------------------------------------------------------------------------
+
diff --git a/RelationalCool/src/DummyTransactionMgr.h b/RelationalCool/src/DummyTransactionMgr.h
new file mode 100644
index 000000000..d56698a1b
--- /dev/null
+++ b/RelationalCool/src/DummyTransactionMgr.h
@@ -0,0 +1,74 @@
+// $Id: DummyTransactionMgr.h,v 1.6 2008-11-04 11:52:10 avalassi Exp $
+#ifndef RELATIONALCOOL_DUMMYTRANSACTIONMGR_H
+#define RELATIONALCOOL_DUMMYTRANSACTIONMGR_H
+
+// Local include files
+#include "IRelationalTransactionMgr.h"
+#include "RelationalException.h"
+
+namespace cool {  
+  
+  /** @class RelationalTransactionMgr RelationalTransactionMgr.h
+   *  
+   *  Dummy manager of relational database transactions.
+   *
+   *  This manager is only used in read-only connections: the only non-dummy 
+   *  operation it performs is to throw if a read-write transaction is open!
+   * 
+   *  @author Andrea Valassi
+   *  @date   2007-03-28
+  */
+  
+  class DummyTransactionMgr: public IRelationalTransactionMgr  
+  {
+    
+  public:
+
+    /// Destructor
+    virtual ~DummyTransactionMgr();
+
+    /// Standard constructor
+    DummyTransactionMgr();
+    
+    void setAutoTransactions( bool ) {}
+    bool autoTransactions() const { return true; }
+    
+  protected:
+
+    /// Start a transaction
+    void start( bool readOnly )
+    {
+      if ( !readOnly ) 
+        throw DatabaseOpenInReadOnlyMode( "DummyTransactionManager" );
+      m_isActive = true;
+    };
+    
+    /// Commit a transaction
+    void commit()
+    {
+      m_isActive = false;
+    };
+    
+    /// Rollback a transaction
+    void rollback()
+    {
+      m_isActive = false;
+    };
+
+    /// Is the transaction active?
+    bool isActive()
+    {
+      return m_isActive;
+    };
+    
+  private:
+
+    /// Is the transaction active?
+    bool m_isActive;
+
+  };
+  
+}
+
+#endif // RELATIONALCOOL_DUMMYTRANSACTIONMGR_H
+
diff --git a/RelationalCool/src/HvsPathHandler.cpp b/RelationalCool/src/HvsPathHandler.cpp
new file mode 100644
index 000000000..5a3c091f4
--- /dev/null
+++ b/RelationalCool/src/HvsPathHandler.cpp
@@ -0,0 +1,160 @@
+// $Id: HvsPathHandler.cpp,v 1.8 2007-10-30 18:06:25 avalassi Exp $
+
+// Include files
+#include <sstream>
+
+// Local include files
+#include "HvsPathHandler.h"
+#include "HvsPathHandlerException.h"
+#include "uppercaseString.h"
+
+// Namespace
+using namespace cool;
+
+//-----------------------------------------------------------------------------
+
+HvsPathHandler::HvsPathHandler() {  
+}
+
+//-----------------------------------------------------------------------------
+
+HvsPathHandler::~HvsPathHandler() {  
+}
+ 
+//-----------------------------------------------------------------------------
+
+const std::pair<std::string, std::string> 
+HvsPathHandler::splitFullPath( const std::string& fullPath ) 
+{
+  if ( fullPath == rootFullPath() ) {
+    std::ostringstream msg;
+    msg << "Full path '" << fullPath 
+        << "' is the root path: it has no parent and cannot be split";
+    throw HvsPathHandlerException( msg.str() );
+  }
+  if( fullPath != removeTrailingSeparators( fullPath ) ) {
+    std::ostringstream msg;
+    msg << "Full path '" << fullPath << "' contains trailing separators";
+    throw HvsPathHandlerException( msg.str() );
+  }
+  if( fullPath != removeDoubleSeparators( fullPath ) ) {
+    std::ostringstream msg;
+    msg << "Full path '" << fullPath << "' contains double separators";
+    throw HvsPathHandlerException( msg.str() );
+  }
+  {    
+    std::string allowedChar = "/ABCDEFGHIJKLMNOPQRSTUVWXYZ_1234567890.-";
+    const std::string ucName = uppercaseString( fullPath );    
+    std::string::size_type pos = ucName.find_first_not_of( allowedChar );
+    if ( pos != ucName.npos )
+    {      
+      std::ostringstream msg;
+      msg << "Full path '" << fullPath << "' contains invalid character '" 
+          << fullPath.substr( pos, 1 ) << "'";
+      throw HvsPathHandlerException( msg.str() );   
+    }
+  }
+  std::string newPath = fullPath;
+  std::string sep( 1, separator() );
+  std::string::size_type lastPos = newPath.rfind( sep );
+  if ( lastPos == std::string::npos ) {
+    std::ostringstream msg;
+    msg << "Full path '" << fullPath 
+        << "' does not contain the separator character '" << sep << "'";
+    throw HvsPathHandlerException( msg.str() );
+  }
+  std::string parent = newPath.substr( 0, lastPos );
+  std::string child = newPath.substr( lastPos+1 );
+  if( parent == rootUnresolvedName() ) parent=rootFullPath();
+  //std::cout << "Split '" << fullPath << "' into '" << parent
+  //          << "' and '" << child << "'" << std::endl;
+  return std::pair<std::string,std::string>( parent, child );
+}
+
+//-----------------------------------------------------------------------------
+
+const std::vector<std::string> 
+HvsPathHandler::decodeFullPath( const std::string& fullPath )
+{
+  std::string newPath = fullPath;
+  std::vector<std::string> nodeRList;
+  while ( newPath != rootFullPath() ) {
+    const std::pair<std::string, std::string> 
+      newPair = splitFullPath( newPath );
+    newPath = newPair.first;
+    nodeRList.push_back( newPair.second );
+  }
+  std::vector<std::string> nodeList;
+  nodeList.push_back( rootUnresolvedName() );
+  //std::cout << "Decode '" << fullPath 
+  //          << "' into '" << rootUnresolvedName() << "'";
+  std::vector<std::string>::reverse_iterator node;
+  for ( node = nodeRList.rbegin(); node != nodeRList.rend(); node++ ) {
+    //std::cout << ", '" << *node << "'";
+    nodeList.push_back( *node );        
+  }
+  //std::cout << std::endl;
+  return nodeList;
+}
+
+//-----------------------------------------------------------------------------
+
+const std::string
+HvsPathHandler::encodeFullPath( const std::vector<std::string>& nodeList )
+{
+  std::string fullPath;
+  std::vector<std::string>::const_iterator node;
+  for ( node = nodeList.begin(); node != nodeList.end(); node++ ) {
+    if ( node == nodeList.begin() ) {
+      if ( *node != rootUnresolvedName() ) {
+        std::ostringstream msg;
+        msg << "The first node name '" << *node 
+            << "' is not the root node name '" << rootUnresolvedName() << "'";
+        throw HvsPathHandlerException( msg.str() );
+      }  
+    } else {
+      fullPath += std::string( 1, separator() );
+    }    
+    if ( (*node).find(std::string(1,separator())) != std::string::npos ) {
+      std::ostringstream msg;
+      msg << "Unresolved node name '" << *node 
+          << "' should not contain the separator '" << separator() << "'";
+      throw HvsPathHandlerException( msg.str() );
+    }  
+    fullPath += *node;
+  }
+  if ( fullPath == rootUnresolvedName() ) fullPath=rootFullPath();
+  return fullPath;
+}
+
+//-----------------------------------------------------------------------------
+
+const std::string 
+HvsPathHandler::removeTrailingSeparators( const std::string& aString ) 
+{
+  std::string newString = aString;
+  while ( true ) {
+    if ( newString.size() <=1 ) return newString;
+    std::string sep( 1, separator() );
+    std::string::size_type lastPos = newString.rfind( sep );
+    if ( lastPos != newString.size()-1 ) return newString;
+    newString = newString.substr( 0, lastPos );
+  }
+}
+
+//-----------------------------------------------------------------------------
+
+const std::string 
+HvsPathHandler::removeDoubleSeparators( const std::string& aString ) 
+{
+  std::string newString = aString;
+  std::string doubleSep( 1, separator() );
+  doubleSep += doubleSep;
+  std::string::size_type pos;
+  while( ( pos = newString.find(doubleSep) ) != std::string::npos ) {
+    newString = newString.substr( 0, pos ) + newString.substr( pos+1 );
+  }
+  return newString;
+}
+
+//-----------------------------------------------------------------------------
diff --git a/RelationalCool/src/HvsPathHandler.h b/RelationalCool/src/HvsPathHandler.h
new file mode 100644
index 000000000..df3660ab4
--- /dev/null
+++ b/RelationalCool/src/HvsPathHandler.h
@@ -0,0 +1,102 @@
+// $Id: HvsPathHandler.h,v 1.7 2008-11-04 10:59:47 avalassi Exp $
+#ifndef RELATIONALCOOL_HVSPATHHANDLER_H 
+#define RELATIONALCOOL_HVSPATHHANDLER_H 1
+
+// Include files
+#include <map>
+#include <string>
+#include <vector>
+
+namespace cool 
+{
+
+  /** @class HvsPathHandler HvsPathHandler.h
+   *  
+   *  Handler of hierarchical path names for HVS.
+   *  
+   *  This class is used to encode, decode and validate full path names
+   *  of the form "/node1/node2/node3" in a UNIX-like node hierarchy.
+   *  
+   *  The handler is also used in the COOL conditions database implementation:
+   *  any features specific to COOL may be changed by virtual inheritance.
+   *  
+   *  The documentation for the class is written assuming "/" is the
+   *  separator character, but this is hardcoded in a single clas variable.
+   *  
+   *  @author Andrea Valassi and Sven A. Schmidt
+   *  @date   2004-12-09
+   */
+
+  class HvsPathHandler {
+    
+    friend class HvsPathHandlerTest;
+
+  public:
+
+    /// Standard constructor.
+    HvsPathHandler(); 
+
+    /// Destructor.
+    virtual ~HvsPathHandler();
+
+    /// Return the separator character '/'.
+    char separator() const 
+    { 
+      return '/';
+    }    
+
+    /// Return the unresolved root name "".
+    const std::string rootUnresolvedName() const 
+    {
+      return "";
+    }    
+
+    /// Return the full root path "/".
+    const std::string rootFullPath() const 
+    {
+      return rootUnresolvedName() + std::string( 1, separator() );
+    }    
+
+    /// Split a full HVS path into parent full path and child unresolved name,
+    /// e.g. split "/a/b/c" into "/a/b" and "c".
+    /// Special case: "/a" is split into "/" and "a".
+    /// Throw an exception if the path has double or trailing separators.
+    /// Throw an exception if the path does not start by "/".
+    /// Throw an exception if the path is the root folder "/".
+    const std::pair<std::string, std::string>
+    splitFullPath( const std::string& fullPath );
+
+    /// Decode a full HVS path into a list of hierarchy node unresolved names,
+    /// e.g. split "/a/b/c" into "", "a", "b" and "c".
+    /// Throw an exception if the path has double or trailing separators.
+    /// Throw an exception if the path does not start by "/"
+    /// (special case: "/" represents the root folder "").
+    const std::vector<std::string> 
+    decodeFullPath( const std::string& fullPath );
+
+    /// Encode a list of unresolved hierarchy node names into a full HVS path,
+    /// e.g. encode "", "a", "b", "c" into "/a/b/c".
+    /// Throw an exception if any node name contains a separator.
+    /// Throw an exception if the first node is not the root node "".
+    const std::string
+    encodeFullPath( const std::vector<std::string>& nodeList );
+
+  private:
+
+    /// Remove trailing separators from a string,
+    /// e.g. simplify "/a//b/c/" into "/a//b/c/".
+    /// Special case: "/" is left as "/".
+    const std::string 
+    removeTrailingSeparators( const std::string& aString );
+
+    /// Remove double separators from a string,
+    /// e.g. simplify "/a//b/c" into "/a/b/c".
+    const std::string 
+    removeDoubleSeparators( const std::string& aString );
+
+  };
+
+}
+
+#endif // RELATIONALCOOL_HVSPATHHANDLER_H
+  
diff --git a/RelationalCool/src/HvsPathHandlerException.h b/RelationalCool/src/HvsPathHandlerException.h
new file mode 100644
index 000000000..e8ca2bcd4
--- /dev/null
+++ b/RelationalCool/src/HvsPathHandlerException.h
@@ -0,0 +1,33 @@
+// $Id: HvsPathHandlerException.h,v 1.1 2006-03-21 12:00:18 avalassi Exp $
+#ifndef RELATIONALCOOL_HVSPATHHANDLEREXCEPTION_H 
+#define RELATIONALCOOL_HVSPATHHANDLEREXCEPTION_H 1
+
+// Include files
+#include <string>
+#include "CoolKernel/Exception.h"
+
+namespace cool 
+{
+
+  /** @class HvsPathHandlerException
+   *  
+   *  Exception thrown by the HvsPathHandler class.
+   */
+
+  class HvsPathHandlerException : public Exception {
+
+  public:
+
+    /// Constructor
+    HvsPathHandlerException( const std::string& message )
+      : Exception( message, "HvsPathHandler" ) {}
+    
+    /// Destructor
+    virtual ~HvsPathHandlerException() throw() {}
+    
+  };
+
+}
+
+#endif // RELATIONALCOOL_HVSPATHHANDLEREXCEPTION_H
+  
diff --git a/RelationalCool/src/HvsTagRecord.h b/RelationalCool/src/HvsTagRecord.h
new file mode 100644
index 000000000..84cd1ce46
--- /dev/null
+++ b/RelationalCool/src/HvsTagRecord.h
@@ -0,0 +1,131 @@
+// $Id: HvsTagRecord.h,v 1.12 2008-11-04 11:52:10 avalassi Exp $
+#ifndef COOLKERNEL_HVSTAGRECORD_H
+#define COOLKERNEL_HVSTAGRECORD_H
+
+// Include files
+#include "CoolKernel/Time.h"
+#include "IHvsTagRecord.h"
+
+// TEMPORARY - debug unknown exception on Windows
+//#include <iostream>
+
+namespace cool {
+
+  /** @class HvsTagRecord HvsTagRecord.h
+   *
+   *  Concrete implementation of an IHvsTagRecord.
+   *
+   *  @author Andrea Valassi
+   *  @date   2006-03-24
+   */
+
+  class HvsTagRecord : public IHvsTagRecord {
+
+  public:
+
+    /// Destructor
+    virtual ~HvsTagRecord() {}
+
+    /// System-assigned tag ID.
+    UInt32 id() const
+    {
+      return m_id;
+    }
+
+    /// Tag scope: node where the tag is defined.
+    UInt32 nodeId() const
+    {
+      return m_nodeId;
+    }
+
+    /// Tag name.
+    const std::string& name() const
+    {
+      return m_name;
+    }
+
+    /// Tag lock status.
+    HvsTagLock::Status lockStatus() const
+    {
+      return m_lockStatus;
+    }
+
+    /// Tag description.
+    const std::string& description() const
+    {
+      return m_description;
+    }
+
+    /// Tag insertion time into the database (creation time).
+    const ITime& insertionTime() const
+    {
+      return m_insertionTime;
+    }
+
+    /// Constructor from all data members.
+    HvsTagRecord( UInt32 id,
+                  UInt32 nodeId,
+                  const std::string& name,
+                  HvsTagLock::Status lockStatus,
+                  const std::string& description,
+                  const ITime& insertionTime )
+      : m_id( id )
+      , m_nodeId( nodeId )
+      , m_name( name )
+      , m_lockStatus( lockStatus )
+      , m_description( description )
+      , m_insertionTime( insertionTime ) 
+    {
+      // TEMPORARY - debug unknown exception on Windows
+      //std::cout << "*** HvsTagRecord - CONSTRUCTOR" << std::endl;
+    }    
+
+    /// Copy constructor.
+    /// AV - Added IHvsTagRecord to avoid gcc344 warning on copy constructor
+    /// AV - To be tested: would this solve the unknown Windows exception???
+    HvsTagRecord( const HvsTagRecord& rhs )
+      : IHvsTagRecord()
+      , m_id( rhs.m_id )
+      , m_nodeId( rhs.m_nodeId )
+      , m_name( rhs.m_name )
+      , m_lockStatus( rhs.m_lockStatus )
+      , m_description( rhs.m_description )
+      , m_insertionTime( rhs.m_insertionTime ) 
+    {
+      // TEMPORARY - debug unknown exception on Windows
+      //std::cout << "*** HvsTagRecord - COPY CONSTRUCTOR" << std::endl;
+    }    
+
+  private:
+
+    /// Standard constructor is private
+    HvsTagRecord();
+
+    /// Assignment operator is private
+    HvsTagRecord& operator=( const HvsTagRecord& rhs ); 
+
+  private:
+
+    /// System-assigned tag ID.
+    UInt32 m_id;
+
+    /// Tag scope: node where the tag is defined.
+    UInt32 m_nodeId;
+
+    /// Tag name.
+    std::string m_name;
+
+    /// Tag lock status.
+    HvsTagLock::Status m_lockStatus;
+
+    /// Tag description.
+    std::string m_description;
+
+    /// Insertion time into the database.
+    Time m_insertionTime;
+
+  };
+
+}
+
+#endif // COOLKERNEL_HVSTAGRECORD_H
diff --git a/RelationalCool/src/IHvsTagMgr.h b/RelationalCool/src/IHvsTagMgr.h
new file mode 100644
index 000000000..90cf9c07f
--- /dev/null
+++ b/RelationalCool/src/IHvsTagMgr.h
@@ -0,0 +1,207 @@
+// $Id: IHvsTagMgr.h,v 1.7 2008-11-04 11:05:22 avalassi Exp $
+#ifndef COOLKERNEL_IHVSTAGMGR_H
+#define COOLKERNEL_IHVSTAGMGR_H
+
+// Include files
+#include <string>
+#include <vector>
+#include "CoolKernel/IHvsNode.h"
+
+namespace cool {  
+  
+  // Forward declarations
+  class HvsTagRecord;
+  //class IHvsTag;
+  //class IHvsTagRecord;
+
+  /** @class IHvsTagMgr IHvsTagMgr.h
+   *  
+   *  Abstract interface for the manager of one HVS tag tree.
+   * 
+   *  An HVS tag represents a tagged version of one HVS node.
+   *  It can be uniquely identified by the tag name and the node name or ID.
+   *  Each tag is also assigned a unique integer ID by the system.
+   *  
+   *  The terms "tag" and "tag name" are NOT equivalent.
+   *  A given tag name can be used either for only one inner node or for any
+   *  number of leaf nodes: the same tag name cannot be used for more than
+   *  one inner node, or for one inner node and one or more leaf nodes.
+   *  Users can reserve the use of a given tag name for either type of node.
+   *
+   *  TEMPORARY! A tag name cannot be used YET for more than one leaf node!
+   *
+   *  For inner nodes, an HVS tag represents a collection 
+   *  of versions of (some of its) children nodes.
+   *  For leaf nodes, an HVS tag typically represents a collection 
+   *  of versions of (some of the) data associated to the leaf node,
+   *  such as a collection of IOVs in a conditions data folder.
+   *  
+   *  When different tags with the same name exist in different leaf nodes,
+   *  they are assigned different integer IDs so that they can be renamed
+   *  independently while keeping their distinct ID and properties.
+   *  
+   *  @author Andrea Valassi
+   *  @date   2006-03-02
+  */
+  
+  class IHvsTagMgr {
+    
+  public:
+
+    /// Destructor
+    virtual ~IHvsTagMgr() {};
+
+    /// This method does not handle transactions.
+    /// Create a tag in an HVS node.
+    /// Throws TagExists if the tag already exists (in this or another node).
+    virtual const HvsTagRecord 
+    createTag( UInt32 nodeId,
+               const std::string& tagName,
+               const std::string& description = "" ) const = 0;
+    
+    /// This method does not handle transactions.
+    /// Delete a tag in an HVS node.
+    virtual void deleteTag( UInt32 nodeId,
+                            const std::string& tagName ) const = 0;
+    
+    /*
+    /// Has this tag name been reserved for a node type?
+    /// [NB: this may be true even if it is not used in any node.]
+    /// Tag names, except for "HEAD", are case sensitive.
+    /// Returns true for the reserved tags "" and "HEAD".
+    virtual bool existsTagName( const std::string& tagName ) const = 0;
+    */
+    
+    /// Return the type of node (inner/leaf) where this tag name can be used.
+    /// Tag names, except for "HEAD", are case sensitive.
+    /// Throws TagNameNotFound if the tag name does not exist.
+    virtual IHvsNode::Type tagNameScope( const std::string& tagName ) const = 0;
+
+    /// Does a tag with this name exist (in any node)?
+    /// Tag names, except for "HEAD", are case sensitive.
+    /// Returns true for the reserved tags "" and "HEAD".
+    virtual bool existsTag( const std::string& tagName ) const = 0;
+    
+    /*
+    /// TEMPORARY! A tag name cannot be used YET for more than one leaf node!
+    /// Return the ID of the node where the tag is defined.
+    /// Throws ReservedHeadTag for the HEAD tag (defined in all folders). 
+    /// Throws TagNotFound if the tag does not exist.
+    virtual UInt32 taggedNodeId( const std::string& tagName ) const = 0;
+
+    /// TEMPORARY! A tag name cannot be used YET for more than one leaf node!
+    /// Return the name of the node where the tag is defined.
+    /// Throws ReservedHeadTag for the HEAD tag (defined in all folders). 
+    /// Throws TagNotFound if the tag does not exist.
+    virtual const std::string taggedNode( const std::string& tagName ) const = 0;
+
+    /// Return the IDs of the nodes where the tag is defined.
+    /// Throws ReservedHeadTag for the HEAD tag (defined in all folders). 
+    /// Throws TagNotFound if the tag does not exist.
+    virtual const std::vector<UInt32> 
+    taggedNodeIds( const std::string& tagName ) const = 0;
+    */
+
+    /// Return the names of the nodes where the tag is defined.
+    /// Throws ReservedHeadTag for the HEAD tag (defined in all folders). 
+    /// Throws TagNotFound if the tag does not exist.
+    virtual const std::vector<std::string> 
+    taggedNodes( const std::string& tagName ) const = 0;
+
+    /*
+    /// Does a tag with this name exist in the given node?
+    /// Tag names, except for "HEAD", are case sensitive.
+    /// Returns true for the reserved tags "" and "HEAD".
+    virtual bool existsTag( const std::string& tagName,
+                            UInt32 nodeId ) = 0;
+    */
+
+    /// Find a tag record by nodeId and tag name.
+    /// Throws ReservedHeadTag for the HEAD tag (defined in all folders). 
+    /// Throws TagNotFound if the tag does not exist.
+    virtual const HvsTagRecord findTagRecord( UInt32 nodeId, 
+                                              const std::string& tagName ) const = 0;
+    
+    /// Find a tag record by nodeId and tagId.
+    /// Throws ReservedHeadTag for the HEAD tag (defined in all folders). 
+    /// Throws TagNotFound if the tag does not exist.
+    virtual const HvsTagRecord findTagRecord( UInt32 nodeId, 
+                                              UInt32 tagId ) const = 0;
+    
+    /*
+    /// Does a tag with this name exist in the given node?
+    /// Tag names, except for "HEAD", are case sensitive.
+    /// Returns true for the reserved tags "" and "HEAD".
+    virtual bool existsTag( const std::string& tagName,
+                                  const std::string& nodeName ) = 0;
+    
+    /// Find a tag record by name and node name.
+    /// Throws ReservedHeadTag for the HEAD tag (defined in all folders). 
+    /// Throws TagNotFound if the tag does not exist in the given node.
+    virtual const IHvsTagRecord 
+    findTagRecord( const std::string& tagName,
+                   const std::string& nodeName ) const = 0;
+    */
+
+    /*
+    /// Find a tag by name and nodeID.
+    /// Throws TagNotFound if the tag does not exist.
+    virtual const IHvsTag& findTag( const std::string& tagName,
+                                    UInt32 nodeId ) const = 0;
+
+    /// Find a tag by name and node name.
+    /// Throws TagNotFound if the tag does not exist.
+    virtual const IHvsTag& findTag( const std::string& tagName,
+                                    const std::string& nodeName ) const = 0;
+    */
+
+    /// Create a relation between tags for a pair of parent/child nodes.
+    /// Create the parent tag in the parent node if not defined yet.
+    /// Create the child tag in the child node if not defined yet.
+    /// Throws ReservedHeadTag if one of the two tags is a HEAD tag.
+    /// Throws NodeIsSingleVersion if either node does not support versioning.
+    /// Throws NodeRelationNotFound if the nodes are not parent and child.
+    /// Throws TagExists if either tag is already used in another node.
+    /// Throws TagRelationExists if a relation to a child tag already exists.
+    virtual void createTagRelation( UInt32 parentNodeId,
+                                    const std::string& parentTagName,
+                                    UInt32 childNodeId,
+                                    const std::string& childTagName ) const = 0;
+    
+    /// Delete the relation between a parent tag node and a child tag.
+    /// Delete the parent tag if not related to another parent/child tag.
+    /// Delete the child tag if not related to another tag or IOVs.
+    /// Throws ReservedHeadTag if the parent tag is a HEAD tag.
+    /// Throws TagNotFound if the parent tag does not exist in the parent node.
+    /// Throws TagRelationNotFound if the parent tag has no related child tag.
+    /// TEMPORARY? - returns the tagId of the deleted related child tag
+    virtual UInt32 deleteTagRelation( UInt32 parentNodeId,
+                                      const std::string& parentTagName,
+                                      UInt32 childNodeId ) const = 0;
+    
+    /// Find the child node tag associated to the given parent node tag.
+    /// Throws ReservedHeadTag if the parent tag is a HEAD tag.
+    /// Throws TagNotFound if the parent tag does not exist in the parent node.
+    /// Throws TagRelationNotFound if the parent tag has no related child tag.
+    virtual UInt32 findTagRelation( UInt32 parentNodeId,
+                                    const std::string& parentTagName,
+                                    UInt32 childNodeId ) const = 0;
+
+    /// Main HVS method: determine the descendant node tag that is related to 
+    /// the given ancestor tag (assumed to be defined in an ancestor node).
+    /// The corresponding ancestor node is also internally determined.
+    /// The ancestor tag is returned if defined directly in the descendant.
+    /// Throws ReservedHeadTag if the ancestor tag is a HEAD tag.
+    /// Throws TagNotFound if the tag does not exist in any inner node.
+    /// Throws NodeRelationNotFound if the inner node where the ancestor tag 
+    /// is defined is not an ancestor of the descendant node.
+    /// Throws TagRelationNotFound if no hierarchical tag relation exists.
+    virtual UInt32 resolveTag( const std::string& ancestorTagName,
+                               UInt32 descendantNodeId ) const = 0;
+    
+  };
+  
+}
+
+#endif // COOLKERNEL_IHVSTAGMGR_H
+
diff --git a/RelationalCool/src/IHvsTagRecord.h b/RelationalCool/src/IHvsTagRecord.h
new file mode 100644
index 000000000..0b4eb0ee0
--- /dev/null
+++ b/RelationalCool/src/IHvsTagRecord.h
@@ -0,0 +1,70 @@
+// $Id: IHvsTagRecord.h,v 1.6 2008-11-04 11:52:10 avalassi Exp $
+#ifndef COOLKERNEL_IHVSTAGRECORD_H
+#define COOLKERNEL_IHVSTAGRECORD_H
+
+// Include files
+#include <string>
+#include "CoolKernel/IHvsNode.h"
+#include "CoolKernel/Time.h"
+
+namespace cool {
+
+  /** @class IHvsTagRecord IHvsTagRecord.h
+   *
+   *  Read-only abstract interface to one tag in an HVS tag tree.
+   *
+   *  An HVS tag represents a tagged version of one HVS node.
+   *  It can be uniquely identified by the tag name and the node name or ID.
+   *  Each tag is also assigned a unique integer ID by the system.
+   *  
+   *  The terms "tag" and "tag name" are NOT equivalent.
+   *  A given tag name can be used either for only one inner node or for any
+   *  number of leaf nodes: the same tag name cannot be used for more than
+   *  one inner node, or for one inner node and one or more leaf nodes.
+   *  Users can reserve the use of a given tag name for either type of node.
+   *
+   *  TEMPORARY! A tag name cannot be used YET for more than one leaf node!
+   *
+   *  For inner nodes, an HVS tag represents a collection 
+   *  of versions of (some of its) children nodes.
+   *  For leaf nodes, an HVS tag typically represents a collection 
+   *  of versions of (some of the) data associated to the leaf node,
+   *  such as a collection of IOVs in a conditions data folder.
+   *  
+   *  When different tags with the same name exist in different leaf nodes,
+   *  they are assigned different integer IDs so that they can be renamed
+   *  independently while keeping their distinct ID and properties.
+   *
+   *  @author Andrea Valassi
+   *  @date   2006-03-03
+   */
+
+  class IHvsTagRecord {
+
+  public:
+
+    /// System-assigned tag ID.
+    virtual UInt32 id() const = 0;
+
+    /// Tag scope: node where the tag is defined.
+    virtual UInt32 nodeId() const = 0;
+
+    /// Tag name.
+    virtual const std::string& name() const = 0;
+
+    /// Tag description.
+    virtual const std::string& description() const = 0;
+
+    /// Tag insertion time into the database (creation time).
+    virtual const ITime& insertionTime() const = 0;
+
+  protected:
+
+    /// Destructor.
+    virtual ~IHvsTagRecord() {}
+
+  };
+
+}
+
+#endif // COOLKERNEL_IHVSTAGRECORD_H
diff --git a/RelationalCool/src/IRelationalBulkOperation.h b/RelationalCool/src/IRelationalBulkOperation.h
new file mode 100644
index 000000000..c9bdc69cc
--- /dev/null
+++ b/RelationalCool/src/IRelationalBulkOperation.h
@@ -0,0 +1,28 @@
+#ifndef RELATIONALCOOL_IRELATIONALBULKOPERATION_H
+#define RELATIONALCOOL_IRELATIONALBULKOPERATION_H
+
+namespace cool {
+
+  /**
+   * Class IRelationalBulkOperation
+   *
+   * Abstract interface for the execution of bulk operations.
+   */
+
+  class IRelationalBulkOperation {
+
+  public:
+
+    /// Destructor
+    virtual ~IRelationalBulkOperation() {}
+
+    /// Processes the next iteration
+    virtual void processNextIteration() = 0;
+    
+    /// Flushes the data on the client side to the server.
+    virtual void flush() = 0;
+
+  };
+
+}
+#endif
diff --git a/RelationalCool/src/IRelationalCursor.h b/RelationalCool/src/IRelationalCursor.h
new file mode 100644
index 000000000..b3b31823c
--- /dev/null
+++ b/RelationalCool/src/IRelationalCursor.h
@@ -0,0 +1,37 @@
+#ifndef RELATIONALCOOL_IRELATIONALCURSOR_H
+#define RELATIONALCOOL_IRELATIONALCURSOR_H
+
+// Include files
+#include "CoralBase/AttributeList.h"
+
+namespace cool 
+{
+
+  /**
+   * Class IRelationalCursor.
+   *
+   * Abstract interface for a query cursor.
+   */
+
+  class IRelationalCursor 
+  {
+
+  public:
+
+    /// Destructor
+    virtual ~IRelationalCursor() {}
+
+    /// Positions the cursor to the next available row in the result set.
+    /// If there are no more rows in the result set false is returned.
+    virtual bool next() = 0;
+    
+    /// Returns a reference to the output buffer holding the last row fetched.
+    virtual const coral::AttributeList& currentRow() const = 0;
+      
+    /// Explicitly closes the cursor, releasing the resources on the server.
+    virtual void close() = 0;
+
+  };
+
+}
+#endif
diff --git a/RelationalCool/src/IRelationalQueryDefinition.h b/RelationalCool/src/IRelationalQueryDefinition.h
new file mode 100644
index 000000000..fa7d858b2
--- /dev/null
+++ b/RelationalCool/src/IRelationalQueryDefinition.h
@@ -0,0 +1,135 @@
+// $Id: IRelationalQueryDefinition.h,v 1.7 2008-11-04 11:52:10 avalassi Exp $
+#ifndef RELATIONALCOOL_IRELATIONALQUERYDEFINITION_H
+#define RELATIONALCOOL_IRELATIONALQUERYDEFINITION_H
+
+// Include files
+#include <iostream>
+#include <string>
+#include <vector>
+#include "CoolKernel/IRecord.h"
+
+namespace cool {
+
+  //--------------------------------------------------------------------------
+
+  /** @class RelationalQueryDefinition RelationalQueryDefinition.h
+   *
+   *  Abstract interface to a relational query definition.
+   *
+   *  @author Andrea Valassi
+   *  @date   2007-06-19
+   */
+
+  class IRelationalQueryDefinition {
+
+  public:
+
+    class ISelectItem
+    {
+    public:
+      virtual ~ISelectItem() {}
+      virtual bool isSubquery() const = 0;
+      virtual const std::string& expression() const = 0;
+      //virtual const IRelationalQueryDefinition& subquery() const = 0;
+      virtual const std::string& alias() const = 0;
+      virtual const ISelectItem* clone() const = 0;
+    };
+
+    class IFromItem
+    {
+    public:
+      virtual ~IFromItem() {}
+      virtual bool isSubquery() const = 0;
+      virtual const std::string& expression() const = 0;
+      virtual const IRelationalQueryDefinition& subquery() const = 0;
+      virtual const std::string& alias() const = 0;
+      virtual const IFromItem* clone() const = 0;
+    };
+
+    class IGroupItem
+    {
+    public:
+      virtual ~IGroupItem() {}
+      virtual const std::string& expression() const = 0;
+      virtual const IGroupItem* clone() const = 0;
+    };
+
+    class IOrderItem
+    {
+    public:
+      virtual ~IOrderItem() {}
+      virtual const std::string& expression() const = 0; // may end in ASC/DESC
+      virtual const IOrderItem* clone() const = 0;
+    };
+
+    /// Destructor.
+    virtual ~IRelationalQueryDefinition() {}
+
+    /// Clone this query definition.
+    virtual const IRelationalQueryDefinition* clone() const = 0;
+
+    /// Get the hint in the format "/*+ hints */"
+    /// ("SELECT /*+ hints */ expr1 alias1, expr2 alias2, ...").
+    virtual const std::string& getHint() const = 0;
+    
+    /// Get the SELECT list size
+    /// ("SELECT expr1 alias1, expr2 alias2, ...").
+    virtual unsigned getSelectSize() const = 0;
+  
+    /// Get a SELECT list item 
+    /// ("SELECT expr1 alias1, expr2 alias2, ...").
+    virtual const ISelectItem& getSelectItem( unsigned item ) const = 0;
+  
+    /// Get the FROM clause size
+    /// ("FROM table1 alias1, table2 alias2, ...").
+    virtual unsigned getFromSize() const = 0;
+  
+    /// Get a FROM clause item
+    /// ("FROM table1 alias1, table2 alias2, ...").
+    virtual const IFromItem& getFromItem( unsigned item ) const = 0;
+  
+    /// Get the WHERE clause ("WHERE ...").
+    virtual const std::string& getWhereClause() const = 0;
+    
+    /// Get the GROUP BY clause size
+    /// ("GROUP BY expr1, expr2...").
+    virtual unsigned getGroupSize() const = 0;
+    
+    /// Get a GROUP BY clause item
+    /// ("GROUP BY expr1, expr2...").
+    virtual const IGroupItem& getGroupItem( unsigned item ) const = 0;
+    
+    /// Get the ORDER BY clause size
+    /// ("ORDER BY expr1, expr2...").
+    virtual unsigned getOrderSize() const = 0;
+
+    /// Get a ORDER BY clause item
+    /// ("ORDER BY expr1, expr2...").
+    virtual const IOrderItem& getOrderItem( unsigned item ) const = 0;
+
+    /// Get the bind variables.
+    /// Bind variables are not necessary here if this is a subquery definition.
+    virtual const IRecord& getBindVariables() const = 0;
+
+    /// Get the result set specification.
+    /// The result set spec is ignored if this is a subquery definition.
+    virtual const IRecordSpecification& getResultSetSpecification() const = 0;
+
+    /// Print the relational query definition to an output stream.
+    virtual std::ostream& print( std::ostream& s ) const = 0;
+
+  };
+
+  //--------------------------------------------------------------------------
+
+  inline std::ostream& operator<<( std::ostream& s, 
+                                   const IRelationalQueryDefinition& def )
+  {
+    return def.print( s );
+  }  
+
+  //--------------------------------------------------------------------------
+
+}
+
+#endif // RELATIONALCOOL_IRELATIONALQUERYDEFINITION_H
diff --git a/RelationalCool/src/IRelationalTransactionMgr.h b/RelationalCool/src/IRelationalTransactionMgr.h
new file mode 100644
index 000000000..f4701db67
--- /dev/null
+++ b/RelationalCool/src/IRelationalTransactionMgr.h
@@ -0,0 +1,46 @@
+// $Id: IRelationalTransactionMgr.h,v 1.3 2008-11-04 11:52:10 avalassi Exp $
+#ifndef RELATIONALCOOL_IRELATIONALTRANSACTIONMGR_H
+#define RELATIONALCOOL_IRELATIONALTRANSACTIONMGR_H
+
+namespace cool {  
+  
+  /** @class IRelationalTransactionMgr IRelationalTransactionMgr.h
+   *  
+   *  Abstract interface for a manager of relational database transactions.
+   * 
+   *  @author Andrea Valassi
+   *  @date   2006-03-10
+  */
+  
+  class IRelationalTransactionMgr {
+    
+    friend class RelationalTransaction;
+    
+  public:
+
+    /// Destructor
+    virtual ~IRelationalTransactionMgr() {};
+
+    /// Is the transaction active?
+    virtual bool isActive() = 0;
+  
+    virtual void setAutoTransactions( bool flag ) = 0;
+    virtual bool autoTransactions() const = 0;
+
+  //protected:
+
+    /// Start a transaction
+    virtual void start( bool readOnly ) = 0;
+    
+    /// Commit a transaction
+    virtual void commit() = 0;
+    
+    /// Rollback a transaction
+    virtual void rollback() = 0;
+
+  };
+  
+}
+
+#endif // RELATIONALCOOL_RELATIONALTRANSACTIONMGR_H
+
diff --git a/RelationalCool/src/IteratorException.h b/RelationalCool/src/IteratorException.h
new file mode 100644
index 000000000..568397a3c
--- /dev/null
+++ b/RelationalCool/src/IteratorException.h
@@ -0,0 +1,150 @@
+// $Id: IteratorException.h,v 1.6 2007-03-30 15:48:15 avalassi Exp $
+#ifndef RELATIONALCOOL_ITERATOREXCEPTION_H 
+#define RELATIONALCOOL_ITERATOREXCEPTION_H 1
+
+// Include files
+#include "CoolKernel/Exception.h"
+
+namespace cool 
+{
+  //--------------------------------------------------------------------------
+
+  /** @class IteratorHasNotStarted
+   *
+   *  Exception thrown when an invalid operation is attempted on an iterator 
+   *  that has not been started yet.
+   *  
+   */
+  
+  class IteratorHasNotStarted : public Exception {
+    
+  public:
+    
+    /// Constructor
+    explicit IteratorHasNotStarted( const std::string& methodName ) 
+      : Exception( "The iterator has not been started yet", methodName ) {}
+    
+    /// Destructor
+    virtual ~IteratorHasNotStarted() throw() {}
+    
+  };
+  
+  //--------------------------------------------------------------------------
+
+  /** @class IteratorIsActive
+   *
+   *  Exception thrown when an invalid operation is attempted on an iterator 
+   *  that has already retrieved some rows.
+   *  
+   */
+  
+  class IteratorIsActive : public Exception {
+    
+  public:
+    
+    /// Constructor
+    explicit IteratorIsActive( const std::string& methodName ) 
+      : Exception
+    ( "The iterator has already retrieved some rows and cannot be reused",
+      methodName ) {}
+    
+    /// Destructor
+    virtual ~IteratorIsActive() throw() {}
+    
+  };
+  
+  //--------------------------------------------------------------------------
+
+  /** @class IteratorIsClosed
+   *
+   *  Exception thrown when an invalid operation is attempted on an iterator 
+   *  that has already ben closed.
+   *  
+   */
+  
+  class IteratorIsClosed : public Exception {
+    
+  public:
+    
+    /// Constructor
+    explicit IteratorIsClosed( const std::string& methodName ) 
+      : Exception( "The iterator has already been closed and cannot be reused",
+      methodName ) {}
+    
+    /// Destructor
+    virtual ~IteratorIsClosed() throw() {}
+    
+  };
+  
+  //--------------------------------------------------------------------------
+
+  /** @class IteratorHasNoCurrentItem
+   *
+   *  Exception thrown when attempting to retrieve the current item from an 
+   *  iterator with no current item.
+   *  
+   */
+  
+  class IteratorHasNoCurrentItem : public Exception {
+    
+  public:
+    
+    /// Constructor
+    explicit IteratorHasNoCurrentItem( const std::string& methodName ) 
+      : Exception( "The iterator has no current item", methodName ) {}
+    
+    /// Destructor
+    virtual ~IteratorHasNoCurrentItem() throw() {}
+    
+  };
+  
+  //--------------------------------------------------------------------------
+
+  /** @class IteratorHasNoNextItem
+   *
+   *  Exception thrown when attempting to retrieve the next item from an 
+   *  iterator with no next item.
+   *  
+   */
+  
+  class IteratorHasNoNextItem : public Exception {
+    
+  public:
+    
+    /// Constructor
+    explicit IteratorHasNoNextItem( const std::string& methodName ) 
+      : Exception( "The iterator has no next item", methodName ) {}
+    
+    /// Destructor
+    virtual ~IteratorHasNoNextItem() throw() {}
+    
+  };
+  
+  //--------------------------------------------------------------------------
+
+  /** @class TooManyIterators
+   *
+   *  Exception thrown when attempting to use two 'live' iterators
+   *  at the same time (this would keep two open server cursors).
+   *  
+   */
+  
+  class TooManyIterators : public Exception {
+    
+  public:
+    
+    /// Constructor
+    explicit TooManyIterators( const std::string& methodName ) 
+      : Exception( "An iterator is already open in this IDatabase", 
+                   methodName ) {}
+    
+    /// Destructor
+    virtual ~TooManyIterators() throw() {}
+    
+  };
+  
+  //--------------------------------------------------------------------------
+
+}
+
+#endif // RELATIONALCOOL_ITERATOREXCEPTION_H
diff --git a/RelationalCool/src/ManualTransaction.cpp b/RelationalCool/src/ManualTransaction.cpp
new file mode 100644
index 000000000..8082c492e
--- /dev/null
+++ b/RelationalCool/src/ManualTransaction.cpp
@@ -0,0 +1,61 @@
+// $Id: ManualTransaction.cpp,v 1.4 2009-01-06 12:30:07 avalassi Exp $
+#ifdef COOL280
+
+// Include files
+#include <string>
+#include <iostream>
+
+// Local include files
+#include "IRelationalTransactionMgr.h"
+#include "ManualTransaction.h"
+
+// Namespace
+using namespace cool;
+
+//-----------------------------------------------------------------------------
+
+ManualTransaction::ManualTransaction
+( const boost::shared_ptr<IRelationalTransactionMgr>& transactionMgr,
+  bool readOnly )
+  : m_transactionMgr( transactionMgr ) 
+{
+  std::string msg;
+  if( readOnly ) msg = "read-only transaction";
+  else msg = "read-write transaction";  
+  m_transactionMgr->start( readOnly );
+}
+
+//-----------------------------------------------------------------------------
+
+ManualTransaction::~ManualTransaction() 
+{
+  rollback();
+}
+
+//-----------------------------------------------------------------------------
+
+void ManualTransaction::commit() 
+{
+  // reset the transaction manager to auto-transaction mode -- this needs
+  // to be done first, because the commit would otherwise be ignored
+  m_transactionMgr->setAutoTransactions( true );
+  if ( m_transactionMgr->isActive() ) {
+    m_transactionMgr->commit();
+  }
+}
+
+//-----------------------------------------------------------------------------
+
+void ManualTransaction::rollback() 
+{
+  // reset the transaction manager to auto-transaction mode -- this needs
+  // to be done first, because the rollback would otherwise be ignored
+  m_transactionMgr->setAutoTransactions( true );
+  if ( m_transactionMgr->isActive() ) {
+    m_transactionMgr->rollback();
+  }
+}
+
+//-----------------------------------------------------------------------------
+
+#endif
diff --git a/RelationalCool/src/ManualTransaction.h b/RelationalCool/src/ManualTransaction.h
new file mode 100644
index 000000000..4bc24ea65
--- /dev/null
+++ b/RelationalCool/src/ManualTransaction.h
@@ -0,0 +1,58 @@
+// $Id: ManualTransaction.h,v 1.5 2009-01-06 12:30:07 avalassi Exp $
+#ifndef RELATIONALCOOL_MANUALTRANSACTION_H 
+#define RELATIONALCOOL_MANUALTRANSACTION_H
+
+#ifdef COOL280
+
+// Include files
+#include <boost/shared_ptr.hpp>
+#include "CoolKernel/ITransaction.h"
+
+namespace cool 
+{
+  
+  // Forward declaration
+  class IRelationalTransactionMgr;
+
+  class ManualTransaction : public ITransaction 
+  {
+    
+  public:
+    
+    /// Destructor
+    virtual ~ManualTransaction();
+    
+    /// Constructor from a IRelationalTransactionMgr
+    ManualTransaction
+    ( const boost::shared_ptr<IRelationalTransactionMgr>& transactionMgr,
+      bool readOnly = false );
+    
+    /// Commit the transaction *and* re-enable auto-transaction mode
+    void commit();
+    
+    /// Rollback the transaction *and* re-enable auto-transaction mode
+    void rollback();
+    
+  private:
+    
+    /// Standard constructor is private
+    ManualTransaction();
+    
+    /// Copy constructor is private
+    ManualTransaction( const ManualTransaction& rhs );
+    
+    /// Assignment operator is private
+    ManualTransaction& operator=( const ManualTransaction& rhs );
+
+  private:
+      
+    /// Handle to the IRelationalTransactionMgr (shared ownership)
+    boost::shared_ptr<IRelationalTransactionMgr> m_transactionMgr;
+    
+  };
+  
+} // namespace
+
+#endif
+
+#endif
diff --git a/RelationalCool/src/ObjectId.cpp b/RelationalCool/src/ObjectId.cpp
new file mode 100644
index 000000000..2b6282aaf
--- /dev/null
+++ b/RelationalCool/src/ObjectId.cpp
@@ -0,0 +1,94 @@
+// $Id: ObjectId.cpp,v 1.6 2008-11-04 11:52:10 avalassi Exp $
+
+// Include files
+#include <sstream>
+
+// Local include files
+#include "ObjectId.h"
+
+// Namespace
+namespace cool {
+
+//-----------------------------------------------------------------------------
+
+ObjectId ObjectIdHandler::userObject( const ObjectId& id ) {
+  return int((id-1)/ObjectIdIncrement)*ObjectIdIncrement+1;
+}  
+
+//-----------------------------------------------------------------------------
+
+ObjectId ObjectIdHandler::lSysObject( const ObjectId& id ) {
+  ObjectId objId = userObject( id );
+  if ( objId <= UINT_MAX -1 ) {
+    return objId + 1;
+  } else {
+    std::ostringstream msg;
+    msg << "lSysObject for '" << id << "' out of range";
+    throw ObjectIdException( msg.str() );
+  }
+}  
+
+//-----------------------------------------------------------------------------
+
+ObjectId ObjectIdHandler::rSysObject( const ObjectId& id ) {
+  ObjectId objId = userObject( id );
+  if ( objId <= UINT_MAX -2 ) {
+    return objId + 2;
+  } else {
+    std::ostringstream msg;
+    msg << "rSysObject for '" << id << "' out of range";
+    throw ObjectIdException( msg.str() );
+  }
+}  
+
+//-----------------------------------------------------------------------------
+
+bool ObjectIdHandler::isUserObject( const ObjectId& id ) {
+  return ( id == userObject(id) );
+}  
+
+//-----------------------------------------------------------------------------
+
+bool ObjectIdHandler::isLSysObject( const ObjectId& id ) {
+  return ( id == lSysObject(id) );
+}  
+
+//-----------------------------------------------------------------------------
+
+bool ObjectIdHandler::isRSysObject( const ObjectId& id ) {
+  return ( id == rSysObject(id) );
+}  
+
+//-----------------------------------------------------------------------------
+
+bool ObjectIdHandler::isSysObject( const ObjectId& id ) {
+  return ( isLSysObject(id) || isRSysObject(id) );
+}  
+
+//-----------------------------------------------------------------------------
+
+ObjectId ObjectIdHandler::nextUserObject( const ObjectId& id ) {
+  ObjectId objId = userObject( id );
+  if ( objId <= UINT_MAX - ObjectIdIncrement ) {
+    return objId + ObjectIdIncrement;
+  } else {
+    std::ostringstream msg;
+    msg << "next object id for '" << id << "' out of range";
+    throw ObjectIdException( msg.str() );
+  }
+}  
+
+//-----------------------------------------------------------------------------
+
+ObjectId ObjectIdHandler::prevUserObject( const ObjectId& id ) {
+  if ( userObject(id) <= ObjectIdIncrement ) {      
+    std::ostringstream msg;
+    msg << "ObjectId '" << id << "' has no previous user object";
+    throw ObjectIdException( msg.str() );
+  }    
+  return userObject(id) - ObjectIdIncrement;
+}  
+
+//-----------------------------------------------------------------------------
+
+} // namespace
diff --git a/RelationalCool/src/ObjectId.h b/RelationalCool/src/ObjectId.h
new file mode 100644
index 000000000..39fe3debd
--- /dev/null
+++ b/RelationalCool/src/ObjectId.h
@@ -0,0 +1,95 @@
+// $Id: ObjectId.h,v 1.9 2008-11-04 11:49:37 avalassi Exp $
+#ifndef RELATIONALCOOL_OBJECTID_H 
+#define RELATIONALCOOL_OBJECTID_H 1
+
+// Include files
+#include "CoolKernel/Exception.h"
+
+namespace cool 
+{
+  
+  /** @class ObjectId ObjectId.h
+   *  
+   *  This file summarises the objectId numbering scheme assumptions.
+   *
+   *  Presently ObjectId is typedefed to an unsigned int.
+   *  Eventually ObjectId may be changed to a pair of unsigned int or 
+   *  something else.
+   *
+   *  Presently this is only used in the RalDatabase "tagAsOfObjectId" 
+   *  implementation. Eventually this should be used as the unique source 
+   *  for the numbering schema.
+   *
+   *  Presently even the typedef is only used in the RalDatabase 
+   *  "tagAsOfObjectId". Eventually all code manipulating objectId's should 
+   *  use the typedef.
+   *
+   *  @author Andrea Valassi and Sven A. Schmidt
+   *  @date   2005-04-05
+   */ 
+ 
+  typedef unsigned int ObjectId;
+
+  const unsigned int ObjectIdIncrement = 6;
+  
+  class ObjectIdTest;
+  
+  namespace ObjectIdHandler {    
+
+    /// Returns true if the given id belongs to a user object
+    bool isUserObject( const ObjectId& id );
+    
+    /// Returns true if the given id belongs to a "left inserted"
+    /// system object
+    bool isLSysObject( const ObjectId& id );
+
+    /// Returns true if the given id belongs to a "right inserted"
+    /// system object
+    bool isRSysObject( const ObjectId& id );
+    
+    /// Returns true if the given id belongs to a system object
+    bool isSysObject( const ObjectId& id );
+
+    /// Transforms a given id into a user object id
+    ObjectId userObject( const ObjectId& id );
+
+    /// Transforms a given id into a "left inserted" system object id
+    /// Throws an ObjectIdExecption if the given id is out of bounds.
+    ObjectId lSysObject( const ObjectId& id );
+    
+    /// Transforms a given id into a "right inserted" system object id
+    /// Throws an ObjectIdExecption if the given id is out of bounds.
+    ObjectId rSysObject( const ObjectId& id );
+    
+    /// Returns a given id's previous user object id
+    /// Throws an ObjectIdExecption if the given id is out of bounds.
+    ObjectId prevUserObject( const ObjectId& id );
+
+    /// Returns a given id's next user object id
+    /// Throws an ObjectIdExecption if the given id is out of bounds.
+    ObjectId nextUserObject( const ObjectId& id );
+
+  }
+
+  
+  /** @class ObjectIdException
+   *  
+   *  Exception thrown by the ObjectIdHandler.
+   */
+
+  class ObjectIdException : public Exception {
+
+  public:
+    
+    /// Constructor
+    ObjectIdException( const std::string& message )
+      : Exception( message, "ObjectId" ) {}
+    
+    /// Destructor
+    virtual ~ObjectIdException() throw() {}
+    
+  };
+  
+}
+
+#endif // RELATIONALCOOL_OBJECTID_H
diff --git a/RelationalCool/src/ObjectIteratorCounter.cpp b/RelationalCool/src/ObjectIteratorCounter.cpp
new file mode 100644
index 000000000..db3b137d2
--- /dev/null
+++ b/RelationalCool/src/ObjectIteratorCounter.cpp
@@ -0,0 +1,150 @@
+// $Id: ObjectIteratorCounter.cpp,v 1.9 2008-09-26 23:16:47 avalassi Exp $
+
+// Include files
+#include <iostream>
+#include "CoolKernel/InternalErrorException.h"
+
+// Local include files 
+#include "IteratorException.h"
+#include "ObjectIteratorCounter.h"
+
+// Namespace
+using namespace cool;
+
+namespace {
+
+  /// @class wrapper
+  /// Minimal wrapper class that execute a unary function object
+  /// to the wrapped class instance on destruction.
+  /// @author Marco Clemencic
+  template <class obj_type, class checker_type> 
+  struct wrapper
+  {
+
+    /// Wrapped instance
+    obj_type m_obj;
+
+    /// Constructor. Simply create a default wrapped instance.
+    wrapper():m_obj(){}
+
+    /// Destructor. Call the checker object on the wrapped instance.
+    ~wrapper()
+    {
+      checker_type checker;
+      checker(m_obj);
+    }
+
+    /// Return reference to the wrapped instance.
+    inline obj_type & get() { return m_obj; }
+
+    /// Conversion to the wrapped type.
+    inline operator obj_type & () { return m_obj; }
+
+  };
+
+  /// @class ObjectIteratorCounterChecker
+  /// Checker class that verifies that the ObjectIteratorCounter map is empty
+  /// (which means all iterators deregistered).
+  /// The type of the map is in a template because the typedef
+  /// ObjectIteratorMap is private.
+  /// @author Marco Clemencic
+  template <class map_type>
+  struct ObjectIteratorCounterChecker
+  {
+    /// Checks if the ObjectIteratorCounter is empty, if not dump
+    /// the content to standard error (trigger a failure on QMtest)
+    void operator () (map_type &the_map)
+    {
+      if ( the_map.size() != 0 ) {
+        std::cerr << "ObjectIteratorCounterWatchDog: "
+                  << the_map.size()
+                  << " sessionMgrs" << std::endl;
+        typename map_type::iterator i;
+        for ( i = the_map.begin(); i != the_map.end(); ++i ){
+          std::cerr << "-> sessionMgr: " << i->first
+                    << ", iterators: "   << i->second.size() << std::endl;
+        }
+      }
+    }
+  };
+}
+
+ObjectIteratorCounter::ObjectIteratorMap& 
+ObjectIteratorCounter::openIterators()
+{
+  // static ObjectIteratorMap s_openIterators;
+  static wrapper<ObjectIteratorMap,ObjectIteratorCounterChecker<ObjectIteratorMap> >
+    s_openIterators;
+  return s_openIterators;
+}
+
+//-----------------------------------------------------------------------------
+
+void 
+ObjectIteratorCounter::registerIterator
+( const IObjectIterator* it,
+  const IRelationalTransactionMgr* sessionMgr )
+{
+  //std::cout << "Register iterator  " << it << " " << sessionMgr << std::endl;
+  if ( openIterators().find( sessionMgr ) != openIterators().end() ) 
+  {
+    //std::cout << "Counter size: " << openIterators().size() << std::endl;
+    //std::cout << "Vector size:  " 
+    //          << openIterators()[sessionMgr].size() << std::endl;
+    throw TooManyIterators( "ObjectIteratorCounter" );
+  }
+  ObjectIteratorVector itVector;
+  itVector.push_back( it );
+  openIterators()[sessionMgr] = itVector;
+}
+
+//-----------------------------------------------------------------------------
+
+void 
+ObjectIteratorCounter::unregisterIterator
+( const IObjectIterator* it,
+  const IRelationalTransactionMgr* sessionMgr )
+{
+  //std::cout << "Unregister iterator " << it << " " << sessionMgr <<std::endl;
+  // This sessionMgr is unknown?
+  if ( openIterators().find( sessionMgr ) == openIterators().end() ) 
+  {
+    throw InternalErrorException
+      ( "PANIC! The iterator is not registered"
+        " (this IRelationalTransactionMgr is unknown)", 
+        "ObjectIteratorCounter" );
+  }
+  ObjectIteratorVector& itVector = openIterators().find( sessionMgr )->second;
+
+  // No iterator for this sessionMgr?
+  if ( itVector.size() == 0 ) 
+  {
+    throw InternalErrorException
+      ( "PANIC! The iterator is not registered"
+        " (none is registered for this IRelationalTransactionMgr)", 
+        "ObjectIteratorCounter" );
+  }
+
+  // More than one iterator for this sessionMgr?
+  if ( itVector.size() > 1 ) 
+  {
+    throw InternalErrorException
+      ( "PANIC! More than one iterator is registered"
+        " for this IRelationalTransactionMgr", 
+        "ObjectIteratorCounter" );
+  }
+
+  // A different iterator is registered for this sessionMgr?
+  if ( itVector[0] != it )
+  {
+    throw InternalErrorException
+      ( "PANIC! The iterator is not registered"
+        " (a different one is registered for this IRelationalTransactionMgr)", 
+        "ObjectIteratorCounter" );
+  }
+
+  // OK: this is the only iterator registered for this sessionMgr - remove it
+  openIterators().erase( openIterators().find( sessionMgr ) );
+}
+
+//-----------------------------------------------------------------------------
diff --git a/RelationalCool/src/ObjectIteratorCounter.h b/RelationalCool/src/ObjectIteratorCounter.h
new file mode 100644
index 000000000..eecca998d
--- /dev/null
+++ b/RelationalCool/src/ObjectIteratorCounter.h
@@ -0,0 +1,58 @@
+// $Id: ObjectIteratorCounter.h,v 1.6 2008-09-26 23:16:47 avalassi Exp $
+#ifndef OBJECTITERATORCOUNTER_H 
+#define OBJECTITERATORCOUNTER_H 1
+
+// Include files
+#include <map>
+#include <vector>
+
+namespace cool 
+{
+
+  // Forward declarations
+  class IRelationalTransactionMgr;
+  class IObjectIterator;
+
+  /** @class ObjectIteratorCounter ObjectIteratorCounter.h
+   *  
+   *  Static counter of open 'live' iterators.
+   *
+   *  @author Andrea Valassi
+   *  @date   2007-03-30
+   */
+
+  class ObjectIteratorCounter {
+    
+  public: 
+
+    // Register an iterator
+    static void registerIterator( const IObjectIterator* it,
+                                  const IRelationalTransactionMgr* trMgr );
+
+    // Unregister an iterator
+    static void unregisterIterator( const IObjectIterator* it,
+                                    const IRelationalTransactionMgr* trMgr );
+
+  private:
+
+    virtual ~ObjectIteratorCounter();
+    ObjectIteratorCounter();
+    ObjectIteratorCounter( const ObjectIteratorCounter& rhs );
+    ObjectIteratorCounter& operator=( const ObjectIteratorCounter& rhs );
+
+  private:
+    
+    typedef 
+    std::vector< const IObjectIterator* > ObjectIteratorVector;
+
+    typedef 
+    std::map< const IRelationalTransactionMgr*, 
+              ObjectIteratorVector > ObjectIteratorMap;
+
+    /// List of active 'live' iterators (there should be only one!)
+    static ObjectIteratorMap& openIterators();
+
+  };
+
+}
+#endif // OBJECTITERATORCOUNTER_H
diff --git a/RelationalCool/src/ObjectVectorIterator.cpp b/RelationalCool/src/ObjectVectorIterator.cpp
new file mode 100644
index 000000000..cbc16578b
--- /dev/null
+++ b/RelationalCool/src/ObjectVectorIterator.cpp
@@ -0,0 +1,92 @@
+// $Id: ObjectVectorIterator.cpp,v 1.18 2008-11-04 11:52:10 avalassi Exp $
+
+// Include files
+#include "CoolKernel/IObject.h"
+#include "CoolKernel/types.h"
+
+// Local include files
+#include "IteratorException.h"
+#include "ObjectVectorIterator.h"
+
+// Namespace
+using namespace cool;
+
+//-----------------------------------------------------------------------------
+
+ObjectVectorIterator::ObjectVectorIterator( const IObjectVectorPtr& objects )
+  : m_objects( objects )
+  , m_size( objects->size() )
+  , m_current1toN( 0 ) 
+  , m_isClosed( false ) 
+{
+}
+
+//-----------------------------------------------------------------------------
+
+ObjectVectorIterator::~ObjectVectorIterator() 
+{
+  close();
+}
+
+//-----------------------------------------------------------------------------
+
+bool ObjectVectorIterator::isEmpty() 
+{
+  if ( m_isClosed ) throw IteratorIsClosed( "ObjectVectorIterator" );
+  return ( m_size == 0 );
+}
+
+//-----------------------------------------------------------------------------
+
+const IObject& ObjectVectorIterator::currentRef()
+{
+  if ( m_isClosed ) throw IteratorIsClosed( "ObjectVectorIterator" );
+  if ( m_current1toN < 1 ) {
+    throw Exception( "Current position is before the first object in the loop",
+                     "ObjectVectorIterator" );
+  } else if ( m_current1toN > m_size ) {
+    throw Exception( "Current position is after the last object in the loop",
+                     "ObjectVectorIterator" );
+  } else {
+    return *(*m_objects)[m_current1toN-1];
+  }  
+}
+
+//-----------------------------------------------------------------------------
+
+bool ObjectVectorIterator::goToNext()
+{
+  if ( m_isClosed ) throw IteratorIsClosed( "ObjectVectorIterator" );
+  if ( ( m_current1toN < m_size ) ) {
+        m_current1toN++;
+        return true;
+  }
+  return false;
+}
+
+//-----------------------------------------------------------------------------
+
+unsigned int ObjectVectorIterator::size() 
+{
+  if ( m_isClosed ) throw IteratorIsClosed( "ObjectVectorIterator" );
+  return m_size;
+}
+
+//-----------------------------------------------------------------------------
+
+const IObjectVectorPtr ObjectVectorIterator::fetchAllAsVector() 
+{
+  if ( m_isClosed ) throw IteratorIsClosed( "ObjectVectorIterator" );
+  if ( m_current1toN > 0 ) throw IteratorIsActive( "ObjectVectorIterator" );
+  return m_objects;
+}
+
+//-----------------------------------------------------------------------------
+
+void ObjectVectorIterator::close() 
+{
+  m_isClosed = true;
+}
+
+//-----------------------------------------------------------------------------
+
diff --git a/RelationalCool/src/ObjectVectorIterator.h b/RelationalCool/src/ObjectVectorIterator.h
new file mode 100644
index 000000000..616150acb
--- /dev/null
+++ b/RelationalCool/src/ObjectVectorIterator.h
@@ -0,0 +1,85 @@
+// $Id: ObjectVectorIterator.h,v 1.21 2008-11-04 11:52:10 avalassi Exp $
+#ifndef RELATIONALCOOL_OBJECTVECTORITERATOR_H
+#define RELATIONALCOOL_OBJECTVECTORITERATOR_H
+
+// Include files
+#include "CoolKernel/IObjectIterator.h"
+
+namespace cool {
+  
+  /** @class ObjectVectorIterator ObjectVectorIterator.h
+   *  
+   *  Vector implementation of a COOL condition database object iterator.
+   *
+   *  Useful for the simplest implementation of object retrieval from 
+   *  the database: retrieving an iterator over the objects in a folder 
+   *  immediately retrieves the full vector of objects.
+   *
+   *  @author Andrea Valassi and Sven A. Schmidt
+   *  @date   2004-12-13
+   */
+  
+  class ObjectVectorIterator : public IObjectIterator {
+
+  public:
+    
+    /// Constructor from a shared pointer to a vector of objects.
+    /// The iterator is positioned BEFORE its first element.
+    ObjectVectorIterator( const IObjectVectorPtr& objects );
+
+    /// Destructor.
+    virtual ~ObjectVectorIterator();
+
+    /// Does the iterator have zero objects in the loop?
+    bool isEmpty();
+
+    /// Fetch the next object in the iterator loop.
+    /// Return false if there is no next object.
+    bool goToNext();
+
+    /// Retrieve a reference to the current object in the iterator loop.
+    /// NB The reference is only valid until next() or goToNext() is called!
+    /// Throw an exception if there is no current object (because the iterator
+    /// is empty or is positioned before the first object in the loop).
+    const IObject& currentRef();
+
+    /// Returns the 'length' of the iterator.
+    unsigned int size();
+
+    /// Returns all objects in the iterator as a vector.
+    const IObjectVectorPtr fetchAllAsVector();
+
+    /// Close the iterator and release any associated server resources.
+    /// The iterator cannot be used any more after this method is called.
+    void close();
+    
+  private:
+
+    /// Standard constructor is private.
+    ObjectVectorIterator();
+
+    /// Copy constructor is private
+    ObjectVectorIterator( const ObjectVectorIterator& rhs );
+
+    /// Assignment operator is private
+    ObjectVectorIterator& operator=( const ObjectVectorIterator& rhs );
+
+  private:
+
+    /// Vector of objects
+    IObjectVectorPtr m_objects;
+    
+    /// Size of the vector of objects
+    unsigned int m_size;
+    
+    /// Current position in the loop
+    unsigned int m_current1toN;
+
+    /// Has the close() method been called?
+    bool m_isClosed;
+
+  };  
+
+}
+
+#endif //RELATIONALCOOL_OBJECTVECTORITERATOR_H
diff --git a/RelationalCool/src/ProcMemory.h b/RelationalCool/src/ProcMemory.h
new file mode 100644
index 000000000..a49944bef
--- /dev/null
+++ b/RelationalCool/src/ProcMemory.h
@@ -0,0 +1,197 @@
+// Include files
+#include <cstdlib>  // for atol
+#include <iostream> // for cout
+#include <sstream>  // for stringstream
+
+class ProcMemory {
+
+public:
+
+  ProcMemory() {
+    m_pid = getProcessId();
+  }
+
+  ~ProcMemory() {}
+
+  void printVm();  
+
+  long getProcessId();  
+
+  long getVsz();  
+  long getRss();  
+  long getProcStatus( const std::string& key );
+
+private:
+
+  int m_pid;
+
+};
+
+//----------------------------------------------------------------------------
+
+inline void ProcMemory::printVm() {
+  long vsz = getVsz();
+  long rss = getRss();
+  std::cout << "VSZ=" << vsz << " RSS=" << rss << std::endl;
+}
+  
+//----------------------------------------------------------------------------
+
+// WINDOWS - see http://msdn2.microsoft.com/en-us/library/t2y34y40
+#ifdef WIN32
+
+#include <process.h>
+inline long ProcMemory::getProcessId() {
+  return _getpid();
+}
+
+// OSX and LINUX
+#else
+
+#include <sys/types.h>
+#include <unistd.h>
+inline long ProcMemory::getProcessId() {
+  return getpid();
+}
+
+#endif
+
+//----------------------------------------------------------------------------
+
+// WINDOWS
+#ifdef WIN32
+
+// For ifstream
+#include <fstream>
+
+inline long ProcMemory::getVsz() {
+  return getProcStatus( "VmSize" );
+}
+
+inline long ProcMemory::getRss() {
+  return getProcStatus( "VmRSS" );
+}
+
+// NB To get rid of the annoying messages "UNC not supported",
+// add a DWORD registry key (hex value 1) called DisableUNCCheck to
+// HKCU\Software\Microsoft\Command Processor.
+// See http://weblogs.asp.net/kdente/archive/2004/01/30/65232.aspx
+
+// NB A non-cygwin alternative for Windows could be to use "tlist":
+// this is only available after installing the Windows XP Support Tools.
+// See http://emea.windowsitpro.com/Article/ArticleID/43569/43569.html?Ad=1
+// See http://www.ss64.com/nt/tlist.html
+
+// NB Another simple non-cygwin alternative could be to use "tasklist":
+// however, this only provides the VmRSS value, which is much less
+// interesting than the VmSize value (only VmSize is affected by malloc).
+
+inline long ProcMemory::getProcStatus( const std::string& key ) {
+  long value = -1;
+  std::stringstream cmd;
+  cmd << "ps | gawk '{if ($4 == " << m_pid 
+      << ") {cmd=\"cat /proc/\"$1\"/status\"; system(cmd)}}'"
+      << " | grep " << key;
+  const int kMaxSize = 256;
+  char line[kMaxSize];
+  FILE* input_stream = _popen( cmd.str().c_str(), "r" );
+  if ( fgets( line, kMaxSize, input_stream ) == NULL ) {
+    //std::cout << "Error while getting status" << std::endl;
+  } else {
+    //std::cout << "line: " << line << std::endl;
+    std::string lineStr = line;
+    if( lineStr.substr(0,key.size()+1) == (key+":") ) {
+      lineStr = lineStr.substr(key.size()+2,lineStr.size()-key.size()-2-3);
+      value = atol(lineStr.c_str());
+    }          
+  }
+  _pclose( input_stream );
+  return value;
+}
+
+//----------------------------------------------------------------------------
+
+// OSX
+#elif defined(__APPLE__)
+
+inline long ProcMemory::getVsz() {
+  return getProcStatus( "vsz" );
+}
+
+inline long ProcMemory::getRss() {
+  return getProcStatus( "rss" );
+}
+
+inline long ProcMemory::getProcStatus( const std::string& key ) {
+  const int kMaxSize = 256;
+  char line[kMaxSize];
+  long value = -1;
+  std::stringstream cmd;
+  cmd << "ps -p " << m_pid << " -o " << key << "| grep -iv " << key;
+  FILE* input_stream = popen( cmd.str().c_str(), "r" );
+  if ( fgets( line, kMaxSize, input_stream ) == NULL ) {
+    //std::cout << "Error while getting status" << std::endl;
+  } else {
+    //std::cout << "Line: " << line << std::endl;
+    value = atol( line );
+  }
+  pclose( input_stream );
+  return value;
+}
+
+//----------------------------------------------------------------------------
+
+// LINUX
+#else
+
+// For getpid()
+#include <sys/types.h>
+#include <unistd.h>
+
+// For ifstream
+#include <fstream>
+
+inline long ProcMemory::getVsz() {
+  return getProcStatus( "VmSize" );
+}
+
+inline long ProcMemory::getRss() {
+  return getProcStatus( "VmRSS" );
+}
+
+inline long ProcMemory::getProcStatus( const std::string& key ) {
+  long value = -1;
+  std::stringstream fileName;
+  fileName << "/proc/" << m_pid << "/status";
+  std::ifstream proc( fileName.str().c_str() );
+  if( !proc ) {
+    std::cout << "Error opening " << fileName.str() << std::endl;
+  } else {
+    char ch;
+    std::string line;      
+    while( proc.get(ch) ) {
+      if ( ch != '\n' ) {
+        line += ch;
+      } else {
+        if( line.substr(0,key.size()+1) == (key+":") ) {
+          line = line.substr(key.size()+2,line.size()-key.size()-2-3);
+          //std::cout << "Line: " << line << std::endl;
+          value = atol(line.c_str());            
+        }          
+        line = "";
+      }
+    }
+    if( !proc.eof() ) {        
+      std::cout << "Error while reading " << fileName.str() << std::endl;
+    } else {
+      //std::cout << "EOF " << fileName.str() << std::endl;   
+    }      
+  }
+  //std::cout << key << ": " << value << std::endl;
+  return value;
+}
+  
+#endif
+
+//----------------------------------------------------------------------------
+
diff --git a/RelationalCool/src/RalBulkOperation.h b/RelationalCool/src/RalBulkOperation.h
new file mode 100644
index 000000000..33f02c6dc
--- /dev/null
+++ b/RelationalCool/src/RalBulkOperation.h
@@ -0,0 +1,56 @@
+#ifndef RELATIONALCOOL_RALBULKOPERATION_H
+#define RELATIONALCOOL_RALBULKOPERATION_H
+
+// Include files
+#include <boost/shared_ptr.hpp>
+#include "RelationalAccess/IBulkOperation.h"
+
+// Local include files
+#include "IRelationalBulkOperation.h"
+
+namespace cool {
+
+  /**
+   * Class RalBulkOperation
+   *
+   * Wrapper for a coral::IBulkOperation.
+   *
+   */
+
+  class RalBulkOperation : public IRelationalBulkOperation {
+
+  public:
+
+    /// Destructor
+    virtual ~RalBulkOperation() {}
+
+    /// Constructor
+    RalBulkOperation( const boost::shared_ptr<coral::IBulkOperation> bulkOp )
+      : m_bulkOperation( bulkOp ) {}
+
+    /// Processes the next iteration
+    void processNextIteration() 
+    {
+      m_bulkOperation->processNextIteration();
+    }    
+    
+    /// Flushes the data on the client side to the server.
+    void flush()
+    {
+      m_bulkOperation->flush();
+    }
+
+  private:
+
+    RalBulkOperation();
+    RalBulkOperation( const RalBulkOperation& );
+    RalBulkOperation& operator=( const RalBulkOperation& );    
+
+  private:
+    
+    boost::shared_ptr<coral::IBulkOperation> m_bulkOperation;
+
+  };
+
+}
+#endif
diff --git a/RelationalCool/src/RalCursor.h b/RelationalCool/src/RalCursor.h
new file mode 100644
index 000000000..30ebd236e
--- /dev/null
+++ b/RelationalCool/src/RalCursor.h
@@ -0,0 +1,71 @@
+#ifndef RELATIONALCOOL_RALCURSOR_H
+#define RELATIONALCOOL_RALCURSOR_H
+
+// Include files
+#include <memory>
+#include "RelationalAccess/ICursor.h"
+#include "RelationalAccess/IQuery.h"
+
+// Local include files
+#include "IRelationalCursor.h"
+//#include "RalQueryMgr.h" // for TimingReport
+
+namespace cool 
+{
+
+  /**
+   * Class RalCursor
+   *
+   * Wrapper for a coral::ICursor.
+   *
+   */
+
+  class RalCursor : public IRelationalCursor {
+
+  public:
+
+    /// Destructor
+    virtual ~RalCursor() {}
+
+    /// Constructor from a CORAL query.
+    /// The constructor takes ownership of the query and executes it.
+    RalCursor( std::auto_ptr<coral::IQuery> query )
+      : m_query( query )
+      , m_cursor( m_query->execute() ) {}
+    //, m_cursor( RalQueryMgr::executeQuery(*m_query) ) {} // with TimingReport
+
+    /// Positions the cursor to the next available row in the result set.
+    /// If there are no more rows in the result set false is returned.
+    bool next()
+    {
+      return m_cursor.next();
+      //return RalQueryMgr::cursorNext( m_cursor ); // with TimingReport
+    }    
+    
+    /// Returns a reference to the output buffer holding the last row fetched.
+    const coral::AttributeList& currentRow() const
+    {
+      return m_cursor.currentRow();
+    }
+    
+    /// Explicitly closes the cursor, releasing the resources on the server.
+    void close()
+    {
+      return m_cursor.close();
+    }
+
+  private:
+
+    RalCursor();
+    RalCursor( const RalCursor& );
+    RalCursor& operator=( const RalCursor& );    
+
+  private:
+    
+    std::auto_ptr<coral::IQuery> m_query;
+    coral::ICursor& m_cursor;
+
+  };
+
+}
+#endif
diff --git a/RelationalCool/src/RalDatabase.cpp b/RelationalCool/src/RalDatabase.cpp
new file mode 100644
index 000000000..4530672d5
--- /dev/null
+++ b/RelationalCool/src/RalDatabase.cpp
@@ -0,0 +1,1479 @@
+// $Id: RalDatabase.cpp,v 1.607 2009-01-06 12:30:07 avalassi Exp $
+
+// Include files
+#include <sstream>
+#include "CoolKernel/ChannelSelection.h"
+#include "HvsTagRecord.h"
+#include "CoolKernel/Record.h"
+#include "CoolKernel/ValidityKey.h"
+#include "CoralBase/Exception.h"
+#include "RelationalAccess/IBulkOperation.h"
+#include "RelationalAccess/ISchema.h"
+#include "RelationalAccess/ITable.h"
+#include "RelationalAccess/ITableDataEditor.h"
+#include "RelationalAccess/SchemaException.h"
+
+// Local include files
+#include "DummyTransactionMgr.h"
+#include "HvsPathHandler.h"
+#include "HvsPathHandlerException.h"
+#include "ManualTransaction.h"
+#include "ObjectId.h"
+#include "RalDatabase.h"
+#include "RalQueryMgr.h"
+#include "RalSchemaMgr.h"
+#include "RalSessionMgr.h"
+#include "RalTransactionMgr.h"
+#include "RelationalChannelTable.h"
+#include "RelationalDatabaseId.h"
+#include "RelationalDatabaseTable.h"
+#include "RelationalException.h"
+#include "RelationalFolder.h"
+#include "RelationalFolderUnsupported.h"
+#include "RelationalFolderSet.h"
+#include "RelationalFolderSetUnsupported.h"
+#include "RelationalNodeMgr.h"
+#include "RelationalNodeTable.h"
+#include "RelationalGlobalTagTable.h"
+#include "RelationalObject.h"
+#include "RelationalObjectMgr.h"
+#include "RelationalObjectTable.h"
+#include "RelationalObjectTableRow.h"
+#include "RelationalObject2TagTable.h"
+#include "RelationalSequence.h"
+#include "RelationalSequenceMgr.h"
+#include "RelationalTableRow.h"
+#include "RelationalTagMgr.h"
+#include "RelationalTagSequence.h"
+#include "RelationalTagTable.h"
+#include "RelationalTag2TagTable.h"
+#include "RelationalTransaction.h"
+#include "SimpleObject.h"
+#include "TimingReportMgr.h"
+#include "VersionInfo.h"
+#include "attributeListToString.h"
+#include "sleep.h"
+#include "timeToString.h"
+#include "uppercaseString.h"
+
+// Additional VersionInfo specific to RalDatabase.cpp
+namespace cool
+{
+  namespace VersionInfo {
+    const std::string cvsCheckout = "$Name: not supported by cvs2svn $";
+    const std::string cvsCheckin = "$Id: RalDatabase.cpp,v 1.607 2009-01-06 12:30:07 avalassi Exp $";
+  }
+}
+
+// Namespace
+using namespace cool;
+
+// Local type definitions
+typedef boost::shared_ptr<RelationalSequence> RelationalSequencePtr;
+
+//-----------------------------------------------------------------------------
+
+RalDatabase::RalDatabase( CoralConnectionServiceProxyPtr ppConnSvc,
+                          const DatabaseId& dbId,
+                          bool readOnly )
+  : RelationalDatabase( dbId )
+  , m_useTimeout( true )
+  , m_sessionMgr( new RalSessionMgr( ppConnSvc, dbId, readOnly ) )
+{
+  std::string ro = ( readOnly ? "R/O" : "R/W" );
+  log() << coral::Info << "Instantiate a " << ro << " RalDatabase for '" 
+        << databaseId() << "'" << coral::MessageStream::endmsg;
+
+  // Create a new relational query manager
+  setQueryMgr( std::auto_ptr<RelationalQueryMgr>
+               ( new RalQueryMgr( sessionMgr() ) ) );
+  
+  // Create a new relational schema manager
+  setSchemaMgr( std::auto_ptr<RelationalSchemaMgr>
+                ( new RalSchemaMgr( *this, sessionMgr() ) ) );
+  
+  // Create a new relational node manager
+  setNodeMgr( std::auto_ptr<RelationalNodeMgr>
+              ( new RelationalNodeMgr( *this ) ) );
+  
+  // Create a new relational tag manager
+  setTagMgr( std::auto_ptr<RelationalTagMgr>
+             ( new RelationalTagMgr( *this ) ) );
+  
+  // Create a new object manager
+  setObjectMgr( std::auto_ptr<RelationalObjectMgr>
+                ( new RelationalObjectMgr( *this ) ) );
+
+  // Create a new relational transaction manager
+  // For read-only connections, a single R/O transaction is started
+  // by the RalSessionMgr for the duration of the database connection:
+  // all other clients use a dummy transaction manager!
+  //if ( !readOnly )
+  if ( !readOnly || getenv ( "COOL_READONLYSESSION_MANYTRANSACTIONS" ) )
+  {
+    setTransactionMgr( boost::shared_ptr<IRelationalTransactionMgr>
+                       ( new RalTransactionMgr( sessionMgr() ) ) );
+  }
+  else
+  {
+    setTransactionMgr( boost::shared_ptr<IRelationalTransactionMgr>
+                       ( new DummyTransactionMgr() ) );    
+  }
+  
+  // Initialize timing reports
+  if ( getenv ( "COOL_TIMINGREPORT" ) )
+  {
+    TimingReportMgr::initialize();
+    TimingReportMgr::startTimer( "TOTAL [cool::RalDatabase]" );
+  }
+}
+
+//-----------------------------------------------------------------------------
+
+RalDatabase::~RalDatabase() 
+{
+  log() << coral::Info << "Delete the RalDatabase for '" 
+        << databaseId() << "'" << coral::MessageStream::endmsg;
+
+  // Loop over all nodes in the node map
+  for ( std::map<std::string,RelationalTableRow*>::const_iterator
+          row = m_nodes.begin(); row != m_nodes.end(); ++row ) 
+  {
+    delete row->second;
+  }
+  
+  // Finalize timing reports
+  if ( TimingReportMgr::isActive() ) {
+    TimingReportMgr::stopTimer( "TOTAL [cool::RalDatabase]" );
+    TimingReportMgr::finalize();
+  }
+}
+
+//-----------------------------------------------------------------------------
+
+void RalDatabase::createDatabase( const IRecord& dbAttr ) 
+{
+  std::string dbName = databaseName();
+  log() << "Create a new database with name " << dbName 
+        << coral::MessageStream::endmsg;
+
+  // Check if the database attribute specification is valid
+  if ( dbAttr.specification() != databaseAttributesSpecification() )
+    throw RelationalException
+        ( "Invalid database attributes specification", "RalDatabase" );
+  m_dbAttr = dbAttr;
+
+  // Add release and schema related attributes
+  m_dbAttr[RelationalDatabaseTable::attributeNames::release].setValue
+    <RelationalDatabaseTable::columnTypes::attributeValue>
+    ( VersionInfo::release );
+  m_dbAttr[RelationalDatabaseTable::attributeNames::cvsCheckout].setValue
+    <RelationalDatabaseTable::columnTypes::attributeValue>
+    ( VersionInfo::cvsCheckout );
+  m_dbAttr[RelationalDatabaseTable::attributeNames::cvsCheckin].setValue
+    <RelationalDatabaseTable::columnTypes::attributeValue>
+    ( VersionInfo::cvsCheckin );
+  m_dbAttr[RelationalDatabaseTable::attributeNames::schemaVersion].setValue
+    <RelationalDatabaseTable::columnTypes::attributeValue>
+    ( VersionInfo::schemaVersion );
+
+  // TEMPORARY? AV 04.04.2005
+  // FIXME: you should check here that the default prefix is not longer
+  // than 8 characters and is already uppercase.
+  // FIXME: you should check here that the table names are all uppercase
+  // and not longer than the maximum allowed Oracle/MySQL limits.
+
+  // Start a read-write transaction
+  RelationalTransaction transaction( transactionMgr() );
+
+  // Get the name of the main management table, create it and fill it
+  schemaMgr().createMainTable( mainTableName() );
+  schemaMgr().fillMainTable( mainTableName(), m_dbAttr.attributeList() );
+
+  /*
+  // *** START *** 3.0.0 schema extensions (task #4307)
+  // Get the name of the iovTables table and create it
+  std::string iovTablesTableName =
+    dbAttr[RelationalDatabaseTable::attributeNames::iovTablesTableName].
+    data<std::string>();
+  schemaMgr().createIovTablesTable( iovTablesTableName );
+
+  // Get the name of the channelTables table and create it
+  std::string channelTablesTableName =
+    dbAttr[RelationalDatabaseTable::attributeNames::channelTablesTableName].
+    data<std::string>();
+  schemaMgr().createChannelTablesTable( channelTablesTableName );
+  // **** END **** 3.0.0 schema extensions (task #4307)
+  */
+
+  // Get the name of the node table and create it
+  std::string nodeTableName =
+    dbAttr[RelationalDatabaseTable::attributeNames::nodeTableName].
+    data<std::string>();
+  std::string defaultTablePrefix =
+    dbAttr[RelationalDatabaseTable::attributeNames::defaultTablePrefix].
+    data<std::string>();
+  schemaMgr().createNodeTable( nodeTableName, defaultTablePrefix );
+
+  // Get the name of the tag table and create it
+  std::string tagTableName =
+    dbAttr[RelationalDatabaseTable::attributeNames::tagTableName].
+    data<std::string>();
+  schemaMgr().createGlobalTagTable( tagTableName, nodeTableName );
+
+  /*
+  // *** START *** 3.0.0 schema extensions (task #4396)
+  // Get the name of the head tag table and create it
+  std::string headTagTableName =
+    dbAttr[RelationalDatabaseTable::attributeNames::headTagTableName].
+    data<std::string>();
+  schemaMgr().createGlobalHeadTagTable( headTagTableName, tagTableName );
+
+  // Get the name of the user tag table and create it
+  std::string userTagTableName =
+    dbAttr[RelationalDatabaseTable::attributeNames::userTagTableName].
+    data<std::string>();
+  schemaMgr().createGlobalUserTagTable( userTagTableName, tagTableName );
+  // **** END **** 3.0.0 schema extensions (task #4396)
+  */
+
+  // Get the name of the tag table and create it
+  std::string tag2TagTableName =
+    dbAttr[RelationalDatabaseTable::attributeNames::tag2TagTableName].
+    data<std::string>();
+  schemaMgr().createTag2TagTable
+    ( tag2TagTableName, tagTableName, nodeTableName );
+
+  // Get the name of the tag shared sequence and create it
+  std::string tagSharedSequenceName =
+    dbAttr[RelationalDatabaseTable::attributeNames::tagSharedSequenceName].
+    data<std::string>();
+  schemaMgr().createSharedSequence( tagSharedSequenceName, nodeTableName );
+
+  // Get the name of the IOV shared sequence and create it
+  std::string iovSharedSequenceName =
+    dbAttr[RelationalDatabaseTable::attributeNames::iovSharedSequenceName].
+    data<std::string>();
+  schemaMgr().createSharedSequence( iovSharedSequenceName, nodeTableName );
+
+  // Commit the transaction
+  transaction.commit();
+
+  // The database is now open
+  m_isOpen = true;
+
+  // TEMPORARY? Sleep to work around the ORA-01466 problem (Oracle only)
+  if ( m_sessionMgr->databaseTechnology() == "Oracle" && m_useTimeout ) {
+    log() << "Sleep to work around the ORA-01466 problem" 
+          << coral::MessageStream::endmsg;
+    cool::sleep(1);
+  }
+
+}
+
+//-----------------------------------------------------------------------------
+
+bool RalDatabase::dropDatabase()
+{
+  log() << coral::Info << "Drop database..." << coral::MessageStream::endmsg;
+
+  // AV 2005-07-07
+  // Return true if all database tables are dropped as expected.
+  // Return false (without throwing any exception) if the database and
+  // all associated tables do not exist any more on exit from this method,
+  // but the database or some associated tables did not exist to start with.
+  bool status = true;
+
+  // Throw a RelationalException if the database or one of its tables
+  // cannot be dropped (i.e. continues to exist on exit from this method).
+  // Any exception is thrown as soon as the first problem appears:
+  // the implementation is based on many individual transactions,
+  // there is no attempt to go back to the last known state on failure
+  // (also because technically difficult, Oracle DDL is auto-committed).
+
+  // Enclose the implementation in a try-catch block anyway,
+  // just to be able to print some debug messages on failures.
+  try 
+  {
+
+    // For each folder, drop IOV table and sequence and delete the folder row.
+    // Also delete any tags associated to the folder from the global tag table
+    // and from the tag2tag table (otherwise FK constraints may be violated)
+    // Throw an Exception if the schema of one of the nodes in this database
+    // is more recent than the schema version supported by the current release:
+    // in this case make sure you do not drop ANY node (throw immediately)!
+    if ( ! dropAllNodes() ) status = false;
+
+    // Drop the IOV shared sequence
+    {
+      std::string tableName = iovSharedSequenceName();
+      log() << coral::Debug << "Drop table " << tableName 
+            << coral::MessageStream::endmsg;
+      RelationalTransaction transaction( transactionMgr() ); // read-write
+      if ( ! schemaMgr().dropTable( tableName ) ) status = false;
+      transaction.commit();
+    }
+    
+    // Drop the tag shared sequence
+    {
+      std::string tableName = tagSharedSequenceName();
+      log() << coral::Debug << "Drop table " << tableName 
+            << coral::MessageStream::endmsg;
+      RelationalTransaction transaction( transactionMgr() ); // read-write
+      if ( ! schemaMgr().dropTable( tableName ) ) status = false;
+      transaction.commit();
+    }
+    
+    // Drop the sequence associated to the tag2tag table
+    {
+      std::string seqName = 
+        RelationalTag2TagTable::sequenceName( tag2TagTableName() );
+      log() << coral::Debug << "Drop sequence " << seqName 
+            << coral::MessageStream::endmsg;
+      RelationalTransaction transaction( transactionMgr() ); // read-write
+      if ( ! queryMgr().sequenceMgr().existsSequence( seqName ) ) 
+      {
+        status = false;
+      } 
+      else 
+      {
+        queryMgr().sequenceMgr().dropSequence( seqName );
+      }
+      transaction.commit();
+    }
+    
+    // Drop the tag2tag table
+    {
+      std::string tableName = tag2TagTableName();
+      log() << coral::Debug << "Drop table " << tableName 
+            << coral::MessageStream::endmsg;
+      RelationalTransaction transaction( transactionMgr() ); // read-write
+      if ( ! schemaMgr().dropTable( tableName ) ) status = false;
+      transaction.commit();
+    }
+    
+    /*
+    // *** START *** 3.0.0 schema extensions (task #4396)
+    // Drop the global user tag table
+    {
+      std::string tableName = globalUserTagTableName();
+      log() << coral::Debug << "Drop table " << tableName 
+            << coral::MessageStream::endmsg;
+      RelationalTransaction transaction( transactionMgr() ); // read-write
+      if ( ! schemaMgr().dropTable( tableName ) ) status = false;
+      transaction.commit();
+    }
+  
+    // Drop the global head tag table
+    {
+      std::string tableName = globalHeadTagTableName();
+      log() << coral::Debug << "Drop table " << tableName 
+            << coral::MessageStream::endmsg;
+      RelationalTransaction transaction( transactionMgr() ); // read-write
+      if ( ! schemaMgr().dropTable( tableName ) ) status = false;
+      transaction.commit();
+    }
+    // **** END **** 3.0.0 schema extensions (task #4396)
+    */
+ 
+    // Drop the global tag table
+    {
+      std::string tableName = globalTagTableName();
+      log() << coral::Debug << "Drop table " << tableName 
+            << coral::MessageStream::endmsg;
+      RelationalTransaction transaction( transactionMgr() ); // read-write
+      if ( ! schemaMgr().dropTable( tableName ) ) status = false;
+      transaction.commit();
+    }
+    
+    // Drop the sequence associated to the node table
+    {
+      std::string seqName = 
+        RelationalNodeTable::sequenceName( nodeTableName() );
+      log() << coral::Debug << "Drop sequence " << seqName 
+            << coral::MessageStream::endmsg;
+      RelationalTransaction transaction( transactionMgr() ); // read-write
+      if ( ! queryMgr().sequenceMgr().existsSequence( seqName ) ) 
+      {
+        status = false;
+      } 
+      else 
+      {
+        queryMgr().sequenceMgr().dropSequence( seqName );
+      }
+      transaction.commit();
+    }
+    
+    // Drop the node table
+    {
+      std::string tableName = nodeTableName();
+      log() << coral::Debug << "Drop table " << tableName 
+            << coral::MessageStream::endmsg;
+      RelationalTransaction transaction( transactionMgr() ); // read-write
+      if ( ! schemaMgr().dropTable( tableName ) ) status = false;
+      transaction.commit();
+    }
+    
+    /*
+    // *** START *** 3.0.0 schema extensions (task #4307)
+    // Drop the channelTables table
+    {
+      std::string tableName = channelTablesTableName();
+      //log() << coral::Debug << "Drop table " << tableName 
+      //      << coral::MessageStream::endmsg;
+      RelationalTransaction transaction( transactionMgr() ); // read-write
+      //if ( ! schemaMgr().dropTable( tableName ) ) status = false;
+      transaction.commit();
+    }
+
+    // Drop the iovTables table
+    {
+      std::string tableName = iovTablesTableName();
+      //log() << coral::Debug << "Drop table " << tableName 
+      //      << coral::MessageStream::endmsg;
+      RelationalTransaction transaction( transactionMgr() ); // read-write
+      //if ( ! schemaMgr().dropTable( tableName ) ) status = false;
+      transaction.commit();
+    }
+    // **** END **** 3.0.0 schema extensions (task #4307)
+    */
+
+    // Drop the main table
+    {
+      std::string tableName = mainTableName();
+      log() << coral::Debug << "Drop table " << tableName 
+            << coral::MessageStream::endmsg;
+      RelationalTransaction transaction( transactionMgr() ); // read-write
+      if ( ! schemaMgr().dropTable( tableName ) ) status = false;
+      transaction.commit();
+    }
+    
+  }
+  catch ( std::exception& e )
+  {
+    log() << coral::Warning << "Exception caught in dropDatabase(): "
+          << e.what() << coral::MessageStream::endmsg;
+    throw;
+  }  
+
+  // Success: the database does not exist anymore
+  // Return status code 'false' if parts of it were missing already
+  log() << coral::Info << "Drop database... DONE" 
+        << coral::MessageStream::endmsg;
+  return status;
+}
+
+//-----------------------------------------------------------------------------
+
+UInt32 RalDatabase::insertNodeTableRow
+( const std::string& fullPath,
+  const std::string& description,
+  bool createParents,
+  bool isLeaf,
+  const std::string& payloadSpecDesc,
+  FolderVersioning::Mode versioningMode ) 
+{
+  // Transaction handled in the outer scope
+
+  // This is the maximum number of nodes that can be created
+  // Note that this limitation is coupled to the folder name
+  // generation via the pattern F%4.4i_IOVS --> max: F9999_IOVS
+  // There is no point in working around this limitation at this time
+  // as the database will not handle several thousands of tables well.
+  // (At least the MySQL backend has proven to be problematic at this scale.)
+  unsigned int kMaxNumberOfNodes = 9999;
+
+  log() << "Create a new node with name " << fullPath 
+        << coral::MessageStream::endmsg;
+  // Cross-check that the database is open
+  if ( ! isOpen() ) throw DatabaseNotOpen( "RalDatabase" );
+
+  /*
+  // AV 09.05.2005 Move this AFTER locking sequence to fix David Front's bug
+  // Check if a folder or folder set with this name already exists
+  if ( existsNode( fullPath ) ) {
+  throw NodeExists( fullPath, "RalDatabase" );
+  }
+  */
+
+  // Split the full path
+  HvsPathHandler pathHandler;
+  std::pair<std::string, std::string> parentAndChild;
+  try {
+    parentAndChild = pathHandler.splitFullPath( fullPath );
+  } catch ( HvsPathHandlerException& ) {
+    log() << coral::Error << "Invalid folder node path '"
+          << fullPath << "'" << coral::MessageStream::endmsg;
+    throw;
+  }
+  std::string parentFullPath = parentAndChild.first;
+  std::string unresolvedName = parentAndChild.second;
+
+  // Look for the parent folder set
+  unsigned int nodeParentId;
+  try {
+    RelationalTableRow row = fetchNodeTableRow( parentFullPath );
+    bool isLeaf = 
+      row[RelationalNodeTable::columnNames::nodeIsLeaf].data<bool>();
+    if ( isLeaf ) {
+      std::stringstream s;
+      s << "Cannot create node '" << fullPath
+        << "', because the parent path contains a leaf node";
+      throw RelationalException( s.str(), "RalDatabase" );
+    }
+    IFolderSetPtr parent
+      ( new RelationalFolderSet( relationalDbPtr(), row.data() ) );
+    nodeParentId = parent->id();
+  } catch ( NodeTableRowNotFound& ) {
+    if( ! createParents ) throw;
+    __createFolderSet( parentFullPath,  // full path  
+                       "",              // description
+                       true );          // createParents
+    RelationalTableRow row = fetchNodeTableRow( parentFullPath );
+    IFolderSetPtr parent
+      ( new RelationalFolderSet( relationalDbPtr(), row.data() ) );
+    nodeParentId = parent->id();
+  }
+
+  // Get a new folder ID from the sequence
+  std::string nodeSeqName =
+    RelationalNodeTable::sequenceName( nodeTableName() );
+  RelationalSequencePtr nodeSeq
+    ( queryMgr().sequenceMgr().getSequence( nodeSeqName ) );
+  unsigned int nodeId = nodeSeq->nextVal();
+  if ( nodeId > kMaxNumberOfNodes )
+    throw RelationalException
+      ( "Node ID out of boundaries", "RalDatabase" );
+  std::string insertionTime = nodeSeq->currDate();
+
+  // AV 09.05.2005 Move this AFTER locking sequence to fix David Front's bug
+  // Check if a folder or folder set with this name already exists
+  if ( existsNode( fullPath ) ) {
+    /*
+    // NB Error message only makes sense if first cross-check is also kept
+    log() << coral::Error
+    << "Congratulations! You tried to create folder " << fullPath
+    << " from two separate connections EXACTLY at the same time!"
+    << coral::MessageStream::endmsg;
+    */
+    throw NodeExists( fullPath, "RalDatabase" );
+  }
+
+  // Register the folder in the node table
+  // AV 14-03-2005 TEMPORARY? Till RAL handles NULL values better
+  // Do not insert NULL values: insert empty strings instead
+  const IRecordSpecification& nodeTableSpec =
+    RelationalNodeTable::tableSpecification( true );
+  coral::AttributeList data = Record( nodeTableSpec ).attributeList();
+  data[RelationalNodeTable::columnNames::nodeId].setValue
+    ( nodeId );
+  data[RelationalNodeTable::columnNames::nodeParentId].setValue
+    ( nodeParentId );
+  data[RelationalNodeTable::columnNames::nodeName].setValue
+    ( unresolvedName );
+  data[RelationalNodeTable::columnNames::nodeFullPath].setValue
+    ( fullPath );
+  data[RelationalNodeTable::columnNames::nodeDescription].setValue
+    ( description );
+  data[RelationalNodeTable::columnNames::nodeIsLeaf].setValue
+    ( isLeaf );
+  if ( isLeaf ) {
+    data[RelationalNodeTable::columnNames::nodeSchemaVersion].setValue
+      ( std::string( RelationalFolder::folderSchemaVersion() ) );
+  } 
+  else {  
+    data[RelationalNodeTable::columnNames::nodeSchemaVersion].setValue
+      ( std::string( RelationalFolderSet::folderSetSchemaVersion() ) );
+  }
+  data[RelationalNodeTable::columnNames::nodeInsertionTime].setValue
+    ( insertionTime );
+  data[RelationalNodeTable::columnNames::lastModDate].setValue
+    ( insertionTime );
+
+  if ( isLeaf ) {
+    // Set the folder specific information
+    data[RelationalNodeTable::columnNames::folderPayloadSpecDesc].setValue
+      ( payloadSpecDesc );
+    data[RelationalNodeTable::columnNames::folderVersioningMode].setValue
+      ( (int)versioningMode );
+    data[RelationalNodeTable::columnNames::folderObjectTableName].setValue
+      ( RelationalObjectTable::defaultTableName
+        ( defaultTablePrefix(), nodeId ) );
+    data[RelationalNodeTable::columnNames::folderTagTableName].setValue
+      ( RelationalTagTable::defaultTableName
+        ( defaultTablePrefix(), nodeId ) );
+    data[RelationalNodeTable::columnNames::folderObject2TagTableName].setValue
+      ( RelationalObject2TagTable::defaultTableName
+        ( defaultTablePrefix(), nodeId ) );
+    data[RelationalNodeTable::columnNames::folderChannelTableName].setValue
+      ( RelationalChannelTable::defaultTableName
+        ( defaultTablePrefix(), nodeId ) );
+  } else {
+    // Insert NULL values for folder sets
+    data[RelationalNodeTable::columnNames::folderPayloadSpecDesc].setValue
+      ( std::string( "" ) );
+    //( payloadSpecDesc );
+    data[RelationalNodeTable::columnNames::folderVersioningMode].setValue
+      ( (int)FolderVersioning::NONE );
+    //( (int)versioningMode );
+    data[RelationalNodeTable::columnNames::folderObjectTableName].setValue
+      ( std::string( "" ) );
+    data[RelationalNodeTable::columnNames::folderTagTableName].setValue
+      ( std::string( "" ) );
+    data[RelationalNodeTable::columnNames::folderObject2TagTableName].setValue
+      ( std::string( "" ) );
+  }
+
+  // TEMPORARY? Will RAL do this as well?
+  // Check that all column values are within their allowed range
+  nodeTableSpec.validate( data );
+
+  // Perform the actual db update
+  queryMgr().insertTableRow( nodeTableName(), data );
+  return nodeId;
+}
+
+//-----------------------------------------------------------------------------
+
+IFolderSetPtr RalDatabase::createFolderSet( const std::string& fullPath,
+                                            const std::string& description,
+                                            bool createParents )
+{
+  if ( ! isOpen() ) throw DatabaseNotOpen( "RalDatabase" );
+  // Cross-check that we're not in manual transaction more
+  if ( ! transactionMgr()->autoTransactions() ) {
+    throw RelationalException("Cannot create folder set in manual "
+                              "transaction mode", "RalDatabase");
+  }
+  RelationalTransaction transaction( transactionMgr() ); // read-write
+  IFolderSetPtr folderset = 
+    __createFolderSet( fullPath, description, createParents );
+  transaction.commit();
+  return folderset;
+}
+
+//-----------------------------------------------------------------------------
+
+IFolderSetPtr RalDatabase::__createFolderSet( const std::string& fullPath,
+                                              const std::string& description,
+                                              bool createParents )
+{
+  log() << coral::Verbose
+        << "Create folder set " << fullPath << coral::MessageStream::endmsg; 
+
+  // Cross-check that the database is open
+  if ( ! isOpen() ) throw DatabaseNotOpen( "RalDatabase" );
+
+  bool isLeaf = false;
+  std::string payloadSpecDesc = "";
+  FolderVersioning::Mode folderVersioningMode = FolderVersioning::NONE;
+
+  unsigned int nodeId = insertNodeTableRow
+    ( fullPath, description, createParents, isLeaf,
+      // The "" payloadSpecDesc argument is set to NULL only in the Oracle db
+      payloadSpecDesc, folderVersioningMode );
+
+  std::string tagSequenceName = RelationalTagSequence::sequenceName
+    ( defaultTablePrefix(), nodeId );
+  schemaMgr().createTagSequence( tagSequenceName );
+
+  log() << coral::Verbose 
+        << "Created folder set " << fullPath 
+        << ": now fetch it and return it" << coral::MessageStream::endmsg; 
+
+  return __getFolderSet( fullPath );
+}
+
+
+//-----------------------------------------------------------------------------
+
+IFolderPtr RalDatabase::createFolder
+( const std::string& fullPath,
+  const IRecordSpecification& payloadSpec,
+  const std::string& description,
+  FolderVersioning::Mode versioningMode,
+  bool createParents )
+{
+  // Cross-check that the database is open
+  if ( ! isOpen() ) throw DatabaseNotOpen( "RalDatabase" );
+  // Cross-check that we're not in manual transaction more
+  if ( ! transactionMgr()->autoTransactions() ) {
+    throw RelationalException("Cannot create folder in manual "
+                              "transaction mode", "RalDatabase");
+  }
+  bool readOnly = false;
+  RelationalTransaction transaction( transactionMgr(), readOnly );
+  IFolderPtr folder = 
+    __createFolder( fullPath, payloadSpec, description,
+                    versioningMode, createParents );
+  transaction.commit();
+  return folder;
+}
+
+//-----------------------------------------------------------------------------
+
+IFolderPtr RalDatabase::createFolder
+(  const std::string& fullPath,
+   const IFolderSpecification& folderSpec,
+   const std::string& description,
+   bool createParents ) 
+{
+  // Cross-check that the database is open
+  if ( ! isOpen() ) throw DatabaseNotOpen( "RalDatabase" );
+  // Cross-check that we're not in manual transaction more
+  if ( ! transactionMgr()->autoTransactions() ) {
+    throw RelationalException("Cannot create folder in manual "
+                              "transaction mode", "RalDatabase");
+  }
+  bool readOnly = false;
+  FolderVersioning::Mode versioningMode = folderSpec.versioningMode();
+  const IRecordSpecification& payloadSpec = folderSpec.payloadSpecification();
+  RelationalTransaction transaction( transactionMgr(), readOnly );
+  IFolderPtr folder = 
+    __createFolder( fullPath, payloadSpec, description,
+                    versioningMode, createParents );
+  transaction.commit();
+  return folder;
+}
+
+//-----------------------------------------------------------------------------
+
+IFolderPtr RalDatabase::__createFolder
+( const std::string& fullPath,
+  const IRecordSpecification& payloadSpec,
+  const std::string& description,
+  FolderVersioning::Mode versioningMode,
+  bool createParents )
+{
+  log() << coral::Verbose 
+        << "Create folder " << fullPath  << coral::MessageStream::endmsg; 
+
+  // Cross-check that the database is open
+  if ( ! isOpen() ) throw DatabaseNotOpen( "RalDatabase" );
+
+  // Validate the payload specification.
+  // Throws InvalidPayloadSpecification if the payload spec is invalid:
+  // there can be at most 900 fields, including up to 10 BLOB fields;
+  // field names must have between 1 and 30 characters (including only 
+  // letters, digits or '_'), must start with a letter and cannot start 
+  // with the "COOL_" prefix (in any lowercase/uppercase combination).
+  validatePayloadSpecification( payloadSpec );
+  
+  // Register the folder in the node table
+  std::string payloadSpecDesc = encodeRecordSpecification( payloadSpec );
+  
+  bool isLeaf = true;
+  unsigned int nodeId = insertNodeTableRow
+    ( fullPath, description, createParents,
+      isLeaf, payloadSpecDesc, versioningMode );
+
+  // Create the IOV table for the folder
+  std::string objectTableName = RelationalObjectTable::defaultTableName
+    ( defaultTablePrefix(), nodeId );
+  std::string obj2tagTableName = RelationalObject2TagTable::defaultTableName
+    ( defaultTablePrefix(), nodeId );
+  std::string tagTableName = RelationalTagTable::defaultTableName
+    ( defaultTablePrefix(), nodeId );
+  std::string tagSequenceName = RelationalTagSequence::sequenceName
+    ( defaultTablePrefix(), nodeId );
+  std::string channelTableName =
+    RelationalChannelTable::defaultTableName( defaultTablePrefix(), nodeId );
+  
+  if ( versioningMode == FolderVersioning::SINGLE_VERSION ||
+       versioningMode == FolderVersioning::MULTI_VERSION ) {
+    
+    schemaMgr().createChannelTable( channelTableName );
+    schemaMgr().createObjectTable
+      ( objectTableName, channelTableName, payloadSpec, versioningMode );
+    if ( versioningMode == FolderVersioning::MULTI_VERSION ) {
+      schemaMgr().createTagSequence( tagSequenceName );
+      schemaMgr().createTagTable( tagTableName );
+      schemaMgr().createObject2TagTable
+        ( obj2tagTableName, objectTableName, tagTableName );
+    }
+    
+  } else {
+    std::stringstream s;
+    s << "Invalid versioning mode specified: " << versioningMode;
+    throw RelationalException( s.str(), "RalDatabase" );
+  }
+  
+  // TEMPORARY? Sleep to work around the ORA-01466 problem (Oracle only)
+  if ( m_sessionMgr->databaseTechnology() == "Oracle" && m_useTimeout ) {
+    log() << "Sleep to work around the ORA-01466 problem" 
+          << coral::MessageStream::endmsg;
+    cool::sleep(1);
+  }
+
+  // Get and return the IFolder instance for the folder that has just been
+  // created [NB This causes a second round trip to fetch the data that has
+  // just been written, but performance impact is low because folder creation
+  // is a relatively rare operation, and it's more modular to use getFolder]
+  log() << coral::Verbose 
+        << "Created folder " << fullPath 
+        << ": now fetch it and return it" << coral::MessageStream::endmsg;
+  return __getFolder( fullPath );
+
+}
+
+//-----------------------------------------------------------------------------
+
+void RalDatabase::updateNodeTableDescription
+( const std::string& fullPath, const std::string& description ) const
+{
+  log() << "Updating node description at path: "
+        << fullPath << coral::MessageStream::endmsg;
+
+  // Cross-check that the database is open and start a transaction
+  if ( ! isOpen() ) throw DatabaseNotOpen( "RalDatabase" );
+  RelationalTransaction transaction( transactionMgr() ); // read-write
+
+  // Define the SET and WHERE clauses for the update using bind variables
+  coral::AttributeList updateData;
+  updateData.extend
+    ( "desc",
+      typeIdToCoralType(RelationalNodeTable::columnTypeIds::nodeDescription) );
+  updateData.extend
+    ( "path",
+      typeIdToCoralType(RelationalNodeTable::columnTypeIds::nodeFullPath) );
+  updateData["desc"].setValue( description );
+  updateData["path"].setValue( fullPath );
+  std::string setClause = RelationalNodeTable::columnNames::nodeDescription;
+  setClause += "= :desc";
+  setClause += ", ";
+  setClause += RelationalNodeTable::columnNames::lastModDate;
+  setClause += " = " + queryMgr().serverTimeClause();
+  std::string whereClause = RelationalNodeTable::columnNames::nodeFullPath;
+  whereClause += "= :path";
+
+  // Execute the update
+  if ( 1 != queryMgr().updateTableRows
+       ( nodeTableName(), setClause, whereClause, updateData ) )
+    throw RowNotUpdated
+      ( "Could not update a row of the node table", "RalDatabase" );
+
+  // Commit the transaction
+  transaction.commit();
+}
+
+//-----------------------------------------------------------------------------
+
+IFolderPtr RalDatabase::getFolder( const std::string& fullPath )
+{
+  if ( ! isOpen() ) throw DatabaseNotOpen( "RalDatabase" );
+  bool readOnly = true;
+  RelationalTransaction transaction( transactionMgr(), readOnly );
+  IFolderPtr folder = __getFolder( fullPath );
+  transaction.commit();
+  return folder;
+}
+
+//-----------------------------------------------------------------------------
+
+IFolderPtr RalDatabase::__getFolder( const std::string& fullPath )
+{
+  if ( TimingReportMgr::isActive() )
+    TimingReportMgr::startTimer( "cool::RalDatabase::__getFolder()" );
+
+  log() << "Get folder with name " << fullPath << coral::MessageStream::endmsg;
+  if ( ! isOpen() ) throw DatabaseNotOpen( "RalDatabase" );
+  
+  IFolderPtr folder;
+
+  // For Update connections, fetch each folder every time
+  if ( !sessionMgr()->isReadOnly() ) 
+  {
+    try {
+      RelationalTableRow row = fetchNodeTableRow( fullPath );
+      folder = __getFolder( row );
+    } catch ( NodeTableRowNotFound& ) {
+      throw FolderNotFound( fullPath, "RalDatabase" );
+    }
+  }
+  
+  // For ReadOnly connections, use the folder cache
+  else
+  {
+    if ( m_nodes.size() == 0 ) __preloadAllNodes();
+    if ( m_nodes.find( fullPath ) != m_nodes.end() ) 
+      folder = __getFolder( *m_nodes[fullPath] );
+    else 
+      throw FolderNotFound( fullPath, "RalDatabase" );
+  }
+  
+  if ( TimingReportMgr::isActive() )
+    TimingReportMgr::stopTimer( "cool::RalDatabase::__getFolder()" );
+  return folder;
+}
+
+//-----------------------------------------------------------------------------
+
+IFolderPtr RalDatabase::__getFolder( const RelationalTableRow& row )
+{
+  std::string fullPath =
+    row[RelationalNodeTable::columnNames::nodeFullPath].data<std::string>();
+  bool isLeaf =
+    row[RelationalNodeTable::columnNames::nodeIsLeaf].data<bool>();
+  if ( ! isLeaf )
+    throw FolderNotFound( fullPath, "RalDatabase", true );
+  VersionNumber schemaVersion = 
+    row[RelationalNodeTable::columnNames::nodeSchemaVersion]
+    .data<std::string>();
+  IFolderPtr folder;
+  // Handle all well-defined hardcoded folder schema versions supported by
+  // the RelationalFolder class; return an unusable Unsupported folder
+  // for folders with schema versions higher than the present s/w release;
+  // throw a PANIC exception for all other values (should never happen!).
+  if ( RelationalFolder::isSupportedSchemaVersion( schemaVersion ) )
+  {
+    folder.reset
+      ( new RelationalFolder( relationalDbPtr(), row.data() ) );
+  }
+  else if ( VersionInfo::release < schemaVersion )
+  {
+    folder.reset
+      ( new RelationalFolderUnsupported( relationalDbPtr(), row.data() ) );
+  }
+  else if ( schemaVersion == VersionNumber( "2.0.0" ) )
+  {
+    folder.reset
+      ( new RelationalFolderUnsupported( relationalDbPtr(), row.data() ) );
+    //throw UnsupportedFolderSchema
+    //  ( fullPath, schemaVersion, "RelationalFolderUnsupported" );
+  }
+  else
+  {
+    std::stringstream s;
+    s << "PANIC! Cannot get folder '" << fullPath 
+      << "': it appears to have been created using UNKNOWN schema version "
+      << schemaVersion 
+      << " that is older than (or as old as) the current software release "
+      << VersionInfo::release;
+    throw RelationalException( s.str(), "RalDatabase" );
+  }
+  return folder;
+}
+
+//-----------------------------------------------------------------------------
+
+IFolderSetPtr RalDatabase::getFolderSet( const std::string& fullPath )
+{
+  if ( ! isOpen() ) throw DatabaseNotOpen( "RalDatabase" );
+  RelationalTransaction transaction( transactionMgr(), true ); // read-only
+  IFolderSetPtr folderset = __getFolderSet( fullPath );
+  transaction.commit();
+  return folderset;
+}
+
+//-----------------------------------------------------------------------------
+
+IFolderSetPtr RalDatabase::__getFolderSet( const std::string& fullPath )
+{
+  log() << "Get folderset with name " << fullPath 
+        << coral::MessageStream::endmsg;
+  if ( ! isOpen() ) throw DatabaseNotOpen( "RalDatabase" );
+
+  IFolderSetPtr folderSet;
+
+  // For Update connections, fetch each folder every time
+  if ( !sessionMgr()->isReadOnly() ) 
+  {
+    try {
+      RelationalTableRow row = fetchNodeTableRow( fullPath );
+      folderSet = __getFolderSet( row );
+    } catch ( NodeTableRowNotFound& ) {
+      throw FolderSetNotFound( fullPath, "RalDatabase" );
+    }
+  }
+  
+  // For ReadOnly connections, use the folder cache
+  else
+  {
+    if ( m_nodes.size() == 0 ) __preloadAllNodes();
+    if ( m_nodes.find( fullPath ) != m_nodes.end() ) 
+      folderSet = __getFolderSet( *m_nodes[fullPath] );
+    else 
+      throw FolderSetNotFound( fullPath, "RalDatabase" );
+  }
+  
+  return folderSet;
+}
+
+//-----------------------------------------------------------------------------
+
+IFolderSetPtr RalDatabase::__getFolderSet( const RelationalTableRow& row )
+{
+  std::string fullPath =
+    row[RelationalNodeTable::columnNames::nodeFullPath].data<std::string>();
+  bool isLeaf =
+    row[RelationalNodeTable::columnNames::nodeIsLeaf].data<bool>();
+  if ( isLeaf )
+    throw FolderSetNotFound( fullPath, "RalDatabase", true );
+  VersionNumber schemaVersion = 
+    row[RelationalNodeTable::columnNames::nodeSchemaVersion]
+    .data<std::string>();
+  IFolderSetPtr folderSet;
+  // Handle all well-defined hardcoded folder set schema versions supported by
+  // the RelationalFolderSet class; return an unusable Unsupported folderSet
+  // for folder sets with schema versions higher than the present s/w release;
+  // throw a PANIC exception for all other values (should never happen!).
+  if ( RelationalFolderSet::isSupportedSchemaVersion( schemaVersion ) )
+  {
+    folderSet.reset
+      ( new RelationalFolderSet( relationalDbPtr(), row.data() ) );
+  }
+  else if ( VersionInfo::release < schemaVersion )
+  {
+    folderSet.reset
+      ( new RelationalFolderSetUnsupported( relationalDbPtr(), row.data() ) );
+  }
+  else
+  {
+    std::stringstream s;
+    s << "PANIC! Cannot get folder set '" << fullPath 
+      << "': it appears to have been created using UNKNOWN schema version "
+      << schemaVersion 
+      << " that is older than (or as old as) the current software release "
+      << VersionInfo::release;
+    throw RelationalException( s.str(), "RalDatabase" );
+  }
+  return folderSet;
+}
+
+//-----------------------------------------------------------------------------
+
+void RalDatabase::__preloadAllNodes()
+{
+  log() << "Preload all nodes" << coral::MessageStream::endmsg;
+
+  if ( ! isOpen() ) throw DatabaseNotOpen( "RalDatabase" );
+
+  if ( m_nodes.size() != 0 ) 
+    throw RelationalException
+      ( "PANIC! Nodes already preloaded", "RalDatabase" );
+
+  if ( !sessionMgr()->isReadOnly() ) 
+    throw RelationalException
+      ( "PANIC! Cannot preload nodes in update mode", "RalDatabase" );
+
+  std::vector<RelationalTableRow> rows = nodeMgr().fetchAllNodeTableRows();
+
+  // Loop over all nodes in the node table
+  for ( std::vector<RelationalTableRow>::const_iterator
+          row = rows.begin(); row != rows.end(); ++row ) 
+  {
+    std::string fullPath =
+      (*row)[RelationalNodeTable::columnNames::nodeFullPath]
+      .data<std::string>();
+
+    if ( m_nodes.find( fullPath ) != m_nodes.end() ) 
+    {
+      std::stringstream s;
+      s << "PANIC! Node '" << fullPath 
+        << "' was found more than once in the node table!";
+      throw RelationalException( s.str(), "RalDatabase" );
+    }
+
+    m_nodes[fullPath] = new RelationalTableRow( *row );
+
+  }
+}
+
+//-----------------------------------------------------------------------------
+
+bool RalDatabase::dropAllNodes()
+{
+  log() << coral::Info << "Drop all nodes..." << coral::MessageStream::endmsg;
+
+  // AV 2005-07-07
+  // Return true if all node, tag and tag2tag rows are deleted and all folder 
+  // tables (for nodes that are folders) are dropped as expected.
+  // Return false (without throwing any exception) if the node rows and
+  // any associated tables do not exist any more on exit from this method,
+  // but some node rows or associated tables did not exist to start with.
+  bool status = true;
+
+  // Throw an Exception if the schema of one of the nodes in this database
+  // is more recent than the schema version supported by the current release:
+  // in this case make sure you do not drop ANY node (throw immediately)!
+  {
+    // Start a read-only transaction
+    RelationalTransaction transaction( transactionMgr(), true );
+    
+    // Iterate over all folders and folder sets and compare schema versions 
+    // to a well-defined hardcoded list supported by this s/w release
+    coral::AttributeList whereData; // select all
+    std::string whereClause; // select all
+    std::vector<RelationalTableRow> rows =
+      queryMgr().fetchRowsFromTables
+      ( RelationalQueryMgr::tableList( nodeTableName() ), 
+        RelationalQueryMgr::columnList
+        ( RelationalNodeTable::tableSpecification() ),
+        whereClause, whereData, "" );
+    for ( std::vector<RelationalTableRow>::const_iterator
+            row = rows.begin(); row != rows.end(); row++ ) 
+    {
+      const std::string fullPath =
+        (*row)[RelationalNodeTable::columnNames::nodeFullPath]
+        .data<std::string>();
+      bool isLeaf =
+        (*row)[RelationalNodeTable::columnNames::nodeIsLeaf]
+        .data<bool>();
+      const VersionNumber schemaVersion =
+        (*row)[RelationalNodeTable::columnNames::nodeSchemaVersion]
+        .data<std::string>();
+      bool isSupported = true;
+      if ( isLeaf ) {
+        if ( !RelationalFolder::isSupportedSchemaVersion( schemaVersion ) )
+          isSupported = false;
+      }
+      else {
+        if ( !RelationalFolderSet::isSupportedSchemaVersion( schemaVersion ) )
+          isSupported = false;
+      }
+      if ( VersionInfo::release < schemaVersion ) {
+        std::stringstream s;
+        s << "Cannot drop database:";
+        if ( isLeaf ) s << " folder '";
+        else s << " folder set '";
+        s << fullPath << " has schema version " << schemaVersion
+          << " that is newer than this software release " 
+          << VersionInfo::release;
+        log() << coral::Warning << s.str() << coral::MessageStream::endmsg;
+        throw RelationalException( s.str(), "RalDatabase" );
+      }
+      else if ( ! isSupported ) {
+        std::stringstream s;
+        s << "PANIC! Cannot drop database:";
+        if ( isLeaf ) s << " folder '";
+        else s << " folder set '";
+        s << fullPath
+          << "' appears to have been created using UNKNOWN schema version "
+          << schemaVersion 
+          << " that is older than (or as old as) the current software release "
+          << VersionInfo::release;
+        throw RelationalException( s.str(), "RalDatabase" );
+      }
+    }
+    
+    // Commit the transaction
+    transaction.commit();
+  }
+  
+  // Throw a RelationalException if a node row cannot be deleted or one table
+  // cannot be dropped (i.e. continues to exist on exit from this method).
+
+  // Listing the nodes in reverse order ensures that integrity constraints
+  // are not violated (children are dropped before their parents)
+  std::vector<std::string> nodes( listAllNodes( false ) );
+  std::vector<std::string>::const_iterator node;
+  log() << coral::Debug << "Will drop nodes in this order:" 
+        << coral::MessageStream::endmsg;
+  for ( node = nodes.begin(); node != nodes.end(); node++ ) 
+  {
+    log() << coral::Debug << "Will drop '" << *node << "'" 
+          << coral::MessageStream::endmsg;
+  }
+  for ( node = nodes.begin(); node != nodes.end(); node++ ) 
+  {  
+    log() << coral::Debug << "Now drop '" << *node << "'" 
+          << coral::MessageStream::endmsg;
+    if ( ! dropNode( *node ) ) status = false;
+  }
+  
+  // Success: the nodes do not exist anymore
+  // Return status code 'false' if some nodes or tables were missing already
+  log() << coral::Info << "Drop all nodes... DONE" 
+        << coral::MessageStream::endmsg;
+  return status;
+
+}
+
+//-----------------------------------------------------------------------------
+
+bool RalDatabase::dropNode( const std::string& fullPath )
+{
+  if ( ! isOpen() ) throw DatabaseNotOpen( "RalDatabase" );
+
+  log() << coral::Debug << "Drop node '" << fullPath << "' ..." 
+        << coral::MessageStream::endmsg;
+
+  RelationalTransaction transaction( transactionMgr() );
+  bool status = __dropNode( fullPath );
+  transaction.commit();
+ 
+  log() << coral::Debug << "Drop node '" << fullPath << "' ... DONE" 
+        << coral::MessageStream::endmsg;
+
+  return status;
+}
+
+//-----------------------------------------------------------------------------
+
+bool RalDatabase::__dropNode( const std::string& fullPath )
+{
+  log() << "Drop node with full path " << fullPath 
+        << coral::MessageStream::endmsg;
+  if ( ! isOpen() ) throw DatabaseNotOpen( "RalDatabase" );
+
+  // AV 2005-07-07
+  // Return true if the node, tag and tag2tag rows for this node are deleted 
+  // and all folder tables (if the node is a folder) are dropped as expected.
+  // Return false (without throwing any exception) if any such row and
+  // any associated tables do not exist any more on exit from this method,
+  // but the node or some associated tables did not exist to start with.
+  bool status = true;
+
+  // Throw a RelationalException if the node row cannot be deleted or one table
+  // cannot be dropped (i.e. continues to exist on exit from this method).
+  // Throw a RelationalException if the node is a non-empty folder set.
+  // Also deletes any tags and tag2tag associated to the node
+  // (and throws a RelationalException if such tags cannot be deleted).
+
+  // Fetch the row for this node
+  RelationalTableRow nodeRow;
+  try {
+    nodeRow = fetchNodeTableRow( fullPath );
+  } catch ( NodeTableRowNotFound& ) {
+    // A node with this name does not exist: nothing to drop
+    log() << coral::Warning << "Node '" << fullPath
+          << "' cannot be dropped (node not found)" 
+          << coral::MessageStream::endmsg;
+    return false;
+  } catch ( coral::QueryException& e ) {
+    // The query on the node table failed: for instance, the query may fail
+    // with ORA-00904 if some columns are missing from the node table because
+    // the process that created the database crashed or was killed while
+    // altering the node table to change the SQL type of its columns
+    log() << coral::Warning << "The node table cannot be queried: '"
+          << e.what() << coral::MessageStream::endmsg;
+    return false;
+  }
+  bool isLeaf =
+    nodeRow[RelationalNodeTable::columnNames::nodeIsLeaf].data<bool>();
+  unsigned int nodeId =
+    nodeRow[RelationalNodeTable::columnNames::nodeId].data<unsigned int>();
+
+  // Throw TagIsLocked if any tags applied to this node are locked
+  // (either LOCKED or PARTIALLYLOCKED - both are equivalent here)
+  {
+    std::vector<RelationalTableRow> rows = 
+      tagMgr().fetchGlobalTagTableRows( nodeId );
+    for ( std::vector<RelationalTableRow>::const_iterator
+            row = rows.begin(); row != rows.end(); ++row ) {
+      HvsTagLock::Status lockStatus = 
+        HvsTagLock::Status 
+        ( (*row)[RelationalGlobalTagTable::columnNames::tagLockStatus]
+          .data<UInt16>() );
+      if ( lockStatus != HvsTagLock::UNLOCKED ) {
+        std::string tagName =
+          (*row)[RelationalGlobalTagTable::columnNames::tagName]
+          .data<std::string>();
+        throw TagIsLocked
+          ( "Cannot drop node '" + fullPath + 
+            "': tag '" + tagName + "' is locked", "RalDatabase" );
+      }
+    }  
+  }  
+
+  // Check that the node schema version is supported by this software release
+  VersionNumber schemaVersion = 
+    nodeRow[RelationalNodeTable::columnNames::nodeSchemaVersion]
+    .data<std::string>();
+  bool isSupported = true;
+  if ( isLeaf ) {
+    if ( !RelationalFolder::isSupportedSchemaVersion( schemaVersion ) )
+      isSupported = false;
+  }
+  else {
+    if ( !RelationalFolderSet::isSupportedSchemaVersion( schemaVersion ) )
+      isSupported = false;
+  }
+  if ( VersionInfo::release < schemaVersion )
+  {
+    std::stringstream s;
+    s << "Cannot drop node:";
+    if ( isLeaf ) s << " folder '";
+    else s << " folder set '";
+    s << fullPath << " has schema version " << schemaVersion
+      << " that is newer than this software release " 
+      << VersionInfo::release;
+    log() << coral::Warning << s.str() << coral::MessageStream::endmsg;
+    throw RelationalException( s.str(), "RalDatabase" );
+  }
+  else if ( !isSupported )
+  {
+    std::stringstream s;
+    s << "PANIC! Cannot drop node:";
+    if ( isLeaf ) s << " folder '";
+    else s << " folder set '";
+    s << fullPath
+      << "' appears to have been created using UNKNOWN schema version "
+      << schemaVersion 
+      << " that is older than (or as old as) the current software release "
+      << VersionInfo::release;
+    throw RelationalException( s.str(), "RalDatabase" );
+  }
+  
+  // Folder: drop folder-specific tables and sequences
+  if ( isLeaf ) 
+  {
+    std::string objectTableName =
+      RelationalFolder::objectTableName( nodeRow.data() );
+    std::string tagTableName =
+      RelationalFolder::tagTableName( nodeRow.data() );
+    std::string object2TagTableName =
+      RelationalFolder::object2TagTableName( nodeRow.data() );
+    FolderVersioning::Mode versioningMode =
+      RelationalFolder::versioningMode( nodeRow.data() );
+    std::string tagSequenceName = RelationalTagSequence::sequenceName
+      ( defaultTablePrefix(), nodeId );
+    std::string tableName;
+    std::string seqName;
+    // Drop tables for MV folders
+    if ( versioningMode == FolderVersioning::MULTI_VERSION ) 
+    {
+      // Drop iov2tag table first as it has FK constraints on the other tables
+      tableName = object2TagTableName;
+      log() << "Drop table " << tableName << coral::MessageStream::endmsg;
+      if ( ! schemaMgr().dropTable( tableName ) ) status = false;
+      // Drop local tag table
+      tableName = tagTableName;
+      log() << "Drop table " << tableName << coral::MessageStream::endmsg;
+      if ( ! schemaMgr().dropTable( tableName ) ) status = false;
+      // Drop local tag sequence
+      seqName = tagSequenceName;
+      log() << "Drop sequence " << seqName << coral::MessageStream::endmsg;
+      if ( ! queryMgr().sequenceMgr().existsSequence( seqName ) ) {
+        status = false;
+      } else {
+        queryMgr().sequenceMgr().dropSequence( seqName );
+      }
+    }
+    // Drop iov table
+    tableName = objectTableName;
+    log() << "Drop table " << tableName << coral::MessageStream::endmsg;
+    if ( ! schemaMgr().dropTable( tableName ) ) status = false;
+    // Drop iov sequence
+    seqName = RelationalObjectTable::sequenceName( objectTableName );
+    log() << "Drop sequence " << seqName << coral::MessageStream::endmsg;
+    if ( ! queryMgr().sequenceMgr().existsSequence( seqName ) ) {
+      status = false;
+    } else {
+      queryMgr().sequenceMgr().dropSequence( seqName );
+    }
+    // Drop channel table last as it is referenced by FKs in the iov table 
+    tableName = 
+      RelationalChannelTable::defaultTableName( defaultTablePrefix(), nodeId );
+    log() << "Drop table " << tableName << coral::MessageStream::endmsg;
+    if ( ! schemaMgr().dropTable( tableName ) ) status = false;
+  }
+
+  // Folder set: make sure it is empty before deleting it and drop tag sequence
+  else 
+  {
+    // Make sure it is empty before deleting it
+    bool hasFolders = ! ( listNodes( nodeId, true ).empty() );
+    bool hasFolderSets = ! ( listNodes( nodeId, false ).empty() );
+    if ( hasFolders || hasFolderSets ) {
+      std::stringstream s;
+      s << "Cannot drop folderset '" << fullPath
+        << "', because it is not empty";
+      throw RelationalException( s.str(), "RalDatabase" );
+    }
+    // Drop local tag sequence
+    std::string tagSequenceName = RelationalTagSequence::sequenceName
+      ( defaultTablePrefix(), nodeId );
+    std::string seqName = tagSequenceName;
+    log() << "Drop sequence " << seqName << coral::MessageStream::endmsg;
+    if ( ! queryMgr().sequenceMgr().existsSequence( seqName ) ) {
+      status = false;
+    } else {
+      queryMgr().sequenceMgr().dropSequence( seqName );
+    }
+  }
+
+  // Delete all tag2tag relations associated to this node
+  if ( ! session().nominalSchema().existsTable( tag2TagTableName() ) )
+    status = false;
+  else
+    tagMgr().deleteTag2TagTableRowsForNode( nodeId );
+
+  // Delete all global tags associated to this node
+  if ( ! session().nominalSchema().existsTable( globalTagTableName() ) )
+    status = false;
+  else
+    tagMgr().deleteGlobalTagTableRowsForNode( nodeId );
+
+  // Delete the node from the node table
+  coral::AttributeList whereData;
+  whereData.extend
+    ( "fullName", 
+      typeIdToCoralType(RelationalNodeTable::columnTypeIds::nodeFullPath) );
+  whereData["fullName"].setValue( fullPath );
+  std::string whereClause = RelationalNodeTable::columnNames::nodeFullPath;
+  whereClause += "= :fullName";
+  queryMgr().deleteTableRows
+    ( nodeTableName(), whereClause, whereData, 1 );
+
+  // Success: the node does not exist anymore
+  // Return status code 'false' if the node or some tables were missing already
+  return status;
+}
+
+//-----------------------------------------------------------------------------
+
+boost::shared_ptr<RelationalObjectTable> 
+RalDatabase::relationalObjectTable( const RelationalFolder& folder ) const 
+{
+  boost::shared_ptr<RelationalObjectTable> 
+    objectTable( new RelationalObjectTable( &(queryMgr()), false, folder ) );
+  return objectTable;
+}
+
+//-----------------------------------------------------------------------------
+
+boost::shared_ptr<RalSessionMgr> RalDatabase::sessionMgr() const
+{
+  return m_sessionMgr;
+}
+
+//-----------------------------------------------------------------------------
+
+coral::ISessionProxy& RalDatabase::session() const
+{
+  return m_sessionMgr->session();
+}
+
+//-----------------------------------------------------------------------------
+
+bool RalDatabase::isConnected() const
+{
+  return m_sessionMgr->isConnected();
+}
+
+//-----------------------------------------------------------------------------
+
+void RalDatabase::connect()
+{
+  return m_sessionMgr->connect();
+}
+
+//-----------------------------------------------------------------------------
+
+void RalDatabase::disconnect()
+{
+  return m_sessionMgr->disconnect();
+}
+
+//-----------------------------------------------------------------------------
+
+#ifdef COOL280
+ITransactionPtr RalDatabase::startTransaction()
+{
+  transactionMgr()->setAutoTransactions( false );
+  return ITransactionPtr( new ManualTransaction( transactionMgr() ) );
+}
+#endif
+
+//-----------------------------------------------------------------------------
diff --git a/RelationalCool/src/RalDatabase.h b/RelationalCool/src/RalDatabase.h
new file mode 100644
index 000000000..62465c3b4
--- /dev/null
+++ b/RelationalCool/src/RalDatabase.h
@@ -0,0 +1,285 @@
+// $Id: RalDatabase.h,v 1.224 2009-01-06 12:30:07 avalassi Exp $
+#ifndef RELATIONALCOOL_RALDATABASE_H
+#define RELATIONALCOOL_RALDATABASE_H 1
+
+// Include files
+#include "RelationalAccess/ISessionProxy.h"
+
+// Local include files
+#include "CoralConnectionServiceProxy.h"
+#include "RalSessionMgr.h"
+#include "RelationalDatabase.h"
+
+namespace cool
+{
+
+  // Forward declarations
+  class RalDatabase;
+  class RalObjectMgr;
+  class RelationalObjectTableRow;
+  class RelationalSequence;
+  class RelationalTableRow;
+  class SimpleObject;
+
+  // Type definitions
+  typedef boost::shared_ptr<RalDatabase> RalDatabasePtr;
+
+  /** @class RalDatabase RalDatabase.h
+   *
+   *  RAL implementation of one COOL "condition database" instance
+   *  (deployed on a specific physical infrastructure).
+   *
+   *  @author Andrea Valassi, Sven A. Schmidt and Marco Clemencic
+   *  @date   2004-11-09
+   */
+
+  class RalDatabase : public RelationalDatabase
+                    , public boost::enable_shared_from_this<RalDatabase>
+  {
+
+    friend class MemoryConsumptionTest;
+    friend class RalDatabaseTest;
+    friend class RalDatabaseTest_extendedSpec;
+    friend class RalDatabaseTest_versioning;
+    friend class RalSequenceTest;
+    friend class RelationalObjectMgrTest;
+    friend class RelationalObjectTableTest;
+
+    // Only the RalDatabaseSvc can instantiate or delete a RalDatabase
+    friend class RalDatabaseSvc;
+
+    // Also the RalSchemaEvolution manager can access all internal methods
+    friend class RalSchemaEvolution;
+
+    // Only the boost shared pointer can delete a RalDatabase: see
+    // http://www.boost.org/libs/smart_ptr/sp_techniques.html#preventing_delete
+    class deleter;
+    friend class deleter;
+
+  public:
+
+    /// Get a CORAL MessageStream
+    coral::MessageStream& log() const 
+    {
+      return RelationalDatabase::log();
+    }
+
+    /// Returns the RAL session manager connected to the database.
+    boost::shared_ptr<RalSessionMgr> sessionMgr() const;
+
+    /// Required access mode to the database.
+    bool isReadOnly() const
+    {
+      return sessionMgr()->isReadOnly();
+    }
+
+    /// Returns the database session.
+    /// Delegated to RalSessionMgr.
+    coral::ISessionProxy& session() const;
+
+    /// Create a new folder set
+    /// Starts a transaction
+    IFolderSetPtr createFolderSet
+    ( const std::string& fullPath,
+      const std::string& description = "",
+      bool createParents = false );
+
+    /// Create a new folder set
+    /// Does not start a transaction (prefix __)
+    IFolderSetPtr __createFolderSet
+    ( const std::string& fullPath,
+      const std::string& description = "",
+      bool createParents = false );
+
+    /// Retrieve an existing folderset and return the corresponding manager
+    /// Throw an exception if the folderset does not exist
+    /// Starts a transaction
+    IFolderSetPtr getFolderSet( const std::string& fullPath );
+
+    /// Retrieve an existing folderset and return the corresponding manager
+    /// Throw an exception if the folderset does not exist
+    /// Does not start a transaction (prefix __)
+    IFolderSetPtr __getFolderSet( const std::string& fullPath );
+
+    /// Return the folderset manager for a given row
+    /// Does not start a transaction (prefix __)
+    IFolderSetPtr __getFolderSet( const RelationalTableRow& row );
+
+    /// Create a new folder and return the corresponding manager.
+    /// The ownership of the folder manager instance is shared.
+    /// Throws DatabaseNotOpen if there is no connection to the database.
+    /// Throws HvsPathHandlerException if the given path has an invalid format.
+    /// Throws NodeExists if a folder[set] with the same path already exists.
+    /// Throws an Exception if the max# of folder[set]s (9999) is exceeded.
+    /// Throws an Exception if an invalid versioning mode has been specified.
+    IFolderPtr createFolder
+    ( const std::string& fullPath,
+      const IFolderSpecification& folderSpec,
+      const std::string& description = "",
+      bool createParents = false );
+
+    /// DEPRECATED: this is likely to be removed in the next major release
+    /// (similar to the COOL133 API, with IRecordSpecification instead of
+    /// ExtendedAttributeListSpecification: use IFolderSpecification instead).
+    IFolderPtr createFolder
+    ( const std::string& fullPath,
+      const IRecordSpecification& payloadSpec,
+      const std::string& description = "",
+      FolderVersioning::Mode mode = FolderVersioning::SINGLE_VERSION,
+      bool createParents = false );
+
+    /// Create a new folder and return the corresponding manager
+    /// The ownership of the folder manager instance is shared
+    /// Does not start a transaction (prefix __)
+    IFolderPtr __createFolder
+      ( const std::string& fullPath,
+        const IRecordSpecification& payloadSpec,
+        const std::string& description = "",
+        FolderVersioning::Mode mode = FolderVersioning::SINGLE_VERSION,
+        bool createParents = false );
+    
+    /// Retrieve an existing folder and return the corresponding manager
+    /// Throw an exception if the folder does not exist
+    IFolderPtr getFolder( const std::string& fullPath );
+    
+    /// Retrieve an existing folder and return the corresponding manager
+    /// Throw an exception if the folder does not exist
+    /// Does not start a transaction (prefix __)
+    IFolderPtr __getFolder( const std::string& fullPath );
+    
+    /// Return the folder manager for a given row
+    /// Does not start a transaction (prefix __)
+    IFolderPtr __getFolder( const RelationalTableRow& row );
+
+    /// Retrieve all existing folders and folder sets
+    /// (preload the cache - used for ReadOnly connections only)
+    /// Does not start a transaction (prefix __)
+    void __preloadAllNodes();
+
+    /// Drop an existing node.
+    bool dropNode( const std::string& fullPath );
+
+    /// Drop an existing node.
+    /// Does not start a transaction (prefix __).
+    bool __dropNode( const std::string& fullPath );
+    
+    /// Get a RelationalObjectTable for the given folder.
+    /// The concrete class can only be created by the concrete database.
+    /// The RelationalFolder parameter is only used to obtain 
+    /// the associated table names and is *not* retained.
+    boost::shared_ptr<RelationalObjectTable> 
+    relationalObjectTable( const RelationalFolder& folder ) const;
+
+    /// Return the RelationalDatabasePtr
+    RelationalDatabasePtr relationalDbPtr() 
+    {
+      return shared_from_this();
+    }
+
+    /// Return the connection state of the database.
+    /// This is different from isOpen(): isConnected() refers only to the 
+    /// connection to the server, a prerequisite to the actual opening of 
+    /// a COOL "database" (which implies reading the management tables).
+    /// Delegated to RalSessionMgr.
+    bool isConnected() const;
+
+    /// (Re)connect to the database.
+    /// Delegated to RalSessionMgr.
+    void connect();
+
+    /// Close the database connection.
+    /// Delegated to RalSessionMgr.
+    void disconnect();
+
+#ifdef COOL280
+    /// Start a new transaction and enter manual transaction mode
+    virtual ITransactionPtr startTransaction();
+#endif
+
+  protected:
+
+    /// The following methods are all protected: only a RalDatabaseSvc can
+    /// instantiate or delete this class and create, drop or open a database
+
+    /// Constructor
+    /// Throws a RelationalException if the RelationalService handle is NULL.
+    /// Throws a RelationalException if a connection cannot be established.
+    RalDatabase( CoralConnectionServiceProxyPtr ppConnSvc,
+                 const DatabaseId& dbId,
+                 bool readOnly );
+
+    /// Destructor
+    virtual ~RalDatabase();
+
+    /// Create a new database with default attributes
+    /// Default attributes are those specific for a RelationalDatabase
+    /// Expose in the public API a protected RelationalDatabase method.
+    void createDatabase() {
+      return RelationalDatabase::createDatabase();
+    }
+
+    /// Create a new database with non-default attributes.
+    /// Throw a RelationalException if the given attributes are invalid.
+    void createDatabase( const IRecord& dbAttr );
+
+    /// Drop the database
+    bool dropDatabase();
+
+  private:
+
+    /// Standard constructor is private
+    RalDatabase();
+
+    /// Copy constructor is private
+    RalDatabase( const RalDatabase& rhs );
+
+    /// Assignment operator is private
+    RalDatabase& operator=( const RalDatabase& rhs );
+
+    /// Update the description for the given node
+    void updateNodeTableDescription( const std::string& fullPath,
+                                     const std::string& description ) const;
+
+    /// Drops all folders
+    bool dropAllNodes();
+
+    /// Creates a new entry in the folder table
+    /// Returns the node id of the new entry
+    UInt32 insertNodeTableRow
+    ( const std::string& fullPath,
+      const std::string& description,
+      bool createParents,
+      bool isLeaf,
+      const std::string& payloadSpecDesc,
+      FolderVersioning::Mode versioningMode );
+
+    /// Set the useTimeout flag
+    void setUseTimeout( bool flag ) { m_useTimeout = flag; }
+
+    /// Private deleter class
+    class deleter
+    {
+    public:
+      void operator()( RalDatabase* pDb ) {
+        delete pDb;
+      }
+    };
+
+  private:
+
+    /// Map of all nodes (cache - only used for ReadOnly connections)
+    /// NB Do not use IFolderPtr/IFolderSetPtr: RalDatabase is never deleted!
+    std::map< std::string, RelationalTableRow* > m_nodes;
+    
+    /// Switch on the schema change timeout (ORA-01466 problem)
+    bool m_useTimeout;
+
+    /// RAL session manager connected to the database 
+    /// (created by this instance, but ownership shared, e.g. with query mgr)
+    boost::shared_ptr<RalSessionMgr> m_sessionMgr;
+
+  };
+
+}
+
+#endif // RELATIONALCOOL_RALDATABASE_H
diff --git a/RelationalCool/src/RalDatabaseSvc.cpp b/RelationalCool/src/RalDatabaseSvc.cpp
new file mode 100644
index 000000000..c0cb1f14f
--- /dev/null
+++ b/RelationalCool/src/RalDatabaseSvc.cpp
@@ -0,0 +1,169 @@
+// $Id: RalDatabaseSvc.cpp,v 1.53 2008-11-04 11:52:10 avalassi Exp $
+
+// Include files
+#include <iostream>
+
+// Local include files
+#include "RalDatabase.h"
+#include "RalDatabaseSvc.h"
+#include "RelationalException.h"
+//#include "TimingReportMgr.h"
+#include "VersionInfo.h"
+
+// Namespace
+using namespace cool;
+
+//-----------------------------------------------------------------------------
+
+RalDatabaseSvc::RalDatabaseSvc
+( coral::IConnectionService& connSvc ) 
+  : m_log( new coral::MessageStream( "RalDatabaseSvc" ) )
+  , m_ppConnSvc( new CoralConnectionServiceProxy( &connSvc ) )
+{
+  initialize();
+}
+
+//-----------------------------------------------------------------------------
+
+void RalDatabaseSvc::initialize()
+{
+  log() << coral::Info << "Instantiate the RalDatabaseSvc"
+        << coral::MessageStream::endmsg;
+
+  // Initialize timing reports
+  //std::cout << "Initialize timing reports" << std::endl;
+  //TimingReportMgr::initialize();
+  //TimingReportMgr::startTimer( "TOTAL - RalDatabaseSvc" );
+}
+
+//-----------------------------------------------------------------------------
+
+RalDatabaseSvc::~RalDatabaseSvc()
+{  
+  log() << coral::Info << "Delete the RalDatabaseSvc..."
+        << coral::MessageStream::endmsg;
+
+  // Finalize timing reports
+  // WARNING: RalDatabaseSvc is generally not deleted (eg in PyCool)...
+  //std::cout << "Finalize timing reports" << std::endl;
+  //TimingReportMgr::stopTimer( "TOTAL - RalDatabaseSvc" );
+  //TimingReportMgr::finalize();
+
+  log() << coral::Info << "Purge the connection pool"
+        << coral::MessageStream::endmsg;
+  m_ppConnSvc->purgeConnectionPool();
+  log() << coral::Info << "Reset the ICS pointer"
+        << coral::MessageStream::endmsg;
+  m_ppConnSvc->resetICS();
+
+  log() << coral::Info << "Delete the RalDatabaseSvc... DONE"
+        << coral::MessageStream::endmsg;
+}
+
+//-----------------------------------------------------------------------------
+
+coral::MessageStream& RalDatabaseSvc::log() const
+{
+  *m_log << coral::Verbose;
+  return *m_log;
+}
+
+//-----------------------------------------------------------------------------
+
+IDatabasePtr
+RalDatabaseSvc::createDatabase( const DatabaseId& dbId ) const
+{
+  log() << "Create database" << coral::MessageStream::endmsg;
+  RalDatabase* ralDb = 0;
+  try {
+    bool readOnly = false;
+    ralDb = new RalDatabase( m_ppConnSvc, dbId, readOnly );
+    ralDb->createDatabase();
+    IDatabasePtr db ( ralDb, RalDatabase::deleter() );
+    log() << "Create database - success" << coral::MessageStream::endmsg;
+    return db;  
+  } catch ( ... ) {
+    if (ralDb) delete ralDb;
+    log() << "Create database - failure" << coral::MessageStream::endmsg;
+    throw;
+  }  
+}
+
+//-----------------------------------------------------------------------------
+
+/*
+IDatabasePtr 
+RalDatabaseSvc::createDatabase( const DatabaseId& dbId, 
+                                const coral::AttributeList& dbAttr ) const
+{
+  RalDatabase* ralDb = new RalDatabase( localContext(), dbId );
+  ralDb->createDatabase( dbAttr );
+  IDatabasePtr db ( ralDb );
+  return db;  
+}
+*/
+
+//-----------------------------------------------------------------------------
+
+IDatabasePtr RalDatabaseSvc::openDatabase( const DatabaseId& dbId, 
+                                           bool readOnly ) const
+{
+  log() << "Open database" << coral::MessageStream::endmsg;
+  RalDatabase* ralDb = 0;
+  try {
+    ralDb = new RalDatabase( m_ppConnSvc, dbId, readOnly );
+    ralDb->openDatabase();
+    IDatabasePtr db ( ralDb, RalDatabase::deleter() );
+    log() << "Open database - success" << coral::MessageStream::endmsg;
+    return db;
+  } catch ( ... ) {
+    if (ralDb) delete ralDb;
+    log() << "Open database - failure" << coral::MessageStream::endmsg;
+    throw;
+  }  
+}
+
+//-----------------------------------------------------------------------------
+
+bool RalDatabaseSvc::dropDatabase( const DatabaseId& dbId ) const
+{
+  log() << "Drop database" << coral::MessageStream::endmsg;
+  try {
+    bool readOnly = false;
+    RalDatabase db( m_ppConnSvc, dbId, readOnly );
+    // Open the database (also check if the database exists)
+    try {      
+      db.openDatabase();
+    } catch ( DatabaseDoesNotExist& /* dummy */ ) {
+      log() << "Drop database - success (database not found)"
+            << coral::MessageStream::endmsg;
+      return false;
+    }
+    // The database exists: drop it
+    bool status = db.dropDatabase();
+    log() << "Drop database - success" << coral::MessageStream::endmsg;
+    return status;
+  }
+  // Throw an exception if the database exists but cannot be dropped
+  catch ( ... ) {
+    log() << "Drop database - failure" << coral::MessageStream::endmsg;
+    throw;
+  }
+}
+
+//-----------------------------------------------------------------------------
+
+const std::string RalDatabaseSvc::serviceVersion() const
+{
+  return VersionInfo::release;
+}
+
+//-----------------------------------------------------------------------------
+
+coral::IConnectionService& RalDatabaseSvc::connectionSvc() const
+{
+  // Return the CORAL connection service PROXY!
+  return *m_ppConnSvc;
+}
+
+//-----------------------------------------------------------------------------
diff --git a/RelationalCool/src/RalDatabaseSvc.h b/RelationalCool/src/RalDatabaseSvc.h
new file mode 100644
index 000000000..918271744
--- /dev/null
+++ b/RelationalCool/src/RalDatabaseSvc.h
@@ -0,0 +1,96 @@
+// $Id: RalDatabaseSvc.h,v 1.32 2008-11-04 11:52:10 avalassi Exp $
+#ifndef RELATIONALCOOL_RALDATABASESVC_H 
+#define RELATIONALCOOL_RALDATABASESVC_H 1
+
+// Include files
+#include <memory>
+#include "CoralBase/AttributeList.h"
+#include "CoralBase/MessageStream.h"
+#include "CoolKernel/IDatabaseSvc.h"
+
+// Local include files
+#include "CoralConnectionServiceProxy.h"
+
+namespace cool 
+{
+
+  /** @class RalDatabaseSvc RalDatabaseSvc.h
+   *  
+   *  Top-level service to create, drop or open "conditions databases" 
+   *  using the RAL implementation of COOL.
+   *
+   *  Implementation as a SEAL service inspired from RelationalService.
+   *  Many thanks to Rado for his help with the SEAL component model!
+   *
+   *  This class will typically be used as a singleton in a user application.
+   *
+   *  @author Andrea Valassi, Sven A. Schmidt and Marco Clemencic
+   *  @date   2004-11-09
+   */ 
+ 
+  class RalDatabaseSvc : public IDatabaseSvc {
+    
+  public:
+
+    /// Constructor
+    RalDatabaseSvc( coral::IConnectionService& connSvc );
+    
+    /// Destructor
+    virtual ~RalDatabaseSvc();
+    
+    /// Create a new database and return the corresponding manager
+    /// Use the default database attributes for the relevant implementation
+    /// The ownership of the database manager instance is shared
+    IDatabasePtr createDatabase( const DatabaseId& dbId ) const;
+
+
+    /*
+    /// Create a new database and return the corresponding manager
+    /// Specify non-default database attributes in an attribute list
+    /// The ownership of the database manager instance is shared
+    IDatabasePtr createDatabase( const DatabaseId& dbId,
+                                 const coral::AttributeList& dbAttr ) const;
+    */
+
+    /// Open an existing database and return the corresponding manager
+    /// The ownership of the database manager instance is shared
+    IDatabasePtr openDatabase( const DatabaseId& dbId, 
+                               bool readOnly ) const;
+
+    /// Drop an existing database.
+    bool dropDatabase( const DatabaseId& dbId ) const;
+
+    /// Retrieve the version number of the database service software.
+    const std::string serviceVersion() const;
+    
+    /// Get the CORAL connection service used by the application.
+    coral::IConnectionService& connectionSvc() const;
+
+    /// Get the CORAL connection service used by the application.
+    CoralConnectionServiceProxyPtr ppConnectionSvc() const
+    {
+      return m_ppConnSvc;
+    };
+
+  private:
+
+    /// Initialize the service
+    void initialize();
+
+    /// Get a CORAL MessageStream
+    coral::MessageStream& log() const;
+
+  private:
+    
+    /// CORAL MessageStream
+    std::auto_ptr<coral::MessageStream> m_log;
+    
+    /// Shared pointer to the CORAL connection service pointer.
+    /// When the database service is deleted, this points to a null pointer.
+    CoralConnectionServiceProxyPtr m_ppConnSvc;
+
+  };
+
+}
+
+#endif // RELATIONALCOOL_RALDATABASESVC_H
diff --git a/RelationalCool/src/RalQueryMgr.cpp b/RelationalCool/src/RalQueryMgr.cpp
new file mode 100644
index 000000000..f9f5089f8
--- /dev/null
+++ b/RelationalCool/src/RalQueryMgr.cpp
@@ -0,0 +1,804 @@
+// $Id: RalQueryMgr.cpp,v 1.100 2008-11-05 14:53:32 avalassi Exp $
+
+#include <sstream>
+
+// Include files (COOL)
+#include "CoolKernel/Record.h"
+
+// Include files (query management)
+#include "CoralBase/Attribute.h"
+#include "RelationalAccess/ICursor.h"
+#include "RelationalAccess/IQuery.h"
+#include "RelationalAccess/ISchema.h"
+#include "RelationalAccess/ITable.h"
+
+// Include files (update management)
+#include "RelationalAccess/ITableDataEditor.h"
+
+// Local include files
+#include "IRelationalQueryDefinition.h"
+#include "RalBulkOperation.h"
+#include "RalCursor.h"
+#include "RalQueryMgr.h"
+#include "RalSequenceMgr.h"
+#include "RalSessionMgr.h"
+#include "RelationalException.h"
+#include "RelationalTableRow.h"
+#include "TimingReportMgr.h"
+//#include "attributeListToString.h"
+
+// Namespace
+using namespace cool;
+
+//---------------------------------------------------------------------------
+
+RalQueryMgr::RalQueryMgr( const boost::shared_ptr<RalSessionMgr>& sessionMgr )
+  : RelationalQueryMgr()
+  , m_sessionMgr( sessionMgr )
+{
+  log() << coral::Debug << "Instantiate a RalQueryMgr" 
+        << coral::MessageStream::endmsg;
+  log() << coral::Debug << "Remote database technology: '" 
+        << databaseTechnology() << "'"
+        << coral::MessageStream::endmsg;
+  m_sequenceMgr = new RalSequenceMgr( *this, m_sessionMgr );
+}
+
+//---------------------------------------------------------------------------
+
+RalQueryMgr::~RalQueryMgr()
+{
+  log() << coral::Debug << "Delete the RalQueryMgr" 
+        << coral::MessageStream::endmsg;
+  delete m_sequenceMgr;
+}
+
+//---------------------------------------------------------------------------
+
+RelationalQueryMgr* RalQueryMgr::clone() const
+{
+  log() << coral::Debug << "Clone a RalQueryMgr" 
+        << coral::MessageStream::endmsg;
+  return new RalQueryMgr( m_sessionMgr );
+}
+
+//---------------------------------------------------------------------------
+
+bool RalQueryMgr::existsTable( const std::string& tableName ) const
+{
+  return m_sessionMgr->session().nominalSchema().existsTable( tableName );
+}
+
+//---------------------------------------------------------------------------
+
+const std::vector<RelationalTableRow>
+RalQueryMgr::fetchOrderedRowsFromTables
+( const TableNamesWithAliases& tables,
+  const SelectListWithRSetSpec& columns,
+  const std::string& whereClause,
+  const coral::AttributeList& whereData,
+  const std::vector<std::string>& orderBy,
+  const std::string& description,
+  UInt32 nExp,
+  bool forUpdate ) const
+{
+  // Prepare the appropriate CORAL query
+  boost::shared_ptr<coral::AttributeList> dataBuffer;
+  std::auto_ptr<coral::IQuery> 
+    query( prepareQuery
+           ( tables, columns, whereClause, whereData, orderBy, dataBuffer ) );
+
+  // Lock the selected rows for update if required
+  if ( forUpdate ) query->setForUpdate();
+
+  // Describe the table list
+  std::stringstream tableList;
+  TableNamesWithAliases::const_iterator table;
+  for ( table = tables.begin();
+        table != tables.end();
+        table++ ) {
+    std::string tableName = table->first;
+    std::string tableAlias = table->second;    
+    if ( tableList.str() != "" ) tableList << ", ";
+    tableList << tableName;
+    if ( tableAlias != "" ) tableList << " as " << tableAlias;
+  }
+
+  // Describe the query
+  std::string msg = "";
+  if ( description != "" ) msg = " ('" + description + "')";
+
+  // Retrieve the result set into a vector of rows
+  // If required, check that exactly nExp rows are selected
+  coral::ICursor& cursor = query->execute();
+  std::vector<RelationalTableRow> rows;
+  //bool cursorHasNext = cursorNext( cursor ); // with TimingReport
+  bool cursorHasNext = cursor.next();
+  while ( cursorHasNext ) {
+    if ( nExp > 0 && rows.size() > nExp ) {
+      std::stringstream s;
+      s << "More than " << nExp << " rows selected from " 
+        << tableList.str() << msg;
+      log() << coral::Verbose 
+            << "TooManyRowsFound: " << s.str() << coral::MessageStream::endmsg; 
+      throw TooManyRowsFound( s.str(), "RalQueryMgr" );
+    }
+    RelationalTableRow row( cursor.currentRow() );
+    rows.push_back( row );
+    //cursorHasNext = cursorNext( cursor ); // with TimingReport
+    cursorHasNext = cursor.next();
+  }
+  if ( nExp > 0 ) {
+    if ( rows.size() == 0 ) {
+      std::stringstream s;
+      s << "No rows selected from " << tableList.str() << msg;
+      log() << coral::Verbose 
+            << "NoRowsFound: " << s.str() << coral::MessageStream::endmsg; 
+      throw NoRowsFound( s.str(), "RalQueryMgr" );
+    }
+    else if ( rows.size() < nExp ) {
+      std::stringstream s;
+      s << "Too few rows selected from " << tableList.str() << msg;
+      log() << coral::Verbose 
+            << "NoRowsFound: " << s.str() << coral::MessageStream::endmsg; 
+      throw NoRowsFound( s.str(), "RalQueryMgr" );
+    }
+  }
+
+  // Return the rows retrieved from the database
+  log() << "Successfully fetched " << rows.size() << " table rows"
+        << msg << coral::MessageStream::endmsg;
+  //std::vector<RelationalTableRow>::const_iterator rowIt;
+  //for ( rowIt = rows.begin(); rowIt != rows.end(); rowIt++ )
+  //  std::cout << attributeListToString( rowIt->data() ) << std::endl;
+  return rows;
+
+}
+
+//---------------------------------------------------------------------------
+
+UInt32 RalQueryMgr::countRowsFromTables
+( const TableNamesWithAliases& tables,
+  const std::string& whereClause,
+  const coral::AttributeList& whereData,
+  const std::string& description ) const
+{
+  // Create a new CORAL query
+  std::auto_ptr<coral::IQuery>
+    query( m_sessionMgr->session().nominalSchema().newQuery() );
+
+  // Describe the table list
+  std::stringstream tableList;
+  TableNamesWithAliases::const_iterator table;
+  for ( table = tables.begin();
+        table != tables.end();
+        table++ ) {
+    std::string tableName = table->first;
+    std::string tableAlias = table->second;    
+    if ( ! existsTable( tableName ) )
+      throw TableNotFound( tableName, "RalQueryMgr" );
+    if ( table->second != "" )
+      query->addToTableList( table->first, table->second );
+    else
+      query->addToTableList( table->first );
+    if ( tableList.str() != "" ) tableList << ", ";
+    tableList << table->first;
+  }
+
+  // Define the output
+  std::string countStar = "COUNT(*)"; // UPPERCASE for CORAL bug #16621
+  // TEMPORARY -- working around a bug in the SQLite backend
+  if ( m_sessionMgr->databaseTechnology() == "SQLite" ) {
+    query->addToOutputList( countStar );
+    // DANGER! CORAL will write the result set into a temporary AttributeList?
+    coral::AttributeList output;
+    output.extend( countStar, "unsigned int" );
+    query->defineOutput( output );
+  } else {
+    query->addToOutputList( countStar );
+  }
+
+  // Set the WHERE clause and bind variables
+  if ( whereClause != "" )
+    query->setCondition( whereClause, whereData );
+
+  // Retrieve a cursor over the result set
+  coral::ICursor& cursor = query->execute();
+
+  // Describe the query
+  std::string msg = "";
+  if ( description != "" ) msg = " ('" + description + "')";
+
+  // Check that at least one row is selected
+  {
+    //bool cursorHasNext = cursorNext( cursor ); // with TimingReport
+    bool cursorHasNext = cursor.next();
+    if ( ! cursorHasNext ) // CORAL bug #16621 appears here
+      throw NoRowsFound
+        ( "No rows selected from " + tableList.str() + msg, "RalQueryMgr" );
+  }
+  
+  // Retrieve the row count from the result set
+  UInt64 count;
+  const coral::Attribute& countAttr = cursor.currentRow()[ countStar ];
+  if ( m_sessionMgr->databaseTechnology() == "SQLite" ) {
+    count = countAttr.data<unsigned int>();
+  } else {
+    if ( countAttr.specification().type() == typeid(int) )
+      count = countAttr.data<int>();
+    else if ( countAttr.specification().type() == typeid(long) )
+      count = countAttr.data<long>();
+    else if ( countAttr.specification().type() == typeid(double) )
+      count = static_cast<Int64>( countAttr.data<double>() );
+    else
+      count = countAttr.data<Int64>();
+  }
+
+  // Check that only row is selected
+  {
+    //bool cursorHasNext = cursorNext( cursor ); // with TimingReport
+    bool cursorHasNext = cursor.next();
+    if ( cursorHasNext )
+      throw TooManyRowsFound
+        ( "More than one rows selected from " + tableList.str() + msg,
+          "RalQueryMgr" );
+  }
+  
+  // Return the row count retrieved from the database
+  log() << "Table row count successfully fetched" << msg 
+        << ": count=" << count << coral::MessageStream::endmsg;
+  return static_cast<UInt32>(count);
+
+}
+
+//---------------------------------------------------------------------------
+
+std::auto_ptr<coral::IQuery> RalQueryMgr::newQuery() const
+{
+  std::auto_ptr<coral::IQuery> 
+    query( m_sessionMgr->session().nominalSchema().newQuery() );
+  return query;
+}
+
+//---------------------------------------------------------------------------
+
+std::auto_ptr<coral::IQuery> 
+RalQueryMgr::prepareQuery
+( const TableNamesWithAliases& tables,
+  const SelectListWithRSetSpec& columns,
+  const std::string& whereClause,
+  const coral::AttributeList& whereData,
+  const std::vector<std::string>& orderBy,
+  boost::shared_ptr<coral::AttributeList>& dataBuffer ) const
+{
+  std::auto_ptr<coral::IQuery> query( newQuery() );
+  prepareQuery( query.get(), 
+                tables, columns, whereClause, whereData, orderBy, dataBuffer );
+  return query;
+}
+
+//---------------------------------------------------------------------------
+
+void RalQueryMgr::prepareQuery
+( coral::IQuery* query,
+  const TableNamesWithAliases& tables,
+  const SelectListWithRSetSpec& columns,
+  const std::string& whereClause,
+  const coral::AttributeList& whereData,
+  const std::vector<std::string>& orderBy,
+  boost::shared_ptr<coral::AttributeList>& dataBuffer ) const
+{
+  // Add the table names (with aliases if != "")
+  TableNamesWithAliases::const_iterator table;
+  for ( table = tables.begin();
+        table != tables.end();
+        table++ ) {
+    std::string tableName = table->first;
+    std::string tableAlias = table->second;    
+    if ( tableAlias != "THIS_IS_A_SUBQUERY" ) 
+    {
+      if ( ! existsTable( tableName ) )
+        throw TableNotFound( tableName, "RalQueryMgr" );
+    }
+    if ( tableAlias != "" && tableAlias != "THIS_IS_A_SUBQUERY" )
+      query->addToTableList( tableName, tableAlias );
+    else
+      query->addToTableList( tableName );
+  }
+
+  // Set the list of selected fields in the SELECT statement
+  const SelectList& selectList = columns.first;
+  for ( SelectList::const_iterator 
+          col = selectList.begin(); col != selectList.end(); ++col ) {
+    query->addToOutputList( *col );
+  }
+
+  // Set the aliases and C++ types of the selected fields in the result set
+  // (the AttributeList is used by CORAL as data buffer for the current row)
+  const RSetSpec& rsetSpec = columns.second;
+  dataBuffer.reset
+    ( new coral::AttributeList( Record(rsetSpec).attributeList() ) );
+  query->defineOutput( *dataBuffer );
+
+  // Set the WHERE clause and bind variables
+  if ( whereClause != "" )
+    query->setCondition( whereClause, whereData );
+
+  // Set the ORDER BY clause
+  std::vector<std::string>::const_iterator orderByColumn;
+  for ( orderByColumn = orderBy.begin();
+        orderByColumn != orderBy.end();
+        orderByColumn++ ) {
+    query->addToOrderList( *orderByColumn );
+  }
+
+  // Set the prefetch row cache size
+  int newRowCacheSize = 100;
+  query->setRowCacheSize( newRowCacheSize );
+}
+
+//---------------------------------------------------------------------------
+
+void RalQueryMgr::prepareQueryDefinition
+( coral::IQueryDefinition& coralDef,
+  const IRelationalQueryDefinition& coolDef,
+  bool countStarSubquery ) const
+{
+  // Add tables and subqueries in the FROM clause (with aliases if != "")
+  for ( unsigned item = 0; item < coolDef.getFromSize(); item++ )
+  {
+    const IRelationalQueryDefinition::IFromItem& 
+      fromItem = coolDef.getFromItem( item );
+    std::string alias = fromItem.alias();
+    if ( !fromItem.isSubquery() ) 
+    {
+      std::string tableName = fromItem.expression();
+      // TODO: fix bug #43528 
+      // [expression() may be "schema.tableName" and existsTable may fails...]
+      if ( ! existsTable( tableName ) )
+        throw TableNotFound( tableName, "RalQueryMgr" );
+      coralDef.addToTableList( tableName, alias );
+    }
+    else
+    {
+      coral::IQueryDefinition& coralSQDef = 
+        coralDef.defineSubQuery( alias );
+      prepareQueryDefinition( coralSQDef, fromItem.subquery() );
+      coralDef.addToTableList( alias );
+    }    
+  }
+
+  // Add all columns and subqueries in the SELECT list (with aliases if != "")
+  // [do this also for 'SELECT COUNT(*) FROM ( subquery )' queries]
+  for ( unsigned item = 0; item < coolDef.getSelectSize(); item++ )
+  {
+    const IRelationalQueryDefinition::ISelectItem& 
+      selectItem = coolDef.getSelectItem( item );
+    std::string alias = selectItem.alias();
+    //if ( !selectItem.isSubquery() ) 
+    {
+      std::string expression = selectItem.expression();
+      if ( item == 0 && coolDef.getHint() != "" ) 
+        expression =  coolDef.getHint() + " " + expression;
+      coralDef.addToOutputList( expression, alias );
+    }
+    //else {}
+  }
+
+  // Set the WHERE clause and bind variables
+  coralDef.setCondition( coolDef.getWhereClause(), 
+                         coolDef.getBindVariables().attributeList() );
+
+  // Add columns to the GROUP BY clause.
+  for ( unsigned item = 0; item < coolDef.getGroupSize(); item++ )
+  {
+    const IRelationalQueryDefinition::IGroupItem& 
+      groupItem = coolDef.getGroupItem( item );
+    coralDef.groupBy( groupItem.expression() );
+  }
+
+  // Add columns to the ORDER BY clause.
+  // Omit the ORDER BY clause for 'SELECT COUNT(*) FROM ( subquery )' queries.
+  if ( ! countStarSubquery ) 
+  {  
+    for ( unsigned item = 0; item < coolDef.getOrderSize(); item++ )
+    {
+      const IRelationalQueryDefinition::IOrderItem& 
+        orderItem = coolDef.getOrderItem( item );
+      coralDef.addToOrderList( orderItem.expression() );
+    }
+  }
+
+}
+
+//---------------------------------------------------------------------------
+
+std::auto_ptr<coral::IQuery> 
+RalQueryMgr::prepareQuery
+( const IRelationalQueryDefinition& coolDef,
+  boost::shared_ptr<coral::AttributeList>& dataBuffer ) const
+{
+  std::auto_ptr<coral::IQuery> query( newQuery() );
+
+  // Prepare the query definition
+  prepareQueryDefinition( *(query.get()), coolDef );
+
+  // Set the aliases and C++ types of the selected fields in the result set
+  // (the AttributeList is used by CORAL as data buffer for the current row)
+  const IRecordSpecification& resultSetSpec =
+    coolDef.getResultSetSpecification();
+  dataBuffer.reset
+    ( new coral::AttributeList( Record(resultSetSpec).attributeList() ) );
+  query->defineOutput( *dataBuffer );
+
+  // Set the prefetch row cache size
+  int newRowCacheSize = 100;
+  query->setRowCacheSize( newRowCacheSize );
+
+  // Return the query
+  return query;
+}
+
+//---------------------------------------------------------------------------
+
+IRelationalCursor* RalQueryMgr::prepareAndExecuteQuery
+( const IRelationalQueryDefinition& coolDef,
+  boost::shared_ptr<coral::AttributeList>& dataBuffer ) const
+{
+  std::auto_ptr<coral::IQuery> query( newQuery() );
+
+  // Prepare the query definition
+  prepareQueryDefinition( *(query.get()), coolDef );
+
+  // Set the aliases and C++ types of the selected fields in the result set
+  // (the AttributeList is used by CORAL as data buffer for the current row)
+  const IRecordSpecification& resultSetSpec =
+    coolDef.getResultSetSpecification();
+  dataBuffer.reset
+    ( new coral::AttributeList( Record(resultSetSpec).attributeList() ) );
+  query->defineOutput( *dataBuffer );
+
+  // Set the prefetch row cache size
+  int newRowCacheSize = 100;
+  query->setRowCacheSize( newRowCacheSize );
+
+  // Execute the CORAL query and return the wrapped cursor
+  return new RalCursor( query );
+}
+
+//---------------------------------------------------------------------------
+
+const std::vector<RelationalTableRow>
+RalQueryMgr::fetchOrderedRows
+( const IRelationalQueryDefinition& coolDef,
+  const std::string& description,
+  UInt32 nExp,
+  bool forUpdate ) const
+{
+  // Prepare the appropriate CORAL query
+  boost::shared_ptr<coral::AttributeList> dataBuffer;
+  std::auto_ptr<coral::IQuery> query( prepareQuery( coolDef, dataBuffer ) );
+
+  // Lock the selected rows for update if required
+  if ( forUpdate ) query->setForUpdate();
+
+  // Describe the table list
+  std::stringstream tableList;
+  for ( unsigned item = 0; item < coolDef.getFromSize(); item++ )
+  {
+    const IRelationalQueryDefinition::IFromItem& 
+      fromItem = coolDef.getFromItem( item );
+    std::string tableAlias = fromItem.alias();
+    std::string tableName;
+    if ( !fromItem.isSubquery() ) 
+      tableName = fromItem.expression();
+    else
+      tableName = "(SELECT ... FROM ...)";
+    if ( tableList.str() != "" ) tableList << ", ";
+    tableList << tableName;
+    if ( tableAlias != "" ) tableList << " as " << tableAlias;
+  }
+
+  // Describe the query
+  std::string msg = "";
+  if ( description != "" ) msg = " ('" + description + "')";
+
+  // Retrieve the result set into a vector of rows
+  // If required, check that exactly nExp rows are selected
+  coral::ICursor& cursor = query->execute();
+  std::vector<RelationalTableRow> rows;
+  //bool cursorHasNext = cursorNext( cursor ); // with TimingReport
+  bool cursorHasNext = cursor.next();
+  while ( cursorHasNext ) {
+    if ( nExp > 0 && rows.size() > nExp ) {
+      std::stringstream s;
+      s << "More than " << nExp << " rows selected from " 
+        << tableList.str() << msg;
+      log() << coral::Verbose 
+            << "TooManyRowsFound: " << s.str() << coral::MessageStream::endmsg; 
+      throw TooManyRowsFound( s.str(), "RalQueryMgr" );
+    }
+    RelationalTableRow row( cursor.currentRow() );
+    rows.push_back( row );
+    //cursorHasNext = cursorNext( cursor ); // with TimingReport
+    cursorHasNext = cursor.next();
+  }
+  if ( nExp > 0 ) {
+    if ( rows.size() == 0 ) {
+      std::stringstream s;
+      s << "No rows selected from " << tableList.str() << msg;
+      log() << coral::Verbose 
+            << "NoRowsFound: " << s.str() << coral::MessageStream::endmsg; 
+      throw NoRowsFound( s.str(), "RalQueryMgr" );
+    }
+    else if ( rows.size() < nExp ) {
+      std::stringstream s;
+      s << "Too few rows selected from " << tableList.str() << msg;
+      log() << coral::Verbose 
+            << "NoRowsFound: " << s.str() << coral::MessageStream::endmsg; 
+      throw NoRowsFound( s.str(), "RalQueryMgr" );
+    }
+  }
+
+  // Return the rows retrieved from the database
+  log() << "Successfully fetched " << rows.size() << " table rows"
+        << msg << coral::MessageStream::endmsg;
+  //std::vector<RelationalTableRow>::const_iterator rowIt;
+  //for ( rowIt = rows.begin(); rowIt != rows.end(); rowIt++ )
+  //  std::cout << attributeListToString( rowIt->data() ) << std::endl;
+  return rows;
+
+}
+
+//---------------------------------------------------------------------------
+
+UInt32 RalQueryMgr::countRows
+( const IRelationalQueryDefinition& coolDef,
+  const std::string& description ) const
+{
+  // Create a new CORAL query
+  std::auto_ptr<coral::IQuery>
+    query( m_sessionMgr->session().nominalSchema().newQuery() );
+
+  // Define a subquery (strictly needed only if there is a GROUP BY clause)
+  // Speed this up by removing the original ORDER BY clause [but keep the 
+  // original SELECTed columns - strictly necessary for MAX/SUM aggregates]
+  coral::IQueryDefinition& subquery = query->defineSubQuery( "subquery" );
+  bool countStarSubquery = true;
+  prepareQueryDefinition( subquery, coolDef, countStarSubquery );
+  query->addToTableList( "subquery" );
+
+  // Describe the table list
+  std::stringstream tableList;
+  for ( unsigned item = 0; item < coolDef.getFromSize(); item++ )
+  {
+    const IRelationalQueryDefinition::IFromItem& 
+      fromItem = coolDef.getFromItem( item );
+    std::string tableAlias = fromItem.alias();
+    std::string tableName;
+    if ( !fromItem.isSubquery() ) 
+      tableName = fromItem.expression();
+    else
+      tableName = "(SELECT ... FROM ...)";
+    if ( tableList.str() != "" ) tableList << ", ";
+    tableList << tableName;
+    if ( tableAlias != "" ) tableList << " as " << tableAlias;
+  }
+
+  // Define the output
+  std::string countStar = "COUNT(*)"; // UPPERCASE for CORAL bug #16621
+  // TEMPORARY -- working around a bug in the SQLite backend
+  if ( m_sessionMgr->databaseTechnology() == "SQLite" ) {
+    query->addToOutputList( countStar );
+    // DANGER! CORAL will write the result set into a temporary AttributeList?
+    coral::AttributeList output;
+    output.extend( countStar, "unsigned int" );
+    query->defineOutput( output );
+  } else {
+    query->addToOutputList( countStar );
+  }
+
+  // Retrieve a cursor over the result set
+  coral::ICursor& cursor = query->execute();
+
+  // Describe the query
+  std::string msg = "";
+  if ( description != "" ) msg = " ('" + description + "')";
+
+  // Check that at least one row is selected
+  {
+    //bool cursorHasNext = cursorNext( cursor ); // with TimingReport
+    bool cursorHasNext = cursor.next();
+    if ( ! cursorHasNext ) // CORAL bug #16621 appears here
+      throw NoRowsFound
+        ( "No rows selected from " + tableList.str() + msg, "RalQueryMgr" );
+  }
+  
+  // Retrieve the row count from the result set
+  UInt64 count;
+  const coral::Attribute& countAttr = cursor.currentRow()[ countStar ];
+  if ( m_sessionMgr->databaseTechnology() == "SQLite" ) {
+    count = countAttr.data<unsigned int>();
+  } else {
+    if ( countAttr.specification().type() == typeid(int) )
+      count = countAttr.data<int>();
+    else if ( countAttr.specification().type() == typeid(long) )
+      count = countAttr.data<long>();
+    else if ( countAttr.specification().type() == typeid(double) )
+      count = static_cast<Int64>( countAttr.data<double>() );
+    else
+      count = countAttr.data<Int64>();
+  }
+
+  // Check that only row is selected
+  {
+    //bool cursorHasNext = cursorNext( cursor ); // with TimingReport
+    bool cursorHasNext = cursor.next();
+    if ( cursorHasNext )
+      throw TooManyRowsFound
+        ( "More than one rows selected from " + tableList.str() + msg,
+          "RalQueryMgr" );
+  }
+  
+  // Return the row count retrieved from the database
+  log() << "Table row count successfully fetched" << msg 
+        << ": count=" << count << coral::MessageStream::endmsg;
+  return static_cast<UInt32>(count);
+
+}
+
+//---------------------------------------------------------------------------
+
+boost::shared_ptr<IRelationalBulkOperation> 
+RalQueryMgr::bulkInsertTableRows( const std::string& tableName,
+                                  const coral::AttributeList& dataBuffer, 
+                                  int rowCacheSize )
+{
+  coral::ITable& table =
+    m_sessionMgr->session().nominalSchema().tableHandle( tableName );
+  boost::shared_ptr<coral::IBulkOperation> coralBulkOperation
+    ( table.dataEditor().bulkInsert( dataBuffer, rowCacheSize ) );  
+  boost::shared_ptr<IRelationalBulkOperation> 
+    bulkInserter( new RalBulkOperation( coralBulkOperation ) );
+  return bulkInserter;
+}
+
+//---------------------------------------------------------------------------
+
+void RalQueryMgr::insertTableRow( const std::string& tableName,
+                                  const coral::AttributeList& data ) const
+{
+  coral::ITable& table =
+    m_sessionMgr->session().nominalSchema().tableHandle( tableName );
+  return table.dataEditor().insertRow( data );
+}
+
+//---------------------------------------------------------------------------
+
+boost::shared_ptr<IRelationalBulkOperation> 
+RalQueryMgr::bulkUpdateTableRows( const std::string& tableName,
+                                  const std::string& setClause,
+                                  const std::string& whereClause,
+                                  const coral::AttributeList& dataBuffer, 
+                                  int rowCacheSize )
+{
+  coral::ITable& table =
+    m_sessionMgr->session().nominalSchema().tableHandle( tableName );
+  boost::shared_ptr<coral::IBulkOperation> coralBulkOperation
+    ( table.dataEditor().bulkUpdateRows
+      ( setClause, whereClause, dataBuffer, rowCacheSize ) );  
+  boost::shared_ptr<IRelationalBulkOperation> 
+    bulkUpdater( new RalBulkOperation( coralBulkOperation ) );
+  return bulkUpdater;
+}
+
+//---------------------------------------------------------------------------
+
+UInt32 RalQueryMgr::updateTableRows
+( const std::string& tableName,
+  const std::string& setClause,
+  const std::string& whereClause,
+  const coral::AttributeList& updateData,
+  UInt32 nExp ) const
+{
+  coral::ITable& table =
+    m_sessionMgr->session().nominalSchema().tableHandle( tableName );
+  UInt32 nRows = 
+    table.dataEditor().updateRows( setClause, whereClause, updateData );
+  if ( nExp > 0 ) {
+    if ( nRows < nExp ) {
+      std::stringstream s;
+      s << "Could not update rows in table '" << tableName
+        << "': updated " << nRows << ", expected " << nExp;
+      throw RowNotUpdated( s.str(), "RalQueryMgr" );
+    }
+    else if ( nRows > nExp ) {
+      std::stringstream s;
+      s << "PANIC! Too many rows updated in table '" << tableName
+        << "': updated " << nRows << ", expected " << nExp;
+      throw RelationalException( s.str(), "RalQueryMgr" );
+    }
+  }
+  return nRows;
+}
+
+//---------------------------------------------------------------------------
+
+UInt32 RalQueryMgr::deleteTableRows
+( const std::string& tableName,
+  const std::string& whereClause,
+  const coral::AttributeList& whereData,
+  UInt32 nExp ) const
+{
+  UInt32 nRowsExp;
+  if ( nExp > 0 ) 
+    nRowsExp = nExp;
+  else
+    nRowsExp = countRowsFromTables
+      ( tableList( tableName ), whereClause, whereData, "" );
+  coral::ITable& table =
+    m_sessionMgr->session().nominalSchema().tableHandle( tableName );
+  UInt32 nRows =
+    table.dataEditor().deleteRows( whereClause, whereData );
+  if ( nRows < nRowsExp ) {
+    std::stringstream s;
+    s << "Could not delete rows from table '" << tableName
+      << "': deleted " << nRows << ", expected " << nRowsExp;
+    throw RowNotDeleted( s.str(), "RalQueryMgr" );
+  }
+  else if ( nRows > nRowsExp ) {
+    std::stringstream s;
+    s << "PANIC! Too many rows deleted from table '" << tableName
+      << "': deleted " << nRows << ", expected " << nRowsExp;
+    throw RelationalException( s.str(), "RalQueryMgr" );
+  }
+  return nRows;
+}
+
+//---------------------------------------------------------------------------
+
+const std::string RalQueryMgr::serverTimeClause() const
+{
+  return RelationalQueryMgr::serverTimeClause
+    ( m_sessionMgr->databaseTechnology() );
+}
+
+//---------------------------------------------------------------------------
+
+coral::ICursor& RalQueryMgr::executeQuery( coral::IQuery& query )
+{
+  if ( TimingReportMgr::isActive() )
+    TimingReportMgr::startTimer( "coral::IQuery::execute()" );
+  coral::ICursor& cursor = query.execute();  
+  if ( TimingReportMgr::isActive() )
+    TimingReportMgr::stopTimer( "coral::IQuery::execute()" );
+  return cursor;
+}
+
+//---------------------------------------------------------------------------
+
+bool RalQueryMgr::cursorNext( coral::ICursor& cursor )
+{
+  if ( TimingReportMgr::isActive() )
+    TimingReportMgr::startTimer( "coral::ICursor::next()" );
+  bool hasNext = cursor.next();
+  if ( TimingReportMgr::isActive() )
+    TimingReportMgr::stopTimer( "coral::ICursor::next()" );
+  return hasNext;
+}
+
+//---------------------------------------------------------------------------
+
+const std::string RalQueryMgr::databaseTechnology() const 
+{
+  return m_sessionMgr->databaseTechnology();
+}
+
+//---------------------------------------------------------------------------
+
+const std::string RalQueryMgr::schemaName() const 
+{
+  return m_sessionMgr->schemaName();
+}
+
+//---------------------------------------------------------------------------
diff --git a/RelationalCool/src/RalQueryMgr.h b/RelationalCool/src/RalQueryMgr.h
new file mode 100644
index 000000000..948729ed1
--- /dev/null
+++ b/RelationalCool/src/RalQueryMgr.h
@@ -0,0 +1,210 @@
+// $Id: RalQueryMgr.h,v 1.67 2008-11-04 11:52:11 avalassi Exp $
+#ifndef RELATIONALCOOL_RALQUERYMGR_H
+#define RELATIONALCOOL_RALQUERYMGR_H
+
+// Include files
+#include "RelationalAccess/IQuery.h"
+
+// Local include files
+#include "RelationalQueryMgr.h"
+
+namespace cool {  
+  
+  // Forward declarations
+  class IRelationalQueryDefinition;
+  class RalSessionMgr;
+
+  /** @class RalQueryMgr RalQueryMgr.h
+   *  
+   *  Manager of relational queries executed using RAL.
+   *  Manager of relational DML operations executed using RAL.
+   *
+   *  Transactions are NOT handled by this class.
+   *
+   *  @author Andrea Valassi and Sven A. Schmidt
+   *  @date   2005-10-11
+   */
+  
+  class RalQueryMgr : public RelationalQueryMgr {
+    
+  public:
+    
+    /// Constructor from a RalSessionMgr shared pointer.
+    RalQueryMgr( const boost::shared_ptr<RalSessionMgr>& sessionMgr );
+    
+    /// Destructor.
+    virtual ~RalQueryMgr();
+    
+    /// Clone this query manager.
+    RelationalQueryMgr* clone() const;
+    
+    /// Checks if a table exists in the schema.
+    /// Implements RelationalQueryMgr pure abstract virtual method.    
+    bool existsTable( const std::string& tableName ) const;
+
+    /// Fetch an ordered set of rows from one or more tables as a vector.
+    /// If nExp>0, throws TooManyRowsFound if more than nExp rows are found.
+    /// If nExp>0, throws an exception if fewer than nExp rows are found.
+    /// Implements RelationalQueryMgr pure abstract virtual method.     
+    const std::vector<RelationalTableRow> fetchOrderedRowsFromTables
+    ( const TableNamesWithAliases& tables,
+      const SelectListWithRSetSpec& columns,
+      const std::string& whereClause,
+      const coral::AttributeList& whereData,
+      const std::vector<std::string>& orderBy,
+      const std::string& description = "",
+      UInt32 nExp = 0,
+      bool forUpdate = false ) const;
+
+    /// Fetch a "select COUNT(*)" row count from one or more tables.
+    /// Implements RelationalQueryMgr pure abstract virtual method.     
+    UInt32 countRowsFromTables
+    ( const TableNamesWithAliases& tables,
+      const std::string& whereClause,
+      const coral::AttributeList& whereData,
+      const std::string& description = "" ) const;
+
+    /// Create a new empty CORAL query.
+    /// This is needed if subqueries must be defined for this query.
+    std::auto_ptr<coral::IQuery> newQuery() const;
+    
+    /// Prepare a CORAL query from one or more tables.
+    /// A pointer to an AttributeList data must be passed to be overwritten
+    /// (a new AL with the right spec is created and used as data buffer).
+    void prepareQuery
+    ( coral::IQuery* query,
+      const TableNamesWithAliases& tables,
+      const SelectListWithRSetSpec& columns,
+      const std::string& whereClause,
+      const coral::AttributeList& whereData,
+      const std::vector<std::string>& orderBy,
+      boost::shared_ptr<coral::AttributeList>& dataBuffer ) const;
+    
+    /// Prepare a CORAL query from one or more tables.
+    /// A pointer to an AttributeList data must be passed to be overwritten
+    /// (a new AL with the right spec is created and used as data buffer).
+    std::auto_ptr<coral::IQuery> prepareQuery
+    ( const TableNamesWithAliases& tables,
+      const SelectListWithRSetSpec& columns,
+      const std::string& whereClause,
+      const coral::AttributeList& whereData,
+      const std::vector<std::string>& orderBy,
+      boost::shared_ptr<coral::AttributeList>& dataBuffer ) const;
+    
+    /// -- NEW -- start
+    /// Prepare a CORAL query definition from one or more tables.
+    void prepareQueryDefinition
+    ( coral::IQueryDefinition& coralDef,
+      const IRelationalQueryDefinition& coolDef,
+      bool countStarSubquery = false ) const;
+    /// Prepare a CORAL query from one or more tables.
+    /// A pointer to an AttributeList data must be passed to be overwritten
+    /// (a new AL with the right spec is created and used as data buffer).
+    std::auto_ptr<coral::IQuery> prepareQuery
+    ( const IRelationalQueryDefinition& coolDef,
+      boost::shared_ptr<coral::AttributeList>& dataBuffer ) const;
+    /// Prepare and execute a CORAL query 
+    /// (and start/stop the relevant timing report).
+    /// The caller becomes the owenr of the returned cursor.
+    IRelationalCursor* prepareAndExecuteQuery
+    ( const IRelationalQueryDefinition& coolDef,
+      boost::shared_ptr<coral::AttributeList>& dataBuffer ) const;
+    /// Fetch an ordered set of rows from one or more tables as a vector.
+    /// If nExp>0, throws TooManyRowsFound if more than nExp rows are found.
+    /// If nExp>0, throws an exception if fewer than nExp rows are found.
+    /// Implements RelationalQueryMgr pure abstract virtual method.
+    const std::vector<RelationalTableRow> fetchOrderedRows
+    ( const IRelationalQueryDefinition& coolDef,
+      const std::string& description = "",
+      UInt32 nExp = 0,
+      bool forUpdate = false ) const;
+    /// Fetch a "select COUNT(*)" row count from one or more tables.
+    /// Implements RelationalQueryMgr pure abstract virtual method.
+    UInt32 countRows
+    ( const IRelationalQueryDefinition& coolDef,
+      const std::string& description = "" ) const;
+    /// -- NEW -- end    
+    
+    /// Returns a new IRelationalBulkOperation object for performing a bulk 
+    /// insert operation specifying the input data buffer and the number of 
+    /// rows that should be cached on the client.
+    boost::shared_ptr<IRelationalBulkOperation> 
+    bulkInsertTableRows( const std::string& tableName,
+                         const coral::AttributeList& dataBuffer, 
+                         int rowCacheSize );
+    
+    /// Insert one row into one table.    
+    void insertTableRow
+    ( const std::string& tableName,
+      const coral::AttributeList& data ) const;
+
+    /// Returns a new IRelationalBulkOperation object for performing a bulk 
+    /// update operation specifying the input data buffer and the number of 
+    /// rows that should be cached on the client.
+    boost::shared_ptr<IRelationalBulkOperation> 
+    bulkUpdateTableRows( const std::string& tableName,
+                         const std::string& setClause,
+                         const std::string& whereClause,
+                         const coral::AttributeList& dataBuffer, 
+                         int rowCacheSize );
+
+    /// Update rows in one table.
+    /// If nExp>0, throws an exception if more than nExp rows are updated.
+    /// If nExp>0, throws an exception if fewer than nExp rows are updated.
+    /// Implements RelationalQueryMgr pure abstract virtual method.    
+    UInt32 updateTableRows
+    ( const std::string& tableName,
+      const std::string& setClause,
+      const std::string& whereClause,
+      const coral::AttributeList& updateData,
+      UInt32 nExp = 0 ) const;
+
+    /// Delete rows from one table.
+    /// Throws an exception if #rows deleted is different from the expectation
+    /// (taken from nExp if > 0; queried internally if nExp = 0).
+    /// Implements RelationalQueryMgr pure abstract virtual method.    
+    UInt32 deleteTableRows
+    ( const std::string& tableName,
+      const std::string& whereClause,
+      const coral::AttributeList& whereData,
+      UInt32 nExp = 0 ) const;
+
+    /// Get a RelationalSequenceMgr.
+    /// Implements RelationalQueryMgr pure abstract virtual method.     
+    RelationalSequenceMgr& sequenceMgr() const 
+    {
+      return *m_sequenceMgr;
+    }
+
+    /// Build the appropriate backend-specific SQL expression
+    /// to compute the server-side time in the format used by COOL.
+    /// Implements RelationalQueryMgr pure abstract virtual method.
+    const std::string serverTimeClause() const;
+
+    /// Execute a CORAL query (and start/stop the relevant timing report)
+    static coral::ICursor& executeQuery( coral::IQuery& query );
+
+    /// Increment a CORAL cursor (and start/stop the relevant timing report)
+    static bool cursorNext( coral::ICursor& cursor );
+
+    /// Return the server technology for the current connection.
+    /// Supported technologies: "Oracle ", "MySQL", "SQLite", "frontier".
+    const std::string databaseTechnology() const;
+
+    /// Return the schema name for the current connection.
+    const std::string schemaName() const;
+
+  private:
+    
+    /// Handle to the RalSessionMgr (shared ownership)
+    boost::shared_ptr<RalSessionMgr> m_sessionMgr;
+    
+    /// RelationalSequenceMgr (owned by this instance)
+    RelationalSequenceMgr* m_sequenceMgr;
+
+  };
+  
+}
+
+#endif // RELATIONALCOOL_RALQUERYMGR_H
+
diff --git a/RelationalCool/src/RalSchemaMgr.cpp b/RelationalCool/src/RalSchemaMgr.cpp
new file mode 100644
index 000000000..5d6474f5d
--- /dev/null
+++ b/RelationalCool/src/RalSchemaMgr.cpp
@@ -0,0 +1,1033 @@
+// $Id: RalSchemaMgr.cpp,v 1.82 2008-11-04 11:52:11 avalassi Exp $
+
+// Include files
+#include "CoolKernel/Record.h"
+#include "CoralBase/Attribute.h"
+#include "CoralBase/AttributeList.h"
+#include "CoralBase/AttributeSpecification.h"
+#include "RelationalAccess/ISchema.h"
+#include "RelationalAccess/ITable.h"
+#include "RelationalAccess/ITableDataEditor.h"
+#include "RelationalAccess/ITypeConverter.h"
+
+// Local include files
+#include "HvsPathHandler.h"
+#include "RalSchemaMgr.h"
+#include "RalSessionMgr.h"
+#include "RelationalChannelTable.h"
+#include "RelationalDatabase.h"
+#include "RelationalDatabaseTable.h"
+#include "RelationalException.h"
+#include "RelationalGlobalTagTable.h"
+#include "RelationalNodeTable.h"
+#include "RelationalObjectTable.h"
+#include "RelationalObject2TagTable.h"
+#include "RelationalQueryMgr.h"
+#include "RelationalSequence.h"
+#include "RelationalSharedSequenceTable.h"
+#include "RelationalSequenceMgr.h"
+#include "RelationalTagSequence.h"
+#include "RelationalTagTable.h"
+#include "RelationalTag2TagTable.h"
+#include "VersionInfo.h"
+#include "attributeListToString.h"
+
+// *** START *** 3.0.0 schema extensions (task #4307, task #4396)
+#include "RelationalChannelTablesTable.h"
+#include "RelationalGlobalHeadTagTable.h"
+#include "RelationalGlobalUserTagTable.h"
+#include "RelationalIovTablesTable.h"
+// **** END **** 3.0.0 schema extensions (task #4307, task #4396)
+
+// Namespace
+using namespace cool;
+
+// Local type definitions
+typedef boost::shared_ptr<RelationalSequence> RelationalSequencePtr;
+
+//---------------------------------------------------------------------------
+
+void RalSchemaMgr::initialize()
+{
+  log() << coral::Debug << "Instantiate a RalSchemaMgr" 
+        << coral::MessageStream::endmsg;
+}
+
+//---------------------------------------------------------------------------
+
+RalSchemaMgr::~RalSchemaMgr()
+{
+  log() << coral::Debug << "Delete the RalSchemaMgr" 
+        << coral::MessageStream::endmsg;
+}
+
+//---------------------------------------------------------------------------
+
+coral::ISessionProxy& RalSchemaMgr::session() const
+{
+  return m_sessionMgr->session();
+}    
+
+//---------------------------------------------------------------------------
+
+bool RalSchemaMgr::dropTable( const std::string& tableName ) const
+{
+  if ( ! queryMgr().existsTable( tableName ) ) {
+    return false;
+  } else {
+    session().nominalSchema().dropTable( tableName );
+    return true;
+  }
+}
+
+//---------------------------------------------------------------------------
+
+std::auto_ptr<coral::TableDescription>
+RalSchemaMgr::createTableDescription( const std::string& tableName,
+                                      const IRecordSpecification& spec,
+                                      const std::string& primaryKey ) const
+{
+  log() << "Create the description of table " << tableName 
+        << coral::MessageStream::endmsg;
+
+  std::auto_ptr<coral::TableDescription>
+    tableDesc( new coral::TableDescription( "cool::RalSchemaMgr" ) );
+
+  tableDesc->setName( tableName );
+
+  for ( unsigned int i=0; i<spec.size(); i++ ) {
+    const IFieldSpecification& field = spec[i];
+    if ( ! isValidColumnName( field.name() ) )
+      throw InvalidColumnName
+        ( field.name(), "RalSchemaMgr::createTableDescription");
+    bool fixedSize = false;
+    int maxSize = field.storageType().maxSize(); // No bug #22543 anymore
+    tableDesc->insertColumn
+      ( field.name(), 
+        coral::AttributeSpecification::typeNameForId
+        ( field.storageType().cppType() ), maxSize, fixedSize );
+  }
+
+  if ( !primaryKey.empty() ) tableDesc->setPrimaryKey( primaryKey );
+  
+  return tableDesc;
+}
+
+//-----------------------------------------------------------------------------
+
+void RalSchemaMgr::createMainTable( const std::string& mainTableName ) const
+{
+  log() << "Create table " << mainTableName << coral::MessageStream::endmsg;
+
+  // Create the description of the main table.
+  // Create the PK (attributeName).
+  std::auto_ptr<coral::TableDescription> mainTableDesc =
+    createTableDescription
+    ( mainTableName,
+      RelationalDatabaseTable::tableSpecification(),
+      RelationalDatabaseTable::columnNames::attributeName );  
+
+  // Create the main table
+  session().nominalSchema().createTable( *mainTableDesc );
+  log() << "Created table " << mainTableName << coral::MessageStream::endmsg;
+}
+
+//-----------------------------------------------------------------------------
+
+void RalSchemaMgr::fillMainTable( const std::string& mainTableName,
+                                  const coral::AttributeList& dbAttr ) const
+{
+  log() << "Fill table " << mainTableName
+        << " with the following database attributes: " 
+        << attributeListToString( dbAttr ) << coral::MessageStream::endmsg;
+
+  // Store the database attributes in the top-level management table
+  const IRecordSpecification& spec =
+    RelationalDatabaseTable::tableSpecification();
+  coral::AttributeList data = Record( spec ).attributeList();
+  for ( coral::AttributeList::const_iterator 
+          dbAttrIt = dbAttr.begin(); dbAttrIt != dbAttr.end(); ++dbAttrIt ) 
+  {
+    RelationalDatabaseTable::columnTypes::attributeName attrName =
+      dbAttrIt->specification().name();
+    // Set the attribute name
+    data[RelationalDatabaseTable::columnNames::attributeName]
+      .data<RelationalDatabaseTable::columnTypes::attributeName>() = 
+      attrName;
+    // Set the attribute value    
+    data[RelationalDatabaseTable::columnNames::attributeValue]
+      .data<RelationalDatabaseTable::columnTypes::attributeValue>() = 
+      dbAttrIt->data<RelationalDatabaseTable::columnTypes::attributeValue>();
+    // TEMPORARY? Check that all column values are within their allowed range.
+    spec.validate(data);
+    // Insert a new row
+    log() << "Insert row: " << attributeListToString( data ) 
+          << coral::MessageStream::endmsg;
+    queryMgr().insertTableRow( mainTableName, data );
+  }
+  log() << "Filled table " << mainTableName << coral::MessageStream::endmsg;
+
+}
+
+//-----------------------------------------------------------------------------
+
+// *** START *** 3.0.0 schema extensions (task #4307)
+void RalSchemaMgr::createIovTablesTable
+//( const std::string& iovTablesTableName ) const
+( const std::string& ) const
+{
+  // TODO
+}
+    
+//-----------------------------------------------------------------------------
+
+void RalSchemaMgr::createChannelTablesTable
+//( const std::string& channelTablesTableName ) const
+( const std::string& ) const
+{
+  // TODO
+}
+// **** END **** 3.0.0 schema extensions (task #4307)
+    
+//-----------------------------------------------------------------------------
+
+void RalSchemaMgr::createNodeTable
+( const std::string& nodeTableName,
+  const std::string& defaultTablePrefix ) const
+{
+  // Create the description of the node table.
+  // Create the PK (nodeId).
+  std::auto_ptr<coral::TableDescription> nodeTableDesc =
+    createTableDescription( nodeTableName,
+                            RelationalNodeTable::tableSpecification(),
+                            RelationalNodeTable::columnNames::nodeId );
+
+  // Create the FK reference to itself (parentNodeId -> nodeId).
+  nodeTableDesc->createForeignKey
+    ( nodeTableName + "_PARENT_FK",
+      RelationalNodeTable::columnNames::nodeParentId,
+      nodeTableName,
+      RelationalNodeTable::columnNames::nodeId );
+
+  // Create a UK constraint on (nodeFullPath)
+  // [NB On Oracle this unique constraint will also create a unique index]
+  nodeTableDesc->setUniqueConstraint
+    ( RelationalNodeTable::columnNames::nodeFullPath,
+      nodeTableName+"_FULLPATH_UK" );
+  
+  // Create a UK constraint on (nodeId, parentNodeId)
+  // [NB On Oracle this unique constraint will also create a unique index]
+  // This is needed so that the TAG2TAG table can reference the NODES table
+  {
+    std::vector<std::string> ukColumns;
+    ukColumns.push_back( RelationalNodeTable::columnNames::nodeId );
+    ukColumns.push_back( RelationalNodeTable::columnNames::nodeParentId ); 
+    nodeTableDesc->setUniqueConstraint
+      ( ukColumns, nodeTableName+"_PARENT_UK" );
+  }
+  
+  // Create the node table
+  log() << "Create table " << nodeTableName << coral::MessageStream::endmsg;
+  session().nominalSchema().createTable( *nodeTableDesc );
+
+  // Create a sequence for the node table PK (will fail if it already exists)
+  std::string nodeSeqName =
+    RelationalNodeTable::sequenceName( nodeTableName );
+  log() << "Create sequence " << nodeSeqName << coral::MessageStream::endmsg;
+  RelationalSequencePtr nodeSeq
+    ( queryMgr().sequenceMgr().createSequence( nodeSeqName ) );
+
+  // Get the node ID for the root folder set from the sequence
+  unsigned int nodeId = nodeSeq->nextVal();
+  if ( nodeId != 0 )
+    throw RelationalException
+      ( "PANIC! First ID from the sequence not equal to 0?", "RalSchemaMgr" );
+  std::string nodeInsTime = nodeSeq->currDate();
+
+  // Get the name of the root folder set from the HvsPathHandler
+  HvsPathHandler handler;
+  std::string nodeUnresolvedName = handler.rootUnresolvedName();
+  std::string nodeFullPath = handler.rootFullPath();
+
+  // Prepare the root folder set row in the node table
+  const IRecordSpecification& rootSpec =
+    RelationalNodeTable::tableSpecification( false, false );
+  coral::AttributeList rootData = Record( rootSpec ).attributeList();
+  rootData[RelationalNodeTable::columnNames::nodeId]
+    .data<RelationalNodeTable::columnTypes::nodeId>() = nodeId;
+  rootData[RelationalNodeTable::columnNames::nodeName]
+    .data<RelationalNodeTable::columnTypes::nodeName>() = nodeUnresolvedName;
+  rootData[RelationalNodeTable::columnNames::nodeFullPath]
+    .data<RelationalNodeTable::columnTypes::nodeFullPath>() = nodeFullPath;
+  rootData[RelationalNodeTable::columnNames::nodeIsLeaf]
+    .data<RelationalNodeTable::columnTypes::nodeIsLeaf>() = false;
+  rootData[RelationalNodeTable::columnNames::nodeSchemaVersion]
+    .data<RelationalNodeTable::columnTypes::nodeSchemaVersion>() = 
+    VersionInfo::schemaVersion;
+  rootData[RelationalNodeTable::columnNames::nodeInsertionTime]
+    .data<RelationalNodeTable::columnTypes::nodeInsertionTime>() = nodeInsTime;
+  rootData[RelationalNodeTable::columnNames::folderVersioningMode]
+    .data<RelationalNodeTable::columnTypes::folderVersioningMode>() = 
+    FolderVersioning::NONE;
+  rootData[RelationalNodeTable::columnNames::lastModDate]
+    .data<RelationalNodeTable::columnTypes::lastModDate>() = nodeInsTime;
+
+  // TEMPORARY? Check that all column values are within their allowed range.
+  rootSpec.validate(rootData);  
+
+  // Insert the root folder set into the node table
+  queryMgr().insertTableRow( nodeTableName, rootData );
+
+  // Create the tag sequence for the root folder set
+  std::string tagSequenceName = RelationalTagSequence::sequenceName
+    ( defaultTablePrefix, nodeId );
+  createTagSequence( tagSequenceName );
+}
+
+//-----------------------------------------------------------------------------
+
+void 
+RalSchemaMgr::createGlobalTagTable( const std::string& globalTagTableName,
+                                    const std::string& nodeTableName ) const
+{
+  // Create the description of the tag table
+  std::auto_ptr<coral::TableDescription> tableDesc = 
+    createTableDescription
+    ( globalTagTableName, RelationalGlobalTagTable::tableSpecification() );
+  
+  // Create the PK (nodeId, tagId)
+  {
+    std::vector<std::string> pkColumns;
+    pkColumns.push_back( RelationalGlobalTagTable::columnNames::nodeId );
+    pkColumns.push_back( RelationalGlobalTagTable::columnNames::tagId );
+    tableDesc->setPrimaryKey( pkColumns );
+  }
+
+  /*
+  // *** START *** 3.0.0 schema extensions (task #4396)
+  // Create a UK constraint on (nodeId, tagId, tagType)
+  // [NB On Oracle this unique constraint will also create a unique index]
+  {
+    std::vector<std::string> ukColumns;
+    ukColumns.push_back( RelationalGlobalTagTable::columnNames::nodeId );
+    ukColumns.push_back( RelationalGlobalTagTable::columnNames::tagId );
+    ukColumns.push_back( RelationalGlobalTagTable::columnNames::tagType );
+    tableDesc->setUniqueConstraint
+      ( ukColumns, globalTagTableName+"_TAGTYPE_UK" );
+  }
+  // Create a NOT NULL constraint on (tagType)
+  tableDesc->setNotNullConstraint
+    ( RelationalGlobalTagTable::columnNames::tagType );
+  // Create a CHECK constraint on (tagType) = {0,1,2}
+  // ... waiting for CORAL (sr#101506) ...
+  // **** END **** 3.0.0 schema extensions (task #4396)
+  */
+
+  // Create a UK constraint on (tagName)
+  // [NB On Oracle this unique constraint will also create a unique index]
+  tableDesc->setUniqueConstraint
+    ( RelationalTagTable::columnNames::tagName,
+      globalTagTableName+"_TAGNAME_UK" );
+  
+  // Create FK reference to the NODES table (nodeId -> nodeId)
+  tableDesc->createForeignKey
+    ( globalTagTableName + "_NODEID_FK",
+      RelationalGlobalTagTable::columnNames::nodeId,
+      nodeTableName,
+      RelationalNodeTable::columnNames::nodeId );
+
+  // Create the table
+  log() << "Create table " << globalTagTableName 
+        << coral::MessageStream::endmsg;
+  session().nominalSchema().createTable( *tableDesc );
+}
+
+//-----------------------------------------------------------------------------
+
+void 
+RalSchemaMgr::createGlobalHeadTagTable
+( const std::string& globalHeadTagTableName,
+  const std::string& globalTagTableName ) const
+{
+  // Create the description of the head tag table
+  std::auto_ptr<coral::TableDescription> tableDesc = 
+    createTableDescription
+    ( globalHeadTagTableName, 
+      RelationalGlobalHeadTagTable::tableSpecification() );
+  
+  // Create the PK (nodeId, tagId)
+  {
+    std::vector<std::string> pkColumns;
+    pkColumns.push_back( RelationalGlobalHeadTagTable::columnNames::nodeId );
+    pkColumns.push_back( RelationalGlobalHeadTagTable::columnNames::tagId );
+    tableDesc->setPrimaryKey( pkColumns );
+  }
+
+  // Create FK reference to the TAGS table (nodeId, tagId, tagType)
+  {
+    std::vector<std::string> fkColumnsSrc;
+    fkColumnsSrc.push_back
+      ( RelationalGlobalHeadTagTable::columnNames::nodeId );
+    fkColumnsSrc.push_back
+      ( RelationalGlobalHeadTagTable::columnNames::tagId );
+    fkColumnsSrc.push_back
+      ( RelationalGlobalHeadTagTable::columnNames::tagType );
+    std::vector<std::string> fkColumnsTgt;
+    fkColumnsTgt.push_back
+      ( RelationalGlobalTagTable::columnNames::nodeId );
+    fkColumnsTgt.push_back
+      ( RelationalGlobalTagTable::columnNames::tagId );
+    fkColumnsTgt.push_back
+      ( RelationalGlobalTagTable::columnNames::tagType );
+    tableDesc->createForeignKey
+      ( globalHeadTagTableName + "_TAGS_FK", fkColumnsSrc,
+        globalTagTableName, fkColumnsTgt );
+  }
+  
+  // Create a CHECK constraint on (tagType) = {1}
+  // ... waiting for CORAL (sr#101506) ...
+
+  // Create the table
+  log() << "Create table " << globalHeadTagTableName 
+        << coral::MessageStream::endmsg;
+  session().nominalSchema().createTable( *tableDesc );
+}
+
+//-----------------------------------------------------------------------------
+
+void 
+RalSchemaMgr::createGlobalUserTagTable
+( const std::string& globalUserTagTableName,
+  const std::string& globalTagTableName ) const
+{
+  // Create the description of the user tag table
+  std::auto_ptr<coral::TableDescription> tableDesc = 
+    createTableDescription
+    ( globalUserTagTableName, 
+      RelationalGlobalUserTagTable::tableSpecification() );
+  
+  // Create the PK (nodeId, tagId)
+  {
+    std::vector<std::string> pkColumns;
+    pkColumns.push_back( RelationalGlobalUserTagTable::columnNames::nodeId );
+    pkColumns.push_back( RelationalGlobalUserTagTable::columnNames::tagId );
+    tableDesc->setPrimaryKey( pkColumns );
+  }
+
+  // Create FK reference to the TAGS table (nodeId, tagId, tagType)
+  {
+    std::vector<std::string> fkColumnsSrc;
+    fkColumnsSrc.push_back
+      ( RelationalGlobalUserTagTable::columnNames::nodeId );
+    fkColumnsSrc.push_back
+      ( RelationalGlobalUserTagTable::columnNames::tagId );
+    fkColumnsSrc.push_back
+      ( RelationalGlobalUserTagTable::columnNames::tagType );
+    std::vector<std::string> fkColumnsTgt;
+    fkColumnsTgt.push_back
+      ( RelationalGlobalTagTable::columnNames::nodeId );
+    fkColumnsTgt.push_back
+      ( RelationalGlobalTagTable::columnNames::tagId );
+    fkColumnsTgt.push_back
+      ( RelationalGlobalTagTable::columnNames::tagType );
+    tableDesc->createForeignKey
+      ( globalUserTagTableName + "_TAGS_FK", fkColumnsSrc,
+        globalTagTableName, fkColumnsTgt );
+  }
+  
+  // Create a CHECK constraint on (tagType) = {2}
+  // ... waiting for CORAL (sr#101506) ...
+
+  // Create the table
+  log() << "Create table " << globalUserTagTableName 
+        << coral::MessageStream::endmsg;
+  session().nominalSchema().createTable( *tableDesc );
+}
+
+//-----------------------------------------------------------------------------
+
+void 
+RalSchemaMgr::createTag2TagTable( const std::string& tag2TagTableName,
+                                  const std::string& globalTagTableName,
+                                  const std::string& nodeTableName ) const
+{
+  // Create the description of the tag2tag table
+  std::auto_ptr<coral::TableDescription> tableDesc = 
+    createTableDescription
+    ( tag2TagTableName, RelationalTag2TagTable::tableSpecification() );
+
+  // Set the primary key
+  std::vector<std::string> pkColumns;
+  pkColumns.push_back( RelationalTag2TagTable::columnNames::parentNodeId );
+  pkColumns.push_back( RelationalTag2TagTable::columnNames::parentTagId );
+  pkColumns.push_back( RelationalTag2TagTable::columnNames::childNodeId );
+  tableDesc->setPrimaryKey( pkColumns );
+
+  // Create FK reference to the NODES table for parent and child nodes
+  {
+    std::vector<std::string> fkColumnsSrc;
+    fkColumnsSrc.push_back
+      ( RelationalTag2TagTable::columnNames::childNodeId );
+    fkColumnsSrc.push_back
+      ( RelationalTag2TagTable::columnNames::parentNodeId );
+    std::vector<std::string> fkColumnsTgt;
+    fkColumnsTgt.push_back
+      ( RelationalNodeTable::columnNames::nodeId );
+    fkColumnsTgt.push_back
+      ( RelationalNodeTable::columnNames::nodeParentId );
+    tableDesc->createForeignKey
+      ( tag2TagTableName + "_NODES_FK", fkColumnsSrc,
+        nodeTableName, fkColumnsTgt );
+  }
+  
+  // Create the table
+  log() << "Create table " << tag2TagTableName << coral::MessageStream::endmsg;
+  session().nominalSchema().createTable( *tableDesc );
+
+  // Create FK reference to the TAGS table for the parent tag (nodeId, tagId)
+  // Create FK reference to the TAGS table for the child tag (nodeId, tagId)
+  createTag2TagFKs( tag2TagTableName, globalTagTableName );
+  
+  // Create a sequence for the tag2tag table insertion time (not for the PK)
+  std::string tag2TagSeqName =
+    RelationalTag2TagTable::sequenceName( tag2TagTableName );
+  log() << "Create sequence " << tag2TagSeqName 
+        << coral::MessageStream::endmsg;
+  queryMgr().sequenceMgr().createSequence( tag2TagSeqName );
+}
+
+//-----------------------------------------------------------------------------
+
+void 
+RalSchemaMgr::createTag2TagFKs( const std::string& tag2TagTableName,
+                                const std::string& globalTagTableName ) const
+{
+  coral::ITable& tag2TagTable = 
+    session().nominalSchema().tableHandle( tag2TagTableName );
+  coral::ITableSchemaEditor& editor = tag2TagTable.schemaEditor();
+  // Create FK reference to the TAGS table for the parent tag (nodeId, tagId)
+  try 
+  {  
+    std::vector<std::string> fkColumnsSrc;
+    fkColumnsSrc.push_back
+      ( RelationalTag2TagTable::columnNames::parentNodeId );
+    fkColumnsSrc.push_back
+      ( RelationalTag2TagTable::columnNames::parentTagId );
+    std::vector<std::string> fkColumnsTgt;
+    fkColumnsTgt.push_back
+      ( RelationalGlobalTagTable::columnNames::nodeId );
+    fkColumnsTgt.push_back
+      ( RelationalGlobalTagTable::columnNames::tagId );
+    log() << "Create FK constraint " << tag2TagTableName + "_PTAG_FK" 
+          << " on table " << tag2TagTableName << coral::MessageStream::endmsg;
+    editor.createForeignKey
+      ( tag2TagTableName + "_PTAG_FK", fkColumnsSrc,
+        globalTagTableName, fkColumnsTgt );
+  }
+  catch ( std::exception& e )
+  {
+    log() << coral::Error 
+          << "Exception caught: '" << e.what() 
+          << "'" << coral::MessageStream::endmsg;
+    log() << coral::Error 
+          << "Failed to create FK constraint " 
+          << tag2TagTableName + "_PTAG_FK" 
+          << " on table " << tag2TagTableName << coral::MessageStream::endmsg;
+    throw; // Re-throw (see bug #40295)
+  }
+  // Create FK reference to the TAGS table for the child tag (nodeId, tagId)
+  try 
+  {
+    std::vector<std::string> fkColumnsSrc;
+    fkColumnsSrc.push_back
+      ( RelationalTag2TagTable::columnNames::childNodeId );
+    fkColumnsSrc.push_back
+      ( RelationalTag2TagTable::columnNames::childTagId );
+    std::vector<std::string> fkColumnsTgt;
+    fkColumnsTgt.push_back
+      ( RelationalGlobalTagTable::columnNames::nodeId );
+    fkColumnsTgt.push_back
+      ( RelationalGlobalTagTable::columnNames::tagId );
+    log() << "Create FK constraint " << tag2TagTableName + "_CTAG_FK" 
+          << " on table " << tag2TagTableName << coral::MessageStream::endmsg;
+    editor.createForeignKey
+      ( tag2TagTableName + "_CTAG_FK", fkColumnsSrc,
+        globalTagTableName, fkColumnsTgt );
+  }  
+  catch ( std::exception& e )
+  {
+    log() << coral::Error 
+          << "Exception caught: '" << e.what() << "'" 
+          << coral::MessageStream::endmsg;
+    log() << coral::Error 
+          << "Failed to create FK constraint " 
+          << tag2TagTableName + "_CTAG_FK" 
+          << " on table " << tag2TagTableName << coral::MessageStream::endmsg;
+    throw; // Re-throw (see bug #40295)
+  }
+}
+
+//-----------------------------------------------------------------------------
+
+bool
+RalSchemaMgr::dropTag2TagFKs( const std::string& tag2TagTableName,
+                              bool verbose ) const
+{
+  bool status = true;
+  coral::ITable& tag2TagTable = 
+    session().nominalSchema().tableHandle( tag2TagTableName );
+  coral::ITableSchemaEditor& editor = tag2TagTable.schemaEditor();
+  // Drop FK reference to the TAGS table for the parent tag (nodeId, tagId)
+  try
+  {
+    log() << "Drop FK constraint " << tag2TagTableName + "_PTAG_FK" 
+          << " on table " << tag2TagTableName << coral::MessageStream::endmsg;
+    editor.dropForeignKey( tag2TagTableName + "_PTAG_FK" );
+  }
+  catch ( std::exception& e )
+  {
+    if ( verbose )
+    {
+      log() << coral::Error 
+            << "Exception caught: '" << e.what() << "'" 
+            << coral::MessageStream::endmsg;
+      log() << coral::Error << "Failed to drop FK constraint " 
+            << tag2TagTableName + "_PTAG_FK" 
+            << " on table " << tag2TagTableName 
+            << coral::MessageStream::endmsg;
+    }
+    status = false;
+  }
+  // Drop FK reference to the TAGS table for the child tag (nodeId, tagId)
+  try
+  {
+    log() << "Drop FK constraint " << tag2TagTableName + "_CTAG_FK" 
+          << " on table " << tag2TagTableName << coral::MessageStream::endmsg;
+    editor.dropForeignKey( tag2TagTableName + "_CTAG_FK" );
+  }
+  catch ( std::exception& e )
+  {
+    if ( verbose )
+    {
+      log() << coral::Error 
+            << "Exception caught: '" << e.what() << "'" 
+            << coral::MessageStream::endmsg;
+      log() << coral::Error << "Failed to drop FK constraint " 
+            << tag2TagTableName + "_CTAG_FK" 
+            << " on table " << tag2TagTableName 
+            << coral::MessageStream::endmsg;
+    }
+    status = false;
+  }
+  return status;
+}
+
+//-----------------------------------------------------------------------------
+
+void 
+RalSchemaMgr::createSharedSequence( const std::string& sharedSequenceName,
+                                    const std::string& nodeTableName ) const
+{
+
+  // Create the description of the shared sequence table
+  std::auto_ptr<coral::TableDescription> tableDesc = 
+    createTableDescription
+    ( sharedSequenceName, 
+      RelationalSharedSequenceTable::tableSpecification(),
+      RelationalSharedSequenceTable::columnNames::nodeId );
+
+  // Create FK reference to the NODES table (nodeId -> nodeId)
+  tableDesc->createForeignKey
+    ( sharedSequenceName + "_NODEID_FK",
+      RelationalSharedSequenceTable::columnNames::nodeId,
+      nodeTableName,
+      RelationalNodeTable::columnNames::nodeId );
+
+  // Create the table
+  log() << "Create table " << sharedSequenceName 
+        << coral::MessageStream::endmsg;
+  session().nominalSchema().createTable( *tableDesc );
+  
+}
+
+//-----------------------------------------------------------------------------
+
+void
+RalSchemaMgr::createObjectTable
+( const std::string& objectTableName,
+  const std::string& channelTableName,
+  const IRecordSpecification& payloadSpec,
+  FolderVersioning::Mode versioningMode ) const
+{
+  // Create the description of the object table
+  std::auto_ptr<coral::TableDescription> objectTableDesc =
+    createTableDescription
+    ( objectTableName,
+      RelationalObjectTable::tableSpecification( payloadSpec ),
+      RelationalObjectTable::columnNames::objectId() );
+  
+  // Index on channel ID
+  // TEMPORARY? In Oracle: one partition per channel?!
+  //std::vector< std::string > objectIndexCh;
+  //objectIndexCh.push_back( RelationalObjectTable::columnNames::channelId );
+  //objectTableDesc->createIndex
+  //  ( objectTableName+"_C_1INDX", objectIndexCh, false );
+
+  // Index on channel ID and object ID
+  // TEMPORARY? In Oracle: primary key on chID+objID, partitioned by chID?
+  std::vector< std::string > objectIndexChOb;
+  objectIndexChOb.push_back( RelationalObjectTable::columnNames::channelId() );
+  objectIndexChOb.push_back( RelationalObjectTable::columnNames::objectId() );
+  objectTableDesc->createIndex( objectTableName+"_CO_2INDX",
+                                objectIndexChOb,
+                                false );
+
+  // Index on channel ID and since
+  // TEMPORARY? In Oracle: local index on since within channel partition?!
+  //std::vector< std::string > objectIndexChSi;
+  //objectIndexChSi.push_back( RelationalObjectTable::columnNames::channelId );
+  //objectIndexChSi.push_back( RelationalObjectTable::columnNames::iovSince );
+  //objectTableDesc->createIndex
+  //  ( objectTableName+"_CS_2INDX", objectIndexChSi, false );
+
+  // Index on channel ID and since and until
+  // TEMPORARY? In Oracle: local index on since/until within channel partition?
+  std::vector< std::string > objectIndexChSiUn;
+  objectIndexChSiUn.push_back
+    ( RelationalObjectTable::columnNames::channelId() );
+  objectIndexChSiUn.push_back
+    ( RelationalObjectTable::columnNames::iovSince() );
+  objectIndexChSiUn.push_back
+    ( RelationalObjectTable::columnNames::iovUntil() );
+  objectTableDesc->createIndex( objectTableName+"_CSU_3INDX",
+                                objectIndexChSiUn,
+                                false );
+
+  // Index on since and until (new in COOL_1_3_0)
+  // Suggested by DavidF and LucaC for SV queries with no channel selection
+  // TEMPORARY? In Oracle: local index on since/until within channel partition?
+  std::vector< std::string > objectIndexSiUn;
+  objectIndexSiUn.push_back
+    ( RelationalObjectTable::columnNames::iovSince() );
+  objectIndexSiUn.push_back
+    ( RelationalObjectTable::columnNames::iovUntil() );
+  objectTableDesc->createIndex( objectTableName+"_SU_2INDX",
+                               objectIndexSiUn,
+                               false );
+
+  // Additional indices for MULTI_VERSION mode
+  if ( versioningMode == FolderVersioning::MULTI_VERSION ) 
+  {
+    // TODO: ALSO need to add a UK constraint - different from unique index
+    // See http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:36858373078604
+    {
+      std::vector<std::string> indColumns;
+      indColumns.push_back( RelationalObjectTable::columnNames::objectId() );
+      indColumns.push_back( RelationalObjectTable::columnNames::channelId() );
+      indColumns.push_back( RelationalObjectTable::columnNames::iovSince() );
+      indColumns.push_back( RelationalObjectTable::columnNames::iovUntil() );
+      bool unique = true;
+      // We are close to the maximum index name length of 31 characters here!
+      std::string indexName = objectTableName + "_OCSU_4INDX";
+      objectTableDesc->createIndex( indexName, indColumns, unique );
+    } 
+    // 5-column index for findObject(userTag) - see task #4381
+    {
+      std::vector<std::string> indColumns;
+      indColumns.push_back( RelationalObjectTable::columnNames::userTagId() );
+      indColumns.push_back( RelationalObjectTable::columnNames::newHeadId() );
+      indColumns.push_back( RelationalObjectTable::columnNames::channelId() );
+      indColumns.push_back( RelationalObjectTable::columnNames::iovSince() );
+      indColumns.push_back( RelationalObjectTable::columnNames::iovUntil() );
+      bool unique = true;
+      std::string indexName = objectTableName + "_UTAG_5INDX";
+      objectTableDesc->createIndex( indexName, indColumns, unique );
+    } 
+  }
+
+  // Create the object table
+  log() << "Create table " << objectTableName << coral::MessageStream::endmsg;
+  session().nominalSchema().createTable( *objectTableDesc );
+
+  // Create FK reference on channelId from object table to channel table
+  createObjectChannelFK( objectTableName, channelTableName ); 
+
+  // Create a sequence for the IOV table primary key
+  std::string objectSeqName =
+    RelationalObjectTable::sequenceName( objectTableName );
+
+  // Create the sequence (will fail if it already exists)
+  log() << "Create sequence " << objectSeqName << coral::MessageStream::endmsg;
+  RelationalSequencePtr objectSeq
+    ( queryMgr().sequenceMgr().createSequence( objectSeqName ) );
+
+  // Initialize the sequence: first inserted IOV will have ID=1 (not ID=0)
+  objectSeq->nextVal();
+}
+
+//-----------------------------------------------------------------------------
+
+void RalSchemaMgr::createObjectChannelFK
+( const std::string& objectTableName,
+  const std::string& channelTableName ) const
+{
+  coral::ITable& objectTable = 
+    session().nominalSchema().tableHandle( objectTableName );
+  coral::ITableSchemaEditor& editor = objectTable.schemaEditor();
+  // Create FK reference to the channel table (channelId)
+  try
+  {
+    log() << "Create FK constraint " << objectTableName + "_CHANNEL_FK" 
+          << " on table " << objectTableName << coral::MessageStream::endmsg;
+    editor.createForeignKey
+      ( objectTableName + "_CHANNEL_FK",
+        RelationalObjectTable::columnNames::channelId(),
+        channelTableName,
+        RelationalChannelTable::columnNames::channelId() );
+  }
+  catch ( std::exception& e )
+  {
+    log() << coral::Error 
+          << "Exception caught: '" << e.what() << "'" 
+          << coral::MessageStream::endmsg;
+    log() << coral::Error 
+          << "Failed to create FK constraint " 
+          << objectTableName + "_CHANNEL_FK" 
+          << " on table " << objectTableName << coral::MessageStream::endmsg;
+  }
+}
+
+//-----------------------------------------------------------------------------
+
+void RalSchemaMgr::dropObjectChannelFK
+( const std::string& objectTableName ) const
+{
+  coral::ITable& objectTable = 
+    session().nominalSchema().tableHandle( objectTableName );
+  coral::ITableSchemaEditor& editor = objectTable.schemaEditor();
+  // Drop FK reference to the channel table (channelId)
+  try
+  {
+    log() << "Drop FK constraint " << objectTableName + "_CHANNEL_FK" 
+          << " on table " << objectTableName << coral::MessageStream::endmsg;
+    editor.dropForeignKey( objectTableName + "_CHANNEL_FK" );
+  }
+  catch ( std::exception& e )
+  {
+    log() << coral::Error 
+          << "Exception caught: '" << e.what() << "'" 
+          << coral::MessageStream::endmsg;
+    log() << coral::Error 
+          << "Failed to drop FK constraint "
+          << objectTableName + "_CHANNEL_FK" 
+          << " on table " << objectTableName << coral::MessageStream::endmsg;
+  }
+}
+
+//-----------------------------------------------------------------------------
+
+void RalSchemaMgr::createTagTable( const std::string& tagTableName ) const
+{
+  // Create the description of the local tag table
+  std::auto_ptr<coral::TableDescription> tableDesc =
+    createTableDescription( tagTableName,
+                            RelationalTagTable::tableSpecification(),
+                            RelationalTagTable::columnNames::tagId );
+  
+  // Create the table
+  log() << "Create table " << tagTableName << coral::MessageStream::endmsg;
+  session().nominalSchema().createTable( *tableDesc );
+
+  // Create a unique index on (tagName)
+  // [NB this is a unique index, not a unique constraint]
+  // [NB this will be obsoleted by the 2.1.0 folder schema]
+  bool unique = true;
+  tableDesc->createIndex( tagTableName+"_NAME_UK",
+                          RelationalTagTable::columnNames::tagName,
+                          unique );
+}
+
+//-----------------------------------------------------------------------------
+
+void RalSchemaMgr::createChannelTable( const std::string& tableName ) const
+{
+  // Create the description of the local channel table
+  std::auto_ptr<coral::TableDescription> tableDesc =
+    createTableDescription( tableName,
+                            RelationalChannelTable::tableSpecification(),
+                            RelationalChannelTable::columnNames::channelId() );
+
+  // Set the unique constraint on the channel name.
+  // Note that Oracle treats "" and NULL as equivalent: multiple rows can
+  // be inserted with "" as name, without violating the UK constraint
+  // (they are all considered as NULL, and many NULLs do not violate a UK).
+  // For MySQL and SQLite we probably need to make sure a real NULL is
+  // inserted, instead of an empty string (this would also be nicer for
+  // consistency across backends, and would help in payload queries too). 
+  // Probably need a hack in the relational query mgr to make sure field="" 
+  // are translated to NULL (note that IField strings are never null - 
+  // this was exactly motivated by the Oracle feature).
+  bool unique = true;
+  tableDesc->createIndex( tableName+"_N_UK",
+                          RelationalChannelTable::columnNames::channelName(),
+                          unique );
+
+  // Create the table
+  log() << "Create table " << tableName << coral::MessageStream::endmsg;
+  session().nominalSchema().createTable( *tableDesc );
+  
+}
+
+//-----------------------------------------------------------------------------
+
+void RalSchemaMgr::createTagSequence( const std::string& seqName ) const
+{
+  // Create a sequence
+  log() << "Create sequence " << seqName << coral::MessageStream::endmsg;
+  RelationalSequencePtr sequence
+    ( queryMgr().sequenceMgr().createSequence( seqName ) );
+
+  // Initialize the sequence: first inserted row will have ID=1 (not ID=0)
+  sequence->nextVal();
+}
+
+//-----------------------------------------------------------------------------
+
+void RalSchemaMgr::createObject2TagTable
+( const std::string& obj2tagTableName,
+  const std::string& objectTableName,
+  const std::string& tagTableName ) const
+{
+  // Create the description of the local tag table
+  std::auto_ptr<coral::TableDescription> tableDesc = 
+    createTableDescription
+    ( obj2tagTableName, RelationalObject2TagTable::tableSpecification() );
+  
+  // Set the primary key
+  std::vector<std::string> pkColumns;
+  pkColumns.push_back( RelationalObject2TagTable::columnNames::tagId );
+  pkColumns.push_back( RelationalObject2TagTable::columnNames::objectId );
+  tableDesc->setPrimaryKey( pkColumns );
+
+  // Create 4D index
+  std::vector<std::string> i4Columns;
+  i4Columns.push_back( RelationalObject2TagTable::columnNames::tagId );
+  i4Columns.push_back( RelationalObject2TagTable::columnNames::channelId );
+  i4Columns.push_back( RelationalObject2TagTable::columnNames::iovSince );
+  i4Columns.push_back( RelationalObject2TagTable::columnNames::iovUntil );
+  // We are close to the maximum index name length of 31 characters here!
+  // (with a default table name of COOLTEST_F0001_IOV2TAG)
+  std::string indexName = obj2tagTableName + "_4INDX";
+  tableDesc->createIndex( indexName, i4Columns );
+
+  // Create the foreign key constraints
+  // TEMPORARY! Disabled: this FK needs a corresponding PK/UK constraint
+  // (which we don't have yet, just a unique index, which does not suffice)
+  // Foreign key #1
+  /*
+    std::vector<std::string> fk1Columns;
+    fk1Columns.push_back( RelationalObject2TagTable::columnNames::objectId );
+    fk1Columns.push_back( RelationalObject2TagTable::columnNames::channelId );
+    fk1Columns.push_back( RelationalObject2TagTable::columnNames::iovSince );
+    fk1Columns.push_back( RelationalObject2TagTable::columnNames::iovUntil );
+    std::string fk1TargetTable = objectTableName;
+    std::vector<std::string> fk1TargetColumns;
+    fk1TargetColumns.push_back( RelationalObjectTable::columnNames::objectId );
+    fk1TargetColumns.push_back( RelationalObjectTable::columnNames::channelId );
+    fk1TargetColumns.push_back( RelationalObjectTable::columnNames::iovSince );
+    fk1TargetColumns.push_back( RelationalObjectTable::columnNames::iovUntil );
+    std::string fk1ConstraintName = tableName + "_OCSU_FK";
+    if ( ! tableDesc->createForeignKey
+    ( fk1ConstraintName, fk1Columns, fk1TargetTable, fk1TargetColumns ) )
+    throw RelationalException( "Could not create FK", "RalSchemaMgr" );
+  */
+  // Foreign key #2
+  std::vector<std::string> fk2Columns;
+  fk2Columns.push_back( RelationalObject2TagTable::columnNames::objectId );
+  std::string fk2TargetTable = objectTableName;
+  std::string fk2ConstraintName = obj2tagTableName + "_O_FK";
+  tableDesc->createForeignKey( fk2ConstraintName,
+                              fk2Columns,
+                              fk2TargetTable,
+                              fk2Columns );
+  // Foreign key #3
+  std::vector<std::string> fk3Columns;
+  fk3Columns.push_back( RelationalObject2TagTable::columnNames::tagId );
+  std::string fk3TargetTable = tagTableName;
+  std::string fk3ConstraintName = obj2tagTableName + "_T_FK";
+  tableDesc->createForeignKey( fk3ConstraintName,
+                              fk3Columns,
+                              fk3TargetTable,
+                              fk3Columns );
+
+  // Create the table
+  log() << "Create table " << obj2tagTableName << coral::MessageStream::endmsg;
+  session().nominalSchema().createTable( *tableDesc );
+}
+
+//-----------------------------------------------------------------------------
+
+void RalSchemaMgr::renameColumnInTable
+( const std::string& tableName,
+  const std::string& oldColumnName,
+  const std::string& newColumnName ) const
+{
+  if ( ! isValidColumnName( newColumnName ) ) 
+    throw InvalidColumnName
+      ( newColumnName, "RalSchemaMgr::renameColumnInTable");  
+
+  coral::ITable& table =
+    session().nominalSchema().tableHandle( tableName );
+
+  table.schemaEditor().renameColumn( oldColumnName, newColumnName );
+}
+
+//-----------------------------------------------------------------------------
+
+void RalSchemaMgr::addColumnsToTable
+( const std::string& tableName,
+  const IRecord& columns ) const
+{
+
+  // Get a table handle
+  coral::ITable& table =
+    session().nominalSchema().tableHandle( tableName );
+
+  // Prepare the set clause for setting the default values
+  std::string setClause;
+
+  // Loop over all columns and add them one by one
+  const IRecordSpecification& spec = columns.specification();
+  for ( UInt32 i = 0; i < spec.size(); i++ ) 
+  {
+    const IField& column = columns[i];
+
+    const std::string& columnName = column.specification().name();
+    const StorageType::TypeId columnTypeId = column.specification().storageType().id();
+
+    if ( ! isValidColumnName( columnName ) ) 
+      throw InvalidColumnName
+        ( columnName, "RalSchemaMgr::addColumnToTable");
+
+    const StorageType& columnType = StorageType::storageType( columnTypeId );  
+    const std::string columnTypeName = 
+      coral::AttributeSpecification::typeNameForId( columnType.cppType() );
+    int maxSize = columnType.maxSize();
+    bool fixedSize = false;
+    table.schemaEditor().insertColumn
+      ( columnName, columnTypeName, maxSize, fixedSize );
+
+    if ( setClause != "" ) setClause += ", ";    
+    setClause += columnName + " = :" + columnName;
+
+  }  
+
+  // Set the default values for the new columns in all existing rows
+  std::string whereClause = "";
+  const coral::AttributeList& updateData = columns.attributeList();
+  table.dataEditor().updateRows( setClause, whereClause, updateData );
+
+}
+
+//-----------------------------------------------------------------------------
+
diff --git a/RelationalCool/src/RalSchemaMgr.h b/RelationalCool/src/RalSchemaMgr.h
new file mode 100644
index 000000000..1c5be6492
--- /dev/null
+++ b/RelationalCool/src/RalSchemaMgr.h
@@ -0,0 +1,184 @@
+// $Id: RalSchemaMgr.h,v 1.28 2008-11-04 11:52:11 avalassi Exp $
+#ifndef RELATIONALCOOL_RALSCHEMAMGR_H
+#define RELATIONALCOOL_RALSCHEMAMGR_H
+
+// Include files
+#include <boost/shared_ptr.hpp>
+#include "RelationalAccess/ISessionProxy.h"
+
+// Local include files
+#include "RelationalSchemaMgr.h"
+
+namespace cool {  
+  
+  // Forward declarations
+  class RalSessionMgr;
+
+  /** @class RalSchemaMgr RalSchemaMgr.h
+   *
+   *  CORAL implementation of the manager
+   *  of the COOL relational database schema.
+   *
+   *  @author Andrea Valassi, Sven A. Schmidt and Marco Clemencic
+   *  @date   2006-03-10 
+  */
+  
+  class RalSchemaMgr : public RelationalSchemaMgr
+  {
+    
+  public:
+
+    /// Constructor from a RelationalDatabase and a RalSessionMgr
+    /// Inlined with the base class non-standard constructor as otherwise 
+    /// the compiler attempts to use the base class standard constructor
+    /// (Windows compilation error C2248: standard constructor is private)
+    RalSchemaMgr( const RelationalDatabase& aDb,
+                  const boost::shared_ptr<RalSessionMgr>& sessionMgr )
+      : RelationalSchemaMgr( aDb )
+      , m_sessionMgr( sessionMgr ) 
+    {
+      initialize();
+    }
+
+    /// Destructor
+    virtual ~RalSchemaMgr();
+
+    /// Drop a table (return false if the table does not exist)
+    bool dropTable( const std::string& tableName ) const;
+
+    /// Creates a CORAL table description from a RecordSpecification
+    std::auto_ptr<coral::TableDescription> createTableDescription
+    ( const std::string& tableName,
+      const IRecordSpecification& payloadSpec,
+      const std::string& primaryKey = "" ) const;
+
+    /// Creates the main table
+    void createMainTable( const std::string& tableName ) const;
+
+    /// Fill the main table
+    void fillMainTable( const std::string& tableName,
+                        const coral::AttributeList& dbAttr ) const;
+
+    /// Creates the iovTables table
+    void createIovTablesTable
+    ( const std::string& iovTablesTableName ) const;
+
+    /// Creates the channelTables table
+    void createChannelTablesTable
+    ( const std::string& channelTablesTableName ) const;
+
+    /// Creates the node table
+    /// TEMPORARY - pass the table prefix to create the root fs tag sequence
+    void createNodeTable( const std::string& nodeTableName,
+                          const std::string& defaultTablePrefix ) const;
+    
+    /// Creates the global tag table    
+    void createGlobalTagTable( const std::string& globalTagTableName,
+                               const std::string& nodeTableName ) const;
+
+    /// Creates the global head tag table
+    void createGlobalHeadTagTable
+    ( const std::string& globalHeadTagTableName,
+      const std::string& globalTagTableName ) const;
+
+    /// Creates the global user tag table
+    void createGlobalUserTagTable
+    ( const std::string& globalUserTagTableName,
+      const std::string& globalTagTableName ) const;
+
+    /// Creates the tag2tag HVS table    
+    void createTag2TagTable( const std::string& tag2tagTableName,
+                             const std::string& globalTagTableName, 
+                             const std::string& nodeTableName ) const;
+
+    /// Creates the tag2tag HVS table FK references to the tag table
+    /// *** This is needed by the coolReplicateDB utility ***    
+    void createTag2TagFKs( const std::string& tag2tagTableName,
+                           const std::string& globalTagTableName ) const;
+    
+    /// Creates the tag2tag HVS table FK references to the tag table
+    /// *** This is needed by the coolReplicateDB utility ***
+    bool dropTag2TagFKs( const std::string& tag2tagTableName,
+                               bool verbose = true ) const;
+
+    /// Creates a shared sequence table    
+    void createSharedSequence( const std::string& sharedSequenceName,
+                               const std::string& nodeTableName ) const;
+
+    /// Creates the tag sequence for a node
+    void createTagSequence( const std::string& seqName ) const;
+
+    /// Creates the tag table for a leaf node
+    void createTagTable( const std::string& tableName ) const;
+
+    /// Creates the channel table for a leaf node
+    void createChannelTable( const std::string& tableName ) const;
+    
+    /// Creates the object2tag (iov2tag) table for a leaf node
+    void createObject2TagTable
+    ( const std::string& object2tagTableName,
+      const std::string& objectTableName,
+      const std::string& tagTableName ) const;
+
+    /// Creates the object (iov) table for a leaf node
+    void createObjectTable
+    ( const std::string& objectTableName,
+      const std::string& channelTableName,
+      const IRecordSpecification& payloadSpec,
+      FolderVersioning::Mode versioningMode ) const;
+
+    /// Creates the FK references from the object table to the channel table
+    /// *** This is needed by the coolReplicateDB utility ***
+    void createObjectChannelFK( const std::string& objectTableName,
+                                const std::string& channelTableName ) const;
+    
+    /// Drops the FK reference from the object table to the channel table
+    /// *** This is needed by the coolReplicateDB utility ***
+    void dropObjectChannelFK( const std::string& objectTableName ) const;
+
+    /// Rename a column of the given table
+    void renameColumnInTable( const std::string& tableName,
+                              const std::string& oldColumnName,
+                              const std::string& newColumnName ) const;
+
+    /// Add columns to the given table
+    void addColumnsToTable( const std::string& tableName,
+                            const IRecord& columnSpecAndValues ) const;
+    
+  private:
+
+    /// Initialize (complete non-standard constructor with non-inlined code)
+    void initialize();
+    
+    /// Standard constructor is private
+    RalSchemaMgr(); 
+
+    /// Copy constructor is private
+    RalSchemaMgr( const RalSchemaMgr& rhs ); 
+
+    /// Assignment operator is private
+    RalSchemaMgr& operator=( const RalSchemaMgr& rhs ); 
+   
+    /// Returns the database session
+    /// Delegated to RalSessionMgr.
+    coral::ISessionProxy& session() const;
+
+    /// Return the server technology for the current connection.
+    /// Delegated to RalSessionMgr.
+    const std::string& databaseTechnology() const;
+
+    /// Returns the server version for the current connection.
+    /// Delegated to RalSessionMgr.
+    const std::string& serverVersion() const;
+
+  private:
+    
+    /// Handle to the RalSessionMgr (shared ownership)
+    boost::shared_ptr<RalSessionMgr> m_sessionMgr;
+    
+  };
+  
+}
+
+#endif // RELATIONALCOOL_RALSCHEMAMGR_H
+
diff --git a/RelationalCool/src/RalSequenceMgr.cpp b/RelationalCool/src/RalSequenceMgr.cpp
new file mode 100644
index 000000000..2e3845a1b
--- /dev/null
+++ b/RelationalCool/src/RalSequenceMgr.cpp
@@ -0,0 +1,142 @@
+// $Id: RalSequenceMgr.cpp,v 1.20 2008-11-04 11:52:11 avalassi Exp $
+
+// Include files
+#include "CoralBase/MessageStream.h"
+#include "CoralBase/Attribute.h"
+#include "CoralBase/AttributeList.h"
+//#include "RelationalAccess/ICursor.h"
+#include "RelationalAccess/IQuery.h"
+#include "RelationalAccess/ISchema.h"
+#include "RelationalAccess/ITable.h"
+#include "RelationalAccess/ITableDataEditor.h"
+#include "RelationalAccess/ITransaction.h"
+#include "RelationalAccess/TableDescription.h"
+#include "CoolKernel/Record.h"
+#include "CoolKernel/RecordSpecification.h"
+
+// Local include files
+#include "RalSequenceMgr.h"
+#include "RalSchemaMgr.h"
+#include "RalSessionMgr.h"
+#include "RelationalSequence.h"
+#include "RelationalSequenceTable.h"
+#include "timeToString.h"
+#include "uppercaseString.h"
+
+// Namespace
+using namespace cool;
+
+//---------------------------------------------------------------------------
+
+void RalSequenceMgr::initialize()
+{
+  log() << coral::Debug << "Instantiate a RalSequenceMgr" << coral::MessageStream::endmsg;
+}
+
+//---------------------------------------------------------------------------
+
+RalSequenceMgr::~RalSequenceMgr()
+{
+  log() << coral::Debug << "Delete the RalSequenceMgr" << coral::MessageStream::endmsg;
+}
+
+//---------------------------------------------------------------------------
+
+boost::shared_ptr<RelationalSequence> 
+RalSequenceMgr::createSequence
+( const std::string& seqName )
+{
+  log() << coral::Verbose << "Create sequence " << seqName << coral::MessageStream::endmsg;
+
+  // Create the description of the sequence table
+  // TEMPORARY? Add a sequenceName column only to workaround a RAL bug
+  log() << coral::Verbose 
+        << "Create the description of table " << seqName << coral::MessageStream::endmsg;
+  coral::TableDescription desc( "cool::RalSequenceMgr" );
+  
+  desc.setName( seqName );
+  
+  const IRecordSpecification& spec = 
+    RelationalSequenceTable::tableSpecification();
+  for ( unsigned int i=0; i<spec.size(); i++ ) {
+    const IFieldSpecification& field = spec[i];
+    bool variableSize = false;
+    desc.insertColumn
+      ( field.name(), 
+        coral::AttributeSpecification::typeNameForId
+        ( field.storageType().cppType() ), 
+        field.storageType().maxSize(), variableSize );
+  }
+  desc.setPrimaryKey( RelationalSequenceTable::columnNames::sequenceName );
+  
+  // Create the sequence
+  log() << coral::Verbose << "Create table " << seqName << coral::MessageStream::endmsg;
+  coral::ITable& table =
+    m_sessionMgr->session().nominalSchema().createTable( desc );
+
+  // Insert into the sequence table one row that has a null value
+  // (insert an AttributeList where the attribute to set as NULL is absent)
+  bool seqNameOnly = true;
+  const IRecordSpecification& dataSpec =
+    RelationalSequenceTable::tableSpecification( seqNameOnly );
+  coral::AttributeList data = Record( dataSpec ).attributeList();
+  data[RelationalSequenceTable::columnNames::sequenceName]
+    .data<RelationalSequenceTable::columnTypes::sequenceName>() = seqName;
+  
+  // TEMPORARY? Will RAL do this as well?
+  // Check that all column values are within their allowed range
+  dataSpec.validate(data);
+
+  // Insert a new row
+  table.dataEditor().insertRow( data );
+
+  // Return the sequence instance
+  return getSequence( seqName );
+}
+
+//-----------------------------------------------------------------------------
+
+bool RalSequenceMgr::existsSequence
+( const std::string& name )
+{
+  log() << coral::Verbose 
+        << "Check existence of sequence " << name << coral::MessageStream::endmsg;
+  return m_sessionMgr->session().nominalSchema().existsTable( name );
+}
+
+//-----------------------------------------------------------------------------
+
+boost::shared_ptr<RelationalSequence>
+RalSequenceMgr::getSequence
+( const std::string& name )
+{
+  log() << coral::Verbose << "Get sequence " << name << coral::MessageStream::endmsg;
+
+  // TEMPORARY! Store MySQL now() __ AS IS __ ASSUMING IT IS GMT!
+  // MySQL does not handle timezones until 4.1.3
+  //std::cout << "dbTech: " << m_sessionMgr->databaseTechnology() << std::endl;
+  if ( m_sessionMgr->databaseTechnology() == "MySQL" ) 
+  {
+    static bool first = true;
+    if ( first ) {
+      first = false;
+      log() << coral::Warning
+            << "COOL will ASSUME that your MySQL server is configured to use "
+            << "GMT times" << coral::MessageStream::endmsg;
+    }
+  }
+
+  // Return the sequence instance
+  return RelationalSequenceMgr::instantiateSequence( name );
+}
+
+//-----------------------------------------------------------------------------
+
+void RalSequenceMgr::dropSequence
+( const std::string& name )
+{
+  log() << coral::Verbose << "Drop sequence " << name << coral::MessageStream::endmsg;
+  m_sessionMgr->session().nominalSchema().dropTable( name );
+}
+
+//-----------------------------------------------------------------------------
diff --git a/RelationalCool/src/RalSequenceMgr.h b/RelationalCool/src/RalSequenceMgr.h
new file mode 100644
index 000000000..083ad61f1
--- /dev/null
+++ b/RelationalCool/src/RalSequenceMgr.h
@@ -0,0 +1,81 @@
+// $Id: RalSequenceMgr.h,v 1.8 2008-11-04 11:52:11 avalassi Exp $
+#ifndef RELATIONALCOOL_RALSEQUENCEMGR_H
+#define RELATIONALCOOL_RALSEQUENCEMGR_H
+
+// Local include files
+#include "RelationalSequenceMgr.h"
+
+namespace cool {  
+  
+  // Forward declarations
+  class RalSessionMgr;
+
+  /** @class RalSequenceMgr RalSequenceMgr.h
+   *
+   *  CORAL implementation of a manager of COOL relational 'sequences'.
+   * 
+   *  Transactions are NOT handled by this class.
+   *
+   *  @author Andrea Valassi and Marco Clemencic
+   *  @date   2006-03-10 
+  */
+  
+  class RalSequenceMgr : public RelationalSequenceMgr
+  {
+    
+  public:
+
+    /// Constructor from a RelationalQueryMgr and a RalSessionMgr
+    /// Inlined with the base class non-standard constructor as otherwise 
+    /// the compiler attempts to use the base class standard constructor
+    /// (Windows compilation error C2248: standard constructor is private)
+    RalSequenceMgr( const RelationalQueryMgr& aQueryMgr,
+                    const boost::shared_ptr<RalSessionMgr>& sessionMgr )
+      : RelationalSequenceMgr( aQueryMgr )
+      , m_sessionMgr( sessionMgr ) 
+    {
+      initialize();
+    }    
+
+    /// Destructor
+    virtual ~RalSequenceMgr();
+
+    /// Create a new sequence (ownership of the C++ instance is shared).
+    boost::shared_ptr<RelationalSequence> 
+    createSequence( const std::string& name );
+
+    /// Does this sequence exist?
+    bool existsSequence( const std::string& name );
+
+    /// Get an existing sequence (ownership of the C++ instance is shared).
+    boost::shared_ptr<RelationalSequence>
+    getSequence( const std::string& name );
+
+    /// Drop an existing sequence
+    void dropSequence( const std::string& name );
+
+  private:
+
+    /// Initialize (complete non-standard constructor with non-inlined code)
+    void initialize();
+
+    /// Standard constructor is private
+    RalSequenceMgr(); 
+
+    /// Copy constructor is private
+    RalSequenceMgr( const RalSequenceMgr& rhs ); 
+
+    /// Assignment operator is private
+    RalSequenceMgr& operator=( const RalSequenceMgr& rhs ); 
+   
+  private:
+    
+    /// Handle to the RalSessionMgr (shared ownership)
+    boost::shared_ptr<RalSessionMgr> m_sessionMgr;
+    
+  };
+  
+}
+
+#endif // RELATIONALCOOL_RALSEQUENCEMGR_H
+
diff --git a/RelationalCool/src/RalSessionMgr.cpp b/RelationalCool/src/RalSessionMgr.cpp
new file mode 100644
index 000000000..9880fc2b6
--- /dev/null
+++ b/RelationalCool/src/RalSessionMgr.cpp
@@ -0,0 +1,349 @@
+// $Id: RalSessionMgr.cpp,v 1.34 2008-11-06 11:18:27 avalassi Exp $
+
+// Include files
+#include <cstdlib>
+#include "RelationalAccess/IConnectionServiceConfiguration.h"
+#include "RelationalAccess/IRelationalDomain.h"
+#include "RelationalAccess/IRelationalService.h"
+#include "RelationalAccess/ITransaction.h"
+
+// Local include files
+#include "RalSessionMgr.h"
+#include "RelationalException.h"
+#include "TimingReportMgr.h"
+
+// Namespace
+using namespace cool;
+
+//-----------------------------------------------------------------------------
+
+/// \todo FIX-ME: I do not like this, but it looks like it is the only way
+/// of using SQLite if you do not have the appropriate lines in the
+/// authentication.xml file.
+std::string cool::RalConnectionString( const RelationalDatabaseId& dbId ) 
+{
+  std::string connectString = dbId.middleTier();
+  if ( dbId.alias().empty() ) 
+  {
+    if ( dbId.technology() == "sqlite" )
+      connectString += 
+        "sqlite_file:" + dbId.schema();
+    else
+      connectString += 
+        dbId.technology() + "://" + dbId.server() + "/" + dbId.schema();
+  }
+  else
+    connectString += dbId.alias();
+  return connectString;
+}
+
+//-----------------------------------------------------------------------------
+
+RalSessionMgr::RalSessionMgr( CoralConnectionServiceProxyPtr ppConnSvc,
+                              const DatabaseId& dbId,
+                              bool readOnly )
+  : m_ppConnSvc( ppConnSvc )
+  , m_relationalDbId( dbId ) 
+  , m_log( new coral::MessageStream( "RalSessionMgr" ) )
+  , m_session( 0 )
+  , m_readOnly( readOnly )
+{
+  std::string ro = ( m_readOnly ? "R/O" : "R/W" );
+  log() << coral::Info << "Instantiate a " << ro << " RalSessionMgr for '" 
+        << m_relationalDbId.urlHidePswd() << "'" << coral::MessageStream::endmsg;  
+  
+  // Create the appropriate RAL session and connect to the database server
+  connect();
+}
+
+//-----------------------------------------------------------------------------
+
+RalSessionMgr::~RalSessionMgr() 
+{
+  
+  log() << coral::Info << "Delete the RalSessionMgr for '" 
+        << m_relationalDbId.urlHidePswd() << "'" << coral::MessageStream::endmsg;  
+
+  // Disconnect from the database server and delete the RAL session
+  disconnect();
+  
+}
+ 
+//-----------------------------------------------------------------------------
+
+const std::string RalSessionMgr::databaseTechnology() const 
+{
+#ifdef NOCORAL210
+  return m_session->properties().flavorName();
+#else
+  return m_session->remoteProperties().flavorName();
+#endif
+}
+
+//-----------------------------------------------------------------------------
+
+const std::string RalSessionMgr::serverVersion() const 
+{
+#ifdef NOCORAL210
+  return m_session->properties().serverVersion();
+#else
+  return m_session->remoteProperties().serverVersion();
+#endif
+}
+
+//-----------------------------------------------------------------------------
+
+bool RalSessionMgr::isConnected() const
+{
+  return ( m_session != 0 );
+}
+
+//-----------------------------------------------------------------------------
+
+coral::IConnectionService& RalSessionMgr::connectionSvc() const
+{
+  // Disable the CORAL connection pool automatic cleanup if requested
+  static bool first = true;
+  if ( first ) 
+  {
+    first = false;
+    if ( getenv( "COOL_DISABLE_CORALCONNECTIONPOOLCLEANUP" ) ) 
+    {
+      m_ppConnSvc->configuration().disablePoolAutomaticCleanUp();
+      m_ppConnSvc->configuration().setConnectionTimeOut( 0 );
+    }
+  }
+  // Return the CORAL connection service PROXY!
+  return *m_ppConnSvc;
+}
+
+//-----------------------------------------------------------------------------
+
+inline static int SetEnv( const std::string& name, const std::string& value )
+{
+#ifndef WIN32
+  // UNIX version
+  return value.empty() ?
+    ::unsetenv(name.c_str()) , 0 :
+    ::setenv(name.c_str(),value.c_str(), 1);
+#else
+  // Windows version
+  return ::_putenv((name+"="+value).c_str());
+#endif
+}
+
+//-----------------------------------------------------------------------------
+
+void RalSessionMgr::connect()
+{
+  if ( ! isConnected() ) 
+  {
+    if ( getenv ( "COOL_TIMINGREPORT" ) )
+    {
+      TimingReportMgr::initialize();
+      TimingReportMgr::startTimer( "EXTRA cool::RalSessionMgr::connect()" );
+    }
+    
+    log() << coral::Info 
+          << "Connect to the database server" << coral::MessageStream::endmsg;
+
+    bool environmentAuthenticationUsed = false;
+    std::auto_ptr<std::string> old_env_content[2];
+
+    std::string ralConnectString = RalConnectionString( m_relationalDbId );
+    // To pass user and password to CORAL ConnectionService we can only
+    // use the environment
+    if ( m_relationalDbId.technology() != "sqlite" &&
+         m_relationalDbId.password() != "" && m_relationalDbId.user() != "" ) {
+      log() << "explicit credentials in the connection string: I use them"
+            << coral::MessageStream::endmsg;
+      log() << coral::Warning 
+            << "You are using explicit credentials in the connection string"
+            << ": this is deprecated"
+            << ", please use either XML or LFC based authentication"
+            << coral::MessageStream::endmsg;
+      
+      // if the user specified _BOTH_ user name and password, we can use the
+      // environment variables to pass those values to CORAL
+      environmentAuthenticationUsed = true; // to know that I have to
+      // revert to old values
+        
+      // keep a copy of the old env values
+      char *tmp = ::getenv("CORAL_AUTH_USER");
+      if (tmp) 
+        old_env_content[0] = 
+          std::auto_ptr<std::string>( new std::string(tmp) );
+      tmp = ::getenv("CORAL_AUTH_PASSWORD");
+      if (tmp) 
+        old_env_content[1] = 
+          std::auto_ptr<std::string>( new std::string(tmp) );
+      
+      // put new values in the environment variables
+      if ( SetEnv("CORAL_AUTH_USER", m_relationalDbId.user()) < 0 ||
+           SetEnv("CORAL_AUTH_PASSWORD",m_relationalDbId.password()) < 0 ) {
+        // something went wrong with the environment :-(
+        // revert to old values and forget
+        log() << coral::Warning <<
+          "Problems when trying to set authentication env. variables, ignoring"
+          " specified credentials." << coral::MessageStream::endmsg;
+        if ( old_env_content[0].get() ) {
+          SetEnv("CORAL_AUTH_USER", *(old_env_content[0]));
+        } else {
+          SetEnv("CORAL_AUTH_USER", "");
+        }
+        if ( old_env_content[1].get() ) {
+          SetEnv("CORAL_AUTH_PASSWORD", *(old_env_content[1]));
+        } else {
+          SetEnv("CORAL_AUTH_PASSWORD", "");
+        }
+        environmentAuthenticationUsed = false;
+      }
+    }
+
+    if ( environmentAuthenticationUsed ) 
+    {
+      connectionSvc().configuration().
+        setAuthenticationService
+        ( "CORAL/Services/EnvironmentAuthenticationService" );
+    }
+
+    // get the session proxy
+    coral::AccessMode accessMode;
+    if ( m_readOnly ) accessMode = coral::ReadOnly;
+    else accessMode = coral::Update;
+    if ( m_relationalDbId.role().empty() ) {
+      m_session = connectionSvc().connect( ralConnectString, 
+                                           accessMode );
+    } else {
+      m_session = connectionSvc().connect( ralConnectString,
+                                           m_relationalDbId.role(),
+                                           accessMode );
+    }
+
+    if ( environmentAuthenticationUsed ) {
+      // revert to old values
+      if ( old_env_content[0].get() ) {
+        SetEnv( "CORAL_AUTH_USER", *( old_env_content[0] ) );
+      } else {
+        SetEnv( "CORAL_AUTH_USER", "" );
+      }
+      if ( old_env_content[1].get() ) {
+        SetEnv( "CORAL_AUTH_PASSWORD", *(old_env_content[1]) );
+      } else {
+        SetEnv( "CORAL_AUTH_PASSWORD", "" );
+      }
+    }
+    
+    if ( !m_session ) {
+      throw RelationalException( "Failed to connect to the server",
+                                 "RalSessionMgr::connect" );
+    }
+
+    log() << "Connection established successfully" << coral::MessageStream::endmsg;
+
+    // In ReaOnly mode start a single transaction for the duration of
+    // the session (all other clients use a dummy transaction manager).
+    //if ( m_readOnly ) 
+    if ( m_readOnly && !getenv ( "COOL_READONLYSESSION_MANYTRANSACTIONS" ) ) 
+    {  
+      log() << coral::Info 
+            << "Start a read-only transaction active"
+            << " for the duration of the database connection" << coral::MessageStream::endmsg;
+      session().transaction().start( m_readOnly );
+    }
+
+    if ( TimingReportMgr::isActive() )
+    {
+      TimingReportMgr::stopTimer( "EXTRA cool::RalSessionMgr::connect()" );
+      TimingReportMgr::finalize();
+    }
+    
+  }
+}
+
+//-----------------------------------------------------------------------------
+
+void RalSessionMgr::disconnect()
+{
+  if ( getenv ( "COOL_TIMINGREPORT" ) )
+  {
+    TimingReportMgr::initialize();
+    TimingReportMgr::startTimer( "EXTRA cool::RalSessionMgr::disconnect()" );
+  }
+  
+  if ( isConnected() ) {
+
+    // In Update mode there should be no active transactions unless the 
+    // session manager is being killed as a result of an exception thrown.
+    // Check if there is an open transactaion, and in that case rollback
+    // (do not rollback all the time, else CORAL will issue a warning!).
+    if ( ! m_readOnly ) {
+      if ( session().transaction().isActive() ) 
+      {
+        log() << coral::Warning
+              << "Active transactions found while disconnecting" 
+              << " from an Update session will be rolled back"
+              << coral::MessageStream::endmsg;
+        session().transaction().rollback();
+      }
+    }
+    // In ReaOnly mode there should be one active transaction.
+    else 
+    {
+      if ( session().transaction().isActive() ) 
+      {
+        log() << coral::Info 
+              << "Commit the read-only transaction active"
+              << " for the duration of the database connection" << coral::MessageStream::endmsg;
+        session().transaction().commit();
+      }
+      else 
+      {        
+        log() << coral::Warning
+              << "PANIC! No active transactions found while disconnecting" 
+              << " from a ReadOnly session"
+              << coral::MessageStream::endmsg;
+      }
+    }
+    
+    // Disconnect from the database server
+    log() << coral::Info 
+          << "Disconnect from the database server" << coral::MessageStream::endmsg;
+    delete m_session;
+    m_session = 0;
+
+  }
+  
+  // TEMPORARY? Should/will be done by CORAL inside ~ISessionProxy?
+  // Purge the CORAL connection pool (see task #3546) to ensure 
+  // that the connection is physically dropped if the timeout is 0
+  try { m_ppConnSvc->purgeConnectionPool(); } catch( ... ){ }  
+
+  if ( TimingReportMgr::isActive() )
+  {
+    TimingReportMgr::stopTimer( "EXTRA cool::RalSessionMgr::disconnect()" );
+    TimingReportMgr::finalize();
+  }
+
+}
+
+//-----------------------------------------------------------------------------
+
+coral::MessageStream& RalSessionMgr::log() 
+{
+  *m_log << coral::Verbose;
+  return *m_log;
+}
+
+//-----------------------------------------------------------------------------
+
+coral::ISessionProxy& RalSessionMgr::session() const
+{
+  if ( isConnected() )
+    return *m_session;
+  else
+    throw RelationalException
+      ( "Not connected to the database server", "RalSessionMgr" );
+}
+
+//-----------------------------------------------------------------------------
diff --git a/RelationalCool/src/RalSessionMgr.h b/RelationalCool/src/RalSessionMgr.h
new file mode 100644
index 000000000..9a26671f1
--- /dev/null
+++ b/RelationalCool/src/RalSessionMgr.h
@@ -0,0 +1,135 @@
+// $Id: RalSessionMgr.h,v 1.25 2008-11-04 11:52:11 avalassi Exp $
+#ifndef RELATIONALCOOL_RALSESSIONMGR_H
+#define RELATIONALCOOL_RALSESSIONMGR_H
+
+// Include files
+#include <memory>
+#include <boost/shared_ptr.hpp>
+#include "CoolKernel/DatabaseId.h"
+#include "CoralBase/MessageStream.h"
+#include "RelationalAccess/AccessMode.h"
+#include "RelationalAccess/IConnectionService.h"
+#include "RelationalAccess/ISchema.h"
+#include "RelationalAccess/ISessionProxy.h"
+#include "RelationalAccess/ISessionProperties.h"
+
+// Local include files
+#include "CoralConnectionServiceProxy.h"
+#include "RelationalDatabaseId.h"
+
+namespace cool {  
+  
+  std::string RalConnectionString( const RelationalDatabaseId& dbId );
+
+  /** @class RalSessionMgr RalSessionMgr.h
+   *  
+   *  Manager of relational database connections via a RAL session.
+   *
+   *  This class knows nothing about COOL tables.
+   *  It is only concerned with relational database connections.
+   *
+   *  @author Andrea Valassi, Sven A. Schmidt and Marco Clemencic
+   *  @date   2005-10-24
+   */
+  
+  class RalSessionMgr {
+    
+  public:
+    
+    /// The constructor automatically connects to the database.
+    RalSessionMgr( CoralConnectionServiceProxyPtr ppConnSvc,
+                   const DatabaseId& dbId,
+                   bool readOnly );
+    
+    /// The destructor automatically disconnects from the database.
+    virtual ~RalSessionMgr();
+
+    /// Return the server technology for the current connection.
+    /// Supported technologies: "Oracle", "MySQL", "SQLite", "frontier".
+    /// This ultimately corresponds to coral::IDomain::flavorName()
+    /// (grep m_flavorName in the four XxxAccess/src/Domain.cpp),
+    /// because it is equal to ConnectionHandle::technologyName(), 
+    /// which is equal to ConnectionParams::technologyName(), which is
+    /// set to IDomain::flavorName() in ReplicaCatalogue::getReplicas.
+    /// *** WARNING!!! THIS MAY CHANGE IN LATER VERSIONS OF THE CODE!!! ***
+    /// New (not for production!): for URLs using a middle tier, this method
+    /// returns the properties of the remote database, not of the middle tier
+    const std::string databaseTechnology() const;
+
+    /// Return the server technology version for the current connection.
+    /// This ultimately corresponds to coral::IConnection::serverVersion()
+    /// (grep serverVersion in the four XxxAccess/src/Connection.cpp),
+    /// because it is equal to ConnectionHandle::serverVersion(), 
+    /// which is equal to IConnection::serverVersion().
+    /// *** WARNING!!! THIS MAY CHANGE IN LATER VERSIONS OF THE CODE!!! ***
+    /// New (not for production!): for URLs using a middle tier, this method
+    /// returns the properties of the remote database, not of the middle tier
+    const std::string serverVersion() const;
+
+    /// Return the schema name for the current connection.
+    inline std::string schemaName() const 
+    {
+      return m_session->nominalSchema().schemaName();
+    }
+
+    /// Return the connection state of the database.
+    /// [Note that this is subtly different from RelationalDatabase::isOpen!]
+    bool isConnected() const;
+
+    /// (Re)connect to the database.
+    void connect();
+
+    /// Close the database connection.
+    void disconnect();
+    
+    /// Get a reference to the RAL database session.
+    /// Throw an exception if there is no connection to the database.
+    coral::ISessionProxy& session() const;
+
+    /// Get a CORAL MessageStream
+    coral::MessageStream& log();
+
+    /// Required access mode to the database.
+    bool isReadOnly() const
+    {
+      return m_readOnly;
+    }
+
+  private:
+
+    /// Standard constructor is private
+    RalSessionMgr(); 
+
+    /// Copy constructor is private
+    RalSessionMgr( const RalSessionMgr& rhs ); 
+
+    /// Assignment operator is private
+    RalSessionMgr& operator=( const RalSessionMgr& rhs ); 
+   
+  private:
+
+    /// Get a reference to the CORAL connection service.
+    coral::IConnectionService& connectionSvc() const;
+    
+    /// Shared pointer to the CORAL connection service pointer.
+    /// When the database service is deleted, this points to a null pointer.
+    CoralConnectionServiceProxyPtr m_ppConnSvc;
+
+    /// Global identifier of the database
+    RelationalDatabaseId m_relationalDbId;
+
+    /// SEAL MessageStream
+    std::auto_ptr<coral::MessageStream> m_log;
+
+    /// RAL session (owned by this instance) connected to the database 
+    coral::ISessionProxy* m_session;
+
+    /// Required access mode to the database
+    bool m_readOnly;
+
+  };
+  
+}
+
+#endif // RELATIONALCOOL_RALSESSIONMGR_H
+
diff --git a/RelationalCool/src/RalTransactionMgr.cpp b/RelationalCool/src/RalTransactionMgr.cpp
new file mode 100644
index 000000000..1f431775b
--- /dev/null
+++ b/RelationalCool/src/RalTransactionMgr.cpp
@@ -0,0 +1,114 @@
+// $Id: RalTransactionMgr.cpp,v 1.8 2008-11-04 11:52:11 avalassi Exp $
+
+// Include files
+#include <string>
+#include "RelationalAccess/ITransaction.h"
+
+// Local include files
+#include "RalSessionMgr.h"
+#include "RalTransactionMgr.h"
+#include "RelationalException.h"
+
+// Namespace
+using namespace cool;
+
+//-----------------------------------------------------------------------------
+
+RalTransactionMgr::RalTransactionMgr
+( const boost::shared_ptr<RalSessionMgr>& sessionMgr, bool autoTransactions )
+  : m_sessionMgr( sessionMgr ) 
+  , m_autoTransactions( autoTransactions )
+{
+  m_sessionMgr->log() << "Instantiate a RalTransactionMgr" << coral::MessageStream::endmsg;
+  if ( ! autoTransactions ) {
+    //std::cout << "auto transation handling disabled" << std::endl;
+  }
+}
+
+//-----------------------------------------------------------------------------
+
+RalTransactionMgr::~RalTransactionMgr() 
+{
+  m_sessionMgr->log() << "Delete the RalTransactionMgr" << coral::MessageStream::endmsg;  
+}
+
+//-----------------------------------------------------------------------------
+
+void RalTransactionMgr::start
+( bool readOnly )
+{
+  std::string msg;
+  if( readOnly ) msg = "read-only transaction";
+  else msg = "read-write transaction";  
+  m_sessionMgr->log() << "Start a new " << msg << coral::MessageStream::endmsg;  
+  if ( !readOnly && m_sessionMgr->isReadOnly() )
+    throw DatabaseOpenInReadOnlyMode( "RalTransactionMgr" );
+  // in case of manual transactions only initiate a new one if none is active
+  // (there is no start transaction hook)
+  if ( autoTransactions() ) {
+    m_sessionMgr->session().transaction().start( readOnly );
+  } else {
+    //std::cout << "start " << msg << " called in semi-manual mode" << std::endl;
+    if ( ! isActive() ) {
+      //std::cout << "starting new " << msg << std::endl;
+      m_sessionMgr->session().transaction().start( readOnly );
+    } else {
+      if ( isReadOnly() ) {
+        //std::cout << "read-only transaction already active" << std::endl;
+        if ( ! readOnly ) {
+          //std::cout << "starting new " << msg << std::endl;
+          m_sessionMgr->session().transaction().start( readOnly );
+        }
+      }
+    }
+  }
+  //std::cout << "transaction started" << std::endl;
+}
+
+//-----------------------------------------------------------------------------
+
+void RalTransactionMgr::commit() 
+{
+  m_sessionMgr->log() << "Commit any open transaction" << coral::MessageStream::endmsg;
+  if ( isActive() ) {
+    if ( autoTransactions() ) {
+      // auto transactions always commit
+      m_sessionMgr->session().transaction().commit();
+    } else if ( isReadOnly() ) {
+      // semi-manual transactions only commit if they are read-only
+      // (this is the 'semi' part of manual: only r/w transactions are
+      // manually committed)
+      m_sessionMgr->session().transaction().commit();
+    }
+  }
+}
+
+//-----------------------------------------------------------------------------
+
+void RalTransactionMgr::rollback() 
+{
+  m_sessionMgr->log() << "Rollback any open transaction" << coral::MessageStream::endmsg;
+  // Better not to check if the transaction is active or not.
+  // If there is no active transaction, CORAL will issue a warning.
+  if ( autoTransactions() ) {
+    m_sessionMgr->session().transaction().rollback();
+    //std::cout << "transaction rolled back" << std::endl;
+  }
+}
+
+//-----------------------------------------------------------------------------
+
+bool RalTransactionMgr::isActive() 
+{
+  return m_sessionMgr->session().transaction().isActive();
+}
+
+//-----------------------------------------------------------------------------
+
+bool RalTransactionMgr::isReadOnly() 
+{
+  return m_sessionMgr->session().transaction().isReadOnly();
+}
+
+//-----------------------------------------------------------------------------
+
diff --git a/RelationalCool/src/RalTransactionMgr.h b/RelationalCool/src/RalTransactionMgr.h
new file mode 100644
index 000000000..8661fa443
--- /dev/null
+++ b/RelationalCool/src/RalTransactionMgr.h
@@ -0,0 +1,78 @@
+// $Id: RalTransactionMgr.h,v 1.6 2008-11-04 11:52:11 avalassi Exp $
+#ifndef RELATIONALCOOL_RALTRANSACTIONMGR_H
+#define RELATIONALCOOL_RALTRANSACTIONMGR_H
+
+// Include files
+#include <boost/shared_ptr.hpp>
+
+// Local include files
+#include "IRelationalTransactionMgr.h"
+
+namespace cool {  
+  
+  // Forward declarations
+  class RalSessionMgr;
+
+  /** @class RalTransactionMgr RalTransactionMgr.h
+   *  
+   *  RAL implementation of a manager of relational database transactions.
+   * 
+   *  @author Andrea Valassi
+   *  @date   2006-03-10
+  */
+  
+  class RalTransactionMgr : public IRelationalTransactionMgr {
+    
+  public:
+
+    /// Destructor
+    virtual ~RalTransactionMgr();
+
+    /// Constructor from a RalSessionMgr
+    RalTransactionMgr( const boost::shared_ptr<RalSessionMgr>& sessionMgr,
+                       bool autoTransactions = true );
+
+  private:
+    
+    /// Standard constructor is private
+    RalTransactionMgr();
+    
+    /// Copy constructor is private
+    RalTransactionMgr( const RalTransactionMgr& rhs );
+    
+    /// Assignment operator is private
+    RalTransactionMgr& operator=( const RalTransactionMgr& rhs );
+
+  protected:
+
+    /// Start a transaction
+    void start( bool readOnly );
+    
+    /// Commit a transaction
+    void commit();
+    
+    /// Rollback a transaction
+    void rollback();
+
+    /// Is the transaction active?
+    bool isActive();
+    
+    /// Is the transaction read-only?
+    bool isReadOnly();
+    
+    void setAutoTransactions( bool flag ) { m_autoTransactions = flag; }
+    bool autoTransactions() const { return m_autoTransactions; }
+    
+  private:
+      
+    /// Handle to the RalSessionMgr (shared ownership)
+    boost::shared_ptr<RalSessionMgr> m_sessionMgr;
+
+    bool m_autoTransactions;
+    
+  };
+  
+}
+
+#endif // RELATIONALCOOL_RALTRANSACTIONMGR_H
+
diff --git a/RelationalCool/src/RelationalChannelTable.cpp b/RelationalCool/src/RelationalChannelTable.cpp
new file mode 100644
index 000000000..11243f7b7
--- /dev/null
+++ b/RelationalCool/src/RelationalChannelTable.cpp
@@ -0,0 +1,188 @@
+// $Id: RelationalChannelTable.cpp,v 1.11 2008-03-20 18:30:19 marcocle Exp $
+
+// Include files
+#include "CoolKernel/RecordSpecification.h"
+#include "CoralBase/Attribute.h"
+//#include "CoralBase/AttributeList.h"
+
+// Local include files
+#include "RelationalChannelTable.h"
+#include "RelationalDatabase.h"
+#include "RelationalFolder.h"
+#include "RelationalQueryMgr.h"
+#include "RelationalTableRow.h"
+
+using namespace cool;
+
+//---------------------------------------------------------------------------
+
+RelationalChannelTable::RelationalChannelTable
+( const RelationalDatabase& db,
+  const RelationalFolder& folder )
+  : m_log( new coral::MessageStream( "RelationalChannelTable" ) )
+  , m_queryMgr( db.queryMgr() )
+  , m_tableName( folder.channelTableName() )
+{
+}
+
+//-----------------------------------------------------------------------------
+
+const cool::IRecordSpecification&
+RelationalChannelTable::tableSpecification()
+{
+
+  static RecordSpecification spec;
+
+  if ( spec.size() == 0 )
+  {
+    spec.extend( RelationalChannelTable::columnNames::channelId(),  
+                 RelationalChannelTable::columnTypeIds::channelId );
+    spec.extend( RelationalChannelTable::columnNames::lastObjectId(),   
+                 RelationalChannelTable::columnTypeIds::lastObjectId );
+    spec.extend( RelationalChannelTable::columnNames::hasNewData(),
+                 RelationalChannelTable::columnTypeIds::hasNewData );
+    spec.extend( RelationalChannelTable::columnNames::channelName(),
+                 RelationalChannelTable::columnTypeIds::channelName );
+    spec.extend( RelationalChannelTable::columnNames::description(),
+                 RelationalChannelTable::columnTypeIds::description );
+  }
+  
+  return spec;  
+
+}
+
+//-----------------------------------------------------------------------------
+
+const RelationalTableRow
+RelationalChannelTable::fetchRowForId( const ChannelId& channelId ) const
+{
+  log() << "Fetch channel row from table " << tableName()
+        << " for channel_id=" << channelId << coral::MessageStream::endmsg;
+
+  // Define the WHERE clause for the selection using bind variables
+  coral::AttributeList whereData;
+  whereData.extend( "channelId",
+                    typeIdToCoralType
+                    (RelationalChannelTable::columnTypeIds::channelId) );
+  whereData["channelId"].setValue( channelId );
+  std::string whereClause = RelationalChannelTable::columnNames::channelId();
+  whereClause += "= :channelId";
+  
+  // Delegate the query to the RelationalQueryMgr
+  std::string desc = "";
+  return queryMgr().fetchRowFromTables
+    ( RelationalQueryMgr::tableList( tableName() ), 
+      RelationalQueryMgr::columnList( tableSpecification() ),
+      whereClause, whereData, desc );
+}
+
+//-----------------------------------------------------------------------------
+
+const RelationalTableRow
+RelationalChannelTable::fetchRowForChannelName
+( const std::string& channelName ) const
+{
+  log() << "Fetch channel row from table " << tableName()
+        << " for channel_name=" << channelName << coral::MessageStream::endmsg;
+  
+  // Define the WHERE clause for the selection using bind variables
+  coral::AttributeList whereData;
+  whereData.extend( "channelName",
+                    typeIdToCoralType
+                    (RelationalChannelTable::columnTypeIds::channelName) );
+  whereData["channelName"].setValue( channelName );
+  std::string whereClause = RelationalChannelTable::columnNames::channelName();
+  whereClause += "= :channelName";
+  
+  // Delegate the query to the RelationalQueryMgr
+  std::string desc = "";
+  return queryMgr().fetchRowFromTables
+    ( RelationalQueryMgr::tableList( tableName() ), 
+      RelationalQueryMgr::columnList( tableSpecification() ),
+      whereClause, whereData, desc );
+}
+
+//---------------------------------------------------------------------------
+
+const std::vector<ChannelId> RelationalChannelTable::listChannels() const
+{
+  log() << "List all channels from table " << tableName() << coral::MessageStream::endmsg;
+
+  RecordSpecification rsetSpec;
+  rsetSpec.extend
+    ( RelationalChannelTable::columnNames::channelId(),
+      RelationalChannelTable::columnTypeIds::channelId );
+
+  std::string whereClause; // empty WHERE clause (all channels)
+  coral::AttributeList whereData;
+
+  std::vector<std::string> orderBy;
+  orderBy.push_back
+    ( RelationalChannelTable::columnNames::channelId() + " ASC" );
+
+  std::vector<RelationalTableRow> rows = 
+    queryMgr().fetchOrderedRowsFromTables
+    ( RelationalQueryMgr::tableList( tableName() ), 
+      RelationalQueryMgr::columnList( rsetSpec ),
+      whereClause, whereData, orderBy, "" );
+
+  std::vector<ChannelId> channels;
+  for ( std::vector<RelationalTableRow>::const_iterator
+          row = rows.begin(); row != rows.end(); ++row ) 
+  {
+    ChannelId channel = 
+      ( *row )[ RelationalChannelTable::columnNames::channelId() ]
+      .data<ChannelId>();
+    channels.push_back( channel );
+  }  
+  return channels;
+
+}
+
+//---------------------------------------------------------------------------
+
+const std::map<ChannelId,std::string> 
+RelationalChannelTable::listChannelsWithNames() const
+{
+  log() << "List all channels with names from table " 
+        << tableName() << coral::MessageStream::endmsg;
+
+  RecordSpecification rsetSpec;
+  rsetSpec.extend
+    ( RelationalChannelTable::columnNames::channelId(),
+      RelationalChannelTable::columnTypeIds::channelId );
+  rsetSpec.extend
+    ( RelationalChannelTable::columnNames::channelName(),
+      RelationalChannelTable::columnTypeIds::channelName );
+
+  std::string whereClause; // empty WHERE clause (all channels)
+  coral::AttributeList whereData;
+
+  std::vector<std::string> orderBy;
+  orderBy.push_back
+    ( RelationalChannelTable::columnNames::channelId() + " ASC" );
+
+  std::vector<RelationalTableRow> rows = 
+    queryMgr().fetchOrderedRowsFromTables
+    ( RelationalQueryMgr::tableList( tableName() ), 
+      RelationalQueryMgr::columnList( rsetSpec ),
+      whereClause, whereData, orderBy, "" );
+
+  std::map<ChannelId,std::string> channelsWithNames;
+  for ( std::vector<RelationalTableRow>::const_iterator
+          row = rows.begin(); row != rows.end(); ++row ) 
+  {
+    ChannelId channelId = 
+      ( *row )[ RelationalChannelTable::columnNames::channelId() ]
+      .data<ChannelId>();
+    std::string channelName = 
+      ( *row )[ RelationalChannelTable::columnNames::channelName() ]
+      .data<std::string>();
+    channelsWithNames[channelId]=channelName;
+  }  
+  return channelsWithNames;
+
+}
+
+//---------------------------------------------------------------------------
+
diff --git a/RelationalCool/src/RelationalChannelTable.h b/RelationalCool/src/RelationalChannelTable.h
new file mode 100644
index 000000000..71b376530
--- /dev/null
+++ b/RelationalCool/src/RelationalChannelTable.h
@@ -0,0 +1,114 @@
+// $Id: RelationalChannelTable.h,v 1.13 2008-11-04 11:52:11 avalassi Exp $
+#ifndef RELATIONALCOOL_RELATIONALCHANNELTABLE_H
+#define RELATIONALCOOL_RELATIONALCHANNELTABLE_H
+
+// Include files
+#include <map>
+#include <memory>
+#include <string>
+#include <vector>
+#include "CoralBase/MessageStream.h"
+#include "CoolKernel/ChannelId.h"
+#include "CoolKernel/StorageType.h"
+
+// Local iclude files
+#include "uppercaseString.h"
+
+namespace cool {  
+  
+  // Forward declarations
+  class IRecordSpecification;
+  class RelationalDatabase;
+  class RelationalFolder;
+  class RelationalQueryMgr;
+  class RelationalTableRow;
+  
+  /** @namespace RelationalChannelTable RelationalChannelTable.h
+   *  
+   *  Relational schema of the table storing COOL channel metadata.
+   *
+   *  @author Sven A. Schmidt and Marco Clemencic
+   *  @date   2006-04-27
+   */
+  
+  class RelationalChannelTable {
+    
+  public:
+    
+    RelationalChannelTable( const RelationalDatabase& db,
+                            const RelationalFolder& folder );
+    
+    static const std::string defaultTableName
+    ( const std::string& prefix, unsigned nodeId ) {
+      char tableName[] = "Fxxxx_CHANNELS";
+      sprintf( tableName, "F%4.4i_CHANNELS", nodeId );
+      // TEMPORARY? AV 04.04.2005 
+      // FIXME: presently the input prefix is uppercase anyway...
+      return uppercaseString( prefix ) + std::string( tableName );
+    }    
+
+    struct columnNames {
+      static const std::string channelId() { return "CHANNEL_ID"; }
+      static const std::string lastObjectId() { return "LAST_OBJECT_ID"; }
+      static const std::string hasNewData() { return "HAS_NEW_DATA"; }
+      static const std::string channelName() { return "CHANNEL_NAME"; }   
+      static const std::string description() { return "DESCRIPTION"; }   
+    };
+
+    struct columnTypeIds {
+      static const StorageType::TypeId channelId    = StorageType::UInt32;
+      static const StorageType::TypeId lastObjectId = StorageType::UInt32;
+      static const StorageType::TypeId hasNewData   = StorageType::Bool;
+      static const StorageType::TypeId channelName  = StorageType::String255;
+      static const StorageType::TypeId description  = StorageType::String255;
+    };
+
+    struct columnTypes {
+      typedef UInt32    channelId;
+      typedef UInt32    lastObjectId;
+      typedef Bool      hasNewData;
+      typedef String255 channelName;
+      typedef String255 description;
+    };
+    
+    /// Get the record specification of the channel table
+    static const IRecordSpecification& tableSpecification();
+    
+    /// Fetches the channel table row for the given channel id.
+    const RelationalTableRow 
+    fetchRowForId( const ChannelId& channelId ) const;
+    
+    /// Fetches the channel table row for the given channel name.
+    const RelationalTableRow 
+    fetchRowForChannelName( const std::string& channelName ) const;
+    
+    /// Lists channels (fetches all rows)
+    const std::vector<ChannelId> listChannels() const;
+    
+    /// Lists channels with names (fetches all rows)
+    const std::map<ChannelId,std::string> listChannelsWithNames() const;
+    
+    /// Returns the table name.
+    const std::string& tableName() const { return m_tableName; }
+        
+  private:
+    
+    /// Get a CORAL MessageStream
+    coral::MessageStream& log() const { return *m_log; }
+        
+    /// Get the RelationalQueryMgr associated to this table
+    RelationalQueryMgr& queryMgr() const { return m_queryMgr; }
+ 
+    /// CORAL MessageStream
+    std::auto_ptr<coral::MessageStream> m_log;
+    
+    /// Relational query manager
+    RelationalQueryMgr& m_queryMgr;
+    
+    /// Channel table name
+    std::string m_tableName;
+    
+  };
+
+}
+#endif // RELATIONALCOOL_RELATIONALCHANNELTABLE_H
diff --git a/RelationalCool/src/RelationalChannelTablesTable.cpp b/RelationalCool/src/RelationalChannelTablesTable.cpp
new file mode 100644
index 000000000..316bc1f02
--- /dev/null
+++ b/RelationalCool/src/RelationalChannelTablesTable.cpp
@@ -0,0 +1,41 @@
+// $Id: RelationalChannelTablesTable.cpp,v 1.1 2007-02-15 14:37:43 avalassi Exp $
+
+// Include files
+#include "CoolKernel/RecordSpecification.h"
+
+// Local include files
+#include "RelationalChannelTablesTable.h"
+
+//-----------------------------------------------------------------------------
+
+const cool::IRecordSpecification&
+cool::RelationalChannelTablesTable::tableSpecification() 
+{
+  static RecordSpecification spec;
+  
+  if ( spec.size() == 0 ) 
+  {
+    spec.extend
+      ( RelationalChannelTablesTable::columnNames::chTableName,
+        RelationalChannelTablesTable::columnTypeIds::chTableName );
+    spec.extend
+      ( RelationalChannelTablesTable::columnNames::chTableSchemaVersion,
+        RelationalChannelTablesTable::columnTypeIds::chTableSchemaVersion );  
+    spec.extend
+      ( RelationalChannelTablesTable::columnNames::chTableVersioningMode,
+        RelationalChannelTablesTable::columnTypeIds::chTableVersioningMode );
+    spec.extend
+      ( RelationalChannelTablesTable::columnNames::chTableInsertionTime,
+        RelationalChannelTablesTable::columnTypeIds::chTableInsertionTime );  
+    spec.extend
+      ( RelationalChannelTablesTable::columnNames::channelSpecDesc,
+        RelationalChannelTablesTable::columnTypeIds::channelSpecDesc );
+    spec.extend
+      ( RelationalChannelTablesTable::columnNames::channelExtRef,
+        RelationalChannelTablesTable::columnTypeIds::channelExtRef );
+  }
+  return spec;
+
+}
+
+//-----------------------------------------------------------------------------
diff --git a/RelationalCool/src/RelationalChannelTablesTable.h b/RelationalCool/src/RelationalChannelTablesTable.h
new file mode 100644
index 000000000..8e3e9781b
--- /dev/null
+++ b/RelationalCool/src/RelationalChannelTablesTable.h
@@ -0,0 +1,82 @@
+// $Id: RelationalChannelTablesTable.h,v 1.1 2007-02-15 14:37:43 avalassi Exp $
+#ifndef RELATIONALCOOL_RELATIONALCHANNELTABLESTABLE_H 
+#define RELATIONALCOOL_RELATIONALCHANNELTABLESTABLE_H 1
+
+// Include files
+#include "CoolKernel/StorageType.h"
+
+// Local include files
+#include "VersionNumber.h"
+#include "uppercaseString.h"
+
+namespace cool 
+{
+
+  // Forward declarations
+  class IRecordSpecification;
+
+  /** @namespace cool::RelationalChannelTablesTable RelationalChannelTablesTable.h
+   *  
+   *  Relational schema of the table storing metadata of COOL channel tables.
+   *
+   *  @author Andrea Valassi
+   *  @date   2007-02-15
+   */
+
+  namespace RelationalChannelTablesTable {
+
+    inline const std::string defaultTableName( const std::string& prefix ) 
+    {
+      return uppercaseString(prefix) + "CHANNELTABLES";
+    }    
+
+    namespace columnNames 
+    {
+      static const 
+      std::string chTableName = "CHANNELTABLE_NAME";
+      static const 
+      std::string chTableSchemaVersion = "CHANNELTABLE_SCHEMA_VERSION";
+      static const 
+      std::string chTableVersioningMode = "CHANNELTABLE_VERSIONING";
+      static const 
+      std::string chTableInsertionTime = "CHANNELTABLE_INSTIME";
+      static const 
+      std::string channelSpecDesc = "CHANNEL_SPEC";
+      static const 
+      std::string channelExtRef = "CHANNEL_EXTREF";
+    }
+
+    namespace columnTypeIds 
+    {
+      static const 
+      StorageType::TypeId chTableName = StorageType::String255;
+      static const 
+      StorageType::TypeId chTableSchemaVersion = StorageType::String255;
+      static const 
+      StorageType::TypeId chTableVersioningMode = StorageType::Int32;
+      static const 
+      StorageType::TypeId chTableInsertionTime = StorageType::String255;
+      static const 
+      StorageType::TypeId channelSpecDesc = StorageType::String64k;
+      static const 
+      StorageType::TypeId channelExtRef = StorageType::String64k;
+    }
+
+    namespace columnTypes 
+    {
+      typedef String255 chTableName;
+      typedef String255 chTableSchemaVersion;
+      typedef Int32     chTableVersioningMode;
+      typedef String255 chTableInsertionTime;
+      typedef String64k channelSpecDesc;
+      typedef String64k channelExtRef;
+    }
+    
+    /// Get the record specification of the channelTables table.
+    const IRecordSpecification& tableSpecification();
+     
+  }
+
+}
+
+#endif // RELATIONALCOOL_RELATIONALCHANNELTABLESTABLE_H
diff --git a/RelationalCool/src/RelationalDatabase.cpp b/RelationalCool/src/RelationalDatabase.cpp
new file mode 100644
index 000000000..2b15c4a46
--- /dev/null
+++ b/RelationalCool/src/RelationalDatabase.cpp
@@ -0,0 +1,1300 @@
+// $Id: RelationalDatabase.cpp,v 1.188 2009-02-09 18:56:15 avalassi Exp $
+
+// Include files
+#include <map>
+#include <vector>
+#include "CoolKernel/Record.h"
+#include "CoolKernel/RecordException.h"
+#include "CoolKernel/RecordSpecification.h"
+#include "CoralBase/Attribute.h"
+#include "CoralBase/AttributeList.h"
+
+// Local include files
+//#include "IRelationalTransactionMgr.h"
+#include "RelationalChannelTable.h"
+#include "RelationalDatabase.h"
+#include "RelationalDatabaseTable.h"
+#include "RelationalException.h"
+#include "RelationalFolderSet.h"
+#include "RelationalGlobalTagTable.h"
+#include "RelationalIovSharedSequenceTable.h"
+#include "RelationalNodeMgr.h"
+#include "RelationalNodeTable.h"
+#include "RelationalObjectTable.h"
+#include "RelationalObject2TagTable.h"
+#include "RelationalObjectMgr.h"
+#include "RelationalQueryMgr.h"
+#include "RelationalSchemaMgr.h"
+#include "RelationalTableRow.h"
+#include "RelationalTag2TagTable.h"
+#include "RelationalTagSequence.h"
+#include "RelationalTagSharedSequenceTable.h"
+#include "RelationalTagTable.h"
+#include "RelationalTagMgr.h"
+#include "RelationalTransaction.h"
+#include "VersionInfo.h"
+
+// *** START *** 3.0.0 schema extensions (task #4307, task #4396)
+#include "RelationalChannelTablesTable.h"
+#include "RelationalGlobalHeadTagTable.h"
+#include "RelationalGlobalUserTagTable.h"
+#include "RelationalIovTablesTable.h"
+// **** END **** 3.0.0 schema extensions (task #4307, task #4396)
+
+// Namespace
+using namespace cool;
+
+//-----------------------------------------------------------------------------
+
+RelationalDatabase::RelationalDatabase( const DatabaseId& dbId )
+  : m_dbAttr()
+  , m_isOpen( false )
+  , m_relationalDbId( dbId )
+  , m_log( new coral::MessageStream( "RelationalDatabase" ) )
+  , m_queryMgr( 0 )
+  , m_schemaMgr( 0 )
+  , m_nodeMgr( 0 )
+  , m_tagMgr( 0 )
+{
+  log() << coral::Debug << "Instantiate a RelationalDatabase for '"
+        << m_relationalDbId.middleTier() 
+        << databaseId() << "'" << coral::MessageStream::endmsg;
+
+  // Parse the dbId URL as RelationalDatabaseId connection parameters
+  std::string technology = m_relationalDbId.technology();
+  std::string server = m_relationalDbId.server();
+  std::string user = m_relationalDbId.user();
+  std::string password = m_relationalDbId.password();
+  std::string schema = m_relationalDbId.schema();
+  std::string dbName = m_relationalDbId.dbName();
+  log() << "Technology: '" << technology << "'" << coral::MessageStream::endmsg;
+  log() << "Server: '" << server << "'" << coral::MessageStream::endmsg;
+  log() << "User: '" << user << "'" << coral::MessageStream::endmsg;
+  if ( getenv( "COOL_AUTH_SHOWPASSWORD" ) )
+    log() << "Password: '" << password << "'" << coral::MessageStream::endmsg;
+  else
+    log() << "Password: '" << "********" << "'" << coral::MessageStream::endmsg;
+  log() << "Schema: '" << schema << "'"  << coral::MessageStream::endmsg;
+  log() << "Conditions database name: '" << dbName << "'" << coral::MessageStream::endmsg;
+}
+
+//-----------------------------------------------------------------------------
+
+RelationalDatabase::~RelationalDatabase() 
+{
+  //*m_pThis = NULL;
+  //m_pThis.reset();
+  log() << coral::Debug << "Delete the RelationalDatabase for '"
+        << m_relationalDbId.middleTier() 
+        << databaseId() << "'" << coral::MessageStream::endmsg;
+}
+
+//-----------------------------------------------------------------------------
+
+const DatabaseId& RelationalDatabase::databaseId() const 
+{
+  return m_relationalDbId.urlHidePswd();
+}
+
+//-----------------------------------------------------------------------------
+
+const std::string& RelationalDatabase::databaseName() const 
+{
+  return m_relationalDbId.dbName();
+}
+
+//-----------------------------------------------------------------------------
+
+const IRecord& RelationalDatabase::databaseAttributes() const 
+{
+  if ( ! isOpen() ) throw DatabaseNotOpen( "RelationalDatabase" );
+  return m_dbAttr;
+}
+
+//-----------------------------------------------------------------------------
+
+void RelationalDatabase::createDatabase() 
+{
+  // Default attributes
+  std::string dbName = databaseName();
+  Record dbAttr( databaseAttributesSpecification() );
+ 
+ std::string defaultTablePrefix = dbName + "_";
+  dbAttr[RelationalDatabaseTable::attributeNames::defaultTablePrefix]
+    .setValue( defaultTablePrefix );
+
+  /*
+  // *** START *** 3.0.0 schema extensions (task #4307)
+  std::string channelTablesTableName =
+    RelationalChannelTablesTable::defaultTableName( defaultTablePrefix );
+  dbAttr[RelationalDatabaseTable::attributeNames::channelTablesTableName]
+    .setValue( channelTablesTableName );
+
+  std::string iovTablesTableName =
+    RelationalIovTablesTable::defaultTableName( defaultTablePrefix );
+  dbAttr[RelationalDatabaseTable::attributeNames::iovTablesTableName]
+    .setValue( iovTablesTableName );
+  // **** END **** 3.0.0 schema extensions (task #4307)
+  */
+
+  std::string nodeTableName =
+    RelationalNodeTable::defaultTableName( defaultTablePrefix );
+  dbAttr[RelationalDatabaseTable::attributeNames::nodeTableName]
+    .setValue( nodeTableName );
+
+  std::string tagTableName =
+    RelationalGlobalTagTable::defaultTableName( defaultTablePrefix );
+  dbAttr[RelationalDatabaseTable::attributeNames::tagTableName]
+    .setValue( tagTableName );
+
+  /*
+  // *** START *** 3.0.0 schema extensions (task #4396)
+  std::string headTagTableName =
+    RelationalGlobalHeadTagTable::defaultTableName( defaultTablePrefix );
+  dbAttr[RelationalDatabaseTable::attributeNames::headTagTableName]
+    .setValue( headTagTableName );
+
+  std::string userTagTableName =
+    RelationalGlobalUserTagTable::defaultTableName( defaultTablePrefix );
+  dbAttr[RelationalDatabaseTable::attributeNames::userTagTableName]
+    .setValue( userTagTableName );
+  // **** END **** 3.0.0 schema extensions (task #4396)
+  */
+
+  std::string tag2TagTableName =
+    RelationalTag2TagTable::defaultTableName( defaultTablePrefix );
+  dbAttr[RelationalDatabaseTable::attributeNames::tag2TagTableName]
+    .setValue( tag2TagTableName );
+
+  std::string tagSharedSequenceName =
+    RelationalTagSharedSequenceTable::defaultTableName( defaultTablePrefix );
+  dbAttr[RelationalDatabaseTable::attributeNames::tagSharedSequenceName]
+    .setValue( tagSharedSequenceName );
+
+  std::string iovSharedSequenceName =
+    RelationalIovSharedSequenceTable::defaultTableName( defaultTablePrefix );
+  dbAttr[RelationalDatabaseTable::attributeNames::iovSharedSequenceName]
+    .setValue( iovSharedSequenceName );
+
+  // Create a database with the default attributes
+  return createDatabase( dbAttr );
+}
+
+//-----------------------------------------------------------------------------
+
+void RelationalDatabase::openDatabase()
+{
+
+  std::string dbName = databaseName();
+  log() << "Open the database with name " << dbName << coral::MessageStream::endmsg;
+
+  // Connect to the backend server if not yet done
+  if ( ! isConnected() ) connect();
+
+  // Retrieve the database attributes in the top-level management table
+  log() << "Fetch database attributes" << coral::MessageStream::endmsg;
+  RelationalTransaction transaction( transactionMgr(), true ); // r/o
+  m_dbAttr = fetchDatabaseAttributes();
+  transaction.commit();
+  log() << "Fetched database attributes: " << m_dbAttr << coral::MessageStream::endmsg;
+
+  // Check that the release number and schema versions of the database are
+  // compatible with the release number and schema versions of this client
+  std::string releaseNumber =
+    m_dbAttr[RelationalDatabaseTable::attributeNames::release].
+    data<std::string>();
+  std::string schemaVersion =
+    m_dbAttr[RelationalDatabaseTable::attributeNames::schemaVersion].
+    data<std::string>();
+  if ( !areReleaseAndSchemaCompatible( releaseNumber, schemaVersion ) ) {      
+    std::stringstream s;
+    s << "Release number mismatch - SCHEMA EVOLUTION REQUIRED: "
+      << "database with OLDER release number " << releaseNumber
+      << " cannot be opened using CURRENT client release number "
+      << VersionInfo::release;
+    throw IncompatibleReleaseNumber( s.str(), "RelationalDatabase" );
+  }
+
+  // The database is now open
+  m_isOpen = true;
+}
+
+//-----------------------------------------------------------------------------
+
+bool 
+RelationalDatabase::areReleaseAndSchemaCompatible
+( const std::string releaseNumber,
+  const std::string schemaVersion ) const
+{
+  bool status = true;
+  // Preliminary check: this release must be 1.2.0 or later
+  // MAKE SURE THAT 1.2.0 <= THISRELEASE
+  VersionNumber db_rel_version(releaseNumber);
+  VersionNumber db_schema_version(schemaVersion);
+  
+  if ( VersionInfo::release < "1.2.0" ) 
+  {
+    std::stringstream s;
+    s << "PANIC! CURRENT client release number " << VersionInfo::release
+      << " is older than 1.2.0?";
+    throw IncompatibleReleaseNumber( s.str(), "RelationalDatabase" );
+  }
+  // Cannot open databases created with releases earlier than 1.2.0
+  // No schema evolution is possible for such database schemas
+  // DbRelease < 1.2.0
+  else if ( db_rel_version < "1.2.0" ) 
+  {
+    std::stringstream s;
+    s << "Release number mismatch"
+      << " - SCHEMA EVOLUTION NOT POSSIBLE: "
+      << "database with OLDER release number " << db_rel_version
+      << " (older than 1.2.0)"
+      << " cannot be opened using CURRENT client release number "
+      << VersionInfo::release;
+    throw IncompatibleReleaseNumber( s.str(), "RelationalDatabase" );
+  }
+  // Schema evolution for 1.2.0 <= DbRelease < THISRELEASE
+  // Open databases created with releases earlier than this release
+  else if ( db_rel_version < VersionInfo::release ) 
+  {
+    // This release (2.7.0) can read 2.6.0
+    // This release (2.7.0) can read 2.5.0
+    // This release (2.7.0) can read 2.4.0
+    // This release (2.7.0) can read 2.3.x (including the unreleased 2.3.1)
+    // This release (2.7.0) can read 2.2.x
+    // This release (2.7.0) can read 2.1.x
+    // This release (2.7.0) can read 2.0.0
+    if ( ( db_rel_version == "2.6.0" ) ||
+         ( db_rel_version == "2.5.0" ) ||
+         ( db_rel_version == "2.4.0" ) ||
+         ( db_rel_version >= "2.3.0" && db_rel_version <= "2.3.1" ) ||
+         ( db_rel_version >= "2.2.0" && db_rel_version <= "2.2.2" ) ||
+         ( db_rel_version >= "2.1.0" && db_rel_version <= "2.1.1" ) ||
+         ( db_rel_version == "2.0.0" ) )
+    {
+      status = true;
+      log() << coral::Warning
+            << "Release number backward compatibility "
+            << "- NO SCHEMA EVOLUTION REQUIRED: "
+            << "database with OLDER release number " << releaseNumber
+            << " will be opened using CURRENT client release number "
+            << VersionInfo::release << coral::MessageStream::endmsg;
+    }
+    else
+    // This release (2.7.0) needs schema evolution before it can read 1.3.0-4
+    if ( db_rel_version >= "1.3.0" && db_rel_version <= "1.3.4" )
+    {
+      status = false;
+      log() << coral::Warning
+            << "Release number mismatch"
+            << " - SCHEMA EVOLUTION REQUIRED: "
+            << "database with OLDER release number " << db_rel_version
+            << " cannot be opened using CURRENT client release number "
+            << VersionInfo::release << coral::MessageStream::endmsg;
+    }
+    else
+    // This release (2.7.0) needs schema evolution before it can read 1.2.0-9
+    if ( db_rel_version >= "1.2.0" && db_rel_version <= "1.2.9" )
+    {
+      status = false;
+      log() << coral::Warning
+            << "Release number mismatch"
+            << " - SCHEMA EVOLUTION REQUIRED: "
+            << "database with OLDER release number " << db_rel_version
+            << " cannot be opened using CURRENT client release number "
+            << VersionInfo::release << coral::MessageStream::endmsg;
+    }
+    // This release (2.7.0) can NOT read any other previous releases
+    else
+    { 
+      std::stringstream s;
+      s << "PANIC! Release number mismatch: "
+        << "database with (UNKNOWN!) OLDER release number " << db_rel_version
+        << " cannot be opened using CURRENT client release number "
+        << VersionInfo::release;
+      throw IncompatibleReleaseNumber( s.str(), "RelationalDatabase" );
+    }
+  }
+  // DbRelease == THISRELEASE
+  else if ( db_rel_version == VersionInfo::release ) 
+  {
+    status = true;
+    log() << coral::Debug 
+          << "Release number match: "
+          << "database with CURRENT release number " << db_rel_version
+          << " will be opened using CURRENT client release number "
+          << VersionInfo::release << coral::MessageStream::endmsg;
+  }
+  // Check schema version for dbs created with releases newer than this one!
+  // THIS_RELEASE < DbRelease
+  else if ( VersionInfo::release < db_rel_version ) 
+  {
+    // Cannot open dbs with schema versions newer than that of this release!
+    // THIS_SCHEMAVERSION < DbSchemaVersion
+    if ( VersionInfo::schemaVersion < db_schema_version ) 
+    {
+      std::stringstream s;
+      s << "Release number and schema version mismatch"
+        << " - SCHEMA NOT BACKWARD COMPATIBLE: "
+        << "database with NEWER release number " << db_rel_version
+        << " and NEWER schema version " << db_schema_version
+        << " cannot be opened using CURRENT client release number "
+        << VersionInfo::release
+        << " (CURRENT schema version " << VersionInfo::schemaVersion << ")";
+      throw IncompatibleReleaseNumber( s.str(), "RelationalDatabase" );
+    }
+    // Open databases created using a newer release but the same schema version
+    // THIS_SCHEMAVERSION == DbSchemaVersion
+    else if ( VersionInfo::schemaVersion == db_schema_version )
+    {
+      status = true;
+      log() << coral::Debug 
+            << "Release number mismatch with schema version match: "
+            << "database with NEWER release number " << db_rel_version
+            << " and CURRENT schema version " << db_schema_version
+            << " will be opened using CURRENT client release number "
+            << VersionInfo::release
+            << " (CURRENT schema version " 
+            << VersionInfo::schemaVersion << ")" << coral::MessageStream::endmsg;
+    }
+    // PANIC! How can it be that a newer release has an older schema?
+    else if ( VersionInfo::schemaVersion > db_schema_version )
+    {
+      std::stringstream s;
+      s << "PANIC! Release number and schema version mismatch: "
+        << "database with NEWER release number " << db_rel_version
+        << " than CURRENT client release number " << VersionInfo::release
+        << " has OLDER schema version " << db_schema_version
+        << " (CURRENT schema version " << VersionInfo::schemaVersion << ")";
+      throw IncompatibleReleaseNumber( s.str(), "RelationalDatabase" );
+    }
+    // PANIC! How can it be that none of "<", "==", ">" is true?
+    else 
+    {
+      std::stringstream s;
+      s << "PANIC! Release number and schema version mismatch: "
+        << "database with NEWER release number " << db_rel_version
+        << " than CURRENT client release number " << VersionInfo::release
+        << " has UNKNOWN schema version " << db_schema_version
+        << " (CURRENT schema version " << VersionInfo::schemaVersion << ")";
+      throw IncompatibleReleaseNumber( s.str(), "RelationalDatabase" );
+    }
+  }
+  // PANIC! How can it be that none of "<", "==", ">" is true?
+  else 
+  {
+    std::stringstream s;
+    s << "PANIC! Release number mismatch: "
+      << "database with UNKNOWN release number " << db_rel_version
+      << " cannot be opened using CURRENT client release number "
+      << VersionInfo::release;
+    throw IncompatibleReleaseNumber( s.str(), "RelationalDatabase" );
+  }
+  return status;
+}
+
+//-----------------------------------------------------------------------------
+
+bool RelationalDatabase::isValidPayloadFieldName
+( const std::string& name )
+{
+  static std::string allowedChar = 
+    "ABCDEFGHIJKLMNOPQRSTUVWXYZ_1234567890";
+  const std::string ucName = uppercaseString( name );    
+  if ( name.size() < 1 || 
+       name.size() > 30 ||
+       ucName.find_first_not_of( allowedChar ) != ucName.npos ||
+       ucName.find_first_not_of( "_1234567890" ) != 0 ||
+       ucName.find( "COOL_" ) == 0 )
+    return false;
+  else
+    return true;
+}
+
+//-----------------------------------------------------------------------------
+
+void RelationalDatabase::validatePayloadSpecification
+( const IRecordSpecification& spec )
+{
+  // Throw PayloadSpecificationTooManyFields if #fields > 900
+  if ( spec.size() > 900 )
+    throw PayloadSpecificationTooManyFields
+      ( spec.size(), "RelationalDatabase" );
+
+  // Throw PayloadSpecificationTooManyBlobFields if #blobFields > 10
+  UInt32 nBlobFields = 0;
+  for ( UInt32 i = 0; i < spec.size(); i++ )
+    if ( spec[i].storageType().id() == StorageType::Blob64k ||
+         spec[i].storageType().id() == StorageType::Blob16M ) nBlobFields++;
+  if ( nBlobFields > 10 )
+    throw PayloadSpecificationTooManyBlobFields
+      ( nBlobFields, "RelationalDatabase" );
+
+  // Throw PayloadSpecificationTooManyString255Fields if #string255Fields > 200
+  UInt32 nSt255Fields = 0;
+  for ( UInt32 i = 0; i < spec.size(); i++ )
+    if ( spec[i].storageType().id() == StorageType::String255 ) nSt255Fields++;
+  if ( nSt255Fields > 200 )
+    throw PayloadSpecificationTooManyString255Fields
+      ( nSt255Fields, "RelationalDatabase" );
+
+  // Throw PayloadSpecificationInvalidFieldName if any field names are invalid.
+  // Names of payload fields must have between 1 and 30 characters (including 
+  // only letters, digits or '_'), must start with a letter and cannot start
+  // with the "COOL_" prefix (in any lowercase/uppercase combination).
+  for ( UInt32 i = 0; i < spec.size(); i++ ) {
+    const std::string& name = spec[i].name();    
+    if ( ! isValidPayloadFieldName( name ) )
+      throw PayloadSpecificationInvalidFieldName( name, "RelationalDatabase" );
+  }
+}
+
+//-----------------------------------------------------------------------------
+
+void RelationalDatabase::closeDatabase()
+{
+  disconnect();
+  m_isOpen = false;
+}
+
+//-----------------------------------------------------------------------------
+
+const std::string RelationalDatabase::mainTableName() const
+{
+  return RelationalDatabaseTable::tableName( databaseName() );
+}
+
+//-----------------------------------------------------------------------------
+
+const std::string RelationalDatabase::defaultTablePrefix() const
+{
+  if ( ! isOpen() ) throw DatabaseNotOpen( "RelationalDatabase" );
+  const IRecord& dbAttr = databaseAttributes();
+  std::string theDefaultTablePrefix =
+    dbAttr[RelationalDatabaseTable::attributeNames::defaultTablePrefix]
+    .data<RelationalDatabaseTable::columnTypes::attributeValue>();
+  return theDefaultTablePrefix;
+}
+
+//-----------------------------------------------------------------------------
+
+// *** START *** 3.0.0 schema extensions (task #4307)
+const std::string RelationalDatabase::iovTablesTableName() const
+{
+  if ( ! isOpen() ) throw DatabaseNotOpen( "RelationalDatabase" );
+  const IRecord& dbAttr = databaseAttributes();
+  std::string tableName =
+    dbAttr[RelationalDatabaseTable::attributeNames::iovTablesTableName]
+    .data<RelationalDatabaseTable::columnTypes::attributeValue>();
+  return tableName;
+}
+
+//-----------------------------------------------------------------------------
+
+const std::string RelationalDatabase::channelTablesTableName() const
+{
+  if ( ! isOpen() ) throw DatabaseNotOpen( "RelationalDatabase" );
+  const IRecord& dbAttr = databaseAttributes();
+  std::string tableName =
+    dbAttr[RelationalDatabaseTable::attributeNames::channelTablesTableName]
+    .data<RelationalDatabaseTable::columnTypes::attributeValue>();
+  return tableName;
+}
+// **** END **** 3.0.0 schema extensions (task #4307)
+
+//-----------------------------------------------------------------------------
+
+const std::string RelationalDatabase::nodeTableName() const
+{
+  if ( ! isOpen() ) throw DatabaseNotOpen( "RelationalDatabase" );
+  const IRecord& dbAttr = databaseAttributes();
+  std::string theNodeTableName =
+    dbAttr[RelationalDatabaseTable::attributeNames::nodeTableName]
+    .data<RelationalDatabaseTable::columnTypes::attributeValue>();
+  return theNodeTableName;
+}
+
+//-----------------------------------------------------------------------------
+
+const std::string RelationalDatabase::globalTagTableName() const
+{
+  if ( ! isOpen() ) throw DatabaseNotOpen( "RelationalDatabase" );
+  const IRecord& dbAttr = databaseAttributes();
+  std::string tableName =
+    dbAttr[RelationalDatabaseTable::attributeNames::tagTableName]
+    .data<RelationalDatabaseTable::columnTypes::attributeValue>();
+  return tableName;
+}
+
+//-----------------------------------------------------------------------------
+
+// *** START *** 3.0.0 schema extensions (task #4396)
+const std::string RelationalDatabase::globalHeadTagTableName() const
+{
+  if ( ! isOpen() ) throw DatabaseNotOpen( "RelationalDatabase" );
+  const IRecord& dbAttr = databaseAttributes();
+  std::string tableName =
+    dbAttr[RelationalDatabaseTable::attributeNames::headTagTableName]
+    .data<RelationalDatabaseTable::columnTypes::attributeValue>();
+  return tableName;
+}
+
+//-----------------------------------------------------------------------------
+
+const std::string RelationalDatabase::globalUserTagTableName() const
+{
+  if ( ! isOpen() ) throw DatabaseNotOpen( "RelationalDatabase" );
+  const IRecord& dbAttr = databaseAttributes();
+  std::string tableName =
+    dbAttr[RelationalDatabaseTable::attributeNames::userTagTableName]
+    .data<RelationalDatabaseTable::columnTypes::attributeValue>();
+  return tableName;
+}
+// **** END **** 3.0.0 schema extensions (task #4396)
+
+//-----------------------------------------------------------------------------
+
+const std::string RelationalDatabase::tag2TagTableName() const
+{
+  if ( ! isOpen() ) throw DatabaseNotOpen( "RelationalDatabase" );
+  const IRecord& dbAttr = databaseAttributes();
+  std::string tableName =
+    dbAttr[RelationalDatabaseTable::attributeNames::tag2TagTableName]
+    .data<RelationalDatabaseTable::columnTypes::attributeValue>();
+  return tableName;
+}
+
+//-----------------------------------------------------------------------------
+
+const std::string RelationalDatabase::tagSharedSequenceName() const
+{
+  if ( ! isOpen() ) throw DatabaseNotOpen( "RelationalDatabase" );
+  const IRecord& dbAttr = databaseAttributes();
+  std::string tableName =
+    dbAttr[RelationalDatabaseTable::attributeNames::tagSharedSequenceName]
+    .data<RelationalDatabaseTable::columnTypes::attributeValue>();
+  return tableName;
+}
+
+//-----------------------------------------------------------------------------
+
+const std::string RelationalDatabase::iovSharedSequenceName() const
+{
+  if ( ! isOpen() ) throw DatabaseNotOpen( "RelationalDatabase" );
+  const IRecord& dbAttr = databaseAttributes();
+  std::string tableName =
+    dbAttr[RelationalDatabaseTable::attributeNames::iovSharedSequenceName]
+    .data<RelationalDatabaseTable::columnTypes::attributeValue>();
+  return tableName;
+}
+
+//-----------------------------------------------------------------------------
+
+/*
+bool RelationalDatabase::isValidAttributeListSpecification
+( const coral::AttributeListSpecification& spec )
+{
+  coral::AttributeListSpecification::const_iterator it;
+  for ( it=spec.begin(); it!=spec.end(); ++it ) {
+    std::string attrName = it->name();
+    
+    // Check that attribute names only contain alphanumeric characters or '_'
+    static std::string allowedChar =
+      "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_";
+    if ( attrName.find_first_not_of(allowedChar) != std::string::npos ) {
+      log() << coral::Debug << "Invalid character in attribute name: '"
+            << attrName << "'" << coral::MessageStream::endmsg;
+      return false;
+    }
+    
+  }
+  return true;
+}
+*/
+
+//-----------------------------------------------------------------------------
+
+bool RelationalDatabase::isOpen() const 
+{
+  return m_isOpen;
+}
+
+//-----------------------------------------------------------------------------
+
+coral::MessageStream& RelationalDatabase::log() const
+{
+  *m_log << coral::Verbose;
+  return *m_log;
+}
+
+//-----------------------------------------------------------------------------
+
+RelationalQueryMgr& RelationalDatabase::queryMgr() const 
+{
+  if ( m_queryMgr.get() ) 
+    return *m_queryMgr;
+  else 
+    throw RelationalException
+      ( "PANIC! RelationalQueryMgr pointer is null", "RelationalDatabase" );
+}
+
+//-----------------------------------------------------------------------------
+
+RelationalSchemaMgr& RelationalDatabase::schemaMgr() const 
+{
+  if ( m_schemaMgr.get() ) 
+    return *m_schemaMgr;
+  else 
+    throw RelationalException
+      ( "PANIC! RelationalSchemaMgr pointer is null", "RelationalDatabase" );
+}
+
+//-----------------------------------------------------------------------------
+
+RelationalNodeMgr& RelationalDatabase::nodeMgr() const 
+{
+  if ( m_nodeMgr.get() ) 
+    return *m_nodeMgr;
+  else 
+    throw RelationalException
+      ( "PANIC! RelationalNodeMgr pointer is null", "RelationalDatabase" );
+}
+
+//-----------------------------------------------------------------------------
+
+RelationalTagMgr& RelationalDatabase::tagMgr() const 
+{
+  if ( m_tagMgr.get() ) 
+    return *m_tagMgr;
+  else 
+    throw RelationalException
+      ( "PANIC! RelationalTagMgr pointer is null", "RelationalDatabase" );
+}
+
+//-----------------------------------------------------------------------------
+
+const RelationalObjectMgr& RelationalDatabase::objectMgr() const 
+{
+  if ( m_objectMgr.get() ) 
+    return *m_objectMgr;
+  else 
+    throw RelationalException
+      ( "PANIC! RelationalObjectMgr pointer is null", 
+        "RelationalDatabase" );
+}
+
+//-----------------------------------------------------------------------------
+
+void RelationalDatabase::setQueryMgr
+( std::auto_ptr<RelationalQueryMgr> queryMgr )
+{
+  m_queryMgr = queryMgr;
+}
+
+//-----------------------------------------------------------------------------
+
+void RelationalDatabase::setSchemaMgr
+( std::auto_ptr<RelationalSchemaMgr> schemaMgr )
+{
+  m_schemaMgr = schemaMgr;
+}
+
+//-----------------------------------------------------------------------------
+
+void RelationalDatabase::setNodeMgr( std::auto_ptr<RelationalNodeMgr> nodeMgr )
+{
+  m_nodeMgr = nodeMgr;
+}
+
+//-----------------------------------------------------------------------------
+
+void RelationalDatabase::setTagMgr( std::auto_ptr<RelationalTagMgr> tagMgr )
+{
+  m_tagMgr = tagMgr;
+}
+
+//-----------------------------------------------------------------------------
+
+void RelationalDatabase::setObjectMgr
+( std::auto_ptr<RelationalObjectMgr> objectMgr )
+{
+  m_objectMgr = objectMgr;
+}
+
+//-----------------------------------------------------------------------------
+
+boost::shared_ptr<IRelationalTransactionMgr> 
+RelationalDatabase::transactionMgr() const 
+{
+  if ( m_transactionMgr.get() ) 
+    return m_transactionMgr;
+  else 
+    throw RelationalException
+      ( "PANIC! RelationalTransactionMgr pointer is null", 
+        "RelationalDatabase" );
+}
+
+//-----------------------------------------------------------------------------
+
+void RelationalDatabase::setTransactionMgr
+( boost::shared_ptr<IRelationalTransactionMgr> transactionMgr )
+{
+  m_transactionMgr = transactionMgr;
+}
+
+//-----------------------------------------------------------------------------
+
+const IRecordSpecification& 
+RelationalDatabase::databaseAttributesSpecification()
+{
+  static RecordSpecification  s_dbAttrSpec;
+  
+  if ( s_dbAttrSpec.size() == 0 ) {
+    s_dbAttrSpec.extend
+      ( RelationalDatabaseTable::attributeNames::defaultTablePrefix,
+        RelationalDatabaseTable::columnTypeIds::attributeValue );
+    /*
+    // *** START *** 3.0.0 schema extensions (task #4307)
+    s_dbAttrSpec.extend
+      ( RelationalDatabaseTable::attributeNames::iovTablesTableName,
+        RelationalDatabaseTable::columnTypeIds::attributeValue );
+    s_dbAttrSpec.extend
+      ( RelationalDatabaseTable::attributeNames::channelTablesTableName,
+        RelationalDatabaseTable::columnTypeIds::attributeValue );
+    // **** END **** 3.0.0 schema extensions (task #4307)
+    */
+    s_dbAttrSpec.extend
+      ( RelationalDatabaseTable::attributeNames::nodeTableName,
+        RelationalDatabaseTable::columnTypeIds::attributeValue );
+    /*
+    // *** START *** 3.0.0 schema extensions (task #4396)
+    s_dbAttrSpec.extend
+      ( RelationalDatabaseTable::attributeNames::headTagTableName,
+        RelationalDatabaseTable::columnTypeIds::attributeValue );
+    s_dbAttrSpec.extend
+      ( RelationalDatabaseTable::attributeNames::userTagTableName,
+        RelationalDatabaseTable::columnTypeIds::attributeValue );
+    // **** END **** 3.0.0 schema extensions (task #4396)
+    */
+    s_dbAttrSpec.extend
+      ( RelationalDatabaseTable::attributeNames::tagTableName,
+        RelationalDatabaseTable::columnTypeIds::attributeValue );
+    s_dbAttrSpec.extend
+      ( RelationalDatabaseTable::attributeNames::tag2TagTableName,
+        RelationalDatabaseTable::columnTypeIds::attributeValue );
+    s_dbAttrSpec.extend
+      ( RelationalDatabaseTable::attributeNames::tagSharedSequenceName,
+        RelationalDatabaseTable::columnTypeIds::attributeValue );
+    s_dbAttrSpec.extend
+      ( RelationalDatabaseTable::attributeNames::iovSharedSequenceName,
+        RelationalDatabaseTable::columnTypeIds::attributeValue );
+    s_dbAttrSpec.extend
+      ( RelationalDatabaseTable::attributeNames::release,
+        RelationalDatabaseTable::columnTypeIds::attributeValue );
+    s_dbAttrSpec.extend
+      ( RelationalDatabaseTable::attributeNames::cvsCheckout,
+        RelationalDatabaseTable::columnTypeIds::attributeValue );
+    s_dbAttrSpec.extend
+      ( RelationalDatabaseTable::attributeNames::cvsCheckin,
+        RelationalDatabaseTable::columnTypeIds::attributeValue );
+    s_dbAttrSpec.extend
+      ( RelationalDatabaseTable::attributeNames::schemaVersion,
+        RelationalDatabaseTable::columnTypeIds::attributeValue );
+  }
+  return s_dbAttrSpec;
+}
+
+//-----------------------------------------------------------------------------
+
+const StorageType& 
+RelationalDatabase::storageType( const std::string& name ) 
+{
+  if ( name == "Bool" )      
+    return StorageType::storageType( StorageType::Bool );
+  //if ( name == "Char" )      
+  //  return StorageType::storageType( StorageType::Char );
+  if ( name == "UChar" )     
+    return StorageType::storageType( StorageType::UChar );
+  if ( name == "Int16" )     
+    return StorageType::storageType( StorageType::Int16 );
+  if ( name == "UInt16" )    
+    return StorageType::storageType( StorageType::UInt16 );
+  if ( name == "Int32" )     
+    return StorageType::storageType( StorageType::Int32 );
+  if ( name == "UInt32" )    
+    return StorageType::storageType( StorageType::UInt32 );
+  if ( name == "UInt63" )    
+    return StorageType::storageType( StorageType::UInt63 );
+  if ( name == "Int64" )     
+    return StorageType::storageType( StorageType::Int64 );
+  //if ( name == "UInt64" )    
+  //  return StorageType::storageType( StorageType::UInt64 );
+  if ( name == "Float" )     
+    return StorageType::storageType( StorageType::Float );
+  if ( name == "Double" )    
+    return StorageType::storageType( StorageType::Double );
+  if ( name == "String255" ) 
+    return StorageType::storageType( StorageType::String255 );
+  if ( name == "String4k" )  
+    return StorageType::storageType( StorageType::String4k );
+  if ( name == "String64k" ) 
+    return StorageType::storageType( StorageType::String64k );
+  if ( name == "String16M" ) 
+    return StorageType::storageType( StorageType::String16M );
+  if ( name == "Blob64k" )      
+    return StorageType::storageType( StorageType::Blob64k );
+  if ( name == "Blob16M" )      
+    return StorageType::storageType( StorageType::Blob16M );
+  throw RelationalException
+    ( "PANIC! No StorageType exists with name " + name, "RelationalDatabase" );
+}
+
+//-----------------------------------------------------------------------------
+
+const std::string RelationalDatabase::encodeRecordSpecification
+( const IRecordSpecification& recordSpec )
+{
+  std::ostringstream out;
+  for ( unsigned int i=0; i<recordSpec.size(); i++ ) {
+    const IFieldSpecification& fieldSpec = recordSpec[i];
+    if ( i != 0 ) out << ",";
+    out << fieldSpec.name()
+        << ":" << fieldSpec.storageType().name();
+  }
+  return out.str();
+}
+
+//-----------------------------------------------------------------------------
+
+const RecordSpecification
+RelationalDatabase::decodeRecordSpecification( const std::string& encodedSpec )
+{
+  RecordSpecification recordSpec;
+  if ( !encodedSpec.empty() ) {
+    std::string::size_type pos = 0;
+    while ( pos != encodedSpec.npos ) {
+      std::string::size_type newpos = encodedSpec.find( ',', pos );
+      std::string item_str;
+      if ( newpos != encodedSpec.npos )
+        item_str = encodedSpec.substr(pos,newpos-pos);
+      else
+        item_str = encodedSpec.substr(pos);
+      std::string::size_type separator_pos = item_str.find(':');
+      if ( separator_pos == item_str.npos ) 
+        throw RelationalException
+          ( std::string 
+            ( "Bad format, ':' not found in encoded RecordSpecification '" )
+            + encodedSpec + "'", "RelationalDatabase" );      
+      recordSpec.extend
+        ( item_str.substr( 0, separator_pos ),
+          RelationalDatabase::storageType
+          ( item_str.substr( separator_pos+1 ) ) );
+      pos = ( newpos != encodedSpec.npos ) ? newpos+1 : newpos;
+    }
+  }
+  return recordSpec;
+}
+
+//-----------------------------------------------------------------------------
+
+RelationalTableRow
+RelationalDatabase::fetchTagTableRow( const std::string& tagTableName,
+                                      const std::string& tagName )
+{  
+  log() << "Fetch tag table row for tag " << tagName
+        << " from table '" << tagTableName << "'" << coral::MessageStream::endmsg;
+  
+  // Define the WHERE clause for the selection using bind variables
+  coral::AttributeList whereData;
+  whereData.extend( "tagName", typeIdToCoralType(RelationalTagTable::columnTypeIds::tagName) );
+  whereData["tagName"].setValue( tagName );
+  std::string whereClause = RelationalTagTable::columnNames::tagName;
+  whereClause += "= :tagName";
+  
+  // Delegate the query to the RelationalQueryMgr
+  try {
+    std::string desc = "";
+    return queryMgr().fetchRowFromTables
+      ( RelationalQueryMgr::tableList( tagTableName ), 
+        RelationalQueryMgr::columnList
+        ( RelationalTagTable::tableSpecification() ),
+        whereClause, whereData, desc );
+  } catch( NoRowsFound& ) {
+    throw TagNotFound
+      ( "Tag '" + tagName + "' not found in local tag table " + tagTableName ,
+        "RelationalDatabase" );
+  }
+}
+
+//-----------------------------------------------------------------------------
+
+const IHvsTagMgr& RelationalDatabase::hvsTagMgr() const 
+{
+  return tagMgr();
+}
+
+//-----------------------------------------------------------------------------
+
+const Record RelationalDatabase::fetchDatabaseAttributes() const
+{
+  // Fetch all rows from the top-level management table
+  std::vector<RelationalTableRow> rows;
+  try {
+    std::string whereClause = "";
+    coral::AttributeList whereData;
+    rows = queryMgr().fetchRowsFromTables
+      ( RelationalQueryMgr::tableList( mainTableName() ), 
+        RelationalQueryMgr::columnList
+        ( RelationalDatabaseTable::tableSpecification() ),
+        whereClause, whereData, "" );
+  } catch ( TableNotFound& ) {
+    log() << coral::Verbose
+          << "Could not open database - main database table not found"
+          << coral::MessageStream::endmsg;
+    throw DatabaseDoesNotExist( "RelationalDatabase" );
+  }
+
+  // Create a new database attributes Record from the rows retrieved
+  // Read ALL rows even if they are not in the default specification
+  // (e.g. read schema evolution information where present)  
+  // Use a vector instead of a map to keep the order of properties.
+  std::vector < std::pair<std::string, std::string> > propertyList;
+  RecordSpecification spec;
+  const StorageType::TypeId attrTypeId = 
+    RelationalDatabaseTable::columnTypeIds::attributeValue;
+  for ( std::vector<RelationalTableRow>::const_iterator
+          row = rows.begin(); row != rows.end(); ++row ) {
+    std::string attrName =
+      (*row)[RelationalDatabaseTable::columnNames::attributeName].
+      data<std::string>();
+    std::string attrValue =
+      (*row)[RelationalDatabaseTable::columnNames::attributeValue].
+      data<std::string>();
+    spec.extend( attrName, attrTypeId );
+    std::pair<std::string, std::string> property( attrName, attrValue );     
+    propertyList.push_back( property );
+  }
+  Record dbAttr( spec );
+  for ( std::vector < std::pair<std::string, std::string> >::const_iterator
+          prop = propertyList.begin(); prop != propertyList.end(); ++prop ) {
+    dbAttr[prop->first].setValue( prop->second );
+  }
+
+  // Return the database attributes
+  return dbAttr;
+}
+
+//-----------------------------------------------------------------------------
+
+RelationalTableRow
+RelationalDatabase::fetchObject2TagTableRow
+( const std::string& object2TagTableName,
+  unsigned int tagId,
+  unsigned int objectId )
+{
+  // Define the WHERE clause for the selection using bind variables
+  RecordSpecification whereSpec;
+  whereSpec.extend
+    ( "tagId", RelationalObject2TagTable::columnTypeIds::tagId );
+  whereSpec.extend
+    ( "objectId", RelationalObject2TagTable::columnTypeIds::objectId );
+  coral::AttributeList whereData = Record( whereSpec ).attributeList();
+  whereData["tagId"].setValue( tagId );
+  whereData["objectId"].setValue( objectId );
+  std::string whereClause = RelationalObject2TagTable::columnNames::tagId;
+  whereClause += "= :tagId";
+  whereClause += " and ";
+  whereClause += RelationalObject2TagTable::columnNames::objectId;
+  whereClause += "= :objectId";
+
+  // Delegate the query to the RelationalQueryMgr
+  std::stringstream s;
+  s << "Query object2Tag table row with tag_id=" << tagId 
+    << " and object_id=" << objectId;
+  return queryMgr().fetchRowFromTables
+    ( RelationalQueryMgr::tableList( object2TagTableName ), 
+      RelationalQueryMgr::columnList
+      ( RelationalObject2TagTable::tableSpecification() ),
+      whereClause, whereData, s.str() );
+}
+
+//-----------------------------------------------------------------------------
+
+const RelationalTableRow 
+RelationalDatabase::fetchNodeTableRow( const std::string& fullPath ) const
+{
+  return nodeMgr().fetchNodeTableRow( fullPath );
+}
+
+//-----------------------------------------------------------------------------
+
+const RelationalTableRow 
+RelationalDatabase::fetchNodeTableRow( unsigned int nodeId ) const
+{
+  return nodeMgr().fetchNodeTableRow( nodeId );
+}
+
+//-----------------------------------------------------------------------------
+
+const RelationalTableRow
+RelationalDatabase::fetchNodeTableRow
+( const std::string& whereClause,
+  const coral::AttributeList& whereData ) const
+{
+  return nodeMgr().fetchNodeTableRow( whereClause, whereData );
+}
+
+//-----------------------------------------------------------------------------
+
+const std::vector<std::string> 
+RelationalDatabase::listNodes( unsigned int nodeId, 
+                               bool isLeaf, 
+                               bool ascending ) const
+{
+  return nodeMgr().listNodes( nodeId, isLeaf, ascending );
+}
+
+//-----------------------------------------------------------------------------
+
+const std::vector<std::string>
+RelationalDatabase::listFolders( const RelationalFolderSet* folderset,
+                                 bool ascending ) const
+{
+  // Cross-check that the database is open
+  if ( ! isOpen() ) throw DatabaseNotOpen( "RelationalDatabase" );
+  RelationalTransaction transaction( transactionMgr(), true ); // read-only
+
+  bool isLeaf = true;
+  std::vector<std::string>
+    nodes( listNodes( folderset->id(), isLeaf, ascending ) );
+
+  transaction.commit();
+
+  return nodes;
+}
+
+//-----------------------------------------------------------------------------
+
+const std::vector<std::string>
+RelationalDatabase::listFolderSets( const RelationalFolderSet* folderset,
+                                    bool ascending ) const
+{
+  // Cross-check that the database is open
+  if ( ! isOpen() ) throw DatabaseNotOpen( "RelationalDatabase" );
+  RelationalTransaction transaction( transactionMgr(), true ); // read-only
+
+  bool isLeaf = false;
+  std::vector<std::string>
+    nodes( listNodes( folderset->id(), isLeaf, ascending ) );
+
+  transaction.commit();
+
+  return nodes;
+}
+
+//-----------------------------------------------------------------------------
+
+const std::vector<std::string>
+RelationalDatabase::listAllNodes( bool ascending ) 
+{
+  // Cross-check that the database is open
+  if ( ! isOpen() ) throw DatabaseNotOpen( "RelationalDatabase" );
+
+  // Start a read-only transaction
+  RelationalTransaction transaction( transactionMgr(), true );
+
+  // Delegate to the node manager
+  std::vector<std::string> nodeList = nodeMgr().listAllNodes( ascending );
+
+  // Commit the transaction
+  transaction.commit();
+
+  // Return the list of nodes
+  return nodeList;
+}
+
+//-----------------------------------------------------------------------------
+
+/*
+const std::vector<std::string>
+RelationalDatabase::listAllNodes( bool ascending ) 
+{
+  return nodeMgr().listAllNodes( ascending );
+}
+*/
+
+//-----------------------------------------------------------------------------
+
+bool RelationalDatabase::existsNode( const std::string& fullPath )
+{
+  return nodeMgr().existsNode( fullPath );
+}
+
+//-----------------------------------------------------------------------------
+
+bool RelationalDatabase::existsFolderSet( const std::string& fullPath )
+{
+  return nodeMgr().existsFolderSet( fullPath );
+}
+
+//-----------------------------------------------------------------------------
+
+bool RelationalDatabase::existsFolder( const std::string& fullPath )
+{
+  return nodeMgr().existsFolder( fullPath );
+}
+
+//-----------------------------------------------------------------------------
+
+const std::vector<std::string> RelationalDatabase::listAllTables() const
+{
+  if ( ! isOpen() ) throw DatabaseNotOpen( "RelationalDatabase" );
+  RelationalTransaction transaction( transactionMgr(), true ); // read-only
+  std::vector<std::string> tables = __listAllTables();
+  transaction.commit();
+  return tables;
+}
+
+//-----------------------------------------------------------------------------
+
+const std::vector<std::string> RelationalDatabase::__listAllTables() const
+{
+  std::vector<std::string> tables;
+
+  // Get the database schema version
+  std::string dbSchemaVersion =
+    m_dbAttr[RelationalDatabaseTable::attributeNames::schemaVersion].
+    data<std::string>();
+
+  // Add the tables of each node
+  coral::AttributeList whereData;    // no query WHERE clause
+  std::string whereClause = "";      // no query WHERE clause
+  std::vector<std::string> orderBy;  // no query ORDER clause
+  std::string desc = "";             // no query description
+  std::vector<RelationalTableRow> nodes =
+    queryMgr().fetchOrderedRowsFromTables
+    ( RelationalQueryMgr::tableList( nodeTableName() ), 
+      RelationalQueryMgr::columnList
+      ( RelationalNodeTable::tableSpecification
+        ( VersionNumber( dbSchemaVersion ) ) ),
+      whereClause, whereData, orderBy, desc );
+  std::vector<RelationalTableRow>::const_iterator node;
+  for ( node = nodes.begin(); node != nodes.end(); node++ ) 
+  {
+    std::string fullPath =
+      (*node)[RelationalNodeTable::columnNames::nodeFullPath]
+      .data<std::string>();
+    bool isLeaf =
+      (*node)[RelationalNodeTable::columnNames::nodeIsLeaf].data<bool>();
+    // If the database schema version is 2.0.0 or higher, check that 
+    // the node schema version is supported by this software release
+    if ( VersionNumber( dbSchemaVersion ) >= VersionNumber( "2.0.0" ) ) 
+    {
+      VersionNumber schemaVersion = 
+        (*node)[RelationalNodeTable::columnNames::nodeSchemaVersion]
+        .data<std::string>();
+      bool isSupported = true;
+      if ( isLeaf ) {
+        if ( !RelationalFolder::isSupportedSchemaVersion( schemaVersion ) )
+        {
+          // Hack: 2.0.0 folders are not supported, but tables can be listed
+          if ( schemaVersion != VersionNumber( "2.0.0" ) ) 
+            isSupported = false;
+        }
+      }
+      else {
+        if ( !RelationalFolderSet::isSupportedSchemaVersion( schemaVersion ) )
+          isSupported = false;
+      }
+      if ( VersionInfo::release < schemaVersion )
+      {
+        std::stringstream s;
+        s << "Cannot list tables for node:";
+        if ( isLeaf ) s << " folder '";
+        else s << " folder set '";
+        s << fullPath << " has schema version " << schemaVersion
+          << " that is newer than this software release " 
+          << VersionInfo::release;
+        log() << coral::Warning << s.str() << coral::MessageStream::endmsg;
+        if ( isLeaf ) 
+          throw UnsupportedFolderSchema( s.str(), "RelationalDatabase" );
+        else 
+          throw UnsupportedFolderSetSchema( s.str(), "RelationalDatabase" );
+      }
+      else if ( !isSupported )
+      {
+        std::stringstream s;
+        s << "PANIC! Cannot list tables for node:";
+        if ( isLeaf ) s << " folder '";
+        else s << " folder set '";
+        s << fullPath
+          << "' appears to have been created using UNKNOWN schema version "
+          << schemaVersion 
+          << " that is older than (or as old as) the current software release "
+          << VersionInfo::release;
+        throw PanicException( s.str(), "RalDatabase" );
+      }
+    }
+    unsigned int nodeId =
+      (*node)[RelationalNodeTable::columnNames::nodeId].data<unsigned int>();
+    // Node is a folder
+    if ( isLeaf ) 
+    {
+      // Add tables for MV folders
+      FolderVersioning::Mode versioningMode =
+        RelationalFolder::versioningMode( (*node).data() );
+      if ( versioningMode == FolderVersioning::MULTI_VERSION ) 
+      {
+        // Add the IOV2tag table
+        tables.push_back
+          ( RelationalFolder::object2TagTableName( (*node).data() ) );
+        // Add the local tag sequence
+        tables.push_back
+          ( RelationalTagSequence::sequenceName
+            ( defaultTablePrefix(), nodeId ) );
+        // Add the local tag table
+        tables.push_back
+          ( RelationalFolder::tagTableName( (*node).data() ) );
+      }
+      // Add the channel table (2.0.0 or higher)
+      if ( VersionNumber( dbSchemaVersion ) >= VersionNumber( "2.0.0" ) ) 
+        tables.push_back
+          ( RelationalChannelTable::defaultTableName
+            ( defaultTablePrefix(), nodeId ) );
+      // Add the IOV table and the associated sequence
+      tables.push_back
+        ( RelationalObjectTable::sequenceName
+          ( RelationalFolder::objectTableName((*node).data()) ) );
+      tables.push_back
+        ( RelationalFolder::objectTableName( (*node).data() ) );
+    }  
+    // Node is a folder set
+    else {
+      // Add the local tag sequence
+      tables.push_back
+        ( RelationalTagSequence::sequenceName
+          ( defaultTablePrefix(), nodeId ) );
+    }    
+  }
+
+  // Add the global tag table
+  tables.push_back( globalTagTableName() );
+
+  // Add the tag2tag table and its associated sequence
+  tables.push_back( RelationalTag2TagTable::sequenceName(tag2TagTableName()) );
+  tables.push_back( tag2TagTableName() );
+
+  // Add the node table and its associated sequence
+  tables.push_back( RelationalNodeTable::sequenceName(nodeTableName()) );
+  tables.push_back( nodeTableName() );
+
+  // Add the main table
+  tables.push_back( mainTableName() );
+
+  // Return the full list of tables
+  return tables;
+}
+
+//-----------------------------------------------------------------------------
+
+
diff --git a/RelationalCool/src/RelationalDatabase.h b/RelationalCool/src/RelationalDatabase.h
new file mode 100644
index 000000000..ab4b0fec1
--- /dev/null
+++ b/RelationalCool/src/RelationalDatabase.h
@@ -0,0 +1,512 @@
+// $Id: RelationalDatabase.h,v 1.211 2009-01-06 12:30:07 avalassi Exp $
+#ifndef RELATIONALCOOL_RELATIONALDATABASE_H
+#define RELATIONALCOOL_RELATIONALDATABASE_H 1
+
+// Include files
+#include <memory>
+#include <vector>
+#include <boost/enable_shared_from_this.hpp>
+#include "CoolKernel/ChannelSelection.h"
+#include "CoolKernel/IDatabase.h"
+#ifdef COOL280
+#include "CoolKernel/ITransaction.h"
+#endif
+#include "CoolKernel/Record.h"
+#include "CoolKernel/ValidityKey.h"
+#include "CoralBase/AttributeList.h"
+#include "CoralBase/MessageStream.h"
+
+// Local include files
+#include "IHvsTagMgr.h"
+#include "RelationalDatabaseId.h"
+#include "RelationalDatabasePtr.h"
+#include "RelationalObjectPtr.h"
+
+namespace cool
+{
+
+  // Forward declarations
+  class ChannelSelection;
+  class IRelationalTransactionMgr;
+  class RelationalFolder;
+  class RelationalFolderSet;
+  class RelationalNodeMgr;
+  class RelationalObjectMgr;
+  class RelationalObjectTable;
+  class RelationalObjectTableRow;
+  class RelationalQueryMgr;
+  class RelationalSchemaMgr;
+  class RelationalTableRow;
+  class RelationalTagMgr;
+
+  /** @class RelationalDatabase RelationalDatabase.h
+   *
+   *  Generic relational implementation of one COOL "condition database"
+   *  instance (deployed on a specific physical infrastructure).
+   *
+   *  Abstract base class for specific relational implementations
+   *  sharing the same relational database schema (RAL, MySQL, ...).
+   *
+   *  @author Andrea Valassi, Sven A. Schmidt and Marco Clemencic
+   *  @date   2004-11-09
+   */
+
+  class RelationalDatabase : public IDatabase
+  {
+
+    friend class RelationalDatabaseTest;
+    friend class RalDatabaseTest;
+    friend class RalDatabaseTest_extendedSpec;
+
+  public:
+
+    // --- Implementation of the IDatabase interface. ---
+
+    /// Return the global identifier of the database
+    /// [WARNING: any visible passwords are masked out].
+    const DatabaseId& databaseId() const;
+
+    /// Return the 'attributes' of the database
+    /// (implementation-specific properties not exposed in the API).
+    /// Throws DatabaseNotOpen if the database is not open.
+    const IRecord& databaseAttributes() const;
+
+    /*
+    /// Does the database support this payload specification?
+    bool isValidPayloadSpecification( const IRecordSpecification& spec );
+    */
+
+    /*
+    /// Does the database support this channel specification?
+    bool isValidChannelSpecification( const IRecordSpecification& spec );
+    */
+
+    /// Create a new folder set and return the corresponding manager.
+    /// The ownership of the folderset manager instance is shared.
+    /// Throws DatabaseNotOpen if the database is not open.
+    /// Throws HvsPathHandlerException if the given path has an invalid format.
+    /// Throws NodeExists if a folder[set] with the same path already exists.
+    /// Throws an Exception if the max# of folder[set]s (9999) is exceeded.
+    /// Throws an Exception if an invalid versioning mode has been specified.
+    /// Throws an Exception if the user does not have writer privileges.
+    /// PURE VIRTUAL method implemented in subclasses.
+    virtual IFolderSetPtr createFolderSet
+    ( const std::string& fullPath,
+      const std::string& description = "",
+      bool createParents = false ) = 0;
+
+    /// Does this folder set exist?
+    /// Throws DatabaseNotOpen if the database is not open.
+    /// Throws HvsPathHandlerException if the given path has an invalid format.
+    bool existsFolderSet( const std::string& folderSetName );
+
+    /// Retrieve an existing folderset and return the corresponding manager.
+    /// The ownership of the folderset manager instance is shared.
+    /// Throws DatabaseNotOpen if the database is not open.
+    /// Throws HvsPathHandlerException if the given path has an invalid format.
+    /// Throws FolderSetNotFound if the folderset does not exist.
+    /// PURE VIRTUAL method implemented in subclasses.
+    virtual IFolderSetPtr getFolderSet( const std::string& fullPath ) = 0;
+
+    /// Create a new folder and return the corresponding manager.
+    /// The ownership of the folder manager instance is shared.
+    /// Throws DatabaseNotOpen if the database is not open.
+    /// Throws HvsPathHandlerException if the given path has an invalid format.
+    /// Throws NodeExists if a folder[set] with the same path already exists.
+    /// Throws an Exception if the max# of folder[set]s (9999) is exceeded.
+    /// Throws an Exception if an invalid versioning mode has been specified.
+    /// Throws an Exception if the user does not have writer privileges.
+    /// PURE VIRTUAL method implemented in subclasses.
+    virtual IFolderPtr createFolder
+    ( const std::string& fullPath,
+      const IFolderSpecification& folderSpec,
+      const std::string& description = "",
+      bool createParents = false ) = 0;
+
+    /// DEPRECATED: use IFolderSpecification instead of IRecordSpecification!
+    /// This is similar to the COOL1.3.3 API (with IRecordSpecification 
+    /// instead of ExtendedAttributeListSpecification), for easier porting of 
+    /// user code, but it is likely to be removed in a future COOL release.
+    /// PURE VIRTUAL method implemented in subclasses.
+    virtual IFolderPtr createFolder
+    ( const std::string& fullPath,
+      const IRecordSpecification& payloadSpec,
+      const std::string& description = "",
+      FolderVersioning::Mode mode = FolderVersioning::SINGLE_VERSION,
+      bool createParents = false ) = 0;
+
+    /// Does this folder exist?
+    /// Throws DatabaseNotOpen if the database is not open.
+    /// Throws HvsPathHandlerException if the given path has an invalid format.
+    bool existsFolder( const std::string& fullPath );
+
+    /// Retrieve an existing folder and return the corresponding manager.
+    /// The ownership of the folder manager instance is shared.
+    /// Throws DatabaseNotOpen if the database is not open.
+    /// Throws HvsPathHandlerException if the given path has an invalid format.
+    /// Throws FolderNotFound if the folder does not exist.
+    /// PURE VIRTUAL method implemented in subclasses.
+    virtual IFolderPtr getFolder( const std::string& fullPath ) = 0;
+
+    /// Return the list of existing nodes
+    /// (in ascending/descending alphabetical order).
+    const std::vector<std::string> listAllNodes( bool ascending = true );
+
+    /// Drop an existing node (folder or folder set).
+    /// Also delete any tags associated to the node.
+    /// Return true if the node and all its structures are dropped as expected.
+    /// Return false (without throwing any exception) if the node and
+    /// all its structures do not exist any more on exit from this method,
+    /// but the node or some of its structures did not exist to start with.
+    /// Throw an Exception if the node schema version is more recent than
+    /// the schema version supported by the current COOL software release.
+    /// Throw an Exception if the node or one of its structures cannot
+    /// be dropped (i.e. continue to exist on exit from this method).
+    /// Throw an Exception if the node is a non-empty folder set.
+    /// Throw an Exception if any associated tags cannot be deleted.
+    /// PURE VIRTUAL method implemented in subclasses.
+    virtual bool dropNode( const std::string& fullPath ) = 0;
+
+    /// HVS: does this tag exist?
+    /// Tag names, except for "HEAD", are case sensitive.
+    /// Returns true for the reserved tags "" and "HEAD".
+    bool existsTag( const std::string& tagName ) const
+    {
+      return hvsTagMgr().existsTag( tagName );
+    }    
+    
+    /// HVS: return the node type (inner/leaf) where this tag name can be used.
+    /// Tag names, except for "HEAD", are case sensitive.
+    /// Throws TagNotFound if the tag does not exist.
+    IHvsNode::Type tagNameScope( const std::string& tagName ) const
+    {
+      return hvsTagMgr().tagNameScope( tagName );
+    }
+
+    /// HVS: return the names of the nodes where this tag is defined.
+    /// Tag names, except for "HEAD", are case sensitive.
+    /// Throws TagNotFound if the tag does not exist.
+    /// Throws ReservedHeadTag for the HEAD tag (defined in all folders).
+    const std::vector<std::string> 
+    taggedNodes( const std::string& tagName ) const
+    {
+      return hvsTagMgr().taggedNodes( tagName );
+    }
+
+    /// Is the database 'open'?
+    /// NB Note the difference between 'open' and 'connected': the database 
+    /// is 'connected' if the connection to the database backend has been
+    /// established; it is 'open' if the management table has been read.
+    bool isOpen() const;
+
+    /// (Re)opens the database.
+    void openDatabase();
+
+    /// Closes the database.
+    void closeDatabase();
+
+    /// Return the "COOL database name".
+    const std::string& databaseName() const;
+    
+#ifdef COOL280
+    /// Start a new transaction and enter manual transaction mode
+    virtual ITransactionPtr startTransaction() = 0;
+#endif
+
+    // --- Other public methods. ---
+
+    /// Return the list of folders inside the given folderset
+    /// (in ascending/descending alphabetical order).
+    const std::vector<std::string>
+    listFolders( const RelationalFolderSet* folderset,
+                 bool ascending = true ) const;
+
+    /// Return the list of foldersets inside the given folderset
+    /// (in ascending/descending alphabetical order).
+    const std::vector<std::string>
+    listFolderSets( const RelationalFolderSet* folderset,
+                    bool ascending = true ) const;
+
+    /// Get a constant reference to the HVS tag manager
+    const IHvsTagMgr& hvsTagMgr() const;
+
+    /// Return the RelationalDatabasePtr
+    /// PURE VIRTUAL method implemented in subclasses.
+    virtual boost::shared_ptr<RelationalDatabase> relationalDbPtr() = 0;
+
+    /// Return the default table prefix (from the database attributes)
+    const std::string defaultTablePrefix() const;
+
+    /// Return the name of the main table (from the db name)
+    const std::string mainTableName() const;
+
+    // *** START *** 3.0.0 schema extensions (task #4307)
+    /// Return the name of the iovTables table (from the db attributes)
+    const std::string iovTablesTableName() const;
+
+    /// Return the name of the channelTables table (from the db attributes)
+    const std::string channelTablesTableName() const;
+    // **** END **** 3.0.0 schema extensions (task #4307)
+
+    /// Return the name of the folder table (from the db attributes)
+    const std::string nodeTableName() const;
+
+    /// Return the name of the global tag table (from the db attributes)
+    const std::string globalTagTableName() const;
+
+    // *** START *** 3.0.0 schema extensions (task #4396)
+    /// Return the name of the global head tag table (from the db attributes)
+    const std::string globalHeadTagTableName() const;
+
+    /// Return the name of the global user tag table (from the db attributes)
+    const std::string globalUserTagTableName() const;
+    // **** END **** 3.0.0 schema extensions (task #4396)
+
+    /// Return the name of the tag2tag table (from the db attributes)
+    const std::string tag2TagTableName() const;
+
+    /// Return the name of the tag shared sequence (from the db attributes)
+    const std::string tagSharedSequenceName() const;
+
+    /// Return the name of the IOV shared sequence (from the db attributes)
+    const std::string iovSharedSequenceName() const;
+
+    /// Get a RelationalObjectTable for the given folder.
+    /// The concrete class can only be created by the concrete database.
+    /// The RelationalFolder parameter is only used to obtain 
+    /// the associated table names and is *not* retained.
+    /// PURE VIRTUAL method implemented in subclasses.
+    virtual boost::shared_ptr<RelationalObjectTable> 
+    relationalObjectTable( const RelationalFolder& folder ) const = 0;
+
+    /// Update the description for the given node
+    /// PURE VIRTUAL method implemented in subclasses.
+    virtual void updateNodeTableDescription
+    ( const std::string& fullPath,
+      const std::string& description ) const = 0;
+
+    /// Get the IRelationalTransactionMgr
+    boost::shared_ptr<IRelationalTransactionMgr> transactionMgr() const;
+
+    /// Return the StorageType singleton for the given type name.
+    /// Throw a RelationalException if no storage type exists with that name.
+    static const StorageType& storageType( const std::string& name );
+
+    /// Get a string representation of a RecordSpecification
+    static const std::string
+    encodeRecordSpecification( const IRecordSpecification& recordSpec );
+    
+    /// Decode a RecordSpecification from its string representation
+    static const RecordSpecification
+    decodeRecordSpecification( const std::string& encodedSpec );
+
+    /// Get the RelationalQueryMgr
+    RelationalQueryMgr& queryMgr() const;
+
+    /// Get the RelationalSchemaMgr
+    RelationalSchemaMgr& schemaMgr() const;
+
+    /// Get the RelationalNodeMgr
+    RelationalNodeMgr& nodeMgr() const;
+
+    /// Get the RelationalTagMgr
+    RelationalTagMgr& tagMgr() const;
+
+    /// Get the RelationalObjectMgr
+    const RelationalObjectMgr& objectMgr() const;
+    
+    /// Is this a valid name for a payload field of a folder?
+    /// Payload field names must have between 1 and 30 characters (including
+    /// only letters, digits or '_'), must start with a letter and cannot start
+    /// with the "COOL_" prefix (in any lowercase/uppercase combination).
+    static bool isValidPayloadFieldName( const std::string& name );
+    
+    /// Return the list of all existing tables (within a transaction)
+    const std::vector<std::string> listAllTables() const;
+
+    /// Return the list of all existing tables (no transaction)
+    const std::vector<std::string> __listAllTables() const;
+
+    /// Required access mode to the database.
+    /// Delegated to RalSessionMgr.
+    virtual bool isReadOnly() const = 0;
+
+  protected:
+
+    /// The following methods are all protected: only subclasses can
+    /// instantiate or delete this class and create, drop or open a database
+
+    /// Destructor
+    virtual ~RelationalDatabase();
+
+    /// Constructor
+    RelationalDatabase( const DatabaseId& dbId );
+
+    /// Create a new database with default attributes.
+    /// Default attributes are those specific for a RelationalDatabase.
+    void createDatabase();
+
+    /// Create a new database with non-default attributes.
+    /// PURE VIRTUAL method implemented in subclasses.
+    virtual void createDatabase( const IRecord& dbAttr ) = 0;
+
+    /// Drop the database.
+    /// PURE VIRTUAL method implemented in subclasses.
+    virtual bool dropDatabase() = 0;
+
+    /// Fetch the database attributes (fetch all rows from the main table).
+    const Record fetchDatabaseAttributes() const;
+
+    /// AV - TO BE REMOVED
+    /// Fetch one node row (lookup by 1 node fullPath)
+    const RelationalTableRow 
+    fetchNodeTableRow( const std::string& fullPath ) const;
+
+    /// AV - TO BE REMOVED
+    /// Fetch one node row (lookup by 1 nodeId)
+    const RelationalTableRow 
+    fetchNodeTableRow( unsigned int nodeId ) const;
+
+    /// AV - TO BE REMOVED
+    /// Fetch one node row (lookup with given WHERE clause and bind variables)
+    const RelationalTableRow 
+    fetchNodeTableRow( const std::string& whereClause,
+                       const coral::AttributeList& whereData ) const;
+
+    /// WARNING: UNUSED! (AV)
+    /// Fetch the tag table row for the given tagname in the given tag table
+    RelationalTableRow
+    fetchTagTableRow( const std::string& tagTableName,
+                      const std::string& tagName );
+
+    /// WARNING: UNUSED! (AV)
+    /// Fetch the object2Tag table row for the given tagId, objectId
+    RelationalTableRow
+    fetchObject2TagTableRow( const std::string& tagTableName,
+                             unsigned int tagId,
+                             unsigned int objectId );
+
+    /// Does this node exist?
+    bool existsNode( const std::string& fullPath );
+
+    /// Return the list of nodes inside the given nodeId with the attribute
+    /// isLeaf as specified (ordered by name asc/desc)
+    const std::vector<std::string> 
+    listNodes( unsigned int nodeId,
+               bool isLeaf,
+               bool ascending = true ) const;
+
+    /// Get a CORAL MessageStream
+    coral::MessageStream& log() const;
+
+    /// Set the RelationalQueryMgr (transfer ownership)
+    void setQueryMgr( std::auto_ptr<RelationalQueryMgr> queryMgr );
+    
+    /// Set the RelationalSchemaMgr (transfer ownership)
+    void setSchemaMgr( std::auto_ptr<RelationalSchemaMgr> schemaMgr );
+    
+    /// Set the RelationalNodeMgr (transfer ownership)
+    void setNodeMgr( std::auto_ptr<RelationalNodeMgr> nodeMgr );
+    
+    /// Set the RelationalTagMgr (transfer ownership)
+    void setTagMgr( std::auto_ptr<RelationalTagMgr> tagMgr );
+    
+    /// Set the RelationalObjectMgr (transfer ownership)
+    void setObjectMgr( std::auto_ptr<RelationalObjectMgr> objectMgr );
+    
+    /// Set the IRelationalTransactionMgr (shared ownership)
+    void setTransactionMgr
+      ( boost::shared_ptr<IRelationalTransactionMgr> mgr );
+    
+    /// Database attribute specification for the RelationalDatabase class
+    static
+    const IRecordSpecification& databaseAttributesSpecification();
+
+    /// Check whether this software library can read the given schema.
+    /// Returns true if the schema can be read without schema evolution.
+    /// Returns false if the schema requires schema evolution.
+    /// Throws an IncompatibleReleaseNumber if the schema is newer than 
+    /// this software library or no schema evolution is possible.
+    bool areReleaseAndSchemaCompatible
+    ( const std::string releaseNumber,
+      const std::string schemaVersion ) const;
+    
+    /// Validate the payload specification.
+    /// Throws InvalidPayloadSpecification if the payload specification is 
+    /// invalid: there can be at most 900 fields, including up to 10 BLOB 
+    /// fields and up to 200 String255 fields; field names must be between 
+    /// 1 and 30 characters (including only letters, digits or '_'), must 
+    /// start with a letter and cannot start with the "COOL_" prefix (in any 
+    /// combination of lowercase and uppercase letters).
+    void validatePayloadSpecification( const IRecordSpecification& spec );
+    
+  private:
+    
+    /// Is the database 'connected'?
+    /// Delegated to RalSessionMgr.
+    /// [NB Note the difference between 'open' and 'connected': the database 
+    /// is 'connected' if the connection to the database backend has been
+    /// established; it is 'open' if the management table has been read].
+    /// PURE VIRTUAL method implemented in subclasses.
+    virtual bool isConnected() const = 0;
+
+    /// (Re)connect to the database.
+    /// Delegated to RalSessionMgr.
+    /// PURE VIRTUAL method implemented in subclasses.
+    virtual void connect() = 0;
+
+    /// Disconnect from the database.
+    /// Delegated to RalSessionMgr.
+    /// PURE VIRTUAL method implemented in subclasses.
+    virtual void disconnect() = 0;
+
+  private:
+
+    /// Standard constructor is private
+    RelationalDatabase();
+
+    /// Copy constructor is private
+    RelationalDatabase( const RelationalDatabase& rhs );
+
+    /// Assignment operator is private
+    RelationalDatabase& operator=( const RelationalDatabase& rhs );
+
+  protected:
+
+    /// Attributes of the database
+    Record m_dbAttr;
+
+    /// Is the database open?
+    bool m_isOpen;
+
+    /// Global identifier of the database
+    RelationalDatabaseId m_relationalDbId;
+
+  private:
+
+    /// CORAL MessageStream
+    std::auto_ptr<coral::MessageStream> m_log;
+
+    /// RelationalQueryMgr (owned by this instance)
+    std::auto_ptr<RelationalQueryMgr> m_queryMgr;
+
+    /// RelationalSchemaMgr (owned by this instance)
+    std::auto_ptr<RelationalSchemaMgr> m_schemaMgr;
+
+    /// RelationalNodeMgr (owned by this instance)
+    std::auto_ptr<RelationalNodeMgr> m_nodeMgr;
+
+    /// RelationalTagMgr (owned by this instance)
+    std::auto_ptr<RelationalTagMgr> m_tagMgr;
+
+    /// RelationalObjectMgr (owned by this instance)
+    std::auto_ptr<RelationalObjectMgr> m_objectMgr;
+
+    /// IRelationalTransactionMgr (shared ownership)
+    boost::shared_ptr<IRelationalTransactionMgr> m_transactionMgr;
+
+  };
+
+}
+
+#endif // RELATIONALCOOL_RELATIONALDATABASE_H
diff --git a/RelationalCool/src/RelationalDatabaseId.cpp b/RelationalCool/src/RelationalDatabaseId.cpp
new file mode 100644
index 000000000..feb4c81cc
--- /dev/null
+++ b/RelationalCool/src/RelationalDatabaseId.cpp
@@ -0,0 +1,334 @@
+// $Id: RelationalDatabaseId.cpp,v 1.30 2009-02-04 10:57:57 avalassi Exp $
+
+// Include files
+#include <sstream>
+
+// Local include files
+#include "RelationalDatabaseId.h"
+#include "RelationalException.h"
+#include "uppercaseString.h"
+
+// Namespace
+using namespace cool;
+
+//-----------------------------------------------------------------------------
+
+RelationalDatabaseId::RelationalDatabaseId( const std::string& url ) 
+  : m_middleTier  ( "" )
+  , m_technology  ( "" )
+  , m_server      ( "" )
+  , m_schema      ( "" )
+  , m_dbName      ( "" ) 
+  , m_user        ( "" )
+  , m_password    ( "" )
+  , m_alias       ( "" )
+  , m_role        ( "" )
+  , m_url         ( "" ) 
+  , m_urlHidePswd ( "" ) 
+  , m_urlNoDbname ( "" ) 
+{
+
+  i_parseUrl( url );  
+
+  // Debug output
+  /*
+  std::cout << "__RelationalDatabaseId Parsing URL: " 
+            << url << std::endl;
+  std::cout << "__RelationalDatabaseId MiddleTier:  " 
+            << m_middleTier << std::endl;
+  std::cout << "__RelationalDatabaseId Technology:  " 
+            << m_technology << std::endl;
+  std::cout << "__RelationalDatabaseId Server:      " 
+            << m_server << std::endl;
+  std::cout << "__RelationalDatabaseId Schema:      " 
+            << m_schema << std::endl;
+  std::cout << "__RelationalDatabaseId DbName:      " 
+            << m_dbName << std::endl;
+  std::cout << "__RelationalDatabaseId User:        " 
+            << m_user << std::endl;
+  std::cout << "__RelationalDatabaseId Password:    " 
+            << m_password << std::endl;
+  std::cout << "__RelationalDatabaseId URL: " 
+            << m_url << std::endl;
+  std::cout << "__RelationalDatabaseId URL with password hidden: " 
+            << m_urlHidePswd << std::endl;
+  std::cout << "__RelationalDatabaseId URL with no dbname: " 
+            << m_urlNoDbname << std::endl;
+  */
+
+  i_validate();
+
+}
+
+//-----------------------------------------------------------------------------
+
+void RelationalDatabaseId::i_validate() {
+
+  // Check that the schema name is not empty
+  if ( m_schema.empty() && m_alias.empty() ) 
+    throw RelationalException
+      ( "Invalid COOL database URL '" + m_url + 
+        "': no schema and no alias specified", 
+        "RelationalDatabaseId" );
+
+  // Check that the database name is not empty
+  if ( m_dbName.empty() ) 
+    throw RelationalException
+      ( "Invalid COOL database URL '" + m_url + 
+        "': no database name specified",
+        "RelationalDatabaseId" );
+
+  // Check that the database name is at most 8 characters long
+  unsigned int dbNameMaxLength = 8;
+  if ( m_dbName.size() > dbNameMaxLength ) {
+    std::stringstream s;
+    s << "Invalid COOL database name '" << m_dbName
+      << "': the database name length must not exceed " 
+      << dbNameMaxLength << " characters";
+    throw RelationalException( s.str(), "RelationalDatabaseId" );
+  } 
+
+  // Check that the database name is uppercase
+  if ( m_dbName != uppercaseString(m_dbName) ) {
+    std::stringstream s;
+    s << "Invalid COOL database name '" << m_dbName 
+      << "': the database name must be UPPERCASE";
+    throw RelationalException( s.str(), "RelationalDatabaseId" );
+  }  
+
+  // Check that the database name contains only letters, numbers or '_'
+  static std::string allowedChar = 
+    "ABCDEFGHIJKLMNOPQRSTUVWXYZ_1234567890";
+  if ( m_dbName.find_first_not_of(allowedChar) != m_dbName.npos ) {
+    std::stringstream s;
+    s << "Invalid COOL database name '" << m_dbName 
+      << "': the database name must contain only letters, numbers"
+      << " or the '_' character";
+    throw RelationalException( s.str(), "RelationalDatabaseId" );
+  }  
+
+  // Check that the database name starts with a letter
+  static std::string allowedFirstChar = 
+    "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
+  if ( m_dbName.find_first_of(allowedFirstChar) != 0 ) {
+    std::stringstream s;
+    s << "Invalid COOL database name '" << m_dbName 
+      << "': the database name must start with a letter";
+    throw RelationalException( s.str(), "RelationalDatabaseId" );
+  }  
+  
+}
+
+//-----------------------------------------------------------------------------
+
+RelationalDatabaseId::RelationalDatabaseId( const std::string& technology,
+                                            const std::string& server,
+                                            const std::string& schema,
+                                            const std::string& dbName,
+                                            const std::string& user,
+                                            const std::string& password )
+  : m_middleTier  ( "" )
+{
+  std::string url = technology + "://" + server;
+  url += std::string( ";schema=" ) + schema;
+  url += std::string( ";dbname=" ) + dbName;
+  if ( user != "" )
+    url += std::string( ";user=" ) + user;
+  if ( password != "" )
+    url += std::string( ";password=" ) + password;
+  i_parseUrl( url );  
+  i_validate();
+}
+
+//-----------------------------------------------------------------------------
+
+RelationalDatabaseId::RelationalDatabaseId( const std::string& alias,
+                                            const std::string& dbName,
+                                            const std::string& dbRole )
+  : m_middleTier  ( "" )
+{
+  if ( dbRole.empty() ){
+    i_parseUrl( alias + "/" + dbName );
+  } else {
+    i_parseUrl( alias + "(" + dbRole + ")/" + dbName );
+  }
+  i_validate();
+}
+
+//-----------------------------------------------------------------------------
+
+const std::string 
+RelationalDatabaseId::extractOption( const std::string& url, 
+                                     const std::string& inputOption ) 
+{
+  std::string option = inputOption;
+  if (option[option.size()-1] != '=') option += '=';
+  size_t pos1 = url.find(option);
+  size_t pos2;
+  if ( pos1 != url.npos ) {
+    pos1 += option.size(); // move to the end of the occurence of "option"
+    pos2 = url.find(";",pos1);
+    if ( pos2 == url.npos )
+      return url.substr(pos1);
+    else 
+      return url.substr(pos1,pos2-pos1);
+  }
+  return "";
+}
+
+//-----------------------------------------------------------------------------
+
+void RelationalDatabaseId::i_parseUrl( const std::string& fullUrl ) 
+{
+
+  // URL formats:
+  //
+  //     <technology>://<server>;schema=<schema>;dbname=<dbname>[;user=<user>;password=<password>]
+  //
+  //     <alias>/<dbname>
+  //
+  //     coral[...]://host:port&<technology>://<server>;schema=<schema>;dbname=<dbname>[;user=<user>;password=<password>]
+  //
+  //     coral[...]://host:port&<alias>/<dbname>
+  //
+
+  // distinguish between the four types
+  std::string url = fullUrl;
+
+  // Third or fourth format
+  if ( url.find("://") != url.npos ) 
+  { 
+
+    std::string sep = "&";
+    size_t pos = url.find(sep);
+    if ( pos != url.npos )
+    {
+      if ( url.find("coral") != 0 )
+        throw RelationalException
+          ( "Middle tier prefix '..." +sep + "' does not start with 'coral'", 
+            "RelationalDatabaseId" );
+      m_middleTier = url.substr(0,pos+1);
+      url = url.substr(pos+1);
+    }    
+
+  }
+  
+  // First or third format
+  if ( url.find("://") != url.npos ) 
+  { 
+    
+    // find technology
+    size_t pos = url.find("://");
+    m_technology = url.substr(0,pos);
+    // check technology
+    if ( m_technology != "oracle" && 
+         m_technology != "mysql" && 
+         m_technology != "sqlite" &&
+         m_technology != "frontier" ) {
+      throw RelationalException
+        ( "Unknown technology '" + m_technology + 
+          "' in input URL '" + url + "'", "RelationalDatabaseId" );
+    }
+    
+    // find server
+    pos += 3; // mo to the end of "://"
+    size_t pos2 = url.find(";",pos);
+    if ( pos2 == url.npos ) { /// \todo FIX-ME: this should not be allowed
+      m_server = url.substr(pos);
+    } else {
+      m_server = url.substr(pos,pos2-pos);
+    }
+    
+    // extract options
+    m_schema   = extractOption(url,"schema");
+    m_dbName   = extractOption(url,"dbname");
+    m_user     = extractOption(url,"user");
+    m_password = extractOption(url,"password");
+
+    m_alias = "";
+
+    // set commodity strings
+    m_url = m_urlHidePswd = m_urlNoDbname = m_technology + "://" + m_server;
+    
+    if (!m_schema.empty()) {
+      std::string schema = ";schema=" + m_schema;
+      m_url += schema;
+      m_urlHidePswd += schema;
+      m_urlNoDbname += schema;
+    }
+    
+    if (!m_dbName.empty()) {
+      std::string dbName = ";dbname=" + m_dbName;
+      m_url += dbName;
+      m_urlHidePswd += dbName;
+    }
+    
+    if (!m_user.empty()) {
+      std::string user = ";user=" + m_user;
+      m_url += user;
+      m_urlHidePswd += user;
+      m_urlNoDbname += user;
+    }
+
+    if (!m_password.empty()) {
+      std::string password = ";password=" + m_password;
+      m_url += password;
+      m_urlHidePswd += std::string(";password=") + "********";
+      m_urlNoDbname += password;
+    }    
+
+  } 
+
+  // Second or fourth format
+  else 
+  { 
+    
+    size_t pos = url.find_last_of('/');
+
+    if ( pos == url.npos ) {
+      throw RelationalException
+        ( "Invalid COOL database URL '" + url + 
+          "': no '/' character found", 
+          "RelationalDatabaseId" );
+    }  
+
+    m_alias = url.substr(0,pos);
+    m_dbName = url.substr(pos+1);
+    
+    if ( m_alias[m_alias.size()-1] == ')' ) {
+      // role explicetely defined
+      pos = url.find_last_of('(');
+      if ( pos == url.npos ) {
+        throw RelationalException
+          ( "Invalid COOL database URL: '" + url +
+            "': no matching '(' character found", 
+            "RelationalDatabaseId" );
+      }
+      m_role  = m_alias.substr(pos+1,m_alias.size()-2-pos);
+      m_alias = m_alias.substr(0,pos);
+    }
+    
+    m_user = m_password = "";
+    // Check if the URL starts with "sqlite_file:"
+    if ( m_alias.substr(0,12) == "sqlite_file:" ) {
+      m_technology = "sqlite";
+      m_schema = m_alias.substr(12);
+    } else {
+      m_technology = "";
+      m_schema = "";
+    }
+
+    // set commodity strings
+    if (m_role.empty()) {
+      m_url = m_urlHidePswd = m_alias + "/" + m_dbName;
+      m_urlNoDbname = m_alias;
+    } else {
+      m_url = m_urlHidePswd = m_alias + "(" + m_role + ")/" + m_dbName;
+      m_urlNoDbname = m_alias + "(" + m_role + ")";
+    }
+  }
+
+}
+
+//-----------------------------------------------------------------------------
+
diff --git a/RelationalCool/src/RelationalDatabaseId.h b/RelationalCool/src/RelationalDatabaseId.h
new file mode 100644
index 000000000..71431d7fb
--- /dev/null
+++ b/RelationalCool/src/RelationalDatabaseId.h
@@ -0,0 +1,175 @@
+// $Id: RelationalDatabaseId.h,v 1.18 2009-02-09 18:56:15 avalassi Exp $
+#ifndef RELATIONALCOOL_RELATIONALALDATABASEID_H 
+#define RELATIONALCOOL_RELATIONALALDATABASEID_H 1
+
+// Include files
+#include <string>
+#include <map>
+
+namespace cool {
+
+  /** @class RelationalDatabaseId RelationalDatabaseId.h
+   *  
+   *  Lookup information for a relational COOL conditions database 
+   *  implemented using the RelationalAccess layer (CORAL).
+   *
+   *  A RelationalDatabaseID can be constructed from a string URL.
+   *  The URL is parsed assuming the following syntax
+   *  - "alias[(role)]/dbname"
+   *  - "technology://server;schema=xx;dbname=xx[;user=xx][;password=xx]"
+   *    (<i>deprecated</i>)
+   *
+   *  The first format uses CORAL ConnectionService. "alias" is the
+   *  CORAL logical database name and the optional parameter "role" is
+   *  the CORAL role.
+   *  
+   *  Options "schema", "dbname", "user" and "password" can be entered
+   *  in any given order. Any other options are presently ignored.
+   *
+   *  Parameter "technology": required.
+   *  Specifies the relational backend technology.
+   *  Supported values: "oracle", "mysql", "sqlite" and "frontier".
+   * 
+   *  Parameter "server": required.
+   *  Specifies the Internet address of the relational database server.
+   *  Supported values:
+   *  - oracle: TNS ("devdb10") or EasyConnect ("oradev10[.cern.ch]:10520/D10")
+   *  - mysql: host[:port] ("pcitdb59[.cern.ch][:3306]")
+   *  - sqlite: none ("none"), sqlite uses files on the local client
+   *  - frontier: oracle EasyConnect ("frontier3d[.cern.ch]:8080/Frontier")
+   * 
+   *  Parameter "schema": required.
+   *  Specifies the namespace to be used as a prefix for accessing COOL
+   *  tables, according to the SQL syntax "select * from namespace.table".
+   *  Supported values:
+   *  - oracle: user name (name of table owner) 
+   *  - mysql: 'database' name
+   *  - sqlite: 'database' name (see http://www.sqlite.org/lang_attach.html)
+   *  - frontier: oracle user name (name of table owner) 
+   * 
+   *  Parameter "dbname": required.
+   *  Restrictions: "dbname" must be uppercase and 1 to 8 characters long; 
+   *  it may contain letters, numbers or '_', but it must start with a letter.
+   *  Specifies a unique identifier of a COOL "database" within a given schema
+   *  (for instance, it may indicate the name of a top-level management table, 
+   *  or a primary key entry in a top-level management table of predefined 
+   *  name, or a string prefixed to predefined table names). 
+   *  Presently, a COOL database "dbname" can be bootstrapped from the single 
+   *  table "dbname"_DB_ATTRIBUTES, which contains the names of all other
+   *  tables or table prefixes for that database; actually, all tables are
+   *  created by default with a "dbname_" prefix, but this is not assumed
+   *  at lookup time.
+   * 
+   *  Parameter "password": optional.
+   *  Specifies the password to connect to the given server as the given user
+   *  (an exception is thrown if "password" is specified but "user" is not).
+   *  If "password" is absent, a database connection using an authentication 
+   *  service is attempted (presently, the password is looked up in an XML 
+   *  file, eventually grid certificates or Kerberos tokens may be used).
+   * 
+   *  Parameter "user": optional.
+   *  Specifies the user name to connect to the given server (the password may
+   *  be either passed in the URL or looked up via the authentication service).
+   *  If "user" is absent, the default user and password for the given server
+   *  and schema [and dbname] are looked up via the authentication service.
+   *  For mysql and sqlite, connections with no user/password are possible.
+   * 
+   *  Examples:
+   *    "oracle://devdb10;schema=aSch;dbname=aDb;user=aUser;password=aPswd"
+   *    "oracle://oradev10:10520/D10;schema=aSc;dbname=aDb;user=aUs"
+   *    "mysql://pcitdb59;schema=aSch;dbname=aDb;user=aUser;password=aPswd"
+   *    "sqlite://none;schema=myFile.db;dbname=aDb"
+   *    "frontier://frontier3d.cern.ch:8080/Frontier;schema=aSch;dbname=aDb"
+   *
+   *  *** WARNING!!! THIS MAY CHANGE IN LATER VERSIONS OF THE CODE!!! ***
+   *  New (not for production!): an optional prefix "coral[...]://host:port&"
+   *  indicates that COOL should connect to a CORAL server. Any prefix that
+   *  begins with "coral" will be interpreted this way (eg "coral", "corals").
+   *  Both explicit URLs and aliases are supported, e.g.
+   *  "coral://host:port&oracle://server;schema=x;dbname=y;user=w;password=z"
+   *  "coral://host:port&alias/dbname"
+   *  *** WARNING!!! THIS MAY CHANGE IN LATER VERSIONS OF THE CODE!!! ***
+   *
+   *  @author Sven A. Schmidt, Andrea Valassi and Marco Clemencic
+   *  @date   2004-08-23
+   */
+
+  class RelationalDatabaseId {
+
+  public:
+
+    /// Construct a RelationalDatabaseId from a string URL
+    RelationalDatabaseId( const std::string& url );
+
+    /// Construct a RelationalDatabaseId from explicit parameters
+    RelationalDatabaseId( const std::string& technology,
+                          const std::string& server,
+                          const std::string& schema,
+                          const std::string& dbName,
+                          const std::string& user = "",
+                          const std::string& password = "" );
+
+    /// Construct a RelationalDatabaseId from explicit parameters
+    RelationalDatabaseId( const std::string& alias,
+                          const std::string& dbName,
+                          const std::string& dbRole = "" );
+
+    /// Destructor
+    virtual ~RelationalDatabaseId(){}
+    
+    const std::string& middleTier() const { return m_middleTier; }
+
+    const std::string& technology() const { return m_technology; }
+    const std::string& server() const { return m_server; }
+    const std::string& schema() const { return m_schema; }
+    const std::string& dbName() const { return m_dbName; }
+    const std::string& user() const { return m_user; }
+    const std::string& password() const { return m_password; }
+
+    const std::string& alias() const { return m_alias; }
+    const std::string& role() const { return m_role; }
+
+    const std::string& url() const { return m_url; }
+    const std::string& urlHidePswd() const { return m_urlHidePswd; }
+    const std::string& urlNoDbname() const { return m_urlNoDbname; }
+
+  private:
+    
+    /// Standard constructor is private
+    RelationalDatabaseId(); 
+    
+    /// Validate the parameters specified in the constructor
+    void i_validate();
+
+    /// Parse a URL and set the connection parameters accordingly
+    void i_parseUrl( const std::string& url );
+
+    /// Extract from a given string containing a sub-string 
+    /// like "option=*****;" the part between '=' and ';' 
+    /// (or the end of the string if ';' is not present).
+    static const std::string 
+    extractOption( const std::string& url, const std::string& option );
+    
+  private:
+
+    std::string m_middleTier; // Example: "coral[...]://host:port&"
+
+    std::string m_technology;
+    std::string m_server;
+    std::string m_schema;
+    std::string m_dbName;
+    std::string m_user;
+    std::string m_password;
+
+    std::string m_alias;
+    std::string m_role;
+
+    std::string m_url;
+    std::string m_urlHidePswd;
+    std::string m_urlNoDbname;
+    
+  };
+  
+}
+
+#endif // RELATIONALCOOL_RELATIONALALDATABASEID_H
diff --git a/RelationalCool/src/RelationalDatabasePtr.h b/RelationalCool/src/RelationalDatabasePtr.h
new file mode 100644
index 000000000..758e53302
--- /dev/null
+++ b/RelationalCool/src/RelationalDatabasePtr.h
@@ -0,0 +1,19 @@
+// $Id: RelationalDatabasePtr.h,v 1.1 2006-03-10 11:52:39 avalassi Exp $
+#ifndef RELATIONALCOOL_RELATIONALDATABASEPTR_H
+#define RELATIONALCOOL_RELATIONALDATABASEPTR_H
+
+// Include files
+#include <boost/shared_ptr.hpp>
+
+namespace cool {
+	
+  // Forward declarations
+  class RelationalDatabase;
+  
+  /// Shared pointer to a RelationalObject
+  typedef boost::shared_ptr<RelationalDatabase> RelationalDatabasePtr;
+	  
+}
+
+#endif
+
diff --git a/RelationalCool/src/RelationalDatabaseTable.cpp b/RelationalCool/src/RelationalDatabaseTable.cpp
new file mode 100644
index 000000000..48a8b9c7f
--- /dev/null
+++ b/RelationalCool/src/RelationalDatabaseTable.cpp
@@ -0,0 +1,26 @@
+// $Id: RelationalDatabaseTable.cpp,v 1.7 2006-09-28 12:49:29 avalassi Exp $
+
+// Include files
+#include "CoolKernel/RecordSpecification.h"
+
+// Local include files
+#include "RelationalDatabaseTable.h"
+
+//-----------------------------------------------------------------------------
+
+const cool::IRecordSpecification&
+cool::RelationalDatabaseTable::tableSpecification()
+{
+  static cool::RecordSpecification spec;
+  if ( spec.size() == 0 ) {
+    spec.extend
+      ( cool::RelationalDatabaseTable::columnNames::attributeName,
+        cool::RelationalDatabaseTable::columnTypeIds::attributeName );
+    spec.extend
+      ( cool::RelationalDatabaseTable::columnNames::attributeValue,
+        cool::RelationalDatabaseTable::columnTypeIds::attributeValue );
+  }
+  return spec;
+}
+
+//-----------------------------------------------------------------------------
diff --git a/RelationalCool/src/RelationalDatabaseTable.h b/RelationalCool/src/RelationalDatabaseTable.h
new file mode 100644
index 000000000..0738b088c
--- /dev/null
+++ b/RelationalCool/src/RelationalDatabaseTable.h
@@ -0,0 +1,110 @@
+// $Id: RelationalDatabaseTable.h,v 1.28 2007-02-16 16:53:29 avalassi Exp $
+#ifndef RELATIONALCOOL_RELATIONALDATABASETABLE_H 
+#define RELATIONALCOOL_RELATIONALDATABASETABLE_H 1
+
+// Include files
+#include "CoolKernel/StorageType.h"
+
+// Local include files
+#include "uppercaseString.h"
+
+namespace cool 
+{
+
+  // Forward declarations
+  class IRecordSpecification;
+
+  /** @namespace cool::RelationalDatabaseTable RelationalDatabaseTable.h
+   *  
+   *  Relational schema of the main table for a COOL conditions "database".
+   *
+   *  @author Andrea Valassi, Sven A. Schmidt and Marco Clemencic
+   *  @date   2004-12-16
+   */
+
+  namespace RelationalDatabaseTable 
+  {
+
+    /// The name of the main table for the given "conditions database name".
+    /// This is the only hardcoded mapping that cannot be changed by the user.
+    inline const std::string tableName( const std::string& dbName ) 
+    {
+      // TEMPORARY? AV 04.04.2005 
+      // The RelationalDatabaseId constructor throws an exception if dbname
+      // is not uppercase: this is meant to prevent users from believing that
+      // dbnames are case-sensitive (e.g., from believing that "myDb", "mydb" 
+      // and "MYDB" are three different databases). Eventually, case-sensitive 
+      // dbnames may be supported by mapping them to different case-sensitive 
+      // table names (such as "myDb_DB_ATTRIBUTES" or "MYDB_DB_ATTRIBUTES").
+      // Note that ALL tables are presently uppercase: if we decide to go for
+      // case-sensitive table names, all other Table classes must be changed!
+      // FIXME: presently the dbname is uppercase anyway...
+      return uppercaseString(dbName) + "_DB_ATTRIBUTES";
+    }
+
+    namespace columnNames 
+    {
+      static const std::string attributeName = "DB_ATTRIBUTE_NAME";
+      static const std::string attributeValue = "DB_ATTRIBUTE_VALUE";
+    }
+
+    namespace columnTypeIds 
+    {
+      static const StorageType::TypeId attributeName = StorageType::String255;
+      static const StorageType::TypeId attributeValue = StorageType::String4k;
+    }
+
+    namespace columnTypes 
+    {
+      typedef String255 attributeName;
+      typedef String4k  attributeValue;
+    }
+
+    namespace attributeNames 
+    {
+      static const 
+      std::string defaultTablePrefix = "DEFAULT_TABLE_PREFIX";
+      // *** START *** 3.0.0 schema extensions (task #4307)
+      static const 
+      std::string iovTablesTableName = "IOVTABLES_TABLE_NAME";
+      static const 
+      std::string channelTablesTableName = "CHANNELTABLES_TABLE_NAME";
+      // **** END **** 3.0.0 schema extensions (task #4307)
+      static const 
+      std::string nodeTableName = "NODE_TABLE_NAME";
+      static const 
+      std::string tagTableName = "TAG_TABLE_NAME";
+      // *** START *** 3.0.0 schema extensions (task #4396)
+      static const 
+      std::string headTagTableName = "HEADTAG_TABLE_NAME";
+      static const 
+      std::string userTagTableName = "USERTAG_TABLE_NAME";
+      // **** END **** 3.0.0 schema extensions (task #4396)
+      static const 
+      std::string tag2TagTableName = "TAG2TAG_TABLE_NAME";
+      static const 
+      std::string tagSharedSequenceName = "TAG_SHAREDSEQ_NAME";
+      static const 
+      std::string iovSharedSequenceName = "IOV_SHAREDSEQ_NAME";
+      static const 
+      std::string release = "RELEASE";
+      static const 
+      std::string cvsCheckout = "CVS_CHECKOUT";
+      static const 
+      std::string cvsCheckin = "CVS_CHECKIN";
+      static const 
+      std::string schemaVersion = "SCHEMA_VERSION";
+      static const 
+      std::string lastReplication = "LAST_REPLICATION";
+      static const 
+      std::string lastReplicationSource = "LAST_REPLICATION_SOURCE";
+    }
+    
+    /// Get the record specification of the main database table.
+    const cool::IRecordSpecification& tableSpecification();
+
+  }
+
+}
+
+#endif // RELATIONALCOOL_RELATIONALDATABASETABLE_H
diff --git a/RelationalCool/src/RelationalException.cpp b/RelationalCool/src/RelationalException.cpp
new file mode 100644
index 000000000..192ce66b5
--- /dev/null
+++ b/RelationalCool/src/RelationalException.cpp
@@ -0,0 +1,38 @@
+// $Id: RelationalException.cpp,v 1.8 2006-02-28 10:43:41 avalassi Exp $
+
+// Local include files
+#include "RelationalException.h"
+
+// Namespace
+using namespace cool;
+
+//-----------------------------------------------------------------------------
+
+RelationalException::RelationalException( const std::string& message,
+                                          const std::string& methodName )
+  : Exception( message, methodName )
+{
+  //std::cout << "Construct new RelationalException from: "
+  //          << "message='" << message << "', "
+  //          << "method='" << methodName << "'" << std::endl;
+}
+
+//-----------------------------------------------------------------------------
+
+RelationalException::RelationalException( const RelationalException& rhs )
+  : Exception( static_cast< const Exception& >( rhs ) )
+{
+  //std::cout << "Copy construct RelationalException from: '"
+  //          << rhs.what() << "'" << std::endl;
+}
+
+//-----------------------------------------------------------------------------
+
+RelationalException::~RelationalException() throw()
+{
+  //std::cout << "Destroy RelationalException: '"
+  //          << what() << "'" << std::endl;
+}
+
+//-----------------------------------------------------------------------------
+
diff --git a/RelationalCool/src/RelationalException.h b/RelationalCool/src/RelationalException.h
new file mode 100644
index 000000000..79e8b5b22
--- /dev/null
+++ b/RelationalCool/src/RelationalException.h
@@ -0,0 +1,446 @@
+// $Id: RelationalException.h,v 1.39 2008-11-04 11:52:11 avalassi Exp $
+#ifndef RELATIONALCOOL_RELATIONALEXCEPTION_H
+#define RELATIONALCOOL_RELATIONALEXCEPTION_H 1
+
+// Include files
+#include "CoolKernel/Exception.h"
+
+// Local include files
+#include "VersionInfo.h"
+
+namespace cool
+{
+
+  //--------------------------------------------------------------------------
+
+  /** @class RelationalException RelationalException.h
+   *
+   *  Base exception class for the relational implementations of COOL.
+   *  Derived from SEAL Exception just like the POOL RelationalException.
+   *
+   *  @author Andrea Valassi, Sven A. Schmidt and Marco Clemencic
+   *  @date   2004-11-10
+   */
+
+  class RelationalException : public Exception {
+
+  public:
+
+    /// Constructor
+    RelationalException( const std::string& message,
+                         const std::string& methodName = "" );
+
+    /// Copy constructor
+    RelationalException( const RelationalException& rhs );
+
+    /// Destructor
+    virtual ~RelationalException() throw();
+
+  };
+
+  //--------------------------------------------------------------------------
+
+  /** @class PanicException PanicException.h
+   *
+   *  Exception class for PANIC situations (asserts).
+   *  These are situations which should not normally happen in user code:
+   *  their meaning is that the code must be extended to cover new use cases.
+   *
+   *  @author Andrea Valassi
+   *  @date   2007-10-26
+   */
+
+  class PanicException : public RelationalException {
+
+  public:
+
+    /// Constructor
+    explicit PanicException( const std::string& message,
+                             const std::string& domain )
+      : RelationalException( message, domain ) 
+    {
+    }
+
+    /// Destructor
+    virtual ~PanicException() throw() {}
+
+  };
+
+  //--------------------------------------------------------------------------
+
+  /** @class NodeTableRowNotFound
+   *
+   *  Exception thrown when the row for a node with a given name
+   *  or nodeId cannot be found in the node table.
+   */
+
+  class NodeTableRowNotFound : public RelationalException {
+
+  public:
+
+    /// Constructor
+    explicit NodeTableRowNotFound( const std::string& methodName )
+      : RelationalException( "Table row for specified node not found",
+                             methodName ) {}
+
+    /// Constructor
+    explicit NodeTableRowNotFound( const std::string& fullPath,
+                                   const std::string& methodName )
+      : RelationalException( "Table row for node with name=" + fullPath
+                             + " not found", methodName ) {}
+
+    /// Constructor
+    explicit NodeTableRowNotFound( unsigned int nodeId,
+                                   const std::string& methodName )
+      : RelationalException( "", methodName )
+    {
+      std::stringstream msg;
+      msg << "Table row for node with nodeId=" << nodeId << " not found";
+      setMessage( msg.str() );
+    }
+
+    /// Destructor
+    virtual ~NodeTableRowNotFound() throw() {}
+
+  };
+
+  //--------------------------------------------------------------------------
+
+  /** @class FolderSpecificTableNotFound
+   *
+   *  Exception thrown when a folder-specific table (object table,
+   *  tag table, object2tag table) cannot be found, even if its name
+   *  was retrieved from the corresponding node table row: this may
+   *  indicate either data corruption or DDL changes by another process
+   *  during the job lifetime (folder has been dropped in the meantime).
+   *
+   */
+
+  class FolderSpecificTableNotFound : public RelationalException {
+
+  public:
+
+    /// Constructor
+    explicit FolderSpecificTableNotFound( const std::string& fullPath,
+                                          const std::string& methodName )
+      : RelationalException( "", methodName )
+    {
+      std::stringstream msg;
+      msg << "PANIC! Folder-specific table "
+          << "not found for folder " << fullPath << ": this indicates"
+          << " either data corruption (if node table row exists)"
+          << " or DDL changes by another process during your job lifetime";
+      setMessage( msg.str() );
+    }
+
+    /// Destructor
+    virtual ~FolderSpecificTableNotFound() throw() {}
+
+  };
+
+  //--------------------------------------------------------------------------
+
+  /** @class TableNotFound
+   *
+   *  Exception thrown when a table cannot be found.
+   *  This is generally a "PANIC" situation where the name of the table
+   *  was retrieved from the database and should exist: this may indicate
+   *  either data corruption or DDL changes by another process during the
+   *  job lifetime (e.g., one folder has been dropped in the meantime).
+   *
+   */
+
+  class TableNotFound : public RelationalException {
+
+  public:
+
+    /// Constructor
+    explicit TableNotFound( const std::string& tableName,
+                            const std::string& methodName )
+      : RelationalException( "", methodName )
+    {
+      std::stringstream msg;
+      msg << "Table " << tableName << " not found:"
+          << " this may indicate a PANIC situation with data corruption"
+          << " or DDL changes by another process during your job lifetime";
+      setMessage( msg.str() );
+    }
+
+    /// Destructor
+    virtual ~TableNotFound() throw() {}
+
+  };
+
+  //--------------------------------------------------------------------------
+
+  /** @class TableNotDropped
+   *
+   *  Exception thrown when a table cannot be dropped.
+   *
+   */
+
+  class TableNotDropped : public RelationalException {
+
+  public:
+
+    /// Constructor
+    explicit TableNotDropped( const std::string& table,
+                              const std::string& methodName )
+      : RelationalException( "Could not drop table/sequence '" + table + "'",
+                             methodName ) {}
+
+    /// Destructor
+    virtual ~TableNotDropped() throw() {}
+
+  };
+
+  //--------------------------------------------------------------------------
+
+  /** @class RowNotDeleted
+   *
+   *  Exception thrown when a table row cannot be deleted.
+   *
+   */
+
+  class RowNotDeleted : public RelationalException {
+
+  public:
+
+    /// Constructor
+    explicit RowNotDeleted( const std::string& message,
+                            const std::string& methodName )
+      : RelationalException( message, methodName ) {}
+
+    /// Destructor
+    virtual ~RowNotDeleted() throw() {}
+
+  };
+
+  //--------------------------------------------------------------------------
+
+  /** @class RowNotUpdated
+   *
+   *  Exception thrown when a table row cannot be updated.
+   *
+   */
+
+  class RowNotUpdated : public RelationalException {
+
+  public:
+
+    /// Constructor
+    explicit RowNotUpdated( const std::string& message,
+                            const std::string& methodName )
+      : RelationalException( message, methodName ) {}
+
+    /// Destructor
+    virtual ~RowNotUpdated() throw() {}
+
+  };
+
+  //--------------------------------------------------------------------------
+
+  /** @class RowNotInserted
+   *
+   *  Exception thrown when a table row cannot be inserted.
+   *
+   */
+
+  class RowNotInserted : public RelationalException {
+
+  public:
+
+    /// Constructor
+    explicit RowNotInserted( const std::string& message,
+                             const std::string& methodName )
+      : RelationalException( message, methodName ) {}
+
+    /// Destructor
+    virtual ~RowNotInserted() throw() {}
+
+  };
+
+  //--------------------------------------------------------------------------
+
+  /** @class NoRowsFound
+   *
+   *  Exception thrown when a query returns zero table rows
+   *  and at least one was expected.
+   *
+   */
+
+  class NoRowsFound : public RelationalException {
+
+  public:
+
+    /// Constructor
+    explicit NoRowsFound( const std::string& message,
+                          const std::string& methodName )
+      : RelationalException( message, methodName ) {}
+
+    /// Destructor
+    virtual ~NoRowsFound() throw() {}
+
+  };
+
+  //--------------------------------------------------------------------------
+
+  /** @class TooManyRowsFound
+   *
+   *  Exception thrown when a query returns more table rows than expected.
+   *
+   */
+
+  class TooManyRowsFound : public RelationalException {
+
+  public:
+
+    /// Constructor
+    explicit TooManyRowsFound( const std::string& message,
+                               const std::string& methodName )
+      : RelationalException( message, methodName ) {}
+
+    /// Destructor
+    virtual ~TooManyRowsFound() throw() {}
+
+  };
+
+  //--------------------------------------------------------------------------
+
+  /** @class IncompatibleReleaseNumber
+   *
+   *  Exception thrown when the software library release number is not
+   *  compatible with the database schema it is attempting to handle.
+   *
+   */
+  
+  class IncompatibleReleaseNumber : public RelationalException 
+  {
+    
+  public:
+    
+    /// Constructor
+    explicit IncompatibleReleaseNumber
+    ( const std::string& message,
+      const std::string& methodName ) 
+      : RelationalException
+    ( "IncompatibleReleaseNumber exception. " + message, methodName ) {}
+    
+    /// Destructor
+    virtual ~IncompatibleReleaseNumber() throw() {}
+    
+  };
+
+  //--------------------------------------------------------------------------
+
+  /** @class InvalidColumnName
+   *
+   *  Exception thrown when attempting to create or rename a column
+   *  of a relational table using an invalid name.
+   *
+   *  Names of column must have between 1 and 30 characters (including only
+   *  letters, digits or the '_' character ) and must start with a letter.
+   *
+   */
+  
+  class InvalidColumnName : public RelationalException 
+  {
+    
+  public:
+    
+    /// Constructor
+    explicit InvalidColumnName( const std::string& name,
+                                const std::string& methodName ) 
+      : RelationalException
+    ( "Invalid column name '" + name + "'", methodName ) {}
+    
+    /// Destructor
+    virtual ~InvalidColumnName() throw() {}
+    
+  };
+
+  //--------------------------------------------------------------------------
+
+  /** @class UnsupportedFolderSchema
+   *
+   *  Exception thrown when attempting to open a folder whose schema
+   *  version is newer than that supported by the present software 
+   *  release (or has been obsoleted and is no longer supported).
+   */
+  
+  class UnsupportedFolderSchema : public RelationalException 
+  {
+    
+  public:
+    
+    /// Constructor
+    explicit UnsupportedFolderSchema( const std::string& fullPath,
+                                      const VersionNumber& schemaVersion,
+                                      const std::string& domain ) 
+      : RelationalException( "", domain )
+    {
+      std::stringstream msg;
+      msg << "Schema version " << schemaVersion << " of folder '"
+          << fullPath << "' is not supported by this software release "
+          << VersionInfo::release << " (using default database schema version "
+          << VersionInfo::schemaVersion << ")";
+      setMessage( msg.str() );
+    }
+    
+    /// Constructor
+    explicit UnsupportedFolderSchema( const std::string& message,
+                                      const std::string& domain ) 
+      : RelationalException( message, domain ) 
+    {
+    }
+    
+    /// Destructor
+    virtual ~UnsupportedFolderSchema() throw() {}
+    
+  };
+
+  //--------------------------------------------------------------------------
+
+  /** @class UnsupportedFolderSetSchema
+   *
+   *  Exception thrown when attempting to open a folder set whose schema
+   *  version is newer than that supported by the present software 
+   *  release (or has been obsoleted and is no longer supported).
+   */
+  
+  class UnsupportedFolderSetSchema : public RelationalException 
+  {
+    
+  public:
+    
+    /// Constructor
+    explicit UnsupportedFolderSetSchema( const std::string& fullPath,
+                                         const VersionNumber& schemaVersion,
+                                         const std::string& domain ) 
+      : RelationalException( "", domain )
+    {
+      std::stringstream msg;
+      msg << "Schema version " << schemaVersion << " of folder set '"
+          << fullPath << "' is not supported by this software release "
+          << VersionInfo::release << " (using default database schema version "
+          << VersionInfo::schemaVersion << ")";
+      setMessage( msg.str() );
+    }
+    
+    /// Constructor
+    explicit UnsupportedFolderSetSchema( const std::string& message,
+                                         const std::string& domain ) 
+      : RelationalException( message, domain ) 
+    {
+    }
+    
+    /// Destructor
+    virtual ~UnsupportedFolderSetSchema() throw() {}
+    
+  };
+  
+  //--------------------------------------------------------------------------
+
+}
+
+#endif // RELATIONALCOOL_RELATIONALEXCEPTION_H
diff --git a/RelationalCool/src/RelationalFolder.cpp b/RelationalCool/src/RelationalFolder.cpp
new file mode 100644
index 000000000..b75abb227
--- /dev/null
+++ b/RelationalCool/src/RelationalFolder.cpp
@@ -0,0 +1,1731 @@
+// $Id: RelationalFolder.cpp,v 1.231 2009-01-13 19:13:09 avalassi Exp $
+
+// Include files
+#include <list>
+#include "CoralBase/MessageStream.h"
+#include "CoolKernel/ChannelSelection.h"
+#include "CoolKernel/ConstRecordAdapter.h"
+#include "CoolKernel/Record.h"
+#include "CoralBase/Attribute.h"
+//#include "CoralBase/AttributeList.h"
+#include "CoralBase/AttributeSpecification.h"
+
+// Local include files
+#include "HvsPathHandler.h"
+#include "HvsTagRecord.h"
+#include "IRelationalBulkOperation.h"
+#include "IRelationalTransactionMgr.h"
+#include "ObjectVectorIterator.h"
+#include "RelationalChannelTable.h"
+#include "RelationalDatabase.h"
+#include "RelationalException.h"
+#include "RelationalFolder.h"
+#include "RelationalGlobalTagTable.h"
+#include "RelationalNodeTable.h"
+#include "RelationalObject.h"
+#include "RelationalObjectMgr.h"
+#include "RelationalObjectTable.h"
+#include "RelationalObjectTableRow.h"
+#include "RelationalObject2TagTable.h"
+#include "RelationalPayloadQuery.h"
+#include "RelationalQueryMgr.h"
+#include "RelationalSequence.h"
+#include "RelationalSequenceMgr.h"
+#include "RelationalSchemaMgr.h"
+#include "RelationalTableRow.h"
+#include "RelationalTagMgr.h"
+#include "RelationalTagTable.h"
+#include "RelationalTag2TagTable.h"
+#include "RelationalTransaction.h"
+#include "TimingReportMgr.h"
+//#include "UrlParser.h"
+#include "timeToString.h"
+
+// Namespace
+using namespace cool;
+
+// Local type definitions
+typedef boost::shared_ptr<RelationalSequence> RelationalSequencePtr;
+
+//-----------------------------------------------------------------------------
+
+bool RelationalFolder::isSupportedSchemaVersion
+( const VersionNumber& rhs )    
+{
+  VersionNumber lhs = folderSchemaVersion();
+  // 1. Hardcoded requirement: folder schema must be >= 2.0.1 (bug #23755)
+  if ( rhs < VersionNumber( "2.0.1" ) ) return false;
+  // 2. In general: 2.0.x (x>=1) is supported if this software supports 2.0.y
+  return 
+    ( lhs.majorVersion() == rhs.majorVersion() ) 
+    && ( lhs.minorVersion() == rhs.minorVersion() );  
+  //&& ( lhs.patchVersion() <= rhs.patchVersion() );
+}
+
+//-----------------------------------------------------------------------------
+
+void RelationalFolder::initialize( const coral::AttributeList& row )
+{
+  m_prefetchAll = true; // Keep the API semantics of COOL_1_2_5
+  m_useBuffer = false;
+  m_userTagOnly = false;
+  m_objectTableName = RelationalFolder::objectTableName( row );    
+  //m_folderSpec = FolderSpecification( versioningMode( row ), payloadSpecification( row ) );
+  if ( m_folderSpec.versioningMode() == FolderVersioning::MULTI_VERSION ) 
+  {
+    m_tagTableName = RelationalFolder::tagTableName( row );
+    m_object2TagTableName = RelationalFolder::object2TagTableName( row );
+  } 
+  else 
+  {
+    m_tagTableName = "";
+    m_object2TagTableName = "";
+  }
+  m_channelTableName = RelationalFolder::channelTableName( row );
+  const IRecordSpecification& spec = 
+    folderAttributesSpecification( m_folderSpec.versioningMode() );
+  m_publicFolderAttributes = Record( spec, row );
+  log() << coral::Debug << "Instantiate a RelationalFolder for '" 
+        << fullPath() << "'" << coral::MessageStream::endmsg;
+}	
+
+//-----------------------------------------------------------------------------
+
+RelationalFolder::~RelationalFolder() 
+{
+  log() << coral::Debug << "Delete the RelationalFolder for '" 
+        << fullPath() << "'" << coral::MessageStream::endmsg;
+}
+
+//-----------------------------------------------------------------------------
+
+coral::MessageStream& RelationalFolder::log() const
+{
+  *m_log << coral::Verbose;
+  return *m_log;
+}
+
+//-----------------------------------------------------------------------------
+
+const IRecord& RelationalFolder::folderAttributes() const {
+  return m_publicFolderAttributes;
+}
+ 
+//-----------------------------------------------------------------------------
+
+const RecordSpecification& 
+RelationalFolder::folderAttributesSpecification
+( FolderVersioning::Mode versioningMode ) 
+{
+  if ( versioningMode == FolderVersioning::MULTI_VERSION ) {
+    
+    static RecordSpecification s_folderAttrSpec_MV;
+    if ( s_folderAttrSpec_MV.size() == 0 ) {
+      s_folderAttrSpec_MV.extend
+        ( RelationalNodeTable::columnNames::nodeSchemaVersion,
+          RelationalNodeTable::columnTypeIds::nodeSchemaVersion );
+      s_folderAttrSpec_MV.extend
+        ( RelationalNodeTable::columnNames::folderObjectTableName,
+          RelationalNodeTable::columnTypeIds::folderObjectTableName );
+      s_folderAttrSpec_MV.extend
+        ( RelationalNodeTable::columnNames::folderTagTableName,
+          RelationalNodeTable::columnTypeIds::folderTagTableName );
+      s_folderAttrSpec_MV.extend
+        ( RelationalNodeTable::columnNames::folderObject2TagTableName,
+          RelationalNodeTable::columnTypeIds::folderObject2TagTableName );
+      s_folderAttrSpec_MV.extend
+        ( RelationalNodeTable::columnNames::folderChannelTableName,
+          RelationalNodeTable::columnTypeIds::folderChannelTableName );
+    }
+    return s_folderAttrSpec_MV;
+
+  } else {
+
+    static RecordSpecification s_folderAttrSpec_SV;
+    if ( s_folderAttrSpec_SV.size() == 0 ) {
+      s_folderAttrSpec_SV.extend
+        ( RelationalNodeTable::columnNames::nodeSchemaVersion,
+          RelationalNodeTable::columnTypeIds::nodeSchemaVersion );
+      s_folderAttrSpec_SV.extend
+        ( RelationalNodeTable::columnNames::folderObjectTableName,
+          RelationalNodeTable::columnTypeIds::folderObjectTableName );
+      s_folderAttrSpec_SV.extend
+        ( RelationalNodeTable::columnNames::folderChannelTableName,
+          RelationalNodeTable::columnTypeIds::folderChannelTableName );
+    }  
+    return s_folderAttrSpec_SV;
+
+  }  
+}
+
+//-----------------------------------------------------------------------------
+
+/*
+bool RelationalFolder::declareExternalReference
+( const std::string& name,
+  const std::vector< std::string >& attributes,
+  const std::string& referencedEntity,
+  const std::vector< std::string >& referencedAttributes ) 
+{
+  // Check if the reference already exists
+  std::map< std::string, IFolder::ExternalReference >::const_iterator 
+    ref = m_externalReferences.find( name );
+  if ( ref != m_externalReferences.end() ) {
+    std::string errMsg =
+      "External reference constraint '" + name 
+      + "' already exists for folder '" + fullPath() + "'";
+    throw RelationalException( errMsg, "RelationalFolder" );
+  }  
+
+  // Check that the number of referenced and referencing attributes match
+  if ( attributes.size() != referencedAttributes.size() ) {
+    std::string errMsg =
+      "External reference constraint '" + name 
+      + "' could not be declared for folder '" + fullPath() 
+      + "': mismatch in the number of referenced and referencing attributes";
+    throw RelationalException( errMsg, "RelationalFolder" );
+  }
+
+  // Check that each referencing attribute is used only once
+  std::list<std::string> uniqueAttributes;
+  std::vector<std::string>::const_iterator attr;
+  for ( attr = attributes.begin(); attr != attributes.end(); attr++ ) {
+    uniqueAttributes.push_back( *attr );
+  }
+  uniqueAttributes.unique();  
+  if ( uniqueAttributes.size() != attributes.size() ) {
+    std::string errMsg =
+      "External reference constraint '" + name 
+      + "' could not be declared for folder '" + fullPath() 
+      + "': one or more referencing attributes appear more than once";
+    throw RelationalException( errMsg, "RelationalFolder" );
+  }
+
+  // Check that the referencing attributes are part of the user payload
+  for ( attr = attributes.begin(); attr != attributes.end(); attr++ ) {
+    try { 
+      extendedRecordSpecification()[ *attr ];  
+    } catch (...) {
+      std::string errMsg =
+        "External reference constraint '" + name 
+        + "' could not be declared for folder '" + fullPath() 
+        + "': attribute '" + *attr + "' not in folder payload specification";
+      throw RelationalException( errMsg, "RelationalFolder" );
+    }
+  }  
+
+  // Check that the syntax of the referenced entity URL is supported
+  // Example: "local://schema=USERNAME;table=TABLENAME".
+  std::string url = referencedEntity;
+  static const std::string s_localPrefix = "local://";
+  std::string foreignSchema = "";
+  std::string foreignTable = "";
+  bool supportedUrl = true;
+  if ( UrlParser::urlStartsWith( url, s_localPrefix ) ) {
+    //std::cout << "URL = '" << url << "'" << std::endl;
+    url = url.substr( s_localPrefix.size() ) + ";";
+    //std::cout << "URL = '" << url << "'" << std::endl;
+    unsigned int semicolonPos = url.find( ";" );
+    while ( semicolonPos != std::string::npos ) {
+      std::string optionString = url.substr( 0, semicolonPos );
+      //std::cout << "option = '" << optionString << "'" << std::endl;
+      url = url.substr( optionString.size()+1 );
+      //std::cout << "URL = '" << url << "'" << std::endl;
+      semicolonPos = url.find( ";" );
+      UrlParser::Option option = UrlParser::parseOptionString( optionString );
+      if ( option.first == "schema" ) {
+        if ( foreignSchema != "" ) supportedUrl = false; //duplicate key
+        foreignSchema = option.second;
+      } 
+      if ( option.first == "table" ) {
+        if ( foreignTable != "" ) supportedUrl = false; //duplicate key
+        foreignTable = option.second;
+      } 
+    }
+  }
+  if ( ! supportedUrl || foreignSchema == "" || foreignTable == "" ) {
+    std::string errMsg =
+      "External reference constraint '" + name 
+      + "' could not be declared for folder '" + fullPath() 
+      + "': unsupported referenced entity URL '" 
+      + referencedEntity + "'";
+    throw RelationalException( errMsg, "RelationalFolder" );
+  }
+  // DUMMY IMPLEMENTATION FOR THE MOMENT: DO NOTHING
+
+  // Add the external reference constraint to the list of constraints
+  IFolder::ExternalReference reference;
+  reference.name = name;
+  reference.attributes = attributes;
+  reference.referencedEntity = referencedEntity;
+  reference.referencedAttributes = referencedAttributes;
+  m_externalReferences[ name ] = reference;
+  return true;
+
+}
+
+//-----------------------------------------------------------------------------
+
+const std::vector< std::string > RelationalFolder::externalReferences() const 
+{
+  std::vector< std::string > references;  
+  std::map< std::string, IFolder::ExternalReference >::const_iterator ref;
+  for ( ref = m_externalReferences.begin();
+        ref != m_externalReferences.end();
+        ref++ ) {
+    references.push_back( ref->first );    
+  }
+  return references;
+}
+
+//-----------------------------------------------------------------------------
+
+const IFolder::ExternalReference&
+RelationalFolder::externalReference( const std::string& name ) const
+{
+  std::map< std::string, IFolder::ExternalReference >::const_iterator 
+    ref = m_externalReferences.find( name );
+  if ( ref != m_externalReferences.end() ) {
+    return ref->second;
+  } else {
+    std::string errMsg =
+      "External reference constraint '" + name 
+      + "' not found for folder '" + fullPath() + "'";
+    throw RelationalException( errMsg, "RelationalFolder" );
+  }  
+}
+*/
+
+//-----------------------------------------------------------------------------
+
+void RelationalFolder::setupStorageBuffer( bool useBuffer ) 
+{
+  if ( ( !useBuffer ) && m_useBuffer && ( !m_objectBuffer.empty() ) ) 
+    flushStorageBuffer();    
+  m_useBuffer = useBuffer;
+}
+
+//-----------------------------------------------------------------------------
+
+unsigned RelationalFolder::maxBufferSize() 
+{
+  // AV 18.01.2004 TEMPORARY?
+  // Oracle - use 50k: workaround for ORA-24381 error if buffer>65535
+  // MySQL -use 10k: this makes writing faster on MySQL
+  //unsigned s_maxBufferSize = 0;
+  unsigned s_maxBufferSize = 10000;
+  return s_maxBufferSize;
+}
+
+//-----------------------------------------------------------------------------
+
+void RelationalFolder::flushStorageBuffer() 
+{  
+  log() << "Flushing storage buffer for folder " << fullPath() << coral::MessageStream::endmsg;
+  if ( m_objectBuffer.empty() ) 
+  {
+    log() << coral::Warning << "Nothing to flush for folder "
+          << fullPath() << ": buffer is empty" << coral::MessageStream::endmsg;
+  } 
+  else 
+  {
+    // Cross-check that the database is open
+    if ( ! db().isOpen() ) throw DatabaseNotOpen( "RalDatabase" );
+    if ( db().transactionMgr()->isActive() ) 
+    {
+      if ( db().isReadOnly() ) {
+        throw DatabaseOpenInReadOnlyMode( "RalDatabase" );
+      } else {
+        if ( db().transactionMgr()->autoTransactions() ) {
+          throw RelationalException
+          ( "Cannot start a concurrent write transaction", "RalDatabase" );
+        }
+      }
+    }
+    RelationalTransaction transaction( db().transactionMgr() ); // r/w
+    //db().__storeObjects( this, m_objectBuffer, m_userTagOnly );
+    //m_objectBuffer.erase( m_objectBuffer.begin(), m_objectBuffer.end() );
+    // AV 18.01.2004 TEMPORARY?
+    unsigned theMaxBufferSize = maxBufferSize();
+    try 
+    {
+      if ( theMaxBufferSize == 0 ) 
+      {
+        log() << "Store all objects (max buffer size = 0)" 
+              << coral::MessageStream::endmsg;
+        db().objectMgr().__storeObjects( this, m_objectBuffer, m_userTagOnly );
+        m_objectBuffer.clear();
+      } 
+      // AV - here could also avoid copy if buffer size is already < MAX
+      else 
+      {
+        log() << "Store at most " << theMaxBufferSize << " objects at a time" 
+              << coral::MessageStream::endmsg;
+        /*
+        // AV Access violation on vc9 (bug #45839)
+        std::vector<RelationalObjectPtr>::iterator begin = 
+          m_objectBuffer.begin();
+        std::vector<RelationalObjectPtr>::iterator end =
+          begin + theMaxBufferSize < m_objectBuffer.end() ? 
+          begin + theMaxBufferSize : 
+          m_objectBuffer.end();        
+        while( begin < m_objectBuffer.end() ) 
+        {
+          // we should avoid this copy by adding an overloaded "storeObjects":
+          // db().__storeObjects( m_objectBuffer, begin, end, m_userTagOnly )
+          std::vector<RelationalObjectPtr> buffer;
+          copy( begin, end, std::back_inserter( buffer ) );
+          db().objectMgr().__storeObjects( this, buffer, m_userTagOnly );
+          begin = end;
+          end = ( end + theMaxBufferSize ) < m_objectBuffer.end() ?
+            end + theMaxBufferSize : 
+            m_objectBuffer.end();
+        }
+        */
+        // AV Fix access violation on vc9 (bug #45839)
+        unsigned int size = m_objectBuffer.size();
+        unsigned int begin = 0;
+        unsigned int end = ( theMaxBufferSize<size ? 
+                             theMaxBufferSize-1 :
+                             size-1 );
+        while( begin < size ) 
+        {
+          // we should avoid this copy by adding an overloaded "storeObjects":
+          // db().__storeObjects( m_objectBuffer, begin, end, m_userTagOnly )
+          std::vector<RelationalObjectPtr> buffer;
+          for ( unsigned int index = begin; index <= end; index++ )
+            buffer.push_back( m_objectBuffer[index] );
+          db().objectMgr().__storeObjects( this, buffer, m_userTagOnly );
+          begin = end+1;
+          end = ( end+theMaxBufferSize < size-1 ? 
+                  end+theMaxBufferSize : 
+                  size-1 );
+        }
+        m_objectBuffer.clear();
+      }    
+    } 
+    catch (...) 
+    {
+      // No need to print a warning if only the invalid IOV is discarded 
+      if ( m_objectBuffer.size() > 1 ) 
+        log() << coral::Warning 
+              << "Exception caught while bulk-inserting IOVs"
+              << ": NONE of the IOVs in the bulk insertion will be stored"
+              << coral::MessageStream::endmsg;
+      m_objectBuffer.clear();
+      throw;
+    }    
+    transaction.commit();
+  }
+
+}
+
+//-----------------------------------------------------------------------------
+
+void RelationalFolder::storeObject( const ValidityKey& since,
+                                    const ValidityKey& until,
+                                    const IRecord& payload,
+                                    const ChannelId& channelId,
+                                    const std::string& userTagName,
+                                    bool userTagOnly ) 
+{
+  log() << "Store into folder " << fullPath()
+        << " the following IOV: since=" << since << " until=" << until
+        << coral::MessageStream::endmsg;
+
+  // Check that userTagOnly is the same for all objects in a bulk insertion
+  if ( m_objectBuffer.size() > 0 )
+  {
+    if ( userTagOnly != m_userTagOnly )
+    {
+      std::stringstream msg;
+      msg << "Conflicting values of userTagOnly in the same bulk insertion";
+      throw RelationalException( msg.str(), "RelationalFolder::storeObject" );
+    }
+  }
+  else
+  {
+    m_userTagOnly = userTagOnly;
+  }
+
+  // Check that userTagName != "" if userTagOnly is true
+  if ( userTagOnly && userTagName == "" )
+  {
+    std::stringstream msg;
+    msg << "A user tag must be specified if userTagOnly is true";
+    throw RelationalException( msg.str(), "RelationalFolder::storeObject" );
+  }
+    
+  // TODO - cross check payload against folder payload spec (bug #24464)?
+
+  // Instantiate a RelationalObject corresponding to the input arguments
+  // Add it to the storage buffer
+  RelationalObjectPtr object
+    ( new RelationalObject( since, until, payload, channelId, userTagName ) );
+  m_objectBuffer.push_back( object );
+  
+  // Store the object immediately if bulk insertion is not active
+  if ( ! m_useBuffer ) flushStorageBuffer();    
+
+}
+
+//-----------------------------------------------------------------------------
+
+void RelationalFolder::storeObject( const ValidityKey& since,
+                                    const ValidityKey& until,
+                                    const coral::AttributeList& payload,
+                                    const ChannelId& channelId,
+                                    const std::string& userTagName,
+                                    bool userTagOnly ) 
+{
+  //log() << "Store object using the AttributeList API" 
+  //      << coral::MessageStream::endmsg;
+  ConstRecordAdapter record( payloadSpecification(), payload );
+  //log() << "Store ConstRecordAdapter using the new API " 
+  //      << coral::MessageStream::endmsg;
+  storeObject( since, until, record, channelId, userTagName, userTagOnly );
+}
+
+//-----------------------------------------------------------------------------
+
+int
+RelationalFolder::truncateObjectValidity( const ValidityKey& until,
+                                          const ChannelSelection& channels )
+{
+  return db().objectMgr().truncateObjectValidity( this, until, channels );
+}
+
+//-----------------------------------------------------------------------------
+
+IObjectPtr RelationalFolder::findObject( const ValidityKey& pointInTime,
+                                         const ChannelId& channelId,
+                                         const std::string& tagName ) const
+{
+  IObjectPtr obj
+    ( db().objectMgr().findObject( this, pointInTime, channelId, tagName ) );
+  return obj;
+}
+
+//-----------------------------------------------------------------------------
+
+IObjectIteratorPtr 
+RelationalFolder::browseObjects( const ValidityKey& since,
+                                 const ValidityKey& until,
+                                 const ChannelSelection& channels,
+                                 const std::string& tagName,
+                                 bool prefetchAll, 
+                                 const IRecordSelection* payloadQuery ) const
+{
+  log() << "Browse objects in folder " << fullPath()
+        << " between since=" << since << " and until=" << until 
+        << coral::MessageStream::endmsg;
+
+  if ( TimingReportMgr::isActive() )
+    TimingReportMgr::startTimer( "cool::RelationalFolder::browseObjects()" );
+  IObjectIteratorPtr browserIt;
+
+  if ( payloadQuery != 0 && !payloadQuery->canSelect(payloadSpecification()) )
+    throw RelationalException
+      ( "Invalid payload query for this folder (wrong payload specification)",
+        "RelationalFolder::browseObject" );  
+  browserIt = db().objectMgr().browseObjects
+    ( this, since, until, channels, tagName, payloadQuery );
+
+  if ( prefetchAll )
+  {
+    if ( TimingReportMgr::isActive() )
+      TimingReportMgr::startTimer
+        ( "cool::RelationalFolder::browseObjects(V)" );
+    IObjectIteratorPtr vectorIt
+      ( new ObjectVectorIterator( browserIt->fetchAllAsVector() ) );
+    browserIt = vectorIt;
+    if ( TimingReportMgr::isActive() )
+      TimingReportMgr::stopTimer
+        ( "cool::RelationalFolder::browseObjects(V)" );
+  }
+
+  if ( TimingReportMgr::isActive() )
+    TimingReportMgr::stopTimer( "cool::RelationalFolder::browseObjects()" );
+  if (payloadQuery !=0 )  
+    log() << "Browse objects will return an iterator with a payloadQuery"
+          << coral::MessageStream::endmsg;
+  else
+  if ( prefetchAll)
+    log() << "Browse objects will return a vector iterator with " 
+          << browserIt->size() << " objects" << coral::MessageStream::endmsg;
+  else 
+    log() << "Browse objects will return a vector iterator of unknown size"
+          << coral::MessageStream::endmsg;
+ 
+  return browserIt;
+}
+
+//-----------------------------------------------------------------------------
+
+IObjectIteratorPtr 
+RelationalFolder::browseObjects( const ValidityKey& since,
+                                 const ValidityKey& until,
+                                 const ChannelSelection& channels,
+                                 const std::string& tagName, 
+                                 const IRecordSelection* payloadQuery ) const
+{
+  /*
+  // AV Move this code fragment where it belongs (RalObjectMgr?...)
+  if ( payloadQuery != 0 ) 
+  {
+    bool trusted = false;
+    if ( typeid( *payloadQuery ) == typeid ( FieldRangeSelection ) )
+      trusted = true;
+    // If trusted -> append describe() to the SQL WHERE clause
+    // If not trusted -> scan locally using the select() method
+  }
+  */
+  return browseObjects
+    ( since, until, channels, tagName, m_prefetchAll, payloadQuery );
+}
+
+//-----------------------------------------------------------------------------
+
+IObjectIteratorPtr 
+RelationalFolder::findObjects( const ValidityKey& pointInTime,
+                               const ChannelSelection& channels,
+                               const std::string& tagName ) const
+{
+  ValidityKey since = pointInTime;
+  ValidityKey until = pointInTime;
+  return browseObjects( since, until, channels, tagName, m_prefetchAll, 0 );
+}
+
+//-----------------------------------------------------------------------------
+
+IObjectVectorPtr
+RelationalFolder::fetchObjectsInRange( const ValidityKey& since,
+                                       const ValidityKey& until,
+                                       const ChannelSelection& channels,
+                                       const std::string& tagName ) const
+{
+  //return db().fetchObjects( this, since, until, channels, tagName );
+  return browseObjects
+    ( since, until, channels, tagName, m_prefetchAll, 0 )->fetchAllAsVector();
+}
+
+//-----------------------------------------------------------------------------
+
+IObjectVectorPtr
+RelationalFolder::fetchObjectsAtTime( const ValidityKey& pointInTime,
+                                      const ChannelSelection& channels,
+                                      const std::string& tagName ) const
+{
+  ValidityKey since = pointInTime;
+  ValidityKey until = pointInTime;
+  return fetchObjectsInRange( since, until, channels, tagName );
+}
+
+//-----------------------------------------------------------------------------
+
+unsigned int 
+RelationalFolder::countObjects( const ValidityKey& since,
+                                const ValidityKey& until,
+                                const ChannelSelection& channels,
+                                const std::string& tagName, 
+                                const IRecordSelection* payloadQuery ) const
+{
+  if ( payloadQuery != 0 && !payloadQuery->canSelect(payloadSpecification()) )
+    throw RelationalException
+      ( "Invalid payload query for this folder (wrong payload specification)",
+        "RelationalFolder::browseObject" );  
+  bool countOnly = true;
+  unsigned int count = db().objectMgr().browseObjects
+    ( this, since, until, channels, tagName, payloadQuery, countOnly )->size();
+  return count;
+}
+
+//-----------------------------------------------------------------------------
+
+const std::vector<ChannelId> 
+RelationalFolder::listChannels() const
+{
+  if ( ! db().isOpen() ) throw DatabaseNotOpen( "RalDatabase" );
+  RelationalTransaction transaction( db().transactionMgr(), true ); // r/o
+  // Use the channels table for both SV and MV folders.
+  // Fix performance bug #24448 for SV folders in COOL_2_2_0.
+  // Fix functional and performance bug #30443 for MV folders in COOL_2_2_2
+  // (remove workaround for bug #23755 - MV channels table not filled).
+  RelationalChannelTable channelTable( db(), *this );
+  std::vector<ChannelId> channels = channelTable.listChannels();
+  transaction.commit();
+  return channels;
+}
+
+//-----------------------------------------------------------------------------
+
+const std::map<ChannelId,std::string>
+RelationalFolder::listChannelsWithNames() const
+{
+  if ( ! db().isOpen() ) throw DatabaseNotOpen( "RalDatabase" );
+  RelationalTransaction transaction( db().transactionMgr(), true ); // r/o
+  // Use the channels table for both SV and MV folders.
+  RelationalChannelTable channelTable( db(), *this );
+  const std::map<ChannelId,std::string> channelsWithNames = 
+    channelTable.listChannelsWithNames();
+  transaction.commit();
+  return channelsWithNames;
+}
+
+//-----------------------------------------------------------------------------
+
+void RelationalFolder::createChannel( const ChannelId& channelId,
+                                      const std::string& channelName,
+                                      const std::string& description )
+{
+  db().objectMgr().createChannel( this, channelId, channelName, description );
+}
+
+//-----------------------------------------------------------------------------
+
+bool RelationalFolder::dropChannel( const ChannelId& channelId )
+{
+  return db().objectMgr().dropChannel( this, channelId );
+}
+
+//-----------------------------------------------------------------------------
+
+void RelationalFolder::setChannelName( const ChannelId& channelId,
+                                       const std::string& channelName )
+{
+  log() << "Modify channel #" << channelId
+        << " in folder '" << fullPath() 
+        << "': set name equal to '" << channelName << "'" 
+        << coral::MessageStream::endmsg;
+  
+  // Start a read-write transaction
+  bool readOnly = false;
+  RelationalTransaction transaction( db().transactionMgr(), readOnly );
+
+  // Throw if a channel with the given name already exists
+  // (unless it is the name of this channel - fix for bug #23754)
+  try {
+    RelationalChannelTable table( db(), *this );
+    RelationalTableRow row = table.fetchRowForChannelName( channelName );
+    if ( channelId !=
+         row[RelationalChannelTable::columnNames::channelId()]
+         .data<ChannelId>() )
+      throw ChannelExists( fullPath(), channelName, "RelationalFolder" );
+  } catch ( NoRowsFound& ) {}
+
+  // Define the SET and WHERE clauses for the update using bind variables
+  coral::AttributeList updateData;
+  updateData.extend( "channelName",
+                     typeIdToCoralType
+                     (RelationalChannelTable::columnTypeIds::channelName) );
+  updateData.extend( "channel",
+                     typeIdToCoralType
+                     (RelationalChannelTable::columnTypeIds::channelId) );
+  updateData["channelName"].setValue( channelName );
+  if ( channelName != "" )
+    updateData["channelName"].setValue( channelName );
+  else
+    updateData["channelName"].setNull();
+  updateData["channel"].setValue( channelId );
+  std::string setClause = RelationalChannelTable::columnNames::channelName();
+  setClause += "= :channelName";
+  std::string whereClause = RelationalChannelTable::columnNames::channelId();
+  whereClause += "= :channel";
+  
+  // Execute the update
+  UInt32 updatedRows = db().queryMgr().updateTableRows
+    ( channelTableName(), setClause, whereClause, updateData );
+
+  // Remove workaround for bug #23755 (MV channels table not filled) and 
+  // old fix for bug #24445 (MV setChannelName fails without createChannel):
+  // 'create' the channel row in the channel table if the channel exists 
+  // (i.e. contains some IOVs) but it has no associated channel table row
+  /*
+  // Was the channel name updated?
+  if ( updatedRows != 1 ) {
+    if ( m_folderSpec.versioningMode() == FolderVersioning::MULTI_VERSION ) {
+      if ( db().relationalObjectTable( *this )->existsChannel( channelId ) ) {
+        unsigned int lastObjectId = 0; // this is not maintained for MV folders
+        bool hasNewData = false;
+        std::string description = "";
+        db().objectMgr().insertChannelTableRow( this->channelTableName(),
+                                                channelId,
+                                                lastObjectId,
+                                                hasNewData,
+                                                channelName,
+                                                description );
+        updatedRows = 1; // hack - workaround for bug #23755
+      }
+    }    
+  }
+  */
+
+  // Commit the transaction
+  transaction.commit();
+
+  // Was the channel name updated?
+  if ( updatedRows != 1 ) {
+    throw ChannelNotFound( channelId, "RalDatabase" );
+  }
+  
+}
+
+//-----------------------------------------------------------------------------
+
+void RelationalFolder::setChannelDescription
+( const ChannelId& channelId,
+  const std::string& description )
+{
+  log() << "Update in table " << channelTableName()
+        << " for channel " << channelId << coral::MessageStream::endmsg;
+  
+  // Define the SET and WHERE clauses for the update using bind variables
+  coral::AttributeList updateData;
+  updateData.extend( "description",
+                     typeIdToCoralType
+                     (RelationalChannelTable::columnTypeIds::description) );
+  updateData.extend( "channel",
+                     typeIdToCoralType
+                     (RelationalChannelTable::columnTypeIds::channelId) );
+  updateData["description"].setValue( description );
+  updateData["channel"].setValue( channelId );
+  std::string setClause = RelationalChannelTable::columnNames::description();
+  setClause += "= :description";
+  std::string whereClause = RelationalChannelTable::columnNames::channelId();
+  whereClause += "= :channel";
+  
+  bool readOnly = false;
+  RelationalTransaction transaction( db().transactionMgr(), readOnly );
+
+  // Execute the update
+  UInt32 updatedRows = db().queryMgr().updateTableRows
+    ( channelTableName(), setClause, whereClause, updateData );
+  
+  // Remove workaround for bug #23755 (MV channels table not filled) and 
+  // old fix for bug #24461 (MV setChannelDesc fails without createChannel):
+  // 'create' the channel row in the channel table if the channel exists 
+  // (i.e. contains some IOVs) but it has no associated channel table row
+  /*
+  // Was the channel name updated?
+  if ( updatedRows != 1 ) {
+    if ( m_folderSpec.versioningMode() == FolderVersioning::MULTI_VERSION ) {
+      if ( db().relationalObjectTable( *this )->existsChannel( channelId ) ) {
+        unsigned int lastObjectId = 0; // this is not maintained for MV folders
+        bool hasNewData = false;
+        std::string channelName = "";
+        db().objectMgr().insertChannelTableRow( this->channelTableName(),
+                                                channelId,
+                                                lastObjectId,
+                                                hasNewData,
+                                                channelName,
+                                                description );
+        updatedRows = 1; // hack - workaround for bug #23755
+      }
+    }    
+  }
+  */
+
+  // Commit the transaction
+  transaction.commit();
+
+  // Was the channel name updated?
+  if ( updatedRows != 1 ) {
+    throw ChannelNotFound( channelId, "RalDatabase" );
+  }
+
+}
+
+//-----------------------------------------------------------------------------
+
+const std::string 
+RelationalFolder::channelName( const ChannelId& channelId ) const 
+{
+  RelationalTransaction transaction( db().transactionMgr(), true ); // r/o
+  bool exists = false;
+  std::string channelName = "";
+  try {
+    RelationalChannelTable table( db(), *this );
+    RelationalTableRow row = table.fetchRowForId( channelId );
+    channelName = row[RelationalChannelTable::columnNames::channelName()].
+      data<std::string>();
+    exists = true;
+  } catch ( NoRowsFound& ) {
+    // Remove workaround for bug #23755 (MV channels table not filled) and
+    // old fix for bug #24463 (MV channelName fails without createChannel)
+    //exists = db().relationalObjectTable( *this )->existsChannel( channelId );
+    exists = false;
+  }
+  transaction.commit();
+  if ( exists ) return channelName;
+  else throw ChannelNotFound( channelId, "RelationalFolder" );
+}
+
+//-----------------------------------------------------------------------------
+
+const std::string 
+RelationalFolder::channelDescription( const ChannelId& channelId ) const 
+{
+  RelationalTransaction transaction( db().transactionMgr(), true ); // r/o
+  bool exists = false;
+  std::string description = "";
+  try {
+    RelationalChannelTable table( db(), *this );
+    RelationalTableRow row = table.fetchRowForId( channelId );
+    description = row[RelationalChannelTable::columnNames::description()].
+      data<std::string>();
+    exists = true;
+  } catch ( NoRowsFound& ) {
+    // Remove workaround for bug #23755 (MV channels table not filled) and old
+    // fix for bug #24463 (MV channelDescription fails without createChannel)
+    //exists = db().relationalObjectTable( *this )->existsChannel( channelId );
+    exists = false;
+  }
+  transaction.commit();
+  if ( exists ) return description;
+  else throw ChannelNotFound( channelId, "RelationalFolder" );
+}
+
+//-----------------------------------------------------------------------------
+
+ChannelId 
+RelationalFolder::channelId( const std::string& channelName ) const 
+{
+  try {
+    bool readOnly = true;
+    RelationalTransaction transaction( db().transactionMgr(), readOnly );
+    RelationalChannelTable table( db(), *this );
+    RelationalTableRow row = table.fetchRowForChannelName( channelName );
+    transaction.commit();
+    return row[RelationalChannelTable::columnNames::channelId()].
+      data<ChannelId>();
+  } catch ( NoRowsFound& ) {
+    throw ChannelNotFound( channelName, "RelationalFolder" );
+  }
+}
+
+//-----------------------------------------------------------------------------
+
+bool 
+RelationalFolder::existsChannel( const std::string& channelName ) const 
+{
+  try {
+    bool readOnly = true;
+    RelationalTransaction transaction( db().transactionMgr(), readOnly );
+    RelationalChannelTable table( db(), *this );
+    table.fetchRowForChannelName( channelName );
+    transaction.commit();
+    return true;
+  } catch ( NoRowsFound& ) {
+    return false;
+  }
+}
+
+//-----------------------------------------------------------------------------
+
+bool 
+RelationalFolder::existsChannel( const ChannelId& channelId ) const 
+{
+  RelationalTransaction transaction( db().transactionMgr(), true ); // r/o
+  bool exists;
+  // Use the channels table for both SV and MV folders.
+  // Fix functional and performance bug #30431 for MV folders in COOL_2_2_2
+  // (remove workaround for bug #23755 - MV channels table not filled - and
+  // old fix for bug #24449 - MV existsChannel fails without createChannel).
+  try {
+    RelationalChannelTable table( db(), *this );
+    table.fetchRowForId( channelId );
+    exists = true;
+  } catch ( NoRowsFound& ) {
+    exists= false;
+  }
+  transaction.commit();
+  return exists;
+}
+
+//-----------------------------------------------------------------------------
+
+const std::string& RelationalFolder::objectTableName() const 
+{
+  return m_objectTableName;
+}
+
+//-----------------------------------------------------------------------------
+
+const std::string& RelationalFolder::tagTableName() const 
+{
+  if ( m_folderSpec.versioningMode() == FolderVersioning::MULTI_VERSION )
+    return m_tagTableName;
+  else 
+    throw FolderIsSingleVersion
+      ( fullPath(), " Tag table does not exist", "RalDatabase" );
+}
+
+//-----------------------------------------------------------------------------
+
+const std::string& RelationalFolder::object2TagTableName() const 
+{
+  if ( m_folderSpec.versioningMode() == FolderVersioning::MULTI_VERSION )
+    return m_object2TagTableName;
+  else 
+    throw FolderIsSingleVersion
+      ( fullPath(), " Object2Tag table does not exist", "RalDatabase" );
+}
+
+//-----------------------------------------------------------------------------
+
+const RecordSpecification
+RelationalFolder::payloadSpecification
+( const coral::AttributeList& folderRow ) 
+{
+  std::string value =
+  folderRow[RelationalNodeTable::columnNames::folderPayloadSpecDesc]
+    .data<std::string>();
+  return RelationalDatabase::decodeRecordSpecification( value );
+}
+
+//-----------------------------------------------------------------------------
+
+FolderVersioning::Mode
+RelationalFolder::versioningMode( const coral::AttributeList& folderRow ) 
+{
+  int value =
+  folderRow[RelationalNodeTable::columnNames::folderVersioningMode]
+    .data<int>();
+  return FolderVersioning::Mode( value );
+}
+
+//-----------------------------------------------------------------------------
+
+const std::string 
+RelationalFolder::objectTableName( const coral::AttributeList& folderRow ) 
+{
+  std::string value =
+  folderRow[RelationalNodeTable::columnNames::folderObjectTableName]
+    .data<std::string>();
+  return value;
+}
+
+//-----------------------------------------------------------------------------
+
+const std::string 
+RelationalFolder::tagTableName( const coral::AttributeList& folderRow ) 
+{
+  std::string value =
+  folderRow[RelationalNodeTable::columnNames::folderTagTableName]
+    .data<std::string>();
+  return value;
+}
+
+//-----------------------------------------------------------------------------
+
+const std::string 
+RelationalFolder::object2TagTableName( const coral::AttributeList& folderRow ) 
+{
+  std::string value =
+  folderRow[RelationalNodeTable::columnNames::folderObject2TagTableName]
+    .data<std::string>();
+  return value;
+}
+
+//-----------------------------------------------------------------------------
+
+const std::string 
+RelationalFolder::channelTableName( const coral::AttributeList& folderRow ) 
+{
+  std::string value =
+  folderRow[RelationalNodeTable::columnNames::folderChannelTableName]
+  .data<std::string>();
+  return value;
+}
+
+//-----------------------------------------------------------------------------
+
+const std::string& RelationalFolder::channelTableName() const {
+  return m_channelTableName;
+}
+
+//-----------------------------------------------------------------------------
+
+void RelationalFolder::tagCurrentHead( const std::string& tagName,
+                                       const std::string& description ) const
+{
+  log() << "Tag current HEAD of folder '" << this->fullPath()
+        << "' with tag '" << tagName << "'" << coral::MessageStream::endmsg;
+
+  if ( m_folderSpec.versioningMode() != FolderVersioning::MULTI_VERSION )
+    throw FolderIsSingleVersion( fullPath(), "RelationalFolder" );
+
+  // Cross-check that the database is open
+  if ( ! db().isOpen() ) throw DatabaseNotOpen( "RelationalFolder" );
+
+  // HEAD tag for SV folders and MV folders
+  if ( IHvsNode::isHeadTag( tagName ) )
+    throw ReservedHeadTag( tagName, "RelationalFolder" );
+
+  // MV folder - identify which objects are to be tagged and tag them
+  else {
+    RelationalTransaction transaction( db().transactionMgr() ); // r/w
+    std::vector<RelationalObjectTableRow> objs =
+      db().relationalObjectTable( *this )->fetchRowsForTaggingCurrentHead();
+    tagObjectList( tagName, description, objs );
+    transaction.commit();
+    log() << "Tagged " << objs.size() << " objects with tag '" << tagName
+          << "'" << coral::MessageStream::endmsg;
+  }
+
+}
+
+//-----------------------------------------------------------------------------
+
+void 
+RelationalFolder::cloneTagAsUserTag( const std::string& tagName, 
+                                     const std::string& tagClone,
+                                     const std::string& description,
+                                     bool forceOverwriteTag )
+{
+  log() << "Clone current HEAD of folder '" << this->fullPath()
+        << "' with tag '" << tagName << "'" << coral::MessageStream::endmsg;
+
+  if ( m_folderSpec.versioningMode() != FolderVersioning::MULTI_VERSION )
+    throw FolderIsSingleVersion( fullPath(), "RelationalFolder" );
+
+  // Cross-check that the database is open
+  if ( ! db().isOpen() ) throw DatabaseNotOpen( "RelationalFolder" );
+
+  // HEAD tag for SV folders and MV folders
+  if ( IHvsNode::isHeadTag( tagClone ) )
+    throw ReservedHeadTag( tagClone, "RelationalFolder" );
+
+  // tagClone should not exist as a tag unless forceOverwriteTag is true
+  if ( !forceOverwriteTag && db().existsTag(tagClone) )
+      throw TagExists( tagName, "RelationalFolder" );
+  
+  // MV folder - identify which objects are to be cloned and clone them
+  IObjectIteratorPtr objIter = browseObjects( ValidityKeyMin, 
+                                              ValidityKeyMax,
+                                              ChannelSelection::all(),
+                                              tagName,
+                                              true, 
+                                              0 );
+  bool m_useBuffer_sav = m_useBuffer;
+  setupStorageBuffer( true );
+  while ( objIter->goToNext() ) 
+  {
+    const IObject& object = objIter->currentRef();
+    storeObject( object.since(),
+                 object.until(),
+                 object.payload(),
+                 object.channelId(),
+                 tagClone,
+                 true );
+  }
+  flushStorageBuffer();
+  // restore original m_useBuffer setting
+  setupStorageBuffer( m_useBuffer_sav );
+
+  if ( description != "" ) setTagDescription( tagClone, description );
+  
+  log() << "Reinserted " << objIter->size() << " objects with tag '" << tagName
+        << "'" << coral::MessageStream::endmsg;
+}
+
+//-----------------------------------------------------------------------------
+
+void RelationalFolder::tagHeadAsOfDate( const ITime& asOfDate,
+                                        const std::string& tagName,
+                                        const std::string& description ) const
+{
+  log() << "Tag HEAD as of date '" << timeToString(asOfDate)
+        << "' of folder '" << this->fullPath()
+        << "' with tag '" << tagName << "'" << coral::MessageStream::endmsg;
+
+  if ( m_folderSpec.versioningMode() != FolderVersioning::MULTI_VERSION )
+    throw FolderIsSingleVersion( fullPath(), "RelationalFolder" );
+
+  // Cross-check that the database is open
+  if ( ! db().isOpen() ) throw DatabaseNotOpen( "RelationalFolder" );
+
+  // HEAD tag for SV folders and MV folders
+  if ( IHvsNode::isHeadTag( tagName ) )
+    throw ReservedHeadTag( tagName, "RelationalFolder" );
+
+  // MV folder - identify which objects are to be tagged and tag them
+  else {
+    RelationalTransaction transaction( db().transactionMgr() ); // r/w
+    std::vector<RelationalObjectTableRow> objs =
+      db().relationalObjectTable( *this )
+      ->fetchRowsForTaggingHeadAsOfDate( asOfDate );
+    tagObjectList( tagName, description, objs );
+    log() << "Tagged " << objs.size() << " objects with tag '" << tagName
+          << "'" << coral::MessageStream::endmsg;
+    transaction.commit();
+  }
+
+}
+
+//-----------------------------------------------------------------------------
+
+void RelationalFolder::tagHeadAsOfObjectId( unsigned int asOfObjectId,
+                                            const std::string& tagName,
+                                            const std::string& description )
+{
+  RelationalTransaction transaction( db().transactionMgr() ); // r/w
+
+  // Identify which objects are to be tagged
+  std::vector<RelationalObjectTableRow> objs =
+    db().relationalObjectTable( *this )
+    ->fetchRowsForTaggingHeadAsOfObjectId( asOfObjectId );
+
+  // Tag the objecs
+  tagObjectList( tagName, description, objs );
+
+  transaction.commit();
+}
+
+//-----------------------------------------------------------------------------
+
+const Time 
+RelationalFolder::insertionTimeOfLastObjectInTag
+( const std::string& tagName ) const
+{
+  // Cross-check that the database is open
+  if ( ! db().isOpen() ) throw DatabaseNotOpen( "RelationalDatabase" );
+
+  // SV folders don't have tags, can't determine a tagTime
+  if ( this->versioningMode() == FolderVersioning::SINGLE_VERSION )
+    throw RelationalException( "tagTime not applicable in "
+                               "SingleVersion mode", "RelationalFolder" );
+
+  // Retrieve the tag insertion time from the folder's tag table
+  RelationalTransaction transaction( db().transactionMgr(), true ); // r/o
+
+  RelationalTableRow
+    row( db().tagMgr().fetchGlobalTagTableRow( this->id(), tagName ) );
+
+  unsigned int tagId =
+    row[RelationalTagTable::columnNames::tagId].data<unsigned int>();
+
+  RelationalObjectTableRow objRow
+    ( db().relationalObjectTable( *this )->fetchLastRowForTagId( tagId ) );
+  
+  transaction.commit();
+
+  return objRow.insertionTime();
+}
+
+//-----------------------------------------------------------------------------
+
+void RelationalFolder::tagObjectList
+( const std::string& tagName,
+  const std::string& description,
+  const std::vector<RelationalObjectTableRow>& objects ) const
+{
+  // Throw TagNotCreated if object list is empty
+  if ( objects.size() == 0 )
+    throw RelationalException
+      ( "Tag '" + tagName + "' not created: no IOVs in the tag",
+        "RelationalFolder" );
+
+  // Transaction and cross-checks handled in outer scope
+  UInt32 tagId;
+  std::string insertionTime;
+  
+  // Tag already exists - check if created by HVS or by IOV tags
+  try {
+    HvsTagRecord tag = db().tagMgr().__findTagRecord( this->id(), tagName );
+    tagId = tag.id();
+    // Tag was created by IOV or user tags - cannot reuse it
+    if ( RelationalFolder::existsUserTagInObjectTable
+         ( db().queryMgr(), tagId, this->objectTableName() ) ||
+         RelationalFolder::existsTagInObject2TagTable
+         ( db().queryMgr(), tagId, this->object2TagTableName() ) ) 
+      throw TagExists( tagName, "RalDatabase" );
+    // Else tag must have been created by HVS (should we check for PANIC?)
+    // TODO! change the description of the tag according to what was provided
+
+    // Throw TagIsLocked if the tag is locked
+    // TODO: differentiate between LOCKED and PARTIALLYLOCKED?
+    // This method is only used for standard 'HEAD' tags, not user tags:
+    // if 'partial locks' are full locks for HEAD tags, then nothing to do.
+    if ( tag.lockStatus() != HvsTagLock::UNLOCKED )
+      throw TagIsLocked
+        ( "Cannot tag objects with tag '" + tagName + 
+          "': tag is locked", "RelationalFolder" );
+   
+    // TEMPORARY! Get the new insertion time from tag2tagseq used as CLOCK!
+    const std::string seqName = 
+      RelationalTag2TagTable::sequenceName( db().tag2TagTableName() );
+    RelationalSequencePtr sequence
+      ( db().queryMgr().sequenceMgr().getSequence( seqName ) );
+    sequence->nextVal(); // TEMPORARY! value not used: need non-sequence clock!
+    insertionTime = sequence->currDate();
+  } 
+
+  // Tag does not exist - get a new ID and insert the tag in the two tag tables
+  catch ( TagNotFound& ) {
+    //tag = tagMgr().createTag( folder->id(), tagName, description );
+    HvsTagRecord tag = db().tagMgr().createTagAndLocalTag
+      ( this->id(), tagName, description, this->tagTableName() );
+    tagId = tag.id();
+    insertionTime = timeToString( tag.insertionTime() );    
+  }
+  
+  // Insert the object ids into the object2Tag table
+  insertObject2TagTableRows
+    ( this->object2TagTableName(), tagId, insertionTime, objects );
+}
+
+//-----------------------------------------------------------------------------
+
+void RelationalFolder::deleteTag( const std::string& tagName ) 
+{
+
+  // Cross-check that the database is open
+  if ( ! db().isOpen() ) throw DatabaseNotOpen( "RalDatabase" );
+
+  // HEAD tag for SV folders and MV folders
+  if ( IHvsNode::isHeadTag( tagName ) )
+    throw ReservedHeadTag( tagName, "RalDatabase" );
+
+  // SV folder
+  if ( this->versioningMode() != FolderVersioning::MULTI_VERSION ) {
+    throw FolderIsSingleVersion( this->fullPath(), "RelationalFolder" );
+  }
+
+  // MV folder - get the tagId for tagName from the global tag table
+  else {
+    RelationalTransaction transaction( db().transactionMgr() ); // r/w
+    RelationalTableRow tagTableRow
+      ( db().tagMgr().fetchGlobalTagTableRow( this->id(), tagName ) );
+    // Throw TagIsLocked if the tag is locked
+    // (either LOCKED or PARTIALLYLOCKED - both are equivalent here)
+    HvsTagLock::Status lockStatus = 
+      HvsTagLock::Status
+      ( tagTableRow[RelationalGlobalTagTable::columnNames::tagLockStatus]
+        .data<UInt16>() );
+    if ( lockStatus != HvsTagLock::UNLOCKED )
+      throw TagIsLocked
+        ( "Cannot delete tag '" + tagName + "': tag is locked", 
+          "RelationalFolder" );
+    unsigned int tagId =
+      tagTableRow[RelationalGlobalTagTable::columnNames::tagId]
+      .data<unsigned int>();
+    deleteObject2TagTableRows( this->object2TagTableName(), tagId );
+    deleteObjectTableRowsForUserTag( this->objectTableName(), tagId );
+    if ( !db().tagMgr().existsTagInTag2TagTable( this->id(), tagId ) ) {
+      db().tagMgr().deleteTagTableRow( this->tagTableName(), tagId );
+      db().tagMgr().deleteGlobalTagTableRow( this->id(), tagId );
+    }
+    transaction.commit();
+  }
+
+}
+
+//-----------------------------------------------------------------------------
+
+void RelationalFolder::insertObject2TagTableRows
+( const std::string& object2TagTableName,
+  unsigned int tagId,
+  const std::string& insertionTime,
+  const std::vector<RelationalObjectTableRow>& rows ) const
+{
+  // Transaction handled in the outer scope
+
+  // Check that there are >0 rows to insert
+  unsigned int nRows = rows.size();
+  if ( nRows == 0 ) {
+    log() << "No rows to store into table "
+          << object2TagTableName << coral::MessageStream::endmsg;
+    return;
+  }
+  log() << "Bulk inserting " << nRows << " rows into table "
+        << object2TagTableName << coral::MessageStream::endmsg;
+
+  // Get a handle to the table
+  //coral::ITable& table =
+  //  session().nominalSchema().tableHandle( object2TagTableName );
+
+  // Setup the relational table bulk inserter
+  const IRecordSpecification& dataSpec =
+    RelationalObject2TagTable::tableSpecification();
+  coral::AttributeList data = Record( dataSpec ).attributeList();
+  //std::auto_ptr<coral::IBulkOperation>
+  //  bulkInserter( table.dataEditor().bulkInsert( data, nRows ) );
+  boost::shared_ptr<IRelationalBulkOperation> 
+    bulkInserter( db().queryMgr().bulkInsertTableRows
+                  ( object2TagTableName, data, nRows ) );
+
+  // Iterate through the objects and register them for insertion
+  for ( std::vector<RelationalObjectTableRow>::const_iterator
+          row = rows.begin(); row != rows.end(); ++row ) {
+
+    // Set all fields in the spec
+    data[RelationalObject2TagTable::columnNames::tagId].setValue
+      ( tagId );
+    data[RelationalObject2TagTable::columnNames::objectId].setValue
+      ( row->objectId() );
+    data[RelationalObject2TagTable::columnNames::channelId].setValue
+      ( row->channelId() );
+    data[RelationalObject2TagTable::columnNames::iovSince].setValue
+      ( row->since() );
+    data[RelationalObject2TagTable::columnNames::iovUntil].setValue
+      ( row->until() );
+    // TEMPORARY! sysInsTime as string rather than DATE
+    data[RelationalObject2TagTable::columnNames::sysInsTime].setValue
+      ( insertionTime );
+
+    // Verbose printout: print out the full row being inserted into the db
+    // TEMPORARY? Speed up tagging by disabling the streaming to MsgStream
+    /*
+      std::ostringstream dataStream;
+      data.print( dataStream );
+      log() << "Insert into the object2tag table the following AttributeList: "
+      << dataStream.str() << coral::MessageStream::endmsg;
+    */
+
+    // TEMPORARY? Will RAL do this as well?
+    // Check that all column values are within their allowed range
+    dataSpec.validate( data );
+    
+    // Insert the new object in the object2tag table
+    bulkInserter->processNextIteration();
+
+  }
+
+  // Flush the bulk inserter
+  bulkInserter->flush();
+
+}
+
+//-----------------------------------------------------------------------------
+
+unsigned int RelationalFolder::deleteObject2TagTableRows
+( const std::string& object2TagTableName,
+  unsigned int tagId ) const
+{
+  // Transaction handled in the outer scope
+  coral::AttributeList whereData;
+  whereData.extend
+    ( "tagId", typeIdToCoralType(RelationalTagTable::columnTypeIds::tagId) );
+  whereData["tagId"].setValue( tagId );
+  std::string whereClause = RelationalTagTable::columnNames::tagId;
+  whereClause += "= :tagId";
+  return db().queryMgr().deleteTableRows
+    ( object2TagTableName, whereClause, whereData );
+}
+
+//-----------------------------------------------------------------------------
+
+unsigned int RelationalFolder::deleteObjectTableRowsForUserTag
+( const std::string& objectTableName,
+  unsigned int tagId ) const
+{
+  // Transaction handled in the outer scope
+  coral::AttributeList whereData;
+  whereData.extend
+    ( "userTagId", 
+      typeIdToCoralType(RelationalObjectTable::columnTypeIds::userTagId) );
+  whereData["userTagId"].setValue( tagId );
+  std::string whereClause = RelationalObjectTable::columnNames::userTagId();
+  whereClause += "= :userTagId";
+  return db().queryMgr().deleteTableRows
+    ( objectTableName, whereClause, whereData );
+}
+
+//-----------------------------------------------------------------------------
+
+bool 
+RelationalFolder::existsUserTag( const std::string& userTagName ) const 
+{
+  // HEAD tag
+  if ( IHvsNode::isHeadTag( userTagName ) ) 
+  {
+    return false;
+  }
+
+  // Not a HEAD tag
+  else 
+  {
+    bool status;
+    RelationalTransaction transaction( db().transactionMgr(), true ); // r/o
+    status = __existsUserTag( userTagName );
+    transaction.commit();
+    return status;
+  }
+}
+
+//-----------------------------------------------------------------------------
+
+bool 
+RelationalFolder::__existsUserTag( const std::string& userTagName ) const 
+{
+  /*
+    User tags are a special kind of tag. They are recorded mainly in the IOV
+    table (although their name and description is also stored in the folder
+    and global tag tables).
+    
+    The difference between a normal tag and a user tag is that the user tagId
+    is referenced in the colum 'tag_id' of the iov table. Therefore in order
+    to find out if a user tag has been assigned, a COUNT(*) on the iov table
+    is made with a contraint tagId = userTagId.
+    
+    The userTagId is obtained from the folder's tag table tag_id. If no row
+    exists for tagName then no user tag by that name has been assigned.
+    
+    Even though this requires two queries to perform this check I don't think
+    we want to add an extra column 'isUserTag' to the tag table just to
+    implement the (temporary, at least for this specification) user tag.
+  */
+
+  // HEAD tag
+  if ( IHvsNode::isHeadTag( userTagName ) ) 
+  {
+    return false;
+  }
+
+  // Not a HEAD tag
+  else 
+  {
+    try {
+      unsigned int userTagId = 
+        db().tagMgr().fetchGlobalTagTableRow( id(), userTagName )
+        [RelationalTagTable::columnNames::tagId].data<unsigned int>();
+      bool status = existsUserTagInObjectTable
+        ( db().queryMgr(), userTagId, objectTableName() );
+      return status;
+    }
+    catch ( TagNotFound& ) {
+      return false;
+    }
+  }
+}
+
+//-----------------------------------------------------------------------------
+
+void RelationalFolder::renamePayload( const std::string& oldName,
+                                      const std::string& newName ) 
+{
+  // Preliminary checks
+  if ( ! payloadSpecification().exists( oldName ) ) 
+    throw RelationalException
+      ( "Cannot rename payload field " + oldName + ": it does not exist",
+        "RelationalFolder" );
+  if ( payloadSpecification().exists( newName ) )
+    throw RelationalException
+      ( "Cannot rename payload field to " + newName + ": it already exists",
+        "RelationalFolder" );
+  if ( ! RelationalDatabase::isValidPayloadFieldName( newName ) )
+    throw RelationalException
+      ( "Cannot rename payload field to " + newName + ": invalid name",
+        "RelationalFolder" );
+  // Cross-check that we're not in manual transaction more
+  if ( ! db().transactionMgr()->autoTransactions() ) {
+    throw RelationalException("Cannot rename payload fields in manual "
+                              "transaction mode", "RalDatabase");
+  }
+  
+  RelationalTransaction transaction( db().transactionMgr(), false ); // r/w
+
+  __renamePayload( oldName, newName );
+  
+  transaction.commit();
+}
+
+//-----------------------------------------------------------------------------
+
+void RelationalFolder::__renamePayload( const std::string& oldName,
+                                        const std::string& newName ) 
+{
+  // Prepare the new specification
+  RecordSpecification newRecordSpecification;
+  for ( unsigned int i = 0; i < payloadSpecification().size(); i++ ) {
+    const IFieldSpecification& field = payloadSpecification()[i];
+    if ( field.name() == oldName ) {
+      newRecordSpecification.extend( newName, field.storageType() );
+    }
+    else {
+      newRecordSpecification.extend( field.name(), field.storageType() );
+    }
+  } 
+  
+  // Rename column
+  db().schemaMgr().renameColumnInTable(m_objectTableName,oldName,newName);
+  
+  // Prepare to update the folder description
+  RecordSpecification dataSpec;
+  dataSpec.extend("newSpec",
+                  RelationalNodeTable::columnTypeIds::folderPayloadSpecDesc);
+  dataSpec.extend("nodeId",
+                  RelationalNodeTable::columnTypeIds::nodeId);
+  
+  Record data( dataSpec );
+  data["newSpec"]
+  .setValue<RelationalNodeTable::columnTypes::folderPayloadSpecDesc>
+  ( db().encodeRecordSpecification( newRecordSpecification ) );
+  data["nodeId"]
+  .setValue<RelationalNodeTable::columnTypes::nodeId>( id() );
+  
+  std::string setClause = 
+  RelationalNodeTable::columnNames::folderPayloadSpecDesc;
+  setClause += " = :newSpec, ";
+  setClause += RelationalNodeTable::columnNames::lastModDate;
+  setClause += " = " + db().queryMgr().serverTimeClause();
+  
+  std::string whereClause = RelationalNodeTable::columnNames::nodeId;
+  whereClause += "= :nodeId";
+  
+  db().queryMgr().updateTableRows( db().nodeTableName(),
+                                  setClause,
+                                  whereClause,
+                                  data.attributeList() );
+  
+  // Set the new specification
+  m_folderSpec.payloadSpecification() = newRecordSpecification;
+}
+
+//-----------------------------------------------------------------------------
+
+void RelationalFolder::extendPayloadSpecification( const IRecord& record )
+{
+  if ( record.specification().size() == 0 ) return;
+  
+  // Cross-check that we're not in manual transaction more
+  if ( ! db().transactionMgr()->autoTransactions() ) {
+    throw RelationalException("Cannot extend payload specification in manual "
+                              "transaction mode", "RalDatabase");
+  }
+  
+  // Start a transaction
+  RelationalTransaction transaction( db().transactionMgr(), false ); // r/w
+
+  __extendPayloadSpecification( record );
+  
+  // Commit the transaction
+  transaction.commit();
+    
+}
+
+//-----------------------------------------------------------------------------
+
+void RelationalFolder::__extendPayloadSpecification( const IRecord& record )
+{
+  // Loop over all fields in the record
+  const IRecordSpecification& spec = record.specification();
+  for ( UInt32 i = 0; i < spec.size(); i++ ) 
+  {
+    // Preliminary checks
+    const std::string& name = spec[i].name();
+    if ( payloadSpecification().exists( name ) )
+      throw RelationalException
+      ( "Cannot add payload field " + name + ": it already exists",
+       "RelationalFolder" );
+    if ( ! RelationalDatabase::isValidPayloadFieldName( name ) )
+      throw RelationalException
+      ( "Cannot add payload field " + name + ": invalid name",
+       "RelationalFolder" );    
+  }
+  
+  // Add columns (and set the values for all existing rows)
+  db().schemaMgr().addColumnsToTable( m_objectTableName, record );
+  
+  // Prepare the new specification
+  RecordSpecification newRecordSpecification = payloadSpecification();
+  newRecordSpecification.extend( spec );
+  
+  // Update the folder description
+  RecordSpecification dataSpec;
+  dataSpec.extend("newSpec",
+                  RelationalNodeTable::columnTypeIds::folderPayloadSpecDesc);
+  dataSpec.extend("nodeId",
+                  RelationalNodeTable::columnTypeIds::nodeId);
+  
+  Record data( dataSpec );
+  data["newSpec"]
+  .setValue<RelationalNodeTable::columnTypes::folderPayloadSpecDesc>
+  ( db().encodeRecordSpecification( newRecordSpecification ) );
+  data["nodeId"]
+  .setValue<RelationalNodeTable::columnTypes::nodeId>( id() );
+  
+  std::string setClause = 
+  RelationalNodeTable::columnNames::folderPayloadSpecDesc;
+  setClause += " = :newSpec, ";
+  setClause += RelationalNodeTable::columnNames::lastModDate;
+  setClause += " = " + db().queryMgr().serverTimeClause();
+  
+  std::string whereClause = RelationalNodeTable::columnNames::nodeId;
+  whereClause += "= :nodeId";
+  
+  db().queryMgr().updateTableRows( db().nodeTableName(),
+                                  setClause,
+                                  whereClause,
+                                  data.attributeList() );
+  
+  // Set the new specification
+  m_folderSpec.payloadSpecification() = newRecordSpecification;
+  
+}
+
+//-----------------------------------------------------------------------------
+
+bool
+RelationalFolder::existsUserTagInObjectTable
+( const RelationalQueryMgr& queryMgr,
+  UInt32 userTagId,
+  const std::string& objectTableName ) 
+{
+  coral::AttributeList whereData;
+  whereData.extend
+    ( "userTagId",
+      typeIdToCoralType(RelationalObjectTable::columnTypeIds::userTagId) );
+  whereData["userTagId"].setValue( userTagId );
+  std::string whereClause = 
+    RelationalObjectTable::columnNames::userTagId();
+  whereClause += "=:userTagId";    
+  unsigned int rowCount = queryMgr.countRowsFromTables
+    ( RelationalQueryMgr::tableList( objectTableName ), 
+      whereClause, whereData, "" );
+  return rowCount > 0;
+}
+
+//-----------------------------------------------------------------------------
+
+bool
+RelationalFolder::existsTagInObject2TagTable
+( const RelationalQueryMgr& queryMgr,
+  UInt32 tagId,
+  const std::string& object2TagTableName )
+{
+  coral::AttributeList whereData;
+  whereData.extend
+    ( "tagId", 
+      typeIdToCoralType(RelationalObject2TagTable::columnTypeIds::tagId) );
+  whereData["tagId"].setValue( tagId );
+  std::string whereClause = 
+    RelationalObject2TagTable::columnNames::tagId;
+  whereClause += "=:tagId";    
+  unsigned int rowCount = queryMgr.countRowsFromTables
+    ( RelationalQueryMgr::tableList( object2TagTableName ), 
+      whereClause, whereData, "" );
+  return rowCount > 0;
+}
+
+//-----------------------------------------------------------------------------
+/*
+bool RelationalFolder::isTagUsed( UInt32 tagId ) const
+{
+  // Is the tag referenced in the TAG2TAG table?
+  if ( RelationalHvsNode::isTagUsed( tagId ) ) {
+    return true;
+  }
+  // Is the tag used as user tag in the IOV table?
+  else if ( existsUserTagInObjectTable( tagId ) ) {
+    return true;
+  }
+  // Is the tag used in the IOV2TAG table?
+  else {
+    return existsTagInObject2TagTable( tagId );
+  } 
+}
+*/
+//-----------------------------------------------------------------------------
+
diff --git a/RelationalCool/src/RelationalFolder.h b/RelationalCool/src/RelationalFolder.h
new file mode 100644
index 000000000..1524680bf
--- /dev/null
+++ b/RelationalCool/src/RelationalFolder.h
@@ -0,0 +1,539 @@
+// $Id: RelationalFolder.h,v 1.158 2009-01-06 12:36:25 avalassi Exp $
+#ifndef RELATIONALCOOL_RELATIONALFOLDER_H
+#define RELATIONALCOOL_RELATIONALFOLDER_H
+
+// Disable warning C4250 on Windows (inheritance via dominance)
+// Copied from SEAL (Dictionary/Reflection/src/Tools.h)
+#ifdef WIN32
+#pragma warning ( disable : 4250 )
+#endif
+
+// Include files
+#include <memory>
+#include <vector>
+#include "CoralBase/MessageStream.h"
+#include "CoolKernel/ChannelSelection.h"
+#include "CoolKernel/FolderSpecification.h"
+#include "CoolKernel/IFolder.h"
+#include "CoolKernel/RecordSpecification.h"
+
+// Local include files
+#include "RelationalDatabase.h"
+#include "RelationalHvsNode.h"
+#include "VersionNumber.h"
+
+namespace cool {
+
+  /** @class RelationalFolder RelationalFolder.h
+   *
+   *  Relational implementation of a COOL condition database "folder".
+   *
+   *  Also represents implementation within COOL of an HVS leaf node.
+   *  Multiple virtual inheritance from IFolder and RelationalHvsNode
+   *  (diamond virtual inheritance of IHvsNodeRecord abstract interface).
+   *
+   *  @author Sven A. Schmidt, Andrea Valassi and Marco Clemencic
+   *  @date   2004-11-24
+   */
+
+  class RelationalFolder : virtual public IFolder,
+                           virtual public RelationalHvsNode 
+  {
+
+  public:
+
+    // Folder schema version for this class
+    static const VersionNumber folderSchemaVersion()
+    { 
+      // Summary of changes since software release COOL_2_0_0:
+      // - COOL_2_0 creates '2.0.0' folders.
+      // - COOL_2_1 still creates '2.0.0' folders (as agreed with users), 
+      //   even if these actually have an additional 5D index in the IOV table 
+      //   with respect to those created using COOL_2_0_0.
+      // - COOL_2_2 creates '2.0.1' folders: these have a FK on channelId
+      //   from the IOV to the channels table (only enforced on Oracle/MySQL);
+      //   also, the MySQL default type for VARCHAR(255) is now BINARY.
+      //   COOL_2_2 continues to read data using the 2.0.0 folder queries.
+      // - COOL_2_3/2_4/2_5/2_6/2_7 create '2.0.1' folders just like COOL_2_2.
+      return "2.0.1";
+    }
+
+    // Check if a folder schema version is supported by this class
+    static bool isSupportedSchemaVersion( const VersionNumber& schemaVersion );
+
+    /// Constructor to create a RelationalFolder from a node table row
+    /// Inlined with the base class non-standard constructors as otherwise 
+    /// the compiler attempts to use the base class standard constructors
+    /// (Windows compilation error C2248: standard constructors are private)
+    RelationalFolder( const RelationalDatabasePtr& db,
+                      const coral::AttributeList& row )
+      : RelationalHvsNodeRecord( row )
+      , RelationalHvsNode( db, row )   
+      , m_log( new coral::MessageStream( "RelationalFolder" ) )
+      , m_folderSpec( versioningMode( row ), payloadSpecification( row ) )
+      , m_publicFolderAttributes() // fill it in initialize
+    {
+      initialize( row );
+    }
+
+    /// Destructor.
+    virtual ~RelationalFolder();
+
+  public:
+
+    /// Return the folder specification.
+    const IFolderSpecification& folderSpecification() const {
+      return m_folderSpec;
+    }
+
+    /// Return the payload specification of the folder.
+    const IRecordSpecification& payloadSpecification() const {
+      return folderSpecification().payloadSpecification();
+    }
+
+    /// Return the folder versioning mode.
+    FolderVersioning::Mode versioningMode() const {
+      return folderSpecification().versioningMode();
+    }
+
+    /// Return the 'attributes' of the folder
+    /// (implementation-specific properties not exposed in the API).
+    const IRecord& folderAttributes() const;
+
+    /*
+    /// Declare that some payload columns reference external payload.
+    /// The referencedEntity URL contains the path to the external container.
+    /// Only FKs to relational tables within the same database are supported
+    /// so far with the syntax "local://schema=USERNAME;table=TABLENAME".
+    /// Non-relational implementation of CoolKernel should throw an exception.
+    /// Returns true in case of success, false in case of any error.
+    bool declareExternalReference
+    ( const std::string& name,
+      const std::vector< std::string >& attributes,
+      const std::string& referencedEntity,
+      const std::vector< std::string >& referencedAttributes );
+    
+    /// List the external reference constraints.
+    const std::vector< std::string > externalReferences() const;
+    
+    /// Retrieve the properties of an external reference constraint
+    const IFolder::ExternalReference&
+    externalReference( const std::string& name ) const;
+    */
+
+    /// Activate/deactivate a storage buffer for bulk insertion of objects.
+    /// If the buffer was used and is deactivated, flush the buffer.
+    void setupStorageBuffer( bool useBuffer = true );
+
+    /// Flush the storage buffer (execute the bulk insertion of objects).
+    /// If the buffer is not used, ignore this command.
+    void flushStorageBuffer();
+
+    /// Store an object in a given channel with the given IOV and data payload.
+    /// If the buffer is used, only register the object for later storage.
+    void storeObject( const ValidityKey& since,
+                      const ValidityKey& until,
+                      const IRecord& payload,
+                      const ChannelId& channelId,
+                      const std::string& userTagName = "",
+                      bool userTagOnly = false );
+
+    // OBSOLETE - kept for backward compatibility
+    void storeObject( const ValidityKey& since,
+                      const ValidityKey& until,
+                      const coral::AttributeList& payload,
+                      const ChannelId& channelId,
+                      const std::string& userTagName = "",
+                      bool userTagOnly = false );
+
+    /// Set a new finite end-of-validity value for all SV objects in a given 
+    /// channel selection whose end-of-validity is currently infinite.
+    /// The channel selection is specified through a ChannelSelection object.
+    /// Throws an Exception if called on a MV folder, or if any of the
+    /// selected channels contains a not open ended IOV at the point until.
+    /// Returns the number of actually truncated IOVs.
+    virtual int truncateObjectValidity( const ValidityKey& until,
+                                        const ChannelSelection& channels );
+
+    /// Find the ONE object in a given channel valid at the given point in time
+    /// in the given tag ("" and "HEAD" both indicate the folder HEAD).
+    /// Tag names, except for "HEAD", are case sensitive.
+    /// If the buffer is used, it must be flushed first (else throw exception).
+    /// Throws an ObjectNotFound exception if no such object exists.
+    /// For single version folders, the tag must be either "" or "HEAD",
+    /// otherwise a TagNotFound exception is thrown.
+    IObjectPtr findObject( const ValidityKey& pointInTime,
+                           const ChannelId& channelId,
+                           const std::string& tagName="" ) const;
+    
+    /// Find the objects for a given channel selection at the given point
+    /// in time in the given tag ("" and "HEAD" both indicate the folder HEAD).
+    /// Tag names, except for "HEAD", are case sensitive.
+    /// The channel selection is specified through a ChannelSelection object.
+    /// The iterator will retrieve only ONE object for each selected channel
+    /// (or none if there is no valid IOV at pointInTime in the channel).
+    /// The iterator returns objects ordered by channel: the order clause
+    /// optionally specified in the ChannelSelection object is ignored.
+    /// For single version folders, the tag must be either "" or "HEAD",
+    /// otherwise a TagNotFound exception is thrown.
+    IObjectIteratorPtr 
+    findObjects( const ValidityKey& pointInTime,
+                 const ChannelSelection& channels,
+                 const std::string& tagName = "" ) const;
+
+    /// Browse the objects for a given channel selection within the given time
+    /// range in the given tag ("" and "HEAD" both indicate the folder HEAD).
+    /// Tag names, except for "HEAD", are case sensitive.
+    /// The validity range is inclusive at both ends as well, i.e.
+    /// since = t1, until = t2 will select an object with since = t2.
+    /// The channel selection is specified through a ChannelSelection object.
+    /// The iterator will retrieve only ONE object at any given validity point
+    /// for a given channel. The default order is channel, since.
+    /// For single version folders, the tag must be either "" or "HEAD",
+    /// otherwise a TagNotFound exception is thrown.
+    IObjectIteratorPtr 
+    browseObjects( const ValidityKey& since,
+                   const ValidityKey& until,
+                   const ChannelSelection& channels,
+                   const std::string& tagName = "", 
+                   const IRecordSelection* payloadQuery = 0 ) const;
+
+    /// Internal method
+    IObjectIteratorPtr
+    browseObjects( const ValidityKey& since,
+                   const ValidityKey& until,
+                   const ChannelSelection& channels,
+                   const std::string& tagName,
+                   bool prefetchAll, 
+                   const IRecordSelection* payloadQuery ) const;   
+
+    /// Return the object count for the given selection. The selection
+    /// parameters are the same as for browseObjects (as is the actual
+    /// selection).
+    unsigned int countObjects( const ValidityKey& since,
+                               const ValidityKey& until,
+                               const ChannelSelection& channels,
+                               const std::string& tagName = "", 
+                               const IRecordSelection* payloadQuery = 0 ) const;
+
+    /// Change the object prefetch policy (default is prefetchAll=true).
+    /// If prefetchAll is true, the browse() methods prefetch all IOVs and
+    /// return IObjectIterator's that are wrappers to IObjectPtr vectors.
+    /// If prefetchAll is false, the browse() methods prefetch only a few
+    /// IOVs at a time and return IObjectIterator's that are wrappers to
+    /// server-side cursors: a transaction and the cursor are opened when
+    /// the iterator is created, and these are only closed when the iterator
+    /// is explicitly deleted (or the shared pointer goes out of scope).
+    /// No other query against the database can be performed during that time.
+    void setPrefetchAll( bool prefetchAll ) {
+      m_prefetchAll = prefetchAll;
+    }
+
+    /// to be documented
+    /// new browseObjects methods returning IObjectVector
+    IObjectVectorPtr fetchObjectsAtTime( const ValidityKey& pointInTime,
+                                         const ChannelSelection& channels,
+                                         const std::string& tagName = "" ) const;
+    
+    /// to be documented
+    /// new browseObjects methods returning IObjectVector
+    IObjectVectorPtr fetchObjectsInRange( const ValidityKey& since,
+                                          const ValidityKey& until,
+                                          const ChannelSelection& channels,
+                                          const std::string& tagName = "" ) const;
+
+    /// Associates the objects that are the current HEAD
+    /// with the given tag name and tag description.
+    void tagCurrentHead( const std::string& tagName,
+                         const std::string& description = "" ) const;
+
+    /// Clones the tag "tagName" as user tag "tagClone" by reinserting 
+    /// the IOVs with the user tag. Does not modify the current head.
+    /// This method is non-const because it sets m_useBuffer to use bulk 
+    /// insertion and eventually restores the original setting of m_useBuffer.
+    void cloneTagAsUserTag( const std::string& tagName, 
+                            const std::string& tagClone,
+                            const std::string& description = "",
+                            bool forceOverwriteTag = false );
+    
+    /// Associates the objects that were the HEAD at 'asOfDate'
+    /// with the given tag name and tag description.
+    void tagHeadAsOfDate( const ITime& asOfDate,
+                          const std::string& tagName,
+                          const std::string& description = "" ) const;
+
+    /// TEMPORARY? Can be commented out until included in the public API?
+    /// Tags the objects in the given folder
+    /// that were at the HEAD at 'asOfObjectId', at the time the object with
+    /// id 'asOfObjectId' was inserted (and including that object)
+    /// with the given tagName and description. Throws a TagExists
+    /// exception if a tag by that name already exists.
+    void tagHeadAsOfObjectId( unsigned int asOfObjectId,
+                              const std::string& tagName,
+                              const std::string& description );
+
+    /// Tags the given objects of the given folder. Throws a TagExists
+    /// exception if a tag by that name already exists.
+    void tagObjectList( const std::string& tagName,
+                        const std::string& description,
+                        const std::vector<RelationalObjectTableRow>& objects ) const;
+    
+    /// Inserts the given objects for the given tag id in the given
+    /// object2Tag table
+    void insertObject2TagTableRows
+    ( const std::string& object2TagTableName,
+      unsigned int tagId,
+      const std::string& insertionTime,
+      const std::vector<RelationalObjectTableRow>& objects ) const;
+
+    /// Delete rows with tagId from the object2tag table.
+    /// Returns the number of deleted rows.
+    unsigned int
+    deleteObject2TagTableRows( const std::string& object2TagTableName,
+                               unsigned int tagId ) const;
+
+    /// Delete rows with tagId from the object table.
+    /// Returns the number of deleted rows.
+    unsigned int
+    deleteObjectTableRowsForUserTag( const std::string& objectTableName,
+                                     unsigned int tagId ) const;
+
+    /// Insertion time of the last inserted IOV in a tag defined for this node.
+    const Time 
+    insertionTimeOfLastObjectInTag( const std::string& tagName ) const;
+
+    /// Deletes a tag from this folder and from the global "tag namespace".
+    /// The tag name is available for tagging again afterwards.
+    void deleteTag( const std::string& tagName );
+
+    /// Does this user tag exist? - This starts a transaction
+    /// Tag names are case sensitive.
+    bool existsUserTag( const std::string& userTagName ) const;
+
+    /// Does this user tag exist? - This does not start a transaction
+    /// Tag names are case sensitive.
+    bool __existsUserTag( const std::string& userTagName ) const;
+
+    /// Rename a payload item
+    void renamePayload( const std::string& oldName,
+                        const std::string& newName );
+
+    /// Rename a payload item - This does not start a transaction
+    void __renamePayload( const std::string& oldName,
+                          const std::string& newName );
+    
+    /// Add new payload fields with the given names and storage types, 
+    /// setting their values for all existing IOVS to the given values.
+    void extendPayloadSpecification( const IRecord& record );
+
+    /// Add new payload fields with the given names and storage types, 
+    /// setting their values for all existing IOVS to the given values.
+    /// - This does not start a transaction
+    void __extendPayloadSpecification( const IRecord& record );
+    
+    /*
+    /// Does this user tag exist in the object table?
+    /// THIS DOES NOT START A TRANSACTION
+    bool existsUserTagInObjectTable( UInt32 userTagId ) const;
+        
+    /// Does this user tag exist in the object2tag table?
+    /// THIS DOES NOT START A TRANSACTION
+    bool existsTagInObject2TagTable( UInt32 userTagId ) const;
+    */
+
+    /*
+    /// Does this tag defined in this node have any relation (i.e. does 
+    /// it reference a parent tag or is it referenced by any children)?
+    /// Returns false if this tag does not exist in this node.
+    /// OVERLOADED RelationalHvsNode method.
+    bool isTagUsed( UInt32 tagId ) const;
+    */
+
+    /// Does this user tag exist in the object table?
+    /// THIS DOES NOT START A TRANSACTION
+    static bool existsUserTagInObjectTable( const RelationalQueryMgr& queryMgr,
+                                            UInt32 userTagId,
+                                            const std::string& objectTableName );
+    
+    /// Does this user tag exist in the object2tag table?
+    /// THIS DOES NOT START A TRANSACTION
+    static bool existsTagInObject2TagTable( const RelationalQueryMgr& queryMgr,
+                                            UInt32 tagId,
+                                            const std::string& object2TagTableName );
+
+  public:
+    
+    // ----- CHANNEL MANAGEMENT -----
+
+    /// Return the list of existing channels (ordered by ascending channelId).
+    const std::vector<ChannelId> listChannels() const;
+
+    /// Return the map of id->name for all existing channels.
+    const std::map<ChannelId,std::string> listChannelsWithNames() const;
+
+    /// Create a new channel with the given id, name and description.
+    /// Throw ChannelExists if the id/name is already used by another channel.
+    /// Throw InvalidChannelName if the channel name is invalid: all valid
+    /// channel names must be between 1 and 255 characters long; they must
+    /// start with a letter and must contain only letters, numbers or the '_'
+    /// character (these constraints may be relaxed in a future COOL release). 
+    /// Throw an Exception if the description is longer than 255 characters.
+    void createChannel( const ChannelId& channelId,
+                        const std::string& channelName,
+                        const std::string& description = "" );
+    
+    /// Drop (delete) an existing channel, given its id.
+    /// Return true if the channel is dropped as expected. Return false 
+    /// (without throwing any exception) if the channel does not exist any 
+    /// more on exit from this method, but it did not exist to start with.
+    /// Throw an Exception if the channel cannot be dropped.
+    /// NB: in the COOL_2_2_0 API, a channel can only be dropped if it exists
+    /// in the channel table but contains no IOVs (an exception is thrown if
+    /// it does contain IOVs); in later COOL releases, the semantics of this
+    /// method may change to mean 'drop the channel and any IOVs it contains'.
+    bool dropChannel( const ChannelId& channelId );
+
+    /// Set the name of a channel, given its id.
+    /// Throw ChannelNotFound if no channel exists with this id.
+    /// Throw InvalidChannelName if the channel name is invalid (see above).
+    /// Throw ChannelExists if the name is already used by another channel.
+    void setChannelName( const ChannelId& channelId,
+                         const std::string& channelName );
+    
+    /// Return the name of a channel, given its id.
+    /// Throw ChannelNotFound if no channel exists with this id.
+    const std::string channelName( const ChannelId& channelId ) const;
+
+    /// Return the id of a channel, given its name.
+    /// Throw InvalidChannelName if the channel name is invalid (see above).
+    /// Throw ChannelNotFound if no channel exists with this name.
+    ChannelId channelId( const std::string& channelName ) const;
+
+    /// Does a channel with this id exist?
+    bool existsChannel( const ChannelId& channelId ) const;
+    
+    /// Does a channel with this name exist?
+    /// Throw InvalidChannelName if the channel name is invalid (see above).
+    bool existsChannel( const std::string& channelName ) const;
+
+    /// Set the description of a channel, given its id.
+    /// Throw ChannelNotFound if no channel exists with this id.
+    /// Throw InvalidChannelName if the channel name is invalid (see above).
+    /// Throw an Exception if the description is longer than 255 characters.
+    void setChannelDescription( const ChannelId& channelId,
+                                const std::string& description );
+    
+    /// Return the description of a channel, given its id.
+    /// Throw ChannelNotFound if no channel exists with this id.
+    const std::string channelDescription( const ChannelId& channelId ) const;
+    
+  public:
+
+    /// Return the IOV table name for this folder.
+    const std::string& objectTableName() const;
+
+    /// Return the tag table name for this folder.
+    const std::string& tagTableName() const;
+
+    /// Return the IOV2tag table name for this folder.
+    const std::string& object2TagTableName() const;
+
+    /// Return the channel table name for this folder.
+    const std::string& channelTableName() const;
+    
+  public:
+
+    /// Get the extended payload specification from the given folder row
+    static const RecordSpecification
+    payloadSpecification( const coral::AttributeList& folderRow );
+
+    /// Get the versioning mode from the given folder row
+    static FolderVersioning::Mode 
+    versioningMode( const coral::AttributeList& folderRow );
+
+    /// Get the object table name from the given folder row
+    static const std::string objectTableName
+    ( const coral::AttributeList& folderRow );
+
+    /// Get the tag table name from the given folder row
+    static const std::string tagTableName
+    ( const coral::AttributeList& folderRow );
+
+    /// Get the object2tag table name from the given folder row
+    static const std::string object2TagTableName
+    ( const coral::AttributeList& folderRow );
+
+    /// Get the channel table name from the given folder row
+    static const std::string channelTableName
+    ( const coral::AttributeList& folderRow );
+    
+    /// Buffer size for bulk insertion
+    static unsigned maxBufferSize();
+
+  private:
+
+    /// Initialize (complete non-standard constructor with non-inlined code)
+    void initialize( const coral::AttributeList& row );
+
+    /// Standard constructor is private
+    RelationalFolder();
+
+    /// Copy constructor is private
+    RelationalFolder( const RelationalFolder& rhs );
+
+    /// Assignment operator is private
+    RelationalFolder& operator=( const RelationalFolder& rhs );
+
+  private:
+
+    /// Get a CORAL MessageStream
+    coral::MessageStream& log() const;
+
+    /// Folder attribute specification for the RelationalFolder class
+    static const RecordSpecification& folderAttributesSpecification
+    ( FolderVersioning::Mode versioningMode );
+
+  private:
+
+    /// CORAL MessageStream
+    std::auto_ptr<coral::MessageStream> m_log;
+
+    /// Folder specification
+    FolderSpecification m_folderSpec;
+
+    /// External reference constraint map
+    //std::map< std::string, IFolder::ExternalReference > m_externalReferences;
+
+    /// Use a storage buffer?
+    bool m_useBuffer;
+
+    /// Object storage buffer
+    std::vector<RelationalObjectPtr> m_objectBuffer;
+
+    /// Insert into the user tag branch only?
+    bool m_userTagOnly;
+
+    /// IOV table name
+    std::string m_objectTableName;
+
+    /// Tag table name
+    std::string m_tagTableName;
+
+    /// IOV2tag table name
+    std::string m_object2TagTableName;
+
+    /// Channel table name
+    std::string m_channelTableName;
+    
+    /// Public attributes of the folder
+    Record m_publicFolderAttributes;
+
+    /// Prefetch all objects into vectors?
+    bool m_prefetchAll;
+
+  };
+
+}
+
+#endif
+
diff --git a/RelationalCool/src/RelationalFolderSet.cpp b/RelationalCool/src/RelationalFolderSet.cpp
new file mode 100644
index 000000000..1bc6e22cd
--- /dev/null
+++ b/RelationalCool/src/RelationalFolderSet.cpp
@@ -0,0 +1,91 @@
+// $Id: RelationalFolderSet.cpp,v 1.16 2008-11-04 11:52:11 avalassi Exp $
+
+// Include files
+#include "CoolKernel/Exception.h"
+
+// Local include files
+#include "RelationalDatabase.h"
+#include "RelationalFolderSet.h"
+#include "RelationalNodeTable.h"
+
+// Namespace
+using namespace cool;
+
+//-----------------------------------------------------------------------------
+
+bool RelationalFolderSet::isSupportedSchemaVersion
+( const VersionNumber& rhs )
+{
+  VersionNumber lhs = folderSetSchemaVersion();
+  return 
+    ( lhs.majorVersion() == rhs.majorVersion() ) 
+    && ( lhs.minorVersion() == rhs.minorVersion() );  
+  //&& ( lhs.patchVersion() <= rhs.patchVersion() );
+}
+
+//-----------------------------------------------------------------------------
+
+void RelationalFolderSet::initialize( const coral::AttributeList& row )
+{
+  const IRecordSpecification& spec = folderSetAttributesSpecification();
+  m_publicFolderSetAttributes = Record( spec, row );
+  log() << coral::Debug << "Instantiate a RelationalFolderSet for '" 
+        << fullPath() << "'" << coral::MessageStream::endmsg;
+}
+
+//-----------------------------------------------------------------------------
+
+RelationalFolderSet::~RelationalFolderSet() 
+{
+  log() << coral::Debug << "Delete the RelationalFolderSet for '" 
+        << fullPath() << "'" << coral::MessageStream::endmsg;
+}
+
+//-----------------------------------------------------------------------------
+
+coral::MessageStream& RelationalFolderSet::log() 
+{
+  *m_log << coral::Verbose;
+  return *m_log;
+}
+
+//-----------------------------------------------------------------------------
+
+std::vector<std::string> 
+RelationalFolderSet::listFolders( bool ascending ) 
+{
+  return db().listFolders( this, ascending );
+}
+
+
+//-----------------------------------------------------------------------------
+
+std::vector<std::string> 
+RelationalFolderSet::listFolderSets( bool ascending ) 
+{
+  return db().listFolderSets( this, ascending );
+}
+
+//-----------------------------------------------------------------------------
+
+const IRecord& RelationalFolderSet::folderSetAttributes() const 
+{
+  return m_publicFolderSetAttributes;
+}
+ 
+//-----------------------------------------------------------------------------
+
+const RecordSpecification& 
+RelationalFolderSet::folderSetAttributesSpecification()
+{
+  static RecordSpecification s_folderSetAttrSpec;
+  if ( s_folderSetAttrSpec.size() == 0 ) {
+    s_folderSetAttrSpec.extend
+      ( RelationalNodeTable::columnNames::nodeSchemaVersion,
+        RelationalNodeTable::columnTypeIds::nodeSchemaVersion );
+  }
+  return s_folderSetAttrSpec;
+}
+
+//-----------------------------------------------------------------------------
+
diff --git a/RelationalCool/src/RelationalFolderSet.h b/RelationalCool/src/RelationalFolderSet.h
new file mode 100644
index 000000000..a26b65fd5
--- /dev/null
+++ b/RelationalCool/src/RelationalFolderSet.h
@@ -0,0 +1,111 @@
+// $Id: RelationalFolderSet.h,v 1.28 2008-11-04 11:30:11 avalassi Exp $
+#ifndef RELATIONALCOOL_RELATIONALFOLDERSET_H
+#define RELATIONALCOOL_RELATIONALFOLDERSET_H
+
+// Disable warning C4250 on Windows (inheritance via dominance)
+// Copied from SEAL (Dictionary/Reflection/src/Tools.h)
+#ifdef WIN32
+#pragma warning ( disable : 4250 )
+#endif
+
+// Include files
+#include <memory>
+#include "CoolKernel/IFolderSet.h"
+#include "CoralBase/MessageStream.h"
+
+// Local include files
+#include "RelationalDatabasePtr.h"
+#include "RelationalHvsNode.h"
+
+namespace cool {
+
+  /** @class RelationalFolderSet RelationalFolderSet.h
+   *
+   *  Relational implementation of a COOL condition database "folderset".
+   *
+   *  Also represents implementation within COOL of an HVS leaf node.
+   *  Multiple virtual inheritance from IFolder and RelationalHvsNode
+   *  (diamond virtual inheritance of IHvsNodeRecord abstract interface).
+   *
+   *  @author Sven A. Schmidt and Andrea Valassi
+   *  @date   2005-06-07
+   */
+
+  class RelationalFolderSet : virtual public IFolderSet,
+                              virtual public RelationalHvsNode 
+  {
+
+  public:
+
+    // Folder set schema version for this class
+    static const VersionNumber folderSetSchemaVersion()
+    { 
+      return "2.0.0";
+    }
+
+    // Check if a folder set schema version is supported by this class
+    static bool isSupportedSchemaVersion( const VersionNumber& schemaVersion );
+
+    /// Constructor to create a RelationalFolderSet from a node table row
+    /// Inlined with the base class non-standard constructors as otherwise 
+    /// the compiler attempts to use the base class standard constructors
+    /// (Windows compilation error C2248: standard constructors are private)
+    RelationalFolderSet( const RelationalDatabasePtr& db,
+                         const coral::AttributeList& row )
+      : RelationalHvsNodeRecord( row )
+      , RelationalHvsNode( db, row )   
+      , m_log( new coral::MessageStream( "RelationalFolderSet" ) )
+      , m_publicFolderSetAttributes() // fill it in initialize
+    {
+      initialize( row );
+    }    
+
+    /// Destructor.
+    virtual ~RelationalFolderSet();
+
+    /// Lists all folders at this level in the node hierarchy
+    std::vector<std::string> listFolders( bool ascending = true );
+    
+    /// Lists all foldersets at this level in the node hierarchy
+    std::vector<std::string> listFolderSets( bool ascending = true );
+
+    /// Return the 'attributes' of the folderset
+    /// (implementation-specific properties not exposed in the API).
+    const IRecord& folderSetAttributes() const;
+
+  private:
+    
+    /// Initialize (complete non-standard constructor with non-inlined code)
+    void initialize( const coral::AttributeList& row );
+
+    /// Standard constructor is private
+    RelationalFolderSet();
+    
+    /// Copy constructor is private
+    RelationalFolderSet( const RelationalFolderSet& rhs );
+    
+    /// Assignment operator is private
+    RelationalFolderSet& operator=( const RelationalFolderSet& rhs );
+    
+  private:
+
+    /// Get a CORAL MessageStream
+    coral::MessageStream& log();
+    
+    /// Folderset attribute specification for the RelationalFolderSetNew class
+    static const RecordSpecification& folderSetAttributesSpecification();
+
+  private:
+
+    /// SEAL MessageStream
+    std::auto_ptr<coral::MessageStream> m_log;
+    
+    /// Public attributes of the folderset
+    Record m_publicFolderSetAttributes;
+
+  };
+
+}
+
+#endif
+
diff --git a/RelationalCool/src/RelationalFolderSetUnsupported.cpp b/RelationalCool/src/RelationalFolderSetUnsupported.cpp
new file mode 100644
index 000000000..6c42f4ed9
--- /dev/null
+++ b/RelationalCool/src/RelationalFolderSetUnsupported.cpp
@@ -0,0 +1,62 @@
+// $Id: RelationalFolderSetUnsupported.cpp,v 1.3 2008-03-20 18:30:20 marcocle Exp $
+
+// Local include files
+#include "RelationalDatabase.h"
+#include "RelationalFolderSetUnsupported.h"
+#include "RelationalNodeTable.h"
+
+// Namespace
+using namespace cool;
+
+//-----------------------------------------------------------------------------
+
+void 
+RelationalFolderSetUnsupported::initialize( const coral::AttributeList& row )
+{
+  const IRecordSpecification& spec = folderSetAttributesSpecification();
+  m_publicFolderSetAttributes = Record( spec, row );
+  log() << coral::Debug 
+        << "Instantiate a RelationalFolderSetUnsupported for '" 
+        << fullPath() << "'" << coral::MessageStream::endmsg;
+}	
+
+//-----------------------------------------------------------------------------
+
+RelationalFolderSetUnsupported::~RelationalFolderSetUnsupported() 
+{
+  log() << coral::Debug 
+        << "Delete the RelationalFolderSetUnsupported for '" 
+        << fullPath() << "'" << coral::MessageStream::endmsg;
+}
+
+//-----------------------------------------------------------------------------
+
+coral::MessageStream& RelationalFolderSetUnsupported::log() 
+{
+  *m_log << coral::Verbose;
+  return *m_log;
+}
+
+//-----------------------------------------------------------------------------
+
+const IRecord& RelationalFolderSetUnsupported::folderSetAttributes() const 
+{
+  return m_publicFolderSetAttributes;
+}
+ 
+//-----------------------------------------------------------------------------
+
+const RecordSpecification& 
+RelationalFolderSetUnsupported::folderSetAttributesSpecification()
+{
+  static RecordSpecification s_folderSetAttrSpec;
+  if ( s_folderSetAttrSpec.size() == 0 ) {
+    s_folderSetAttrSpec.extend
+      ( RelationalNodeTable::columnNames::nodeSchemaVersion,
+        RelationalNodeTable::columnTypeIds::nodeSchemaVersion );
+  }
+  return s_folderSetAttrSpec;
+}
+
+//-----------------------------------------------------------------------------
+
diff --git a/RelationalCool/src/RelationalFolderSetUnsupported.h b/RelationalCool/src/RelationalFolderSetUnsupported.h
new file mode 100644
index 000000000..266c99686
--- /dev/null
+++ b/RelationalCool/src/RelationalFolderSetUnsupported.h
@@ -0,0 +1,124 @@
+// $Id: RelationalFolderSetUnsupported.h,v 1.7 2008-11-04 11:52:11 avalassi Exp $
+#ifndef RELATIONALCOOL_RELATIONALFOLDERSETUNSUPPORTED_H
+#define RELATIONALCOOL_RELATIONALFOLDERSETUNSUPPORTED_H
+
+// Disable warning C4250 on Windows (inheritance via dominance)
+// Copied from SEAL (Dictionary/Reflection/src/Tools.h)
+#ifdef WIN32
+#pragma warning ( disable : 4250 )
+#endif
+
+// Include files
+#include <memory>
+#include "CoolKernel/IFolderSet.h"
+#include "CoralBase/MessageStream.h"
+
+// Local include files
+#include "RelationalDatabase.h"
+#include "RelationalException.h"
+#include "RelationalHvsNode.h"
+
+namespace cool {
+
+  //--------------------------------------------------------------------------
+  
+  /** @class RelationalFolderSetUnsupported RelationalFolderSetUnsupported.h
+   *
+   *  UNSUPPORTED relational implementation of a COOL condition db "folderset".
+   *
+   *  Also represents implementation within COOL of an HVS leaf node.
+   *  Multiple virtual inheritance from IFolder and RelationalHvsNode
+   *  (diamond virtual inheritance of IHvsNodeRecord abstract interface).
+   *
+   *  Within the COOL 2.0 software, this represents a handle to a folder set
+   *  created using the COOL 2.1 software and implementing the new 2.1 schema.
+   *  Such a folder set cannot be opened for reading or writing using the 2.0
+   *  software (its contents cannot be read or modified): only its generic 
+   *  properties (those retrieved from the node table) can be queried.
+   *
+   *  @author Andrea Valassi
+   *  @date   2007-01-09
+   */
+
+  class RelationalFolderSetUnsupported : virtual public IFolderSet,
+                                         virtual public RelationalHvsNode {
+
+  public:
+
+    /// Ctor to create a RelationalFolderSetUnsupported from a node table row
+    /// Inlined with the base class non-standard constructors as otherwise 
+    /// the compiler attempts to use the base class standard constructors
+    /// (Windows compilation error C2248: standard constructors are private)
+    RelationalFolderSetUnsupported( const RelationalDatabasePtr& db,
+                                    const coral::AttributeList& row )
+      : RelationalHvsNodeRecord( row )
+      , RelationalHvsNode( db, row )   
+      , m_log( new coral::MessageStream( "RelationalFolderSetUnsupported" ) )
+      , m_publicFolderSetAttributes() // fill it in initialize
+    {
+      initialize( row );
+    }    
+
+    /// Destructor.
+    virtual ~RelationalFolderSetUnsupported();
+
+    /// Return the 'attributes' of the folderset
+    /// (implementation-specific properties not exposed in the API).
+    const IRecord& folderSetAttributes() const;
+
+  public:
+
+    // -- THE FOLLOWING METHODS ALL THROW --
+
+    /// Lists all folders at this level in the node hierarchy
+    std::vector<std::string> listFolders( bool /*ascending = true*/ )
+    {
+      throw UnsupportedFolderSetSchema
+        ( fullPath(), schemaVersion(), "RelationalFolderSetUnsupported" );
+    };
+    
+    /// Lists all foldersets at this level in the node hierarchy
+    std::vector<std::string> listFolderSets( bool /*ascending = true*/ )
+    {
+      throw UnsupportedFolderSetSchema
+        ( fullPath(), schemaVersion(), "RelationalFolderSetUnsupported" );
+    };
+
+  private:
+    
+    /// Initialize (complete non-standard constructor with non-inlined code)
+    void initialize( const coral::AttributeList& row );
+
+    /// Standard constructor is private
+    RelationalFolderSetUnsupported();
+    
+    /// Copy constructor is private
+    RelationalFolderSetUnsupported
+    ( const RelationalFolderSetUnsupported& rhs );
+    
+    /// Assignment operator is private
+    RelationalFolderSetUnsupported& 
+    operator=( const RelationalFolderSetUnsupported& rhs );
+    
+  private:
+
+    /// Get a CORAL MessageStream
+    coral::MessageStream& log();
+    
+    /// Folderset attribute spec for the RelationalFolderSetUnsupported class
+    static const RecordSpecification& folderSetAttributesSpecification();
+
+  private:
+
+    /// CORAL MessageStream
+    std::auto_ptr<coral::MessageStream> m_log;
+    
+    /// Public attributes of the folderset
+    Record m_publicFolderSetAttributes;
+
+  };
+
+}
+
+#endif
+
diff --git a/RelationalCool/src/RelationalFolderUnsupported.cpp b/RelationalCool/src/RelationalFolderUnsupported.cpp
new file mode 100644
index 000000000..a509c0602
--- /dev/null
+++ b/RelationalCool/src/RelationalFolderUnsupported.cpp
@@ -0,0 +1,59 @@
+// $Id: RelationalFolderUnsupported.cpp,v 1.2 2008-03-20 18:30:19 marcocle Exp $
+
+// Local include files
+#include "RelationalFolderUnsupported.h"
+#include "RelationalNodeTable.h"
+
+// Namespace
+using namespace cool;
+
+//-----------------------------------------------------------------------------
+
+void RelationalFolderUnsupported::initialize( const coral::AttributeList& row )
+{
+  const IRecordSpecification& spec = folderAttributesSpecification();
+  m_publicFolderAttributes = Record( spec, row );
+  log() << coral::Debug 
+        << "Instantiate a RelationalFolderUnsupported for '" 
+        << fullPath() << "'" << coral::MessageStream::endmsg;
+}	
+
+//-----------------------------------------------------------------------------
+
+RelationalFolderUnsupported::~RelationalFolderUnsupported() 
+{
+  log() << coral::Debug << "Delete the RelationalFolderUnsupported for '" 
+        << fullPath() << "'" << coral::MessageStream::endmsg;
+}
+
+//-----------------------------------------------------------------------------
+
+coral::MessageStream& RelationalFolderUnsupported::log() const
+{
+  *m_log << coral::Verbose;
+  return *m_log;
+}
+  
+//-----------------------------------------------------------------------------
+
+const IRecord& RelationalFolderUnsupported::folderAttributes() const 
+{
+  return m_publicFolderAttributes;
+}
+ 
+//-----------------------------------------------------------------------------
+
+const RecordSpecification& 
+RelationalFolderUnsupported::folderAttributesSpecification()
+{
+  static RecordSpecification s_folderAttrSpec;
+  if ( s_folderAttrSpec.size() == 0 ) {
+    s_folderAttrSpec.extend
+      ( RelationalNodeTable::columnNames::nodeSchemaVersion,
+        RelationalNodeTable::columnTypeIds::nodeSchemaVersion );
+  }
+  return s_folderAttrSpec;
+}
+
+//-----------------------------------------------------------------------------
+
diff --git a/RelationalCool/src/RelationalFolderUnsupported.h b/RelationalCool/src/RelationalFolderUnsupported.h
new file mode 100644
index 000000000..69334d136
--- /dev/null
+++ b/RelationalCool/src/RelationalFolderUnsupported.h
@@ -0,0 +1,388 @@
+// $Id: RelationalFolderUnsupported.h,v 1.24 2008-11-04 11:52:11 avalassi Exp $
+#ifndef RELATIONALCOOL_RELATIONALFOLDERUNSUPPORTED_H
+#define RELATIONALCOOL_RELATIONALFOLDERUNSUPPORTED_H
+
+// Disable warning C4250 on Windows (inheritance via dominance)
+// Copied from SEAL (Dictionary/Reflection/src/Tools.h)
+#ifdef WIN32
+#pragma warning ( disable : 4250 )
+#endif
+
+// Include files
+#include <memory>
+#include "CoralBase/MessageStream.h"
+#include "CoolKernel/IFolder.h"
+#include "CoolKernel/Time.h"
+
+// Local include files
+#include "RelationalDatabase.h"
+#include "RelationalException.h"
+#include "RelationalHvsNode.h"
+
+namespace cool {
+
+  //--------------------------------------------------------------------------
+
+  /** @class RelationalFolderUnsupported RelationalFolderUnsupported.h
+   *
+   *  UNSUPPORTED relational implementation of a COOL condition db "folder".
+   *
+   *  Also represents implementation within COOL of an HVS leaf node.
+   *  Multiple virtual inheritance from IFolder and RelationalHvsNode
+   *  (diamond virtual inheritance of IHvsNodeRecord abstract interface).
+   *
+   *  Within the COOL 2.0 software, this represents a handle to a folder
+   *  created using the COOL 2.1 software and implementing the new 2.1 schema.
+   *  Such a folder cannot be opened for reading or writing using the 2.0
+   *  software (its contents cannot be read or modified): only its generic 
+   *  properties (those retrieved from the node table) can be queried.
+   *
+   *  Within the COOL 2.2.2 software, this may also represent a handle
+   *  to a folder with schema version 2.0.0, that is no longer supported.
+   *
+   *  @author Andrea Valassi
+   *  @date   2007-01-09
+   */
+
+  class RelationalFolderUnsupported : virtual public IFolder,
+                                      virtual public RelationalHvsNode {
+    
+  public:
+
+    /// Ctor to create a RelationalFolderUnsupported from a node table row
+    /// Inlined with the base class non-standard constructors as otherwise 
+    /// the compiler attempts to use the base class standard constructors
+    /// (Windows compilation error C2248: standard constructors are private)
+    RelationalFolderUnsupported( const RelationalDatabasePtr& db,
+                                 const coral::AttributeList& row )
+      : RelationalHvsNodeRecord( row )
+      , RelationalHvsNode( db, row )   
+      , m_log
+      ( new coral::MessageStream( "RelationalFolderUnsupported" ) )
+      , m_publicFolderAttributes() // fill it in initialize
+    {
+      initialize( row );
+    }
+
+    /// Destructor.
+    virtual ~RelationalFolderUnsupported();
+
+    /// Return the 'attributes' of the folder
+    /// (implementation-specific properties not exposed in the API).
+    const IRecord& folderAttributes() const;
+
+  public:
+
+    // -- THE FOLLOWING METHODS ALL THROW --
+
+    /// Return the folder specification.
+    const IFolderSpecification& folderSpecification() const 
+    {
+      throw UnsupportedFolderSchema
+        ( fullPath(), schemaVersion(), "RelationalFolderUnsupported" );
+    };
+
+    /// Return the payload specification of the folder.
+    const IRecordSpecification& payloadSpecification() const
+    {
+      throw UnsupportedFolderSchema
+        ( fullPath(), schemaVersion(), "RelationalFolderUnsupported" );
+    };
+
+    /// Return the folder versioning mode.
+    FolderVersioning::Mode versioningMode() const
+    {
+      throw UnsupportedFolderSchema
+        ( fullPath(), schemaVersion(), "RelationalFolderUnsupported" );
+    };
+
+    /// Activate/deactivate a storage buffer for bulk insertion of objects.
+    /// If the buffer was used and is deactivated, flush the buffer.
+    void setupStorageBuffer( bool /*useBuffer*/ )
+    {
+      throw UnsupportedFolderSchema
+        ( fullPath(), schemaVersion(), "RelationalFolderUnsupported" );
+    };
+
+    /// Flush the storage buffer (execute the bulk insertion of objects).
+    /// If the buffer is not used, ignore this command.
+    void flushStorageBuffer()
+    {
+      throw UnsupportedFolderSchema
+        ( fullPath(), schemaVersion(), "RelationalFolderUnsupported" );
+    };
+
+    /// Store an object in a given channel with the given IOV and data payload.
+    void storeObject( const ValidityKey& /*since*/,
+                      const ValidityKey& /*until*/,
+                      const IRecord& /*payload*/,
+                      const ChannelId& /*channelId*/,
+                      const std::string& /*userTagName*/,
+                      bool /*userTagOnly*/ )
+    {
+      throw UnsupportedFolderSchema
+        ( fullPath(), schemaVersion(), "RelationalFolderUnsupported" );
+    };
+
+    /// DEPRECATED - added for easier compatibility with COOL 1.3
+    /// (this is likely to be removed in a future COOL release).
+    void storeObject( const ValidityKey& /*since*/,
+                      const ValidityKey& /*until*/,
+                      const coral::AttributeList& /*payload*/,
+                      const ChannelId& /*channelId*/,
+                      const std::string& /*userTagName = ""*/,
+                      bool /*userTagOnly*/ )
+    {
+      throw UnsupportedFolderSchema
+        ( fullPath(), schemaVersion(), "RelationalFolderUnsupported" );
+    };
+
+    /// Set a new finite end-of-validity value for all SV objects in a given 
+    /// channel selection whose end-of-validity is currently infinite.
+    int truncateObjectValidity( const ValidityKey& /*until*/,
+                                 const ChannelSelection& /*channels*/ )
+    {
+      throw UnsupportedFolderSchema
+        ( fullPath(), schemaVersion(), "RelationalFolderUnsupported" );
+    };
+
+    /// Find the ONE object in a given channel valid at the given point in time
+    /// in the given tag ("" and "HEAD" both indicate the folder HEAD).
+    IObjectPtr findObject( const ValidityKey& /*pointInTime*/,
+                           const ChannelId& /*channelId*/,
+                           const std::string& /*tagName*/ ) const
+    {
+      throw UnsupportedFolderSchema
+        ( fullPath(), schemaVersion(), "RelationalFolderUnsupported" );
+    };
+
+    /// Find the objects for a given channel selection at the given point
+    /// in time in the given tag ("" and "HEAD" both indicate the folder HEAD).
+    IObjectIteratorPtr findObjects( const ValidityKey& /*pointInTime*/,
+                                    const ChannelSelection& /*channels*/,
+                                    const std::string& /*tagName*/ ) const
+    {
+      throw UnsupportedFolderSchema
+        ( fullPath(), schemaVersion(), "RelationalFolderUnsupported" );
+    };
+
+    /// Browse the objects for a given channel selection within the given time
+    /// range in the given tag ("" and "HEAD" both indicate the folder HEAD).
+    IObjectIteratorPtr browseObjects( const ValidityKey& /*since*/,
+                                      const ValidityKey& /*until*/,
+                                      const ChannelSelection& /*channels*/,
+                                      const std::string& /*tagName*/,
+                                      const IRecordSelection* /*payloadQuery*/ ) const
+    {
+      throw UnsupportedFolderSchema
+        ( fullPath(), schemaVersion(), "RelationalFolderUnsupported" );
+    };
+
+    /// Rename a payload item
+    void renamePayload( const std::string& /*oldName*/,
+                        const std::string& /*newName*/ )
+    {
+      throw UnsupportedFolderSchema
+        ( fullPath(), schemaVersion(), "RelationalFolderUnsupported" );
+    };
+
+    /// Add new payload fields with the given names and storage types, 
+    /// setting their values for all existing IOVS to the given values.
+    void extendPayloadSpecification( const IRecord& /*record*/ )
+    {
+      throw UnsupportedFolderSchema
+        ( fullPath(), schemaVersion(), "RelationalFolderUnsupported" );
+    };
+
+    /// Count the number of objects that would be returned by the
+    /// browseObjects method for the same selection parameters.
+    unsigned int countObjects( const ValidityKey& /*since*/,
+                               const ValidityKey& /*until*/,
+                               const ChannelSelection& /*channels*/,
+                               const std::string& /*tagName = ""*/, 
+                               const IRecordSelection* /*payloadQuery = 0*/ ) const
+    {
+      throw UnsupportedFolderSchema
+        ( fullPath(), schemaVersion(), "RelationalFolderUnsupported" );
+    };
+
+    /// Change the object prefetch policy (default is prefetchAll=true).
+    void setPrefetchAll( bool /*prefetchAll*/ )
+    {
+      throw UnsupportedFolderSchema
+        ( fullPath(), schemaVersion(), "RelationalFolderUnsupported" );
+    };
+
+    /// Associates the objects that are the current HEAD
+    /// with the given tag name and tag description.
+    void tagCurrentHead( const std::string& /*tagName*/,
+                         const std::string& /*description = ""*/ ) const
+    {
+      throw UnsupportedFolderSchema
+        ( fullPath(), schemaVersion(), "RelationalFolderUnsupported" );
+    };
+    
+    /// Clones the tag "tagName" as user tag "tagClone" by reinserting 
+    /// the IOVs with the user tag. Does not modify the current head.
+    void cloneTagAsUserTag( const std::string& /*tagName*/, 
+                            const std::string& /*tagClone*/,
+                            const std::string& /*description = ""*/, 
+                            bool /*forceOverwrite = false*/)
+    {
+      throw UnsupportedFolderSchema
+        ( fullPath(), schemaVersion(), "RelationalFolderUnsupported" );
+    };
+    
+    /// Associates the objects that were the HEAD at 'asOfDate'
+    /// with the given tag name and tag description.
+    void tagHeadAsOfDate( const ITime& /*asOfDate*/,
+                          const std::string& /*tagName*/,
+                          const std::string& /*description = ""*/ ) const
+    {
+      throw UnsupportedFolderSchema
+        ( fullPath(), schemaVersion(), "RelationalFolderUnsupported" );
+    };
+
+    /// Insertion time of the last inserted IOV in a tag defined for this node.
+    const Time 
+    insertionTimeOfLastObjectInTag( const std::string& /*tagName*/ ) const
+    {
+      throw UnsupportedFolderSchema
+        ( fullPath(), schemaVersion(), "RelationalFolderUnsupported" );
+    };
+
+    /// Deletes a tag from this folder and from the global "tag namespace".
+    void deleteTag( const std::string& /*tagName*/ )
+    {
+      throw UnsupportedFolderSchema
+        ( fullPath(), schemaVersion(), "RelationalFolderUnsupported" );
+    };
+
+    /// Does this user tag exist?    
+    bool existsUserTag( const std::string& /*userTagName*/ ) const
+    {
+      throw UnsupportedFolderSchema
+        ( fullPath(), schemaVersion(), "RelationalFolderUnsupported" );
+    };
+
+    /// Return the list of existing channels (ordered by ascending channelId).
+    const std::vector<ChannelId> listChannels() const
+    {
+      throw UnsupportedFolderSchema
+        ( fullPath(), schemaVersion(), "RelationalFolderUnsupported" );
+    };
+
+    /// Return the map of id->name for all existing channels.
+    const std::map<ChannelId,std::string> listChannelsWithNames() const
+    {
+      throw UnsupportedFolderSchema
+        ( fullPath(), schemaVersion(), "RelationalFolderUnsupported" );
+    };
+
+    /// Create a new channel with the given id, name and description.
+    void createChannel( const ChannelId& /*channelId*/,
+                        const std::string& /*channelName*/,
+                        const std::string& /*description = ""*/ )
+    {
+      throw UnsupportedFolderSchema
+        ( fullPath(), schemaVersion(), "RelationalFolderUnsupported" );
+    };
+
+
+    /// Drop a channel with the given id
+    bool dropChannel( const ChannelId& /*channelId*/ )
+    {
+      throw UnsupportedFolderSchema
+        ( fullPath(), schemaVersion(), "RelationalFolderUnsupported" );
+    };
+
+
+    /// Set the name of a channel, given its id.
+    void setChannelName( const ChannelId& /*channelId*/,
+                         const std::string& /*channelName*/ )
+    {
+      throw UnsupportedFolderSchema
+        ( fullPath(), schemaVersion(), "RelationalFolderUnsupported" );
+    };
+    
+    /// Return the name of a channel, given its id.
+    const std::string channelName( const ChannelId& /*channelId*/ ) const
+    {
+      throw UnsupportedFolderSchema
+        ( fullPath(), schemaVersion(), "RelationalFolderUnsupported" );
+    };
+
+    /// Return the id of a channel, given its name.    
+    ChannelId channelId( const std::string& /*channelName*/ ) const
+    {
+      throw UnsupportedFolderSchema
+        ( fullPath(), schemaVersion(), "RelationalFolderUnsupported" );
+    };
+
+    /// Does a channel with this id exist?
+    bool existsChannel( const ChannelId& /*channelId*/ ) const
+    {
+      throw UnsupportedFolderSchema
+        ( fullPath(), schemaVersion(), "RelationalFolderUnsupported" );
+    };
+    
+    /// Does a channel with this name exist?    
+    bool existsChannel( const std::string& /*channelName*/ ) const
+    {
+      throw UnsupportedFolderSchema
+        ( fullPath(), schemaVersion(), "RelationalFolderUnsupported" );
+    };
+
+    /// Set the description of a channel, given its id.
+    void setChannelDescription( const ChannelId& /*channelId*/,
+                                        const std::string& /*description*/ )
+    {
+      throw UnsupportedFolderSchema
+        ( fullPath(), schemaVersion(), "RelationalFolderUnsupported" );
+    };
+    
+    /// Return the description of a channel, given its id.
+    const std::string 
+    channelDescription( const ChannelId& /*channelId*/ ) const
+    {
+      throw UnsupportedFolderSchema
+        ( fullPath(), schemaVersion(), "RelationalFolderUnsupported" );
+    };    
+    
+  private:
+
+    /// Initialize (complete non-standard constructor with non-inlined code)
+    void initialize( const coral::AttributeList& row );
+
+    /// Standard constructor is private
+    RelationalFolderUnsupported();
+
+    /// Copy constructor is private
+    RelationalFolderUnsupported( const RelationalFolderUnsupported& rhs );
+
+    /// Assignment operator is private
+    RelationalFolderUnsupported& 
+    operator=( const RelationalFolderUnsupported& rhs );
+
+  private:
+
+    /// Get a CORAL MessageStream
+    coral::MessageStream& log() const;
+
+    /// Folder attribute spec for the RelationalFolderUnsupported class
+    static const RecordSpecification& folderAttributesSpecification();
+
+  private:
+
+    /// CORAL MessageStream
+    std::auto_ptr<coral::MessageStream> m_log;
+
+    /// Public attributes of the folder
+    Record m_publicFolderAttributes;
+
+  };
+
+}
+
+#endif
+
diff --git a/RelationalCool/src/RelationalGlobalHeadTagTable.cpp b/RelationalCool/src/RelationalGlobalHeadTagTable.cpp
new file mode 100644
index 000000000..e44ef888c
--- /dev/null
+++ b/RelationalCool/src/RelationalGlobalHeadTagTable.cpp
@@ -0,0 +1,29 @@
+// $Id: RelationalGlobalHeadTagTable.cpp,v 1.1 2007-02-16 14:54:18 avalassi Exp $
+
+// Include files
+#include "CoolKernel/RecordSpecification.h"
+
+// Local include files
+#include "RelationalGlobalHeadTagTable.h"
+
+//-----------------------------------------------------------------------------
+
+const cool::IRecordSpecification&
+cool::RelationalGlobalHeadTagTable::tableSpecification() 
+{
+  static RecordSpecification spec;
+  
+  if ( spec.size() == 0 ) 
+  {
+    spec.extend( RelationalGlobalHeadTagTable::columnNames::nodeId,
+                 RelationalGlobalHeadTagTable::columnTypeIds::nodeId );
+    spec.extend( RelationalGlobalHeadTagTable::columnNames::tagId,
+                 RelationalGlobalHeadTagTable::columnTypeIds::tagId );
+    spec.extend( RelationalGlobalHeadTagTable::columnNames::tagType,
+                 RelationalGlobalHeadTagTable::columnTypeIds::tagType );
+  }
+  return spec;
+
+}
+
+//-----------------------------------------------------------------------------
diff --git a/RelationalCool/src/RelationalGlobalHeadTagTable.h b/RelationalCool/src/RelationalGlobalHeadTagTable.h
new file mode 100644
index 000000000..a2667081f
--- /dev/null
+++ b/RelationalCool/src/RelationalGlobalHeadTagTable.h
@@ -0,0 +1,61 @@
+// $Id: RelationalGlobalHeadTagTable.h,v 1.2 2007-02-16 14:59:48 avalassi Exp $
+#ifndef RELATIONALCOOL_RELATIONALGLOBALHEADTAGTABLE_H
+#define RELATIONALCOOL_RELATIONALGLOBALHEADTAGTABLE_H
+
+// Include files
+#include "CoolKernel/StorageType.h"
+
+// Local include files
+#include "uppercaseString.h"
+
+namespace cool {
+
+  // Forward declarations
+  class IRecordSpecification;
+
+  /** @namespace cool::RelationalGlobalHeadTagTable RelationalGlobalHeadTagTable.h
+   *
+   *  Relational schema of the table storing COOL global HEAD tags.
+   *
+   *  @author Andrea Valassi
+   *  @date   2007-02-15
+   */
+
+  namespace RelationalGlobalHeadTagTable {
+
+    inline const std::string defaultTableName( const std::string& prefix ) 
+    {
+      return uppercaseString(prefix) + "HEADTAGS";
+    }
+
+    namespace columnNames 
+    {
+      static const std::string nodeId  = "NODE_ID";
+      static const std::string tagId   = "TAG_ID";
+      // Tag type (NOT NULL): 0(unknown), 1(head), 2(user) 
+      // Tag type must be equal to 1 (CHECK constraint) for the head tag table
+      static const std::string tagType = "TAG_TYPE";
+    }
+
+    namespace columnTypeIds 
+    {
+      static const StorageType::TypeId nodeId  = StorageType::UInt32;
+      static const StorageType::TypeId tagId   = StorageType::UInt32;
+      static const StorageType::TypeId tagType = StorageType::UInt16;
+    }
+    
+    namespace columnTypes 
+    {
+      typedef UInt32 nodeId;
+      typedef UInt32 tagId;
+      typedef UInt16 tagType;
+    }
+
+    /// Get the record specification of the global user tag table
+    const IRecordSpecification& tableSpecification();
+
+  }
+
+}
+
+#endif // RELATIONALCOOL_RELATIONALGLOBALHEADTAGTABLE_H
diff --git a/RelationalCool/src/RelationalGlobalTagTable.cpp b/RelationalCool/src/RelationalGlobalTagTable.cpp
new file mode 100644
index 000000000..cc3be30e7
--- /dev/null
+++ b/RelationalCool/src/RelationalGlobalTagTable.cpp
@@ -0,0 +1,40 @@
+// $Id: RelationalGlobalTagTable.cpp,v 1.13 2007-02-16 16:53:29 avalassi Exp $
+
+// Include files
+#include "CoolKernel/RecordSpecification.h"
+
+// Local include files
+#include "RelationalGlobalTagTable.h"
+
+//-----------------------------------------------------------------------------
+
+const cool::IRecordSpecification&
+cool::RelationalGlobalTagTable::tableSpecification() 
+{
+  static RecordSpecification spec;
+  
+  if ( spec.size() == 0 ) {
+    spec.extend( RelationalGlobalTagTable::columnNames::nodeId,         
+                 RelationalGlobalTagTable::columnTypeIds::nodeId );
+    spec.extend( RelationalGlobalTagTable::columnNames::tagId,          
+                 RelationalGlobalTagTable::columnTypeIds::tagId );
+    spec.extend( RelationalGlobalTagTable::columnNames::tagName,        
+                 RelationalGlobalTagTable::columnTypeIds::tagName );
+    spec.extend( RelationalGlobalTagTable::columnNames::tagLockStatus, 
+                 RelationalGlobalTagTable::columnTypeIds::tagLockStatus );
+    spec.extend( RelationalGlobalTagTable::columnNames::tagDescription, 
+                 RelationalGlobalTagTable::columnTypeIds::tagDescription );
+    /*
+    // *** START *** 3.0.0 schema extensions (task #4396)
+    spec.extend( RelationalGlobalTagTable::columnNames::tagType,          
+                 RelationalGlobalTagTable::columnTypeIds::tagType );
+    // **** END **** 3.0.0 schema extensions (task #4396)
+    */
+    spec.extend( RelationalGlobalTagTable::columnNames::sysInsTime,     
+                 RelationalGlobalTagTable::columnTypeIds::sysInsTime );
+  }
+  return spec;
+
+}
+
+//-----------------------------------------------------------------------------
diff --git a/RelationalCool/src/RelationalGlobalTagTable.h b/RelationalCool/src/RelationalGlobalTagTable.h
new file mode 100644
index 000000000..cfe8242de
--- /dev/null
+++ b/RelationalCool/src/RelationalGlobalTagTable.h
@@ -0,0 +1,78 @@
+// $Id: RelationalGlobalTagTable.h,v 1.19 2007-02-16 16:06:23 avalassi Exp $
+#ifndef RELATIONALCOOL_RELATIONALGLOBALTAGTABLE_H
+#define RELATIONALCOOL_RELATIONALGLOBALTAGTABLE_H
+
+// Include files
+#include "CoolKernel/StorageType.h"
+
+// Local include files
+#include "uppercaseString.h"
+
+namespace cool {
+
+  // Forward declarations
+  class IRecordSpecification;
+
+  /** @namespace cool::RelationalGlobalTagTable RelationalGlobalTagTable.h
+   *
+   *  Relational schema of the table storing COOL global tags.
+   *
+   *  @author Andrea Valassi, Sven A. Schmidt and Marco Clemencic
+   *  @date   2005-03-01
+   */
+
+  namespace RelationalGlobalTagTable {
+
+    inline const std::string defaultTableName( const std::string& prefix ) 
+    {
+      return uppercaseString(prefix) + "TAGS";
+    }
+
+    namespace columnNames 
+    {
+      static const std::string nodeId = "NODE_ID";
+      static const std::string tagId = "TAG_ID";
+      static const std::string tagName = "TAG_NAME";
+      static const std::string tagLockStatus = "TAG_LOCK_STATUS";
+      static const std::string tagDescription = "TAG_DESCRIPTION";
+      // *** START *** 3.0.0 schema extensions (task #4396)
+      // Tag type (NOT NULL): 0(unknown), 1(head), 2(user) 
+      static const std::string tagType = "TAG_TYPE";
+      // **** END **** 3.0.0 schema extensions (task #4396)
+      static const std::string sysInsTime = "SYS_INSTIME";
+    }
+
+    namespace columnTypeIds 
+    {
+      static const StorageType::TypeId nodeId         = StorageType::UInt32;
+      static const StorageType::TypeId tagId          = StorageType::UInt32;
+      static const StorageType::TypeId tagName        = StorageType::String255;
+      static const StorageType::TypeId tagLockStatus  = StorageType::UInt16;
+      static const StorageType::TypeId tagDescription = StorageType::String255;
+      // *** START *** 3.0.0 schema extensions (task #4396)
+      static const StorageType::TypeId tagType        = StorageType::UInt16;
+      // **** END **** 3.0.0 schema extensions (task #4396)
+      static const StorageType::TypeId sysInsTime     = StorageType::String255;
+    }
+    
+    namespace columnTypes 
+    {
+      typedef UInt32 nodeId;
+      typedef UInt32 tagId;
+      typedef String255 tagName;
+      typedef UInt16 tagLockStatus;
+      typedef String255 tagDescription;
+      // *** START *** 3.0.0 schema extensions (task #4396)
+      typedef UInt16 tagType;
+      // **** END **** 3.0.0 schema extensions (task #4396)
+      typedef String255 sysInsTime;
+    }
+
+    /// Get the record specification of the global tag table
+    const IRecordSpecification& tableSpecification();
+
+  }
+
+}
+
+#endif // RELATIONALCOOL_RELATIONALGLOBALTAGTABLE_H
diff --git a/RelationalCool/src/RelationalGlobalUserTagTable.cpp b/RelationalCool/src/RelationalGlobalUserTagTable.cpp
new file mode 100644
index 000000000..97bd08068
--- /dev/null
+++ b/RelationalCool/src/RelationalGlobalUserTagTable.cpp
@@ -0,0 +1,29 @@
+// $Id: RelationalGlobalUserTagTable.cpp,v 1.2 2007-02-16 14:54:18 avalassi Exp $
+
+// Include files
+#include "CoolKernel/RecordSpecification.h"
+
+// Local include files
+#include "RelationalGlobalUserTagTable.h"
+
+//-----------------------------------------------------------------------------
+
+const cool::IRecordSpecification&
+cool::RelationalGlobalUserTagTable::tableSpecification() 
+{
+  static RecordSpecification spec;
+  
+  if ( spec.size() == 0 ) 
+  {
+    spec.extend( RelationalGlobalUserTagTable::columnNames::nodeId,
+                 RelationalGlobalUserTagTable::columnTypeIds::nodeId );
+    spec.extend( RelationalGlobalUserTagTable::columnNames::tagId,
+                 RelationalGlobalUserTagTable::columnTypeIds::tagId );
+    spec.extend( RelationalGlobalUserTagTable::columnNames::tagType,
+                 RelationalGlobalUserTagTable::columnTypeIds::tagType );
+  }
+  return spec;
+
+}
+
+//-----------------------------------------------------------------------------
diff --git a/RelationalCool/src/RelationalGlobalUserTagTable.h b/RelationalCool/src/RelationalGlobalUserTagTable.h
new file mode 100644
index 000000000..7a6e20cfe
--- /dev/null
+++ b/RelationalCool/src/RelationalGlobalUserTagTable.h
@@ -0,0 +1,61 @@
+// $Id: RelationalGlobalUserTagTable.h,v 1.4 2007-02-16 14:59:48 avalassi Exp $
+#ifndef RELATIONALCOOL_RELATIONALGLOBALUSERTAGTABLE_H
+#define RELATIONALCOOL_RELATIONALGLOBALUSERTAGTABLE_H
+
+// Include files
+#include "CoolKernel/StorageType.h"
+
+// Local include files
+#include "uppercaseString.h"
+
+namespace cool {
+
+  // Forward declarations
+  class IRecordSpecification;
+
+  /** @namespace cool::RelationalGlobalUserTagTable RelationalGlobalUserTagTable.h
+   *
+   *  Relational schema of the table storing COOL global user tags.
+   *
+   *  @author Andrea Valassi
+   *  @date   2007-02-15
+   */
+
+  namespace RelationalGlobalUserTagTable {
+
+    inline const std::string defaultTableName( const std::string& prefix ) 
+    {
+      return uppercaseString(prefix) + "USERTAGS";
+    }
+
+    namespace columnNames 
+    {
+      static const std::string nodeId  = "NODE_ID";
+      static const std::string tagId   = "TAG_ID";
+      // Tag type (NOT NULL): 0(unknown), 1(head), 2(user) 
+      // Tag type must be equal to 2 (CHECK constraint) for the user tag table
+      static const std::string tagType = "TAG_TYPE";
+    }
+
+    namespace columnTypeIds 
+    {
+      static const StorageType::TypeId nodeId  = StorageType::UInt32;
+      static const StorageType::TypeId tagId   = StorageType::UInt32;
+      static const StorageType::TypeId tagType = StorageType::UInt16;
+    }
+    
+    namespace columnTypes 
+    {
+      typedef UInt32 nodeId;
+      typedef UInt32 tagId;
+      typedef UInt16 tagType;
+    }
+
+    /// Get the record specification of the global user tag table
+    const IRecordSpecification& tableSpecification();
+
+  }
+
+}
+
+#endif // RELATIONALCOOL_RELATIONALGLOBALUSERTAGTABLE_H
diff --git a/RelationalCool/src/RelationalHvsNode.cpp b/RelationalCool/src/RelationalHvsNode.cpp
new file mode 100644
index 000000000..9673244ca
--- /dev/null
+++ b/RelationalCool/src/RelationalHvsNode.cpp
@@ -0,0 +1,170 @@
+// $Id: RelationalHvsNode.cpp,v 1.35 2008-11-04 11:52:11 avalassi Exp $
+
+// Include files
+//#include "CoolKernel/HvsTagRecord.h"
+#include "HvsTagRecord.h"
+#include "CoralBase/Attribute.h"
+
+// Local include files
+//#include "IRelationalTransactionMgr.h"
+#include "RelationalDatabase.h"
+#include "RelationalGlobalTagTable.h"
+#include "RelationalHvsNode.h"
+#include "RelationalTableRow.h"
+#include "RelationalTagMgr.h"
+#include "RelationalTransaction.h"
+
+// Namespace
+using namespace cool;
+
+//-----------------------------------------------------------------------------
+
+RelationalHvsNode::RelationalHvsNode
+( const RelationalDatabasePtr& db,
+  const coral::AttributeList& nodeTableRow )
+  : RelationalHvsNodeRecord( nodeTableRow )
+  , m_db( db ) 
+{
+}    
+
+//-----------------------------------------------------------------------------
+
+RelationalHvsNode::~RelationalHvsNode()
+{
+}
+
+//-----------------------------------------------------------------------------
+
+void RelationalHvsNode::setDescription( const std::string& description ) 
+{
+  db().updateNodeTableDescription( fullPath(), description );
+  RelationalHvsNodeRecord::setDescription( description );
+}
+
+//-----------------------------------------------------------------------------
+
+const std::vector<std::string> RelationalHvsNode::listTags() const
+{
+  //return db().listTags( this );
+  if ( ! db().isOpen() ) throw DatabaseNotOpen( "RalDatabase" );
+  std::vector<std::string> tags;
+  RelationalTransaction transaction( db().transactionMgr(), true ); // r/o
+  std::vector<RelationalTableRow> rows = 
+    db().tagMgr().fetchGlobalTagTableRows( id() );
+  for ( std::vector<RelationalTableRow>::const_iterator
+          row = rows.begin(); row != rows.end(); ++row ) {
+    std::string tagName =
+      (*row)[RelationalGlobalTagTable::columnNames::tagName]
+      .data<std::string>();
+    tags.push_back( tagName );
+  }  
+  transaction.commit();
+  return tags;
+}
+    
+//-----------------------------------------------------------------------------
+
+const Time 
+RelationalHvsNode::tagInsertionTime( const std::string& tagName ) const
+{
+  return db().tagMgr().tagInsertionTime( this, tagName );
+}
+    
+//-----------------------------------------------------------------------------
+
+void
+RelationalHvsNode::setTagDescription( const std::string& tagName,
+                                      const std::string& description )
+{
+  return db().tagMgr().setTagDescription( this, tagName, description );
+}
+
+//-----------------------------------------------------------------------------
+
+const std::string 
+RelationalHvsNode::tagDescription( const std::string& tagName ) const
+{
+  return db().tagMgr().tagDescription( this, tagName );
+}
+
+//-----------------------------------------------------------------------------
+
+void 
+RelationalHvsNode::setTagLockStatus( const std::string& tagName,
+                                     HvsTagLock::Status tagLockStatus )
+{
+  return db().tagMgr().setTagLockStatus( this, tagName, tagLockStatus );
+}
+
+//-----------------------------------------------------------------------------
+
+HvsTagLock::Status
+RelationalHvsNode::tagLockStatus( const std::string& tagName ) const
+{
+  return db().tagMgr().tagLockStatus( this, tagName );
+}
+
+//-----------------------------------------------------------------------------
+
+void 
+RelationalHvsNode::createTagRelation( const std::string& parentTagName,
+                                      const std::string& tagName ) const
+{
+  if ( ! db().isOpen() ) throw DatabaseNotOpen( "RelationalHvsNode" );
+  RelationalTransaction transaction( db().transactionMgr(), false ); // r/w
+  db().tagMgr().createTagRelation( parentId(), parentTagName, id(), tagName );
+  transaction.commit();
+}
+
+//-----------------------------------------------------------------------------
+
+void 
+RelationalHvsNode::deleteTagRelation( const std::string& parentTagName ) const
+{
+  if ( ! db().isOpen() ) throw DatabaseNotOpen( "RelationalHvsNode" );
+  RelationalTransaction transaction( db().transactionMgr(), false ); // r/w
+  // TEMPORARY - START
+  //db().tagMgr().deleteTagRelation( parentId(), parentTagName, id() );
+  db().tagMgr().deleteTagRelation( *this, parentTagName );
+  // TEMPORARY - END
+  transaction.commit();
+}
+
+//-----------------------------------------------------------------------------
+
+const std::string
+RelationalHvsNode::findTagRelation( const std::string& parentTagName ) const
+{
+  if ( ! db().isOpen() ) throw DatabaseNotOpen( "RelationalHvsNode" );
+  RelationalTransaction transaction( db().transactionMgr(), true ); // r/o
+  UInt32 tagId = 
+    db().tagMgr().findTagRelation( parentId(), parentTagName, id() );
+  std::string tag = db().tagMgr().__findTagRecord( id(), tagId ).name();  
+  transaction.commit();
+  return tag;
+}
+
+//-----------------------------------------------------------------------------
+
+const std::string
+RelationalHvsNode::resolveTag( const std::string& ancestorTagName ) const
+{
+  if ( ! db().isOpen() ) throw DatabaseNotOpen( "RelationalHvsNode" );
+  RelationalTransaction transaction( db().transactionMgr(), true ); // r/o
+  UInt32 tagId = 
+    db().tagMgr().resolveTag( ancestorTagName, id() );
+  std::string tag = db().tagMgr().__findTagRecord( id(), tagId ).name();  
+  transaction.commit();
+  return tag;
+}
+
+//-----------------------------------------------------------------------------
+/*
+bool
+RelationalHvsNode::isTagUsed( UInt32 tagId ) const
+{
+  // Is the tag referenced in the TAG2TAG table?
+  return db().tagMgr().existsTagInTag2TagTable( id(), tagId );
+}
+*/
+//-----------------------------------------------------------------------------
diff --git a/RelationalCool/src/RelationalHvsNode.h b/RelationalCool/src/RelationalHvsNode.h
new file mode 100644
index 000000000..3dd401df2
--- /dev/null
+++ b/RelationalCool/src/RelationalHvsNode.h
@@ -0,0 +1,156 @@
+// $Id: RelationalHvsNode.h,v 1.30 2008-11-04 11:52:11 avalassi Exp $
+#ifndef RELATIONALCOOL_RELATIONALHVSNODE_H
+#define RELATIONALCOOL_RELATIONALHVSNODE_H
+
+// Disable warning C4250 on Windows (inheritance via dominance)
+// Copied from SEAL (Dictionary/Reflection/src/Tools.h)
+#ifdef WIN32
+#pragma warning ( disable : 4250 )
+#endif
+
+// Include files
+#include "CoolKernel/IHvsNode.h"
+
+// Local include files
+#include "RelationalDatabasePtr.h"
+#include "RelationalHvsNodeRecord.h"
+
+namespace cool {
+
+  /** @class RelationalHvsNode RelationalHvsNode.h
+   *
+   *  Relational implementation of one node in an HVS node tree.
+   *  Multiple virtual inheritance from IHvsNode and RelationalHvsNodeRecord
+   *  (diamond virtual inheritance of IHvsNodeRecord abstract interface).
+   *
+   *  @author Andrea Valassi and Sven A. Schmidt
+   *  @date   2004-12-10
+   */
+
+  class RelationalHvsNode : virtual public IHvsNode,
+                            virtual public RelationalHvsNodeRecord {
+
+  public:
+
+    /// Destructor
+    virtual ~RelationalHvsNode();
+
+    /// Set the node description
+    void setDescription( const std::string& description );
+    
+    /// Lists all tags defined for this node (ordered alphabetically)
+    const std::vector<std::string> listTags() const;
+    
+    /// Insertion time of a tag defined for this node
+    /// (i.e. the time when the tag was first assigned to this node)
+    const Time tagInsertionTime( const std::string& tagName ) const;
+    
+    /// Set the description of a tag.
+    /// Throws TagNotFound the tag does not exist.
+    /// Throws an Exception if the description is longer than 255 characters.
+    void setTagDescription( const std::string& tagName,
+                            const std::string& description );
+    
+    /// Description of a tag defined for this node
+    const std::string tagDescription( const std::string& tagName ) const;
+
+    /// Set the persistent lock status of a tag defined for this node.
+    void setTagLockStatus( const std::string& tagName,
+                           HvsTagLock::Status tagLockStatus );
+
+    /// Get the persistent lock status of a tag defined for this node.
+    HvsTagLock::Status tagLockStatus( const std::string& tagName ) const;
+
+    /// Create a relation between a parent node tag and a tag in this node.
+    /// Create the parent node tag if not defined yet.
+    /// Create the tag in this node if not defined yet.
+    /// Throws ReservedHeadTag if one of the two tags is a HEAD tag.
+    /// Throws NodeIsSingleVersion if either node does not support versioning.
+    /// Throws TagExists if either tag is already used in another node.
+    /// Throws TagRelationExists if a relation to a child tag already exists.
+    void createTagRelation( const std::string& parentTagName,
+                            const std::string& tagName ) const;
+
+    /// Delete the relation between a parent tag node and a tag in this node.
+    /// Delete the parent tag if not related to another parent/child tag.
+    /// Delete the tag in this node if not related to another tag or IOVs.
+    /// Throws TagNotFound if the parent tag does not exist in the parent node.
+    /// Throws TagRelationNotFound if the parent tag has no related child tag.
+    void deleteTagRelation( const std::string& parentTagName ) const;
+
+    /// Show the tag in this node associated to the given parent node tag.
+    /// Throws ReservedHeadTag if the parent tag is a HEAD tag.
+    /// Throws TagNotFound if the parent tag does not exist in the parent node.
+    /// Throws TagRelationNotFound if the parent tag has no related child tag.
+    const std::string 
+    findTagRelation( const std::string& parentTagName ) const;
+
+    /// Main HVS method: determine the tag in this node that is related to the
+    /// given ancestor tag (assumed to be defined in an ancestor of this node).
+    /// The corresponding ancestor node is also internally determined.
+    /// The ancestor tag is returned if defined directly in the descendant.
+    /// Throws ReservedHeadTag if the ancestor tag is a HEAD tag.
+    /// Throws TagNotFound if the tag does not exist in any inner node.
+    /// Throws NodeRelationNotFound if the inner node where the ancestor tag 
+    /// is defined is not an ancestor of the descendant node.
+    /// Throws TagRelationNotFound if no hierarchical tag relation exists.
+    const std::string resolveTag( const std::string& ancestorTagName ) const;
+
+    /*
+    /// Does this tag exist in this node (independently of whether
+    /// it references a parent tag or is referenced by any children)?
+    /// Throws ReservedHeadTag if this is the HEAD tag.
+    bool existsTag( const std::string& tagName ) const;
+
+    /// Does this tag defined in this node have any relation (i.e. does 
+    /// it reference a parent tag or is it referenced by any children)?
+    /// Throws ReservedHeadTag if this is the HEAD tag.
+    /// Throws TagNotFound if this tag does not exist in this node.
+    bool isTagUsed( const std::string& tagName ) const;
+    */
+
+    /*
+    /// Does this tag defined in this node have any relation (i.e. does 
+    /// it reference a parent tag or is it referenced by any children)?
+    /// Returns false if this tag does not exist in this node.
+    bool isTagUsed( UInt32 tagId ) const;
+    */
+
+    /// Get a RelationalDatabase reference
+    const RelationalDatabase& db() const { return *m_db; }
+
+  protected:
+
+    /// Constructor from a relational row retrieved from persistent storage
+    /// This constructor is protected, hence no need to inline with base class
+    /// non-standard constructors to prevent Windows compilation error C2248
+    RelationalHvsNode( const RelationalDatabasePtr& db,
+                       const coral::AttributeList& nodeTableRow );
+
+    /*
+    /// Constructor from a RelationalHvsNodeRecord
+    RelationalHvsNode( const RelationalDatabasePtr& db,
+                       const RelationalHvsNodeRecord& nodeRecord );
+    */
+    
+  private:
+
+    /// Standard constructor is private
+    RelationalHvsNode();
+
+    /// Copy constructor is private
+    RelationalHvsNode( const RelationalHvsNode& rhs );
+
+    /// Assignment operator is private
+    RelationalHvsNode& operator=( const RelationalHvsNode& rhs );
+
+  private:
+
+    /// Backward pointer to the parent RelationalDatabase
+    RelationalDatabasePtr m_db;
+    
+  };
+
+}
+
+#endif // RELATIONALCOOL_RELATIONALHVSNODE_H
diff --git a/RelationalCool/src/RelationalHvsNodeRecord.cpp b/RelationalCool/src/RelationalHvsNodeRecord.cpp
new file mode 100644
index 000000000..a2e8b7148
--- /dev/null
+++ b/RelationalCool/src/RelationalHvsNodeRecord.cpp
@@ -0,0 +1,116 @@
+// $Id: RelationalHvsNodeRecord.cpp,v 1.6 2008-11-04 11:52:11 avalassi Exp $
+
+// Include files
+#include "CoralBase/Attribute.h"
+
+// Local include files
+#include "HvsPathHandler.h"
+#include "RelationalHvsNodeRecord.h"
+#include "RelationalNodeTable.h"
+#include "timeToString.h"
+
+// Namespace
+using namespace cool;
+
+//-----------------------------------------------------------------------------
+
+RelationalHvsNodeRecord::RelationalHvsNodeRecord
+( const coral::AttributeList& row )
+  : m_schemaVersion( row[RelationalNodeTable::columnNames::nodeSchemaVersion]
+                     .data<std::string>() )
+  , m_nodeAttributes()
+{
+  // TODO: use COOL typedefs instead of explicit <T> like <std::string>...
+
+  m_id = row[RelationalNodeTable::columnNames::nodeId]
+    .data<unsigned int>();
+
+  m_fullPath = row[RelationalNodeTable::columnNames::nodeFullPath]
+    .data<std::string>();
+
+  // TEMPORARY! CHECK IF nodeId==0 TO ASSUME ROOT FOLDER SET
+  // EVENTUALLY: fetch METHODS SHOULD RETURN LIST OF NULL ATTRIBUTES
+  HvsPathHandler handler;
+  if( m_fullPath == handler.rootFullPath() ) {
+    m_parentId = m_id;
+  } else {
+    m_parentId = row[RelationalNodeTable::columnNames::nodeParentId]
+      .data<unsigned int>();
+  }
+
+  m_description = row[RelationalNodeTable::columnNames::nodeDescription]
+    .data<std::string>();
+
+  m_isLeaf = row[RelationalNodeTable::columnNames::nodeIsLeaf]
+    .data<bool>();
+
+  // No default constructor for VersionNumber
+  //m_schemaVersion = row[RelationalNodeTable::columnNames::nodeSchemaVersion]
+  //  .data<std::string>();
+
+  std::string time = row[RelationalNodeTable::columnNames::nodeInsertionTime]
+    .data<std::string>();
+  m_insertionTime = stringToTime( time );
+}
+
+//-----------------------------------------------------------------------------
+
+const std::string& RelationalHvsNodeRecord::fullPath() const 
+{
+  return m_fullPath;
+}
+
+//-----------------------------------------------------------------------------
+
+const std::string& RelationalHvsNodeRecord::description() const 
+{
+  return m_description;
+}
+
+//-----------------------------------------------------------------------------
+
+bool RelationalHvsNodeRecord::isLeaf() const 
+{
+  return m_isLeaf;
+}
+
+//-----------------------------------------------------------------------------
+
+const VersionNumber& RelationalHvsNodeRecord::schemaVersion() const 
+{
+  return m_schemaVersion;
+}
+
+//-----------------------------------------------------------------------------
+
+const ITime& RelationalHvsNodeRecord::insertionTime() const 
+{
+  return m_insertionTime;
+}
+
+//-----------------------------------------------------------------------------
+
+unsigned int RelationalHvsNodeRecord::id() const 
+{
+  return m_id;
+}
+
+//-----------------------------------------------------------------------------
+
+unsigned int RelationalHvsNodeRecord::parentId() const 
+{
+  return m_parentId;
+}
+
+//-----------------------------------------------------------------------------
+
+const IRecord& RelationalHvsNodeRecord::nodeAttributes() const
+{
+  /// Avoid link time error: 'liblcg_RelationalCool.so: undefined reference to 
+  /// `virtual thunk to cool::RelationalHvsNodeRecord::nodeAttributes() const'
+  ///return (const IRecord&)m_nodeAttributes;
+  const Record& attr = m_nodeAttributes;
+  return attr;
+}
+
+//-----------------------------------------------------------------------------
diff --git a/RelationalCool/src/RelationalHvsNodeRecord.h b/RelationalCool/src/RelationalHvsNodeRecord.h
new file mode 100644
index 000000000..9f3b1fe6d
--- /dev/null
+++ b/RelationalCool/src/RelationalHvsNodeRecord.h
@@ -0,0 +1,115 @@
+// $Id: RelationalHvsNodeRecord.h,v 1.7 2008-11-04 11:52:11 avalassi Exp $
+#ifndef RELATIONALCOOL_RELATIONALHVSNODERECORD_H
+#define RELATIONALCOOL_RELATIONALHVSNODERECORD_H
+
+// Include files
+#include "CoolKernel/Record.h"
+#include "CoolKernel/Time.h"
+#include "CoolKernel/IHvsNodeRecord.h"
+
+// Local include files
+#include "VersionNumber.h"
+
+namespace cool {
+
+  /** @class RelationalHvsNodeRecord RelationalHvsNodeRecord.h
+   *
+   *  Relational read-only implementation of one node in an HVS node tree.
+   *
+   *  @author Andrea Valassi and Sven A. Schmidt
+   *  @date   2004-12-10
+   */
+
+  class RelationalHvsNodeRecord : virtual public IHvsNodeRecord {
+
+  public:
+
+    /// Destructor
+    virtual ~RelationalHvsNodeRecord() {}
+
+    /// Node full path name in the HVS hierarchy
+    /// (this is always unique within a database)
+    const std::string& fullPath() const;
+    
+    /// Node description
+    const std::string& description() const;
+    
+    /// Is this a leaf node?
+    bool isLeaf() const;
+
+    /// Has this node been stored into the database?
+    bool isStored() const { return true; }
+
+    /// Schema version for this node
+    const VersionNumber& schemaVersion() const;
+
+    /// Insertion time into the database
+    /// Throws an exception if the node has not been stored yet
+    const ITime& insertionTime() const;
+
+    /// System-assigned node ID
+    /// Throws an exception if the node has not been stored yet
+    unsigned int id() const;
+
+    /// System-assigned ID of the parent node
+    /// Throws an exception if the node has not been stored yet
+    /// Convention: parentId() = id() if the node has no parent (root node)
+    unsigned int parentId() const;
+
+  protected:
+
+    /// Return additional 'attributes' of the HVS node 
+    /// (implementation-specific attributes not exposed in the API)
+    const IRecord& nodeAttributes() const;
+
+    /// Constructor from a relational row retrieved from persistent storage
+    RelationalHvsNodeRecord( const coral::AttributeList& nodeTableRow );
+    
+    /// Change the node description
+    void setDescription( const std::string& description ) 
+    {
+      m_description = description;
+    }
+
+  private:
+
+    /// Standard constructor is private
+    RelationalHvsNodeRecord();
+
+    /// Copy constructor is private
+    RelationalHvsNodeRecord( const RelationalHvsNodeRecord& rhs );
+
+    /// Assignment operator is private
+    RelationalHvsNodeRecord& operator=( const RelationalHvsNodeRecord& rhs );
+
+  private:
+
+    /// System-assigned node ID
+    unsigned int m_id;
+
+    /// System-assigned ID of the parent node
+    unsigned int m_parentId;
+
+    /// Node full path name in the HVS hierarchy
+    std::string m_fullPath;
+    
+    /// Node description
+    std::string m_description;
+    
+    /// Is this a leaf node?
+    bool m_isLeaf;
+
+    /// Schema version for this node
+    VersionNumber m_schemaVersion;
+
+    /// Insertion time into the database
+    Time m_insertionTime;
+
+    /// Additional implementation-specific 'attributes' of the HVS node
+    Record m_nodeAttributes;
+    
+  };
+
+}
+
+#endif // RELATIONALCOOL_RELATIONALHVSNODERECORD_H
diff --git a/RelationalCool/src/RelationalHvsTagRecord.cpp b/RelationalCool/src/RelationalHvsTagRecord.cpp
new file mode 100644
index 000000000..d65f1d721
--- /dev/null
+++ b/RelationalCool/src/RelationalHvsTagRecord.cpp
@@ -0,0 +1,93 @@
+// $Id: RelationalHvsTagRecord.cpp,v 1.12 2007-03-20 19:03:43 avalassi Exp $
+
+// Include files
+#include "CoralBase/Attribute.h"
+#include "CoralBase/AttributeList.h"
+
+// Local include files
+#include "RelationalHvsTagRecord.h"
+#include "RelationalGlobalTagTable.h"
+#include "timeToString.h"
+
+// TEMPORARY - debug unknown exception on Windows
+//#include <iostream>
+
+// Namespace
+using namespace cool;
+
+//-----------------------------------------------------------------------------
+
+const HvsTagRecord 
+RelationalHvsTagRecord::fromRow( const coral::AttributeList& row )
+{
+  //std::cout << "*** RelationalHvsTagRecord::fromRow - START" << std::endl;
+
+  try {
+
+    //std::cout << "*** Windows will throw UNKNOWN exception?" << std::endl;
+    // AV - The following line throws an unknown exception on Windows
+    // [only if fromRow is called from the RelationalHvsTagRecord constructor]
+    //std::cout << "*** RelationalHvsTagRecord::fromRow - input AL size: " 
+    //          << row.size() << std::endl;
+    //std::cout << "*** Windows has thrown UNKNOWN exception?" << std::endl;
+
+    //std::stringstream msg;
+    //row.toOutputStream( msg );
+    
+    //std::cout << "*** RelationalHvsTagRecord::fromRow - input AL: " 
+    //          << msg.str() << std::endl;
+
+    UInt32 id = 
+      row[RelationalGlobalTagTable::columnNames::tagId].data<UInt32>();
+    
+    UInt32 nodeId = 
+      row[RelationalGlobalTagTable::columnNames::nodeId].data<UInt32>();
+    
+    std::string name = 
+      row[RelationalGlobalTagTable::columnNames::tagName].data<std::string>();
+    
+    HvsTagLock::Status lockStatus = 
+      HvsTagLock::Status
+      ( row[RelationalGlobalTagTable::columnNames::tagLockStatus]
+        .data<UInt16>() );
+    
+    std::string description = 
+      row[RelationalGlobalTagTable::columnNames::tagDescription]
+      .data<std::string>();
+    
+    std::string time = 
+      row[RelationalGlobalTagTable::columnNames::sysInsTime]
+      .data<std::string>();
+    Time insertionTime = stringToTime( time );
+    
+    //std::cout << "*** RelationalHvsTagRecord::fromRow - END" << std::endl;
+
+    return HvsTagRecord
+      ( id, nodeId, name, lockStatus, description, insertionTime );
+
+  } catch ( std::exception& /*e*/ ) {
+    //std::cout << "*** PANIC! RelationalHvsTagRecord::fromRow - "
+    //          << "Exception caught: " << e.what() << std::endl;
+    throw;
+  } catch ( ... ) {
+    std::cout << "*** PANIC! RelationalHvsTagRecord::fromRow - "
+              << "UNKNOWN exception caught" << std::endl;
+    throw;
+  }
+}
+
+//-----------------------------------------------------------------------------
+/*
+const coral::AttributeList& RelationalHvsTagRecord::tagAttributes() const 
+{
+  return m_tagAttributes;
+}
+*/
+//-----------------------------------------------------------------------------
+/*
+void RelationalHvsTagRecord::setDescription( const std::string& description )
+{
+  m_description = description;
+}
+*/
+//-----------------------------------------------------------------------------
diff --git a/RelationalCool/src/RelationalHvsTagRecord.h b/RelationalCool/src/RelationalHvsTagRecord.h
new file mode 100644
index 000000000..5bdebd439
--- /dev/null
+++ b/RelationalCool/src/RelationalHvsTagRecord.h
@@ -0,0 +1,79 @@
+// $Id: RelationalHvsTagRecord.h,v 1.14 2007-07-05 11:50:02 avalassi Exp $
+#ifndef RELATIONALCOOL_RELATIONALHVSTAGRECORD_H
+#define RELATIONALCOOL_RELATIONALHVSTAGRECORD_H
+
+// Include files
+//#include "CoolKernel/HvsTagRecord.h"
+#include "HvsTagRecord.h"
+
+namespace cool {
+
+  /** @class RelationalHvsTagRecord RelationalHvsTagRecord.h
+   *
+   *  Relational read-only implementation of one tag in an HVS tag tree
+   *  (i.e. transient representation of one row in the HVS tag table).
+   *
+   *  @author Andrea Valassi
+   *  @date   2006-03-07
+   */
+
+  class RelationalHvsTagRecord : public HvsTagRecord {
+
+  public:
+
+    /// Reinterpret a relational row retrieved from persistent storage
+    static const HvsTagRecord fromRow( const coral::AttributeList& tableRow );
+
+    /// Destructor
+    virtual ~RelationalHvsTagRecord() {}
+
+    /// AV - This throws an unknown exception within fromRow on Windows
+    /// [as soon as the tableRow AL argument is accessed within fromRow]
+    /// Constructor from a relational row retrieved from persistent storage
+    /*
+    RelationalHvsTagRecord( const coral::AttributeList& tableRow )
+      : HvsTagRecord( fromRow( tableRow ) ) {}
+    */
+
+    /// Copy constructor
+    /// AV - Added IHvsTagRecord to avoid gcc344 warning on copy constructor
+    /// AV - To be tested: would this solve the unknown Windows exception???
+    RelationalHvsTagRecord( const RelationalHvsTagRecord& rhs )
+      : HvsTagRecord( rhs ) {}
+    
+    /// AV - The following is a workaround (WHY???)
+    /// Constructor from an HvsTagRecord
+    RelationalHvsTagRecord( const HvsTagRecord& rhs )
+      : HvsTagRecord( rhs ) {}
+    
+    /*
+    /// Return additional 'attributes' of the HVS tag 
+    /// (implementation-specific attributes not exposed in the API)
+    const coral::AttributeList& tagAttributes() const;
+    */
+
+    /*
+    /// Change the tag description (transient - no persistent change!)
+    void setDescription( const std::string& description );
+    */
+
+  private:
+
+    /// Standard constructor is private
+    RelationalHvsTagRecord();
+
+    /// Assignment operator is private
+    RelationalHvsTagRecord& operator=( const RelationalHvsTagRecord& rhs );
+
+  private:
+
+    /*
+    /// Additional implementation-specific 'attributes' of the HVS tag
+    coral::AttributeList m_tagAttributes;
+    */
+    
+  };
+
+}
+
+#endif // RELATIONALCOOL_RELATIONALHVSTAGRECORD_H
diff --git a/RelationalCool/src/RelationalIovSharedSequenceTable.h b/RelationalCool/src/RelationalIovSharedSequenceTable.h
new file mode 100644
index 000000000..704486797
--- /dev/null
+++ b/RelationalCool/src/RelationalIovSharedSequenceTable.h
@@ -0,0 +1,30 @@
+// $Id: RelationalIovSharedSequenceTable.h,v 1.1 2007-02-01 00:28:33 avalassi Exp $
+#ifndef RELATIONALCOOL_RELATIONALIOVSHAREDSEQUENCETABLE_H
+#define RELATIONALCOOL_RELATIONALIOVSHAREDSEQUENCETABLE_H
+
+// Local include files
+#include "uppercaseString.h"
+
+namespace cool {  
+  
+  /** @namespace cool::RelationalIovSharedSequenceTable RelationalIovSharedSequenceTable.h
+   *  
+   *  Relational schema of the shared 'sequence table' for IOV PKs.
+   *
+   *  @author Andrea Valassi
+   *  @date   2007-01-31
+   */
+  
+  namespace RelationalIovSharedSequenceTable 
+  {
+    
+    inline const std::string defaultTableName( const std::string& prefix ) 
+    {
+      // Note: presently the input prefix is uppercase anyway...
+      return uppercaseString(prefix) + "IOVS_SEQ";
+    }
+
+  }
+  
+}
+#endif // RELATIONALCOOL_RELATIONALIOVSHAREDSEQUENCETABLE_H
diff --git a/RelationalCool/src/RelationalIovTablesTable.cpp b/RelationalCool/src/RelationalIovTablesTable.cpp
new file mode 100644
index 000000000..da7dbf0e2
--- /dev/null
+++ b/RelationalCool/src/RelationalIovTablesTable.cpp
@@ -0,0 +1,44 @@
+// $Id: RelationalIovTablesTable.cpp,v 1.1 2007-02-15 14:37:43 avalassi Exp $
+
+// Include files
+#include "CoolKernel/RecordSpecification.h"
+
+// Local include files
+#include "RelationalIovTablesTable.h"
+
+//-----------------------------------------------------------------------------
+
+const cool::IRecordSpecification&
+cool::RelationalIovTablesTable::tableSpecification() 
+{
+  static RecordSpecification spec;
+  
+  if ( spec.size() == 0 ) 
+  {
+    spec.extend
+      ( RelationalIovTablesTable::columnNames::iovTableName,
+        RelationalIovTablesTable::columnTypeIds::iovTableName );
+    spec.extend
+      ( RelationalIovTablesTable::columnNames::iovTableSchemaVersion,
+        RelationalIovTablesTable::columnTypeIds::iovTableSchemaVersion );  
+    spec.extend
+      ( RelationalIovTablesTable::columnNames::iovTableVersioningMode,
+        RelationalIovTablesTable::columnTypeIds::iovTableVersioningMode );
+    spec.extend
+      ( RelationalIovTablesTable::columnNames::iovTableInsertionTime,
+        RelationalIovTablesTable::columnTypeIds::iovTableInsertionTime );  
+    spec.extend
+      ( RelationalIovTablesTable::columnNames::payloadSpecDesc,
+        RelationalIovTablesTable::columnTypeIds::payloadSpecDesc );
+    spec.extend
+      ( RelationalIovTablesTable::columnNames::payloadInline,
+        RelationalIovTablesTable::columnTypeIds::payloadInline );
+    spec.extend
+      ( RelationalIovTablesTable::columnNames::payloadExtRef,
+        RelationalIovTablesTable::columnTypeIds::payloadExtRef );
+  }
+  return spec;
+
+}
+
+//-----------------------------------------------------------------------------
diff --git a/RelationalCool/src/RelationalIovTablesTable.h b/RelationalCool/src/RelationalIovTablesTable.h
new file mode 100644
index 000000000..bc8f2648c
--- /dev/null
+++ b/RelationalCool/src/RelationalIovTablesTable.h
@@ -0,0 +1,87 @@
+// $Id: RelationalIovTablesTable.h,v 1.1 2007-02-15 14:37:43 avalassi Exp $
+#ifndef RELATIONALCOOL_RELATIONALIOVTABLESTABLE_H 
+#define RELATIONALCOOL_RELATIONALIOVTABLESTABLE_H 1
+
+// Include files
+#include "CoolKernel/StorageType.h"
+
+// Local include files
+#include "VersionNumber.h"
+#include "uppercaseString.h"
+
+namespace cool 
+{
+
+  // Forward declarations
+  class IRecordSpecification;
+
+  /** @namespace cool::RelationalIovTablesTable RelationalIovTablesTable.h
+   *  
+   *  Relational schema of the table storing metadata of COOL IOV tables.
+   *
+   *  @author Andrea Valassi
+   *  @date   2007-02-15
+   */
+
+  namespace RelationalIovTablesTable {
+
+    inline const std::string defaultTableName( const std::string& prefix ) 
+    {
+      return uppercaseString(prefix) + "IOVTABLES";
+    }    
+
+    namespace columnNames 
+    {
+      static const 
+      std::string iovTableName = "IOVTABLE_NAME";
+      static const 
+      std::string iovTableSchemaVersion = "IOVTABLE_SCHEMA_VERSION";
+      static const 
+      std::string iovTableVersioningMode = "IOVTABLE_VERSIONING";
+      static const 
+      std::string iovTableInsertionTime = "IOVTABLE_INSTIME";
+      static const 
+      std::string payloadSpecDesc = "PAYLOAD_SPEC";
+      static const 
+      std::string payloadInline = "PAYLOAD_INLINE";
+      static const 
+      std::string payloadExtRef = "PAYLOAD_EXTREF";
+    }
+
+    namespace columnTypeIds 
+    {
+      static const 
+      StorageType::TypeId iovTableName = StorageType::String255;
+      static const 
+      StorageType::TypeId iovTableSchemaVersion = StorageType::String255;
+      static const 
+      StorageType::TypeId iovTableVersioningMode = StorageType::Int32;
+      static const 
+      StorageType::TypeId iovTableInsertionTime = StorageType::String255;
+      static const 
+      StorageType::TypeId payloadSpecDesc = StorageType::String64k;
+      static const 
+      StorageType::TypeId payloadInline = StorageType::UInt16;
+      static const 
+      StorageType::TypeId payloadExtRef = StorageType::String64k;
+    }
+
+    namespace columnTypes 
+    {
+      typedef String255 iovTableName;
+      typedef String255 iovTableSchemaVersion;
+      typedef Int32     iovTableVersioningMode;
+      typedef String255 iovTableInsertionTime;
+      typedef String64k payloadSpecDesc;
+      typedef UInt16    payloadInline;
+      typedef String64k payloadExtRef;
+    }
+    
+    /// Get the record specification of the iovTables table.
+    const IRecordSpecification& tableSpecification();
+     
+  }
+
+}
+
+#endif // RELATIONALCOOL_RELATIONALIOVTABLESTABLE_H
diff --git a/RelationalCool/src/RelationalNodeMgr.cpp b/RelationalCool/src/RelationalNodeMgr.cpp
new file mode 100644
index 000000000..b99899b71
--- /dev/null
+++ b/RelationalCool/src/RelationalNodeMgr.cpp
@@ -0,0 +1,324 @@
+// $Id: RelationalNodeMgr.cpp,v 1.22 2008-11-04 11:52:11 avalassi Exp $
+
+// Include files
+#include "CoralBase/Attribute.h"
+#include "CoolKernel/Record.h"
+#include "CoolKernel/RecordSpecification.h"
+
+// Local include files
+#include "RelationalDatabase.h"
+#include "RelationalException.h"
+#include "RelationalNodeMgr.h"
+#include "RelationalNodeTable.h"
+#include "RelationalQueryMgr.h"
+#include "RelationalTableRow.h"
+#include "RelationalTransaction.h"
+
+// Namespace
+using namespace cool;
+
+//-----------------------------------------------------------------------------
+
+RelationalNodeMgr::RelationalNodeMgr( const RelationalDatabase& aDb )
+  : m_db( aDb )
+  , m_log( new coral::MessageStream( "RelationalNodeMgr" ) )
+{
+  log() << coral::Debug << "Instantiate a RelationalNodeMgr" 
+        << coral::MessageStream::endmsg;
+}
+
+//-----------------------------------------------------------------------------
+
+RelationalNodeMgr::~RelationalNodeMgr()
+{
+  log() << coral::Debug << "Delete the RelationalNodeMgr" << coral::MessageStream::endmsg;
+}
+
+//-----------------------------------------------------------------------------
+
+RelationalQueryMgr& RelationalNodeMgr::queryMgr() const
+{
+  return db().queryMgr();
+}
+
+//-----------------------------------------------------------------------------
+
+bool RelationalNodeMgr::existsNode( const std::string& fullPath )
+{
+  // Transaction handled in the outer scope
+  try {
+    fetchNodeTableRow( fullPath );
+    return true;
+  } catch ( NodeTableRowNotFound& ) {
+    return false;
+  }
+}
+
+//-----------------------------------------------------------------------------
+
+bool RelationalNodeMgr::existsFolderSet( const std::string& fullPath )
+{
+  // Cross-check that the database is open
+  if ( ! db().isOpen() ) throw DatabaseNotOpen( "RelationalTagMgr" );
+
+  try {
+    RelationalTransaction transaction( db().transactionMgr(), true ); // r/o
+    RelationalTableRow row = fetchNodeTableRow( fullPath );
+    bool isLeaf =
+      row[RelationalNodeTable::columnNames::nodeIsLeaf].data<bool>();
+    transaction.commit();
+    return (!isLeaf);
+  } catch ( NodeTableRowNotFound& ) {
+    return false;
+  }
+}
+
+//-----------------------------------------------------------------------------
+
+bool RelationalNodeMgr::existsFolder( const std::string& fullPath )
+{
+  // Cross-check that the database is open
+  if ( ! db().isOpen() ) throw DatabaseNotOpen( "RelationalTagMgr" );
+
+  try {
+    RelationalTransaction transaction( db().transactionMgr(), true ); // r/o
+    RelationalTableRow row = fetchNodeTableRow( fullPath );
+    bool isLeaf =
+      row[RelationalNodeTable::columnNames::nodeIsLeaf].data<bool>();
+    transaction.commit();
+    return isLeaf;
+  } catch ( NodeTableRowNotFound& ) {
+    return false;
+  }
+}
+
+//-----------------------------------------------------------------------------
+
+const std::vector<std::string> 
+RelationalNodeMgr::listNodes( unsigned int nodeId, 
+                              bool isLeaf, 
+                              bool ascending ) 
+{
+  // Transaction handled in the outer scope
+  // Cross-check that the database is open
+  if ( ! db().isOpen() ) throw DatabaseNotOpen( "RelationalDatabase" );
+
+  // Define the WHERE clause for the selection using bind variables
+  // NB: Oracle execution plan -- still to be tested
+  RecordSpecification spec;
+  spec.extend("parentId", RelationalNodeTable::columnTypeIds::nodeParentId);
+  spec.extend("isLeaf", RelationalNodeTable::columnTypeIds::nodeIsLeaf);
+  coral::AttributeList whereData = Record( spec ).attributeList();
+  whereData["parentId"].setValue( nodeId );
+  whereData["isLeaf"].setValue( isLeaf );
+  std::string whereClause = RelationalNodeTable::columnNames::nodeParentId;
+  whereClause += "= :parentId";
+  whereClause += " and ";
+  whereClause += RelationalNodeTable::columnNames::nodeIsLeaf;
+  whereClause += "= :isLeaf";
+
+  /// Define the ORDER BY clause for the selection
+  std::vector<std::string> orderBy;
+  std::string orderClause = RelationalNodeTable::columnNames::nodeFullPath;
+  if ( ascending ) orderClause += " ASC";
+  else orderClause += " DESC";
+  orderBy.push_back( orderClause );
+
+  // Delegate the query to the RalQueryMgr
+  std::string desc = "";
+  std::vector<RelationalTableRow> rows =
+    queryMgr().fetchOrderedRowsFromTables
+    ( RelationalQueryMgr::tableList( db().nodeTableName() ), 
+      RelationalQueryMgr::columnList
+      ( RelationalNodeTable::tableSpecification() ),
+      whereClause, whereData, orderBy, desc );
+
+  // Loop over all rows and copy folder names into a string vector
+  std::vector<std::string> folderList;
+  for ( std::vector<RelationalTableRow>::const_iterator
+          row = rows.begin(); row != rows.end(); ++row ) {
+    std::string fullPath =
+      (*row)[RelationalNodeTable::columnNames::nodeFullPath]
+      .data<std::string>();
+    folderList.push_back( fullPath );
+  }
+  return folderList;
+}
+
+//-----------------------------------------------------------------------------
+
+const std::vector<std::string>
+RelationalNodeMgr::listAllNodes( bool ascending ) 
+{
+  // Loop over all rows and copy folder names into a string vector
+  std::vector<RelationalTableRow> rows =
+    fetchAllNodeTableRows( ascending );
+  std::vector<std::string> folderList;
+  for ( std::vector<RelationalTableRow>::const_iterator
+          row = rows.begin(); row != rows.end(); ++row ) {
+    std::string fullPath =
+      (*row)[RelationalNodeTable::columnNames::nodeFullPath]
+      .data<std::string>();
+    folderList.push_back( fullPath );
+  }
+
+  // Return the list of folders
+  return folderList;
+}
+
+//-----------------------------------------------------------------------------
+
+const std::vector<RelationalTableRow> 
+RelationalNodeMgr::fetchAllNodeTableRows( bool ascending ) const
+{
+  log() << "Fetch all nodes in the database" << coral::MessageStream::endmsg;
+
+  // Transaction handled in the outer scope
+  // Cross-check that the database is open
+  if ( ! db().isOpen() ) throw DatabaseNotOpen( "RelationalDatabase" );
+
+  // Define the WHERE clause for the selection - empty!
+  coral::AttributeList whereData;
+  std::string whereClause = "";
+
+  // Define the ORDER BY clause for the selection
+  // NB: Oracle execution plan, from interactive Benthic test, uses
+  // => ASCENDING: fast access via the 1D primary key index on nodeId
+  // (SELECT STATEMENT, TABLE ACCESS BY INDEX ROWID, INDEX FULL SCAN)
+  // => DESCENDING: ?
+  // NB: the above applies to previous ordering by nodeId
+  std::vector<std::string> orderBy;
+  std::string orderClause = RelationalNodeTable::columnNames::nodeFullPath;
+  if ( ascending ) orderClause += " ASC";
+  else orderClause += " DESC";
+  orderBy.push_back( orderClause );
+
+  // Delegate the query to the RalQueryMgr
+  std::string desc = "";
+  std::vector<RelationalTableRow> rows =
+    queryMgr().fetchOrderedRowsFromTables
+    ( RelationalQueryMgr::tableList( db().nodeTableName() ), 
+      RelationalQueryMgr::columnList
+      ( RelationalNodeTable::tableSpecification() ),
+      whereClause, whereData, orderBy, desc );
+
+  // Return the list of folders
+  return rows;
+}
+
+//-----------------------------------------------------------------------------
+
+const RelationalTableRow 
+RelationalNodeMgr::fetchNodeTableRow( const std::string& fullPath ) const
+{
+  log() << "Fetch table row for folder[set] with fullPath="
+        << fullPath << coral::MessageStream::endmsg;
+
+  // Define the WHERE clause for the selection using bind variables
+  // NB: Oracle execution plan, from interactive Benthic test, uses
+  // fast access via the 1D index on fullPath
+  // (SELECT STATEMENT, TABLE ACCESS BY INDEX ROWID, INDEX RANGE SCAN)
+  coral::AttributeList whereData;
+  whereData.extend
+    ( "fullName", 
+      typeIdToCoralType(RelationalNodeTable::columnTypeIds::nodeFullPath) );
+  whereData["fullName"].setValue( fullPath );
+  std::string whereClause = RelationalNodeTable::columnNames::nodeFullPath;
+  whereClause += "= :fullName";
+
+  // Execute the query
+  try {
+    return fetchNodeTableRow( whereClause, whereData );
+  } catch( NodeTableRowNotFound& /* dummy */ ) {
+    throw NodeTableRowNotFound( fullPath, "RelationalNodeMgr" );
+  }
+}
+
+//-----------------------------------------------------------------------------
+
+const RelationalTableRow 
+RelationalNodeMgr::fetchNodeTableRow( unsigned int nodeId ) const
+{
+  log() << "Fetch table row for folder[set] with nodeId="
+        << nodeId << coral::MessageStream::endmsg;
+
+  // Define the WHERE clause for the selection using bind variables
+  // NB: Oracle execution plan -- still to be tested
+  coral::AttributeList whereData;
+  whereData.extend
+    ( "nodeId", typeIdToCoralType(RelationalNodeTable::columnTypeIds::nodeId) );
+  whereData["nodeId"].setValue( nodeId );
+  std::string whereClause = RelationalNodeTable::columnNames::nodeId;
+  whereClause += "= :nodeId";
+
+  // Execute the query
+  try {
+    return fetchNodeTableRow( whereClause, whereData );
+  } catch( NodeTableRowNotFound& /* dummy */ ) {
+    throw NodeTableRowNotFound( nodeId, "RelationalNodeMgr" );
+  }
+}
+
+//-----------------------------------------------------------------------------
+
+const RelationalTableRow 
+RelationalNodeMgr::fetchNodeTableRow
+( const std::string& whereClause,
+  const coral::AttributeList& whereData ) const
+{
+  try {
+    std::string desc = "";
+    return queryMgr().fetchRowFromTables
+      ( RelationalQueryMgr::tableList( db().nodeTableName() ), 
+        RelationalQueryMgr::columnList
+        ( RelationalNodeTable::tableSpecification() ),
+        whereClause, whereData, desc );
+  } catch( NoRowsFound& ) {
+    throw NodeTableRowNotFound( "RelationalNodeMgr" );
+  }
+}
+
+//-----------------------------------------------------------------------------
+
+const std::vector<UInt32> 
+RelationalNodeMgr::resolveNodeHierarchy( UInt32 ancestorNodeId,
+                                         UInt32 descendantNodeId ) const
+{
+  log() << "Find all descendants of node #" << ancestorNodeId 
+        << " until node #" << descendantNodeId << " included" << coral::MessageStream::endmsg;
+  if ( ancestorNodeId == descendantNodeId )
+    throw NodeRelationNotFound
+      ( ancestorNodeId, descendantNodeId, "RelationalNodeMgr" );
+  std::vector<UInt32> nodes;
+  UInt32 nodeId = descendantNodeId;
+  while ( true ) {
+    RelationalTableRow row = fetchNodeTableRow( nodeId );
+    UInt32 parentId = 
+      row[RelationalNodeTable::columnNames::nodeParentId].data<UInt32>();
+    if ( parentId == nodeId ) 
+    {
+      // End of the loop: root node - node hierarchy not resolved
+      throw NodeRelationNotFound
+        ( ancestorNodeId, descendantNodeId, "RelationalNodeMgr" );
+    }
+    else if ( parentId == ancestorNodeId ) 
+    {
+      // End of the loop: ancestor found - node hierarchy resolved
+      std::vector<UInt32> revNodes; 
+      for ( std::vector<UInt32>::reverse_iterator
+              node = nodes.rbegin(); node != nodes.rend(); ++node )
+        revNodes.push_back( *node );
+      revNodes. push_back( descendantNodeId );
+      return revNodes;
+    }    
+    else 
+    {
+      // Continue the loop
+      nodes.push_back( parentId );
+      nodeId = parentId;
+    }    
+  }
+}
+
+//-----------------------------------------------------------------------------
+
diff --git a/RelationalCool/src/RelationalNodeMgr.h b/RelationalCool/src/RelationalNodeMgr.h
new file mode 100644
index 000000000..67acc1bfa
--- /dev/null
+++ b/RelationalCool/src/RelationalNodeMgr.h
@@ -0,0 +1,114 @@
+// $Id: RelationalNodeMgr.h,v 1.21 2008-11-04 11:52:11 avalassi Exp $
+#ifndef RELATIONALCOOL_RELATIONALNODEMGR_H
+#define RELATIONALCOOL_RELATIONALNODEMGR_H
+
+// Include files
+#include <memory>
+#include "CoolKernel/types.h"
+#include "CoralBase/AttributeList.h"
+#include "CoralBase/MessageStream.h"
+
+namespace cool {  
+  
+  // Forward declarations
+  class RelationalDatabase;
+  class RelationalQueryMgr;
+  class RelationalTableRow;
+
+  /** @class RelationalNodeMgr RelationalNodeMgr.h
+   *  
+   *  Abstract base class for a manager of a hierarchy 
+   *  of conditions database nodes stored in a relational database.
+   * 
+   *  @author Andrea Valassi and Marco Clemencic
+   *  @date   2006-03-02
+  */
+  
+  class RelationalNodeMgr {
+    
+  public:
+
+    /// Destructor
+    virtual ~RelationalNodeMgr();
+
+    /// Constructor from a RelationalDatabase reference
+    RelationalNodeMgr( const RelationalDatabase& db );
+
+    /// Does this node exist?
+    bool existsNode( const std::string& fullPath );
+
+    /// Does this folder set exist?
+    bool existsFolderSet( const std::string& folderSetName );
+
+    /// Does this folder exist?
+    bool existsFolder( const std::string& folderSetName );
+
+    /// Return the list of existing nodes (ordered alphabetically
+    /// ascending/descending)
+    const std::vector<std::string> listAllNodes( bool ascending = true );
+
+    /// Return the list of nodes inside the given nodeId with the attribute
+    /// isLeaf as specified (ordered by name asc/desc)
+    const std::vector<std::string> listNodes( unsigned int nodeId,
+                                              bool isLeaf,
+                                              bool ascending = true );
+
+    /// Fetch all node rows
+    const std::vector<RelationalTableRow>
+    fetchAllNodeTableRows( bool ascending = true ) const;
+
+    /// Fetch one node row (lookup by 1 node fullPath)
+    const RelationalTableRow 
+    fetchNodeTableRow( const std::string& fullPath ) const;
+
+    /// Fetch one node row (lookup by 1 nodeId)
+    const RelationalTableRow 
+    fetchNodeTableRow( unsigned int nodeId ) const;
+
+    /// Fetch one node row (lookup with given WHERE clause and bind variables)
+    const RelationalTableRow 
+    fetchNodeTableRow( const std::string& whereClause,
+                       const coral::AttributeList& whereData ) const;
+
+    /// List all nodes in the hierarchy line between ancestor and descendant 
+    /// (ordered from the ancestor's child to the descendant itself included)
+    const std::vector<UInt32> 
+    resolveNodeHierarchy( UInt32 ancestorNodeId,
+                          UInt32 descendantNodeId ) const;
+
+  protected:
+
+    /// Get the RelationalDatabase reference
+    const RelationalDatabase& db() const { return m_db; }
+
+    /// Get a CORAL MessageStream
+    coral::MessageStream& log() const { return *m_log; }
+
+    /// Get a relational query manager
+    RelationalQueryMgr& queryMgr() const;
+
+  private:
+
+    /// Standard constructor is private
+    RelationalNodeMgr();
+
+    /// Copy constructor is private
+    RelationalNodeMgr( const RelationalNodeMgr& rhs );
+
+    /// Assignment operator is private
+    RelationalNodeMgr& operator=( const RelationalNodeMgr& rhs );
+
+  protected:
+
+    /// Reference to the RelationalDatabase
+    const RelationalDatabase& m_db;
+
+    /// CORAL MessageStream
+    std::auto_ptr<coral::MessageStream> m_log;
+
+  };
+  
+}
+
+#endif // RELATIONALCOOL_RELATIONALNODEMGR_H
+
diff --git a/RelationalCool/src/RelationalNodeTable.cpp b/RelationalCool/src/RelationalNodeTable.cpp
new file mode 100644
index 000000000..270d154cf
--- /dev/null
+++ b/RelationalCool/src/RelationalNodeTable.cpp
@@ -0,0 +1,114 @@
+// $Id: RelationalNodeTable.cpp,v 1.30 2008-11-04 11:52:11 avalassi Exp $
+
+// Include files
+#include <map>
+#include "CoolKernel/RecordSpecification.h"
+
+// Local include files
+#include "RelationalNodeTable.h"
+#include "RelationalException.h"
+#include "VersionInfo.h"
+
+//-----------------------------------------------------------------------------
+
+const cool::IRecordSpecification&
+cool::RelationalNodeTable::tableSpecification( bool isLeaf,
+                                               bool hasParent )
+{
+  return tableSpecification
+    ( VersionInfo::schemaVersion, isLeaf, hasParent );
+}
+
+//-----------------------------------------------------------------------------
+
+const cool::IRecordSpecification&
+cool::RelationalNodeTable::tableSpecification
+( const VersionNumber& dbSchemaVersion,
+  bool isLeaf,
+  bool hasParent )
+{
+  static std::map< VersionNumber, RecordSpecification> specs_leaf;
+  static std::map< VersionNumber, RecordSpecification> specs_inner;
+  static std::map< VersionNumber, RecordSpecification> specs_inner_noparent;
+  
+  // Consistency check: the only node with no parent is a folder set
+  if ( !hasParent && isLeaf ) {
+    std::string msg = "Invalid arguments to tableSpecification";
+    msg += ": a folder always has parents";    
+    throw RelationalException( msg, "RelationalNodeTable" );
+  }  
+
+  std::map< VersionNumber, RecordSpecification>& specs =
+    isLeaf ? specs_leaf : ( hasParent ? specs_inner : specs_inner_noparent );
+
+  RecordSpecification& spec = specs[dbSchemaVersion];
+  if ( spec.size() == 0 ) 
+  {
+    // Default columns for both folder sets and folders
+    spec.extend( RelationalNodeTable::columnNames::nodeId,
+                 RelationalNodeTable::columnTypeIds::nodeId );
+    if ( hasParent )
+      spec.extend( RelationalNodeTable::columnNames::nodeParentId,
+                   RelationalNodeTable::columnTypeIds::nodeParentId );
+    spec.extend( RelationalNodeTable::columnNames::nodeName,
+                 RelationalNodeTable::columnTypeIds::nodeName );  
+    spec.extend( RelationalNodeTable::columnNames::nodeFullPath,
+                 RelationalNodeTable::columnTypeIds::nodeFullPath );  
+    spec.extend( RelationalNodeTable::columnNames::nodeDescription,
+                 RelationalNodeTable::columnTypeIds::nodeDescription );  
+    spec.extend( RelationalNodeTable::columnNames::nodeIsLeaf,
+                 RelationalNodeTable::columnTypeIds::nodeIsLeaf );  
+    if ( dbSchemaVersion >= VersionNumber( "2.0.0" ) )
+      spec.extend( RelationalNodeTable::columnNames::nodeSchemaVersion,
+                   RelationalNodeTable::columnTypeIds::nodeSchemaVersion );  
+    spec.extend( RelationalNodeTable::columnNames::nodeInsertionTime,
+                 RelationalNodeTable::columnTypeIds::nodeInsertionTime );  
+    if ( dbSchemaVersion >= VersionNumber( "2.0.0" ) )
+      spec.extend( RelationalNodeTable::columnNames::lastModDate,
+                   RelationalNodeTable::columnTypeIds::lastModDate );  
+    spec.extend
+      ( RelationalNodeTable::columnNames::folderVersioningMode,
+        RelationalNodeTable::columnTypeIds::folderVersioningMode );
+    
+    // Default columns for folders only
+    if ( isLeaf ) 
+    {
+      spec.extend
+        ( RelationalNodeTable::columnNames::folderPayloadSpecDesc,
+          RelationalNodeTable::columnTypeIds::folderPayloadSpecDesc );
+      if ( dbSchemaVersion >= VersionNumber( "2.0.0" ) ) 
+      {
+        spec.extend
+          ( RelationalNodeTable::columnNames::folderPayloadInline,
+            RelationalNodeTable::columnTypeIds::folderPayloadInline );
+        spec.extend
+          ( RelationalNodeTable::columnNames::folderPayloadExtRef,
+            RelationalNodeTable::columnTypeIds::folderPayloadExtRef );
+        spec.extend
+          ( RelationalNodeTable::columnNames::folderChannelSpecDesc,
+            RelationalNodeTable::columnTypeIds::folderChannelSpecDesc );
+        spec.extend
+          ( RelationalNodeTable::columnNames::folderChannelExtRef,
+            RelationalNodeTable::columnTypeIds::folderChannelExtRef );
+      }
+      spec.extend
+        ( RelationalNodeTable::columnNames::folderObjectTableName,
+          RelationalNodeTable::columnTypeIds::folderObjectTableName );
+      spec.extend
+        ( RelationalNodeTable::columnNames::folderTagTableName,
+          RelationalNodeTable::columnTypeIds::folderTagTableName );
+      spec.extend
+        ( RelationalNodeTable::columnNames::folderObject2TagTableName,
+          RelationalNodeTable::columnTypeIds::folderObject2TagTableName );
+      if ( dbSchemaVersion >= VersionNumber( "2.0.0" ) )
+        spec.extend
+          ( RelationalNodeTable::columnNames::folderChannelTableName,
+            RelationalNodeTable::columnTypeIds::folderChannelTableName );
+    }
+  }
+
+  return spec;
+  
+}
+
+//-----------------------------------------------------------------------------
diff --git a/RelationalCool/src/RelationalNodeTable.h b/RelationalCool/src/RelationalNodeTable.h
new file mode 100644
index 000000000..75684639a
--- /dev/null
+++ b/RelationalCool/src/RelationalNodeTable.h
@@ -0,0 +1,172 @@
+// $Id: RelationalNodeTable.h,v 1.38 2008-11-04 11:52:11 avalassi Exp $
+#ifndef RELATIONALCOOL_RELATIONALNODETABLE_H 
+#define RELATIONALCOOL_RELATIONALNODETABLE_H 1
+
+// Include files
+#include "CoolKernel/StorageType.h"
+
+// Local include files
+#include "VersionNumber.h"
+#include "uppercaseString.h"
+
+namespace cool 
+{
+
+  // Forward declarations
+  class IRecordSpecification;
+
+  /** @namespace cool::RelationalNodeTable RelationalNodeTable.h
+   *  
+   *  Relational schema of the table storing COOL HVS "nodes"
+   *  (conditions database "folders" and "folder sets").
+   *
+   *  @author Andrea Valassi, Sven A. Schmidt and Marco Clemencic
+   *  @date   2004-12-16
+   */
+
+  namespace RelationalNodeTable {
+
+    inline const std::string defaultTableName( const std::string& prefix ) 
+    {
+      // TEMPORARY? AV 04.04.2005 
+      // FIXME: presently the input prefix is uppercase anyway...
+      return uppercaseString(prefix) + "NODES";
+    }    
+
+    inline const std::string sequenceName( const std::string& tableName ) 
+    {
+      // TEMPORARY? AV 04.04.2005 
+      // FIXME: presently the input table name is uppercase anyway...
+      return uppercaseString(tableName) + "_SEQ";
+    }    
+
+    namespace columnNames 
+    {
+      static const 
+      std::string nodeId = "NODE_ID";    
+      static const 
+      std::string nodeParentId = "NODE_PARENTID";    
+      static const 
+      std::string nodeName = "NODE_NAME";    
+      static const 
+      std::string nodeFullPath = "NODE_FULLPATH";    
+      static const 
+      std::string nodeDescription = "NODE_DESCRIPTION";
+      static const 
+      std::string nodeIsLeaf = "NODE_ISLEAF";    
+      static const 
+      std::string nodeSchemaVersion = "NODE_SCHEMA_VERSION";    
+      static const 
+      std::string nodeInsertionTime = "NODE_INSTIME";    
+      static const 
+      std::string lastModDate = "LASTMOD_DATE";    
+      static const 
+      std::string folderPayloadSpecDesc = "FOLDER_PAYLOADSPEC";
+      static const 
+      std::string folderPayloadInline = "FOLDER_PAYLOAD_INLINE";
+      static const 
+      std::string folderPayloadExtRef = "FOLDER_PAYLOAD_EXTREF"; 
+      static const 
+      std::string folderChannelSpecDesc = "FOLDER_CHANNELSPEC";
+      static const 
+      std::string folderChannelExtRef = "FOLDER_CHANNEL_EXTREF";
+      static const 
+      std::string folderVersioningMode = "FOLDER_VERSIONING";    
+      static const 
+      std::string folderObjectTableName = "FOLDER_IOVTABLENAME";
+      static const 
+      std::string folderTagTableName = "FOLDER_TAGTABLENAME";
+      static const 
+      std::string folderObject2TagTableName = "FOLDER_IOV2TAGTABLENAME";
+      static const 
+      std::string folderChannelTableName = "FOLDER_CHANNELTABLENAME";
+    }
+
+    namespace columnTypeIds 
+    {
+      static const 
+      StorageType::TypeId nodeId                    = StorageType::UInt32;
+      static const
+      StorageType::TypeId nodeParentId              = StorageType::UInt32;
+      static const 
+      StorageType::TypeId nodeName                  = StorageType::String255;
+      static const 
+      StorageType::TypeId nodeFullPath              = StorageType::String255;
+      static const 
+      StorageType::TypeId nodeDescription           = StorageType::String255;
+      static const 
+      StorageType::TypeId nodeIsLeaf                = StorageType::Bool;
+      static const 
+      StorageType::TypeId nodeSchemaVersion         = StorageType::String255;
+      static const 
+      StorageType::TypeId nodeInsertionTime         = StorageType::String255;
+      static const 
+      StorageType::TypeId lastModDate               = StorageType::String255;
+      static const 
+      StorageType::TypeId folderPayloadSpecDesc     = StorageType::String64k;
+      static const 
+      StorageType::TypeId folderPayloadInline       = StorageType::UInt16;
+      static const 
+      StorageType::TypeId folderPayloadExtRef       = StorageType::String64k;
+      static const 
+      StorageType::TypeId folderChannelSpecDesc     = StorageType::String64k;
+      static const 
+      StorageType::TypeId folderChannelExtRef       = StorageType::String64k;
+      static const 
+      StorageType::TypeId folderVersioningMode      = StorageType::Int32;
+      static const 
+      StorageType::TypeId folderObjectTableName     = StorageType::String255;
+      static const 
+      StorageType::TypeId folderTagTableName        = StorageType::String255;
+      static const 
+      StorageType::TypeId folderObject2TagTableName = StorageType::String255;
+      static const 
+      StorageType::TypeId folderChannelTableName    = StorageType::String255;
+    }
+
+    namespace columnTypes 
+    {
+      typedef UInt32    nodeId;
+      typedef UInt32    nodeParentId;
+      typedef String255 nodeName;
+      typedef String255 nodeFullPath;
+      typedef String255 nodeDescription;
+      typedef Bool      nodeIsLeaf;
+      typedef String255 nodeSchemaVersion;
+      typedef String255 nodeInsertionTime;
+      typedef String255 lastModDate;
+      typedef String64k folderPayloadSpecDesc;
+      typedef UInt16    folderPayloadInline;
+      typedef String64k folderPayloadExtRef;
+      typedef String64k folderChannelSpecDesc;
+      typedef String64k folderChannelExtRef;
+      typedef Int32     folderVersioningMode;
+      typedef String255 folderObjectTableName;
+      typedef String255 folderTagTableName;
+      typedef String255 folderObject2TagTableName;
+      typedef String255 folderChannelTableName;
+    }
+    
+    /// Get the record specification of the folder table for a given
+    /// COOL release (this is needed by the schema evolution tools).
+    /// Folder-specific columns that are not relevant for folder sets
+    /// are included by default unless the isLeaf flag is set to false.
+    /// The parentId column may be excluded for the root folder set.
+    const IRecordSpecification& 
+    tableSpecification( const VersionNumber& dbSchemaVersion,
+                        bool isLeaf = true,
+                        bool hasParents = true );
+    
+    /// Get the record specification of the folder table for this COOL release.
+    /// Folder-specific columns that are not relevant for folder sets
+    /// are included by default unless the isLeaf flag is set to false.
+    /// The parentId column may be excluded for the root folder set.
+    const IRecordSpecification& 
+    tableSpecification( bool isLeaf = true,
+                        bool hasParents = true );
+    
+  }
+
+}
+
+#endif // RELATIONALCOOL_RELATIONALNODETABLE_H
diff --git a/RelationalCool/src/RelationalObject.cpp b/RelationalCool/src/RelationalObject.cpp
new file mode 100644
index 000000000..59a9b9c04
--- /dev/null
+++ b/RelationalCool/src/RelationalObject.cpp
@@ -0,0 +1,284 @@
+// $Id: RelationalObject.cpp,v 1.46 2008-11-04 11:52:11 avalassi Exp $
+
+// Include files
+#include "CoolKernel/ConstRecordAdapter.h"
+
+// Local include files
+#include "RelationalException.h"
+#include "RelationalObject.h"
+#include "RelationalObjectTable.h"
+#include "RelationalObjectTableRow.h"
+#include "TimingReportMgr.h"
+#include "timeToString.h"
+
+// Namespace
+using namespace cool;
+
+//-----------------------------------------------------------------------------
+
+RelationalObject::RelationalObject( const ValidityKey& since, 
+                                    const ValidityKey& until,
+                                    const IRecord& payload,
+                                    const ChannelId& channelId,
+                                    const std::string& userTagName )
+  : m_since( since )
+  , m_until( until )
+  , m_payload( payload ) 
+  , m_channelId( channelId )
+  , m_userTagName( userTagName )
+  , m_objectId( 0 )
+  , m_userTagId( 0 )
+{
+  
+  // This is used for WRITING data.
+
+  // NB The input IRecord& payload is the one specified by the user 
+  // in IFolder::storeObject: the user owns it and control its lifetime,
+  // hence the data must be copied at least once (here using copy ctor),
+  // __IF__ COOL is meant to ultimately own the data (as in COOL 133).
+
+  // On the other hand, the COOL133 code was not optimal because the data 
+  // owned by the user could be directly stored into the database via CORAL!
+
+  // Need TWO separate implementations for writing (data owned by the user
+  // and not copied) and reading (data owned by COOL)?
+
+  // Bulk insertion - MUST copy...
+
+}
+
+//-----------------------------------------------------------------------------
+
+IObject* RelationalObject::clone() const 
+{
+  RelationalObject *ret= new RelationalObject(m_since, m_until, m_payload, 
+                m_channelId, m_userTagName );
+  ret->m_objectId  = m_objectId;
+  ret->m_userTagId = m_userTagId;
+  ret->m_insertionTime = m_insertionTime;
+
+  return ret;
+}
+//-----------------------------------------------------------------------------
+
+/*
+RelationalObject::RelationalObject
+( RelationalObjectTableRow& row,
+  const IRecordSpecification& payloadSpec )
+  : m_since( row.since() )
+  , m_until( row.until() )
+  , m_payload()
+  //, m_payload( ConstRecordAdapter( payloadSpec, row.data() ) // later
+  , m_channelId( row.channelId() )
+  , m_userTagName( "" )
+  , m_insertionTime( row.insertionTime() )
+  , m_objectId( row.objectId() )
+  , m_userTagId( row.userTagId() )
+{
+
+  // This is used for READING back data.
+
+  // ASSUME (check...) that RelationalObjectTableRow is a wrapper around
+  // a reference to a temporary CORAL buffer: here you must do a DEEP copy!
+
+  // CHECK: is this copying 'fast' enough? 
+  ConstRecordAdapter rec( payloadSpec, row.data() );
+  m_payload = rec;
+
+}
+*/
+
+//-----------------------------------------------------------------------------
+
+RelationalObject::RelationalObject
+( const coral::AttributeList& aList,
+  const IRecordSpecification& payloadSpec )
+  : m_since( aList[RelationalObjectTable::columnNames::iovSince()]
+             .data<ValidityKey>() )
+  , m_until( aList[RelationalObjectTable::columnNames::iovUntil()]
+             .data<ValidityKey>() )
+  , m_payload()
+  , m_channelId( aList[RelationalObjectTable::columnNames::channelId()]
+                 .data<ChannelId>() )
+  , m_userTagName( "" )
+  , m_insertionTime( stringToTime
+                     ( aList[RelationalObjectTable::columnNames::sysInsTime()]
+                       .data<std::string>() ) )
+  , m_objectId( aList[RelationalObjectTable::columnNames::objectId()]
+                .data<unsigned int>() )
+  , m_userTagId( aList[RelationalObjectTable::columnNames::userTagId()]
+                 .data<unsigned int>() )
+{
+
+  // This is used for READING back data.
+
+  // ASSUME (check...) that RelationalObjectTableRow is a wrapper around
+  // a reference to a temporary CORAL buffer: here you must do a DEEP copy!
+
+  if ( TimingReportMgr::isActive() )
+    TimingReportMgr::startTimer( "cool::RelationalObject::ctor" );
+
+  // CHECK: is this copying 'fast' enough? 
+  ConstRecordAdapter rec( payloadSpec, aList );
+  m_payload = rec;
+
+  if ( TimingReportMgr::isActive() )
+    TimingReportMgr::stopTimer( "cool::RelationalObject::ctor" );
+
+}
+
+//-----------------------------------------------------------------------------
+
+const ValidityKey& RelationalObject::since() const 
+{
+  return m_since;
+}
+
+//-----------------------------------------------------------------------------
+
+const ValidityKey& RelationalObject::until() const 
+{
+  return m_until;
+}
+
+//-----------------------------------------------------------------------------
+
+const IRecord& RelationalObject::payload() const 
+{
+  return m_payload;
+}
+
+//-----------------------------------------------------------------------------
+
+const ChannelId& RelationalObject::channelId() const 
+{
+  return m_channelId;
+}
+
+//-----------------------------------------------------------------------------
+
+/*
+const std::string& RelationalObject::channelName() const 
+{
+  throw RelationalException
+    ( "RelationalObject::channelName is not implemented yet" );
+}
+*/
+
+//-----------------------------------------------------------------------------
+
+const std::string& RelationalObject::userTagName() const 
+{
+  return m_userTagName;
+}
+
+//-----------------------------------------------------------------------------
+
+unsigned int RelationalObject::userTagId() const 
+{
+  return m_userTagId;
+}
+
+//-----------------------------------------------------------------------------
+
+bool RelationalObject::isStored() const 
+{
+  return true;
+}
+
+//-----------------------------------------------------------------------------
+
+unsigned int RelationalObject::objectId() const 
+{
+  return m_objectId;
+}
+
+//-----------------------------------------------------------------------------
+
+const ITime& RelationalObject::insertionTime() const 
+{
+  return m_insertionTime;
+}
+
+//-----------------------------------------------------------------------------
+/*
+const ValidityKey& RelationalObject::sinceOriginal() const 
+{
+  return m_sinceOriginal;
+}
+
+//-----------------------------------------------------------------------------
+
+const ValidityKey& RelationalObject::untilOriginal() const 
+{
+  return m_untilOriginal;
+}
+
+//-----------------------------------------------------------------------------
+
+const ITime& RelationalObject::insertionTimeOriginal() const 
+{
+  return m_insertionTimeOriginal;
+}
+*/
+//-----------------------------------------------------------------------------
+
+std::ostream& RelationalObject::print( std::ostream& s ) const 
+{
+  s << "Object: ";
+  { 
+    unsigned int maxSize = 3;
+    s << std::setw(maxSize) << objectId();
+  }
+  
+  s << " ";
+  
+  { 
+    unsigned int maxSize = 2;
+    s << "(" << std::setw(maxSize) << channelId() << ")";
+  }
+  
+  { // assemble IOV
+    std::stringstream iov;
+    iov << " [" << since() << "," ;
+    if ( until() == ValidityKeyMax ) {
+      iov << "+inf";
+    } else {
+      iov << until();
+    }
+    iov << "[";
+    unsigned int maxSize = 10;
+    s << std::setiosflags(std::ios::left) << std::setw(maxSize);
+    s << iov.str();
+    s << std::resetiosflags(std::ios::left);
+  }
+  
+  s << " ";
+  
+  { // assemble payload
+    std::stringstream p;
+    p << "[";
+    bool first = true;
+    const IRecordSpecification& spec = payload().specification();
+    for ( unsigned int i = 0; i < spec.size(); i++ ) {
+      if ( first ) {
+        first = false;
+        p << payload()[i];
+      } else {
+        p << "|" << payload()[i];
+      }
+    }
+    p << "] ";
+
+    unsigned int maxSize = 20;
+    s << std::setiosflags(std::ios::left) << std::setw(maxSize);
+    s << p.str();
+    s << std::resetiosflags(std::ios::left);
+  }
+  
+  s << timeToString( insertionTime() );
+  return s;
+}
+
+//-----------------------------------------------------------------------------
+
diff --git a/RelationalCool/src/RelationalObject.h b/RelationalCool/src/RelationalObject.h
new file mode 100644
index 000000000..adf8e2e42
--- /dev/null
+++ b/RelationalCool/src/RelationalObject.h
@@ -0,0 +1,155 @@
+// $Id: RelationalObject.h,v 1.40 2008-11-04 11:52:11 avalassi Exp $
+#ifndef RELATIONALCOOL_RELATIONALOBJECT_H
+#define RELATIONALCOOL_RELATIONALOBJECT_H
+
+// Include files
+#include "CoolKernel/IObject.h"
+#include "CoolKernel/IRecordSpecification.h"
+#include "CoolKernel/Record.h"
+#include "CoolKernel/Time.h"
+
+namespace cool {
+  
+  // Forward declarations
+  class RelationalObjectTableRow;
+
+  /** @class RelationalObject RelationalObject.h
+   *  
+   *  Generic relational implementation of a COOL condition database "object"
+   *
+   *  @author Sven A. Schmidt, Andrea Valassi and Marco Clemencic
+   *  @date   2004-11-30
+   */
+  
+  class RelationalObject : public IObject {
+
+  public:
+    
+    /// Constructor of an object scheduled to be stored persistently
+    RelationalObject( const ValidityKey& since, 
+                      const ValidityKey& until,
+                      const IRecord& payload,
+                      const ChannelId& channelId,
+                      const std::string& userTagName = "" );
+    
+    /*
+    /// Constructor of an object retrieved from persistent storage
+    /// Note: the row can not be const, because the attributes are shared
+    /// TEMPORARY? A simple ALS is enough in input: an extended ALS would
+    /// be needed only if COOL had to check that data read back from the 
+    /// database passes the size checks. For the moment we choose to only
+    /// implement size checks when WRITING the data into the database
+    /// (and if data is only inserted through the C++ API, no checks are
+    /// needed in reading back anyway...)
+    RelationalObject
+    ( RelationalObjectTableRow& row,
+      const IRecordSpecification& payloadSpec );
+    */
+    
+    /// Constructor of an object retrieved from persistent storage
+    /// AV 2007.03.26 Use a coral::AttributeList to make this faster.
+    /// Observed query time reduction from 0.31s to 0.27s on slc3_ia32_gcc323
+    /// for the benchmark Atlas prompt reconstruction query (100MB, 100k rows).
+    RelationalObject
+    ( const coral::AttributeList& aList,
+      const IRecordSpecification& payloadSpec );
+    
+    /// Destructor
+    virtual ~RelationalObject() {}
+
+    /// deep copy clone
+    virtual IObject* clone() const;
+
+    /// Channel identifier
+    const ChannelId& channelId() const;
+    
+    /// Channel name
+    //const std::string& channelName() const;
+
+    /// Start of validity interval
+    /// For stored objects this refers to the visible validity interval
+    const ValidityKey& since() const;
+    
+    /// End of validity interval
+    /// For stored objects this refers to the visible validity interval
+    const ValidityKey& until() const;
+    
+    /// Data payload
+    const IRecord& payload() const;
+
+    /// The user tag id
+    unsigned int userTagId() const;
+    
+    /// The user tag name this objects has been assigned to
+    const std::string& userTagName() const;
+    
+    /// Has the object been stored into the database?
+    bool isStored() const;
+    
+    /// System-assigned object ID
+    /// Throws an exception if the object has not been stored yet
+    unsigned int objectId() const;
+    
+    /// Insertion time into the database
+    /// Throws an exception if the object has not been stored yet
+    const ITime& insertionTime() const;
+    
+    /// Start of original validity interval
+    /// Throws an exception if the object has not been stored yet
+    //const ValidityKey& sinceOriginal() const;
+    
+    /// End of original validity interval
+    /// Throws an exception if the object has not been stored yet
+    //const ValidityKey& untilOriginal() const;
+    
+    /// Insertion time of the original object into the database
+    /// Throws an exception if the object has not been stored yet
+    //const ITime& insertionTimeOriginal() const;
+    
+    /// Pretty print to an output stream
+    std::ostream& print( std::ostream& s ) const;
+    
+  private:
+    
+    RelationalObject();
+    RelationalObject( const RelationalObject& rhs );
+    RelationalObject& operator=( const RelationalObject& rhs );
+    
+    /// Beginning of the interval of validity
+    ValidityKey m_since;
+    
+    /// End of the interval of validity
+    ValidityKey m_until;
+    
+    /// Object payload - this is always owned by the RelationalObject
+    Record m_payload;
+
+    /// Channel id
+    ChannelId m_channelId;
+    
+    /// User tag name
+    std::string m_userTagName;
+    
+    /// Insertion time
+    Time m_insertionTime;
+
+    /// Object id
+    unsigned int m_objectId;
+    
+    /// User tag id
+    unsigned int m_userTagId;
+    
+    /// Beginning of the original interval of validity
+    //ValidityKey m_sinceOriginal;
+    
+    /// End of the original interval of validity
+    //ValidityKey m_untilOriginal;
+    
+    /// Original insertion time
+    //Time m_insertionTimeOriginal;
+
+  };  
+
+}
+
+#endif
diff --git a/RelationalCool/src/RelationalObject2TagTable.cpp b/RelationalCool/src/RelationalObject2TagTable.cpp
new file mode 100644
index 000000000..8f8340da4
--- /dev/null
+++ b/RelationalCool/src/RelationalObject2TagTable.cpp
@@ -0,0 +1,35 @@
+// $Id: RelationalObject2TagTable.cpp,v 1.9 2006-09-28 12:49:29 avalassi Exp $
+
+// Include files
+#include "CoolKernel/RecordSpecification.h"
+
+// Local include files
+#include "RelationalObject2TagTable.h"
+
+//-----------------------------------------------------------------------------
+
+const cool::IRecordSpecification&
+cool::RelationalObject2TagTable::tableSpecification() 
+{
+  
+  static RecordSpecification spec;
+  if ( spec.size() == 0 ) {
+    spec.extend( RelationalObject2TagTable::columnNames::tagId,      
+                 RelationalObject2TagTable::columnTypeIds::tagId );
+    spec.extend( RelationalObject2TagTable::columnNames::objectId,   
+                 RelationalObject2TagTable::columnTypeIds::objectId );
+    spec.extend( RelationalObject2TagTable::columnNames::channelId,  
+                 RelationalObject2TagTable::columnTypeIds::channelId );
+    spec.extend( RelationalObject2TagTable::columnNames::iovSince,   
+                 RelationalObject2TagTable::columnTypeIds::iovSince );
+    spec.extend( RelationalObject2TagTable::columnNames::iovUntil,   
+                 RelationalObject2TagTable::columnTypeIds::iovUntil );
+    spec.extend( RelationalObject2TagTable::columnNames::sysInsTime, 
+                 RelationalObject2TagTable::columnTypeIds::sysInsTime );
+  }
+  return spec;  
+
+}
+
+//-----------------------------------------------------------------------------
+
diff --git a/RelationalCool/src/RelationalObject2TagTable.h b/RelationalCool/src/RelationalObject2TagTable.h
new file mode 100644
index 000000000..15fada44a
--- /dev/null
+++ b/RelationalCool/src/RelationalObject2TagTable.h
@@ -0,0 +1,71 @@
+// $Id: RelationalObject2TagTable.h,v 1.19 2008-11-04 11:52:11 avalassi Exp $
+#ifndef RELATIONALCOOL_RELATIONALOBJECT2TAGTABLE_H
+#define RELATIONALCOOL_RELATIONALOBJECT2TAGTABLE_H
+
+// Include files
+#include "CoolKernel/StorageType.h"
+
+// Local include files
+#include "uppercaseString.h"
+
+namespace cool {  
+  
+  // Forward declarations
+  class IRecordSpecification;
+
+  /** @namespace cool::RelationalObject2TagTable RelationalObject2TagTable.h
+   *  
+   *  Relational schema of the table storing COOL tag <--> object relations.
+   *
+   *  @author Andrea Valassi, Sven A. Schmidt and Marco Clemencic
+   *  @date   2005-02-06
+   */
+  
+  namespace RelationalObject2TagTable {
+    
+    inline const std::string defaultTableName
+    ( const std::string& prefix, unsigned nodeId ) {
+      char tableName[] = "Fxxxx_IOV2TAG";
+      sprintf( tableName, "F%4.4i_IOV2TAG", nodeId );
+      // TEMPORARY? AV 04.04.2005 
+      // FIXME: presently the input prefix is uppercase anyway...
+      return uppercaseString( prefix ) + std::string( tableName );
+    }    
+
+    namespace columnNames {
+      static const std::string tagId = "TAG_ID";    
+      static const std::string objectId = "OBJECT_ID";    
+      static const std::string channelId = "CHANNEL_ID";    
+      static const std::string iovSince = "IOV_SINCE";    
+      static const std::string iovUntil = "IOV_UNTIL";    
+      static const std::string sysInsTime = "SYS_INSTIME";    
+    }
+
+    namespace columnTypeIds {
+      static const StorageType::TypeId tagId      = StorageType::UInt32;
+      static const StorageType::TypeId objectId   = StorageType::UInt32;
+      static const StorageType::TypeId channelId  = StorageType::UInt32;
+      static const StorageType::TypeId iovSince   = StorageType::UInt63;
+      static const StorageType::TypeId iovUntil   = StorageType::UInt63;
+      // TEMPORARY! Should be Time?
+      static const StorageType::TypeId sysInsTime = StorageType::String255;
+    }
+
+    namespace columnTypes {
+      typedef UInt32 tagId;
+      typedef UInt32 objectId;
+      typedef UInt32 channelId;
+      typedef UInt63 iovSince;
+      typedef UInt63 iovUntil;
+      // TEMPORARY! Should be Time?
+      typedef String255 sysInsTime;
+    }
+
+    /// Get the RecordSpecification of the tag table
+    const IRecordSpecification& tableSpecification();    
+    
+  }
+
+}
+
+#endif // RELATIONALCOOL_RELATIONALOBJECT2TAGTABLE_H
diff --git a/RelationalCool/src/RelationalObjectIterator.cpp b/RelationalCool/src/RelationalObjectIterator.cpp
new file mode 100644
index 000000000..0b97c95f1
--- /dev/null
+++ b/RelationalCool/src/RelationalObjectIterator.cpp
@@ -0,0 +1,457 @@
+// $Id: RelationalObjectIterator.cpp,v 1.13 2008-11-06 18:50:04 avalassi Exp $
+
+// Include files
+#include "CoolKernel/InternalErrorException.h"
+#include "CoolKernel/types.h"
+#include "RelationalAccess/ICursor.h"
+#include "RelationalAccess/IQuery.h"
+#include "RelationalAccess/IQueryDefinition.h"
+#include "RelationalAccess/ISchema.h"
+#include "RelationalAccess/ITable.h"
+
+// Local include files
+#include "HvsTagRecord.h"
+#include "IRelationalCursor.h"
+#include "IRelationalQueryDefinition.h"
+#include "IteratorException.h"
+#include "ObjectIteratorCounter.h"
+#include "RelationalObjectIterator.h"
+#include "RelationalException.h"
+#include "RelationalFolder.h"
+#include "RelationalObject.h"
+#include "RelationalObjectTable.h"
+#include "RelationalObjectTableRow.h"
+#include "RelationalQueryMgr.h"
+#include "RelationalTagMgr.h"
+#include "RelationalTransaction.h"
+#include "TimingReportMgr.h"
+
+// Namespace
+using namespace cool;
+
+//---------------------------------------------------------------------------
+
+RelationalObjectIterator::RelationalObjectIterator
+( const RelationalQueryMgr& queryMgr,
+  const boost::shared_ptr<IRelationalTransactionMgr>& transactionMgr,
+  const RelationalTagMgr& tagMgr,
+  const RelationalFolder& folder,
+  const ValidityKey& since,
+  const ValidityKey& until,
+  const ChannelSelection& channels,
+  const std::string& tagName,
+  bool isUserTag, 
+  const IRecordSelection* payloadQuery,
+  const bool countOnly )
+  : m_isTimingActive( isTimingActive() )
+  , m_transactionMgr( transactionMgr.get() )
+  , m_isRegistered( false )
+  , m_queryMgr( queryMgr.clone() )
+  , m_objectTable( new RelationalObjectTable(m_queryMgr.get(), false, folder) )
+  , m_versioningMode( folder.versioningMode() )
+  , m_transaction( new RelationalTransaction( transactionMgr, true ) ) // r/o
+  , m_dataBuffer( new coral::AttributeList() )
+  , m_since(since)
+  , m_until(until)
+  , m_channels(channels)
+  , m_tagName(tagName)
+  , m_isUserTag(isUserTag)
+  , m_selection( payloadQuery != 0 ? payloadQuery->clone() : 0 )
+  , m_pq( payloadQuery != 0 ? 
+          new RelationalPayloadQuery( *m_selection.get() ) : 0 )
+  , m_queryDef( ( m_selection.get() !=0 && m_pq->isTrusted() ) ?
+                getQueryDefinition( since, until, channels, tagName, isUserTag, m_selection.get() ) : 
+                getQueryDefinition( since, until, channels, tagName, isUserTag, 0 ) )
+  , m_size_known( false )
+  , m_size( 0 )
+  , m_currentObject( 0 )
+{
+  //std::cout << "RelationalObjectIterator ctor " << this << std::endl;
+
+  if ( countOnly )
+  {
+    m_state = COUNTONLY;
+  }
+  else
+  {
+    m_cursor.reset( m_queryMgr->prepareAndExecuteQuery( *m_queryDef, m_dataBuffer ) );
+    m_currentRowAdapter.reset( new ConstRelationalObjectAdapter( *m_dataBuffer, folder.payloadSpecification() ) );
+    m_state = ACTIVE;
+  }    
+
+  // Marco: this needs to be here to avoid the registration of the iterator 
+  // if an exception occurs in the initialization statements (bug #25256).
+  ObjectIteratorCounter::registerIterator( this, m_transactionMgr );
+  m_isRegistered = true;
+    
+  // After starting the transaction, check that the tag exists
+  // Throw TagNotFound if the tag does not exist in this folder
+  if ( ! IHvsNode::isHeadTag( tagName ) ) 
+  {
+    try 
+    {
+      // Throws TagNotFound if tag does not exist
+      tagMgr.__findTagRecord( folder.id(), tagName );
+    }
+    catch ( ... )
+    {
+      // Release any associated server resources and unregister the iterator
+      bool rollback = true;
+      close( rollback );
+      throw;
+    }
+  }  
+
+  if ( m_isTimingActive )
+    TimingReportMgr::stopTimer
+      ( "cool::RelationalObjectIterator::ctor" );
+}
+
+//---------------------------------------------------------------------------
+
+RelationalObjectIterator::~RelationalObjectIterator()
+{
+  //std::cout << "RelationalObjectIterator dtor " << this << std::endl;
+
+  // Move the iterator into the Closed state.
+  close();
+
+  //if ( m_isTimingActive )
+  //  TimingReportMgr::stopTimer
+  //    ( "cool::RelationalObjectIterator [LIFETIME]" );
+}
+
+//---------------------------------------------------------------------------
+
+bool RelationalObjectIterator::isTimingActive() const 
+{
+  if ( TimingReportMgr::isActive() ) 
+  {
+    TimingReportMgr::startTimer
+      ( "cool::RelationalObjectIterator::ctor" );
+    //TimingReportMgr::startTimer
+    //  ( "cool::RelationalObjectIterator [LIFETIME]" );
+    return true;
+  }
+  else return false;
+}
+
+//-----------------------------------------------------------------------------
+
+bool RelationalObjectIterator::isEmpty() 
+{
+  if ( m_currentObject > 0 ) return false;
+  return size() == 0;
+}
+
+//---------------------------------------------------------------------------
+
+const IObject& RelationalObjectIterator::currentRef()
+{
+  // Iterator is in the CountOnly state
+  if ( m_state == COUNTONLY ) 
+  {
+    throw InternalErrorException( "PANIC! Iterator can be used only for counting",
+                                  "RelationalObjectIterator" );
+  }
+  
+  // Iterator is in the Closed state
+  else if ( m_state == CLOSED ) 
+  {
+    throw IteratorIsClosed( "RelationalObjectIterator" );
+  }
+  
+  // Iterator is in the Started state
+  // [next() has not been called yet and/or the iterator is empty].
+  else if ( m_currentObject == 0 || m_state == END_OF_ROWS ) 
+  {
+    throw IteratorHasNoCurrentItem( "RelationalObjectIterator" );
+  }
+  
+  // Iterator is in the Active state
+  else 
+  {
+    if ( m_isTimingActive ) {
+      TimingReportMgr::startTimer
+        ( "cool::RelationalObjectIterator::currentRef" );
+      TimingReportMgr::stopTimer
+        ( "cool::RelationalObjectIterator::currentRef" );
+    }
+    return *m_currentRowAdapter;
+  }
+  
+}
+
+//---------------------------------------------------------------------------
+
+bool RelationalObjectIterator::goToNext()
+{
+  if ( m_state == COUNTONLY ) 
+    throw InternalErrorException( "PANIC! Iterator can be used only for counting",
+                                  "RelationalObjectIterator" );
+
+  if ( m_isTimingActive )
+    TimingReportMgr::startTimer
+      ( "cool::RelationalObjectIterator::goToNext()" );
+
+  // Iterator is in the Closed state
+  if ( m_state == CLOSED ) {
+    if ( m_isTimingActive )
+      TimingReportMgr::stopTimer
+        ( "cool::RelationalObjectIterator::goToNext()" );
+    throw IteratorIsClosed( "RelationalObjectIterator" );
+  }
+  
+  // Iterator (Started or Active) has a non-null next object
+  else   
+  {
+    bool client_side_pq = m_selection.get()!=0 && !m_pq->isTrusted();
+    // If there is a payload selection (m_selection), fetch objects 
+    // until one satisfies the selection or we have no more objects
+
+    bool gotNext = false;
+    do {
+      m_currentObject++;
+    }
+    while ( ( gotNext = fetchNext() ) == true 
+            && client_side_pq 
+            && !m_selection->select( currentRef().payload() ) );
+    if (!gotNext)
+        m_state = END_OF_ROWS;
+
+    if ( m_isTimingActive )
+      TimingReportMgr::stopTimer
+        ( "cool::RelationalObjectIterator::goToNext()" );
+     
+    return gotNext;
+  }
+}
+
+
+//---------------------------------------------------------------------------
+
+unsigned int RelationalObjectIterator::size()
+{
+  //std::cout << "RelationalObjectIterator::size()" << std::endl;
+  // Iterator is in the Closed state
+  if ( m_state == CLOSED ) {
+    throw IteratorIsClosed( "RelationalObjectIterator" );
+  } 
+  else if ( m_selection.get()!=0 && !m_pq->isTrusted() ) 
+  {
+    // NB This makes sense also for COUNTONLY iterators...
+    throw RelationalException
+      ( "Size is not known since the payload query is not trusted",
+        "RelationalObjectIterator" );
+  }
+  // Iterator is in the NotStarted, Started or Active state
+  else if ( !m_size_known )
+  {
+    // size is requested for the first time, so fetch it
+    m_size_known=true;
+    m_size=getSize
+      ( m_since, m_until, m_channels, m_tagName, m_isUserTag, m_selection.get() ); 
+  }
+  //std::cout << "RelationalObjectIterator::size() is " << m_size << std::endl;
+  return m_size;
+}
+
+//---------------------------------------------------------------------------
+
+const IObjectVectorPtr RelationalObjectIterator::fetchAllAsVector()
+{ 
+  if ( m_state == COUNTONLY ) 
+    throw InternalErrorException( "PANIC! Iterator can be used only for counting",
+                                  "RelationalObjectIterator" );
+
+  // Iterator is in the Closed state
+  if ( m_state == CLOSED ) {
+    throw IteratorIsClosed( "RelationalObjectIterator" );
+  }
+
+  // Iterator is in the Started state
+  else if ( m_currentObject == 0 ) {
+    IObjectVectorPtr objects( new IObjectVector() );
+    if ( m_isTimingActive )
+      TimingReportMgr::startTimer
+        ( "cool::RelationalObjectIterator::fetchAllAsVec()" );
+    while( goToNext() ) {
+      objects->push_back( IObjectPtr( currentRef().clone() ) );
+    }
+    if ( m_isTimingActive )
+      TimingReportMgr::stopTimer
+        ( "cool::RelationalObjectIterator::fetchAllAsVec()" );
+    return objects;  
+  }
+
+  // Iterator is in the Active state
+  else {
+    throw IteratorIsActive( "RelationalObjectIterator" );
+  }
+}
+
+//---------------------------------------------------------------------------
+
+void RelationalObjectIterator::close( bool rollback )
+{
+  //std::cout << "RelationalObjectIterator close() " << this << std::endl;
+
+  // Iterator is not already in the Closed state
+  if (  m_state != CLOSED ) {
+
+    // Delete the cursor and release all associated database resources
+    std::auto_ptr<IRelationalCursor> nullCursor;
+    m_cursor = nullCursor;
+
+    // Commit and delete the read-only transaction
+    if ( m_transaction ) {
+      if ( ! rollback ) m_transaction->commit();
+      else m_transaction->rollback();
+      delete m_transaction;
+      m_transaction = 0;
+    }
+
+    // Move the iterator into the Closed state
+    m_state = CLOSED;
+
+    // Unregister the iterator
+    ObjectIteratorCounter::unregisterIterator( this, m_transactionMgr );
+  }
+}
+
+//---------------------------------------------------------------------------
+
+unsigned int
+RelationalObjectIterator::getSize( const ValidityKey& since,
+                                   const ValidityKey& until,
+                                   const ChannelSelection& channels,
+                                   const std::string& tagName,
+                                   bool isUserTag, 
+                                   const IRecordSelection* payloadQuery ) const
+{
+  unsigned int size;
+  if ( m_versioningMode == FolderVersioning::SINGLE_VERSION ) 
+  {
+    if ( ! IHvsNode::isHeadTag( tagName ) ) 
+      throw RelationalException
+        ( "Single version folder: browsing within a non-null tag '"
+          + tagName + "' makes no sense", "RelationalObjectIterator" );
+    const std::auto_ptr<IRelationalQueryDefinition> 
+      def( m_objectTable->queryDefinitionSV
+           ( since, until, channels, payloadQuery ) );
+    size = m_queryMgr->countRows( *def, "SV object count" );
+  } 
+  else if ( m_versioningMode == FolderVersioning::MULTI_VERSION ) 
+  {
+    if ( isUserTag ) 
+    {
+      const std::auto_ptr<IRelationalQueryDefinition> 
+        def( m_objectTable->queryDefinitionHeadAndUserTag
+             ( since, until, channels, tagName, payloadQuery ) );
+      size = m_queryMgr->countRows( *def, "MV userTag object count" );
+    } 
+    else if ( IHvsNode::isHeadTag( tagName ) ) 
+    {
+      const std::auto_ptr<IRelationalQueryDefinition> 
+	        def( m_objectTable->queryDefinitionHeadAndUserTag
+	             ( since, until, channels, tagName, payloadQuery ) );
+	      size = m_queryMgr->countRows( *def, "MV headTag object count" );
+    }
+    else 
+    {
+      const std::auto_ptr<IRelationalQueryDefinition> 
+        def( m_objectTable->queryDefinitionTag
+             ( since, until, channels, tagName, payloadQuery ) );
+      size = m_queryMgr->countRows( *def, "MV tag object count" );
+    }
+  }
+  else 
+  {
+    std::stringstream s;
+    s << "Object count not supported for this folder type: "
+      << m_versioningMode;
+    throw RelationalException( s.str(), "RelationalObjectIterator" );
+  }
+  return size;
+}
+
+//---------------------------------------------------------------------------
+
+std::auto_ptr<IRelationalQueryDefinition>
+RelationalObjectIterator::getQueryDefinition( const ValidityKey& since,
+                                        const ValidityKey& until,
+                                        const ChannelSelection& channels,
+                                        const std::string& tagName,
+                                        bool isUserTag, 
+                                        const IRecordSelection* payloadQuery )
+{
+
+  // --- SINGLE VERSION ---
+
+  if ( m_versioningMode == FolderVersioning::SINGLE_VERSION )
+  {
+    if ( ! IHvsNode::isHeadTag( tagName ) ) 
+      throw RelationalException
+        ( "Single version folder: browsing within a non-null tag '"
+          + tagName + "' makes no sense", "RelationalObjectIterator" );
+    std::auto_ptr<IRelationalQueryDefinition> 
+      def( m_objectTable->queryDefinitionSV
+           ( since, until, channels, payloadQuery ) );
+    return def;
+  } 
+  
+  // --- MULTI VERSION ---
+  
+  else 
+  {
+    if ( IHvsNode::isHeadTag( tagName ) ) 
+    { // MV HEAD
+      std::auto_ptr<IRelationalQueryDefinition> 
+        def( m_objectTable->queryDefinitionHeadAndUserTag
+             ( since, until, channels, "HEAD", payloadQuery ) );
+      return def;
+    } 
+    else if ( isUserTag )
+    { // MV User Tag
+      std::auto_ptr<IRelationalQueryDefinition> 
+        def( m_objectTable->queryDefinitionHeadAndUserTag
+             ( since, until, channels, tagName, payloadQuery ) );
+      return def;
+    } 
+    else 
+    { // MV Tag
+      std::auto_ptr<IRelationalQueryDefinition> 
+        def( m_objectTable->queryDefinitionTag
+             ( since, until, channels, tagName, payloadQuery ) );
+      return def;
+    }
+  }
+}
+
+//---------------------------------------------------------------------------
+
+bool RelationalObjectIterator::fetchNext()
+{
+  if ( m_state == COUNTONLY ) 
+    throw InternalErrorException( "PANIC! Iterator can be used only for counting",
+                                  "RelationalObjectIterator" );
+
+  // Iterator is in the Closed state (???)
+  if ( m_state == CLOSED )
+    throw InternalErrorException( "PANIC! The iterator is closed!?", 
+                                  "RelationalObjectIterator" );
+
+  // Fetch the next row from the RAL cursor
+  if ( m_cursor->next() ) 
+  {
+    // The currentRow() contains a reference to the current row
+    return true;
+  } else {
+    // The currentRow() should not be used
+    return false;
+  }
+
+}
+
+//---------------------------------------------------------------------------
+
diff --git a/RelationalCool/src/RelationalObjectIterator.h b/RelationalCool/src/RelationalObjectIterator.h
new file mode 100644
index 000000000..bc2dba2fb
--- /dev/null
+++ b/RelationalCool/src/RelationalObjectIterator.h
@@ -0,0 +1,198 @@
+// $Id: RelationalObjectIterator.h,v 1.12 2008-11-06 15:43:02 avalassi Exp $
+#ifndef COOLKERNEL_RELATIONALOBJECTITERATOR_H
+#define COOLKERNEL_RELATIONALOBJECTITERATOR_H
+
+// Include files
+#include <memory>
+#include "CoolKernel/ChannelSelection.h"
+#include "CoolKernel/IObjectIterator.h"
+#include "CoolKernel/FolderVersioning.h"
+
+// Local include files
+#include "ConstRelationalObjectAdapter.h"
+#include "RelationalPayloadQuery.h"
+
+namespace cool 
+{
+
+  // Forward declarations
+  class IRecordSelection;
+  class IRelationalCursor;
+  class IRelationalQueryDefinition;
+  class IRelationalTransactionMgr;
+  class RelationalFolder;
+  class RelationalObjectTable;
+  class RelationalQueryMgr;
+  class RelationalTagMgr;
+  class RelationalTransaction;
+
+  /** @class RelationalObjectIterator RelationalObjectIterator.h
+   *
+   *  RAL implementation of an object iterator.
+   *
+   *  The iterator can be used only ONCE to forward-iterate over a result set.
+   *
+   *  During its whole lifetime, the iterator is associated to a read-only RAL
+   *  transaction (started in the constructor), a RAL query (created in the
+   *  constructor) and a RAL cursor reference (obtained by processing this
+   *  query in the constructor). All these resources are released in the
+   *  destructor by a call to the close() method, which commits and deletes
+   *  the transaction, and deletes the query. The close() method can also be
+   *  called explicitly in the user code to release the resources: this moves
+   *  the iterator to the Closed state, from which it cannot be reused.
+   *
+   *  For perfomance reasons the iterator doesn't query the number of rows,
+   *  unless size() or isEmpty() are called.
+   *
+   *  @author Andrea Valassi
+   *  @date   2007-03-29
+   */
+
+  class RelationalObjectIterator : public IObjectIterator {
+
+  public:
+
+    /// Destructor
+    virtual ~RelationalObjectIterator();
+
+    /// Constructor from all relevant query parameters
+    RelationalObjectIterator
+    ( const RelationalQueryMgr& queryMgr,
+      const boost::shared_ptr<IRelationalTransactionMgr>& transactionMgr,
+      const RelationalTagMgr& tagMgr,
+      const RelationalFolder& folder,
+      const ValidityKey& since,
+      const ValidityKey& until,
+      const ChannelSelection& channels,
+      const std::string& tagName,
+      bool isUserTag, 
+      const IRecordSelection* payloadQuery = 0,
+      const bool countOnly = false );
+
+    /// Does the iterator have zero objects in the loop?
+    bool isEmpty();
+
+    /// Fetch the next object in the iterator loop.
+    /// Return false if there is no next object.
+    bool goToNext();
+
+    /// Retrieve a reference to the current object in the iterator loop.
+    /// NB The reference is only valid until goToNext() is called!
+    /// Throw an exception if there is no current object (because the iterator
+    /// is empty or is positioned before the first object in the loop).
+    const IObject& currentRef();
+
+    /// Returns the 'length' of the iterator
+    unsigned int size();
+
+    /// Returns all objects in the iterator as a vector.
+    /// Throws an exception if goToNext() has already retrieved one object:
+    /// this method can only be called INSTEAD of the loop using goToNext().
+    const IObjectVectorPtr fetchAllAsVector();
+
+    /// Close the iterator and release any associated server resources.
+    /// The iterator cannot be used any more after this method is called.
+    void close()
+    {
+      bool rollback = false;
+      close( rollback );
+    }
+
+  private:
+
+    /// Prefetch the number of rows that the iterator will return
+    unsigned int getSize( const ValidityKey& since,
+                          const ValidityKey& until,
+                          const ChannelSelection& channels,
+                          const std::string& tagName,
+                          bool isUserTag, 
+                          const IRecordSelection* payloadQuery = 0 ) const;
+
+    /// Get the appropriate query definition for this iterator
+    std::auto_ptr<IRelationalQueryDefinition>
+    getQueryDefinition( const ValidityKey& since,
+                        const ValidityKey& until,
+                        const ChannelSelection& channels,
+                        const std::string& tagName,
+                        bool isUserTag, 
+                        const IRecordSelection* payloadQuery = 0 );
+
+    /// Fetch the next object from the CORAL cursor
+    bool fetchNext();
+
+    /// Is timing active? (hack to activate it at beginning of ctor)
+    bool isTimingActive() const;
+
+    /// Close the iterator and release any associated server resources.
+    /// The iterator cannot be used any more after this method is called.
+    /// Commit/rollback the open transaction in case of success/failure.
+    void close( bool rollback );
+
+  private:
+
+    /// Is timing active? (hack to activate it at beginning of ctor)
+    bool m_isTimingActive;
+
+    /// The IRelationalTransactionMgr referenced in the iterator counter    
+    /// NB This is only used as an index - you don't even need the header!
+    const IRelationalTransactionMgr* m_transactionMgr;
+
+    /// Is this iterator registered? (hack to do it at beginning of ctor)
+    bool m_isRegistered;
+
+    /// Relational query manager
+    std::auto_ptr<RelationalQueryMgr> m_queryMgr;
+
+    /// Object table for the relevant folder
+    std::auto_ptr<RelationalObjectTable> m_objectTable;
+
+    /// Versioning mode for the relevant folder
+    FolderVersioning::Mode m_versioningMode;
+
+    /// Active relational transaction
+    RelationalTransaction* m_transaction;
+
+     /// Data buffer used by the active cursor
+    boost::shared_ptr<coral::AttributeList> m_dataBuffer;
+ 
+    /// details about the query, needed to fetch the size of the vector
+    /// if demanded.
+    const ValidityKey m_since;
+    const ValidityKey m_until;
+    const ChannelSelection m_channels;
+    const std::string m_tagName;
+    bool m_isUserTag;
+   
+    /// Record selection for this iterator
+    std::auto_ptr<IRecordSelection> m_selection;
+    
+    /// Payload query for this iterator
+    std::auto_ptr<RelationalPayloadQuery> m_pq;
+
+    /// Relational query definition
+    std::auto_ptr<IRelationalQueryDefinition> m_queryDef;
+
+    /// is m_size known 
+    bool m_size_known;
+
+    /// number of rows that the iterator will return
+    /// queried on demand by the size() method
+    unsigned int m_size;
+
+    /// FSM - current object in RelationalObjectIterator private cache
+    unsigned int m_currentObject;
+
+    /// Active cursor
+    std::auto_ptr<IRelationalCursor> m_cursor;
+
+    /// Adapter of const AttributeList& currentRow() to the IObject interface.
+    std::auto_ptr<ConstRelationalObjectAdapter> m_currentRowAdapter;
+
+    /// state of the iterator (active, end of rows reached, closed; or countonly)
+    enum { ACTIVE, END_OF_ROWS, CLOSED, COUNTONLY } m_state;
+
+  };
+
+}
+
+#endif
diff --git a/RelationalCool/src/RelationalObjectMgr.cpp b/RelationalCool/src/RelationalObjectMgr.cpp
new file mode 100644
index 000000000..e566e4588
--- /dev/null
+++ b/RelationalCool/src/RelationalObjectMgr.cpp
@@ -0,0 +1,1895 @@
+// $Id: RelationalObjectMgr.cpp,v 1.38 2009-01-13 18:30:10 avalassi Exp $
+
+// Include files
+#include <boost/scoped_array.hpp>
+#include "CoolKernel/InternalErrorException.h"
+#include "CoolKernel/IObjectIterator.h"
+#include "CoralBase/Attribute.h"
+#include "RelationalAccess/SchemaException.h"
+
+// Local include files
+#include "HvsTagRecord.h"
+#include "IRelationalBulkOperation.h"
+#include "RelationalChannelTable.h"
+#include "RelationalException.h"
+#include "RelationalGlobalTagTable.h"
+#include "RelationalObject.h"
+#include "RelationalObjectIterator.h"
+#include "RelationalObjectMgr.h"
+#include "RelationalObjectTable.h"
+#include "RelationalObjectTableRow.h"
+#include "RelationalQueryDefinition.h"
+#include "RelationalSequence.h"
+#include "RelationalSequenceMgr.h"
+#include "RelationalTableRow.h"
+#include "RelationalTagMgr.h"
+#include "RelationalTagTable.h"
+#include "RelationalTransaction.h"
+#include "SimpleObject.h"
+
+// Namespace
+using namespace cool;
+
+//-----------------------------------------------------------------------------
+
+RelationalObjectMgr::RelationalObjectMgr( const RelationalDatabase& db )
+  : m_db( db )
+  , m_log( new coral::MessageStream( "RelationalObjectMgr" ) )
+{
+}
+
+//-----------------------------------------------------------------------------
+
+coral::MessageStream& RelationalObjectMgr::log() const
+{
+  *m_log << coral::Verbose;
+  return *m_log;
+}
+
+//-----------------------------------------------------------------------------
+
+IObjectPtr 
+RelationalObjectMgr::findObject( const RelationalFolder* folder,
+                                 const ValidityKey& pointInTime,
+                                 const ChannelId& channelId,
+                                 const std::string& tagName ) const
+{
+  // Cross-check that the database is open
+  if ( ! db().isOpen() ) throw DatabaseNotOpen( "RalDatabase" );
+  
+  IObjectIteratorPtr objs = browseObjects( folder, 
+                                           pointInTime,
+                                           pointInTime,
+                                           ChannelSelection( channelId ),
+                                           tagName );
+ 
+  if ( ! objs->goToNext() ) 
+  {
+    std::stringstream s;
+    s << pointInTime;
+    throw ObjectNotFound( s.str(), folder->fullPath() );
+  }
+  IObjectPtr obj( objs->currentRef().clone() );
+  if ( objs->goToNext() )
+    throw InternalErrorException
+      ( "PANIC! More than one object in findObject query", "RalDatabase" );
+  return obj;
+}
+
+//-----------------------------------------------------------------------------
+
+IObjectIteratorPtr
+RelationalObjectMgr::browseObjects
+( const RelationalFolder* folder,
+  const ValidityKey& since,
+  const ValidityKey& until,
+  const ChannelSelection& channels,
+  const std::string& tagName, 
+  const IRecordSelection* payloadQuery,
+  const bool countOnly ) const
+{
+  IObjectIteratorPtr iterator;
+
+  // Cross-check that the database is open
+  if ( ! db().isOpen() ) throw DatabaseNotOpen( "RalDatabase" );
+  
+  FolderVersioning::Mode versioningMode = folder->versioningMode();
+  try 
+  {
+    // Throw TagNotFound if the tag does not exist in this folder
+    // [this is delegated to the RelationalObjectIterator constructor]
+
+    if ( versioningMode == FolderVersioning::SINGLE_VERSION ) 
+    {
+      bool isUserTag = false;
+      iterator.reset
+        ( new RelationalObjectIterator
+          ( queryMgr(), transactionMgr(), tagMgr(),
+            *folder, since, until, channels, tagName, isUserTag,
+            payloadQuery, countOnly ));
+    } 
+    else if ( versioningMode == FolderVersioning::MULTI_VERSION ) 
+    {
+      bool isUserTag = folder->existsUserTag( tagName );
+      iterator.reset
+        ( new RelationalObjectIterator
+          ( queryMgr(), transactionMgr(), tagMgr(),
+            *folder, since, until, channels, tagName, isUserTag,
+            payloadQuery, countOnly ));
+    } 
+    else 
+    {
+      std::stringstream s;
+      s << "Unsupported folder versioning mode: "
+        << versioningMode;
+      throw RelationalException( s.str(), "RalDatabase" );
+    }
+  } 
+  catch ( coral::TableNotExistingException& ) 
+  {
+    // Guard against a dropped folder and provide meaningful feedback
+    // (minor issue: catch CORAL exception in a generic Relational class...)
+    throw FolderSpecificTableNotFound( folder->fullPath(), "RalDatabase" );
+  }  
+  return iterator;
+}
+
+//-----------------------------------------------------------------------------
+
+bool 
+RelationalObjectMgr::dropChannel( const RelationalFolder* folder,
+                                  const ChannelId& channelId ) const 
+{
+  bool readOnly = false;
+  RelationalTransaction transaction( transactionMgr(), readOnly );
+  const std::string folderName = folder->fullPath();
+  // FIRST check if there are any IOVs for this channel
+  // (throw an exception if there are any - this is the semantics
+  // of the dropChannel method, it is NOT a workaround for bug #23755).
+  if ( db().relationalObjectTable( *folder )->existsChannel( channelId ) )
+  { 
+    std::ostringstream s;
+    s << "Cannot drop channel with id=" << channelId
+      << " in folder '" << folder->fullPath() 
+      << "': the channel contains some IOVs";
+    throw RelationalException( s.str(), "RelationalObjectMgr" );
+  }
+  // THEN check if the channel exists (only) in the channel table
+  RelationalChannelTable table( db(), *folder );
+  try 
+  { 
+    table.fetchRowForId( channelId );
+  } 
+  catch ( NoRowsFound& ) 
+  {
+    transaction.commit();
+    return false;
+  }
+  std::string whereClause = RelationalChannelTable::columnNames::channelId();
+  whereClause += "= :channel";
+  coral::AttributeList whereData;
+  whereData.extend
+    ( "channel",
+      typeIdToCoralType(RelationalChannelTable::columnTypeIds::channelId) );
+  whereData["channel"].setValue( channelId );
+  // Rely on the queryMgr to throw an exception if the DELETE goes wrong
+  queryMgr().deleteTableRows( table.tableName(), whereClause, whereData, 1 );
+  // Commit the transaction
+  transaction.commit();
+  return true;
+}
+
+//-----------------------------------------------------------------------------
+
+void 
+RelationalObjectMgr::createChannel( const RelationalFolder* folder,
+                                    const ChannelId& channelId,
+                                    const std::string& channelName,
+                                    const std::string& description ) const 
+{
+  bool readOnly = false;
+  RelationalTransaction transaction( transactionMgr(), readOnly );
+  const std::string folderName = folder->fullPath();
+  // Check if a channel with the given ID already exists
+  try 
+  {
+    RelationalChannelTable table( db(), *folder );
+    table.fetchRowForId( channelId );
+    throw ChannelExists( folderName, channelId, "RelationalObjectMgr" );
+  } 
+  catch ( NoRowsFound& ) {}
+  // Check if a channel with the given name already exists
+  try 
+  {
+    RelationalChannelTable table( db(), *folder );
+    table.fetchRowForChannelName( channelName );
+    throw ChannelExists( folderName, channelName, "RelationalObjectMgr" );
+  } catch ( NoRowsFound& ) {}
+  // Create a new channel with the given ID and name
+  unsigned int lastObjectId = 0;
+  bool hasNewData = false;
+  insertChannelTableRow( folder->channelTableName(),
+                         channelId,
+                         lastObjectId,
+                         hasNewData,
+                         channelName,
+                         description );
+  // Commit the transaction
+  transaction.commit();
+}
+
+//-----------------------------------------------------------------------------
+
+void RelationalObjectMgr::insertChannelTableRow
+( const std::string& channelTableName,
+  const ChannelId& channelId,
+  unsigned int lastObjectId,
+  bool hasNewData,
+  const std::string& channelName,
+  const std::string& description ) const
+{
+  coral::AttributeList data =
+    Record( RelationalChannelTable::tableSpecification() ).attributeList();
+  data[RelationalChannelTable::columnNames::channelId()].setValue
+    ( channelId );
+  data[RelationalChannelTable::columnNames::lastObjectId()].setValue
+    ( lastObjectId );
+  data[RelationalChannelTable::columnNames::hasNewData()].setValue
+    ( hasNewData );
+  if ( channelName != "" )
+    data[RelationalChannelTable::columnNames::channelName()].setValue
+      ( channelName );
+  else
+    data[RelationalChannelTable::columnNames::channelName()].setNull();
+  data[RelationalChannelTable::columnNames::description()].setValue
+    ( description );
+  queryMgr().insertTableRow( channelTableName, data );
+}
+
+//-----------------------------------------------------------------------------
+
+void RelationalObjectMgr::updateChannelTable
+( const std::string& channelTableName,
+  const ChannelId& channelId,
+  unsigned int lastObjectId,
+  bool hasNewData ) const
+{
+  log() << "Update in table " << channelTableName 
+        << " for channel " << channelId << coral::MessageStream::endmsg;
+  
+  // Update the lastObjectId column only if hasNewData is false
+  // Enforce that lastObjectId should be 0 otherwise
+  bool updateLastObjectId = (!hasNewData);
+  if ( !updateLastObjectId && lastObjectId != 0 )  
+    throw RelationalException
+      ( "PANIC! Unexpected arguments to updateChannelTable", "RelationalObjectMgr" );
+
+  // Define the SET and WHERE clauses for the update using bind variables
+  coral::AttributeList updateData;
+  if ( updateLastObjectId )  
+    updateData.extend( "lastObjectId",
+                       typeIdToCoralType
+                       (RelationalChannelTable::columnTypeIds::lastObjectId) );
+  updateData.extend( "hasNewData",
+                     typeIdToCoralType
+                     (RelationalChannelTable::columnTypeIds::hasNewData) );
+  updateData.extend( "channel",
+                     typeIdToCoralType
+                     (RelationalChannelTable::columnTypeIds::channelId) );
+  if ( updateLastObjectId )  
+    updateData["lastObjectId"].setValue( lastObjectId );
+  updateData["hasNewData"].setValue( hasNewData );
+  updateData["channel"].setValue( channelId );
+  std::string setClause;
+  if ( updateLastObjectId )
+  {
+    setClause += RelationalChannelTable::columnNames::lastObjectId();
+    setClause += " = :lastObjectId";
+    setClause += ", ";
+  }
+  setClause += RelationalChannelTable::columnNames::hasNewData();
+  setClause += "= :hasNewData";
+  std::string whereClause = RelationalChannelTable::columnNames::channelId();
+  whereClause += "= :channel";
+  
+  // Execute the update
+  UInt32 updatedRows = queryMgr().updateTableRows
+    ( channelTableName, setClause, whereClause, updateData );
+    
+  if ( updatedRows == 0 ) {
+    // it's a new channel
+    coral::AttributeList data =
+      Record( RelationalChannelTable::tableSpecification() ).attributeList();
+    data[RelationalChannelTable::columnNames::channelId()].setValue
+      ( channelId );
+    data[RelationalChannelTable::columnNames::lastObjectId()].setValue
+      ( lastObjectId );
+    data[RelationalChannelTable::columnNames::hasNewData()].setValue
+      ( hasNewData );    
+    //data[RelationalChannelTable::columnNames::channelName()].setValue
+    //  ( std::string("") );
+    data[RelationalChannelTable::columnNames::channelName()].setNull(); // UK!
+    queryMgr().insertTableRow( channelTableName, data );
+  } else if ( updatedRows != 1 ) {
+    throw RowNotUpdated
+    ( "Could not update a row of the channels table", "RalDatabase" );
+  }
+}
+
+//-----------------------------------------------------------------------------
+
+void RelationalObjectMgr::bulkUpdateChannelTable
+( const std::string& channelTableName,
+  const std::map< ChannelId, unsigned int >& updateDataMap,
+  bool hasNewData ) const
+{
+  log() << "Bulk update channel table " << channelTableName 
+        << coral::MessageStream::endmsg;
+  
+  if ( updateDataMap.empty() ) {
+    log() << "Nothing to update" << coral::MessageStream::endmsg;
+    return;
+  }
+
+  // Update the lastObjectId column only if hasNewData is false
+  bool updateLastObjectId = (!hasNewData);
+  
+  // ATTEMPT BULK UPDATE
+  {    
+    // Define the SET and WHERE clauses for the update using bind variables
+    coral::AttributeList updateData;
+    if ( updateLastObjectId )
+      updateData.extend
+        ( "lastObjectId",
+          typeIdToCoralType
+          (RelationalChannelTable::columnTypeIds::lastObjectId) );
+    updateData.extend
+      ( "hasNewData",
+        typeIdToCoralType
+        (RelationalChannelTable::columnTypeIds::hasNewData) );
+    updateData.extend
+      ( "channel",
+        typeIdToCoralType
+        (RelationalChannelTable::columnTypeIds::channelId) );
+    std::string setClause;
+    if ( updateLastObjectId )
+    {
+      setClause += RelationalChannelTable::columnNames::lastObjectId();
+      setClause += " = :lastObjectId";
+      setClause += ", ";
+    }
+    setClause += RelationalChannelTable::columnNames::hasNewData();
+    setClause += "= :hasNewData";
+    std::string whereClause = RelationalChannelTable::columnNames::channelId();
+    whereClause += "= :channel";
+  
+    int dataCacheSize = 1000; // rows
+    boost::shared_ptr<IRelationalBulkOperation> query = 
+      db().queryMgr().bulkUpdateTableRows
+      ( channelTableName, setClause, whereClause, updateData, dataCacheSize );
+    
+    for ( std::map< ChannelId, unsigned int >::const_iterator
+            i = updateDataMap.begin(); i != updateDataMap.end(); ++i ) 
+    {
+      updateData["channel"].setValue( i->first );
+      if ( updateLastObjectId )
+        updateData["lastObjectId"].setValue( i->second );
+      updateData["hasNewData"].setValue( hasNewData );
+      query->processNextIteration();
+    }
+    query->flush();
+    
+  }
+
+  // CHECK BULK UPDATE - ELSE SINGLE ROW INSERT/UPDATE 
+  // (NB THIS CAN ONLY BE DONE IF HASNEWDATA IS TRUE!)
+  if ( hasNewData )
+  {
+    // Get updated row count
+    RelationalQueryDefinition def;
+    //def.addSelectItems(...); // None - SELECT COUNT(*) FROM ( SELECT * ... )
+    def.addFromItem( channelTableName, "" );
+    std::string whereClause = 
+      RelationalChannelTable::columnNames::hasNewData() + " = :hasNewData";
+    def.setWhereClause( whereClause );
+    RecordSpecification whereDataSpec;
+    whereDataSpec.extend( "hasNewData", StorageType::Bool );
+    Record whereData( whereDataSpec );
+    whereData["hasNewData"].setValue( hasNewData );
+    def.setBindVariables( whereData );
+    UInt32 rowCount = queryMgr().countRows( def );
+    
+    // If the row count differs from what is expected, 
+    // insert/update channels one by one in the table
+    if ( rowCount != updateDataMap.size() ) 
+    {
+      log() << "Bulk update failed (rows updated=" << rowCount
+            << ", rows to be updated=" << updateDataMap.size() 
+            << "): use single row insert/update" 
+            << coral::MessageStream::endmsg;
+
+      // Fall back to the non-bulk channel update
+      for ( std::map< ChannelId, unsigned int >::const_iterator
+              i = updateDataMap.begin(); i != updateDataMap.end(); ++i ) 
+      {
+        ChannelId channel = i->first;
+        log() << "Insert or update channel " << channel 
+              << coral::MessageStream::endmsg;
+        updateChannelTable
+          ( channelTableName, channel, i->second, hasNewData );
+      }
+    }
+  }
+  
+}
+
+//-----------------------------------------------------------------------------
+
+void RelationalObjectMgr::bulkUpdateObjectTableIov
+( const std::string& objectTableName,
+  const std::map<unsigned int,ValidityKey>& objectIdNewUntil ) const
+{
+  log() << "Bulk update IOVs in table " << objectTableName 
+        << coral::MessageStream::endmsg;
+  
+  if ( objectIdNewUntil.empty() ) {
+    log() << "Nothing to update" << coral::MessageStream::endmsg;
+    return;
+  }
+  
+  // Define the SET and WHERE clauses for the update using bind variables
+  // NB: Oracle execution plan, from interactive Benthic test, uses
+  // fast access via the 1D index on objectId
+  // (UPDATE STATEMENT, UPDATE, INDEX UNIQUE SCAN)
+  coral::AttributeList updateData;
+  updateData.extend
+    ( "until",
+      typeIdToCoralType(RelationalObjectTable::columnTypeIds::iovUntil) );
+  updateData.extend
+    ( "objId",
+      typeIdToCoralType(RelationalObjectTable::columnTypeIds::objectId) );
+  std::string setClause = RelationalObjectTable::columnNames::iovUntil();
+  setClause += "= :until";
+  setClause += ", ";
+  setClause += RelationalObjectTable::columnNames::lastModDate();
+  setClause += " = " + queryMgr().serverTimeClause();
+  std::string whereClause = RelationalObjectTable::columnNames::objectId();
+  whereClause += "= :objId";
+  
+  int dataCacheSize = 100; // rows
+  boost::shared_ptr<IRelationalBulkOperation> query = 
+    db().queryMgr().bulkUpdateTableRows
+    ( objectTableName, setClause, whereClause, updateData, dataCacheSize );
+                                            
+  for ( std::map<unsigned int,ValidityKey>::const_iterator
+        i = objectIdNewUntil.begin(); i != objectIdNewUntil.end(); ++i ) {
+    updateData["objId"].setValue( i->first );
+    updateData["until"].setValue( i->second );
+    query->processNextIteration();
+  }
+  query->flush();
+  
+}
+
+//-----------------------------------------------------------------------------
+
+// TODO Andrea/Romain: do we really need channelId here?
+// Roman noted that the 'SELECT IN' query could be rewritten without the
+// loop on the channel table... but maybe actually what needs to be done
+// is to keep the loop on the channels table and remove the selection
+// on channelId in the WHERE clause (update all channels in bulk)?
+
+bool RelationalObjectMgr::bulkUpdateObjectTableNewHeadId
+( const std::string& objectTableName,
+  const std::string& channelTableName,
+  const SOVector& updateNewHeads,
+  unsigned int userTagId ) const
+{
+  log() << "Bulk update IOV table" << coral::MessageStream::endmsg;
+
+  // Bind variable values for the SET and WHERE clauses 
+  coral::AttributeList updateData;
+  updateData.extend
+    ( "newHeadId",
+      typeIdToCoralType( RelationalObjectTable::columnTypeIds::newHeadId ) );
+  updateData.extend
+    ( "channel",
+      typeIdToCoralType( RelationalObjectTable::columnTypeIds::channelId ) );
+  updateData.extend
+    ( "userTagId",
+      typeIdToCoralType( RelationalObjectTable::columnTypeIds::userTagId ) );
+  updateData.extend
+    ( "userTagId1",
+      typeIdToCoralType( RelationalObjectTable::columnTypeIds::userTagId ) );
+  updateData.extend
+    ( "since1",
+      typeIdToCoralType( RelationalObjectTable::columnTypeIds::iovSince ) );
+  updateData.extend
+    ( "since2",
+      typeIdToCoralType( RelationalObjectTable::columnTypeIds::iovSince ) );
+  updateData.extend
+    ( "until1",
+      typeIdToCoralType( RelationalObjectTable::columnTypeIds::iovUntil ) );
+  updateData.extend
+    ( "since3",
+      typeIdToCoralType( RelationalObjectTable::columnTypeIds::iovSince ) );
+
+  // Prepare the SET clause
+  std::string setClause = RelationalObjectTable::columnNames::newHeadId();
+  setClause += "= :newHeadId";
+  setClause += ", ";
+  setClause += RelationalObjectTable::columnNames::lastModDate();
+  setClause += " = " + queryMgr().serverTimeClause();
+  
+  // Prepare the WHERE clause
+  std::string whereClause;
+  if ( queryMgr().databaseTechnology() == "MySQL" ||
+       getenv( "COOL_TASK6086_DISABLERBUPDATE" ) )
+  {
+    // Prepare the WHERE clause (COOL230 all backends and COOL231 MySQL)
+    whereClause = RelationalObjectTable::columnNames::channelId();
+    whereClause += "= :channel";
+    whereClause += " AND ";
+    whereClause += RelationalObjectTable::columnNames::userTagId();
+    whereClause += "= :userTagId";
+    whereClause += " AND ";
+    whereClause += RelationalObjectTable::columnNames::newHeadId();
+    whereClause += "= 0";
+    whereClause += " AND ";  
+    // Also see SimpleObject::overlaps for this clause
+    std::string s = RelationalObjectTable::columnNames::iovSince();
+    std::string u = RelationalObjectTable::columnNames::iovUntil();
+    whereClause += "(";
+    whereClause += "( ( " + s + " <= :since1 ) AND ( :since2 < " +u+ " ) )";
+    whereClause += " OR ( ( :since3 <= " +s+ " ) AND ( " +s+ " < :until1 ) )";
+    whereClause += ")";
+  }
+  else 
+  {
+    std::string schemaPrefix = "";
+    if ( queryMgr().schemaName() != "" ) 
+      schemaPrefix = queryMgr().schemaName() + ".";
+
+    // Prepare the WHERE clause (COOL231 Oracle/Frontier/SQLite by Romain)
+    // Latest change by Andrea: MERGE subqueries to simplify the SQL query:
+    // result is very similar to RelationaObjectTable::queryDefinitionGeneric
+    whereClause = RelationalObjectTable::columnNames::objectId();
+    whereClause += " IN ( SELECT ";
+    whereClause += "/*+ QB_NAME(BROWSE3) ";
+    if ( queryMgr().databaseTechnology() == "Oracle" ||
+         queryMgr().databaseTechnology() == "frontier" ) 
+    {
+      whereClause += "INDEX_RS_ASC(@BROWSE3 COOL_I3@BROWSE3 (USER_TAG_ID ";
+      whereClause += "NEW_HEAD_ID CHANNEL_ID IOV_SINCE IOV_UNTIL)) ";
+      whereClause += "LEADING(@BROWSE3 COOL_C2@BROWSE3 COOL_I3@BROWSE3) ";
+      whereClause += "USE_NL(@BROWSE3 COOL_I3@BROWSE3) ";
+      whereClause += "INDEX(@MAX1 COOL_I1@MAX1 (USER_TAG_ID ";
+      whereClause += "NEW_HEAD_ID CHANNEL_ID IOV_SINCE IOV_UNTIL)) ";
+    }
+    whereClause += "*/ ";    
+    whereClause += "COOL_I3.";
+    whereClause += RelationalObjectTable::columnNames::objectId();
+    whereClause += " FROM " ;
+    whereClause += schemaPrefix + channelTableName + " COOL_C2, ";
+    whereClause += schemaPrefix + objectTableName + " COOL_I3 ";
+    whereClause += "WHERE COOL_C2.CHANNEL_ID=:channel ";
+    whereClause += "AND COOL_I3.USER_TAG_ID=:userTagId ";
+    whereClause += "AND COOL_I3.NEW_HEAD_ID=0 ";
+    whereClause += "AND COOL_I3.CHANNEL_ID=COOL_C2.CHANNEL_ID ";
+    whereClause += "AND COOL_I3.IOV_SINCE>= " ;
+    whereClause += "COALESCE( ";
+    whereClause += "( SELECT /*+ QB_NAME(MAX1) */ ";
+    whereClause += "MAX(COOL_I1.IOV_SINCE) FROM ";
+    whereClause += schemaPrefix + objectTableName + " COOL_I1 ";
+    whereClause += "WHERE  ";
+    whereClause += "COOL_I1.USER_TAG_ID= :userTagId1 AND ";
+    whereClause += "COOL_I1.NEW_HEAD_ID=0 AND ";
+    whereClause += "COOL_I1.CHANNEL_ID=COOL_C2.CHANNEL_ID AND ";
+    whereClause += "COOL_I1.IOV_SINCE<=:since1 ) ";
+    whereClause += ",:since2) ";    
+    whereClause += "AND COOL_I3.IOV_SINCE<:until1 ";
+    whereClause += "AND COOL_I3.IOV_UNTIL>:since3 ";
+    whereClause += " ) ";
+  }
+  
+  int dataCacheSize = 100; // rows
+  boost::shared_ptr<IRelationalBulkOperation> query = 
+    db().queryMgr().bulkUpdateTableRows
+    ( objectTableName, setClause, whereClause, updateData, dataCacheSize );
+  //std::cout << "*** setClause: " << setClause << std::endl;
+  //std::cout << "*** whereClause: " << whereClause << std::endl;
+
+  ObjectId minNewHeadId = 0;
+  for ( SOIterator interval =  updateNewHeads.begin();
+        interval != updateNewHeads.end();
+        ++interval) 
+  {
+    // where data
+    updateData["channel"].setValue( (unsigned int) interval->channelId );
+    updateData["userTagId"].setValue( userTagId );
+    updateData["userTagId1"].setValue( userTagId );
+    updateData["since1"].setValue( interval->since );
+    updateData["since2"].setValue( interval->since );
+    updateData["since3"].setValue( interval->since );
+    updateData["until1"].setValue( interval->until );
+    // set data
+    updateData["newHeadId"].setValue( interval->objectId );
+    if ( minNewHeadId == 0 || interval->objectId < minNewHeadId )
+      minNewHeadId = interval->objectId;
+    //std::cout << " [ " << interval->since 
+    //          << ", " << interval->until << " [ oID "
+    //          << interval->objectId << std::endl;
+    query->processNextIteration();
+  }
+  query->flush();
+
+  // Check if any rows have been updated
+  bool updated = false;
+  {
+    RelationalQueryDefinition checkDef;
+    // This triggers bug #43528
+    //std::string schemaPrefix = "";
+    //if ( queryMgr().schemaName() != "" ) 
+    //  schemaPrefix = queryMgr().schemaName() + ".";
+    //checkDef.addFromItem( schemaPrefix + objectTableName );
+    checkDef.addFromItem( objectTableName );
+    checkDef.setWhereClause
+      ( RelationalObjectTable::columnNames::userTagId() + "=:userTagId AND " +
+        RelationalObjectTable::columnNames::newHeadId() + ">=:minNewHeadId" );
+    RecordSpecification checkDataSpec;
+    checkDataSpec.extend
+      ( "userTagId", RelationalObjectTable::columnTypeIds::userTagId );
+    checkDataSpec.extend
+      ( "minNewHeadId", RelationalObjectTable::columnTypeIds::newHeadId );
+    Record checkData( checkDataSpec );
+    checkData["userTagId"].setValue( userTagId );
+    checkData["minNewHeadId"].setValue( minNewHeadId );
+    checkDef.setBindVariables( checkData );
+    UInt32 updatedRows = queryMgr().countRows( checkDef );
+    if ( updatedRows > 0 ) updated = true;
+    //std::cout << "Number of updated rows: " << updatedRows << std::endl;
+  }
+  return updated;
+}
+
+//-----------------------------------------------------------------------------
+
+int RelationalObjectMgr::truncateObjectValidity
+( const RelationalFolder* folder,
+  const ValidityKey& until,
+  const ChannelSelection& channels ) const
+{ 
+  if ( folder->versioningMode() != FolderVersioning::SINGLE_VERSION )
+    throw RelationalException("Truncating of IOVs is only supported for "
+                              "single version Folders.",
+                              "RelationalObjectMgr"); 
+
+  bool readOnly = false;
+  RelationalTransaction transaction( transactionMgr(), readOnly );
+  RelationalObjectTable objectTable( &(queryMgr()), false, *folder );
+  std::map<unsigned int,ValidityKey> objectIdNewUntil;
+  int count=0;
+
+  // get all rows in [until, until[
+  const std::auto_ptr<IRelationalQueryDefinition> 
+    def( objectTable.queryDefinitionSV( until, until, channels ) );
+  std::vector<RelationalTableRow> result = queryMgr().fetchOrderedRows( *def, 
+      "SV truncate object validity");
+
+  // Process the result set
+  for ( std::vector<RelationalTableRow>::const_iterator
+      i = result.begin(); i != result.end(); ++i ) {
+    RelationalObjectTableRow obj( *i );
+    if ( obj.until() == ValidityKeyMax ) {
+      objectIdNewUntil[ obj.objectId() ] = until;
+      count++;
+    } else 
+      throw RelationalException("Truncating IOVs is only allowed for "
+                "until +inf IOVs", "RelationalObjectMgr"); 
+  }
+
+  // Bulk update the rows with open IOVs
+  bulkUpdateObjectTableIov( folder->objectTableName(), objectIdNewUntil );
+  transaction.commit();
+  return count;
+}
+
+//-----------------------------------------------------------------------------
+
+void RelationalObjectMgr::bulkInsertObjectTableRows
+( const std::string& objectTableName,
+  const std::vector<RelationalObjectTableRow>& rows,
+  const RecordSpecification& rowSpec ) const
+{
+  // Check that there are >0 rows to store
+  unsigned int nRows = rows.size();
+  if ( nRows == 0 ) {
+    log() << "No rows to store into table "
+          << objectTableName << coral::MessageStream::endmsg;
+    return;
+  }
+  log() << "Bulk inserting " << nRows << " rows into table "
+        << objectTableName << coral::MessageStream::endmsg;
+  
+  // Get a new IOV ID from the sequence
+  // Get also the corresponding database server system date
+  boost::shared_ptr<RelationalSequence> objectIdSeq
+    ( queryMgr().sequenceMgr().getSequence
+      ( RelationalObjectTable::sequenceName( objectTableName ) ) );
+  std::string sysDate = objectIdSeq->currDate();
+  
+  bool useBulkInserter = true;  
+  // Setup the relational table bulk inserter
+
+  // AV 07.03.2007 - fix for bug #24464 
+  // (record to be stored may have fewer fields and in a different order!)
+  // [NB - this may lead to C++ performance degradations]
+  //coral::AttributeList data( rows[0].data() );
+  RecordSpecification tableSpec =
+    RelationalObjectTable::tableSpecification( rowSpec );
+  coral::AttributeList data( Record( tableSpec ).attributeList() );
+
+  boost::shared_ptr<IRelationalBulkOperation> bulkInserter;
+  if ( useBulkInserter )
+    bulkInserter = db().queryMgr().bulkInsertTableRows
+      ( objectTableName, data, nRows );
+
+  // Iterate through the objects and register them for insertion
+  std::vector<RelationalObjectTableRow>::const_iterator row;
+  for ( row = rows.begin(); row != rows.end(); ++row ) {
+  
+    // AV 30.11.2006 - fast is not the fastest! we should use share?
+    //data.fastCopyData( row->data() );
+
+    // AV 07.03.2007 - fix for bug #24464 
+    // (record to be stored may have fewer fields and in a different order!)
+    for ( coral::AttributeList::iterator 
+            iAtt = data.begin(); iAtt != data.end(); ++iAtt )
+      iAtt->setNull();
+    for ( coral::AttributeList::const_iterator 
+            iAtt = row->data().begin(); iAtt != row->data().end(); ++iAtt )
+    {
+      const std::string& name = iAtt->specification().name();
+      try {
+        data[name].fastCopy( *iAtt );
+      }
+      catch ( coral::AttributeListException& ) {
+        throw RelationalException
+          ( "A field with name '" + name 
+            + "' does not exist in the folder payload specification",
+            "RelationalObjectMgr" );
+      }      
+    }
+    
+    // TEMPORARY! sysInsTime and lastUpdate as string rather than DATE
+    data[RelationalObjectTable::columnNames::sysInsTime()]
+      .setValue( sysDate );
+    data[RelationalObjectTable::columnNames::lastModDate()]
+      .setValue( sysDate );
+    
+    // Verbose printout: print the full row that is being inserted into the DB
+    // TEMPORARY? Speed up insertion by disabling IOV streaming to MsgStream
+    /*
+     std::ostringstream dataStream;
+     data.print( dataStream );
+     log() << "Insert into the IOV table the following AttributeList: "
+     << dataStream.str() << coral::MessageStream::endmsg;
+     */
+    
+    // TEMPORARY? Will RAL do this as well?
+    // Check that all column values are within their allowed range
+    rowSpec.validate( data, false ); // data only ( no spec size )
+    
+    // Insert the new object in the IOV table
+    if ( useBulkInserter ){
+      bulkInserter->processNextIteration();
+    } else {
+      queryMgr().insertTableRow( objectTableName, data );
+    }
+  }
+  
+  // Flush the bulk inserter
+  if ( useBulkInserter )
+    bulkInserter->flush();
+  
+}
+
+//-----------------------------------------------------------------------------
+
+/// Channel comparison functor to compare RelationalObjectPtrs
+class eq_channel 
+  : public std::unary_function<RelationalObjectPtr, bool> 
+{
+public:
+  eq_channel( const ChannelId& channel ) : m_channelid( channel ) {}
+  bool operator()( const RelationalObjectPtr& obj ) const 
+  { 
+    return ( obj->channelId() == m_channelid  ); 
+  }
+private:
+  ChannelId m_channelid;
+};
+
+//-----------------------------------------------------------------------------
+
+void RelationalObjectMgr::updateSingleVersionIovs
+( RelationalFolder* folder,
+  const std::pair<ChannelIdValidityKeyMap,ChannelIdObjectIdMap>& intersectors,
+  const std::vector<RelationalObjectPtr>& objects ) const
+{
+  RelationalObjectTable objectTable( &(queryMgr()), false, *folder );
+  log() << "Update SV IOVs" << coral::MessageStream::endmsg;
+  
+  // The first map contains the new 'since' per channel for update in the
+  // channel table
+  const ChannelIdValidityKeyMap& channelSince = intersectors.first;
+  // The second map contains the new 'lastObjectId' per channel for update in 
+  // the channel table. We make a copy, because it potentially has to be 
+  // modified in the 'back-insertion' algorithm.
+  ChannelIdObjectIdMap channelLastObjectId = intersectors.second;
+  
+  // Flag the channels that have new data for the later join
+  
+
+  // Implementation of task #2009, comment #13:
+  // Try the bulk insertion first, check by counting if the expected number
+  // of channels has been flagged in the channels table and if so proceed
+  // with the bulk insertion.
+  // If the count is not what expected, fall back to single update version.
+  {
+    // Flag the channels in need of an update in the channels table
+    bool hasNewData = true;
+    unsigned int lastObjectId = 0; // dummy - ignored
+    std::map< ChannelId, unsigned int > updateDataMap;
+    for ( ChannelIdValidityKeyMap::const_iterator
+          i = channelSince.begin(); i != channelSince.end(); ++i ) 
+    {
+      const ChannelId& channel = i->first;
+      updateDataMap[channel] = lastObjectId;
+    }
+    bulkUpdateChannelTable
+      ( folder->channelTableName(), updateDataMap, hasNewData );    
+  }
+  
+  // Fetch the 'last row' for each channel with new data
+  std::vector<RelationalObjectTableRow> lastRows;
+  fetchLastRowsWithNewData( folder, lastRows );
+  
+  // This map records the object ids in need of an until update
+  std::map<unsigned int,ValidityKey> objectIdNewUntil;
+
+  // Update the IOVs of the last rows if required
+  for ( std::vector<RelationalObjectTableRow>::const_iterator
+        row = lastRows.begin(); row != lastRows.end(); ++row ) {
+    // check IOV
+    // bulk update if necessary
+    ChannelId channel = row->channelId();
+    ChannelIdValidityKeyMap::const_iterator
+    intersector = channelSince.find( channel );
+    ValidityKey newUntil = 
+      intersector != channelSince.end() 
+      ? intersector->second
+      : // this can't possibly happen as we only select rows that have
+        // previously been marked from this very map. This throw only
+        // completes the code path.
+      throw RelationalException( "Channel without corresponding "
+                                 "intersector", "RalDatabase" );
+    if ( row->until() == ValidityKeyMax &&
+         row->since() < newUntil ) {
+      // Record this object id for IOV update
+      objectIdNewUntil[row->objectId()] = newUntil;
+    } else if ( newUntil < row->until() ) {
+      // task #3138: Change SV requirement to "do not overlap" 
+      // instead of "do not backinsert"
+      
+      // Prepare a channel comparator to filer on the current channel
+      eq_channel channel_cmp( channel );
+      
+      // Find all objects in the current channel and count them
+      std::vector<RelationalObjectPtr>::const_iterator
+      i = find_if( objects.begin(), objects.end(), channel_cmp );
+      int count = 0;
+      RelationalObjectPtr obj = *i;
+      if ( i != objects.end() ) {
+        ++count;
+        if ( find_if( ++i, objects.end(), channel_cmp ) != objects.end() ) {
+          ++count;
+        }
+      }
+      
+      // We can do back-insertion only if there's no more than one IOV in
+      // this channel
+      if ( count == 1 ) {
+        // Select [since, until[ and check for 0 iovs -- otherwise we have
+        // an overlap
+        ValidityKey until = obj->until();
+        // We want to select [since, until[ but the countRows method selects
+        // [since, until] (i.e. including the upper bound. Therefore we need
+        // to decrement the until value. This might seem dodgy but:
+        // 1. it allows us to reuse the count query instead of writing a new
+        //    one with :until < iov_until instead of '<='
+        // 2. it is safe as long as the ValidityKey type defines operator--.
+        //    Currently it's an integer type and therefore safe. A note
+        //    regarding this has been added to the type definition. The only
+        //    foreseeable problem with this change is if ValidityKey should
+        //    ever turn into an 'non-decrementable' type, e.g. a float.
+        //    If that should happen, implementing operator-- will not be 
+        //    possible and the warning placed at ValidityKey's place of 
+        //    definition will lead to this place.
+        --until;
+        // Count the objects in [since, until[
+        const std::auto_ptr<IRelationalQueryDefinition> 
+          def( objectTable.queryDefinitionSV( obj->since(), until, channel ) );
+        //const std::auto_ptr<IRelationalQueryDefinition> 
+        //  def( objectTable.queryDefinitionGeneric
+        //       ( obj->since(), until, channel ) );
+        int count = queryMgr().countRows( *def, "SV object count" );
+        if ( count != 0 ) {
+          // We have a collision
+          log() << coral::Verbose
+                << "Exception - overlapping intervals: new until = "
+                << newUntil << ", last until = " 
+                << row->until() << coral::MessageStream::endmsg;
+          throw RelationalException
+            ( "Back-insertion collision: "
+              "overlapping intervals not allowed in SINGLE_VERSION mode",
+              "RalDatabase" );
+        }
+        // No collision, we can back-insert. We also have to update the 
+        // 'lastObjectId' update map for this channel, because it currently
+        // has the newly (back-inserted) object id recorded for this channel.
+        // Since we're back-inserted it's not the true 'lastObjectId'. This
+        // is actually the 'row' object (the current iterator of lastRows in
+        // this loop) which has been fetched via 'fetchLastRowsWithNewData'.
+        channelLastObjectId[channel] = row->objectId();
+      } else {
+        log() << coral::Verbose
+              << "Exception - overlapping intervals: new until = "
+              << newUntil << ", last until = " << row->until() 
+              << coral::MessageStream::endmsg;
+        throw RelationalException
+          ( "Back-insertion not possible due to multiple objects in channel" );
+      }
+    }
+  }
+  
+  // Bulk update the rows with open IOVs
+  bulkUpdateObjectTableIov( folder->objectTableName(), objectIdNewUntil );
+  
+  // Bulk update the channel table data
+  bool hasNewData = false;
+  std::map< ChannelId, unsigned int > updateDataMap;
+  for ( ChannelIdObjectIdMap::const_iterator
+        i = channelLastObjectId.begin(); i != channelLastObjectId.end(); ++i )
+  {
+    const ChannelId& channel = i->first;
+    const unsigned int& lastObjectId = i->second;
+    updateDataMap[channel] = lastObjectId;
+  }
+  bulkUpdateChannelTable
+    ( folder->channelTableName(), updateDataMap, hasNewData );
+
+}
+
+//-----------------------------------------------------------------------------
+
+void RelationalObjectMgr::fetchLastRowsWithNewData
+( RelationalFolder* folder,
+  std::vector<RelationalObjectTableRow>& rows ) const 
+{
+  // NEW (with RelationalQueryDefinition)
+  RelationalQueryDefinition def;
+
+  // Use a hint to stabilize the execution plan (task #5654) 
+  def.setHint( "/*+ INDEX(C) INDEX_RS_ASC(O) LEADING(C O) USE_NL(C O) */" );
+  //def.setHint( "/*+ INDEX(O) */" ); // BAD (Oracle bug 4323868)
+  //def.setHint( "/*+ LEADING(C O) USE_HASH(C O) */" ); // BAD (as COOL_2_2_1)
+
+  RelationalObjectTable objectTable( &(queryMgr()), false, *folder );
+  def.addSelectItems( objectTable.tableSpecification(), "O." );
+  def.setResultSetSpecification( objectTable.tableSpecification() );
+
+  def.addFromItem( folder->objectTableName(), "O" );
+  def.addFromItem( folder->channelTableName(), "C" );
+
+  std::string whereClause;
+  whereClause +=
+    "C." + RelationalChannelTable::columnNames::hasNewData() 
+    + " = :hasNewData";
+  whereClause += " AND ";
+  whereClause +=
+    "C." + RelationalChannelTable::columnNames::lastObjectId() + " = "
+    "O." + RelationalObjectTable::columnNames::objectId();
+  def.setWhereClause( whereClause );
+  
+  def.addOrderItem
+    ( "C." + RelationalChannelTable::columnNames::channelId() + " ASC" );
+  
+  RecordSpecification whereDataSpec;
+  whereDataSpec.extend( "hasNewData", StorageType::Bool );
+  Record whereData( whereDataSpec );
+  whereData["hasNewData"].setValue( true );
+  def.setBindVariables( whereData );
+
+  std::vector<RelationalTableRow> result = queryMgr().fetchOrderedRows( def );
+
+  // Process the result set
+  for ( std::vector<RelationalTableRow>::const_iterator
+        i = result.begin(); i != result.end(); ++i ) {
+    rows.push_back( RelationalObjectTableRow( *i ) );
+  }
+
+}
+
+//-----------------------------------------------------------------------------
+
+void RelationalObjectMgr::__storeObjects
+( RelationalFolder* folder,
+  const std::vector<RelationalObjectPtr>& objects,
+  bool userTagOnly ) const
+{
+  log() << "Store " << objects.size() << " objects into folder "
+        << folder->fullPath() << coral::MessageStream::endmsg;
+  FolderVersioning::Mode versioningMode = folder->versioningMode();  
+  if ( versioningMode == FolderVersioning::SINGLE_VERSION ) 
+  {
+    if ( userTagOnly )
+    {
+      std::stringstream msg;
+      msg << "Single version folder: userTagOnly is meaningless";
+      throw RelationalException( msg.str(), 
+                                 "RelationalObjectMgr::storeObjects" );
+    }
+    __storeSingleVersionObjects( folder, objects );  
+  } 
+  else if ( versioningMode == FolderVersioning::MULTI_VERSION ) 
+  {
+    __storeMultiVersionObjects( folder, objects, userTagOnly );
+  } 
+  else 
+  {
+    std::stringstream s;
+    s << "invalid versioning mode: " << versioningMode;
+    throw RelationalException( s.str(), "RalDatabase" );
+  }
+}
+
+//-----------------------------------------------------------------------------
+
+void RelationalObjectMgr::__storeSingleVersionObjects
+( RelationalFolder* folder,
+  const std::vector<RelationalObjectPtr>& objects ) const
+{
+  log() << "Store " << objects.size() << " SV Objects into folder '"
+        << folder->fullPath() << "'" << coral::MessageStream::endmsg;
+  
+  if ( objects.empty() ) return;  
+  // check for a user tag being specified
+  for ( std::vector<RelationalObjectPtr>::const_iterator 
+        i = objects.begin(); i != objects.end(); ++i ) {
+    if ( (*i)->userTagName() != "" ) {
+      std::stringstream s;
+      s << "Cannot store a SV object with user tag: " << (*i)->userTagName();
+      throw FolderIsSingleVersion
+        ( folder->fullPath(), s.str(), "RalDatabase" );
+    }
+  }  
+  
+  RecordSpecification rowSpec = folder->payloadSpecification();
+  
+  std::vector<RelationalObjectTableRow> rows;
+  
+  // Set the objectIdOffset: We start from the current sequence value +1
+  boost::shared_ptr<RelationalSequence> objectIdSeq
+    ( queryMgr().sequenceMgr().getSequence
+      ( RelationalObjectTable::sequenceName( folder->objectTableName() ) ) );
+  unsigned int objectIdOffset = objectIdSeq->currVal() +1;
+  objectIdSeq->nextVal( objects.size() );
+  
+  std::pair<ChannelIdValidityKeyMap,ChannelIdObjectIdMap>
+    intersectors( processSingleVersionObjects
+                  ( objects, rows, objectIdOffset ) );
+  
+  updateSingleVersionIovs( folder, intersectors, objects );
+  
+  bulkInsertObjectTableRows( folder->objectTableName(), rows, rowSpec );
+}
+
+//-----------------------------------------------------------------------------
+
+void RelationalObjectMgr::__storeMultiVersionObjects
+( RelationalFolder* folder,
+  const std::vector<RelationalObjectPtr>& objects,
+  bool userTagOnly ) const
+{
+  log() << "Store " << objects.size() << " MV Objects into folder '"
+        << folder->fullPath() << "'" << coral::MessageStream::endmsg;
+  
+  if ( objects.empty() ) return;
+  
+  // confirm that all objects have the same tagName (if any)
+  std::string userTagName( objects[0]->userTagName() );
+  for ( std::vector<RelationalObjectPtr>::const_iterator 
+        i = objects.begin(); i != objects.end(); ++i ) 
+  {
+    if ( (*i)->userTagName() != userTagName ) 
+    {
+      std::stringstream s;
+      s << "Conflicting tag '" << (*i)->userTagName() << "' specified "
+        << "during bulk insertion";
+      throw RelationalException( s.str(), "RalDatabase" );
+    }
+  }
+  
+  // Determine user tag id (by fetching or creation)
+  // Any HEAD tag ("", "head", "HEAD", "Head"...) -> no user tag (userTagId=0)
+  // NB Cannot make a difference between "" and "HEAD"!!!
+  unsigned int userTagId;
+  bool partiallyLocked=false;
+  if ( IHvsNode::isHeadTag( userTagName ) ) 
+  {
+    userTagId = 0;
+  }
+  
+  // Proper user tag - check if tag exists or must be created
+  else 
+  {
+    bool createTag = false;
+    if ( ! tagMgr().existsTag( userTagName ) ) 
+    {
+      // Tag does not exist in any folder - create it
+      createTag = true;
+    }
+    else 
+    {
+      try 
+      {
+        // Tag exists in this folder - check if user tag or standard (HEAD) tag
+        RelationalTableRow tagRow =
+          tagMgr().fetchGlobalTagTableRow( folder->id(), userTagName );
+        userTagId = 
+          tagRow[RelationalTagTable::columnNames::tagId]
+          .data<unsigned int>();
+        // Throw TagIsLocked if the tag is locked
+        HvsTagLock::Status lockStatus = 
+          HvsTagLock::Status
+          ( tagRow[RelationalGlobalTagTable::columnNames::tagLockStatus]
+            .data<UInt16>() );
+        if ( lockStatus == HvsTagLock::LOCKED )
+          throw TagIsLocked
+            ( "Cannot store objects with user tag '" + userTagName + 
+              "': tag is locked", "RelationalObjectMgr" );
+        if ( lockStatus == HvsTagLock::PARTIALLYLOCKED )
+           partiallyLocked=true;
+        
+        // Tag is a standard tag in this folder - throw TagExists (can't mix!)
+        // TODO - performance (see task #4381)
+        if ( RelationalFolder::existsTagInObject2TagTable
+             ( queryMgr(), userTagId, folder->object2TagTableName() ) )
+          throw TagExists( userTagName, "RalDatabase" );
+        // Else tag exists already either because of user tag or HVS
+        // (should we check and throw a PANIC exception otherwise?)
+      } 
+      catch ( TagNotFound& ) 
+      {
+        // TEMPORARY! Eventually can use same tag in several folders!
+        // Tag exists in another folder - throw TagExists
+        throw TagExists( userTagName, "RalDatabase" );
+      }
+    }    
+    if ( createTag ) 
+    {
+      // Get a new tag ID and insert the new tag in the global tag table
+      // PERFORMANCE WARNING - createTag() will query existsTag() a 2nd time
+      std::string description = "";
+      HvsTagRecord userTag = 
+        //tagMgr().createTag( folder->id(), userTagName, description );
+        tagMgr().createTagAndLocalTag
+        ( folder->id(), userTagName, description, folder->tagTableName() );
+      userTagId = userTag.id(); 
+    }  
+  }  
+  
+  log() << "All MV Objects have the same user tag '"
+        << userTagName << "' (tagId=" << userTagId << ")" 
+        << coral::MessageStream::endmsg;
+  
+  // Set the objectIdOffset: We start from the current sequence value +1
+  boost::shared_ptr<RelationalSequence> objectIdSeq
+    ( queryMgr().sequenceMgr().getSequence
+      ( RelationalObjectTable::sequenceName( folder->objectTableName() ) ) );
+  unsigned int objectIdOffset = objectIdSeq->currVal() +1;
+  // Reserve ids for two system objects in addition to the user object
+  // and also leave room for the user tag ids:
+  // therefore 6*size()
+  objectIdSeq->nextVal( ObjectIdIncrement * objects.size() );
+  
+  std::vector<RelationalObjectTableRow> rows;
+  std::map<unsigned int, unsigned int> idToIndex;
+  
+  // Insert global head objects
+  // (append the global head rows to the 'rows' vector)
+  if ( ! userTagOnly )
+  {
+    std::vector<SimpleObject>
+      intersectors( processMultiVersionObjects
+                    ( objects, rows, objectIdOffset, idToIndex ) );  
+    mergeWithHead( folder, intersectors, rows, idToIndex );
+  }
+  
+  // Insert user tag head objects
+  // (append the user tag rows to the 'rows' vector)
+  if ( ! IHvsNode::isHeadTag( userTagName ) ) 
+  {
+    std::vector<RelationalObjectTableRow> userTagRows;
+    std::map<unsigned int, unsigned int> idToIndexUserTagRows;  
+
+    std::vector<SimpleObject> userTagIntersectors
+      ( processMultiVersionObjects( objects, 
+                                    userTagRows, 
+                                    objectIdOffset, 
+                                    idToIndexUserTagRows, 
+                                    userTagId,
+                                    partiallyLocked ) );
+    
+    // Compute the user tag head rows (to be appended to the 'rows' vector)
+    mergeWithHead( folder, userTagIntersectors, userTagRows, 
+                   idToIndexUserTagRows, userTagId, partiallyLocked );
+
+    // Append user tag head rows into the 'rows' vector
+    std::copy( userTagRows.begin(), 
+               userTagRows.end(), 
+               std::back_inserter( rows ) );    
+
+  }
+  
+  // Fill the channel table for MV folders (fix bug #23755).
+  // Analyse the 'rows' vector to extract the channels that need an update.
+  // BulkUpdate must be called twice - first with hasNewData==true (so that
+  // the single row update/insert can work) and then with hasNewData==false.
+  // For the first execution, lastObjectId must be set to 0
+  // (just use the map to indicate which channels are updated).
+  std::map< ChannelId, unsigned int > updateDataMap;
+  std::vector<RelationalObjectTableRow>::const_iterator row;
+  for ( row = rows.begin(); row != rows.end(); ++row ) 
+  {
+    const ChannelId& channel = row->channelId();
+    updateDataMap[channel] = 0;
+  }
+  bool hasNewData = true; 
+  bulkUpdateChannelTable
+    ( folder->channelTableName(), updateDataMap, hasNewData );
+  // For the second execution, compute the highest objectId in each channel
+  for ( row = rows.begin(); row != rows.end(); ++row ) 
+  {
+    const ChannelId& channel = row->channelId();
+    const unsigned int& objectId = row->objectId();
+    if ( updateDataMap[channel] < objectId )
+      updateDataMap[channel] = objectId;
+  }
+  hasNewData = false;
+  bulkUpdateChannelTable
+    ( folder->channelTableName(), updateDataMap, hasNewData );
+
+  // Now write all head rows from the 'rows' vector into the database
+  // (both the global head rows and the user tag rows)
+  bulkInsertObjectTableRows( folder->objectTableName(), 
+                             rows, 
+                             folder->payloadSpecification() );
+}
+
+//-----------------------------------------------------------------------------
+
+std::pair<ChannelIdValidityKeyMap, ChannelIdObjectIdMap>
+RelationalObjectMgr::processSingleVersionObjects
+( const std::vector<RelationalObjectPtr>& objects,
+  std::vector<RelationalObjectTableRow>& rows,
+  unsigned int objectIdOffset ) const
+{
+  // records the lowest 'since' per channel
+  ChannelIdValidityKeyMap lowestSince;
+  // records the last object id per channel
+  ChannelIdObjectIdMap lastObjectIds;
+  // records the last object id from the 'objects' stack that has been
+  // validated in a given channel
+  std::map<ChannelId,unsigned int> prevObjects;
+  rows.reserve( objects.size() );
+  
+  for ( unsigned int object_index = 0;
+        object_index < objects.size(); ++object_index ) {
+    
+    RelationalObjectPtr obj = objects[ object_index ];
+    
+    RelationalObjectTableRow row( obj );
+    row.setObjectId( object_index + objectIdOffset );
+    
+    ValidityKey since = row.since();
+    ValidityKey until = row.until();
+    
+    // Internal consistency check: since<until (NB: since=until NOT ALLOWED!)
+    if ( since >= until )
+      throw ValidityIntervalBackwards( since, until, "RalDatabase" );
+    
+    // Validity key checks
+    if ( since > ValidityKeyMax )
+      throw ValidityKeyOutOfBoundaries( since, "RalDatabase" );
+    if ( until > ValidityKeyMax )
+      throw ValidityKeyOutOfBoundaries( until, "RalDatabase" );
+    
+    std::map<ChannelId,unsigned int>::iterator
+      prevObj = prevObjects.find( row.channelId() );
+    if ( prevObj != prevObjects.end() ) {
+      
+      unsigned int index = prevObj->second;
+      
+      RelationalObjectTableRow& prevRow( rows[ index ] );
+      
+      if ( prevRow.until() == ValidityKeyMax &&
+           prevRow.since() < row.since() ) {
+        prevRow.setUntil( row.since() );
+      } else if ( prevRow.until() > row.since() ) {
+        log() << coral::Verbose
+              << "Exception - overlapping intervals: new since = "
+              << row.since() << ", last until = "
+              << prevRow.until() << coral::MessageStream::endmsg;
+        throw RelationalException
+          ( "Overlapping intervals not allowed in SINGLE_VERSION mode",
+            "RalDatabase" );
+      }
+    }
+    
+    prevObjects[ obj->channelId() ] = object_index;
+    
+    // update lowestSince map if there's no entry yet
+    if ( lowestSince.find( row.channelId() ) == lowestSince.end() ) {
+      lowestSince[ row.channelId() ] = row.since();
+    }
+    // update last object id
+    lastObjectIds[ row.channelId() ] = row.objectId();
+    
+    rows.push_back( row );
+  }
+  
+  return std::make_pair( lowestSince, lastObjectIds );
+}
+
+//-----------------------------------------------------------------------------
+
+std::vector<SimpleObject> 
+RelationalObjectMgr::processMultiVersionObjects
+( const std::vector<RelationalObjectPtr>& objects,
+  std::vector<RelationalObjectTableRow>& rows,
+  unsigned int objectIdOffset,
+  std::map<unsigned int, unsigned int>& idToIndex,
+  unsigned int userTagId,
+  bool partiallyLocked ) const
+{
+  
+  rows.reserve( objects.size() );
+  
+  // The head is the current top layer of the object stack
+  std::vector<SimpleObject> head;
+  
+  // The bottom is the list of object intervals as seen from 'below'
+  // -- think of it as the head if you invert the layers.
+  std::vector<SimpleObject> bottom;
+  
+  for ( unsigned int object_index = 0;
+        object_index < objects.size(); ++object_index ) {
+    
+    RelationalObjectPtr obj = objects[ object_index ];
+    
+    // Validity key checks
+    if ( obj->since() > ValidityKeyMax )
+      throw ValidityKeyOutOfBoundaries( obj->since(), "RalDatabase" );
+    if ( obj->until() > ValidityKeyMax )
+      throw ValidityKeyOutOfBoundaries( obj->until(), "RalDatabase" );
+    
+    // Objects in the rows vector are inserted with an
+    // object_id == 6*object_index + objectIdOffset
+    // to reserve object_ids that are possibly needed for system objecs
+    // created by mergeWithHead (maximum of two system objects per user object)
+    // Additional room is reserved for ids need by user tags in the future
+    // The object_id 0 is reserved for 'null' references
+    // (objectIdOffset is > 0)
+    RelationalObjectTableRow currentRow( obj );
+    if ( userTagId == 0 ) {
+      currentRow.setObjectId
+      ( ObjectIdIncrement * object_index + objectIdOffset );
+    } else {
+      // user tag objects have an objectId offset of 3
+      currentRow.setObjectId
+      ( ObjectIdIncrement * object_index + objectIdOffset +3 );
+    }
+    currentRow.setUserTagId( userTagId );
+    idToIndex[ currentRow.objectId() ] = rows.size();
+    rows.push_back( currentRow );
+    
+    SimpleObject currentObject( currentRow.objectId(),
+                                currentRow.channelId(),
+                                currentRow.since(),
+                                currentRow.until() );
+    
+    // Check which objects in the head are affected
+    std::vector<SimpleObject> affectedObjs = currentObject.intersect( head );
+    
+    if ( partiallyLocked && affectedObjs.size()!=0)
+        throw  TagIsLocked
+            ( "Cannot store objects with user tag: " 
+              "tag is partially locked "
+              "and there are overlapping IOVs in bulk insert",
+              "RelationalObjectMgr" );
+            
+    // Add the current object to the head and, if it 'falls through' the
+    // current head, i.e. does not intersect with it, also to the bottom
+    head.push_back( currentObject );
+    if ( affectedObjs.empty() ) bottom.push_back( currentObject );
+    
+    for ( std::vector<SimpleObject>::const_iterator
+          headObj = affectedObjs.begin();
+          headObj != affectedObjs.end();
+          ++headObj ) {
+      
+      unsigned int headObjIndex = idToIndex[ headObj->objectId ];
+      
+      // Update the newHeadId of the intersected head object and remove
+      // it from the head
+      rows[headObjIndex].setNewHeadId( currentObject.objectId );
+      head.erase( remove( head.begin(), head.end(), *headObj ) );
+      
+      // Cut the examined headObj with the currentObject. Create system
+      // objects from the intervals (one or two), set their originalId
+      // and add them to the head and the rows.
+      SOVector topVisibleIntervals = currentObject.filter( *headObj );
+      for ( SOIterator interval = topVisibleIntervals.begin();
+            interval != topVisibleIntervals.end();
+            ++interval ) {
+        // assign the object id in a fixed order:
+        // [ sysobj: id+1 ][ userobj: id ][ sysobj: id+2 ]
+        unsigned int objectId = interval->since < currentObject.since
+        ? currentObject.objectId +1
+        : currentObject.objectId +2;
+        idToIndex[ objectId ] = rows.size();
+        log() << "Create system object: [" 
+              << interval->since << "," << interval->until << "]" 
+              << coral::MessageStream::endmsg;
+        RelationalObjectTableRow
+          sysObjRow = createSystemObjectRow
+          ( rows[headObjIndex], objectId, interval->since, interval->until );
+        sysObjRow.setNewHeadId( 0 );
+        rows.push_back( sysObjRow );
+        SimpleObject sysObj( sysObjRow.objectId(),
+                             sysObjRow.channelId(),
+                             sysObjRow.since(),
+                             sysObjRow.until() );
+        head.push_back( sysObj );
+        // Sort the head to ensure a reproducible order of system objects,
+        // such that the lower end system object always comes before the
+        // upper end system object. One could perhaps avoid the sort and
+        // bookkeep the indexes but sort is most likely not a performance
+        // problem.
+        sort( head.begin(), head.end(), lt_since() );
+      }
+      
+      // Check which parts of the current object 'fall through' the current
+      // bottom -- i.e. which parts are visible from below --
+      // and add them to the head.
+      SOVector visibleIntervals = currentObject.visibleThrough( bottom );
+      bottom.insert
+        ( bottom.end(), visibleIntervals.begin(), visibleIntervals.end() );
+      
+    } // for ( affectedObjs.begin() )
+    
+  } // for ( objects.begin()
+  
+  return bottom;
+}
+
+//-----------------------------------------------------------------------------
+
+// Types used in mergeWithHead
+struct sIOV 
+{
+  ValidityKey since;
+  ValidityKey until;
+  unsigned int count;
+};
+typedef std::map<ValidityKey,RelationalObjectTableRow*> keyRowMap;
+
+//-----------------------------------------------------------------------------
+
+void RelationalObjectMgr::mergeWithHead
+( RelationalFolder* folder,
+  const std::vector<SimpleObject> splitters,
+  std::vector<RelationalObjectTableRow>& rows,
+  std::map<unsigned int, unsigned int>& idToIndex,
+  unsigned int userTagId,
+  bool partiallyLocked ) const
+{
+  log() << "Merge with HEAD" << coral::MessageStream::endmsg;
+
+  // The transient head is a list of head objects created from intersecting
+  // the persistent head with the 'splitters' intervals
+  SOVector transHead;
+  RelationalObjectTable objectTable( &(queryMgr()), false, *folder );
+ 
+  // load relevant objects of the persistent head into a map which 
+  // can be accessed by channel -> iov_since
+  // there are now overlaps, so by this we can easily find the IOV
+  // which corresponds to a point in time
+  std::map<ChannelId, keyRowMap > channelIovRowMap;
+
+  // owner of the row vectors! 
+  // they are automatically deleted when the method is finished 
+  boost::scoped_array< std::auto_ptr< std::vector<RelationalObjectTableRow> > >
+    channelsPersHead( 0 );
+
+  // find min and max IOV for each channel
+  std::map<ChannelId, sIOV> channelIov;
+  for ( SOIterator splitter = splitters.begin();
+      splitter != splitters.end();
+      ++splitter ) {
+    std::map<ChannelId, sIOV>::iterator it=
+      channelIov.find(splitter->channelId);
+
+    if ( it == channelIov.end() ) {
+      // channel doesn't exist
+      struct sIOV iov;
+      iov.since=splitter->since;
+      iov.until=splitter->until;
+      iov.count=1;
+      channelIov[splitter->channelId]=iov;
+    } else {
+      if ( it->second.since > splitter->since )
+        it->second.since = splitter->since;
+      if ( it->second.until < splitter->until )
+        it->second.until = splitter->until;
+      ++it->second.count;
+    }
+  }
+
+  // allocate array of auto_ptrs to vectors
+  channelsPersHead.reset
+    ( new std::auto_ptr< std::vector<RelationalObjectTableRow> >
+      [ channelIov.size() ]() );
+
+  // maximum number of rows that will be prefetched
+  unsigned int maxRows=1000;
+  if ( getenv("COOL_MVINSERTION_PREFETCH_MAXROWS") ) {
+    
+    std::stringstream rows( getenv("COOL_MVINSERTION_PREFETCH_MAXROWS" ) ); 
+    rows >> maxRows;
+    if (rows.fail())
+       log() << coral::Error << "setting MV insertion prefetch maxRows to '" 
+             <<  getenv("COOL_MVINSERTION_PREFETCH_MAXROWS" )
+             <<"' failed. Current maxRows value: " << maxRows 
+             << coral::MessageStream::endmsg;
+    else 
+      log() << coral::Info << "setting MV insertion prefetch maxRows to " 
+            << maxRows << coral::MessageStream::endmsg;
+    log() << coral::Debug;
+  }
+
+  int idx=0;      
+  // load IOVs for all channels for which splitter exits
+  for (std::map<ChannelId, sIOV>::iterator 
+         it = channelIov.begin();
+       it != channelIov.end() && maxRows>0;
+       ++it, ++idx ) {
+    ChannelId cId=it->first;
+ 
+    // don't prefetch channels with only one or less splitters
+    if (it->second.count <= 1) {
+      continue;
+    }
+    log() <<"loading persistent head for Channel " << cId 
+         << " ["<< it->second.since << ", "<< it->second.until 
+         << " [ splitter count "<< it->second.count
+         << " maxRows "<< maxRows << coral::MessageStream::endmsg;
+
+    // load IOVs which are in the current head
+    // return 0 if more than maxRows rows would be loaded
+    channelsPersHead[idx] = objectTable.fetchRowsBtTimesInHead
+      ( it->second.since, it->second.until, cId, userTagId, maxRows );
+
+    // if channel contained too many to be overwritten IOVs skip this channel
+    if ( channelsPersHead[idx].get() == 0) {
+      log() << coral::Info 
+            << "MV insertion maxRows limit reached. Not prefetching "
+            << "more IOVs" << coral::MessageStream::endmsg;
+      log() << coral::Debug;
+      continue;
+    }
+    maxRows-=channelsPersHead[idx]->size();
+
+    std::vector<RelationalObjectTableRow>& 
+      currChannelRows( *(channelsPersHead[idx]) );
+
+    // fill map for channel with the rows
+    keyRowMap& IovMap=channelIovRowMap[cId];
+    for (std::vector<RelationalObjectTableRow>::iterator 
+           row=currChannelRows.begin(); row!=currChannelRows.end(); ++row) 
+    {
+      IovMap[row->since()]=&(*row);
+    }
+  }
+ 
+  // Vector to hold all splitters which require an update of the newHeadID
+  // of the persistent head.
+  SOVector newHeadUpdaters;
+
+  log() << "Loop over splitters - begin" << coral::MessageStream::endmsg;
+  for ( SOIterator splitter = splitters.begin();
+        splitter != splitters.end();
+        ++splitter ) {
+    
+    log() << "Process splitter [" << splitter->since
+          << "," << splitter->until << "]" << coral::MessageStream::endmsg;
+    // Find affected objects from intersecting the transient head with splitter
+    SOVector affectedObjs = splitter->intersect( transHead );
+    SOVector bottomVisibleIntervals = splitter->visibleThrough( transHead );
+    
+    if ( partiallyLocked && affectedObjs.size() !=0 )
+      throw RelationalException
+        ( "PANIC! Tag is partially locked and transHead is not empty!",
+          "RelationalObjectMgr" );
+    
+    for ( SOIterator headObj = affectedObjs.begin();
+          headObj != affectedObjs.end();
+          ++headObj ) {
+      unsigned int headObjIndex = idToIndex[ headObj->objectId ];
+      
+      // Update the newHeadId of the intersected head object and remove
+      // it from the transient head
+      rows[headObjIndex].setNewHeadId( splitter->objectId );
+      transHead.erase
+        ( remove( transHead.begin(), transHead.end(), *headObj ) );
+      
+      // Cut the examined headObj with the splitter. Create system
+      // objects from the intervals (one or two), set their originalId
+      // and add them to the transient head and the rows.
+      SOVector topVisibleIntervals = splitter->filter( *headObj );
+      for ( SOIterator interval = topVisibleIntervals.begin();
+            interval != topVisibleIntervals.end();
+            ++interval ) {
+        unsigned int objectId = interval->since < splitter->since
+        ? splitter->objectId +1
+        : splitter->objectId +2;
+        idToIndex[ objectId ] = rows.size();
+        log() << "Create system object (intersecting transient HEAD): [" 
+              << interval->since << "," << interval->until << "]" 
+              << coral::MessageStream::endmsg;
+        RelationalObjectTableRow
+          sysObjRow = createSystemObjectRow
+          ( rows[headObjIndex], objectId, interval->since, interval->until );
+        sysObjRow.setNewHeadId( 0 );
+        rows.push_back( sysObjRow );
+        SimpleObject sysObj( sysObjRow.objectId(),
+                             sysObjRow.channelId(),
+                             sysObjRow.since(),
+                             sysObjRow.until() );
+        transHead.push_back( sysObj );
+        // Sort the head to ensure a reproducible order of system objects,
+        // such that the lower end system object always comes before the
+        // upper end system object.
+        sort( transHead.begin(), transHead.end(), lt_since() );
+      }
+      
+    } // for ( affectedObjs.begin() ... )
+    
+    // Now that the transient head has been examined we have to check
+    // which parts of the splitter have not been 'absorbed' by it and
+    // 'fall through' to the persistent head.
+    //SOVector bottomVisibleIntervals = splitter->visibleThrough( transHead );
+
+    for ( SOIterator interval = bottomVisibleIntervals.begin();
+          interval != bottomVisibleIntervals.end();
+          ++interval ) {
+      bool sortHead = false;
+      
+      try { // Check if we need to create a system object at the lower end
+        keyRowMap::iterator obj;
+        bool prefetched=false;
+         if ( channelIovRowMap.find(interval->channelId) != 
+              channelIovRowMap.end() )
+         {
+           // we have prefetched IOVs for this channel
+           prefetched=true;
+           keyRowMap& IovMap=channelIovRowMap[interval->channelId];
+           obj=IovMap.upper_bound(interval->since);
+           // upper bound returns the next greater IOV, but we want the
+           // IOV just bevore interval->since
+           if ( obj != IovMap.begin()  )
+             --obj;
+           if ( obj == IovMap.end() )
+             // no object at point interval->since 
+             throw ObjectNotFound("temporary","mergeWithHead");
+         }
+         RelationalObjectTableRow lowerEnd = 
+           prefetched ? 
+           *(obj->second) :
+           objectTable.fetchRowAtTimeInHead( interval->since,
+                                             interval->channelId,
+                                             userTagId );
+        ValidityKey sysObjSince = lowerEnd.since();
+        ValidityKey sysObjUntil = interval->since;
+        if ( lowerEnd.until()>interval->since &&
+             lowerEnd.since()<interval->since &&
+             sysObjUntil > sysObjSince // avoid 0 length IOVs
+           ) {                     
+          // will not be reached if no intersecting object
+          if ( partiallyLocked )
+              throw TagIsLocked
+              ( "Cannot store objects with user tag: " 
+                "tag is partially locked and the IOVs are overlapping with "
+                "tag head (IOV start)",
+                "RelationalObjectMgr" );
+        
+          unsigned int objectId = interval->objectId +1;
+          idToIndex[ objectId ] = rows.size();
+          log() << "Create system object (intersecting persistent HEAD"
+                << " at low end): [" << sysObjSince 
+                << "," << sysObjUntil << "]" << coral::MessageStream::endmsg;
+          RelationalObjectTableRow
+            sysObjRow = createSystemObjectRow( lowerEnd, objectId,
+                                               sysObjSince,
+                                               sysObjUntil );
+          sysObjRow.setNewHeadId( 0 );
+          rows.push_back( sysObjRow );
+          SimpleObject sysObj( sysObjRow.objectId(),
+                               sysObjRow.channelId(),
+                               sysObjRow.since(),
+                               sysObjRow.until() );
+          transHead.push_back( sysObj );
+          sortHead = true;
+        }
+        
+         
+      } catch ( ObjectNotFound& /* ignored */ ) { }
+      
+      try { // Check if we need to create a system object at the upper end
+        keyRowMap::iterator obj;
+        bool prefetched=false;
+         if ( channelIovRowMap.find(interval->channelId) != 
+              channelIovRowMap.end() )
+         {
+           // we have prefetched IOVs for this channel
+           prefetched=true;
+           keyRowMap& IovMap=channelIovRowMap[interval->channelId];
+           obj=IovMap.upper_bound(interval->until);
+           // upper bound returns the next greater IOV, but we want the
+           // IOV just bevore interval->since
+           if ( obj != IovMap.begin()  )
+             --obj;
+           if ( obj == IovMap.end() )
+             // channel map is empty
+             throw ObjectNotFound("temporary","mergeWithHead");
+         }
+         RelationalObjectTableRow upperEnd = 
+           prefetched ? 
+           *(obj->second) :
+           objectTable.fetchRowAtTimeInHead( interval->until,
+                                             interval->channelId,
+                                             userTagId );
+        ValidityKey sysObjSince = interval->until;
+        ValidityKey sysObjUntil = upperEnd.until();
+        if ( 
+            upperEnd.since()<interval->until &&
+            upperEnd.until()>interval->until &&
+
+            sysObjUntil > sysObjSince  
+            // avoid 0 length IOVs
+            &&
+            interval->until != upperEnd.since() 
+            // needed because
+            // fetchObjectTableRowHead at pointInTime "interval->until"
+            // will fetch an object that *starts* at "interval->until"
+            // but we actually only want objects up to
+            // "interval->until - epsilon"
+            // Instead of using "interval->until -1" as point in time
+            // (which would assume granularity of 1 in IOVs) we select at
+            // "interval->until" and discard objects that start exactly at
+            // "interval->until", i.e. [a,b[ = [a,b] - [b]
+            ) 
+        {
+                    
+          // will not be reached if no intersecting object
+          if ( partiallyLocked )
+              throw TagIsLocked
+              ( "Cannot store objects with user tag: " 
+                "tag is partially locked and the IOVs are overlapping with "
+                "tag head (IOV end)",
+                "RelationalObjectMgr" );
+        
+          unsigned int objectId = interval->objectId +2;
+          idToIndex[ objectId ] = rows.size();
+          log() << "Create system object (intersecting persistent HEAD"
+                << " at high end): [" << sysObjSince 
+                << "," << sysObjUntil << "]" << coral::MessageStream::endmsg;
+          RelationalObjectTableRow
+            sysObjRow = createSystemObjectRow( upperEnd,
+                                               objectId,
+                                               sysObjSince,
+                                               sysObjUntil );
+          sysObjRow.setNewHeadId( 0 );
+          rows.push_back( sysObjRow );
+          SimpleObject sysObj( sysObjRow.objectId(),
+                               sysObjRow.channelId(),
+                               sysObjRow.since(),
+                               sysObjRow.until() );
+          transHead.push_back( sysObj );
+          sortHead = true;
+         }
+      } catch ( ObjectNotFound& /* ignored */ ) { }
+      
+      // See above why we sort
+      if ( sortHead ) sort( transHead.begin(), transHead.end(), lt_since() );
+      
+      // Update the newHeadIds of all overlapped head rows
+      keyRowMap::iterator obj;
+      bool callUpdate=true;
+      if ( channelIovRowMap.find(interval->channelId) != 
+           channelIovRowMap.end() )
+      {
+        // we have prefetched IOVs for this channel
+        keyRowMap& IovMap=channelIovRowMap[interval->channelId];
+        obj=IovMap.upper_bound(interval->since);
+        // upper bound returns the next greater IOV, but we want the
+        // IOV just bevore interval->since
+        if ( obj != IovMap.begin()  )
+          --obj;
+        while (obj!=IovMap.end() && obj->second->until()<=interval->since )
+          ++obj;
+        // check if in the prefetched row there is at least one
+        // which is covered by this splitter
+        if (obj==IovMap.end() || obj->second->since()>interval->until ) 
+          callUpdate=false;
+      }
+      if ( callUpdate )
+        newHeadUpdaters.insert(newHeadUpdaters.end(),*interval);
+    } // for ( bottomVisibleIntervals.begin() ... )
+    
+  } // for ( splitters.begin() ... )
+  if ( newHeadUpdaters.size()>0 ) 
+  {  
+    bool updated = bulkUpdateObjectTableNewHeadId( folder->objectTableName(),
+                                                   folder->channelTableName(),
+                                                   newHeadUpdaters,
+                                                   userTagId );
+    if ( partiallyLocked && updated ) 
+    {
+      // Inserted IOV covers existing ivos
+      //std::cout << "ERROR: tag is partially locked and "
+      //          << updated << " IOVS need to be updated" << std::endl;
+      throw TagIsLocked
+        ( "Cannot store objects with user tag: " 
+          "tag is partially locked and the IOVs are overlapping "
+          "with tag head (covering existing IOV)",
+          "RelationalObjectMgr" );
+    }
+  }
+  log() << "Loop over splitters - end" << coral::MessageStream::endmsg;
+}
+
+//-----------------------------------------------------------------------------
+
+RelationalObjectTableRow
+RelationalObjectMgr::createSystemObjectRow
+( const RelationalObjectTableRow& origRow,
+  unsigned int objectId,
+  const ValidityKey& since,
+  const ValidityKey& until ) const
+{
+  RelationalObjectTableRow row( origRow );
+  
+  // Update some fields
+  row.setObjectId( objectId );
+  row.setSince( since);
+  row.setUntil( until );
+  row.setOriginalId( origRow.objectId() );
+  
+  return row;
+}
+
+//-----------------------------------------------------------------------------
+
diff --git a/RelationalCool/src/RelationalObjectMgr.h b/RelationalCool/src/RelationalObjectMgr.h
new file mode 100644
index 000000000..eba9cd67e
--- /dev/null
+++ b/RelationalCool/src/RelationalObjectMgr.h
@@ -0,0 +1,288 @@
+// $Id: RelationalObjectMgr.h,v 1.38 2008-11-06 15:43:02 avalassi Exp $
+#ifndef RELATIONALCOOL_RELATIONALOBJECTMGR_H
+#define RELATIONALCOOL_RELATIONALOBJECTMGR_H
+
+// Include files
+#include <memory>
+#include "CoralBase/MessageStream.h"
+
+// Local include files
+#include "ObjectId.h"
+#include "RelationalFolder.h"
+#include "RelationalObjectPtr.h"
+#include "SimpleObject.h"
+
+namespace cool 
+{
+
+  // Forward declarations
+  class RelationalDatabase;
+  class RelationalQueryMgr;
+  class RelationalTagMgr;
+  class SimpleObject;
+  
+  // Type definitions
+  typedef std::map< ChannelId, ValidityKey > ChannelIdValidityKeyMap;
+  typedef std::map< ChannelId, ObjectId > ChannelIdObjectIdMap;  
+  
+  /// @class RelationalObjectMgr RelationalObjectMgr.h
+  ///
+  /// RelationalObjectMgr handles object queries of a COOL database instance.
+  ///
+  /// @author Sven A. Schmidt
+  /// @date   2006-04-19
+  ///
+  class RelationalObjectMgr 
+  {
+    
+    friend class RelationalObjectMgrTest;
+
+  public:
+    
+    // Virtual destructor
+    virtual ~RelationalObjectMgr() {}
+    
+    /// Constructor from a RelationalDatabase reference.
+    RelationalObjectMgr( const RelationalDatabase& db );
+
+    /// Find THE conditions object valid at the given point in time
+    IObjectPtr findObject( const RelationalFolder* folder,
+                           const ValidityKey& pointInTime,
+                           const ChannelId& channelId,
+                           const std::string& tagName="" ) const;
+
+    /// Browse the objects in a given folder for a given
+    /// channel selection within the given tag.
+    /// The iterator will retrieve only ONE object at any given validity point
+    /// for a given channel. The default order is channel, since if a channel
+    /// range is specified.
+    /// For SINGLE_VERSION folders, throw exception if tag != "" is specified.
+    IObjectIteratorPtr
+    browseObjects( const RelationalFolder* folder,
+                   const ValidityKey& since,
+                   const ValidityKey& until,
+                   const ChannelSelection& channels,
+                   const std::string& tagName = "", 
+                   const IRecordSelection* payloadQuery = 0,
+                   const bool countOnly = false ) const;
+
+    /// Store a list of conditions objects in the specified order
+    /// Do not start a transaction
+    void __storeObjects
+    ( RelationalFolder* folder,
+      const std::vector<RelationalObjectPtr> & objects,
+      bool userTagOnly = false ) const;
+  
+    /// Set a new finite end-of-validity value for all SV objects in a given 
+    /// channel selection whose end-of-validity is currently infinite.
+    /// Throws an Exception if called on a MV folder, or if any of the
+    /// selected channels contains a not open ended IOV at the point until.
+    /// Returns the number of actually truncated IOVs.
+    int truncateObjectValidity( const RelationalFolder* folder,
+                                const ValidityKey& until,
+                                const ChannelSelection& channels ) const;
+ 
+    /// Create a new channel
+    void createChannel( const RelationalFolder* folder,
+                        const ChannelId& channelId,
+                        const std::string& channelName,
+                        const std::string& description="" ) const;
+    
+    /// Drop a channel
+    bool dropChannel( const RelationalFolder* folder,
+                            const ChannelId& channelId ) const;
+ 
+    /// Get the RelationalDatabase
+    const RelationalDatabase& db() const
+    {
+      return m_db;
+    }    
+    
+    /// Get the RelationalQueryMgr
+    RelationalQueryMgr& queryMgr() const 
+    { 
+      return db().queryMgr(); 
+    }
+    
+    /// Get the RelationalTagMgr
+    RelationalTagMgr& tagMgr() const 
+    { 
+      return db().tagMgr(); 
+    }
+    
+    /// Get the IRelationalTransactionMgr
+    boost::shared_ptr<IRelationalTransactionMgr> transactionMgr() const 
+    {
+      return db().transactionMgr();
+    }
+
+  protected:
+
+    /// Get a CORAL MessageStream
+    coral::MessageStream& log() const;
+    
+    /// Insert a new channel table row.
+    void insertChannelTableRow( const std::string& channelTableName,
+                                const ChannelId& channelId,
+                                unsigned int lastObjectId,
+                                bool hasNewData,
+                                const std::string& channelName,
+                                const std::string& description ) const;
+
+    /// Updates lastObjectId and hasNewData for the given channel.
+    /// Column lastObjectId is updated only if hasNewData is false; if 
+    /// hasNewData is true, the input lastObjectId must be 0 (else exception).
+    /// Check that lastObjectId is expected to be 0 if hasNewData is false.
+    /// If the channel does not exist, create it with the given metadata.
+    void updateChannelTable( const std::string& channelTableName,
+                             const ChannelId& channelId,
+                             unsigned int lastObjectId,
+                             bool hasNewData ) const;
+    
+    /// Bulk update lastObjectId and hasNewData for the given channels
+    /// (but lastObjectId is updated only if hasNewData is false).
+    /// If hasNewData is true, also check whether bulk update fails because 
+    /// some channels are missing, and in that case use single row update and 
+    /// create any missing channels (NB this relies on hasNewData being 
+    /// different from false in the database only while updating/inserting).
+    void bulkUpdateChannelTable
+      ( const std::string& channelTableName,
+        const std::map< ChannelId, unsigned int >& updateDataMap,
+        bool hasNewData ) const;
+
+    /// Bulk update the IOV until values in the object table row with the 
+    /// given ids in the objectIdNewUntil map.
+    void bulkUpdateObjectTableIov
+      ( const std::string& objectTableName,
+        const std::map<unsigned int,ValidityKey>& objectIdNewUntil ) const;
+      
+    /// Update the newHeadId value in the object table rows overlapping with
+    /// the given since, until interval.
+    /// Returns true if some rows have been updated.
+    bool
+    bulkUpdateObjectTableNewHeadId( const std::string& objectTableName,
+                                    const std::string& channelTableName,
+                                    const SOVector& updateNewHeads,
+                                    unsigned int userTagId ) const;
+
+    /// Stores the given list of rows in the given iov table
+    /// NB: This method assumes that the objectIds of the rows are set
+    /// externally and that the objectId sequence is advanced. Since SV and MV
+    /// use different objectId assignment, this is necessary to be able to use
+    /// the some storage method for both. Only the insertionTime is updated
+    /// before flushing the rows to the database.
+    void bulkInsertObjectTableRows
+      ( const std::string& objectTableName,
+        const std::vector<RelationalObjectTableRow>& rows,
+        const RecordSpecification& rowSpec ) const;
+    
+    /// Updates open-ended IOVs for the given vector of intersectors. This list
+    /// is expected to contain one ValidityKey 'since' per channel indicating
+    /// the potential 'closing' IOV.
+    /// Throws an exception if any object with an until > since is found \e
+    /// unless this until is equal to ValidityKeyMax.
+    void updateSingleVersionIovs
+    ( RelationalFolder* folder,
+      const std::pair<ChannelIdValidityKeyMap, ChannelIdObjectIdMap>& 
+      intersectors,
+      const std::vector<RelationalObjectPtr>& objects ) const;
+    
+    /// Fetches all object table rows for channels that have new data.
+    /// This method is used in multi channel bulk insertion and selects
+    /// the rows in (potential) need of open IOV updating.
+    void fetchLastRowsWithNewData
+      ( RelationalFolder* folder,
+        std::vector<RelationalObjectTableRow>& rows ) const;
+      
+    /// Stores objects in 'SingleVersion' mode
+    /// This does not start a transaction
+    void __storeSingleVersionObjects
+    ( RelationalFolder* folder,
+      const std::vector<RelationalObjectPtr>& objects ) const;
+    
+    /// Stores objects in 'MultiVersion' mode
+    /// This does not start a transaction
+    void __storeMultiVersionObjects
+      ( RelationalFolder* folder,
+        const std::vector<RelationalObjectPtr>& objects,
+        bool userTagOnly = false ) const;
+    
+    /// Validates the given objects for SV storage (with respect to overlapping
+    /// IOVs). Returns a map of channelIds with the lowest IOV per channel
+    /// of the objects for updating open-ended IOVs in the persistent store
+    /// and validating the insertion and a map of the last object ids per 
+    /// channel which is used to update the channel table.
+    std::pair<ChannelIdValidityKeyMap, ChannelIdObjectIdMap>
+    processSingleVersionObjects
+    ( const std::vector<RelationalObjectPtr>& objects,
+      std::vector<RelationalObjectTableRow>& rows,
+      unsigned int objectIdOffset ) const;
+    
+    /// Processes 'MultiVersion' objects for bulk insertion:
+    ///    - analyse the objects and insert system objects if required
+    ///    - find and return potential 'intersections' from the given
+    ///      objects that might cause splitting in the HEAD
+    ///    - create consistent references references (original_id,
+    ///      new_head_id) among the objects. In order to do this without
+    ///      having to access the objectId sequence for each new system
+    ///      object being inserted, the objectIdOffset is used and the
+    ///      objectIds inside processMultiVersionObjects are created from this
+    ///      offset.
+    ///    - idToIndex is used to bookkeep the object id to 'rows' index
+    ///      mapping. This is subsequently used by mergeWithHead to know
+    ///      where to insert further system objects.
+    ///   Throws an TagIsLocked exception if partiallyLocked==true and the IOVs
+    ///   of the objects overlap
+    std::vector<SimpleObject> processMultiVersionObjects // OUT
+    ( const std::vector<RelationalObjectPtr>& objects,   // IN
+      std::vector<RelationalObjectTableRow>& rows,       // OUT
+      unsigned int objectIdOffset,                 // IN
+      std::map<unsigned int, unsigned int>& idToIndex,   // OUT
+      unsigned int userTagId = 0,                  // IN
+      bool partiallyLocked = false ) const;        // IN
+    
+    /// Merges the previously processed 'MultiVersion' objects (by
+    /// processMultiVersionObjects()) with the persistent head
+    /// Throws TagIsLocked exception if partiallyLocked==true and
+    /// there are overlapping IOVs 
+    void mergeWithHead( RelationalFolder* folder,
+                        const std::vector<SimpleObject> splitters,
+                        std::vector<RelationalObjectTableRow>& rows,
+                        std::map<unsigned int, unsigned int>& idToIndex,
+                        unsigned int userTagId = 0,
+                        bool partiallyLocked = false ) const;
+    
+    /// Creates a system object row templated from the given row
+    /// The iov and the object id are updated with the given values,
+    /// original_id is set to the original row's object_id
+    RelationalObjectTableRow
+      createSystemObjectRow( const RelationalObjectTableRow& origRow,
+                             unsigned int objectId,
+                             const ValidityKey& since,
+                             const ValidityKey& until ) const;
+    
+  private:
+    
+    /// Standard constructor is private
+    RelationalObjectMgr();
+
+    /// Copy constructor is private
+    RelationalObjectMgr( const RelationalObjectMgr& rhs );
+    
+    /// Assignment operator is private
+    RelationalObjectMgr& operator=( const RelationalObjectMgr& rhs );
+    
+  private:
+
+    /// The RelationalDatabase reference
+    const RelationalDatabase& m_db;
+
+    /// CORAL MessageStream
+    std::auto_ptr<coral::MessageStream> m_log;
+    
+  };
+
+} // namespace
+
+
+#endif // RELATIONALCOOL_RELATIONALOBJECTMGR_H
diff --git a/RelationalCool/src/RelationalObjectPtr.h b/RelationalCool/src/RelationalObjectPtr.h
new file mode 100644
index 000000000..d5048ccd7
--- /dev/null
+++ b/RelationalCool/src/RelationalObjectPtr.h
@@ -0,0 +1,19 @@
+// $Id: RelationalObjectPtr.h,v 1.1 2006-03-10 11:52:40 avalassi Exp $
+#ifndef RELATIONALCOOL_RELATIONALOBJECTPTR_H
+#define RELATIONALCOOL_RELATIONALOBJECTPTR_H
+
+// Include files
+#include <boost/shared_ptr.hpp>
+
+namespace cool {
+	
+  // Forward declarations
+  class RelationalObject;
+  
+  /// Shared pointer to a RelationalObject
+  typedef boost::shared_ptr<RelationalObject> RelationalObjectPtr;
+	  
+}
+
+#endif
+
diff --git a/RelationalCool/src/RelationalObjectTable.cpp b/RelationalCool/src/RelationalObjectTable.cpp
new file mode 100644
index 000000000..af822bd87
--- /dev/null
+++ b/RelationalCool/src/RelationalObjectTable.cpp
@@ -0,0 +1,1509 @@
+// $Id: RelationalObjectTable.cpp,v 1.190 2009-01-08 13:55:50 avalassi Exp $
+
+// Include files
+#include "CoralBase/AttributeSpecification.h"
+#include "CoralBase/Attribute.h"
+
+// Local include files
+#include "HvsTagRecord.h"
+#include "ObjectId.h"
+#include "RelationalChannelTable.h"
+#include "RelationalException.h"
+#include "RelationalFolder.h"
+#include "RelationalObject.h"
+#include "RelationalObjectTable.h"
+#include "RelationalObjectTableRow.h"
+#include "RelationalObject2TagTable.h"
+#include "RelationalPayloadQuery.h"
+#include "RelationalQueryDefinition.h"
+#include "RelationalQueryMgr.h"
+#include "RelationalTagMgr.h"
+#include "RelationalTagTable.h"
+#include "timeToString.h"
+
+// Namespace
+using namespace cool;
+
+//---------------------------------------------------------------------------
+
+RelationalObjectTable::RelationalObjectTable
+( RelationalQueryMgr* pQueryMgr,
+  bool ownQueryMgr,
+  const RelationalFolder& folder )
+  : m_log( new coral::MessageStream( "RelationalObjectTable" ) )
+  , m_pQueryMgr( pQueryMgr )
+  , m_ownQueryMgr( ownQueryMgr )
+  , m_tagMgr( folder.db().tagMgr() )
+  , m_payloadSpecification( folder.payloadSpecification() )
+  , m_tableSpecification( tableSpecification( folder.payloadSpecification() ) )
+  , m_nodeId( folder.id() )
+{
+  m_objectTableName = folder.objectTableName();
+  if ( folder.versioningMode() == FolderVersioning::MULTI_VERSION ) {
+    m_tagTableName = folder.tagTableName();
+    m_object2TagTableName = folder.object2TagTableName();
+  } else {
+    m_tagTableName = "";
+    m_object2TagTableName = "";
+  }
+  m_channelTableName = folder.channelTableName();
+}
+
+//---------------------------------------------------------------------------
+
+coral::MessageStream& RelationalObjectTable::log() const
+{
+  *m_log << coral::Verbose;
+  return *m_log;
+}
+
+//---------------------------------------------------------------------------
+
+RelationalObjectTable::~RelationalObjectTable()
+{
+  if ( m_ownQueryMgr && m_pQueryMgr )
+  {
+    delete m_pQueryMgr;
+    m_pQueryMgr = 0;
+  }
+}
+
+//---------------------------------------------------------------------------
+
+const IRecordSpecification&
+RelationalObjectTable::defaultSpecification()
+{
+  static RecordSpecification spec;
+
+  if ( spec.size() == 0 ) {
+    spec.extend( RelationalObjectTable::columnNames::objectId(),
+                 RelationalObjectTable::columnTypeIds::objectId );
+    spec.extend( RelationalObjectTable::columnNames::channelId(),
+                 RelationalObjectTable::columnTypeIds::channelId );
+    spec.extend( RelationalObjectTable::columnNames::iovSince(),
+                 RelationalObjectTable::columnTypeIds::iovSince );
+    spec.extend( RelationalObjectTable::columnNames::iovUntil(),
+                 RelationalObjectTable::columnTypeIds::iovUntil );
+    spec.extend( RelationalObjectTable::columnNames::userTagId(),
+                 RelationalObjectTable::columnTypeIds::userTagId );
+    spec.extend( RelationalObjectTable::columnNames::sysInsTime(),
+                 RelationalObjectTable::columnTypeIds::sysInsTime );
+    spec.extend( RelationalObjectTable::columnNames::lastModDate(),
+                 RelationalObjectTable::columnTypeIds::lastModDate );
+
+    // Management columns for 'MultiVersion' folders
+    spec.extend( RelationalObjectTable::columnNames::originalId(),
+                 RelationalObjectTable::columnTypeIds::originalId );
+    spec.extend( RelationalObjectTable::columnNames::newHeadId(),
+                 RelationalObjectTable::columnTypeIds::newHeadId );
+  }
+
+  return spec;
+}
+
+//---------------------------------------------------------------------------
+
+const RecordSpecification
+RelationalObjectTable::tableSpecification
+( const IRecordSpecification& payloadSpec )
+{
+  RecordSpecification spec;
+  for ( unsigned int i=0; i<defaultSpecification().size(); i++ ) {
+    const IFieldSpecification& field = defaultSpecification()[i];
+    spec.extend( field.name(), field.storageType() );
+  }
+  for ( unsigned int i=0; i<payloadSpec.size(); i++ ) {
+    const IFieldSpecification& field = payloadSpec[i];
+    spec.extend( field.name(), field.storageType() );
+  }
+  return spec;
+}
+
+//---------------------------------------------------------------------------
+
+const coral::AttributeList
+RelationalObjectTable::rowAttributeList
+( const coral::AttributeList& payload )
+{
+  coral::AttributeList al = Record( defaultSpecification() ).attributeList();
+
+  // User-defined payload columns
+  for ( coral::AttributeList::const_iterator
+          i = payload.begin(); i != payload.end(); ++i ) {
+    al.extend( i->specification().name(), i->specification().typeName() );
+  }
+
+  return al;
+}
+
+//-----------------------------------------------------------------------------
+
+const RelationalObjectTableRow
+RelationalObjectTable::fetchRowForId( unsigned int objectId,
+                                      bool fetchPayload ) const
+{
+  log() << "Fetch object row from table " << objectTableName()
+        << " for object_id=" << objectId << coral::MessageStream::endmsg;
+
+  // Define the WHERE clause for the selection using bind variables
+  coral::AttributeList whereData;
+  whereData.extend
+    ( "objectId",
+      typeIdToCoralType(RelationalObjectTable::columnTypeIds::objectId) );
+  whereData["objectId"].setValue( objectId );
+  std::string whereClause = RelationalObjectTable::columnNames::objectId();
+  whereClause += "= :objectId";
+
+  // Delegate the query to the RelationalQueryMgr
+  try {
+    std::string desc = "";
+    // Fetch both the IOV metadata and the payload
+    if ( fetchPayload )
+      return RelationalObjectTableRow
+        ( queryMgr().fetchRowFromTables
+          ( RelationalQueryMgr::tableList( objectTableName() ),
+            RelationalQueryMgr::columnList( tableSpecification() ),
+            whereClause, whereData, desc ) );
+    // Fetch only the IOV metadata, not the payload
+    else
+      return RelationalObjectTableRow
+        ( queryMgr().fetchRowFromTables
+          ( RelationalQueryMgr::tableList( objectTableName() ),
+            RelationalQueryMgr::columnList( defaultSpecification() ),
+            whereClause, whereData, desc ) );
+  } catch( NoRowsFound& ) {
+    std::stringstream s;
+    s << "object_id: " << objectId;
+    throw ObjectNotFound
+      ( s.str(), objectTableName(), "RelationalObjectTable" );
+  }
+}
+
+//---------------------------------------------------------------------------
+
+const std::vector<std::string>
+RelationalObjectTable::orderByClause( const ChannelSelection& channels,
+                                      const std::string& objectTableName )
+{
+  // Create a prefix if an objectTableName was specified
+  std::string prefix = "";
+  if ( objectTableName != "" ) prefix = objectTableName + ".";
+
+  // Define the ORDER BY clause for the selection
+  //
+  // sas 2005-08-09: I'm not sure if we even have to make the following
+  // distinction of single/multi channel selection or should just
+  // generally have "channelId, iovSince" or vice versa ordering. The fact
+  // that we have a 3D index might make this superfluous.
+  std::vector<std::string> orderBy;
+  if ( ! channels.isNumeric()
+       || ( channels.isNumeric() &&
+            ( channels.firstChannel() == channels.lastChannel() ) )
+       ) {
+    // Only one channel, skip 'channelId' in order clause
+    if ( channels.order() == ChannelSelection::channelBeforeSince ||
+         channels.order() == ChannelSelection::sinceBeforeChannel ) {
+      orderBy.push_back
+        ( prefix + RelationalObjectTable::columnNames::iovSince() + " ASC" );
+    }
+    else {
+      orderBy.push_back
+        ( prefix + RelationalObjectTable::columnNames::iovSince() + " DESC" );
+    }
+  } else {
+    if ( channels.order() == ChannelSelection::channelBeforeSince ) {
+      orderBy.push_back
+        ( prefix + RelationalObjectTable::columnNames::channelId() + " ASC" );
+      orderBy.push_back
+        ( prefix + RelationalObjectTable::columnNames::iovSince() + " ASC" );
+    }
+    else if ( channels.order() == ChannelSelection::sinceBeforeChannel ){
+      orderBy.push_back
+        ( prefix + RelationalObjectTable::columnNames::iovSince() + " ASC" );
+      orderBy.push_back
+        ( prefix + RelationalObjectTable::columnNames::channelId() + " ASC" );
+    }
+    else if ( channels.order() == ChannelSelection::channelBeforeSinceDesc ){
+      orderBy.push_back
+        ( prefix + RelationalObjectTable::columnNames::channelId() + " ASC" );
+      orderBy.push_back
+        ( prefix + RelationalObjectTable::columnNames::iovSince() + " DESC" );
+    }
+    else if ( channels.order() == ChannelSelection::sinceDescBeforeChannel ){
+      orderBy.push_back
+        ( prefix + RelationalObjectTable::columnNames::iovSince() + " DESC" );
+      orderBy.push_back
+        ( prefix + RelationalObjectTable::columnNames::channelId() + " ASC" );
+    }
+  }
+  return orderBy;
+}
+
+//---------------------------------------------------------------------------
+
+/*
+/// TEMPORARY! This is ONLY needed by David's VerificationClient
+RelationalObjectTableRow
+RelationalObjectTable::fetchLastRowSV( const ChannelId& channelId,
+                                       bool fetchPayload )
+{
+  log() << "Fetch last object row from table " << objectTableName()
+        << coral::MessageStream::endmsg;
+  
+  // The "last object" inserted in each channel of a SV folder is retrieved
+  // as the object with the highest objectId in that channel (two possible
+  // alternatives could be to use the highest iovSince or iovUntil).
+  // The present algorithm uses two queries:
+  // 1. First, select MAX(objectId) in the given channel
+  // 2. Then, retrieve the full row for the object wih id=maxId
+  
+  // QUERY 1: select MAX(objectId) for the given channel
+  std::string maxObjectIdName =
+    std::string("MAX(") + RelationalObjectTable::columnNames::objectId() + ")";
+  
+  RecordSpecification spec;
+  spec.extend( maxObjectIdName,
+               RelationalObjectTable::columnTypeIds::objectId );
+  coral::AttributeList whereData;
+  whereData.extend
+    ( "channel",
+      typeIdToCoralType(RelationalObjectTable::columnTypeIds::channelId) );
+  whereData["channel"]
+    .data<RelationalObjectTable::columnTypes::channelId>() = channelId;
+  std::string whereClause = RelationalObjectTable::columnNames::channelId();
+  whereClause += "= :channel";
+  
+  // Delegate the query to the RalQueryMgr
+  ObjectId maxObjectId;
+  try {
+    std::string desc = "";
+    RelationalTableRow maxObjectIdRow = queryMgr().fetchRowFromTables
+      ( RelationalQueryMgr::tableList( objectTableName() ),
+        RelationalQueryMgr::columnList( spec ),
+        whereClause, whereData, desc );
+    maxObjectId = maxObjectIdRow[ maxObjectIdName ].data<ObjectId>();
+  } catch( NoRowsFound& ) {
+    throw ObjectNotFound
+      ( "MAX(objectId)", objectTableName(), "RelationalObjectTable" );
+  }
+  
+  // QUERY 2: select * for objectId = MAX(objectId)
+  return
+    fetchRowForId( maxObjectId, fetchPayload );
+  
+}
+*/
+
+//---------------------------------------------------------------------------
+
+const RelationalObjectTableRow
+RelationalObjectTable::fetchLastRowForTagId( unsigned int tagId,
+                                             bool fetchPayload ) const
+{
+  log() << "Fetch last object row from table " << objectTableName()
+        << " for tagId " << tagId << coral::MessageStream::endmsg;
+  ObjectId maxObjectId=0;
+  bool isUserTag=true;
+
+  // QUERY 1: select MAX(objectId) for the given tag
+  std::string maxObjectIdName =
+    std::string("MAX(") + RelationalObjectTable::columnNames::objectId() + ")";
+  RecordSpecification spec;
+  spec.extend( maxObjectIdName,
+               RelationalObjectTable::columnTypeIds::objectId );
+
+  // first guess: it is a user tag
+  coral::AttributeList whereData;
+  whereData.extend
+    ( "userTagId",
+      typeIdToCoralType(RelationalObjectTable::columnTypeIds::userTagId) );
+  whereData["userTagId"].setValue( tagId );
+  std::string whereClause =
+    RelationalObjectTable::columnNames::userTagId();
+  whereClause += "=:userTagId";
+
+  try {
+    std::string desc = "";
+    RelationalTableRow maxObjectIdRow = queryMgr().fetchRowFromTables(
+                                                                      RelationalQueryMgr::tableList( objectTableName() ),
+                                                                      RelationalQueryMgr::columnList( spec ),
+                                                                      whereClause, whereData, desc );
+    if (maxObjectIdRow[ maxObjectIdName ].isNull())
+      isUserTag=false;
+    else maxObjectId = maxObjectIdRow[ maxObjectIdName ].data<ObjectId>();
+  } catch (NoRowsFound & ) {
+    isUserTag=false;
+  }
+  if ( !isUserTag) {
+    // no user tag
+    coral::AttributeList whereData;
+    whereData.extend( "tagId",
+                      typeIdToCoralType(RelationalObject2TagTable::columnTypeIds::tagId) );
+    whereData["tagId"].setValue( tagId );
+    std::string whereClause = RelationalObject2TagTable::columnNames::tagId;
+    whereClause += "= :tagId";
+
+    // Delegate the query to the RalQueryMgr
+    try {
+      std::string desc = "";
+      RelationalTableRow maxObjectIdRow = queryMgr().fetchRowFromTables
+        ( RelationalQueryMgr::tableList( object2TagTableName() ),
+          RelationalQueryMgr::columnList( spec ),
+          whereClause, whereData, desc );
+      maxObjectId = maxObjectIdRow[ maxObjectIdName ].data<ObjectId>();
+    } catch( NoRowsFound& ) {
+      throw ObjectNotFound
+        ( "MAX(objectId)", object2TagTableName(), "RelationalObjectTable" );
+    }
+  }
+
+  // QUERY 2: select * for objectId = MAX(objectId)
+  return
+    fetchRowForId( maxObjectId, fetchPayload );
+
+}
+
+//---------------------------------------------------------------------------
+
+const RelationalObjectTableRow RelationalObjectTable::fetchRowAtTimeInHead
+( const ValidityKey& pointInTime,
+  const ChannelId& channelId,
+  unsigned int userTagId )
+{
+  log() << "Fetch object row HEAD from table " << objectTableName()
+        << " for channel=" << channelId
+        << " at time=" << pointInTime
+        << " (with user tag=" << userTagId << ")"
+        << coral::MessageStream::endmsg;
+
+  const std::auto_ptr<IRelationalQueryDefinition>
+    def( queryDefinitionGeneric
+         ( pointInTime, pointInTime, channelId, &userTagId ) );
+
+  // Delegate the query to the RalQueryMgr
+  try {
+    std::string desc = "";
+    const std::vector<RelationalTableRow> rows
+      ( queryMgr().fetchOrderedRows( *def, desc, 1 ) );
+    return RelationalObjectTableRow( rows[0] );
+  } catch( NoRowsFound& ) {
+    std::stringstream s;
+    s << pointInTime;
+    throw ObjectNotFound
+      ( s.str(), objectTableName(), "RelationalObjectTable" );
+  }
+}
+//---------------------------------------------------------------------------
+
+std::auto_ptr< std::vector<RelationalObjectTableRow> >
+RelationalObjectTable::fetchRowsBtTimesInHead
+( const ValidityKey& since,
+  const ValidityKey& until,
+  const ChannelId& channelId,
+  unsigned int userTagId,
+  unsigned int maxRows )
+{
+  log() << "Fetch object row HEAD from table " << objectTableName()
+        << " for channel=" << channelId
+        << " bt times=" << since
+        << ", " << until
+        << " (with user tag=" << userTagId << ")"
+        << coral::MessageStream::endmsg;
+
+  const std::auto_ptr<IRelationalQueryDefinition>
+    def( queryDefinitionGeneric
+         ( since, until, channelId, &userTagId ) );
+
+  // Delegate the query to the RalQueryMgr
+  try {
+    std::string desc = "";
+
+    // return a auto_ptr to 0 if maxRow count is exceeded
+    unsigned int count=queryMgr().countRows( *def, desc );
+    if ( count  > maxRows )
+      return std::auto_ptr< std::vector< RelationalObjectTableRow > >( 0 );
+
+    const std::vector<RelationalTableRow> rows
+      ( queryMgr().fetchOrderedRows( *def, desc ) );
+
+    std::auto_ptr< std::vector<RelationalObjectTableRow> > objectRows(
+                                                                      new std::vector<RelationalObjectTableRow>( ) );
+
+    for ( std::vector<RelationalTableRow>::const_iterator
+            row = rows.begin(); row != rows.end(); ++row ) {
+      RelationalObjectTableRow objectRow( *row );
+      objectRows->push_back( objectRow );
+    }
+
+    return objectRows;
+  } catch( NoRowsFound& ) {
+    std::stringstream s;
+    s << since << ", " << until;
+    throw ObjectNotFound
+      ( s.str(), objectTableName(), "RelationalObjectTable" );
+  }
+}
+
+//---------------------------------------------------------------------------
+
+/*
+RelationalObjectTableRow RelationalObjectTable::fetchRowAtTimeInTag
+( const ValidityKey& pointInTime,
+  const ChannelId& channelId,
+  const std::string& tagName )
+{
+  log() << "Fetch object row in tag from table " << objectTableName()
+        << " for channel=" << channelId
+        << " at time=" << pointInTime
+        << " with tag=" << tagName
+        << coral::MessageStream::endmsg;
+  
+  const std::auto_ptr<IRelationalQueryDefinition>
+    def( queryDefinitionTag
+         ( pointInTime, pointInTime, channelId, tagName ) );
+  
+  // Delegate the query to the RalQueryMgr
+  try {
+    std::string desc = "";
+    const std::vector<RelationalTableRow> rows
+      ( queryMgr().fetchOrderedRows( *def, desc, 1 ) );
+    return RelationalObjectTableRow( rows[0] );
+  } catch( NoRowsFound& ) {
+    std::stringstream s;
+    s << pointInTime;
+    throw ObjectNotFound
+      ( s.str(), objectTableName(), "RelationalObjectTable" );
+  }
+}
+*/
+
+//---------------------------------------------------------------------------
+
+std::vector<RelationalObjectTableRow>
+RelationalObjectTable::fetchRowsForTaggingCurrentHead()
+{
+
+  // Add 'meta data' columns to the output list and define the output format
+  RecordSpecification spec;
+  spec.extend( RelationalObjectTable::columnNames::objectId(),
+               RelationalObjectTable::columnTypeIds::objectId );
+  spec.extend( RelationalObjectTable::columnNames::channelId(),
+               RelationalObjectTable::columnTypeIds::channelId );
+  spec.extend( RelationalObjectTable::columnNames::iovSince(),
+               RelationalObjectTable::columnTypeIds::iovSince );
+  spec.extend( RelationalObjectTable::columnNames::iovUntil(),
+               RelationalObjectTable::columnTypeIds::iovUntil );
+  spec.extend( RelationalObjectTable::columnNames::userTagId(),
+               RelationalObjectTable::columnTypeIds::userTagId );
+  spec.extend( RelationalObjectTable::columnNames::sysInsTime(),
+               RelationalObjectTable::columnTypeIds::sysInsTime );
+
+  // Define the WHERE clause for the selection using bind variables
+  coral::AttributeList whereData;
+  whereData.extend
+    ( "newHeadId",
+      typeIdToCoralType(RelationalObjectTable::columnTypeIds::newHeadId) );
+  whereData.extend
+    ( "userTagId",
+      typeIdToCoralType(RelationalObjectTable::columnTypeIds::userTagId) );
+  whereData["newHeadId"].setValue( 0u );
+  whereData["userTagId"].setValue( 0u );
+  std::string whereClause = RelationalObjectTable::columnNames::newHeadId();
+  whereClause += "= :newHeadId";
+  whereClause += " AND ";
+  whereClause += RelationalObjectTable::columnNames::userTagId();
+  whereClause += "= :userTagId";
+
+  /// Results are ordered by ascending values of the "since" start of IOV
+  std::vector<std::string> orderBy;
+  orderBy.push_back( RelationalObjectTable::columnNames::objectId() + " ASC" );
+
+  // Delegate the query to the RalQueryMgr
+  std::string desc = "";
+  std::vector<RelationalTableRow> rows =
+    queryMgr().fetchOrderedRowsFromTables
+    ( RelationalQueryMgr::tableList( objectTableName() ),
+      RelationalQueryMgr::columnList( spec ),
+      whereClause, whereData, orderBy, desc );
+
+  // TEMPORARY? Conversion to RelationalObjectTableRow
+  std::vector<RelationalObjectTableRow> objectRows;
+  for ( std::vector<RelationalTableRow>::const_iterator
+          row = rows.begin(); row != rows.end(); ++row ) {
+    RelationalObjectTableRow objectRow( *row );
+    objectRows.push_back( objectRow );
+  }
+
+  // Return the results
+  return objectRows;
+
+}
+
+//---------------------------------------------------------------------------
+
+std::vector<RelationalObjectTableRow>
+RelationalObjectTable::fetchRowsForTaggingHeadAsOfDate( const ITime& asOfDate )
+{
+  log() << "Fetch IOV rows from table '" << objectTableName()
+        << "' for tagging as of date '" << timeToString(asOfDate)
+        << "'" << coral::MessageStream::endmsg;
+
+  // Ideally, this methods query should be merged with fetchObjectTableRows,
+  // but it is not so easy due the output column specifications
+
+  // Define the list of tables to query
+  // NB Use UPPERCASE table aliases for Frontier (see task #3536)
+  RelationalQueryMgr::TableNamesWithAliases tables;
+  tables.push_back
+    ( RelationalQueryMgr::TableNameWithAlias( objectTableName(), "I" ) );
+  tables.push_back
+    ( RelationalQueryMgr::TableNameWithAlias( objectTableName(), "O" ) );
+
+  // Add 'meta data' columns to the output list and define the output format
+  RecordSpecification spec;
+  spec.extend( RelationalObjectTable::columnNames::objectId(),
+               RelationalObjectTable::columnTypeIds::objectId );
+  spec.extend( RelationalObjectTable::columnNames::channelId(),
+               RelationalObjectTable::columnTypeIds::channelId );
+  spec.extend( RelationalObjectTable::columnNames::iovSince(),
+               RelationalObjectTable::columnTypeIds::iovSince );
+  spec.extend( RelationalObjectTable::columnNames::iovUntil(),
+               RelationalObjectTable::columnTypeIds::iovUntil );
+  spec.extend( RelationalObjectTable::columnNames::userTagId(),
+               RelationalObjectTable::columnTypeIds::userTagId );
+  spec.extend( RelationalObjectTable::columnNames::sysInsTime(),
+               RelationalObjectTable::columnTypeIds::sysInsTime );
+  RelationalQueryMgr::SelectListWithRSetSpec columns =
+    RelationalQueryMgr::columnList( spec, "I." );
+
+  // Define the WHERE clause for the selection using bind variables
+  coral::AttributeList whereData;
+  whereData.extend
+    ( "asOfDate1",
+      typeIdToCoralType(RelationalObjectTable::columnTypeIds::sysInsTime) );
+  whereData.extend
+    ( "userTagId",
+      typeIdToCoralType(RelationalObjectTable::columnTypeIds::userTagId) );
+  whereData.extend
+    ( "newHeadId",
+      typeIdToCoralType(RelationalObjectTable::columnTypeIds::newHeadId) );
+  whereData.extend
+    ( "asOfDate2",
+      typeIdToCoralType(RelationalObjectTable::columnTypeIds::sysInsTime) );
+
+  whereData["asOfDate1"].setValue( timeToString( asOfDate ) );
+  whereData["userTagId"].setValue( 0u );
+  whereData["newHeadId"].setValue( 0u );
+  whereData["asOfDate2"].setValue( timeToString( asOfDate ) );
+  std::string ins = RelationalObjectTable::columnNames::sysInsTime();
+  std::string oid = RelationalObjectTable::columnNames::objectId();
+  std::string nhid = RelationalObjectTable::columnNames::newHeadId();
+  std::string whereClause = "I." + ins + " <= :asOfDate1";
+  whereClause += " AND ";
+  whereClause += "I." + RelationalObjectTable::columnNames::userTagId();
+  whereClause += "= :userTagId";
+  whereClause += " AND ( ";
+  whereClause += "( I." + nhid + " = :newHeadId";
+  whereClause += " AND I." + oid + " = O." + oid; // constrains self join
+  whereClause += " ) ";
+  whereClause += " OR ";
+  whereClause += "( I." + nhid + " = O." + oid;
+  whereClause += " AND O." + ins + " > :asOfDate2";
+  whereClause += " ) ";
+  whereClause += ")";
+
+  /// Results are ordered by ascending values of the "since" start of IOV
+  std::vector<std::string> orderBy;
+  orderBy.push_back( std::string("I.") +
+                     RelationalObjectTable::columnNames::objectId() + " ASC" );
+
+  // Delegate the query to the RalQueryMgr
+  std::string desc = "";
+  std::vector<RelationalTableRow> rows =
+    queryMgr().fetchOrderedRowsFromTables
+    ( tables, columns, whereClause, whereData, orderBy, desc );
+
+  // TEMPORARY? Conversion to RelationalObjectTableRow
+  std::vector<RelationalObjectTableRow> objectRows;
+  for ( std::vector<RelationalTableRow>::const_iterator
+          row = rows.begin(); row != rows.end(); ++row ) {
+    RelationalObjectTableRow objectRow( *row );
+    objectRows.push_back( objectRow );
+  }
+
+  // Return the results
+  return objectRows;
+
+}
+
+//---------------------------------------------------------------------------
+
+std::vector<RelationalObjectTableRow>
+RelationalObjectTable::fetchRowsForTaggingHeadAsOfObjectId
+( unsigned int asOfObjectId )
+{
+
+  // Add 'meta data' columns to the output list and define the output format
+  RecordSpecification spec;
+  spec.extend( RelationalObjectTable::columnNames::objectId(),
+               RelationalObjectTable::columnTypeIds::objectId );
+  spec.extend( RelationalObjectTable::columnNames::channelId(),
+               RelationalObjectTable::columnTypeIds::channelId );
+  spec.extend( RelationalObjectTable::columnNames::iovSince(),
+               RelationalObjectTable::columnTypeIds::iovSince );
+  spec.extend( RelationalObjectTable::columnNames::iovUntil(),
+               RelationalObjectTable::columnTypeIds::iovUntil );
+  spec.extend( RelationalObjectTable::columnNames::userTagId(),
+               RelationalObjectTable::columnTypeIds::userTagId );
+  spec.extend( RelationalObjectTable::columnNames::sysInsTime(),
+               RelationalObjectTable::columnTypeIds::sysInsTime );
+
+  // AV 05.04.2005 Bug fix
+  // The asOfObjectId argument must first be mapped into current user object
+  // Also change algorithm so that next (rather than current) user obj is used
+  ObjectId nextUserObjectId = ObjectIdHandler::nextUserObject( asOfObjectId );
+
+  // Define the WHERE clause for the selection using bind variables
+  coral::AttributeList whereData;
+  whereData.extend
+    ( "userTagId",
+      typeIdToCoralType(RelationalObjectTable::columnTypeIds::userTagId) );
+  whereData.extend
+    ( "oid1",
+      typeIdToCoralType(RelationalObjectTable::columnTypeIds::objectId) );
+  whereData.extend
+    ( "oid2",
+      typeIdToCoralType(RelationalObjectTable::columnTypeIds::objectId) );
+
+  whereData["userTagId"].setValue( 0u );
+  whereData["oid1"].setValue( nextUserObjectId );
+  whereData["oid2"].setValue( nextUserObjectId );
+  std::string oid = RelationalObjectTable::columnNames::objectId();
+  std::string nhid = RelationalObjectTable::columnNames::newHeadId();
+  std::string whereClause = RelationalObjectTable::columnNames::userTagId();
+  whereClause += "= :userTagId";
+  whereClause += " AND ";
+  whereClause += oid + " < :oid1";
+  whereClause += " AND ( ";
+  whereClause +=
+    "   " + nhid + " = 0 or"; // AV 05.04.2005 No need to bind 0 (constant)
+  whereClause += "   " + nhid + " >= :oid2";
+  whereClause += " )";
+
+  /// Results are ordered by ascending values of the "since" start of IOV
+  std::vector<std::string> orderBy;
+  orderBy.push_back( RelationalObjectTable::columnNames::objectId() + " ASC" );
+
+  // Delegate the query to the RalQueryMgr
+  std::string desc = "";
+  std::vector<RelationalTableRow> rows =
+    queryMgr().fetchOrderedRowsFromTables
+    ( RelationalQueryMgr::tableList( objectTableName() ),
+      RelationalQueryMgr::columnList( spec ),
+      whereClause, whereData, orderBy, desc );
+
+  // TEMPORARY? Conversion to RelationalObjectTableRow
+  std::vector<RelationalObjectTableRow> objectRows;
+  for ( std::vector<RelationalTableRow>::const_iterator
+          row = rows.begin(); row != rows.end(); ++row ) {
+    RelationalObjectTableRow objectRow( *row );
+    objectRows.push_back( objectRow );
+  }
+
+  // Return the results
+  return objectRows;
+
+}
+
+//---------------------------------------------------------------------------
+
+bool
+RelationalObjectTable::existsChannel( const ChannelId& channelId ) const
+{
+  std::string whereClause = RelationalObjectTable::columnNames::channelId();
+  whereClause += "= :channelId";
+  coral::AttributeList whereData;
+  whereData.extend
+    ( "channelId",
+      typeIdToCoralType(RelationalObjectTable::columnTypeIds::channelId) );
+  whereData["channelId"].setValue( channelId );
+  UInt32 nRows =
+    queryMgr().countRowsFromTables
+    ( RelationalQueryMgr::tableList( this->objectTableName() ),
+      whereClause, whereData, "" );
+  return ( nRows > 0 );
+}
+
+//---------------------------------------------------------------------------
+
+std::auto_ptr<IRelationalQueryDefinition>
+RelationalObjectTable::queryDefinitionSV
+( const ValidityKey& since,
+  const ValidityKey& until,
+  const ChannelSelection& channels,
+  const IRecordSelection* payloadQuery )
+{
+  // Delegate to queryDefinitionGeneric
+  const unsigned int* pTagId = 0;
+  bool isUserTag = true;
+  return queryDefinitionGeneric( since, until, channels, pTagId, isUserTag, payloadQuery );
+}
+
+//---------------------------------------------------------------------------
+
+std::auto_ptr<IRelationalQueryDefinition>
+RelationalObjectTable::queryDefinitionHeadAndUserTag
+( const ValidityKey& since,
+  const ValidityKey& until,
+  const ChannelSelection& channels,
+  const std::string& userTagName,
+  const IRecordSelection* payloadQuery )
+{
+  // TEMPORARY? Could provide tagName and do the tagName->tagId
+  // mapping in the same join: here I assume we retrieve it before
+  unsigned int tagId = 0;
+  if (!IHvsNode::isHeadTag( userTagName ))
+    try
+    {
+      tagId = m_tagMgr.__findTagRecord( m_nodeId, userTagName ).id();
+      //std::cout << "Tag '" << tagName << "' has tagId=" << tagId << std::endl;
+    }
+    catch(...)
+    {
+      //std::cout << "Tag '" << tagName
+      //          << "' does not exist - use a dummy value tagId=0" << std::endl;
+    }
+
+  // Delegate to queryDefinitionGeneric
+  bool isUserTag = true;
+  return queryDefinitionGeneric( since, until, channels, &tagId, isUserTag, payloadQuery );
+}
+
+//---------------------------------------------------------------------------
+
+std::auto_ptr<IRelationalQueryDefinition>
+RelationalObjectTable::queryDefinitionTag
+( //const std::string& objectTableName,
+ const ValidityKey& since,
+ const ValidityKey& until,
+ const ChannelSelection& channels,
+ const std::string& tagName,
+ const IRecordSelection* payloadQuery )
+{
+  // TEMPORARY? Could provide tagName and do the tagName->tagId
+  // mapping in the same join: here I assume we retrieve it before
+  unsigned int tagId = 0;
+  try
+  {
+    tagId = m_tagMgr.__findTagRecord( m_nodeId, tagName ).id();
+    //std::cout << "Tag '" << tagName << "' has tagId=" << tagId << std::endl;
+  }
+  catch(...)
+  {
+    //std::cout << "Tag '" << tagName
+    //          << "' does not exist - use a dummy value tagId=0" << std::endl;
+  }
+
+  // Delegate to queryDefinitionGeneric
+  bool isUserTag = false;
+  return queryDefinitionGeneric( since, until, channels, &tagId, isUserTag, payloadQuery );
+}
+//---------------------------------------------------------------------------
+
+// NEW IMPLEMENTATION - IMPLEMENT TWO VIEW MERGES DIRECTLY!
+std::auto_ptr<IRelationalQueryDefinition>
+RelationalObjectTable::queryDefinitionGeneric
+( //const std::string& objectTableName,
+ const ValidityKey& since,
+ const ValidityKey& until,
+ const ChannelSelection& channels,
+ const unsigned int* pTagId, // pTagId=0 means SV, (*pTagId)==0 means HEAD
+ bool isUserTag, // ignored for SV and HEAD, used only for (*pTagId)!=0
+ const IRecordSelection* payloadQuery )
+{
+  // TEMPORARY? This method could accept a tag name as an argument instead
+  // of a pointer to a tagID (in which case we would need to retrieve the
+  // tagID inside this method, for instance using a join with the tag table -
+  // which we may already have in some cases). The present implementation
+  // assumes instead that we retrieve it before (or that we do not need it,
+  // for instance for insertion...).
+
+  // TEMPORARY - this method should be moved elsewhere
+  // and table names should be provided as arguments...
+  const std::string& objectTableName = m_objectTableName;
+  const std::string& object2TagTableName = m_object2TagTableName;
+
+  // Add double quotes for all techologies except SQLite
+  std::string quotes = "";
+  if ( queryMgr().databaseTechnology() == "Oracle" ||
+       queryMgr().databaseTechnology() == "MySQL" ||
+       queryMgr().databaseTechnology() == "frontier" ) quotes = "\"";
+
+  // Create the hint prefix and suffix without interefering with C++ comments
+  std::string hintPrefix = std::string("/") + std::string("*");
+  std::string hintSuffix = std::string(" *") + std::string("/");
+
+  // --- SQL QUERY STRATEGY: 'external OR' vs. 'coalesce'/'internal OR' ---
+
+  // Choose the SQL query strategy (externalOR vs. internalOR/coalesce)
+  // DEFAULT: internalOR (userTagMV)/coalesce(SV/tagMV)
+  bool useExternalOr = false;
+  // Override the SQL strategy using environment variables
+  if ( getenv( "COOL_QUERYDEFGEN_EXTERNALOR" ) )
+  {
+    std::cout << "__COOL alternative SQL strategy EXTERNALOR" << std::endl;
+    useExternalOr = true;
+  }
+
+  // --- SQL QUERY STRATEGY: 'coalesce' vs. 'internal OR' ---
+
+  // Choose the SQL query strategy (internalOR vs. coalesce)
+  // DEFAULT: coalesce for all (SV/tagMV/userTagMV)
+  bool useCoalesce = true;
+  /*
+  if ( pTagId == 0 )
+  {
+    // Default for SV: use coalesce
+    useCoalesce = true;
+  }
+  else
+  {
+    if ( isUserTag )
+    {
+      // Default for MV user tags: use coalesce
+      useCoalesce = true;
+    }
+    else
+    {
+      // Default for MV tags: do not use coalesce
+      useCoalesce = true;
+    }
+  }
+  */
+  // Override the SQL strategy using environment variables
+  if ( getenv( "COOL_QUERYDEFGEN_COALESCE" ) )
+  {
+    useCoalesce = true;
+    std::cout << "__COOL alternative SQL strategy COALESCE" << std::endl;
+  }
+  else if ( getenv( "COOL_QUERYDEFGEN_NOCOALESCE" ) )
+  {
+    useCoalesce = false;
+    std::cout << "__COOL alternative SQL strategy NOCOALESCE" << std::endl;
+  }
+
+  // --- MV WHERE CLAUSES ---
+
+  // If pTagId == 0, this is SV: no additional tagWhereClause.
+  // If pTagId != 0, this is MV: prepare the additional tagWhereClause.
+  std::string whereClauseTag1;
+  Record whereDataTag1;
+  std::string whereClauseTag3;
+  Record whereDataTag3;
+  std::string whereClauseTag3b;
+  Record whereDataTag3b;
+  //std::cout << "pTagId=" << pTagId << std::endl;
+  //std::cout << "isUserTag=" << ( isUserTag?"T":"F") << std::endl;
+  if ( pTagId != 0 )
+  {
+    unsigned int tagId = *pTagId;
+    if ( isUserTag )
+    {
+      const std::string iovUtagIdName =
+        RelationalObjectTable::columnNames::userTagId();
+      const std::string iovNewHIdName =
+        RelationalObjectTable::columnNames::newHeadId();
+      const StorageType::TypeId iovUtagIdTyId =
+        RelationalObjectTable::columnTypeIds::userTagId;
+      // Use the 5D indx on userTagId, newHeadId, channelId, iovSince, iovUntil
+      // that was originally introduced for findObject(userTag) in task #4381
+      // Clause and data for subquery1 (max)
+      {
+        whereClauseTag1 += "COOL_I1." + iovUtagIdName;
+        whereClauseTag1 += "=:" + quotes+"utagid1"+quotes;
+        whereClauseTag1 += " AND ";
+        whereClauseTag1 += iovNewHIdName + "=0";
+        whereClauseTag1 += " AND ";
+        RecordSpecification spec;
+        spec.extend( "utagid1", iovUtagIdTyId );
+        Record rec( spec );
+        rec["utagid1"].setValue( tagId );
+        whereDataTag1.extend( rec );
+      }
+      // Clause and data for subquery3 (browse)
+      {
+        whereClauseTag3 += "COOL_I3." + iovUtagIdName;
+        whereClauseTag3 += "=:" + quotes+"utagid3"+quotes;
+        whereClauseTag3 += " AND ";
+        whereClauseTag3 += iovNewHIdName + "=0";
+        whereClauseTag3 += " AND ";
+        RecordSpecification spec;
+        spec.extend( "utagid3", iovUtagIdTyId );
+        Record rec( spec );
+        rec["utagid3"].setValue( tagId );
+        whereDataTag3.extend( rec );
+      }
+      // Clause and data for subquery3b (browse) - ONLY FOR EXTERNAL OR
+      {
+        whereClauseTag3b += "COOL_I3." + iovUtagIdName;
+        whereClauseTag3b += "=:" + quotes+"utagid3b"+quotes;
+        whereClauseTag3b += " AND ";
+        whereClauseTag3b += iovNewHIdName + "=0";
+        whereClauseTag3b += " AND ";
+        RecordSpecification spec;
+        spec.extend( "utagid3b", iovUtagIdTyId );
+        Record rec( spec );
+        rec["utagid3b"].setValue( tagId );
+        whereDataTag3b.extend( rec );
+      }
+    }
+    else
+    {
+      const std::string i2tTagName =
+        RelationalObject2TagTable::columnNames::tagId;
+      const StorageType::TypeId i2tTagTyId =
+        RelationalObject2TagTable::columnTypeIds::tagId;
+      // Use the 4D index on tagId, channelId, iovSince, iovUntil
+      // Clause and data for subquery1 (max)
+      {
+        whereClauseTag1 += "COOL_I1." + i2tTagName;
+        whereClauseTag1 += "=:" + quotes+"tagid1"+quotes;
+        whereClauseTag1 += " AND ";
+        RecordSpecification spec;
+        spec.extend( "tagid1", i2tTagTyId );
+        Record rec( spec );
+        rec["tagid1"].setValue( tagId );
+        whereDataTag1.extend( rec );
+      }
+      // Clause and data for subquery3 (browse)
+      {
+        whereClauseTag3 += "COOL_I3." + i2tTagName;
+        whereClauseTag3 += "=:" + quotes+"tagid3"+quotes;
+        whereClauseTag3 += " AND ";
+        RecordSpecification spec;
+        spec.extend( "tagid3", i2tTagTyId );
+        Record rec( spec );
+        rec["tagid3"].setValue( tagId );
+        whereDataTag3.extend( rec );
+      }
+      // Clause and data for subquery3b (browse) - ONLY FOR EXTERNAL OR
+      {
+        whereClauseTag3b += "COOL_I3." + i2tTagName;
+        whereClauseTag3b += "=:" + quotes+"tagid3b"+quotes;
+        whereClauseTag3b += " AND ";
+        RecordSpecification spec;
+        spec.extend( "tagid3b", i2tTagTyId );
+        Record rec( spec );
+        rec["tagid3b"].setValue( tagId );
+        whereDataTag3b.extend( rec );
+      }
+    }
+  }
+
+  // --- SCHEMA ELEMENTS FOR SUBQUERY 1/2 (max) and SUBQUERY 3 (browse) ---
+
+  std::string iovTable13;
+  std::string iovSince13Name;
+  std::string iovUntil13Name;
+  std::string iovObjId13Name;
+  std::string iovChnId13Name;
+  StorageType::TypeId iovSince13TyId;
+  StorageType::TypeId iovUntil13TyId;
+  StorageType::TypeId iovObjId13TyId;
+  if ( pTagId == 0 || isUserTag )
+  {
+    iovTable13 = objectTableName;
+    iovSince13Name = RelationalObjectTable::columnNames::iovSince();
+    iovUntil13Name = RelationalObjectTable::columnNames::iovUntil();
+    iovObjId13Name = RelationalObjectTable::columnNames::objectId();
+    iovChnId13Name = RelationalObjectTable::columnNames::channelId();
+    iovSince13TyId = RelationalObjectTable::columnTypeIds::iovSince;
+    iovUntil13TyId = RelationalObjectTable::columnTypeIds::iovUntil;
+    iovObjId13TyId = RelationalObjectTable::columnTypeIds::objectId;
+  }
+  else
+  {
+    iovTable13 = object2TagTableName;
+    iovSince13Name = RelationalObject2TagTable::columnNames::iovSince;
+    iovUntil13Name = RelationalObject2TagTable::columnNames::iovUntil;
+    iovObjId13Name = RelationalObject2TagTable::columnNames::objectId;
+    iovChnId13Name = RelationalObject2TagTable::columnNames::channelId;
+    iovSince13TyId = RelationalObject2TagTable::columnTypeIds::iovSince;
+    iovUntil13TyId = RelationalObject2TagTable::columnTypeIds::iovUntil;
+    iovObjId13TyId = RelationalObject2TagTable::columnTypeIds::objectId;
+  }
+  std::string chnChnId13Name;
+  std::string chnChnNm13Name;
+  StorageType::TypeId chnChnId13TyId;
+  StorageType::TypeId chnChnNm13TyId;
+  chnChnId13Name = RelationalChannelTable::columnNames::channelId();
+  chnChnNm13Name = RelationalChannelTable::columnNames::channelName();
+  chnChnId13TyId = RelationalChannelTable::columnTypeIds::channelId;
+  chnChnNm13TyId = RelationalChannelTable::columnTypeIds::channelName;
+
+  // --- SUBQUERY 1 (max1: max for one channel) ---
+
+  std::string subQuery1;
+  Record whereDataSQ1;
+  {
+    std::string schemaPrefix;
+    if ( queryMgr().schemaName() != "" )
+      schemaPrefix = queryMgr().schemaName() + ".";
+    // Hint for subquery1
+    std::string hint = hintPrefix + "+ QB_NAME(MAX1) ";
+    if ( getenv( "COOL_QUERYDEFGEN_HINTMAX1" ) )
+    {
+      hint += getenv( "COOL_QUERYDEFGEN_HINTMAX1" );
+    }
+    hint = hint + hintSuffix;
+    // Clause for subquery1
+    subQuery1 += "( SELECT "+hint+" ";
+    subQuery1 += "MAX(COOL_I1." + iovSince13Name + ")";
+    subQuery1 += " FROM " + schemaPrefix + iovTable13 + " COOL_I1";
+    subQuery1 += " WHERE ";
+    subQuery1 += whereClauseTag1;
+    subQuery1 += "COOL_I1."+iovChnId13Name + "=COOL_C2." + chnChnId13Name;
+    subQuery1 += " AND ";
+    subQuery1 += "COOL_I1."+iovSince13Name + "<=:" + quotes+"since1"+quotes;
+    subQuery1 += " )";
+    // Data for subquery1
+    {
+      whereDataSQ1.extend( whereDataTag1 );
+      RecordSpecification spec;
+      spec.extend( "since1", iovSince13TyId );
+      Record rec( spec );
+      rec["since1"].setValue( since );
+      whereDataSQ1.extend( rec );
+    }
+  }
+
+  // --- MAIN QUERY ---
+
+  std::auto_ptr<RelationalQueryDefinition> pMainQuery
+    ( new RelationalQueryDefinition() );
+  RelationalQueryDefinition& mainQuery = *pMainQuery;
+  Record whereDataMQ;
+  std::string whereClauseMQ;
+
+  // --- Formerly SUBQUERY 3 (browse) ---
+  // --- There is no SUBQUERY2 (it is already merged with SQ3!) ---
+  // --- This is the main query for SV and MV user tags (no extra join) ---
+  // --- There is no SUBQUERY3 (it is already merged with MAIN!) ---
+  // --- There is an extra join for MV user tags (no extra join) ---
+
+  {
+    RelationalQueryDefinition& subQuery3 = mainQuery;
+    Record& whereDataSQ3 = whereDataMQ;
+    std::string& whereClauseSQ3 = whereClauseMQ;
+    // FROM ...
+    subQuery3.addFromItem( m_channelTableName, "COOL_C2" );
+    subQuery3.addFromItem( iovTable13, "COOL_I3" );
+    // WHERE ...
+    if ( ! channels.allChannels() )
+    {
+      std::string whereClauseSQ2;
+      Record whereDataSQ2;
+      unsigned int maxNonContiguousRanges = 50;
+      if ( channels.isNumeric() )
+      {
+        if ( channels.firstChannel() == channels.lastChannel() )
+        {
+          whereClauseSQ2 += "COOL_C2."+chnChnId13Name;
+          whereClauseSQ2 += "=:" + quotes+"chid"+quotes;
+          RecordSpecification spec;
+          spec.extend( "chid", chnChnId13TyId );
+          Record rec( spec );
+          rec["chid"].setValue( channels.firstChannel() );
+          whereDataSQ2.extend( rec );
+        }
+        else if ( channels.isContiguous() )
+        {
+          whereClauseSQ2 += "COOL_C2."+chnChnId13Name;
+          whereClauseSQ2 += ">=:" + quotes+"chmin"+quotes;
+          whereClauseSQ2 += " AND ";
+          whereClauseSQ2 += "COOL_C2."+chnChnId13Name;
+          whereClauseSQ2 += "<=:" + quotes+"chmax"+quotes;
+          RecordSpecification spec;
+          spec.extend( "chmin", chnChnId13TyId );
+          spec.extend( "chmax", chnChnId13TyId );
+          Record rec( spec );
+          rec["chmin"].setValue( channels.firstChannel() );
+          rec["chmax"].setValue( channels.lastChannel() );
+          whereDataSQ2.extend( rec );
+        } 
+        else if (channels.rangeCount() <= maxNonContiguousRanges ) 
+        {
+          whereClauseSQ2 += "(";
+          unsigned int index = 0;
+          for (std::vector<ChannelSelection::ChannelRange>::const_iterator
+                 i = channels.begin(); i != channels.end(); ++i) 
+          {
+            if (index > 0) whereClauseSQ2 += " OR ";
+
+            std::stringstream chmin;
+            chmin << "chmin" << index;
+            std::stringstream chmax;
+            chmax << "chmax" << index;
+
+            whereClauseSQ2 += "COOL_C2."+chnChnId13Name;
+            whereClauseSQ2 += ">=:" + quotes+chmin.str()+quotes;
+            whereClauseSQ2 += " AND ";
+            whereClauseSQ2 += "COOL_C2."+chnChnId13Name;
+            whereClauseSQ2 += "<=:" + quotes+chmax.str()+quotes;
+            RecordSpecification spec;
+            spec.extend( chmin.str(), chnChnId13TyId );
+            spec.extend( chmax.str(), chnChnId13TyId );
+            Record rec( spec );
+            rec[chmin.str()].setValue( i->firstChannel() );
+            rec[chmax.str()].setValue( i->lastChannel() );
+            whereDataSQ2.extend( rec );
+
+            ++index;
+          }
+          whereClauseSQ2 += ")";
+        } 
+        else 
+        {
+          std::stringstream s;
+          s << "Non-contiguous channel selection only supported for up to "
+            << maxNonContiguousRanges << " ranges";
+          throw RelationalException(s.str(), "RelationalObjectTable");
+        }
+      }
+      else
+      {
+        whereClauseSQ2 += "COOL_C2."+chnChnNm13Name;
+        whereClauseSQ2 += "=:" + quotes+"chname"+quotes;
+        RecordSpecification spec;
+        spec.extend( "chname", chnChnNm13TyId );
+        Record rec( spec );
+        rec["chname"].setValue( channels.channelName() );
+        whereDataSQ2.extend( rec );
+      }
+      whereClauseSQ3 += whereClauseSQ2 + " AND ";
+      whereDataSQ3.extend( whereDataSQ2 );
+    }
+    // Do not use a subquery for MySQL
+    // (Romain - MySQL performance is bad if there are subqueries)
+    if ( queryMgr().databaseTechnology() == "MySQL" )
+    {
+      whereClauseSQ3 += whereClauseTag3;
+      whereClauseSQ3 += "COOL_I3."+iovChnId13Name+"=COOL_C2."+iovChnId13Name;
+      whereClauseSQ3 += " AND ";
+      {
+        whereDataSQ3.extend( whereDataTag3 );
+      }
+      whereClauseSQ3 += "( ";
+      whereClauseSQ3 += "( ";
+      whereClauseSQ3 += "COOL_I3."+iovSince13Name;
+      whereClauseSQ3 += "<=:" + quotes+"sinc3"+ quotes;
+      whereClauseSQ3 += " AND ";
+      whereClauseSQ3 += "COOL_I3."+iovUntil13Name;
+      whereClauseSQ3 += ">:" + quotes+"sinc3u"+ quotes;
+      whereClauseSQ3 += " )";
+      {
+        whereDataSQ3.extend( whereDataSQ1 );
+        RecordSpecification spec;
+        spec.extend( "sinc3u", iovUntil13TyId );
+        spec.extend( "sinc3", iovUntil13TyId );
+        Record rec( spec );
+        rec["sinc3u"].setValue( since );
+        rec["sinc3"].setValue( since );
+        whereDataSQ3.extend( rec );
+      }
+      whereClauseSQ3 += " OR ";
+      whereClauseSQ3 += "( ";
+      whereClauseSQ3 += "COOL_I3."+iovSince13Name;
+      whereClauseSQ3 += ">=:" + quotes+"sinc3s"+quotes;
+      whereClauseSQ3 += " AND ";
+      whereClauseSQ3 += "COOL_I3."+iovSince13Name;
+      whereClauseSQ3 += "<=:" + quotes+"until3"+quotes;
+      whereClauseSQ3 += " )";
+      whereClauseSQ3 += " )";
+      {
+        RecordSpecification spec;
+        spec.extend( "sinc3s", iovSince13TyId );
+        spec.extend( "until3", iovSince13TyId );
+        Record rec( spec );
+        rec["sinc3s"].setValue( since );
+        rec["until3"].setValue( until );
+        whereDataSQ3.extend( rec );
+      }
+    }
+    else
+    {
+      // Use the chosen SQL query strategy (externalOr vs. internalOr/coalesce)
+      if ( useExternalOr )
+      {
+        //std::cout << "__COOL using EXTERNALOR" << std::endl;
+        // 1. Implementation with external OR
+        whereClauseSQ3 += "( ";
+        whereClauseSQ3 += "( ";
+        whereClauseSQ3 += whereClauseTag3;
+        whereClauseSQ3 += "COOL_I3."+iovChnId13Name+"=COOL_C2."+iovChnId13Name;
+        whereClauseSQ3 += " AND ";
+        {
+          whereDataSQ3.extend( whereDataTag3 );
+        }
+        whereClauseSQ3 += "COOL_I3."+iovSince13Name;
+        whereClauseSQ3 += "=" + subQuery1;
+        whereClauseSQ3 += " AND ";
+        whereClauseSQ3 += "COOL_I3."+iovUntil13Name;
+        whereClauseSQ3 += ">:" + quotes+"sinc3u"+ quotes;
+        {
+          whereDataSQ3.extend( whereDataSQ1 );
+          RecordSpecification spec;
+          spec.extend( "sinc3u", iovUntil13TyId );
+          Record rec( spec );
+          rec["sinc3u"].setValue( since );
+          whereDataSQ3.extend( rec );
+        }
+        whereClauseSQ3 += " ) OR ( ";
+        whereClauseSQ3 += whereClauseTag3b;
+        whereClauseSQ3 += "COOL_I3."+iovChnId13Name+"=COOL_C2."+iovChnId13Name;
+        whereClauseSQ3 += " AND ";
+        {
+          whereDataSQ3.extend( whereDataTag3b );
+        }
+        whereClauseSQ3 += "COOL_I3."+iovSince13Name;
+        whereClauseSQ3 += ">=:" + quotes+"sinc3s"+quotes;
+        whereClauseSQ3 += " AND ";
+        whereClauseSQ3 += "COOL_I3."+iovSince13Name;
+        whereClauseSQ3 += "<=:" + quotes+"until3"+quotes;
+        {
+          RecordSpecification spec;
+          spec.extend( "sinc3s", iovSince13TyId );
+          spec.extend( "until3", iovSince13TyId );
+          Record rec( spec );
+          rec["sinc3s"].setValue( since );
+          rec["until3"].setValue( until );
+          whereDataSQ3.extend( rec );
+        }
+        whereClauseSQ3 += " )";
+        whereClauseSQ3 += " )";
+      }
+      else
+      {
+        whereClauseSQ3 += whereClauseTag3;
+        whereClauseSQ3 += "COOL_I3."+iovChnId13Name+"=COOL_C2."+iovChnId13Name;
+        whereClauseSQ3 += " AND ";
+        {
+          whereDataSQ3.extend( whereDataTag3 );
+        }
+        // Use the chosen SQL query strategy (internalOr vs. coalesce)
+        if ( useCoalesce )
+        {
+          //std::cout << "__COOL using COALESCE" << std::endl;
+          // 2. Implementation with COALESCE
+          whereClauseSQ3 += "COOL_I3."+iovSince13Name;
+          whereClauseSQ3 += ">=COALESCE("+ subQuery1;
+          whereClauseSQ3 += ",:" + quotes+"sinc3s"+quotes + ")";
+          whereClauseSQ3 += " AND ";
+          whereClauseSQ3 += "COOL_I3."+iovSince13Name;
+          whereClauseSQ3 += "<=:" + quotes+"until3"+quotes;
+          whereClauseSQ3 += " AND ";
+          whereClauseSQ3 += "COOL_I3."+iovUntil13Name;
+          whereClauseSQ3 += ">:" + quotes+"sinc3u"+ quotes;
+          {
+            whereDataSQ3.extend( whereDataSQ1 );
+            RecordSpecification spec;
+            spec.extend( "sinc3s", iovSince13TyId );
+            spec.extend( "until3", iovSince13TyId );
+            spec.extend( "sinc3u", iovUntil13TyId );
+            Record rec( spec );
+            rec["sinc3s"].setValue( since );
+            rec["until3"].setValue( until );
+            rec["sinc3u"].setValue( since );
+            whereDataSQ3.extend( rec );
+          }
+        }
+        else
+        {
+          //std::cout << "__COOL using INTERNALOR" << std::endl;
+          // 3. Implementation with internal OR (without COALESCE)
+          whereClauseSQ3 += "( ";
+          whereClauseSQ3 += "( ";
+          whereClauseSQ3 += "COOL_I3."+iovSince13Name;
+          whereClauseSQ3 += "=" + subQuery1;
+          whereClauseSQ3 += " AND ";
+          whereClauseSQ3 += "COOL_I3."+iovUntil13Name;
+          whereClauseSQ3 += ">:" + quotes+"sinc3u"+ quotes;
+          whereClauseSQ3 += " )";
+          {
+            whereDataSQ3.extend( whereDataSQ1 );
+            RecordSpecification spec;
+            spec.extend( "sinc3u", iovUntil13TyId );
+            Record rec( spec );
+            rec["sinc3u"].setValue( since );
+            whereDataSQ3.extend( rec );
+          }
+          whereClauseSQ3 += " OR ";
+          whereClauseSQ3 += "( ";
+          whereClauseSQ3 += "COOL_I3."+iovSince13Name;
+          whereClauseSQ3 += ">=:" + quotes+"sinc3s"+quotes;
+          whereClauseSQ3 += " AND ";
+          whereClauseSQ3 += "COOL_I3."+iovSince13Name;
+          whereClauseSQ3 += "<=:" + quotes+"until3"+quotes;
+          whereClauseSQ3 += " )";
+          whereClauseSQ3 += " )";
+          {
+            RecordSpecification spec;
+            spec.extend( "sinc3s", iovSince13TyId );
+            spec.extend( "until3", iovSince13TyId );
+            Record rec( spec );
+            rec["sinc3s"].setValue( since );
+            rec["until3"].setValue( until );
+            whereDataSQ3.extend( rec );
+          }
+        }
+      }
+    }
+  }
+
+  // --- MAIN QUERY FOR SV AND MV USER TAGS ---
+
+  std::string cool_i_main;
+  if ( pTagId == 0 || isUserTag )
+  {
+    cool_i_main = "COOL_I3.";
+  }
+
+  // --- MAIN QUERY FOR MV TAGS ---
+
+  else
+  {
+    cool_i_main = "COOL_I4.";
+    // --- MAIN QUERY FOR MV TAGS ---
+    mainQuery.addFromItem( objectTableName, "COOL_I4" );
+    // WHERE ...
+    const std::string iovObjIdName =
+      RelationalObjectTable::columnNames::objectId();
+    whereClauseMQ += " AND COOL_I4."+iovObjIdName;
+    whereClauseMQ += "=COOL_I3."+iovObjIdName;
+  }
+
+  // --- MAIN QUERY (COMMON TO ALL CASES) ---
+
+  {
+    // SELECT ...
+    for ( unsigned int i=0; i<tableSpecification().size(); i++ )
+    {
+      std::string expression = tableSpecification()[i].name();
+      // AV PDBSTRESSTEST - START
+      static bool first = true;
+      if ( getenv( "COOL_PDBSTRESSTEST_NBYTES" ) )
+      {
+        if ( expression == "S" )
+        {
+          expression = std::string( "SUBSTR(S,1," ) +
+            getenv( "COOL_PDBSTRESSTEST_NBYTES" ) + ")";
+          //expression = std::string
+          //  ( "SUBSTR(REPLACE(S,SUBSTR(S,100,1),SUBSTR(S,101,1)),1," ) +
+          //  getenv( "COOL_PDBSTRESSTEST_NBYTES" ) + ")";
+          if ( first )
+          {
+            std::cout << "__COOL_PDBSTRESSTEST Hack: will select "
+                      << expression << std::endl;
+            first = false;
+          }
+        }
+      }
+      // AV PDBSTRESSTEST - END
+      expression = cool_i_main + expression;
+      mainQuery.addSelectItem( expression );
+    }
+    mainQuery.setResultSetSpecification( tableSpecification() );
+    // SELECT / * + HINT * / ...
+    if ( queryMgr().databaseTechnology() == "Oracle" ||
+         queryMgr().databaseTechnology() == "frontier" )
+    {
+      // These hints force Oracle to use always the same execution plan:
+      // 1. For different bind variable values (otherwise bind variable
+      // peeking may result in a plan that is good only for some values).
+      // Alternatively one may disable bind variable peeking at the session
+      // level via ALTER SESSION SET "_OPTIM_PEEK_USER_BINDS" = FALSE.
+      // Bind variable peeking cannot be disabled at the statement level
+      // because hint OPT_PARAM('_OPTIM_PEEK_USER_BINDS','FALSE') does not
+      // work (it's essentially ignored, bind variables are peeked anyway).
+      // 2. Whether or not statistics have been computed.
+      std::string hint = hintPrefix+"+ QB_NAME(MAIN) ";
+      if ( getenv( "COOL_QUERYDEFGEN_HINTMAIN" ) )
+      {
+        hint += getenv( "COOL_QUERYDEFGEN_HINTMAIN" );
+      }
+      else if ( pTagId != 0 && *pTagId == 0 && !isUserTag )
+      {
+        // Hints from Romain in task #5821 (current head IOV retrieval)
+        hint += "INDEX(@MAIN COOL_C2@MAIN (CHANNEL_ID)) "; // depends...
+        hint += "INDEX(COOL_I3@MAIN (USER_TAG_ID NEW_HEAD_ID CHANNEL_ID IOV_SINCE IOV_UNTIL)) ";
+        hint += "LEADING(@MAIN COOL_C2@MAIN COOL_I3@MAIN) ";
+        hint += "USE_NL(COOL_I3@MAIN) ";
+        hint += "INDEX(@MAX1 COOL_I1@MAX1 (USER_TAG_ID NEW_HEAD_ID CHANNEL_ID IOV_SINCE IOV_UNTIL)) ";
+      }
+      else if ( pTagId != 0 && !isUserTag )
+      {
+        // Hints from task #5820 (standard tag IOV retrieval)
+        //hint += "INDEX(@MAIN COOL_C2@MAIN (CHANNEL_ID)) "; // depends...
+        hint += "INDEX_RS_ASC(@MAIN COOL_I3@MAIN (TAG_ID CHANNEL_ID IOV_SINCE IOV_UNTIL)) ";
+        hint += "INDEX_RS_ASC(@MAIN COOL_I4@MAIN (OBJECT_ID)) ";
+        hint += "LEADING(@MAIN COOL_C2@MAIN COOL_I3@MAIN COOL_I4@MAIN) ";
+        hint += "USE_NL(@MAIN COOL_I3@MAIN) ";
+        hint += "USE_NL(@MAIN COOL_I4@MAIN) ";
+        hint += "INDEX(@MAX1 COOL_I1@MAX1 (TAG_ID CHANNEL_ID IOV_SINCE IOV_UNTIL)) ";
+      }
+      else if ( pTagId != 0 && isUserTag )
+      {
+        // Hints from Romain in task #6086 (user tag IOV insertion)
+        // Hints apply also to task #4381 (user tag IOV retrieval)
+        //hint += "INDEX(@MAIN COOL_C2@MAIN (CHANNEL_ID)) "; // depends...
+        hint += "INDEX_RS_ASC(@MAIN COOL_I3@MAIN (USER_TAG_ID NEW_HEAD_ID CHANNEL_ID IOV_SINCE IOV_UNTIL)) ";
+        hint += "LEADING(@MAIN COOL_C2@MAIN COOL_I3@MAIN) ";
+        hint += "USE_NL(COOL_I3@MAIN) ";
+        hint += "INDEX(@MAX1 COOL_I1@MAX1 (USER_TAG_ID NEW_HEAD_ID CHANNEL_ID IOV_SINCE IOV_UNTIL)) ";
+      }
+      else if ( pTagId == 0 )
+      {
+        // Hints for SV IOV retrieval (task #2223, task #3675, task #4402)
+        hint += "INDEX(COOL_C2@MAIN (CHANNEL_ID)) ";
+        hint += "INDEX(COOL_I3@MAIN (CHANNEL_ID IOV_SINCE IOV_UNTIL)) ";
+        hint += "LEADING(COOL_C2@MAIN COOL_I3@MAIN) ";
+        hint += "USE_NL(COOL_I3@MAIN) ";
+        hint += "INDEX(@MAX1 COOL_I1@MAX1 (CHANNEL_ID IOV_SINCE IOV_UNTIL)) ";
+      }
+      hint += hintSuffix;
+      mainQuery.setHint( hint );
+    }
+    if ( payloadQuery !=0 )
+    {
+      RelationalPayloadQuery pq(*payloadQuery, cool_i_main,
+                                queryMgr().databaseTechnology());
+
+      if ( pq.isTrusted() ) {
+        whereClauseMQ+=" AND ( "+pq.whereClause()+" )";
+        whereDataMQ.extend( pq.whereData() );
+      }
+      //std::cout <<"where clause "<< whereClauseMQ << std::endl;
+    }
+    // WHERE...
+    mainQuery.setWhereClause( whereClauseMQ );
+    //std::cout << "Bind variables: " << whereDataMQ << std::endl;
+    mainQuery.setBindVariables( whereDataMQ );
+    // ORDER BY ...
+    std::vector<std::string> orderBy = orderByClause( channels );
+    for ( std::vector<std::string>::const_iterator
+            it = orderBy.begin(); it != orderBy.end(); it++ )
+    {
+      // TODO: Optimise? Use cool_c2.channel_id, cool_i3.iov_since?
+      //mainQuery.addOrderItem( cool_i_main + *it ); // no good?...
+      mainQuery.addOrderItem( "COOL_I3." + *it ); // better...
+    }
+  }
+
+  // --- RETURN THE MAIN QUERY DEFINITION ---
+  //log() << "Prepared generic query definition: "
+  //      << *pMainQuery << coral::MessageStream::endmsg;
+  return std::auto_ptr<IRelationalQueryDefinition>( pMainQuery.release() );
+
+}
+
+//---------------------------------------------------------------------------
diff --git a/RelationalCool/src/RelationalObjectTable.h b/RelationalCool/src/RelationalObjectTable.h
new file mode 100644
index 000000000..488745b96
--- /dev/null
+++ b/RelationalCool/src/RelationalObjectTable.h
@@ -0,0 +1,327 @@
+// $Id: RelationalObjectTable.h,v 1.109 2008-11-04 11:52:11 avalassi Exp $
+#ifndef RELATIONALCOOL_RELATIONALOBJECTTABLE_H
+#define RELATIONALCOOL_RELATIONALOBJECTTABLE_H
+
+// Include files
+#include <memory>
+#include "CoralBase/AttributeSpecification.h"
+#include "CoralBase/MessageStream.h"
+#include "CoolKernel/IObject.h"
+#include "CoolKernel/Record.h"
+#include "CoolKernel/RecordSpecification.h"
+#include "CoolKernel/ValidityKey.h"
+#include "CoolKernel/IRecordSelection.h"
+
+// Local include files
+#include "RelationalQueryMgr.h"
+#include "uppercaseString.h"
+
+namespace cool {
+
+  // Forward declarations
+  class ChannelSelection;
+  class IRelationalQueryDefinition;
+  class RelationalFolder;
+  class RelationalObjectTableRow;
+  class RelationalTagMgr;
+
+  /** @class RelationalObjectTable RelationalObjectTable.h
+   *
+   *  Relational schema of the table storing COOL conditions "objects"
+   *
+   *  Relational implementation of the object table queries
+   *  in termns of the RelationalQueryMgr.
+   *
+   *  @author Andrea Valassi, Sven A. Schmidt and Marco Clemencic
+   *  @date   2004-12-16
+   */
+
+  class RelationalObjectTable
+  {
+
+    friend class RelationalObjectMgrTest;
+    friend class RelationalObjectTableTest;
+    
+  public:
+
+    static const std::string defaultTableName
+    ( const std::string& prefix, unsigned nodeId ) {
+      char tableName[] = "Fxxxx_IOVS";
+      sprintf( tableName, "F%4.4i_IOVS", nodeId );
+      // TEMPORARY? AV 04.04.2005
+      // FIXME: presently the prefix is uppercase anyway...
+      return uppercaseString( prefix ) + std::string( tableName );
+    }
+
+    static const std::string sequenceName( const std::string& tableName ) {
+      // TEMPORARY? AV 04.04.2005
+      // FIXME: presently the input table name is uppercase anyway...
+      return uppercaseString(tableName) + "_SEQ";
+    }
+
+    struct columnNames {
+      static const std::string objectId() { return "OBJECT_ID"; }
+      static const std::string channelId() { return "CHANNEL_ID"; }
+      static const std::string iovSince() { return "IOV_SINCE"; }
+      static const std::string iovUntil() { return "IOV_UNTIL"; }
+      static const std::string userTagId() { return "USER_TAG_ID"; }
+      static const std::string sysInsTime() { return "SYS_INSTIME"; }
+      static const std::string lastModDate() { return "LASTMOD_DATE"; }
+      static const std::string originalId() { return "ORIGINAL_ID"; }
+      static const std::string newHeadId() { return "NEW_HEAD_ID"; }
+    };
+
+    struct columnTypeIds {
+      static const StorageType::TypeId objectId   = StorageType::UInt32;
+      static const StorageType::TypeId channelId  = StorageType::UInt32;
+      static const StorageType::TypeId iovSince   = StorageType::UInt63;
+      static const StorageType::TypeId iovUntil   = StorageType::UInt63;
+      static const StorageType::TypeId userTagId  = StorageType::UInt32;
+      // TEMPORARY! Should be Time?
+      static const StorageType::TypeId sysInsTime = StorageType::String255;
+      // TEMPORARY! Should be Time?
+      static const StorageType::TypeId lastModDate = StorageType::String255;
+      static const StorageType::TypeId originalId = StorageType::UInt32;
+      static const StorageType::TypeId newHeadId  = StorageType::UInt32;
+    };
+
+    struct columnTypes {
+      typedef UInt32 objectId;
+      typedef UInt32 channelId;
+      typedef UInt63 iovSince;
+      typedef UInt63 iovUntil;
+      typedef UInt32 userTagId;
+      // TEMPORARY! Should be Time?
+      typedef String255 sysInsTime;
+      // TEMPORARY! Should be Time?
+      typedef String255 lastModDate;
+      typedef UInt32 originalId;
+      typedef UInt32 newHeadId;
+    };
+
+  public:
+
+    // Destructor
+    virtual ~RelationalObjectTable();
+
+    /// Constructor
+    RelationalObjectTable
+    ( RelationalQueryMgr* pQueryMgr,
+      bool ownQueryMgr,
+      const RelationalFolder& folder );
+
+    const IRecordSpecification& payloadSpecification() const {
+      return m_payloadSpecification;
+    }
+
+    const IRecordSpecification& tableSpecification() const {
+      return m_tableSpecification;
+    }
+
+    /// Returns the table specification for the given payload columns
+    static const RecordSpecification tableSpecification
+    ( const IRecordSpecification& payloadSpec );
+
+    /// Returns an AttributeList for the given payload columns
+    static const coral::AttributeList rowAttributeList
+    ( const coral::AttributeList& payload );
+
+    /// Define the ORDER clause for the SV, MV HEAD and MV Tag selections.
+    static const 
+    std::vector<std::string> orderByClause
+    ( const ChannelSelection& channels,
+      const std::string& objectTableName = "" );
+
+    /// Define the query for the SV selection.
+    std::auto_ptr<IRelationalQueryDefinition>
+    queryDefinitionSV( const ValidityKey& since,
+                       const ValidityKey& until,
+                       const ChannelSelection& channels, 
+                       const IRecordSelection* payloadQuery = 0 );
+
+    /// Define the query for the MV user tag and HEAD selection;
+    /// user tags are assumed unless isHeadTag(userTagName) is true.
+    std::auto_ptr<IRelationalQueryDefinition>
+    queryDefinitionHeadAndUserTag( const ValidityKey& since,
+                                   const ValidityKey& until,
+                                   const ChannelSelection& channels,
+                                   const std::string& userTagName, 
+                                   const IRecordSelection* payloadQuery = 0 );
+
+    /// Define the query for the MV tag selection.
+    std::auto_ptr<IRelationalQueryDefinition>
+    queryDefinitionTag( const ValidityKey& since,
+                        const ValidityKey& until,
+                        const ChannelSelection& channels,
+                        //unsigned int tagId );
+                        const std::string& tagName, 
+                        const IRecordSelection* payloadQuery = 0 );
+
+    /// Define the query for all four: SV, MV user tag, MV HEAD and MV tag.
+    /// By default this defines the SV query (pTagId==0, isUserTag is ignored).
+    /// The HEAD case is triggered if (*pTagId)==0 (isUserTag is ignored).
+    std::auto_ptr<IRelationalQueryDefinition>
+    queryDefinitionGeneric( const ValidityKey& since,
+                            const ValidityKey& until,
+                            const ChannelSelection& channels,
+                            const unsigned int* pTagId = 0,
+                            bool isUserTag = true, 
+                            const IRecordSelection* payloadQuery = 0 );
+
+  public:
+
+    /// Returns the table name.
+    const std::string& objectTableName() const { return m_objectTableName; }
+
+    /// Returns the associated tag table name.
+    const std::string& tagTableName() const { return m_tagTableName; }
+
+    /// Returns the associated IOV2tag table name.
+    const std::string& object2TagTableName() const {
+      return m_object2TagTableName; }
+
+    /// Returns the associated channel table name.
+    const std::string& channelTableName() const { return m_channelTableName; }
+    
+    /*
+    /// TEMPORARY! This is ONLY needed by David's VerificationClient
+    /// Fetch one IOV row (lookup for last inserted row in 1 channel - SV)
+    /// [Rows are inserted with strictly ascending objectIds: this method
+    /// fetches the row with the highest objectId in the given channel]
+    RelationalObjectTableRow fetchLastRowSV( const ChannelId& channelId,
+                                             bool fetchPayload = false );
+    */
+
+    /// Fetch the last row in a given tag (the highest object_id)
+    const RelationalObjectTableRow 
+    fetchLastRowForTagId( unsigned int tagId,
+                          bool fetchPayload = false ) const;
+
+    /// Fetch one IOV row (lookup at 1 time in 1 channel in HEAD tag - MV)
+    /// \todo TODO sas 2006-04-11 - this method was mainly used in findObject
+    /// which is now using browseObjects instead. There's one other use
+    /// (apart from tests) in RalDatabase that could be eliminated.
+    const RelationalObjectTableRow fetchRowAtTimeInHead
+    ( const ValidityKey& pointInTime,
+      const ChannelId& channelId,
+      unsigned int userTagId = 0 );
+
+    /*
+    /// Fetch one IOV row (lookup at 1 time in 1 channel in 1 tag - MV)
+    /// \todo TODO sas 2006-04-11 - this method was mainly used in findObject
+    /// which is now using browseObjects instead. There's no other use
+    /// (apart from tests).
+    RelationalObjectTableRow fetchRowAtTimeInTag
+    ( const ValidityKey& pointInTime,
+      const ChannelId& channelId,
+      const std::string& tagName );
+    */
+
+    std::auto_ptr< std::vector<RelationalObjectTableRow> > 
+    fetchRowsBtTimesInHead
+    ( const ValidityKey& since,
+      const ValidityKey& until,
+      const ChannelId& channelId,
+      unsigned int userTagId,
+      unsigned int maxRows );
+    
+    /// Utility method to fetch the HEAD object table rows for tagging
+    /// The query only fetches the meta data (object_id, since, until,...)
+    /// in order to avoid reading the payload and be more lightweight.
+    /// Therefore the normal fetchObjectTableRows method is not used.
+    std::vector<RelationalObjectTableRow> fetchRowsForTaggingCurrentHead();
+
+    /// Utility method to fetch the object table rows 'asOfDate' for tagging.
+    /// The query only fetches the meta data (object_id, since, until,...)
+    /// in order to avoid reading the payload and be more lightweight.
+    /// Therefore the normal fetchObjectTableRows method is not used.
+    std::vector<RelationalObjectTableRow> fetchRowsForTaggingHeadAsOfDate
+    ( const ITime& asOfDate );
+
+    /// Utility method to fetch the object table rows 'asOfObjectId'
+    /// for tagging. The object with id 'objectId' is included.
+    /// The query only fetches the meta data (object_id, since, until,...)
+    /// in order to avoid reading the payload and be more lightweight.
+    /// Therefore the normal fetchObjectTableRows method is not used.
+    std::vector<RelationalObjectTableRow> fetchRowsForTaggingHeadAsOfObjectId
+    ( unsigned int asOfObjectId );
+
+    /// Returns the name of the object_id sequence associated with this table.
+    const std::string sequenceName() {
+      // TEMPORARY? AV 04.04.2005
+      // FIXME: presently the input table name is uppercase anyway...
+      return uppercaseString( objectTableName() ) + "_SEQ";
+    }
+
+    /// Returns the table specification for the given payload columns
+    static const IRecordSpecification& defaultSpecification();
+        
+    /// Does a channel with this id exist?
+    /// This is needed by dropChannel (throw if the channel has any IOVs).
+    bool existsChannel( const ChannelId& channelId ) const;
+
+  protected:
+
+    /// Get a CORAL MessageStream
+    coral::MessageStream& log() const;
+
+    /// Get the RelationalQueryMgr associated to this table
+    RelationalQueryMgr& queryMgr() const { return *m_pQueryMgr; }
+
+    /// Fetch one IOV row (lookup by 1 objectId - SV and MV)
+    const RelationalObjectTableRow 
+    fetchRowForId( unsigned int objectId,
+                   bool fetchPayload = false ) const;
+
+  private:
+
+    /// Copy constructor is private
+    RelationalObjectTable( const RelationalObjectTable& rhs );
+
+    /// Assignment operator is private
+    RelationalObjectTable& operator=( const RelationalObjectTable& rhs );
+
+    /// CORAL MessageStream
+    std::auto_ptr<coral::MessageStream> m_log;
+
+    /// Relational query manager
+    RelationalQueryMgr* m_pQueryMgr;
+
+    /// Does this instance own the relational query manager?
+    bool m_ownQueryMgr;
+
+  protected: // TEMPORARY? For the RelationalObjectTableTest friend only
+
+    /// Relational tag manager
+    RelationalTagMgr& m_tagMgr;
+
+  private:
+
+    /// Payload specification
+    RecordSpecification m_payloadSpecification;
+
+    /// Full table specification
+    RecordSpecification m_tableSpecification;
+
+    /// IOV table name
+    std::string m_objectTableName;
+
+    /// Tag table name
+    std::string m_tagTableName;
+
+    /// IOV2tag table name
+    std::string m_object2TagTableName;
+
+    /// Channel table name
+    std::string m_channelTableName;
+
+  protected: // TEMPORARY? For the RelationalObjectTableTest friend only
+
+    /// Node id for this node
+    unsigned int m_nodeId;
+
+  };
+
+}
+
+#endif // RELATIONALCOOL_RELATIONALOBJECTTABLE_H
diff --git a/RelationalCool/src/RelationalObjectTableRow.cpp b/RelationalCool/src/RelationalObjectTableRow.cpp
new file mode 100644
index 000000000..39e295ff6
--- /dev/null
+++ b/RelationalCool/src/RelationalObjectTableRow.cpp
@@ -0,0 +1,237 @@
+// $Id: RelationalObjectTableRow.cpp,v 1.25 2008-11-04 11:52:11 avalassi Exp $
+
+#include "CoralBase/AttributeSpecification.h"
+
+// Local include files
+#include "RelationalObjectTable.h"
+#include "RelationalObjectTableRow.h"
+#include "timeToString.h"
+
+// Namespace
+using namespace cool;
+
+//-----------------------------------------------------------------------------
+
+RelationalObjectTableRow::~RelationalObjectTableRow() 
+{
+}
+
+//-----------------------------------------------------------------------------
+
+RelationalObjectTableRow::RelationalObjectTableRow
+( const coral::AttributeList& data )
+  : RelationalTableRowBase( data )
+{
+}
+
+//-----------------------------------------------------------------------------
+
+RelationalObjectTableRow::RelationalObjectTableRow( const IObjectPtr& object )
+  : RelationalTableRowBase( RelationalObjectTable::rowAttributeList
+                            ( object->payload().attributeList() ) )
+{
+  
+  m_data[RelationalObjectTable::columnNames::objectId()].setValue
+    ( object->objectId() );
+  
+  m_data[RelationalObjectTable::columnNames::channelId()].setValue
+    ( object->channelId() );
+  
+  m_data[RelationalObjectTable::columnNames::iovSince()].setValue
+    ( object->since() );
+
+  m_data[RelationalObjectTable::columnNames::iovUntil()].setValue
+    ( object->until() );
+  
+  m_data[RelationalObjectTable::columnNames::sysInsTime()].setValue
+    ( std::string("") );
+  
+  m_data[RelationalObjectTable::columnNames::lastModDate()].setValue
+    ( std::string("") );
+  
+  m_data[RelationalObjectTable::columnNames::originalId()].setValue( 0u );
+  
+  m_data[RelationalObjectTable::columnNames::newHeadId()].setValue( 0u );
+  
+  // Add the data payload columns
+  const coral::AttributeList& payload = object->payload().attributeList();
+  for ( coral::AttributeList::const_iterator attr = payload.begin(); 
+        attr != payload.end(); 
+        ++attr ) {
+    // share data instead of copying
+    m_data[ attr->specification().name() ].shareData( *attr );
+    // copy
+    //coral::AttributeValueAccessor
+    //( (*m_data)[ attr->spec().name() ] ).setValueFromData
+    //( coral::AttributeValueAccessor( *attr ).getMemoryAddress() );
+  }  
+    
+}
+
+//-----------------------------------------------------------------------------
+
+RelationalObjectTableRow::RelationalObjectTableRow
+( const RelationalTableRow& row )
+  : RelationalTableRowBase( row.data() )
+{
+}
+
+//-----------------------------------------------------------------------------
+
+RelationalObjectTableRow::RelationalObjectTableRow
+( const RelationalObjectTableRow& aRow ) 
+  : RelationalTableRowBase( aRow )
+{
+}
+
+//-----------------------------------------------------------------------------
+
+RelationalObjectTableRow& 
+RelationalObjectTableRow::operator=( const RelationalObjectTableRow& rhs ) 
+{
+  m_data = rhs.m_data;
+  return *this;
+}
+
+//-----------------------------------------------------------------------------
+/*
+const RelationalObjectTableRow& 
+RelationalObjectTableRow::operator=( const RelationalObjectTableRow& rhs ) {
+  m_spec = rhs.m_spec;
+  m_data = AttrListPtr( new coral::AttributeList( m_spec ) );
+  
+  // Copy the individual Attribute values
+  coral::AttributeList::const_iterator sourceAttr;
+  coral::AttributeList::iterator targetAttr = m_data->begin();
+  for ( sourceAttr = rhs.m_data->begin(); 
+        sourceAttr != rhs.m_data->end(); 
+        sourceAttr++, targetAttr++ ) {
+    
+    coral::AttributeValueAccessor( *targetAttr ).setValueFromData
+    ( coral::AttributeValueAccessor( *sourceAttr ).getMemoryAddress() );
+    
+  }
+  
+  return *this;
+}
+*/
+//-----------------------------------------------------------------------------
+
+unsigned int RelationalObjectTableRow::objectId() const 
+{
+  return
+  m_data[RelationalObjectTable::columnNames::objectId()].data<unsigned int>();
+}
+
+//-----------------------------------------------------------------------------
+
+ValidityKey RelationalObjectTableRow::since() const 
+{
+  return
+  m_data[RelationalObjectTable::columnNames::iovSince()].data<ValidityKey>();
+}
+
+//-----------------------------------------------------------------------------
+
+ValidityKey RelationalObjectTableRow::until() const 
+{
+  return
+  m_data[RelationalObjectTable::columnNames::iovUntil()].data<ValidityKey>();
+}
+
+//-----------------------------------------------------------------------------
+
+ChannelId RelationalObjectTableRow::channelId() const 
+{
+  return
+  m_data[RelationalObjectTable::columnNames::channelId()].data<ChannelId>();
+}
+
+//-----------------------------------------------------------------------------
+
+unsigned int RelationalObjectTableRow::userTagId() const 
+{
+  return
+  m_data[RelationalObjectTable::columnNames::userTagId()].data<unsigned int>();
+}
+
+//-----------------------------------------------------------------------------
+
+unsigned int RelationalObjectTableRow::originalId() const 
+{
+  return
+  m_data[RelationalObjectTable::columnNames::originalId()]
+  .data<unsigned int>();
+}
+
+//-----------------------------------------------------------------------------
+
+unsigned int RelationalObjectTableRow::newHeadId() const 
+{
+  return
+  m_data[RelationalObjectTable::columnNames::newHeadId()].data<unsigned int>();
+}
+
+//-----------------------------------------------------------------------------
+
+Time RelationalObjectTableRow::insertionTime() const 
+{
+  std::string value =
+  m_data[RelationalObjectTable::columnNames::sysInsTime()].data<std::string>();
+  return stringToTime( value );
+}
+
+//-----------------------------------------------------------------------------
+
+Time RelationalObjectTableRow::lastModDate() const 
+{
+  std::string value =
+  m_data[RelationalObjectTable::columnNames::lastModDate()]
+    .data<std::string>();
+  return stringToTime( value );
+}
+
+//-----------------------------------------------------------------------------
+
+void RelationalObjectTableRow::setObjectId( unsigned int objectId ) 
+{
+  m_data[RelationalObjectTable::columnNames::objectId()].setValue( objectId );
+}
+
+//-----------------------------------------------------------------------------
+
+void RelationalObjectTableRow::setSince( const ValidityKey& since ) 
+{
+  m_data[RelationalObjectTable::columnNames::iovSince()].setValue( since );
+}
+
+//-----------------------------------------------------------------------------
+
+void RelationalObjectTableRow::setUntil( const ValidityKey& until ) 
+{
+  m_data[RelationalObjectTable::columnNames::iovUntil()].setValue( until );
+}
+
+//-----------------------------------------------------------------------------
+
+void RelationalObjectTableRow::setUserTagId( unsigned int userTagId ) 
+{
+  m_data[RelationalObjectTable::columnNames::userTagId()].setValue( userTagId );
+}
+
+//-----------------------------------------------------------------------------
+
+void RelationalObjectTableRow::setOriginalId( unsigned int value ) 
+{
+  m_data[RelationalObjectTable::columnNames::originalId()].setValue( value );
+}
+
+//-----------------------------------------------------------------------------
+
+void RelationalObjectTableRow::setNewHeadId( unsigned int value ) 
+{
+  m_data[RelationalObjectTable::columnNames::newHeadId()].setValue( value );
+}
+
+//-----------------------------------------------------------------------------
+
diff --git a/RelationalCool/src/RelationalObjectTableRow.h b/RelationalCool/src/RelationalObjectTableRow.h
new file mode 100644
index 000000000..9e5044a41
--- /dev/null
+++ b/RelationalCool/src/RelationalObjectTableRow.h
@@ -0,0 +1,177 @@
+// $Id: RelationalObjectTableRow.h,v 1.31 2008-11-04 11:52:11 avalassi Exp $
+#ifndef RELATIONALCOOL_RELATIONALOBJECTTABLEROW_H
+#define RELATIONALCOOL_RELATIONALOBJECTTABLEROW_H
+
+// Include files
+#include "CoolKernel/IObject.h"
+#include "CoolKernel/Time.h"
+#include "CoolKernel/ValidityKey.h"
+#include "CoralBase/Attribute.h"
+#include "CoralBase/AttributeListException.h"
+
+// Local include files
+#include "RelationalTableRow.h"
+#include "RelationalTableRowBase.h"
+
+namespace cool {  
+  
+  /** @class RelationalObjectTableRow RelationalObjectTableRow.h
+   *  
+   *  Representation of a RelationalObject as a row in the object table.
+   *  Used internally to read/write data from/into persistent storage.
+   *
+   *  @author Andrea Valassi, Sven A. Schmidt and Marco Clemencic
+   *  @date   2005-02-09
+   */
+  
+  class RelationalObjectTableRow : public RelationalTableRowBase
+  {
+
+  public:
+
+    /// Destructor
+    virtual ~RelationalObjectTableRow();
+
+    /// Constructor from an AttributeList.
+    /// Performs a deep copy of the AttributeList values.
+    explicit RelationalObjectTableRow( const coral::AttributeList& data );
+    
+    /// Constructor from an IObjectPtr.
+    /// For performance reasons, only copies references to the object payload:
+    /// a row is expected to never outlive the object it originated from.
+    explicit RelationalObjectTableRow( const IObjectPtr& object );
+
+    /// Constructor from a RelationalTableRow.
+    /// This constructor is used to 'reinterpret' a generic table row as
+    /// obtained from fetch methods as a RelationalObjectTableRow.
+    explicit RelationalObjectTableRow( const RelationalTableRow& row );
+    
+    /// Copy constructor
+    /// Performs a deep copy of the AttributeList values.
+    RelationalObjectTableRow( const RelationalObjectTableRow& aRow );
+    
+    /// Assignment operator.
+    /// Performs a deep copy of the AttributeList values.
+    RelationalObjectTableRow& operator=( const RelationalObjectTableRow& rhs );
+    
+    /// Comparison operator -- only takes into account object_id
+    bool operator==( const RelationalObjectTableRow& rhs ) 
+    {
+      return objectId() == rhs.objectId();
+    }
+    
+    /// Returns true if the given point in time lies in the row's IOV
+    bool contains( const ValidityKey& pointInTime ) 
+    {
+      return since() <= pointInTime && pointInTime < until();
+    }
+    
+    /// Returns the object id
+    unsigned int objectId() const;
+    
+    /// Returns the beginning of the IOV
+    ValidityKey since() const;
+    
+    /// Returns the beginning of the IOV
+    ValidityKey until() const;
+    
+    /// Returns the channel id
+    ChannelId channelId() const;
+    
+    /// Returns the user tag id
+    unsigned int userTagId() const;
+    
+    /// Returns the original id
+    unsigned int originalId() const;
+    
+    /// Returns the new head id
+    unsigned int newHeadId() const;
+    
+    /// Returns the insertion time
+    Time insertionTime() const;
+    
+    /// Returns the last modification date
+    Time lastModDate() const;
+    
+    /// Sets the object id
+    void setObjectId( unsigned int objectId );
+    
+    /// Sets the beginning of the IOV
+    void setSince( const ValidityKey& since );
+    
+    /// Sets the end of the IOV
+    void setUntil( const ValidityKey& until );
+    
+    /// Sets the user tag id
+    void setUserTagId( unsigned int userTagId );
+    
+    /// Sets the original id
+    void setOriginalId( unsigned int value );
+    
+    /// Sets the new head id
+    void setNewHeadId( unsigned int value );
+    
+    /// Data payload value for a specific payload item - returned as true type
+    template<class T> const T& payloadValue( const std::string& name ) const 
+    {
+      // AV 19.06.2006 Old version that works for Linux gcc323
+      //return m_data[name].data();
+      // SAS 19.06.2006 changed for linux gcc403 but fails for Linux gcc323
+      //return m_data[name].data<T>();
+      // MCl 28.03.2006 this one works on gcc 4.x and 3.2
+      return m_data[name].template data<T>();
+    }
+    
+  private:
+
+    /// Standard constructor is private.
+    RelationalObjectTableRow();
+
+  };
+
+  /// Streamer for RelationalObjectTableRow objects
+  inline std::ostream &operator<<
+    ( std::ostream& s, const RelationalObjectTableRow& r ) 
+  {
+    s << r.objectId() << " [" << r.since() << "," << r.until() << "] ";
+    s << "[";
+    bool first = true;
+    for ( coral::AttributeList::const_iterator attr = r.begin();
+          attr != r.end(); ++attr ) {
+      if ( first ) {
+        first = false;
+      } else {
+        s << "|";
+      }
+      attr->toOutputStream( s );
+    }
+    s << "] ";
+    try {
+      s << r.originalId() << " " << r.newHeadId();
+    } catch ( coral::AttributeListException& ) { /* ignored */ }
+    return s;
+  }
+  
+  /// Comparison functor to compare RelationalObjectTableRow by their objectId
+  struct eq_objectId : 
+    public std::binary_function<RelationalObjectTableRow, unsigned int, bool>
+  {
+    bool operator()( const RelationalObjectTableRow& r,
+                     unsigned int objectId ) const { 
+      return r.objectId() == objectId; }
+  };
+  
+  /// Less than comparison functor to compare RelationalObjectTableRow 
+  /// by their objectId
+  struct lt_objectId : 
+    public std::binary_function< RelationalObjectTableRow, 
+    RelationalObjectTableRow, bool>
+  {
+    bool operator()( const RelationalObjectTableRow& lhs,
+                     const RelationalObjectTableRow& rhs ) const { 
+      return lhs.objectId() < rhs.objectId(); }
+  };
+  
+}
+
+#endif // RELATIONALCOOL_RELATIONALOBJECTTABLEROW_H
diff --git a/RelationalCool/src/RelationalPayloadQuery.cpp b/RelationalCool/src/RelationalPayloadQuery.cpp
new file mode 100644
index 000000000..385b7c6e7
--- /dev/null
+++ b/RelationalCool/src/RelationalPayloadQuery.cpp
@@ -0,0 +1,315 @@
+// $Id: RelationalPayloadQuery.cpp,v 1.13 2008-11-04 11:52:11 avalassi Exp $
+
+// Include files
+#include <typeinfo>
+#include "CoolKernel/InternalErrorException.h"
+
+// Local include files
+#include "RelationalException.h"
+#include "RelationalPayloadQuery.h"
+
+// Namespace
+using namespace cool;
+
+//---------------------------------------------------------------------------
+
+RelationalPayloadQuery::~RelationalPayloadQuery() 
+{
+}
+ 
+//---------------------------------------------------------------------------
+
+RelationalPayloadQuery::RelationalPayloadQuery( const IRecordSelection& sel,
+                                                const std::string& tableName,
+                                                const std::string& technology )
+  : m_tableName( tableName )
+  , m_technology( technology )
+{
+  if ( m_technology != "" &&
+       m_technology != "Oracle" &&
+       m_technology != "MySQL" &&
+       m_technology != "SQLite" &&
+       m_technology != "Frontier" )
+    throw RelationalException( "Unknown technology '" + technology + "'", 
+                               "RelationalPayloadQuery" );
+
+  // Build the WHERE clause and WHERE data for the selection
+  m_isTrusted = addSelection( sel, m_whereClause, m_whereData );
+
+  // Reset WHERE clause and WHERE data if the query is not trusted
+  if ( !m_isTrusted )
+  {
+    m_whereClause = "";
+    m_whereData = Record();
+  }
+
+}
+
+//---------------------------------------------------------------------------
+
+const std::string& RelationalPayloadQuery::whereClause() const
+{
+  if ( !m_isTrusted )
+    throw RelationalException( "Query is not trusted", 
+                               "RelationalPayloadQuery" );
+  return m_whereClause;
+}
+ 
+//---------------------------------------------------------------------------
+
+const IRecord& RelationalPayloadQuery::whereData() const
+{
+  if ( !m_isTrusted )
+    throw RelationalException( "Query is not trusted", 
+                               "RelationalPayloadQuery" );
+  return m_whereData;
+}
+ 
+//---------------------------------------------------------------------------
+
+const std::string 
+RelationalPayloadQuery::bindVariableName( unsigned ibv ) const
+{
+  if ( ibv >= 10000 )
+    throw RelationalException( "Too many bind variables!",
+                               "RelationalPayloadQuery" );
+  char cName[] = "pqbv0001";
+  int cSize = std::string(cName).size();
+  if ( sprintf( cName, "pqbv%4.4d", ibv ) != cSize )
+    throw InternalErrorException( "PANIC! Error encoding bind variable name",
+                                  "RelationalPayloadQuery" );
+  std::string sName( cName );
+  return sName;
+}
+
+//---------------------------------------------------------------------------
+
+bool
+RelationalPayloadQuery::addSelection( const IRecordSelection& sel,
+                                      std::string& whereClause,
+                                      Record& whereData ) const
+{
+  // Loop over trusted query classes
+  const std::type_info& selType = typeid( sel );
+
+  // Is the query a FieldSelection?
+  if ( selType == typeid( FieldSelection ) )
+  {
+    const FieldSelection* pSel = 
+      dynamic_cast<const FieldSelection*>( &sel );
+    if ( !pSel ) 
+      throw InternalErrorException
+        ( "PANIC! Cannot dynamic cast to FieldSelection*",
+          "RelationalPayloadQuery" );
+    // Add the WHERE clause and WHERE data for a FieldSelection
+    return addFieldSelection( *pSel, whereClause, whereData );
+  }
+
+  // Is the query a CompositeSelection?
+  else if ( selType == typeid( CompositeSelection ) )
+  {
+    const CompositeSelection* pSel = 
+      dynamic_cast<const CompositeSelection*>( &sel );
+    if ( !pSel ) 
+      throw InternalErrorException
+        ( "PANIC! Cannot dynamic cast to CompositeSelection*",
+          "RelationalPayloadQuery" );
+    // Add the WHERE clause and WHERE data for a CompositeSelection
+    return addCompositeSelection( *pSel, whereClause, whereData );
+  }
+
+  // UNKNOWN query (user-supplied query)
+  else
+  {
+    return false;
+  }
+
+}
+
+//---------------------------------------------------------------------------
+
+bool
+RelationalPayloadQuery::addFieldSelection( const FieldSelection& sel,
+                                           std::string& whereClause,
+                                           Record& whereData ) const
+{
+  FieldSelection::Relation rel = sel.relation();
+  const IField& ref = sel.referenceValue();
+
+  // FieldSelection is a comparison to NULL (either IS_NULL or IS_NOT_NULL)
+  if ( ref.isNull() )
+  {
+    FieldSelection::Nullness nul = sel.nullness();
+    // No path to here if ref is a string: ref.isNull() is always false!
+    if ( ref.specification().storageType().id() == StorageType::String255 ||
+         ref.specification().storageType().id() == StorageType::String4k  ||
+         ref.specification().storageType().id() == StorageType::String64k ||
+         ref.specification().storageType().id() == StorageType::String16M )
+      throw InternalErrorException
+        ( "PANIC! isNull() cannot be true for string fields",
+          "RelationalPayloadQuery" );
+    // Add the WHERE clause (no WHERE data to add)
+    if ( m_tableName != "" ) whereClause += m_tableName;
+    whereClause += ref.specification().name();
+    whereClause += " ";
+    whereClause += FieldSelection::describe( nul ); // IS_NULL or IS_NOT_NULL
+  }
+
+  // FieldSelection is NOT a comparison to NULL
+  // (but it could still be a comparison to the '' string)
+  else
+  {
+    // Special handling for strings
+    if ( ref.specification().storageType().id() == StorageType::String255 ||
+         ref.specification().storageType().id() == StorageType::String4k  ||
+         ref.specification().storageType().id() == StorageType::String64k ||
+         ref.specification().storageType().id() == StorageType::String16M )
+    {
+      if ( rel != FieldSelection::EQ && rel != FieldSelection::NE )
+        throw InternalErrorException
+          ( "PANIC! Relation other than EQ or NE for strings",
+            "RelationalPayloadQuery" );
+      // Comparison to empty string ''
+      if ( ref.data<std::string>() == "" )
+      {
+        // Oracle: do not compare to '', use IS NULL and IS NOT NULL instead
+        // [Oracle non-Boolean logic: "S=''" is NULL, neither true nor false]
+        // => S EQ '' uses "S IS NULL" 
+        // => S NE '' uses "S IS NOT NULL" 
+        if ( m_technology == "Oracle" || m_technology == "Frontier" )
+        {
+          // Add WHERE clause
+          if ( m_tableName != "" ) whereClause += m_tableName;
+          whereClause += ref.specification().name();
+          whereClause += " ";
+          if ( rel == FieldSelection::EQ )
+          {
+            whereClause += 
+              FieldSelection::describe( FieldSelection::IS_NULL );
+          }
+          else
+          {
+            whereClause += 
+              FieldSelection::describe( FieldSelection::IS_NOT_NULL );
+          }
+        }
+        // Other backends: compare to '' and also to NULL
+        // => S EQ '' uses "S IS NULL OR S=''" 
+        // => S NE '' uses "S IS NOT NULL AND S!=''" 
+        else
+        {
+          // Add WHERE clause
+          if ( m_tableName != "" ) whereClause += m_tableName;
+          whereClause += ref.specification().name();
+          whereClause += " ";
+          if ( rel == FieldSelection::EQ )
+          {
+            whereClause += 
+              FieldSelection::describe( FieldSelection::IS_NULL );
+            whereClause += " OR ";
+          }
+          else
+          {
+            whereClause += 
+              FieldSelection::describe( FieldSelection::IS_NOT_NULL );
+            whereClause += " AND ";
+          }
+          if ( m_tableName != "" ) whereClause += m_tableName;
+          whereClause += ref.specification().name();
+          whereClause += " ";
+          whereClause += FieldSelection::describe( rel );
+          whereClause += " ''"; // No bind variables (more readable SQL)
+        }
+      }
+      // Comparison to non-empty string 'XXX'
+      else
+      {
+        // Same for Oracle and others
+        // => S EQ 'XXX' uses "S IS NOT NULL AND S='XXX'" 
+        // => S NE 'XXX' uses "S IS NULL OR S!='XXX'" 
+        {
+          // Get the next available bind variable name
+          unsigned ibv = whereData.size() + 1;
+          std::string bvName = bindVariableName( ibv );
+          // Add the WHERE clause
+          if ( m_tableName != "" ) whereClause += m_tableName;
+          whereClause += ref.specification().name();
+          whereClause += " ";
+          if ( rel == FieldSelection::EQ )
+          {
+            whereClause += 
+              FieldSelection::describe( FieldSelection::IS_NOT_NULL );
+            whereClause += " AND ";
+          }
+          else
+          {
+            whereClause += 
+              FieldSelection::describe( FieldSelection::IS_NULL );
+            whereClause += " OR ";
+          }
+          if ( m_tableName != "" ) whereClause += m_tableName;
+          whereClause += ref.specification().name();
+          whereClause += " ";
+          whereClause += FieldSelection::describe( rel );
+          whereClause += " :" + bvName;
+          // Add the WHERE data
+          RecordSpecification rspec;
+          rspec.extend( bvName, ref.specification().storageType() );
+          Record rec( rspec );    
+          rec[0].setValue( ref );
+          whereData.extend( rec );
+        }
+      }
+    }
+    // All types other than strings
+    else
+    {
+      // Get the next available bind variable name
+      unsigned ibv = whereData.size() + 1;
+      std::string bvName = bindVariableName( ibv );
+      // Add the WHERE clause
+      if ( m_tableName != "" ) whereClause += m_tableName;
+      whereClause += ref.specification().name();
+      whereClause += " ";
+      whereClause += FieldSelection::describe( rel );
+      whereClause += " :" + bvName;
+      // Add the WHERE data
+      RecordSpecification rspec;
+      rspec.extend( bvName, ref.specification().storageType() );
+      Record rec( rspec );    
+      rec[0].setValue( ref );
+      whereData.extend( rec );
+    }
+  }  
+
+  // Success - selection is trusted
+  return true;  
+}
+
+//---------------------------------------------------------------------------
+
+bool
+RelationalPayloadQuery::addCompositeSelection( const CompositeSelection& sel,
+                                               std::string& whereClause,
+                                               Record& whereData ) const
+{
+  // Loop over the connected selections
+  for ( unsigned int iSel = 0; iSel < sel.size(); iSel++ )
+  {
+    if ( iSel > 0 )
+    {
+      whereClause += " ";
+      whereClause += CompositeSelection::describe( sel.connective() );
+      whereClause += " ";
+    }
+    whereClause += "( ";
+    if ( !addSelection( *(sel[iSel]), whereClause, whereData ) ) return false;
+    whereClause += " )";
+  }
+
+  // Success - selection is trusted
+  return true;    
+}
+
+//---------------------------------------------------------------------------
+
diff --git a/RelationalCool/src/RelationalPayloadQuery.h b/RelationalCool/src/RelationalPayloadQuery.h
new file mode 100644
index 000000000..0a5ad23ef
--- /dev/null
+++ b/RelationalCool/src/RelationalPayloadQuery.h
@@ -0,0 +1,129 @@
+// $Id: RelationalPayloadQuery.h,v 1.9 2008-11-04 11:52:11 avalassi Exp $
+#ifndef RELATIONALCOOL_RELATIONALPAYLOADQUERY_H
+#define RELATIONALCOOL_RELATIONALPAYLOADQUERY_H
+
+// Include files
+//#include <memory>
+#include "CoolKernel/CompositeSelection.h"
+#include "CoolKernel/FieldSelection.h"
+#include "CoolKernel/IRecordSelection.h"
+#include "CoolKernel/Record.h"
+
+namespace cool {  
+  
+  /** @class RelationalPayloadQuery RelationalPayloadQuery.h
+   *
+   *  @author Andrea Valassi, Martin Wache
+   *  @date   2008-07-29 
+   */
+  
+  // AV Inheritance is probably not needed here?
+  class RelationalPayloadQuery //: virtual public IRecordSelection 
+  {
+    
+  public:
+
+    /// Destructor
+    virtual ~RelationalPayloadQuery();
+
+    /// Constructor from an IRecordSelection.
+    /// Parameter tableName should already contain the trailing '.' so that it
+    /// can be prepended directly to column names (e.g. 'table.' + 'column').
+    RelationalPayloadQuery( const IRecordSelection& selection,
+                            const std::string& tableName = "",
+                            const std::string& technology = "" );
+    
+    /*
+    /// Can the selection be applied to a record with the given specification?
+    bool canSelect( const IRecordSpecification& spec ) const
+    {
+      return m_selection->canSelect( spec );
+    }    
+    
+    /// Apply the selection to the given record.
+    bool select( const IRecord& record ) const
+    {
+      return m_selection->canSelect( spec );
+    }    
+    
+    /// Clone the record selection (and any objects referenced therein).
+    IRecordSelection* clone() const;
+    */
+
+    /// Is this payload query trusted?
+    bool isTrusted() const
+    {
+      return m_isTrusted;
+    }
+
+    /// Return the WHERE clause.
+    /// Throw an exception if this payload query is not trusted.
+    const std::string& whereClause() const;
+
+    /// Return the WHERE data (bind variables).
+    /// Throw an exception if this payload query is not trusted.
+    const IRecord& whereData() const;
+
+  private:
+    
+    /// Copy constructor is private
+    RelationalPayloadQuery( const RelationalPayloadQuery& rhs ); 
+
+    /// Assignment operator is private
+    RelationalPayloadQuery& operator=( const RelationalPayloadQuery& rhs ); 
+   
+    /// Bind variable name for the i-th bind variable (i>0)
+    const std::string bindVariableName( unsigned ibv ) const;
+    
+    /// Add WHERE clause and WHERE data for a generic IRecordSelection.
+    /// The return value (true on success, false on failure)
+    /// indicates whether the input record selection can be trusted.
+    /// Keep track of how many variables have been used already.
+    bool addSelection( const IRecordSelection& sel,
+                             std::string& whereClause,
+                             Record& whereData ) const;
+
+    /// Add WHERE clause and WHERE data for a FieldSelection.
+    /// The return value (true on success, false on failure)
+    /// indicates whether the input record selection can be trusted.
+    /// Keep track of how many variables have been used already.
+    bool addFieldSelection( const FieldSelection& sel,
+                                  std::string& whereClause,
+                                  Record& whereData ) const;
+
+    /// Add WHERE clause and WHERE data for a CompositeSelection.
+    /// The return value (true on success, false on failure)
+    /// indicates whether the input record selection can be trusted.
+    /// Keep track of how many variables have been used already.
+    bool addCompositeSelection( const CompositeSelection& sel,
+                                      std::string& whereClause,
+                                      Record& whereData ) const;
+
+  private:
+
+    /*
+    // AV The clone is probably not needed here with no inheritance?
+    /// Private clone of the user-supplied record selection
+    std::auto_ptr<IRecordSelection> m_selection;
+    */
+
+    /// Table name
+    const std::string m_tableName;
+    
+    /// Technology
+    const std::string m_technology;
+    
+    /// Is this payload query truested?
+    bool m_isTrusted;
+
+    /// The WHERE clause (SQL fragment)
+    std::string m_whereClause;
+
+    /// The WHERE data (bind variables)
+    Record m_whereData;
+    
+  };
+  
+}
+
+#endif // RELATIONALCOOL_RELATIONALPAYLOADQUERY_H
diff --git a/RelationalCool/src/RelationalQueryDefinition.cpp b/RelationalCool/src/RelationalQueryDefinition.cpp
new file mode 100644
index 000000000..9aab9ffee
--- /dev/null
+++ b/RelationalCool/src/RelationalQueryDefinition.cpp
@@ -0,0 +1,445 @@
+// $Id: RelationalQueryDefinition.cpp,v 1.8 2008-11-04 11:52:11 avalassi Exp $
+
+// Local include files
+#include "RelationalException.h"
+#include "RelationalQueryDefinition.h"
+
+//---------------------------------------------------------------------------
+
+namespace cool 
+{
+  namespace RelationalQueryDefinitionImpl 
+  {
+    class SelectItem : public IRelationalQueryDefinition::ISelectItem
+    {
+      
+    public:
+      
+      virtual ~SelectItem() 
+      {
+        if ( m_subquery ) delete m_subquery;
+      }
+      
+      SelectItem( const std::string& expression,
+                  const std::string& alias = "" ) 
+        : m_expression( expression )
+        , m_subquery( 0 )
+        , m_alias( alias ) 
+      {
+      }
+      
+      SelectItem( const IRelationalQueryDefinition& subquery,
+                  const std::string& alias ) 
+        : m_expression( "" )
+        , m_subquery( subquery.clone() )
+        , m_alias( alias ) 
+      {
+        if ( m_alias == "" ) 
+          throw RelationalException( "Subquery with no alias", "SelectItem" );
+      }
+      
+      bool isSubquery() const 
+      { 
+        return NULL != m_subquery;
+      }
+      
+      const std::string& expression() const
+      { 
+        if ( m_subquery ) 
+          throw RelationalException( "This is a subquery", "SelectItem" );
+        return m_expression;
+      }
+      
+      const IRelationalQueryDefinition& subquery() const
+      { 
+        if ( ! m_subquery ) 
+          throw RelationalException( "This is not a subquery", "SelectItem" );
+        return *m_subquery;
+      }
+      
+      const std::string& alias() const
+      {
+        return m_alias;
+      }    
+      
+      const ISelectItem* clone() const
+      {
+        if ( m_subquery ) return new SelectItem( *m_subquery, m_alias );
+        else return new SelectItem( m_expression, m_alias );
+      }      
+      
+    private:
+      
+      const std::string m_expression;
+      const IRelationalQueryDefinition* m_subquery;
+      const std::string m_alias;
+      
+    };    
+  }
+}
+
+//---------------------------------------------------------------------------
+
+namespace cool 
+{
+  namespace RelationalQueryDefinitionImpl 
+  {
+    class FromItem : public IRelationalQueryDefinition::IFromItem
+    {
+      
+    public:
+      
+      virtual ~FromItem() 
+      {
+        if ( m_subquery ) delete m_subquery;
+      }
+      
+      FromItem( const std::string& expression,
+                const std::string& alias = "" ) 
+        : m_expression( expression )
+        , m_subquery( 0 )
+        , m_alias( alias ) 
+      {
+      }
+      
+      FromItem( const IRelationalQueryDefinition& subquery,
+                const std::string& alias ) 
+        : m_expression( "" )
+        , m_subquery( subquery.clone() )
+        , m_alias( alias ) 
+      {
+        if ( m_alias == "" ) 
+          throw RelationalException( "Subquery with no alias", "FromItem" );
+      }
+      
+      bool isSubquery() const 
+      { 
+        return NULL != m_subquery;
+      }
+      
+      const std::string& expression() const
+      { 
+        if ( m_subquery ) 
+          throw RelationalException( "This is a subquery", "FromItem" );
+        return m_expression;
+      }
+      
+      const IRelationalQueryDefinition& subquery() const
+      { 
+        if ( ! m_subquery ) 
+          throw RelationalException( "This is not a subquery", "FromItem" );
+        return *m_subquery;
+      }
+      
+      const std::string& alias() const
+      {
+        return m_alias;
+      }    
+      
+      const IFromItem* clone() const
+      {
+        if ( m_subquery ) return new FromItem( *m_subquery, m_alias );
+        else return new FromItem( m_expression, m_alias );
+      }      
+      
+    private:
+      
+      const std::string m_expression;
+      const IRelationalQueryDefinition* m_subquery;
+      const std::string m_alias;
+      
+    };    
+  }
+}
+
+//---------------------------------------------------------------------------
+
+namespace cool 
+{
+  namespace RelationalQueryDefinitionImpl 
+  {
+    class GroupItem : public IRelationalQueryDefinition::IGroupItem
+    {
+      
+    public:
+      
+      virtual ~GroupItem() 
+      {
+      }
+      
+      GroupItem( const std::string& expression )
+        : m_expression( expression )
+      {
+      }
+      
+      const std::string& expression() const
+      { 
+        return m_expression;
+      }
+      
+      const IGroupItem* clone() const
+      {
+        return new GroupItem( m_expression );
+      }      
+      
+    private:
+      
+      const std::string m_expression;
+      
+    };    
+  }
+}
+
+//---------------------------------------------------------------------------
+
+namespace cool 
+{
+  namespace RelationalQueryDefinitionImpl 
+  {
+    class OrderItem : public IRelationalQueryDefinition::IOrderItem
+    {
+      
+    public:
+      
+      virtual ~OrderItem() 
+      {
+      }
+      
+      OrderItem( const std::string& expression )
+        : m_expression( expression )
+      {
+      }
+      
+      const std::string& expression() const
+      { 
+        return m_expression;
+      }
+      
+      const IOrderItem* clone() const
+      {
+        return new OrderItem( m_expression );
+      }      
+      
+    private:
+      
+      const std::string m_expression;
+      
+    };    
+  }
+}
+
+//---------------------------------------------------------------------------
+
+// Namespaces
+using namespace cool;
+using namespace RelationalQueryDefinitionImpl;
+
+//---------------------------------------------------------------------------
+
+RelationalQueryDefinition::RelationalQueryDefinition() {}
+
+//---------------------------------------------------------------------------
+
+RelationalQueryDefinition::~RelationalQueryDefinition() 
+{
+  for ( std::vector<const ISelectItem* >::const_iterator 
+          it = m_selectList.begin(); it != m_selectList.end(); it++ ) 
+    delete *it;
+  
+  for ( std::vector<const IFromItem* >::const_iterator 
+          it = m_fromClause.begin(); it != m_fromClause.end(); it++ ) 
+    delete *it;
+
+  for ( std::vector<const IGroupItem* >::const_iterator 
+          it = m_groupClause.begin(); it != m_groupClause.end(); it++ ) 
+    delete *it;
+
+  for ( std::vector<const IOrderItem* >::const_iterator 
+          it = m_orderClause.begin(); it != m_orderClause.end(); it++ ) 
+    delete *it;
+}
+  
+//---------------------------------------------------------------------------
+
+const IRelationalQueryDefinition* RelationalQueryDefinition::clone() const
+{
+  RelationalQueryDefinition* query = new RelationalQueryDefinition();
+
+  query->setHint( m_hint );
+
+  for ( std::vector<const ISelectItem* >::const_iterator 
+          it = m_selectList.begin(); it != m_selectList.end(); it++ ) 
+    query->addSelectItem( **it );
+
+  for ( std::vector<const IFromItem* >::const_iterator 
+          it = m_fromClause.begin(); it != m_fromClause.end(); it++ ) 
+    query->addFromItem( **it );
+
+  query->setWhereClause( m_whereClause );
+
+  for ( std::vector<const IGroupItem* >::const_iterator 
+          it = m_groupClause.begin(); it != m_groupClause.end(); it++ ) 
+    query->addGroupItem( **it );
+
+  for ( std::vector<const IOrderItem* >::const_iterator 
+          it = m_orderClause.begin(); it != m_orderClause.end(); it++ ) 
+    query->addOrderItem( **it );
+
+  query->setBindVariables( m_bindVariables );
+
+  query->setResultSetSpecification( m_resultSetSpecification );
+  
+  return query;
+}
+
+//---------------------------------------------------------------------------
+
+std::ostream& RelationalQueryDefinition::print( std::ostream& s ) const
+{
+  s << "RelationalQueryDefinition: ";
+  
+  s << "SELECT ";
+
+  if ( m_hint != "" ) s << m_hint << " ";
+  else s << "/*+ [None] */ ";
+
+  if ( m_selectList.size() > 0 ) 
+  {
+    for ( std::vector<const ISelectItem* >::const_iterator 
+            it = m_selectList.begin(); it != m_selectList.end(); it++ ) 
+    {
+      if ( it != m_selectList.begin() ) s << ", ";
+      s << (*it)->expression();
+      if ( (*it)->alias() != "" ) s << " AS " << (*it)->alias();
+    }
+  }  
+  else s << "[None]";
+
+  s << " FROM ";
+  if ( m_fromClause.size() > 0 ) 
+  {
+    for ( std::vector<const IFromItem* >::const_iterator 
+            it = m_fromClause.begin(); it != m_fromClause.end(); it++ ) 
+    {
+      if ( it != m_fromClause.begin() ) s << ", ";
+      if ( (*it)->isSubquery() ) s << "( " << (*it)->subquery() << " )";
+      else s << (*it)->expression();
+      if ( (*it)->alias() != "" ) s << " AS " << (*it)->alias();
+    }
+  }  
+  else s << "[None]";
+
+  s << " WHERE ";  
+  if ( m_whereClause != "" ) s << m_whereClause;
+  else s << "[None]";
+
+  s << " GROUP BY ";  
+  if ( m_groupClause.size() > 0 ) 
+  {
+    for ( std::vector<const IGroupItem* >::const_iterator 
+            it = m_groupClause.begin(); it != m_groupClause.end(); it++ )
+    {
+      if ( it != m_groupClause.begin() ) s << ", ";
+      s << (*it)->expression();
+    }
+  }  
+  else s << "[None]";
+  
+  s << " ORDER BY ";  
+  if ( m_orderClause.size() > 0 ) 
+  {
+    for ( std::vector<const IOrderItem* >::const_iterator 
+            it = m_orderClause.begin(); it != m_orderClause.end(); it++ ) 
+    {
+      if ( it != m_orderClause.begin() ) s << ", ";
+      s << (*it)->expression();
+    }
+  }  
+  else s << "[None]";
+
+  s << "; BIND VARIABLES: ";
+  if ( m_bindVariables.size() > 0 ) 
+  {
+    s << m_bindVariables;  
+  }  
+  else s << "[None]";
+
+  s << "; RESULT SET SPECIFICATION: ";
+  if ( m_resultSetSpecification.size() > 0 ) 
+  {
+    for ( UInt32 i = 0; i < m_resultSetSpecification.size(); ++i ) 
+    {
+      if ( i > 0 ) s << ", ";
+      s << m_resultSetSpecification[i].name();
+    }
+  }  
+  else s << "[None]";
+
+  return s;
+}
+
+//---------------------------------------------------------------------------
+
+void 
+RelationalQueryDefinition::addSelectItem( const std::string& expression,
+                                          const std::string& alias )
+{
+  m_selectList.push_back( new SelectItem( expression, alias ) );
+}
+
+//---------------------------------------------------------------------------
+
+void 
+RelationalQueryDefinition::addSelectItems( const IRecordSpecification& items,
+                                           const std::string& prefix )
+{
+  for ( unsigned int i=0; i<items.size(); i++ ) 
+    m_selectList.push_back( new SelectItem( prefix + items[i].name() ) );
+}
+
+//---------------------------------------------------------------------------
+
+/*
+void 
+RelationalQueryDefinition::addSelectItem( const IRelationalQueryDefinition& sq,
+                                          const std::string& alias )
+{
+  m_selectList.push_back( new SelectItem( sq, alias ) );
+}
+*/
+
+//---------------------------------------------------------------------------
+
+void 
+RelationalQueryDefinition::addFromItem( const std::string& expression,
+                                        const std::string& alias )
+{
+  m_fromClause.push_back( new FromItem( expression, alias ) );
+}
+
+//---------------------------------------------------------------------------
+
+void 
+RelationalQueryDefinition::addFromItem( const IRelationalQueryDefinition& sq,
+                                        const std::string& alias )
+{
+  m_fromClause.push_back( new FromItem( sq, alias ) );
+}
+
+//---------------------------------------------------------------------------
+
+void 
+RelationalQueryDefinition::addGroupItem( const std::string& expression )
+{
+  m_groupClause.push_back( new GroupItem( expression ) );
+}
+
+//---------------------------------------------------------------------------
+
+void 
+RelationalQueryDefinition::addOrderItem( const std::string& expression )
+{
+  m_orderClause.push_back( new OrderItem( expression ) );
+}
+
+//---------------------------------------------------------------------------
diff --git a/RelationalCool/src/RelationalQueryDefinition.h b/RelationalCool/src/RelationalQueryDefinition.h
new file mode 100644
index 000000000..3aa75e3e1
--- /dev/null
+++ b/RelationalCool/src/RelationalQueryDefinition.h
@@ -0,0 +1,226 @@
+// $Id: RelationalQueryDefinition.h,v 1.7 2008-11-04 11:52:11 avalassi Exp $
+#ifndef RELATIONALCOOL_RELATIONALQUERYDEFINITION_H
+#define RELATIONALCOOL_RELATIONALQUERYDEFINITION_H
+
+// Include files
+#include "CoolKernel/Record.h"
+
+// Local include files
+#include "IRelationalQueryDefinition.h"
+
+namespace cool {
+
+  /** @class RelationalQueryDefinition RelationalQueryDefinition.h
+   *
+   *  Relational query definition.
+   *
+   *  @author Andrea Valassi
+   *  @date   2007-06-19
+   */
+
+  class RelationalQueryDefinition : public IRelationalQueryDefinition {
+
+  public:
+
+    /// Constructor.
+    RelationalQueryDefinition();
+
+    /// Destructor.
+    virtual ~RelationalQueryDefinition();
+
+    /// Clone this query definition.
+    const IRelationalQueryDefinition* clone() const;
+
+    /// Get the hint in the format "/*+ hints */"
+    /// ("SELECT /*+ hints */ expr1 alias1, expr2 alias2, ...").
+    const std::string& getHint() const
+    {
+      return m_hint;
+    }
+    
+    /// Get the SELECT list size
+    /// ("SELECT expr1 alias1, expr2 alias2, ...").
+    unsigned getSelectSize() const 
+    {
+      return m_selectList.size();
+    }    
+  
+    /// Get a SELECT list item 
+    /// ("SELECT expr1 alias1, expr2 alias2, ...").
+    const ISelectItem& getSelectItem( unsigned item ) const
+    {
+      return *(m_selectList[item]);
+    }
+  
+    /// Get the FROM clause size
+    /// ("FROM table1 alias1, table2 alias2, ...").
+    unsigned getFromSize() const
+    {
+      return m_fromClause.size();
+    }    
+  
+    /// Get a FROM clause item
+    /// ("FROM table1 alias1, table2 alias2, ...").
+    const IFromItem& getFromItem( unsigned item ) const
+    {
+      return *(m_fromClause[item]);
+    }
+  
+    /// Get the WHERE clause ("WHERE ...").
+    const std::string& getWhereClause() const
+    {
+      return m_whereClause;
+    }
+    
+    /// Get the GROUP BY clause size
+    /// ("GROUP BY expr1, expr2...").
+    unsigned getGroupSize() const
+    {
+      return m_groupClause.size();
+    }    
+    
+    /// Get a GROUP BY clause item
+    /// ("GROUP BY expr1, expr2...").
+    const IGroupItem& getGroupItem( unsigned item ) const
+    {
+      return *(m_groupClause[item]);
+    }
+    
+    /// Get the ORDER BY clause size
+    /// ("ORDER BY expr1, expr2...").
+    unsigned getOrderSize() const
+    {
+      return m_orderClause.size();
+    }    
+
+    /// Get an ORDER BY clause item
+    /// ("ORDER BY expr1, expr2...").
+    const IOrderItem& getOrderItem( unsigned item ) const
+    {
+      return *(m_orderClause[item]);
+    }
+
+    /// Get the bind variables.
+    /// Bind variables are not necessary here if this is a subquery definition.
+    const IRecord& getBindVariables() const
+    {
+      return m_bindVariables;
+    }    
+
+    /// Get the result set specification.
+    /// The result set spec is ignored if this is a subquery definition.
+    const IRecordSpecification& getResultSetSpecification() const
+    {
+      return m_resultSetSpecification;
+    }    
+
+    /// Print the relational query definition to an output stream.
+    std::ostream& print( std::ostream& s ) const;
+
+    /// Set the hint for the query: "SELECT /*+ hints */".
+    /// The input argument should already be in the form "/*+ hints */".
+    void setHint( const std::string& hint )
+    {
+      m_hint = hint;
+    }    
+  
+    /// Appends an expression to the select list: "SELECT expression alias".
+    void addSelectItem( const std::string& expression,
+                        const std::string& alias = "" );
+  
+    /// Appends a subquery to the select list: "SELECT (subquery) alias".
+    /// This may contain bind variables whose values will be defined later.
+    /// A deep copy of the subquery definition is performed.
+    //void addSelectItem( const IRelationalQueryDefinition& subquery,
+    //                    const std::string& alias = "" );
+  
+    /// Appends many fields to the select list: "SELECT [prefix]x1...".
+    void addSelectItems( const IRecordSpecification& items,
+                         const std::string& prefix = "" );
+  
+    /// Appends an item to the SELECT list.
+    /// This may contain bind variables whose values will be defined later.
+    /// A deep copy of the SELECT list item is performed.
+    void addSelectItem( const ISelectItem& item ) 
+    {
+      m_selectList.push_back( item.clone() );
+    }
+  
+    /// Appends a table to the FROM clause: "FROM table alias".
+    void addFromItem( const std::string& expression,
+                      const std::string& alias = "" );
+    
+    /// Appends a subquery to the FROM clause: "FROM (subquery) alias".
+    /// This may contain bind variables whose values will be defined later.
+    /// A deep copy of the subquery definition is performed.
+    void addFromItem( const IRelationalQueryDefinition& subquery,
+                      const std::string& alias = "" );
+
+    /// Appends an item to the FROM clause.
+    /// This may contain bind variables whose values will be defined later.
+    /// A deep copy of the FROM clause item is performed.
+    void addFromItem( const IFromItem& item ) 
+    {
+      m_fromClause.push_back( item.clone() );
+    }
+  
+    /// Defines the WHERE clause for the query.
+    /// This may contain bind variables whose values will be defined later.
+    void setWhereClause( const std::string& condition )
+    {
+      m_whereClause = condition;
+    }    
+    
+    /// Appends an item to the GROUP BY clause.
+    void addGroupItem( const std::string& expression );
+
+    /// Appends an item to the GROUP BY clause.
+    /// A deep copy of the GROUP BY clause item is performed.
+    void addGroupItem( const IGroupItem& item ) 
+    {
+      m_groupClause.push_back( item.clone() );
+    }
+  
+    /// Appends an item to the ORDER BY clause.
+    void addOrderItem( const std::string& expression );
+
+    /// Appends an item to the ORDER BY clause.
+    /// A deep copy of the ORDER BY clause item is performed.
+    void addOrderItem( const IOrderItem& item ) 
+    {
+      m_orderClause.push_back( item.clone() );
+    }
+
+    /// Defines the bind variables.
+    void setBindVariables( const IRecord& bindVariables )
+    {
+      m_bindVariables = bindVariables;
+    }    
+    
+    /// Defines the result set specification.
+    void setResultSetSpecification( const IRecordSpecification& spec )
+    {
+      m_resultSetSpecification = spec;
+    }    
+    
+  private:
+
+    RelationalQueryDefinition( const RelationalQueryDefinition& );
+    RelationalQueryDefinition& operator=( const RelationalQueryDefinition& );
+    
+  private:
+
+    std::string m_hint;
+    std::vector<const ISelectItem* > m_selectList;
+    std::vector<const IFromItem* > m_fromClause;
+    std::string m_whereClause;
+    std::vector<const IGroupItem*> m_groupClause;
+    std::vector<const IOrderItem*> m_orderClause;
+    Record m_bindVariables;
+    RecordSpecification m_resultSetSpecification;
+    
+  };
+
+}
+
+#endif // RELATIONALCOOL_RELATIONALQUERYDEFINITION_H
diff --git a/RelationalCool/src/RelationalQueryMgr.cpp b/RelationalCool/src/RelationalQueryMgr.cpp
new file mode 100644
index 000000000..2904e2cc9
--- /dev/null
+++ b/RelationalCool/src/RelationalQueryMgr.cpp
@@ -0,0 +1,106 @@
+// $Id: RelationalQueryMgr.cpp,v 1.27 2008-11-04 11:52:11 avalassi Exp $
+
+// Local include files
+#include "RelationalException.h"
+#include "RelationalQueryMgr.h"
+#include "RelationalTableRow.h"
+#include "timeToString.h"
+
+// Namespace
+using namespace cool;
+
+//---------------------------------------------------------------------------
+
+RelationalQueryMgr::RelationalQueryMgr(  )
+  : m_log( new coral::MessageStream( "RelationalQueryMgr" ) ) 
+{
+  log() << coral::Debug 
+        << "Instantiate a RelationalQueryMgr" << coral::MessageStream::endmsg;
+}
+
+//---------------------------------------------------------------------------
+
+RelationalQueryMgr::~RelationalQueryMgr() 
+{
+  log() << coral::Debug 
+        << "Delete the RelationalQueryMgr" << coral::MessageStream::endmsg;
+}
+ 
+//---------------------------------------------------------------------------
+
+const RelationalTableRow RelationalQueryMgr::fetchRowFromTables
+( const TableNamesWithAliases& tables,
+  const SelectListWithRSetSpec& columns,
+  const std::string& whereClause,
+  const coral::AttributeList& whereData,
+  const std::string& description,
+  bool forUpdate ) const
+{
+  UInt32 nExp = 1; // Delegate check as well as fetch
+  std::vector<RelationalTableRow> rows = fetchRowsFromTables
+    ( tables, columns, whereClause, whereData, description, nExp, forUpdate );
+  if ( rows.size() == 0 ) // PANIC! This should never happen!
+  {
+    std::stringstream tableList;
+    TableNamesWithAliases::const_iterator table;
+    for ( table = tables.begin(); 
+          table != tables.end(); 
+          table++ ) {
+      if ( tableList.str() != "" ) tableList << ", ";
+      tableList << table->first;
+    }
+    throw NoRowsFound( "PANIC! No rows selected from " + tableList.str(), 
+                       "RelationalQueryMgr" );
+  }
+  return rows[0];
+}
+
+//---------------------------------------------------------------------------
+
+const std::vector<RelationalTableRow> RelationalQueryMgr::fetchRowsFromTables
+( const TableNamesWithAliases& tables,
+  const SelectListWithRSetSpec& columns,
+  const std::string& whereClause,
+  const coral::AttributeList& whereData,
+  const std::string& description,
+  UInt32 nExp,
+  bool forUpdate ) const
+{
+  std::vector<std::string> orderBy; // Empty orderBy clause
+  return fetchOrderedRowsFromTables
+    ( tables, columns, 
+      whereClause, whereData, orderBy, description, nExp, forUpdate );
+}
+
+//---------------------------------------------------------------------------
+
+const std::string 
+RelationalQueryMgr::serverTimeClause( const std::string& technology )
+{
+  std::string clause;
+  if ( technology == "MySQL" ) {
+    // TEMPORARY! Store MySQL now() __ AS IS __ ASSUMING IT IS GMT!
+    // MySQL does not handle timezones until 4.1.3
+    clause = "DATE_FORMAT(now(),'%Y-%m-%d_%H:%i:%s.000000000 GMT')";
+  }
+  else if ( technology == "Oracle" || technology == "frontier" ) {
+    // Store Oracle SYSTIMESTAMP converted to GMT
+    clause = "TO_CHAR(SYSTIMESTAMP AT TIME ZONE 'GMT',";
+    clause += "'yyyy-mm-dd_hh24:mi:ss.ff6')||'000 GMT'";
+  }
+  else if ( technology == "SQLite" ) {
+    // Use GMT time from C++ client with SQLite (there is no server)
+    // TEMPORARY! Use seal::Time (CURRENT_TIMESTAMP only in SQLite 3.1.0)
+    // TODO: Use SQLite's CURRENT_TIMESTAMP.
+    clause = "'";
+    clause += timeToString( cool::Time() );
+    clause += "'";
+  }
+  else {
+    throw RelationalException
+      ( std::string( "Unknown technology " ) + technology, "RalQueryMgr" );
+  }
+  return clause;
+}
+
+//---------------------------------------------------------------------------
diff --git a/RelationalCool/src/RelationalQueryMgr.h b/RelationalCool/src/RelationalQueryMgr.h
new file mode 100644
index 000000000..da2b3f126
--- /dev/null
+++ b/RelationalCool/src/RelationalQueryMgr.h
@@ -0,0 +1,314 @@
+// $Id: RelationalQueryMgr.h,v 1.64 2008-11-04 11:52:11 avalassi Exp $
+#ifndef RELATIONALCOOL_RELATIONALQUERYMGR_H
+#define RELATIONALCOOL_RELATIONALQUERYMGR_H
+
+// Include files
+#include <memory>
+#include <string>
+#include <boost/shared_ptr.hpp>
+#include "CoolKernel/types.h"
+#include "CoolKernel/RecordSpecification.h"
+#include "CoralBase/AttributeList.h"
+#include "CoralBase/AttributeSpecification.h"
+#include "CoralBase/MessageStream.h"
+
+namespace cool {  
+  
+  // Forward declarations
+  class IRelationalBulkOperation;
+  class IRelationalCursor;
+  class IRelationalQueryDefinition;
+  class RelationalSequenceMgr;
+  class RelationalTableRow;
+
+  // TEMPORARY...
+  inline const std::type_info& 
+  typeIdToCoralType( const StorageType::TypeId type_id )
+  {
+    return StorageType::storageType( type_id ).cppType();
+  }
+
+  /** @class RelationalQueryMgr RelationalQueryMgr.h
+   *  -----------------------------------------------------------------------
+   *  RelationalQueryMgr: abstract base class for a manager 
+   *  of relational queries (SELECT statements).
+   * 
+   *  Only three methods are pure virtual and implemented in a derived class:
+   *  a check for the existence of a table in the schema,
+   *  a generic query for many ordered rows from many aliased tables,
+   *  and a generic COUNT(*) query from many aliased tables.
+   *
+   *  Some simpler queries are implemented within this class in terms
+   *  of the two more generic pure abstract methods described above.
+   * 
+   *  Transactions are NOT handled by this class.
+   *  -----------------------------------------------------------------------
+   *  RelationalUpdateMgr: abstract base class for a manager 
+   *  of relational DML operations (INSERT/UPDATE/DELETE statements).
+   * 
+   *  Transactions are NOT handled by this class.
+   * 
+   *  TEMPORARY? These functionalities are presently in RelationalQueryMgr.
+   *  -----------------------------------------------------------------------
+   *  RelationalSequenceMgr: return a reference to the abstract interface 
+   *  for a manager of COOL relational 'sequences'.
+   * 
+   *  Transactions are NOT handled by this class.
+   * 
+   *  TEMPORARY? These functionalities are presently in RelationalQueryMgr.
+   *  -----------------------------------------------------------------------
+   *  @author Andrea Valassi, Sven A. Schmidt and Marco Clemencic
+   *  @date   2005-10-11 
+  */
+  
+  class RelationalQueryMgr 
+  {
+    
+  public:
+
+    typedef std::pair< std::string, std::string > TableNameWithAlias;
+    typedef std::vector< TableNameWithAlias > TableNamesWithAliases;
+
+    /// Build a list of table names and aliases
+    /// from a single table name and alias.
+    inline static const TableNamesWithAliases tableList
+    ( const TableNameWithAlias& table )
+    {
+      TableNamesWithAliases tables;
+      tables.push_back( table );
+      return tables;      
+    }
+    
+    /// Build a list of table names and aliases
+    /// from a single table name (with or without alias).
+    inline static const TableNamesWithAliases tableList
+    ( const std::string& tableName,
+      const std::string& tableAlias = "" )
+    {
+      TableNameWithAlias table( tableName, tableAlias );
+      return tableList( table );
+    }
+
+    /// Build a list of table names and aliases
+    /// from a list of table names without alias.
+    inline static const TableNamesWithAliases tableList
+    ( const std::vector<std::string>& tableNames )
+    {
+      TableNamesWithAliases tables;
+      std::vector<std::string>::const_iterator tableName;
+      for ( tableName = tableNames.begin();
+            tableName != tableNames.end();
+            tableName++ ) {
+        TableNameWithAlias table( *tableName, "" );
+        tables.push_back( table );
+      }
+      return tables;
+    }
+    
+  public:
+
+    typedef std::vector< std::string > SelectList;
+    typedef RecordSpecification RSetSpec;
+    typedef std::pair< SelectList, RSetSpec > SelectListWithRSetSpec;
+
+    /// Build a select list and result set specification 
+    /// from a result set specification and an optional common prefix
+    /// (i.e. from a coral::AttributeListSpecification and an optional string).
+    /// The input result set specification is used unchanged.
+    /// The names of the selected fields are built by prepending the prefix.
+    inline static const SelectListWithRSetSpec columnList
+    ( const IRecordSpecification& recSpec,
+      const std::string& prefix = "" )
+    {
+      SelectList selectList;
+      RSetSpec rsetSpec;
+      for ( unsigned int i=0; i<recSpec.size(); i++ ) {
+        const IFieldSpecification& fldSpec = recSpec[i];        
+        selectList.push_back( prefix + fldSpec.name() );
+        rsetSpec.extend( fldSpec );
+      }
+      SelectListWithRSetSpec columns( selectList, rsetSpec );
+      return columns;
+    }
+
+  public:
+
+    /// Destructor
+    virtual ~RelationalQueryMgr();
+
+    /// Clone this query manager.
+    /// PURE VIRTUAL method implemented in subclasses.
+    virtual RelationalQueryMgr* clone() const = 0;
+
+    /// Checks if a table exists in the schema.
+    /// PURE VIRTUAL method implemented in subclasses.
+    virtual bool existsTable( const std::string& tableName ) const = 0;
+
+    /// Fetch a single row from one or more tables.
+    /// Throws NoRowsFound if no rows are found.
+    /// Throws TooManyRowsFound if more than one rows are found.
+    const RelationalTableRow fetchRowFromTables
+    ( const TableNamesWithAliases& tables,
+      const SelectListWithRSetSpec& columns,
+      const std::string& whereClause,
+      const coral::AttributeList& whereData,
+      const std::string& description = "",
+      bool forUpdate = false ) const;
+
+    /// Fetch a set of rows from one or more tables as a vector.
+    /// If nExp>0, throws TooManyRowsFound if more than nExp rows are found.
+    /// If nExp>0, throws an exception if fewer than nExp rows are found.
+    const std::vector<RelationalTableRow> fetchRowsFromTables
+    ( const TableNamesWithAliases& tables,
+      const SelectListWithRSetSpec& columns,
+      const std::string& whereClause,
+      const coral::AttributeList& whereData,
+      const std::string& description = "",
+      UInt32 nExp = 0,
+      bool forUpdate = false ) const;
+
+    /// Fetch an ordered set of rows from one or more tables as a vector.
+    /// If nExp>0, throws TooManyRowsFound if more than nExp rows are found.
+    /// If nExp>0, throws an exception if fewer than nExp rows are found.
+    /// PURE VIRTUAL method implemented in subclasses.
+    virtual const std::vector<RelationalTableRow> fetchOrderedRowsFromTables
+    ( const TableNamesWithAliases& tables,
+      const SelectListWithRSetSpec& columns,
+      const std::string& whereClause,
+      const coral::AttributeList& whereData,
+      const std::vector<std::string>& orderBy,
+      const std::string& description = "",
+      UInt32 nExp = 0,
+      bool forUpdate = false ) const = 0;
+
+    /// Fetch a "select COUNT(*)" row count from one or more tables.
+    /// PURE VIRTUAL method implemented in subclasses.
+    virtual UInt32 countRowsFromTables
+    ( const TableNamesWithAliases& tables,
+      const std::string& whereClause,
+      const coral::AttributeList& whereData,
+      const std::string& description = "" ) const = 0;
+
+    /// -- NEW -- start
+    /// Prepare and execute a CORAL query 
+    /// (and start/stop the relevant timing report).
+    /// The caller becomes the owenr of the returned cursor.
+    /// PURE VIRTUAL method implemented in subclasses.
+    virtual IRelationalCursor* prepareAndExecuteQuery
+    ( const IRelationalQueryDefinition& coolDef,
+      boost::shared_ptr<coral::AttributeList>& dataBuffer ) const = 0;
+    /// Fetch an ordered set of rows from one or more tables as a vector.
+    /// If nExp>0, throws TooManyRowsFound if more than nExp rows are found.
+    /// If nExp>0, throws an exception if fewer than nExp rows are found.
+    /// PURE VIRTUAL method implemented in subclasses.
+    virtual const std::vector<RelationalTableRow> fetchOrderedRows
+    ( const IRelationalQueryDefinition& coolDef,
+      const std::string& description = "",
+      UInt32 nExp = 0,
+      bool forUpdate = false ) const = 0;
+    /// Fetch a "select COUNT(*)" row count from one or more tables.
+    /// PURE VIRTUAL method implemented in subclasses.
+    virtual UInt32 countRows
+    ( const IRelationalQueryDefinition& coolDef,
+      const std::string& description = "" ) const = 0;
+    /// -- NEW -- end    
+
+    /// Returns a new IRelationalBulkOperation object for performing a bulk 
+    /// insert operation specifying the input data buffer and the number of 
+    /// rows that should be cached on the client.
+    /// PURE VIRTUAL method implemented in subclasses.
+    virtual boost::shared_ptr<IRelationalBulkOperation> 
+    bulkInsertTableRows( const std::string& tableName,
+                         const coral::AttributeList& dataBuffer, 
+                         int rowCacheSize ) = 0;
+    
+    /// Insert one row into one table.
+    /// PURE VIRTUAL method implemented in subclasses.
+    virtual void insertTableRow
+    ( const std::string& tableName,
+      const coral::AttributeList& data ) const = 0;
+
+    /// Returns a new IRelationalBulkOperation object for performing a bulk 
+    /// update operation specifying the input data buffer and the number of 
+    /// rows that should be cached on the client.
+    /// PURE VIRTUAL method implemented in subclasses.
+    virtual boost::shared_ptr<IRelationalBulkOperation> 
+    bulkUpdateTableRows( const std::string& tableName,
+                         const std::string& setClause,
+                         const std::string& whereClause,
+                         const coral::AttributeList& dataBuffer, 
+                         int rowCacheSize ) = 0;
+    
+    /// Update rows in one table.
+    /// If nExp>0, throws an exception if more than nExp rows are updated.
+    /// If nExp>0, throws an exception if fewer than nExp rows are updated.
+    /// PURE VIRTUAL method implemented in subclasses.
+    virtual UInt32 updateTableRows
+    ( const std::string& tableName,
+      const std::string& setClause,
+      const std::string& whereClause,
+      const coral::AttributeList& updateData,
+      UInt32 nExp = 0 ) const = 0;
+
+    /// Delete rows from one table.
+    /// Throws an exception if #rows deleted is different from the expectation
+    /// (taken from nExp if > 0; queried internally if nExp = 0).
+    /// PURE VIRTUAL method implemented in subclasses.
+    virtual UInt32 deleteTableRows
+    ( const std::string& tableName,
+      const std::string& whereClause,
+      const coral::AttributeList& whereData,
+      UInt32 nExp = 0 ) const = 0;
+
+    /// Get a RelationalSequenceMgr.
+    /// PURE VIRTUAL method implemented in subclasses.
+    virtual RelationalSequenceMgr& sequenceMgr() const = 0;
+
+    /// Build the appropriate backend-specific SQL expression
+    /// to compute the server-side time in the format used by COOL.
+    /// PURE VIRTUAL method implemented in subclasses.
+    virtual const std::string serverTimeClause() const = 0;
+
+    /// Build the appropriate backend-specific SQL expression
+    /// to compute the server-side time in the format used by COOL.
+    static const std::string serverTimeClause( const std::string& technology );
+
+    /// Return the server technology for the current connection.
+    /// Supported technologies: "Oracle ", "MySQL", "SQLite", "frontier".
+    /// PURE VIRTUAL method implemented in subclasses.
+    virtual const std::string databaseTechnology() const = 0;
+
+    /// Return the schema name for the current connection.
+    /// PURE VIRTUAL method implemented in subclasses.
+    virtual const std::string schemaName() const = 0;
+
+  protected:
+    
+    /// Constructor is protected
+    RelationalQueryMgr();
+    
+    /// Get a CORAL MessageStream
+    coral::MessageStream& log() const
+    { 
+      return *m_log; 
+    }
+    
+  private:
+    
+    /// Copy constructor is private
+    RelationalQueryMgr( const RelationalQueryMgr& rhs ); 
+
+    /// Assignment operator is private
+    RelationalQueryMgr& operator=( const RelationalQueryMgr& rhs ); 
+   
+  private:
+
+    /// CORAL MessageStream
+    std::auto_ptr<coral::MessageStream> m_log;
+    
+  };
+  
+}
+
+#endif // RELATIONALCOOL_RELATIONALQUERYMGR_H
+
diff --git a/RelationalCool/src/RelationalSchemaMgr.cpp b/RelationalCool/src/RelationalSchemaMgr.cpp
new file mode 100644
index 000000000..f010cd654
--- /dev/null
+++ b/RelationalCool/src/RelationalSchemaMgr.cpp
@@ -0,0 +1,63 @@
+// $Id: RelationalSchemaMgr.cpp,v 1.9 2008-11-04 11:52:11 avalassi Exp $
+
+// Local include files
+#include "RelationalDatabase.h"
+#include "RelationalSchemaMgr.h"
+#include "uppercaseString.h"
+
+// Namespace
+using namespace cool;
+
+//-----------------------------------------------------------------------------
+
+RelationalSchemaMgr::RelationalSchemaMgr( const RelationalDatabase& aDb )
+  : m_db( aDb )
+  , m_log( new coral::MessageStream( "RelationalSchemaMgr" ) )
+{
+  log() << coral::Debug << "Instantiate a RelationalSchemaMgr" 
+        << coral::MessageStream::endmsg;
+}
+
+//-----------------------------------------------------------------------------
+
+RelationalSchemaMgr::~RelationalSchemaMgr()
+{
+  log() << coral::Debug << "Delete the RelationalSchemaMgr" 
+        << coral::MessageStream::endmsg;
+}
+
+//-----------------------------------------------------------------------------
+
+
+coral::MessageStream& RelationalSchemaMgr::log() const
+{
+  *m_log << coral::Verbose;
+  return *m_log;
+}
+
+//-----------------------------------------------------------------------------
+
+RelationalQueryMgr& RelationalSchemaMgr::queryMgr() const
+{
+  return db().queryMgr();
+}
+
+//-----------------------------------------------------------------------------
+
+bool 
+RelationalSchemaMgr::isValidColumnName( const std::string& name ) const
+{
+  static std::string allowedChar = 
+    "ABCDEFGHIJKLMNOPQRSTUVWXYZ_1234567890";
+  const std::string ucName = uppercaseString( name );    
+  if ( name.size() < 1 ||
+       name.size() > 30 ||
+       ucName.find_first_not_of( allowedChar ) != ucName.npos ||
+       ucName.find_first_not_of( "_1234567890" ) != 0 )
+    return false;
+  else
+    return true;
+}
+
+//-----------------------------------------------------------------------------
+
diff --git a/RelationalCool/src/RelationalSchemaMgr.h b/RelationalCool/src/RelationalSchemaMgr.h
new file mode 100644
index 000000000..f9964ff56
--- /dev/null
+++ b/RelationalCool/src/RelationalSchemaMgr.h
@@ -0,0 +1,208 @@
+// $Id: RelationalSchemaMgr.h,v 1.34 2008-11-04 11:52:11 avalassi Exp $
+#ifndef RELATIONALCOOL_RELATIONALSCHEMAMGR_H
+#define RELATIONALCOOL_RELATIONALSCHEMAMGR_H
+
+// Include files
+#include <memory>
+#include "CoolKernel/FolderVersioning.h"
+#include "CoralBase/AttributeList.h" // SAS 19.06.2006 needed only on Mac/gcc4?
+#include "CoralBase/MessageStream.h"
+#include "RelationalAccess/TableDescription.h"
+
+namespace cool {  
+  
+  // Forward declarations
+  class IRecordSpecification;
+  class RelationalDatabase;
+  class RelationalQueryMgr;
+
+  /** @class RelationalSchemaMgr RelationalSchemaMgr.h
+   *  
+   *  Abstract base class for the manager 
+   *  of the COOL relational database schema.
+   * 
+   *  @author Andrea Valassi and Marco Clemencic
+   *  @date   2006-03-15
+  */
+  
+  class RelationalSchemaMgr {
+    
+  public:
+
+    /// Destructor
+    virtual ~RelationalSchemaMgr();
+
+    /// Drop a table (return false if the table does not exist)
+    /// PURE VIRTUAL method implemented in subclasses.
+    virtual bool dropTable( const std::string& tableName ) const = 0;
+    
+    /// Creates the main table
+    /// PURE VIRTUAL method implemented in subclasses.
+    virtual void createMainTable( const std::string& tableName ) const = 0;
+    
+    /// Fill the main table
+    /// PURE VIRTUAL method implemented in subclasses.
+    virtual void fillMainTable( const std::string& tableName,
+                                const coral::AttributeList& dbAttr ) const = 0;
+
+    // *** START *** 3.0.0 schema extensions (task #4307)
+    /// Creates the iovTables table
+    /// PURE VIRTUAL method implemented in subclasses.
+    virtual void createIovTablesTable
+    ( const std::string& iovTablesTableName ) const = 0;
+
+    /// Creates the channelTables table
+    /// PURE VIRTUAL method implemented in subclasses.
+    virtual void createChannelTablesTable
+    ( const std::string& channelTablesTableName ) const = 0;
+    // **** END **** 3.0.0 schema extensions (task #4307)
+
+    /// Creates the node table
+    /// TEMPORARY - pass the table prefix to create the root fs tag sequence
+    /// PURE VIRTUAL method implemented in subclasses.
+    virtual 
+    void createNodeTable( const std::string& nodeTableName,
+                          const std::string& defaultTablePrefix ) const = 0;
+
+    /// Creates the global tag table
+    /// PURE VIRTUAL method implemented in subclasses.
+    virtual 
+    void createGlobalTagTable( const std::string& globalTagTableName,
+                               const std::string& nodeTableName ) const = 0;
+
+    // *** START *** 3.0.0 schema extensions (task #4396)
+    /// Creates the global head tag table
+    /// PURE VIRTUAL method implemented in subclasses.
+    virtual void createGlobalHeadTagTable
+    ( const std::string& globalHeadTagTableName,
+      const std::string& globalTagTableName ) const = 0;
+
+    /// Creates the global user tag table
+    /// PURE VIRTUAL method implemented in subclasses.
+    virtual void createGlobalUserTagTable
+    ( const std::string& globalUserTagTableName,
+      const std::string& globalTagTableName ) const = 0;
+    // **** END **** 3.0.0 schema extensions (task #4396)
+
+    /// Creates the tag2tag HVS table
+    /// PURE VIRTUAL method implemented in subclasses.
+    virtual 
+    void createTag2TagTable( const std::string& tag2tagTableName,
+                             const std::string& globalTagTableName, 
+                             const std::string& nodeTableName ) const = 0;
+
+    /// Creates the tag2tag HVS table FK references to the tag table
+    /// *** This is needed by the coolReplicateDB utility ***
+    /// PURE VIRTUAL method implemented in subclasses.
+    virtual 
+    void createTag2TagFKs( const std::string& tag2tagTableName,
+                           const std::string& globalTagTableName ) const = 0;
+    
+    /// Creates the tag2tag HVS table FK references to the tag table
+    /// *** This is needed by the coolReplicateDB utility ***
+    /// PURE VIRTUAL method implemented in subclasses.
+    virtual 
+    bool dropTag2TagFKs( const std::string& tag2tagTableName,
+                               bool verbose = true ) const = 0;
+    
+    /// Creates a shared sequence table
+    /// PURE VIRTUAL method implemented in subclasses.
+    virtual 
+    void createSharedSequence( const std::string& sharedSequenceName,
+                               const std::string& nodeTableName ) const = 0;
+    
+    /// Creates the tag sequence for a node
+    /// PURE VIRTUAL method implemented in subclasses.
+    virtual void createTagSequence( const std::string& seqName ) const = 0;
+
+    /// Creates the tag table for a leaf node
+    /// PURE VIRTUAL method implemented in subclasses.
+    virtual void createTagTable( const std::string& tableName ) const = 0;
+
+    /// Creates the channel table for a leaf node
+    /// PURE VIRTUAL method implemented in subclasses.
+    virtual void createChannelTable( const std::string& tableName ) const = 0;
+    
+    /// Creates the object2tag (iov2tag) table for a leaf node
+    /// PURE VIRTUAL method implemented in subclasses.
+    virtual void createObject2TagTable
+    ( const std::string& object2tagTableName,
+      const std::string& objectTableName,
+      const std::string& tagTableName ) const = 0;
+
+    /// Creates the object (iov) table for a leaf node
+    /// PURE VIRTUAL method implemented in subclasses.
+    virtual void createObjectTable
+    ( const std::string& objectTableName,
+      const std::string& channelTableName,
+      const IRecordSpecification& payloadSpec,
+      FolderVersioning::Mode versioningMode ) const = 0;
+
+    /// Creates the FK references from the object table to the channel table
+    /// *** This is needed by the coolReplicateDB utility ***
+    /// PURE VIRTUAL method implemented in subclasses.
+    virtual void createObjectChannelFK
+    ( const std::string& objectTableName,
+      const std::string& channelTableName ) const = 0;
+    
+    /// Drops the FK reference from the object table to the channel table
+    /// *** This is needed by the coolReplicateDB utility ***
+    /// PURE VIRTUAL method implemented in subclasses.
+    virtual void dropObjectChannelFK
+    ( const std::string& objectTableName ) const = 0;
+
+    /// Rename a column of the given table
+    /// PURE VIRTUAL method implemented in subclasses.
+    virtual void renameColumnInTable
+    ( const std::string& tableName,
+      const std::string& oldColumnName,
+      const std::string& newColumnName ) const = 0;
+    
+    /// Add columns to the given table
+    /// PURE VIRTUAL method implemented in subclasses.
+    virtual void addColumnsToTable
+    ( const std::string& tableName,
+      const IRecord& columnSpecAndValues ) const = 0;
+    
+    /// Is this a valid name for a column of a relational table?
+    virtual bool isValidColumnName( const std::string& name ) const;
+    
+  protected:
+
+    /// Constructor from a RelationalDatabase reference
+    RelationalSchemaMgr( const RelationalDatabase& db );
+
+    /// Get the RelationalDatabase reference
+    const RelationalDatabase& db() const { return m_db; }
+
+    /// Get a CORAL MessageStream
+    coral::MessageStream& log() const;
+
+    /// Get a relational query manager
+    RelationalQueryMgr& queryMgr() const;
+
+  private:
+
+    /// Standard constructor is private
+    RelationalSchemaMgr();
+
+    /// Copy constructor is private
+    RelationalSchemaMgr( const RelationalSchemaMgr& rhs );
+
+    /// Assignment operator is private
+    RelationalSchemaMgr& operator=( const RelationalSchemaMgr& rhs );
+
+  protected:
+
+    /// Reference to the RelationalDatabase
+    const RelationalDatabase& m_db;
+
+    /// CORAL MessageStream
+    std::auto_ptr<coral::MessageStream> m_log;
+
+  };
+  
+}
+
+#endif // RELATIONALCOOL_RELATIONALSCHEMAMGR_H
+
diff --git a/RelationalCool/src/RelationalSequence.cpp b/RelationalCool/src/RelationalSequence.cpp
new file mode 100644
index 000000000..45985dabb
--- /dev/null
+++ b/RelationalCool/src/RelationalSequence.cpp
@@ -0,0 +1,128 @@
+// $Id: RelationalSequence.cpp,v 1.10 2008-11-04 11:52:11 avalassi Exp $
+
+// Include files
+#include "CoralBase/Attribute.h"
+#include "CoolKernel/RecordSpecification.h"
+
+// Local include files
+#include "RelationalDatabase.h"
+#include "RelationalException.h"
+#include "RelationalQueryMgr.h"
+#include "RelationalSequence.h"
+#include "RelationalSequenceMgr.h"
+#include "RelationalSequenceTable.h"
+#include "RelationalTableRow.h"
+#include "uppercaseString.h"
+
+// Namespace
+using namespace cool;
+
+//-----------------------------------------------------------------------------
+
+RelationalSequence::RelationalSequence
+( const std::string& name,
+  const RelationalSequenceMgr& sequenceMgr )
+  : m_name( name )
+  , m_sequenceMgr( sequenceMgr )
+{
+  //std::cout << "RelationalSequence constructor" << std::endl;
+}
+
+//-----------------------------------------------------------------------------
+
+RelationalSequence::~RelationalSequence() 
+{
+  //std::cout << "RelationalSequence destructor" << std::endl;
+}
+
+//-----------------------------------------------------------------------------
+
+const std::pair<unsigned int, std::string>
+RelationalSequence::currValDate( unsigned int nSteps ) 
+{
+  bool setNextValue = false;
+  if ( nSteps>0 ) setNextValue = true;
+
+  // Select the row with the current sequence value and date FOR UPDATE
+  RecordSpecification spec;
+  spec.extend( RelationalSequenceTable::columnNames::currentValue,
+               RelationalSequenceTable::columnTypeIds::currentValue );
+  spec.extend( RelationalSequenceTable::columnNames::lastModDate,
+               RelationalSequenceTable::columnTypeIds::lastModDate );
+
+  std::string whereClause = ""; // no selection
+  coral::AttributeList whereData;
+  std::string desc = "";
+  bool forUpdate = true;
+  RelationalTableRow row = sequenceMgr().queryMgr().fetchRowFromTables
+    ( RelationalQueryMgr::tableList( name() ), 
+      RelationalQueryMgr::columnList( spec ), 
+      whereClause, whereData, desc, forUpdate );
+  const coral::AttributeList& attr = row.data();
+
+  // Test whether the sequence is initialised
+  bool isNull =
+    attr[RelationalSequenceTable::columnNames::currentValue].isNull();
+
+  // If setNextValue==false, return the current value
+  // Throw an exception if the sequence is not yet initialised
+  if ( !setNextValue ) {
+    if ( isNull ) {
+      throw RelationalException
+        ( "Sequence is not initialized yet", "RelationalSequence" );
+    } else {
+      unsigned int currValue =
+        attr[RelationalSequenceTable::columnNames::currentValue]
+        .data<RelationalSequenceTable::columnTypes::currentValue>();
+      std::string lastModDate =
+        attr[RelationalSequenceTable::columnNames::lastModDate]
+        .data<RelationalSequenceTable::columnTypes::lastModDate>();
+      return std::pair<unsigned int, std::string>( currValue, lastModDate );
+    }
+  }
+
+  // If setNextValue==true, increment the current value and return it
+  // Initialise the sequence if the sequence is not yet initialised
+  else {
+    unsigned int nextValue;
+    if ( isNull ) {
+      nextValue = s_firstValue;
+      nextValue += s_increment * (nSteps - 1);
+    } else {
+      nextValue =
+        attr[RelationalSequenceTable::columnNames::currentValue]
+        .data<RelationalSequenceTable::columnTypes::currentValue>();
+      nextValue += s_increment * nSteps;
+    }
+    coral::AttributeList updateData;
+    updateData.extend
+      ( "newvalue",
+        typeIdToCoralType(RelationalSequenceTable::columnTypeIds::currentValue) );
+    updateData["newvalue"]
+      .data<RelationalSequenceTable::columnTypes::currentValue>() = nextValue;
+    std::string setClause = RelationalSequenceTable::columnNames::currentValue;
+    setClause += "=:newvalue";
+    setClause += ", ";
+    setClause += RelationalSequenceTable::columnNames::lastModDate;
+    setClause += "=";
+    setClause += sequenceMgr().queryMgr().serverTimeClause();
+    std::string whereClause = ""; // no selection (update all rows)
+
+    // TEMPORARY? No need for checkAttributeListCompliance size checks here
+    // at update time (the sequence name is unchanged and was checked at
+    // insertion time, the sequence value has no maximum size to check,
+    // the last modification date is a short string by construction)
+
+    if ( ! sequenceMgr().queryMgr().updateTableRows
+         ( name(), setClause, whereClause,  updateData ) )
+      throw RowNotUpdated
+        ( "Could not update the sequence table", "RelationalSequence" );
+    std::string lastModDate = "UNKNOWN";
+    return std::pair<unsigned int, std::string>( nextValue, lastModDate );
+  }
+
+}
+
+//-----------------------------------------------------------------------------
+
+
diff --git a/RelationalCool/src/RelationalSequence.h b/RelationalCool/src/RelationalSequence.h
new file mode 100644
index 000000000..a8349d806
--- /dev/null
+++ b/RelationalCool/src/RelationalSequence.h
@@ -0,0 +1,112 @@
+// $Id: RelationalSequence.h,v 1.11 2008-11-04 11:25:57 avalassi Exp $
+#ifndef RELATIONALCOOL_RELATIONALSEQUENCE_H
+#define RELATIONALCOOL_RELATIONALSEQUENCE_H
+
+// Include files
+#include <string>
+
+// Local include files
+#include "RelationalException.h"
+
+namespace cool {
+
+  /** @class RelationalSequence RelationalSequence.h
+   *
+   *  Generic relational implementation of a COOL 'sequence'.
+   *
+   *  This is actually a table row providing an increasing integer number
+   *  in a sequence with no holes, as well as its last modification date.
+   *
+   *  Presently each 'sequence' is stored as a separate relational table.
+   *
+   *  WARNING: this is a private class of the implementation library.
+   *  An instance of this class can only be used as long as the
+   *  RelationalSequenceMgr instance that created it still exists.
+   *
+   *  @author Andrea Valassi and Marco Clemencic
+   *  @date   2006-03-10
+   */
+
+  class RelationalSequence 
+  {
+
+    friend class RelationalSequenceMgr;
+
+  public:
+
+    /// Destructor
+    virtual ~RelationalSequence();
+
+    /// Returns the name of the sequence
+    const std::string& name() const
+    {
+      return m_name;
+    }    
+
+    /// Returns the current value of the sequence
+    /// Throw an exception if the sequence is not yet initialised
+    unsigned int currVal()
+    {
+      return currValDate(0).first;
+    }
+
+    /// Increments the sequence and return the new current value
+    /// Initialise the sequence if the sequence is not yet initialised
+    /// The nSteps>0 option increments the value by n steps for bulk insertions
+    unsigned int nextVal( unsigned int nSteps = 1 ) 
+    {
+      if ( nSteps == 0 )
+        throw RelationalException
+          ( "Invalid argument=0 to nextVal()", "RelationalSequence" );
+      return currValDate(nSteps).first;
+    }
+
+    /// Returns the date corresponding to the current value of the sequence
+    /// Throw an exception if the sequence is not yet initialised
+    const std::string currDate() 
+    {
+      return currValDate(0).second;
+    }
+
+  protected:
+    
+    /// Constructor from a sequence name and a RelationalSequenceMgr
+    RelationalSequence( const std::string& name,
+                        const RelationalSequenceMgr& sequenceMgr );
+
+    /// Get the RelationalSequenceMgr reference
+    const RelationalSequenceMgr& sequenceMgr() const { return m_sequenceMgr; }
+
+    /// Returns the current (nSteps=0) or the next (nSteps>0) value and date
+    const std::pair<unsigned int, std::string> currValDate( unsigned int nSteps );
+
+  private:
+
+    /// Standard constructor is private
+    RelationalSequence();
+
+    /// Copy constructor is private
+    RelationalSequence( const RelationalSequence& rhs );
+
+    /// Assignment operator is private
+    RelationalSequence& operator=( const RelationalSequence& rhs );
+
+  private:
+
+    /// The name of the sequence (i.e. the name of the sequence table)
+    std::string m_name;
+
+    /// Reference to the parent RelationalSequenceMgr
+    const RelationalSequenceMgr& m_sequenceMgr;
+
+    /// The first value of the sequence
+    static const unsigned int s_firstValue = 0;
+
+    /// The increment value of the sequence
+    static const unsigned int s_increment = 1;
+
+  };
+
+}
+
+#endif // RELATIONALCOOL_RELATIONALSEQUENCE_H
diff --git a/RelationalCool/src/RelationalSequenceMgr.cpp b/RelationalCool/src/RelationalSequenceMgr.cpp
new file mode 100644
index 000000000..699edc178
--- /dev/null
+++ b/RelationalCool/src/RelationalSequenceMgr.cpp
@@ -0,0 +1,40 @@
+// $Id: RelationalSequenceMgr.cpp,v 1.6 2008-03-20 18:30:19 marcocle Exp $
+
+// Local include files
+#include "RelationalQueryMgr.h"
+#include "RelationalSequence.h"
+#include "RelationalSequenceMgr.h"
+
+// Namespace
+using namespace cool;
+
+//---------------------------------------------------------------------------
+
+RelationalSequenceMgr::RelationalSequenceMgr
+( const RelationalQueryMgr& queryMgr )
+  : m_queryMgr( queryMgr )
+  , m_log( new coral::MessageStream( "RelationalSequenceMgr" ))
+{
+  log() << coral::Debug 
+        << "Instantiate a RelationalSequenceMgr" << coral::MessageStream::endmsg;
+}
+
+//---------------------------------------------------------------------------
+
+RelationalSequenceMgr::~RelationalSequenceMgr()
+{
+  log() << coral::Debug 
+        << "Delete the RelationalSequenceMgr" << coral::MessageStream::endmsg;
+}
+
+//---------------------------------------------------------------------------
+
+boost::shared_ptr<RelationalSequence>
+RelationalSequenceMgr::instantiateSequence( const std::string& name )
+{
+  boost::shared_ptr<RelationalSequence>
+    ptr( new RelationalSequence( name, *this ) );
+  return ptr;
+}
+
+//-----------------------------------------------------------------------------
diff --git a/RelationalCool/src/RelationalSequenceMgr.h b/RelationalCool/src/RelationalSequenceMgr.h
new file mode 100644
index 000000000..5d1b0951d
--- /dev/null
+++ b/RelationalCool/src/RelationalSequenceMgr.h
@@ -0,0 +1,92 @@
+// $Id: RelationalSequenceMgr.h,v 1.12 2008-11-04 11:52:11 avalassi Exp $
+#ifndef RELATIONALCOOL_RELATIONALSEQUENCEMGR_H
+#define RELATIONALCOOL_RELATIONALSEQUENCEMGR_H
+
+// Include files
+#include <memory>
+#include <string>
+#include <boost/shared_ptr.hpp>
+#include "CoralBase/MessageStream.h"
+
+namespace cool {  
+  
+  // Forward declarations
+  class RelationalQueryMgr;
+  class RelationalSequence;
+
+  /** @class RelationalSequenceMgr RelationalSequenceMgr.h
+   *
+   *  Abstract base class for a manager of COOL relational 'sequences'.
+   * 
+   *  Transactions are NOT handled by this class.
+   *
+   *  @author Andrea Valassi
+   *  @date   2006-03-10 
+  */
+  
+  class RelationalSequenceMgr 
+  {
+    
+  public:
+
+    /// Destructor
+    virtual ~RelationalSequenceMgr();
+
+    /// Create a new sequence (ownership of the C++ instance is shared).
+    /// PURE VIRTUAL method implemented in subclasses.
+    virtual boost::shared_ptr<RelationalSequence>
+    createSequence( const std::string& name ) = 0;
+
+    /// Does this sequence exist?
+    /// PURE VIRTUAL method implemented in subclasses.
+    virtual bool existsSequence( const std::string& name ) = 0;
+
+    /// Get an existing sequence (ownership of the C++ instance is shared).
+    /// PURE VIRTUAL method implemented in subclasses.
+    virtual boost::shared_ptr<RelationalSequence>
+    getSequence( const std::string& name ) = 0;
+
+    /// Drop an existing sequence
+    /// PURE VIRTUAL method implemented in subclasses.
+    virtual void dropSequence( const std::string& name ) = 0;
+
+    /// Instantiate a sequence (ownership of the C++ instance is shared).
+    boost::shared_ptr<RelationalSequence> 
+    instantiateSequence( const std::string& name );
+
+    /// Get the RelationalQueryMgr reference
+    const RelationalQueryMgr& queryMgr() const { return m_queryMgr; }
+
+  protected:
+
+    /// Constructor from a RelationalQueryMgr reference
+    RelationalSequenceMgr( const RelationalQueryMgr& queryMgr );
+
+    /// Get a CORAL MessageStream
+    coral::MessageStream& log() const { return *m_log; }
+
+  private:
+
+    /// Standard constructor is private
+    RelationalSequenceMgr();
+
+    /// Copy constructor is private
+    RelationalSequenceMgr( const RelationalSequenceMgr& rhs );
+
+    /// Assignment operator is private
+    RelationalSequenceMgr& operator=( const RelationalSequenceMgr& rhs );
+
+  protected:
+
+    /// Reference to the parent RelationalQueryMgr
+    const RelationalQueryMgr& m_queryMgr;
+
+    /// CORAL MessageStream
+    std::auto_ptr<coral::MessageStream> m_log;
+
+  };
+  
+}
+
+#endif // RELATIONALCOOL_RELATIONALSEQUENCEMGR_H
+
diff --git a/RelationalCool/src/RelationalSequenceTable.cpp b/RelationalCool/src/RelationalSequenceTable.cpp
new file mode 100644
index 000000000..ac9f9d8e5
--- /dev/null
+++ b/RelationalCool/src/RelationalSequenceTable.cpp
@@ -0,0 +1,36 @@
+// $Id: RelationalSequenceTable.cpp,v 1.7 2008-11-04 11:52:11 avalassi Exp $
+
+// Include files
+#include "CoolKernel/RecordSpecification.h"
+
+// Local include files
+#include "RelationalSequenceTable.h"
+
+//-----------------------------------------------------------------------------
+
+const cool::IRecordSpecification&
+cool::RelationalSequenceTable::tableSpecification
+( bool seqNameOnly )
+{
+  static RecordSpecification spec_all;
+  static RecordSpecification spec_name_only;
+  RecordSpecification& spec = seqNameOnly ? spec_name_only : spec_all;
+  
+  if ( spec.size() == 0 ) {
+    // Include the first column (the sequence name)
+    spec.extend( RelationalSequenceTable::columnNames::sequenceName, 
+                 RelationalSequenceTable::columnTypeIds::sequenceName );
+    // Include also all columns after the first column (the sequence name)
+    if ( ! seqNameOnly ) {    
+      spec.extend( RelationalSequenceTable::columnNames::currentValue, 
+                   RelationalSequenceTable::columnTypeIds::currentValue );
+      spec.extend( RelationalSequenceTable::columnNames::lastModDate, 
+                   RelationalSequenceTable::columnTypeIds::lastModDate );
+    }
+  }
+  
+  return spec;
+  
+}
+
+//-----------------------------------------------------------------------------
diff --git a/RelationalCool/src/RelationalSequenceTable.h b/RelationalCool/src/RelationalSequenceTable.h
new file mode 100644
index 000000000..10d567a62
--- /dev/null
+++ b/RelationalCool/src/RelationalSequenceTable.h
@@ -0,0 +1,49 @@
+#ifndef RELATIONALCOOL_RELATIONALSEQUENCETABLE_H
+#define RELATIONALCOOL_RELATIONALSEQUENCETABLE_H
+
+// Include files
+#include "CoolKernel/StorageType.h"
+
+namespace cool {
+
+  // Forward declarations
+  class IRecordSpecification;
+
+  /** @namespace cool::RelationalSequenceTable RelationalSequenceTable.h
+   *  
+   *  Relational schema of the tables implementing "sequence" functionalities.
+   *
+   *  @author Andrea Valassi, Sven A. Schmidt and Marco Clemencic
+   *  @date   2005-04-15
+   */
+  
+  namespace RelationalSequenceTable {
+    
+    namespace columnNames {
+      static const std::string sequenceName = "SEQUENCE_NAME";    
+      static const std::string currentValue = "CURRENT_VALUE";    
+      static const std::string lastModDate = "LASTMOD_DATE";    
+    }
+
+    namespace columnTypeIds {
+      static const StorageType::TypeId sequenceName = StorageType::String255;
+      static const StorageType::TypeId currentValue = StorageType::UInt32;
+      static const StorageType::TypeId lastModDate  = StorageType::String255;
+    }
+
+    namespace columnTypes {
+      typedef String255 sequenceName;
+      typedef UInt32    currentValue;
+      typedef String255 lastModDate;
+    }
+
+    /// Get the RecordSpecification of the sequence table.
+    /// If the flag is true, include only the first column (the sequence name).
+    const IRecordSpecification& 
+    tableSpecification( bool seqNameOnly = false );
+    
+  }
+
+}
+
+#endif // RELATIONALCOOL_RELATIONALSEQUENCETABLE_H
diff --git a/RelationalCool/src/RelationalSharedSequenceTable.cpp b/RelationalCool/src/RelationalSharedSequenceTable.cpp
new file mode 100644
index 000000000..c070feced
--- /dev/null
+++ b/RelationalCool/src/RelationalSharedSequenceTable.cpp
@@ -0,0 +1,43 @@
+// $Id: RelationalSharedSequenceTable.cpp,v 1.2 2008-11-04 11:52:11 avalassi Exp $
+
+// Include files
+#include "CoolKernel/RecordSpecification.h"
+
+// Local include files
+#include "RelationalSharedSequenceTable.h"
+
+//-----------------------------------------------------------------------------
+
+const cool::IRecordSpecification&
+cool::RelationalSharedSequenceTable::tableSpecification
+( bool nodeIdOnly )
+{
+  static RecordSpecification spec_all;
+  static RecordSpecification spec_id_only;
+  RecordSpecification& spec = nodeIdOnly ? spec_id_only : spec_all;
+  
+  if ( spec.size() == 0 ) 
+  {
+
+    // Include the first column (the nodeId)
+    spec.extend
+      ( RelationalSharedSequenceTable::columnNames::nodeId, 
+        RelationalSharedSequenceTable::columnTypeIds::nodeId );
+
+    // Include also all columns after the first column (the nodeId)
+    if ( ! nodeIdOnly ) 
+    {    
+      spec.extend
+        ( RelationalSharedSequenceTable::columnNames::currentValue, 
+          RelationalSharedSequenceTable::columnTypeIds::currentValue );
+      spec.extend
+        ( RelationalSharedSequenceTable::columnNames::lastModDate, 
+          RelationalSharedSequenceTable::columnTypeIds::lastModDate );
+    }
+
+  }  
+  return spec;
+  
+}
+
+//-----------------------------------------------------------------------------
diff --git a/RelationalCool/src/RelationalSharedSequenceTable.h b/RelationalCool/src/RelationalSharedSequenceTable.h
new file mode 100644
index 000000000..40718c187
--- /dev/null
+++ b/RelationalCool/src/RelationalSharedSequenceTable.h
@@ -0,0 +1,60 @@
+#ifndef RELATIONALCOOL_RELATIONALSHAREDSEQUENCETABLE_H
+#define RELATIONALCOOL_RELATIONALSHAREDSEQUENCETABLE_H
+
+// Include files
+#include "CoolKernel/StorageType.h"
+
+namespace cool {
+
+  // Forward declarations
+  class IRecordSpecification;
+
+  /** @namespace cool::RelationalSharedSequenceTable RelationalSharedSequenceTable.h
+   *  
+   *  Relational schema of the new "sequence" tables for tag 
+   *  (tag and IOV) numbering in individual folder sets (folders).
+   *
+   *  These new sequence tables are designed to be shared by
+   *  several nodes, hence they have a nodeId column as primary key.
+   *  Two such tables are foreseen, one for tags and one for IOVS.
+   *  Note that IOV numbering in each individual folders uses PKs
+   *  that are globally unique across all channels in the folder.
+   *
+   *  @author Andrea Valassi
+   *  @date   2007-01-31
+   */
+  
+  namespace RelationalSharedSequenceTable 
+  {
+
+    namespace columnNames
+    {
+      static const std::string nodeId = "NODE_ID";
+      static const std::string currentValue = "CURRENT_VALUE";
+      static const std::string lastModDate = "LASTMOD_DATE";
+    }
+
+    namespace columnTypeIds
+    {
+      static const StorageType::TypeId nodeId = StorageType::UInt32;
+      static const StorageType::TypeId currentValue = StorageType::UInt32;
+      static const StorageType::TypeId lastModDate = StorageType::String255;
+    }
+
+    namespace columnTypes
+    {
+      typedef UInt32 nodeId;
+      typedef UInt32 currentValue;
+      typedef String255 lastModDate;
+    }
+
+    /// Get the RecordSpecification of the sequence table.
+    /// If the flag is true, include only the first column (the nodeId).
+    const IRecordSpecification& 
+    tableSpecification( bool nodeIdOnly = false );
+    
+  }
+
+}
+
+#endif // RELATIONALCOOL_RELATIONALSHAREDSEQUENCETABLE_H
diff --git a/RelationalCool/src/RelationalTableRow.cpp b/RelationalCool/src/RelationalTableRow.cpp
new file mode 100644
index 000000000..9fa5d0242
--- /dev/null
+++ b/RelationalCool/src/RelationalTableRow.cpp
@@ -0,0 +1,46 @@
+// $Id: RelationalTableRow.cpp,v 1.5 2006-03-14 16:58:12 avalassi Exp $
+
+// Local include files
+#include "RelationalTableRow.h"
+
+// Namespace
+using namespace cool;
+
+//-----------------------------------------------------------------------------
+
+RelationalTableRow::~RelationalTableRow() 
+{
+}
+
+//-----------------------------------------------------------------------------
+
+RelationalTableRow::RelationalTableRow() 
+  : RelationalTableRowBase() 
+{
+}
+
+//-----------------------------------------------------------------------------
+
+RelationalTableRow::RelationalTableRow
+( const RelationalTableRow& aRow ) 
+  : RelationalTableRowBase( aRow )
+{
+}
+
+//-----------------------------------------------------------------------------
+
+RelationalTableRow& 
+RelationalTableRow::operator=( const RelationalTableRow& aRow )
+{
+  m_data = aRow.data();
+  return *this;
+}
+
+//---------------------------------------------------------------------------
+
+RelationalTableRow::RelationalTableRow( const coral::AttributeList& data ) 
+  : RelationalTableRowBase( data )
+{
+}
+
+//-----------------------------------------------------------------------------
diff --git a/RelationalCool/src/RelationalTableRow.h b/RelationalCool/src/RelationalTableRow.h
new file mode 100644
index 000000000..582a3abb5
--- /dev/null
+++ b/RelationalCool/src/RelationalTableRow.h
@@ -0,0 +1,53 @@
+// $Id: RelationalTableRow.h,v 1.11 2007-07-05 09:05:12 avalassi Exp $
+#ifndef RELATIONALCOOL_RELATIONALTABLEROW_H
+#define RELATIONALCOOL_RELATIONALTABLEROW_H
+
+// Local include files
+#include "RelationalTableRowBase.h"
+
+namespace cool {  
+  
+  /** @class RelationalTableRow RelationalTableRow.h
+   *  
+   *  Concrete implementation of a generic relational table row.
+   *
+   *  This is the generic relational table row created by fetch statements. 
+   *  It is the default implementation of a RelationalTableRowBase.
+   *
+   *  This class can be 'reinterpreted' as rows of specific tables by
+   *  defining a derived class FooTableRow with one constructor from a
+   *  RelationalTableRow. This class mainly exists to avoid constructing a
+   *  FooTableRow from an instance of its base class RelationalTableRowBase.
+   *
+   *  @author Andrea Valassi and Sven A. Schmidt
+   *  @date   2005-10-12
+   */
+  
+  class RelationalTableRow : public RelationalTableRowBase {
+
+  public:
+
+    /// Destructor.
+    virtual ~RelationalTableRow();
+    
+    /// Standard constructor.
+    /// Creates a table row with empty AttributeList data.
+    RelationalTableRow();
+
+    /// Copy constructor.
+    /// Performs a deep copy of the AttributeList values.
+    RelationalTableRow( const RelationalTableRow& rhs );
+
+    /// Assignment operator.
+    /// Performs a deep copy of the AttributeList values.
+    RelationalTableRow& operator=( const RelationalTableRow& rhs );
+
+    /// Constructor from an AttributeList.
+    /// Performs a deep copy of the AttributeList values.
+    explicit RelationalTableRow( const coral::AttributeList& data );
+    
+  };
+  
+}
+
+#endif // RELATIONALCOOL_RELATIONALTABLEROW_H
diff --git a/RelationalCool/src/RelationalTableRowBase.cpp b/RelationalCool/src/RelationalTableRowBase.cpp
new file mode 100644
index 000000000..e410043ca
--- /dev/null
+++ b/RelationalCool/src/RelationalTableRowBase.cpp
@@ -0,0 +1,46 @@
+// $Id: RelationalTableRowBase.cpp,v 1.1 2006-03-14 16:58:12 avalassi Exp $
+
+// Local include files
+#include "RelationalTableRowBase.h"
+
+// Namespace
+using namespace cool;
+
+//---------------------------------------------------------------------------
+
+RelationalTableRowBase::~RelationalTableRowBase()
+{
+}
+
+//---------------------------------------------------------------------------
+
+RelationalTableRowBase::RelationalTableRowBase()
+{
+}
+
+//---------------------------------------------------------------------------
+
+RelationalTableRowBase::RelationalTableRowBase
+( const RelationalTableRowBase& aRow ) 
+  : m_data( aRow.m_data )
+{
+}
+
+//---------------------------------------------------------------------------
+
+RelationalTableRowBase& 
+RelationalTableRowBase::operator=( const RelationalTableRowBase& aRow )
+{
+  m_data = aRow.data();
+  return *this;
+}
+
+//---------------------------------------------------------------------------
+
+RelationalTableRowBase::RelationalTableRowBase
+( const coral::AttributeList& data )
+  : m_data( data )
+{
+}
+
+//---------------------------------------------------------------------------
diff --git a/RelationalCool/src/RelationalTableRowBase.h b/RelationalCool/src/RelationalTableRowBase.h
new file mode 100644
index 000000000..00569a741
--- /dev/null
+++ b/RelationalCool/src/RelationalTableRowBase.h
@@ -0,0 +1,97 @@
+// $Id: RelationalTableRowBase.h,v 1.1 2006-03-14 16:58:12 avalassi Exp $
+#ifndef RELATIONALCOOL_RELATIONALTABLEROWBASE_H
+#define RELATIONALCOOL_RELATIONALTABLEROWBASE_H
+
+// Include files
+#include "CoralBase/AttributeList.h"
+#include "CoralBase/AttributeListSpecification.h"
+
+namespace cool {  
+  
+  /** @class RelationalTableRowBase RelationalTableRowBase.h
+   *  
+   *  Base class for a relational table row.
+   *  This class cannot be instantiated as all its constructors are protected.
+   *  
+   *  This class mainly exists because of the known problems with the
+   *  coral::AttributeList copy constructor and assignment operator.
+   *
+   *  @author Andrea Valassi and Sven A. Schmidt
+   *  @date   2006-03-11
+   */
+  
+  class RelationalTableRowBase {
+
+  public:
+
+    /*
+    /// Returns the row specification.
+    const coral::AttributeListSpecification& rowSpecification() const 
+    {
+      return m_data->attributeListSpecification(); 
+    }
+    */
+    
+    /// Returns the start const iterator for the fields.
+    coral::AttributeList::const_iterator begin() const 
+    { 
+      return m_data.begin(); 
+    }
+    
+    /// Returns the end const iterator for the fields.
+    coral::AttributeList::const_iterator end() const 
+    { 
+      return m_data.end(); 
+    }
+    
+    /// Proxy for the AttributeList [] access operator (non const version).
+    coral::Attribute& operator[]( const std::string& name ) 
+    {
+      return m_data[name];
+    }
+    
+    /// Proxy for the AttributeList [] access operator (const version).
+    const coral::Attribute& operator[]( const std::string& name ) const 
+    {
+      return m_data[name];
+    }
+    
+    /// Accessor to the row data.
+    const coral::AttributeList& data() const 
+    { 
+      return m_data; 
+    }
+
+  protected:
+
+    /// Destructor.
+    virtual ~RelationalTableRowBase();
+    
+    /// Standard constructor.
+    /// Creates a table row with empty AttributeList data.
+    RelationalTableRowBase();
+
+    /// Copy constructor.
+    /// Performs a deep copy of the AttributeList values.
+    RelationalTableRowBase( const RelationalTableRowBase& rhs );
+
+    /// Constructor from an AttributeList.
+    /// Performs a deep copy of the AttributeList values.
+    explicit RelationalTableRowBase( const coral::AttributeList& data );
+    
+    /// Assignment operator.
+    /// Performs a deep copy of the AttributeList values.
+    /// [AV 14.03.06 - I would have left this private but this is needed by 
+    /// vector<RelationalObjectTable>::push_back()... check why!]
+    RelationalTableRowBase& operator=( const RelationalTableRowBase& rhs );
+
+  protected:
+
+    // The relational row data.
+    coral::AttributeList m_data;
+    
+  };
+  
+}
+
+#endif // RELATIONALCOOL_RELATIONALTABLEROWBASE_H
diff --git a/RelationalCool/src/RelationalTag2TagTable.cpp b/RelationalCool/src/RelationalTag2TagTable.cpp
new file mode 100644
index 000000000..b4e39dd9a
--- /dev/null
+++ b/RelationalCool/src/RelationalTag2TagTable.cpp
@@ -0,0 +1,30 @@
+// $Id: RelationalTag2TagTable.cpp,v 1.5 2006-09-28 12:49:29 avalassi Exp $
+
+// Include files
+#include "CoolKernel/RecordSpecification.h"
+
+// Local include files
+#include "RelationalTag2TagTable.h"
+
+//-----------------------------------------------------------------------------
+
+const cool::IRecordSpecification &
+cool::RelationalTag2TagTable::tableSpecification()
+{
+  static RecordSpecification spec;
+  if ( spec.size() == 0 ) {
+    spec.extend( RelationalTag2TagTable::columnNames::parentNodeId,
+                 RelationalTag2TagTable::columnTypeIds::parentNodeId );
+    spec.extend( RelationalTag2TagTable::columnNames::parentTagId,
+                 RelationalTag2TagTable::columnTypeIds::parentTagId );
+    spec.extend( RelationalTag2TagTable::columnNames::childNodeId,
+                 RelationalTag2TagTable::columnTypeIds::childNodeId );
+    spec.extend( RelationalTag2TagTable::columnNames::childTagId,
+                 RelationalTag2TagTable::columnTypeIds::childTagId );
+    spec.extend( RelationalTag2TagTable::columnNames::sysInsTime,
+                 RelationalTag2TagTable::columnTypeIds::sysInsTime );
+  }
+  return spec;
+}
+
+//-----------------------------------------------------------------------------
diff --git a/RelationalCool/src/RelationalTag2TagTable.h b/RelationalCool/src/RelationalTag2TagTable.h
new file mode 100644
index 000000000..f1edae543
--- /dev/null
+++ b/RelationalCool/src/RelationalTag2TagTable.h
@@ -0,0 +1,69 @@
+// $Id: RelationalTag2TagTable.h,v 1.9 2007-01-17 17:55:45 avalassi Exp $
+#ifndef RELATIONALCOOL_RELATIONALTAG2TAGTABLE_H
+#define RELATIONALCOOL_RELATIONALTAG2TAGTABLE_H
+
+// Local include files
+#include "uppercaseString.h"
+
+namespace cool {
+
+  // Forward declarations
+  class IRecordSpecification;
+
+  /** @namespace cool::RelationalTag2TagTable RelationalTag2TagTable.h
+   *
+   *  Relational schema of the table storing
+   *  parent-child relations between HVS global tags.
+   *
+   *  @author Andrea Valassi and Marco Clemencic
+   *  @date   2006-03-23
+   */
+
+  namespace RelationalTag2TagTable {
+
+    inline const std::string defaultTableName( const std::string& prefix ) {
+      // TEMPORARY? AV 04.04.2005
+      // FIXME: presently the input prefix is uppercase anyway...
+      return uppercaseString(prefix) + "TAG2TAG";
+    }
+
+    inline const std::string sequenceName( const std::string& tableName ) {
+      // TEMPORARY? AV 04.04.2005 
+      // FIXME: presently the input table name is uppercase anyway...
+      return uppercaseString(tableName) + "_SEQ";
+    }    
+
+    namespace columnNames {
+      static const std::string parentNodeId = "PARENT_NODEID";
+      static const std::string parentTagId = "PARENT_TAGID";
+      static const std::string childNodeId = "CHILD_NODEID";
+      static const std::string childTagId = "CHILD_TAGID";
+      static const std::string sysInsTime = "SYS_INSTIME";
+    }
+
+    namespace columnTypeIds {
+      static const StorageType::TypeId parentNodeId = StorageType::UInt32;
+      static const StorageType::TypeId parentTagId  = StorageType::UInt32;
+      static const StorageType::TypeId childNodeId  = StorageType::UInt32;
+      static const StorageType::TypeId childTagId   = StorageType::UInt32;
+      // TEMPORARY! Should be Time?
+      static const StorageType::TypeId sysInsTime   = StorageType::String255;
+    }
+
+    namespace columnTypes {
+      typedef UInt32 parentNodeId;
+      typedef UInt32 parentTagId;
+      typedef UInt32 childNodeId;
+      typedef UInt32 childTagId;
+      // TEMPORARY! Should be Time?
+      typedef String255 sysInsTime;
+    }
+    
+    /// Get the record specification of the tag table
+    const IRecordSpecification& tableSpecification();
+
+  }
+
+}
+
+#endif // RELATIONALCOOL_RELATIONALTAG2TAGTABLE_H
diff --git a/RelationalCool/src/RelationalTagMgr.cpp b/RelationalCool/src/RelationalTagMgr.cpp
new file mode 100644
index 000000000..d20c662c8
--- /dev/null
+++ b/RelationalCool/src/RelationalTagMgr.cpp
@@ -0,0 +1,1440 @@
+// $Id: RelationalTagMgr.cpp,v 1.99 2008-11-04 11:52:11 avalassi Exp $
+
+// Include files
+#include "CoralBase/Attribute.h"
+#include "CoolKernel/Record.h"
+#include "CoolKernel/RecordSpecification.h"
+
+// Local include files
+#include "IRelationalTransactionMgr.h"
+#include "RelationalDatabase.h"
+#include "RelationalException.h"
+#include "RelationalFolder.h"
+#include "RelationalQueryMgr.h"
+#include "RelationalGlobalTagTable.h"
+#include "RelationalHvsTagRecord.h"
+#include "RelationalNodeMgr.h"
+#include "RelationalNodeTable.h"
+#include "RelationalSequence.h"
+#include "RelationalSequenceMgr.h"
+#include "RelationalTableRow.h"
+#include "RelationalTagMgr.h"
+#include "RelationalTagSequence.h"
+#include "RelationalTag2TagTable.h"
+#include "RelationalTransaction.h"
+#include "timeToString.h"
+
+// Namespace
+using namespace cool;
+
+// Local type definitions
+typedef boost::shared_ptr<RelationalSequence> RelationalSequencePtr;
+
+//-----------------------------------------------------------------------------
+
+RelationalTagMgr::RelationalTagMgr
+( const RelationalDatabase& aDb )
+  : m_db( aDb )
+  , m_log( new coral::MessageStream( "RelationalTagMgr" ) )
+{
+  log() << coral::Debug << "Instantiate a RelationalTagMgr" 
+        << coral::MessageStream::endmsg;
+}
+
+//-----------------------------------------------------------------------------
+
+RelationalTagMgr::~RelationalTagMgr()
+{
+  log() << coral::Debug << "Delete the RelationalTagMgr" << coral::MessageStream::endmsg;
+}
+
+//-----------------------------------------------------------------------------
+
+RelationalQueryMgr& RelationalTagMgr::queryMgr() const
+{
+  return db().queryMgr();
+}
+
+//-----------------------------------------------------------------------------
+
+RelationalNodeMgr& RelationalTagMgr::nodeMgr() const
+{
+  return db().nodeMgr();
+}
+
+//-----------------------------------------------------------------------------
+
+const RelationalTableRow
+RelationalTagMgr::fetchGlobalTagTableRowForNode
+( const std::string& tagName ) const
+{
+  log() << "Fetch global tag table row for tag " << tagName 
+        << coral::MessageStream::endmsg;
+
+  // TEMPORARY implementation - until the isLeaf column is added
+  bool leafFound = false;
+  bool innerFound = false;
+  RelationalTableRow row;
+  const std::vector<RelationalTableRow> rows =
+    fetchGlobalTagTableRows( tagName );
+
+  // Loop over all tag records retrieved
+  for ( std::vector<RelationalTableRow>::const_iterator
+          rowIt = rows.begin(); rowIt != rows.end(); ++rowIt ) {
+    const RelationalTableRow& tagRow = *rowIt;
+    UInt32 nodeId =
+      tagRow[RelationalGlobalTagTable::columnNames::nodeId].data<UInt32>();
+    const RelationalTableRow nodeRow =
+      nodeMgr().fetchNodeTableRow( nodeId );    
+    bool isLeaf = 
+      nodeRow[RelationalNodeTable::columnNames::nodeIsLeaf].data<bool>();
+    if ( isLeaf ) {
+      leafFound = true;
+      row = tagRow;
+    }
+    else {
+      if ( innerFound ) {
+        throw RelationalException
+          ( "PANIC! Tag applied to more than one inner node!",
+            "RelationalTagMgr" );      
+      }
+      else {
+        innerFound = true;
+        row = tagRow;
+      }
+    }
+  }
+
+  // Tag not found in any (inner or leaf) node
+  if ( !innerFound && !leafFound ) 
+    throw TagNotFound
+      ( "Tag '" + tagName + "' not found in any node", "RelationalTagMgr" );
+
+  // Tag found both in an inner and in a leaf node?!
+  if ( innerFound && leafFound ) 
+    throw RelationalException
+      ( "PANIC! Tag applied to both inner and leaf nodes!", 
+        "RelationalTagMgr" );
+
+  // Tag found (either in an inner or in a leaf node)
+  // Do not use "else" here: workaround for a warning on MacOSX
+  // (control reaches end of non-void function) - see task #2062
+  return row;
+  
+}
+
+//-----------------------------------------------------------------------------
+
+const std::vector<RelationalTableRow>
+RelationalTagMgr::fetchGlobalTagTableRows( UInt32 nodeId ) const
+{
+  log() << "Fetch global tag table rows for node #" << nodeId << coral::MessageStream::endmsg;
+
+  // Define the WHERE clause for the selection using bind variables
+  coral::AttributeList whereData;
+  whereData.extend
+    ( "nodeId", typeIdToCoralType
+      (RelationalGlobalTagTable::columnTypeIds::nodeId) );
+  whereData["nodeId"].setValue( nodeId );
+  std::string whereClause = RelationalGlobalTagTable::columnNames::nodeId;
+  whereClause += "= :nodeId";
+
+  // Delegate the query to the RelationalQueryMgr
+  std::string desc = "";
+  std::vector<RelationalTableRow> rows =
+    queryMgr().fetchRowsFromTables
+    ( RelationalQueryMgr::tableList( db().globalTagTableName() ), 
+      RelationalQueryMgr::columnList
+      ( RelationalGlobalTagTable::tableSpecification() ),
+      whereClause, whereData, desc );
+  return rows;
+}
+
+//-----------------------------------------------------------------------------
+
+const std::vector<RelationalTableRow>
+RelationalTagMgr::fetchGlobalTagTableRows( const std::string& tagName ) const
+{
+  log() << "Fetch global tag table rows for tag " << tagName << coral::MessageStream::endmsg;
+
+  // Define the WHERE clause for the selection using bind variables
+  coral::AttributeList whereData;
+  whereData.extend
+    ( "tagName", typeIdToCoralType
+      (RelationalGlobalTagTable::columnTypeIds::tagName) );
+  whereData["tagName"].setValue( tagName );
+  std::string whereClause = RelationalGlobalTagTable::columnNames::tagName;
+  whereClause += "= :tagName";
+
+  // Delegate the query to the RelationalQueryMgr
+  std::string desc = "";
+  std::vector<RelationalTableRow> rows =
+    queryMgr().fetchRowsFromTables
+    ( RelationalQueryMgr::tableList( db().globalTagTableName() ), 
+      RelationalQueryMgr::columnList
+      ( RelationalGlobalTagTable::tableSpecification() ),
+      whereClause, whereData, desc );
+  if ( rows.size() != 0 )
+    return rows;
+  else
+    throw TagNotFound( "Tag '" + tagName + "' not found in any node", 
+                       "RelationalTagMgr" );
+}
+
+//-----------------------------------------------------------------------------
+
+const RelationalTableRow
+RelationalTagMgr::fetchGlobalTagTableRow( UInt32 nodeId,
+                                          const std::string& tagName ) const
+{
+  log() << "Fetch global tag table row for nodeId=" << nodeId 
+        << " and tag=" << tagName << coral::MessageStream::endmsg;
+
+  // Define the WHERE clause for the selection using bind variables
+  coral::AttributeList whereData;
+  whereData.extend
+    ( "nodeId", typeIdToCoralType
+      (RelationalGlobalTagTable::columnTypeIds::nodeId) );
+  whereData.extend
+    ( "tagName", typeIdToCoralType
+      (RelationalGlobalTagTable::columnTypeIds::tagName) );
+  whereData["nodeId"].setValue( nodeId );
+  whereData["tagName"].setValue( tagName );
+  std::string whereClause;
+  whereClause += RelationalGlobalTagTable::columnNames::nodeId;
+  whereClause += "= :nodeId";
+  whereClause += " AND ";
+  whereClause += RelationalGlobalTagTable::columnNames::tagName;
+  whereClause += "= :tagName";
+  
+  // Delegate the query to the RelationalQueryMgr
+  try {
+    std::string desc = "";
+    return queryMgr().fetchRowFromTables
+      ( RelationalQueryMgr::tableList( db().globalTagTableName() ), 
+        RelationalQueryMgr::columnList
+        ( RelationalGlobalTagTable::tableSpecification() ),
+        whereClause, whereData, desc );
+  } catch( NoRowsFound& ) {
+    throw TagNotFound( tagName, nodeId, "RelationalTagMgr" );
+  }
+}
+
+//-----------------------------------------------------------------------------
+
+const RelationalTableRow
+RelationalTagMgr::fetchGlobalTagTableRow( UInt32 nodeId,
+                                          UInt32 tagId ) const
+{
+  log() << "Fetch global tag table row for nodeId=" << nodeId 
+        << " and tagId=" << tagId << coral::MessageStream::endmsg;
+
+  // Define the WHERE clause for the selection using bind variables
+  coral::AttributeList whereData;
+  whereData.extend
+    ( "nodeId", typeIdToCoralType
+      (RelationalGlobalTagTable::columnTypeIds::nodeId) );
+  whereData.extend
+    ( "tagId", typeIdToCoralType
+      (RelationalGlobalTagTable::columnTypeIds::tagId) );
+  whereData["nodeId"].setValue( nodeId );
+  whereData["tagId"].setValue( tagId );
+  std::string whereClause;
+  whereClause += RelationalGlobalTagTable::columnNames::nodeId;
+  whereClause += "= :nodeId";
+  whereClause += " AND ";
+  whereClause += RelationalGlobalTagTable::columnNames::tagId;
+  whereClause += "= :tagId";
+  
+  // Delegate the query to the RelationalQueryMgr
+  try {
+    std::string desc = "";
+    return queryMgr().fetchRowFromTables
+      ( RelationalQueryMgr::tableList( db().globalTagTableName() ), 
+        RelationalQueryMgr::columnList
+        ( RelationalGlobalTagTable::tableSpecification() ),
+        whereClause, whereData, desc );
+  } catch( NoRowsFound& ) {
+    throw TagNotFound( tagId, nodeId, "RelationalTagMgr" );
+  }
+}
+
+//-----------------------------------------------------------------------------
+
+bool RelationalTagMgr::existsTag( const std::string& tagName ) const
+{
+  if ( IHvsNode::isHeadTag( tagName ) ) return true;
+  try {
+    // TEMPORARY! This STILL assumes 'tag = tag name' and one node per tag!
+    tagNameScope( tagName );
+    return true;
+  } catch ( TagNotFound& ) {
+    return false;
+  }
+}
+
+//-----------------------------------------------------------------------------
+
+IHvsNode::Type 
+RelationalTagMgr::tagNameScope( const std::string& tagName ) const
+{
+  // Cross-check that the database is open
+  if ( ! db().isOpen() ) throw DatabaseNotOpen( "RelationalTagMgr" );
+
+  bool isLeaf;
+  if ( IHvsNode::isHeadTag( tagName ) )
+    isLeaf = true;
+  RelationalTableRow nodeRow;
+  RelationalTransaction* pTransaction = 0;
+  if ( !db().transactionMgr()->isActive() )
+    pTransaction = 
+      new RelationalTransaction( db().transactionMgr(), true ); // r/o
+  try {
+    std::vector<RelationalTableRow> tagRows = 
+      fetchGlobalTagTableRows( tagName ); // throws TagNotFound if none found
+    UInt32 nRows = tagRows.size();
+    if ( nRows == 0 ) {
+      throw RelationalException
+        ( "PANIC! No rows and no throw from fetchGlobalTagTableRows?" );
+    }
+    else if ( nRows > 1 ) {
+      // AV TEMPORARY - UGLY AND DANGEROUS!
+      isLeaf = true;
+    }
+    else {
+      RelationalTableRow& tagRow = tagRows[0];
+      UInt32 nodeId =
+        tagRow[RelationalGlobalTagTable::columnNames::nodeId].data<UInt32>();
+      nodeRow = nodeMgr().fetchNodeTableRow( nodeId );
+      isLeaf = 
+        nodeRow[RelationalNodeTable::columnNames::nodeIsLeaf].data<bool>();
+    }
+  } catch (...) {
+    if ( pTransaction ) delete pTransaction;
+    throw;
+  }
+  if ( pTransaction ) delete pTransaction;
+  if ( isLeaf ) 
+    return IHvsNode::LEAF_NODE;
+  else 
+    return IHvsNode::INNER_NODE;
+}
+
+//-----------------------------------------------------------------------------
+
+const std::vector<std::string> 
+RelationalTagMgr::taggedNodes( const std::string& tagName ) const
+{
+  // Cross-check that the database is open
+  if ( ! db().isOpen() ) throw DatabaseNotOpen( "RelationalTagMgr" );
+
+  std::vector<std::string> nodes;
+  if ( IHvsNode::isHeadTag( tagName ) )
+    throw ReservedHeadTag( tagName, "RelationalTagMgr" );
+  RelationalTransaction* pTransaction = 0;
+  if ( !db().transactionMgr()->isActive() ) 
+    pTransaction = 
+      new RelationalTransaction( db().transactionMgr(), true ); // r/o
+  try {
+    std::vector<RelationalTableRow> rows = 
+      fetchGlobalTagTableRows( tagName ); // throws TagNotFound if none found
+    for ( std::vector<RelationalTableRow>::const_iterator
+            row = rows.begin(); row != rows.end(); ++row ) {
+      const RelationalTableRow& tagRow = *row;
+      unsigned int nodeId =
+        tagRow[RelationalGlobalTagTable::columnNames::nodeId]
+        .data<unsigned int>();
+      RelationalTableRow nodeRow = nodeMgr().fetchNodeTableRow( nodeId );
+      std::string fullPath =
+        nodeRow[RelationalNodeTable::columnNames::nodeFullPath]
+        .data<std::string>();
+      nodes.push_back( fullPath );
+    }
+    if ( pTransaction ) delete pTransaction;
+    return nodes;
+  } catch (...) {
+    if ( pTransaction ) delete pTransaction;
+    throw;
+  }
+}
+
+//-----------------------------------------------------------------------------
+
+const HvsTagRecord
+RelationalTagMgr::findTagRecord( UInt32 nodeId,
+                                 const std::string& tagName ) const
+{
+  //std::cout << "*** RelationalTagMgr::findTagRecord - START" << std::endl;
+
+  // Cross-check that the database is open
+  if ( ! db().isOpen() ) throw DatabaseNotOpen( "RelationalTagMgr" );
+
+  RelationalTransaction transaction( db().transactionMgr(), true ); // r/o
+
+  RelationalHvsTagRecord record(__findTagRecord(nodeId,tagName));
+
+  transaction.commit();
+  return record;
+}
+
+//-----------------------------------------------------------------------------
+
+const HvsTagRecord
+RelationalTagMgr::__findTagRecord( UInt32 nodeId,
+                                   const std::string& tagName ) const
+{
+
+  RelationalTableRow
+    row( fetchGlobalTagTableRow( nodeId, tagName ) );
+  //std::cout << "*** RelationalTagMgr::findTagRecord - 2" << std::endl;
+  
+  // AV - Split up the following line in two parts for clarity
+  //RelationalHvsTagRecord record( row.data() );
+  
+  const coral::AttributeList &rowAL = row.data();
+  //std::cout << "*** RelationalTagMgr::findTagRecord - 3" << std::endl;
+  //std::cout << "*** RelationalTagMgr::findTagRecord - input AL size: " 
+  //          << rowAL.size() << std::endl;
+  //std::stringstream msg;
+  //rowAL.toOutputStream( msg );
+  //std::cout << "*** RelationalTagMgr::findTagRecord - input AL: " 
+  //          << msg.str() << std::endl;
+  
+  // AV - The following will throw an unknown exception on Windows
+  //RelationalHvsTagRecord record( rowAL );
+
+  // AV - The following is a workaround (WHY???)
+  HvsTagRecord record0 = RelationalHvsTagRecord::fromRow( rowAL );      
+  //std::cout << "*** RelationalTagMgr::findTagRecord - 4" << std::endl;
+  RelationalHvsTagRecord record( record0 );   
+  
+  //std::cout << "*** RelationalTagMgr::findTagRecord - END" << std::endl;
+  return record;
+}
+
+//-----------------------------------------------------------------------------
+
+const HvsTagRecord
+RelationalTagMgr::findTagRecord( UInt32 nodeId,
+                                 UInt32 tagId ) const
+{
+  // Cross-check that the database is open
+  if ( ! db().isOpen() ) throw DatabaseNotOpen( "RelationalTagMgr" );
+
+  RelationalTransaction transaction( db().transactionMgr(), true ); // r/o
+
+  RelationalHvsTagRecord record(__findTagRecord(nodeId,tagId));
+
+  transaction.commit();
+  return record;
+}
+
+//-----------------------------------------------------------------------------
+
+const HvsTagRecord
+RelationalTagMgr::__findTagRecord( UInt32 nodeId,
+                                   UInt32 tagId ) const
+{
+  RelationalTableRow
+    row( fetchGlobalTagTableRow( nodeId, tagId ) );
+
+  // AV - Split up the following line in two parts for clarity
+  //RelationalHvsTagRecord record( row.data() );
+  const coral::AttributeList &rowAL = row.data();
+  // AV - The following will throw an unknown exception on Windows
+  //RelationalHvsTagRecord record( rowAL );
+  // AV - Apply the same workaround as for findTagRecord( nodeId, tagId )
+  HvsTagRecord record0 = RelationalHvsTagRecord::fromRow( rowAL );      
+  RelationalHvsTagRecord record( record0 );
+  
+  return record;
+}
+
+//-----------------------------------------------------------------------------
+
+const Time
+RelationalTagMgr::tagInsertionTime
+( const IHvsNode* node, const std::string& tagName ) const
+{
+  //std::cout << "*** RelationalTagMgr::tagInsertionTime - START" << std::endl;
+
+  // HEAD tag for folder sets, SV folders, MV folders
+  if ( IHvsNode::isHeadTag( tagName ) ) {
+    //std::cout << "*** RelationalTagMgr::tagInsTime - END HEAD" << std::endl;
+    return node->insertionTime();
+  }
+  
+  // Retrieve the tag insertion time from the global tag table
+  return findTagRecord( node->id(), tagName ).insertionTime();
+  
+  /*
+  // Folder set - retrieve the tag insertion time from the global tag table
+  if ( !node->isLeaf() ) {
+    return findTagRecord( node->id(), tagName ).insertionTime();
+  }
+
+  // Folder
+  else {
+    const RelationalFolder* folder = 
+      dynamic_cast<const RelationalFolder*>( node );
+    if ( !folder )
+      throw RelationalException
+        ( "PANIC! Could not dynamic cast IHvsNode* to RelationalFolder*",
+          "RelationalTagMgr" );
+    // SV folder
+    if ( folder->versioningMode() != FolderVersioning::MULTI_VERSION ) {
+      throw TagNotFound( tagName, folder->fullPath(), "RelationalTagMgr" );
+    }
+    // MV folder - retrieve the tag insertion time from the global tag table
+    else {
+      //std::cout << "*** RelationalTagMgr::tagInsTime - END MV" << std::endl;
+      return findTagRecord( folder->id(), tagName ).insertionTime();
+    }
+  }
+  */
+
+}
+
+//-----------------------------------------------------------------------------
+
+const std::string
+RelationalTagMgr::tagDescription
+( const IHvsNode* node, const std::string& tagName ) const
+{
+  // HEAD tag for folder sets, SV folders, MV folders
+  if ( IHvsNode::isHeadTag( tagName ) )
+    return std::string( "HEAD tag" );
+
+  // Retrieve the tag description from the global tag table
+  return findTagRecord( node->id(), tagName ).description();      
+
+  /*
+  // Folder set - retrieve the tag description from the global tag table
+  if ( !node->isLeaf() ) {
+    return findTagRecord( node->id(), tagName ).description();
+  }
+
+  // Folder
+  else {
+    const RelationalFolder* folder = 
+      dynamic_cast<const RelationalFolder*>( node );
+    if ( !folder )
+      throw RelationalException
+        ( "PANIC! Could not dynamic cast IHvsNode* to RelationalFolder*",
+          "RelationalTagMgr" );
+    // SV folder
+    if ( folder->versioningMode() != FolderVersioning::MULTI_VERSION ) {
+      throw TagNotFound( tagName, node->fullPath(), "RelationalTagMgr" );
+    }
+    // MV folder - retrieve the tag description from the global tag table
+    else {
+      return findTagRecord( folder->id(), tagName ).description();      
+    }
+  }
+  */
+
+}
+
+//-----------------------------------------------------------------------------
+
+HvsTagLock::Status
+RelationalTagMgr::tagLockStatus
+( const IHvsNode* node, const std::string& tagName ) const
+{
+  // HEAD tag for folder sets, SV folders, MV folders - never locked!
+  if ( IHvsNode::isHeadTag( tagName ) ) {
+    return HvsTagLock::UNLOCKED;
+  }
+
+  // Retrieve the tag lock status from the global tag table
+  return findTagRecord( node->id(), tagName ).lockStatus();      
+
+  /*
+  // Folder set - retrieve the tag lock status from the global tag table
+  if ( !node->isLeaf() ) {
+    return findTagRecord( node->id(), tagName ).lockStatus();      
+  }
+
+  // Folder
+  else {
+    const RelationalFolder* folder = 
+      dynamic_cast<const RelationalFolder*>( node );
+    if ( !folder )
+      throw RelationalException
+        ( "PANIC! Could not dynamic cast IHvsNode* to RelationalFolder*",
+          "RelationalTagMgr" );
+    // SV folder
+    if ( folder->versioningMode() != FolderVersioning::MULTI_VERSION ) {
+      throw TagNotFound( tagName, folder->fullPath(), "RelationalTagMgr" );
+    }
+    // MV folder - retrieve the tag lock status from the global tag table
+    else {
+      return findTagRecord( folder->id(), tagName ).lockStatus();
+    }
+  }
+  */
+
+}
+
+//-----------------------------------------------------------------------------
+
+void 
+RelationalTagMgr::setTagLockStatus( const IHvsNode* node, 
+                                    const std::string& tagName, 
+                                    HvsTagLock::Status tagLockStatus )
+{
+  // HEAD tag for folder sets, SV folders, MV folders - never locked!
+  if ( IHvsNode::isHeadTag( tagName ) ) {
+    throw ReservedHeadTag( tagName, "RelationalTagMgr" );
+  }
+
+  // Start a transaction
+  RelationalTransaction transaction( db().transactionMgr() ); // read-write
+
+  // Define the SET and WHERE clauses for the update using bind variables
+  coral::AttributeList updateData;
+  updateData.extend
+    ( "tagLockStatus", typeIdToCoralType
+      (RelationalGlobalTagTable::columnTypeIds::tagLockStatus) );
+  updateData.extend
+    ( "nodeId", typeIdToCoralType
+      (RelationalGlobalTagTable::columnTypeIds::nodeId) );
+  updateData.extend
+    ( "tagName", typeIdToCoralType
+      (RelationalGlobalTagTable::columnTypeIds::tagName) );
+  updateData["tagLockStatus"].setValue( (UInt16)tagLockStatus );
+  updateData["nodeId"].setValue( node->id() );
+  updateData["tagName"].setValue( tagName );
+  std::string setClause = 
+    RelationalGlobalTagTable::columnNames::tagLockStatus;
+  setClause += "= :tagLockStatus";
+  std::string whereClause = RelationalGlobalTagTable::columnNames::nodeId;
+  whereClause += " = :nodeId";
+  whereClause += " AND ";
+  whereClause += RelationalGlobalTagTable::columnNames::tagName;
+  whereClause += " = :tagName";
+
+  // Execute the update
+  if ( 1 != queryMgr().updateTableRows
+       ( db().globalTagTableName(), setClause, whereClause, updateData ) )
+    throw RowNotUpdated
+      ( "Could not update the tag lock status - does tag exist?", 
+        "RalDatabase" );
+
+  // Commit the transaction
+  transaction.commit();
+
+}
+
+//-----------------------------------------------------------------------------
+
+const HvsTagRecord
+RelationalTagMgr::findOrCreateTag( UInt32 nodeId,
+                                   const std::string& tagName ) const
+{
+  if ( ! db().isOpen() ) throw DatabaseNotOpen( "RelationalTagMgr" );
+  try {
+
+    // AV - Split up the following line in two parts for clarity
+    //RelationalHvsTagRecord record
+    //  ( fetchGlobalTagTableRow( nodeId, tagName ).data() );
+    const coral::AttributeList rowAL = 
+      fetchGlobalTagTableRow( nodeId, tagName ).data();
+    // AV - The following will throw an unknown exception on Windows
+    //RelationalHvsTagRecord record( rowAL );
+    // AV - Apply the same workaround as for findTagRecord( nodeId, tagId )
+    HvsTagRecord record0 = RelationalHvsTagRecord::fromRow( rowAL );      
+    RelationalHvsTagRecord record( record0 );
+
+    return record;
+  }
+  catch ( TagNotFound& ) {
+    // PERFORMANCE WARNING - createTag() will query existsTag() a 2nd time
+    std::string description = "";
+    return createTag( nodeId, tagName, description );
+  }
+}
+
+//-----------------------------------------------------------------------------
+
+const HvsTagRecord
+RelationalTagMgr::createTag( UInt32 nodeId,
+                             const std::string& tagName,
+                             const std::string& description ) const
+{
+  return createTagAndLocalTag( nodeId, tagName, description, "" );
+}
+
+//-----------------------------------------------------------------------------
+
+const HvsTagRecord
+RelationalTagMgr::createTagAndLocalTag
+( UInt32 nodeId,
+  const std::string& tagName,
+  const std::string& description,
+  const std::string& inputTagTableName ) const
+{
+  // Check if this tag exists (globally)
+  // [NB existsTag(tagName) returns true for the reserved tags "" or "HEAD"]
+  if ( existsTag( tagName ) )
+    throw TagExists( tagName, "RelationalTagMgr" );
+
+  // TEMPORARY! - Start
+  // TEMPORARY! Functionality needed but this implementation is an ugly hack!
+  // Check whether the node supports versioning - is it a SV folder?
+  // Must perform the check before retrieving the tag sequence (none for SV!)
+  // HACK - Skip check if input local tag name is provided
+  std::string tagTableName = "";
+  if ( inputTagTableName != "" ) {    
+    tagTableName = inputTagTableName;
+  }
+  else {
+    RelationalTableRow row = nodeMgr().fetchNodeTableRow( nodeId );
+    bool isLeaf =
+      row[RelationalNodeTable::columnNames::nodeIsLeaf].data<bool>();
+    if ( isLeaf ) {
+      FolderVersioning::Mode mode =
+        RelationalFolder::versioningMode( row.data() );
+      if ( mode == FolderVersioning::MULTI_VERSION )
+        tagTableName = RelationalFolder::tagTableName( row.data() );
+      else
+        throw FolderIsSingleVersion( nodeId, "RelationalTagMgr" );
+    }
+  }
+  // TEMPORARY! - End
+
+  // Get a new tag ID from the sequence
+  std::string tagSeqName = RelationalTagSequence::sequenceName
+    ( db().defaultTablePrefix(), nodeId );
+  RelationalSequencePtr sequence
+    ( db().queryMgr().sequenceMgr().getSequence( tagSeqName ) );
+  UInt32 tagId = sequence->nextVal();
+  const std::string insertionTime = sequence->currDate();
+
+  // New tags are UNLOCKED
+  HvsTagLock::Status tagLockStatus = HvsTagLock::UNLOCKED;
+
+  // Register the tag in the global tag table
+  insertGlobalTagTableRow
+    ( nodeId, tagId, tagName, tagLockStatus, description, insertionTime );
+
+  // TEMPORARY! - Start
+  // TEMPORARY! - Also fill the local tag table if necessary.
+  // Fill the local tag table name if one is provided.
+  // Otherwise retrieve it from the node table for MV folders.
+  // Insert the new tag also in the local tag table
+  if ( tagTableName != "" )
+    insertTagTableRow
+      ( tagTableName, tagId, tagName, description, insertionTime );
+  // TEMPORARY! - End
+
+  // Return the new tag ID
+  return HvsTagRecord( tagId, nodeId, tagName, tagLockStatus, description,
+                       stringToTime( insertionTime ) );
+}
+
+//-----------------------------------------------------------------------------
+
+void RelationalTagMgr::deleteTag( UInt32 nodeId,
+                                  const std::string& tagName ) const
+{
+  deleteGlobalTagTableRow( nodeId, findTagRecord( nodeId, tagName ).id() );
+}
+    
+//-----------------------------------------------------------------------------
+
+void RelationalTagMgr::insertGlobalTagTableRow
+( UInt32 nodeId,
+  UInt32 tagId,
+  const std::string& tagName,
+  HvsTagLock::Status tagLockStatus,
+  const std::string& tagDescription,
+  const std::string& insertionTime ) const
+{
+  // Transaction handled in the outer scope
+  // Existence check handled in the outer scope
+
+  // Register the tag in the global tag table
+  Record data( RelationalGlobalTagTable::tableSpecification() );  
+  data[RelationalGlobalTagTable::columnNames::nodeId].setValue
+    ( nodeId );
+  data[RelationalGlobalTagTable::columnNames::tagId].setValue
+    ( tagId );
+  data[RelationalGlobalTagTable::columnNames::tagName].setValue
+    ( tagName );
+  data[RelationalGlobalTagTable::columnNames::tagLockStatus].setValue
+    ( (UInt16)tagLockStatus );
+  data[RelationalGlobalTagTable::columnNames::tagDescription].setValue
+    ( tagDescription );
+  data[RelationalGlobalTagTable::columnNames::sysInsTime].setValue
+    ( insertionTime );
+
+  // TEMPORARY? Will RAL do this as well?
+  // Check that all column values are within their allowed range
+  RelationalGlobalTagTable::tableSpecification().validate(data);
+
+  // Perform the actual db update
+  queryMgr().insertTableRow
+    ( db().globalTagTableName(), data.attributeList() );
+}
+
+//-----------------------------------------------------------------------------
+
+void RelationalTagMgr::deleteGlobalTagTableRow( UInt32 nodeId,
+                                                UInt32 tagId ) const
+{
+  // Throw TagIsLocked if the tag is locked (either LOCKED or PARTIALLYLOCKED,
+  // both are equivalent here): this is not strictly necessary because 
+  // this protection is already implemented where necessary (i.e.
+  // in deleteTag for MV folders and in deleteTagRelation), but is added
+  // here for extra protection at the cost of little performance overhead.
+  // PANIC exception because there should be no path to this statement...!
+  const HvsTagRecord tag = __findTagRecord( nodeId, tagId );
+  if ( tag.lockStatus() != HvsTagLock::UNLOCKED ) {
+    std::stringstream msg;
+    msg << "PANIC! Cannot delete global tag table row for tag '" << tag.name()
+        << " (tag #" << tagId << ") in node #" << nodeId 
+        << ": tag is locked";
+    throw TagIsLocked( msg.str(), "RelationalTagMgr" );
+  }
+  // Transaction handled in the outer scope
+  coral::AttributeList whereData;
+  whereData.extend
+    ( "nodeId", typeIdToCoralType
+      (RelationalGlobalTagTable::columnTypeIds::nodeId) );
+  whereData.extend
+    ( "tagId", typeIdToCoralType
+      (RelationalGlobalTagTable::columnTypeIds::tagId) );
+  whereData["nodeId"].setValue( nodeId );
+  whereData["tagId"].setValue( tagId );
+  std::string whereClause;
+  whereClause += RelationalGlobalTagTable::columnNames::nodeId;
+  whereClause += "= :nodeId";
+  whereClause += " AND ";
+  whereClause += RelationalGlobalTagTable::columnNames::tagId;
+  whereClause += "= :tagId";
+  queryMgr().deleteTableRows
+    ( db().globalTagTableName(), whereClause, whereData, 1 );
+}
+
+//-----------------------------------------------------------------------------
+
+UInt32
+RelationalTagMgr::deleteGlobalTagTableRowsForNode( UInt32 nodeId ) const
+{
+  // Transaction handled in the outer scope
+  coral::AttributeList whereData;
+  whereData.extend
+    ( "nodeId", typeIdToCoralType
+      (RelationalGlobalTagTable::columnTypeIds::nodeId) );
+  whereData["nodeId"].setValue( nodeId );
+  std::string whereClause = RelationalGlobalTagTable::columnNames::nodeId;
+  whereClause += "= :nodeId";
+  return queryMgr().deleteTableRows
+    ( db().globalTagTableName(), whereClause, whereData );
+}
+
+//-----------------------------------------------------------------------------
+
+void RelationalTagMgr::insertTagTableRow
+( const std::string& tagTableName,
+  UInt32 tagId,
+  const std::string& tagName,
+  const std::string& description,
+  const std::string& insertionTime ) const
+{
+  // Transaction handled in the outer scope
+
+  // AV - DO NOT TEST IF TAG EXISTS HERE - TAG DOES EXIST IN GLOBAL TAG TABLE!
+
+  // Register the tag in the local tag table
+  
+  const IRecordSpecification& dataSpec =
+    RelationalTagTable::tableSpecification();
+  coral::AttributeList data = Record( dataSpec ).attributeList();
+  data[RelationalTagTable::columnNames::tagId].setValue
+    ( tagId );
+  data[RelationalTagTable::columnNames::tagName].setValue
+    ( tagName );
+  data[RelationalTagTable::columnNames::tagDescription].setValue
+    ( description );
+  data[RelationalTagTable::columnNames::sysInsTime].setValue
+    ( insertionTime );
+
+  // TEMPORARY? Will RAL do this as well?
+  // Check that all column values are within their allowed range
+  dataSpec.validate(data);
+  
+  // Perform the actual db update
+  queryMgr().insertTableRow( tagTableName, data );
+
+  // Return the systemID for the tag
+  //return tagId;
+}
+
+//-----------------------------------------------------------------------------
+
+void RelationalTagMgr::deleteTagTableRow( const std::string& tagTableName,
+                                          UInt32 tagId ) const
+{
+  // Transaction handled in the outer scope
+  coral::AttributeList whereData;
+  whereData.extend
+    ( "tagId", typeIdToCoralType
+      (RelationalTagTable::columnTypeIds::tagId) );
+  whereData["tagId"].setValue( tagId );
+  std::string whereClause = RelationalTagTable::columnNames::tagId;
+  whereClause += "= :tagId";
+  queryMgr().deleteTableRows( tagTableName, whereClause, whereData, 1 );
+}
+
+//-----------------------------------------------------------------------------
+
+void RelationalTagMgr::insertTag2TagTableRow
+( UInt32 parentNodeId,
+  UInt32 parentTagId,
+  UInt32 childNodeId,
+  UInt32 childTagId,
+  const std::string& insertionTime ) const
+{
+  // Transaction handled in the outer scope
+  // Existence check handled in the outer scope
+
+  // Register the tag in the global tag table
+  const IRecordSpecification& dataSpec = 
+    RelationalTag2TagTable::tableSpecification();
+  Record data( dataSpec );  
+  data[RelationalTag2TagTable::columnNames::parentNodeId].setValue
+    ( parentNodeId );
+  data[RelationalTag2TagTable::columnNames::parentTagId].setValue
+    ( parentTagId );
+  data[RelationalTag2TagTable::columnNames::childNodeId].setValue
+    ( childNodeId );
+  data[RelationalTag2TagTable::columnNames::childTagId].setValue
+    ( childTagId );
+  data[RelationalTag2TagTable::columnNames::sysInsTime].setValue
+    ( insertionTime );
+
+  // TEMPORARY? Will RAL do this as well?
+  // Check that all column values are within their allowed range
+  dataSpec.validate(data);
+
+  // Perform the actual db update
+  queryMgr().insertTableRow
+    ( db().tag2TagTableName(), data.attributeList() );
+}
+
+//-----------------------------------------------------------------------------
+
+const RelationalTableRow
+RelationalTagMgr::fetchTag2TagTableRow( UInt32 parentNodeId,
+                                        UInt32 parentTagId,
+                                        UInt32 childNodeId ) const
+{
+  log() << "Fetch tag2tag row for relation between parent tag #" 
+        << parentTagId << " in node #" << parentNodeId 
+        << " and child tag in node #" << childNodeId << coral::MessageStream::endmsg;
+
+  // Transaction handled in the outer scope
+
+  coral::AttributeList whereData;
+  whereData.extend
+    ( "parentNodeId", typeIdToCoralType
+      (RelationalTag2TagTable::columnTypeIds::parentNodeId) );
+  whereData.extend
+    ( "parentTagId", typeIdToCoralType
+      (RelationalTag2TagTable::columnTypeIds::parentTagId) );
+  whereData.extend
+    ( "childNodeId", typeIdToCoralType
+      (RelationalTag2TagTable::columnTypeIds::childNodeId) );
+  whereData["parentNodeId"].setValue( parentNodeId );
+  whereData["parentTagId"].setValue( parentTagId );
+  whereData["childNodeId"].setValue( childNodeId );
+  std::string whereClause;
+  whereClause += RelationalTag2TagTable::columnNames::parentNodeId;
+  whereClause += "= :parentNodeId";
+  whereClause += " AND ";
+  whereClause += RelationalTag2TagTable::columnNames::parentTagId;
+  whereClause += "= :parentTagId";
+  whereClause += " AND ";
+  whereClause += RelationalTag2TagTable::columnNames::childNodeId;
+  whereClause += "= :childNodeId";
+  try {
+    std::string desc = "";
+    return queryMgr().fetchRowFromTables
+      ( RelationalQueryMgr::tableList( db().tag2TagTableName() ), 
+        RelationalQueryMgr::columnList
+        ( RelationalTag2TagTable::tableSpecification() ),
+        whereClause, whereData, desc );
+  } catch( NoRowsFound& ) {
+    throw TagRelationNotFound
+      ( parentNodeId, parentTagId, childNodeId, "RelationalTagMgr" );
+  }
+}
+
+//-----------------------------------------------------------------------------
+
+void RelationalTagMgr::deleteTag2TagTableRow( UInt32 parentNodeId,
+                                              UInt32 parentTagId,
+                                              UInt32 childNodeId ) const
+{
+  log() << "Delete tag2tag row for relation between parent tag #" 
+        << parentTagId << " in node #" << parentNodeId 
+        << " and child tag in node #" << childNodeId << coral::MessageStream::endmsg;
+
+  // Transaction handled in the outer scope
+
+  coral::AttributeList whereData;
+  whereData.extend
+    ( "parentNodeId", typeIdToCoralType
+      (RelationalTag2TagTable::columnTypeIds::parentNodeId) );
+  whereData.extend
+    ( "parentTagId", typeIdToCoralType
+      (RelationalTag2TagTable::columnTypeIds::parentTagId) );
+  whereData.extend
+    ( "childNodeId", typeIdToCoralType
+      (RelationalTag2TagTable::columnTypeIds::childNodeId) );
+  whereData["parentNodeId"].setValue( parentNodeId );
+  whereData["parentTagId"].setValue( parentTagId );
+  whereData["childNodeId"].setValue( childNodeId );
+  std::string whereClause;
+  whereClause += RelationalTag2TagTable::columnNames::parentNodeId;
+  whereClause += "= :parentNodeId";
+  whereClause += " AND ";
+  whereClause += RelationalTag2TagTable::columnNames::parentTagId;
+  whereClause += "= :parentTagId";
+  whereClause += " AND ";
+  whereClause += RelationalTag2TagTable::columnNames::childNodeId;
+  whereClause += "= :childNodeId";
+  queryMgr().deleteTableRows
+    ( db().tag2TagTableName(), whereClause, whereData, 1 );
+}
+
+//-----------------------------------------------------------------------------
+
+UInt32
+RelationalTagMgr::deleteTag2TagTableRowsForNode( UInt32 nodeId ) const
+{
+  // Transaction handled in the outer scope
+  coral::AttributeList whereData;
+  whereData.extend
+    ( "parentNodeId", typeIdToCoralType
+      (RelationalTag2TagTable::columnTypeIds::parentNodeId) );
+  whereData.extend
+    ( "childNodeId", typeIdToCoralType
+      (RelationalTag2TagTable::columnTypeIds::childNodeId) );
+  whereData["parentNodeId"].setValue( nodeId );
+  whereData["childNodeId"].setValue( nodeId );
+  std::string whereClause;
+  whereClause += RelationalTag2TagTable::columnNames::parentNodeId;
+  whereClause += "= :parentNodeId";
+  whereClause += " OR ";
+  whereClause += RelationalTag2TagTable::columnNames::childNodeId;
+  whereClause += "= :childNodeId";
+  return queryMgr().deleteTableRows
+    ( db().tag2TagTableName(), whereClause, whereData );
+}
+
+//-----------------------------------------------------------------------------
+
+bool
+RelationalTagMgr::existsTagInTag2TagTable( UInt32 nodeId,
+                                           UInt32 tagId ) const
+{
+  // Transaction handled in the outer scope
+  coral::AttributeList whereData;
+  whereData.extend
+    ( "parentNodeId", typeIdToCoralType
+      (RelationalTag2TagTable::columnTypeIds::parentNodeId) );
+  whereData.extend
+    ( "parentTagId", typeIdToCoralType
+      (RelationalTag2TagTable::columnTypeIds::parentTagId) );
+  whereData.extend
+    ( "childNodeId", typeIdToCoralType
+      (RelationalTag2TagTable::columnTypeIds::childNodeId) );
+  whereData.extend
+    ( "childTagId", typeIdToCoralType
+      (RelationalTag2TagTable::columnTypeIds::childTagId) );
+  whereData["parentNodeId"].setValue( nodeId );
+  whereData["parentTagId"].setValue( tagId );
+  whereData["childNodeId"].setValue( nodeId );
+  whereData["childTagId"].setValue( tagId );
+  std::string whereClause;
+  whereClause += "( ";
+  whereClause += RelationalTag2TagTable::columnNames::parentNodeId;
+  whereClause += " = :parentNodeId";
+  whereClause += " AND ";
+  whereClause += RelationalTag2TagTable::columnNames::parentTagId;
+  whereClause += " = :parentTagId";
+  whereClause += " ) OR ( ";
+  whereClause += RelationalTag2TagTable::columnNames::childNodeId;
+  whereClause += " = :childNodeId";
+  whereClause += " AND ";
+  whereClause += RelationalTag2TagTable::columnNames::childTagId;
+  whereClause += " = :childTagId";
+  whereClause += " )";
+  unsigned int rowCount = db().queryMgr().countRowsFromTables
+    ( RelationalQueryMgr::tableList( db().tag2TagTableName() ),
+      whereClause, whereData, "" );
+  return rowCount > 0;
+}
+
+//-----------------------------------------------------------------------------
+/*
+bool
+RelationalTagMgr::isTagUsed( UInt32 nodeId,
+                             UInt32 tagId ) const
+{
+  // Is the tag referenced in the TAG2TAG table?
+  if ( existsTagInTag2TagTable( nodeId, tagId ) ) {
+    return true;
+  }
+  // TEMPORARY? Not nice to have this code here :-(
+  // Otherwise - must check if this is a folder or folder set
+  else {
+    // If this is a folder set, return false
+    // If this is a folder, check the IOV and IOV2TAG tables
+  }
+}
+*/
+//-----------------------------------------------------------------------------
+
+void 
+RelationalTagMgr::createTagRelation( UInt32 parentNodeId,
+                                     const std::string& parentTagName,
+                                     UInt32 childNodeId,
+                                     const std::string& childTagName ) const
+{
+  log() << "Create tag relation between parent tag '" << parentTagName
+        << "' in node #" << parentNodeId << " and child tag '" << childTagName
+        << "' in node #" << childNodeId << coral::MessageStream::endmsg;
+
+  // Throw ReservedHeadTag if one of the two tags is a HEAD tag
+  if ( IHvsNode::isHeadTag( parentTagName ) )
+    throw ReservedHeadTag( parentTagName, "RelationalTagMgr" );
+  if ( IHvsNode::isHeadTag( childTagName ) )
+    throw ReservedHeadTag( childTagName, "RelationalTagMgr" );
+
+  // Throw NodeRelationNotFound if the nodes are not parent and child
+  // TEMPORARY! Replace by a method returning a node record...
+  RelationalTableRow childNode =
+    db().nodeMgr().fetchNodeTableRow( childNodeId );
+  if ( childNode[RelationalNodeTable::columnNames::nodeParentId].data<UInt32>()
+       != parentNodeId )
+    throw NodeRelationNotFound
+      ( parentNodeId, childNodeId, "RelationalTagMgr", true );  
+  
+  // Create the parent tag in the parent node if not defined yet.
+  const HvsTagRecord parentTag = 
+    findOrCreateTag( parentNodeId, parentTagName );
+  UInt32 parentTagId = parentTag.id();
+
+  // Throw TagIsLocked if the tag is fully LOCKED.
+  // A new relation can be created both if UNLOCKED or PARTIALLYLOCKED:
+  // I can add a new child tag relation to a partially locked parent tag.
+  // If a relation already exists, TagRelationExists is thrown in all cases!
+  if ( parentTag.lockStatus() != HvsTagLock::UNLOCKED &&
+       parentTag.lockStatus() != HvsTagLock::PARTIALLYLOCKED )
+    throw TagIsLocked
+      ( "Cannot create tag relation to parent tag '" + parentTagName + 
+        "': tag is locked", "RelationalTagMgr" );
+
+  // Create the child tag in the child node if not defined yet.
+  UInt32 childTagId = 
+    findOrCreateTag( childNodeId, childTagName ).id();
+
+  // Throw TagRelationExists if a relation to a child tag already exists
+  bool tagRelationExists = false;
+  try {
+    findTagRelation( parentNodeId, parentTagName, childNodeId );
+    tagRelationExists = true;
+  }
+  catch( ... ) {}
+  if ( tagRelationExists ) 
+    throw TagRelationExists
+      ( parentNodeId, parentTagId, childNodeId, "RelationalTagMgr" );
+
+  // Get a new insertion time from the tag2tag sequence
+  const std::string tableName = db().tag2TagTableName();  
+  const std::string seqName = 
+    RelationalTag2TagTable::sequenceName( tableName );
+  RelationalSequencePtr sequence
+    ( db().queryMgr().sequenceMgr().getSequence( seqName ) );
+  sequence->nextVal(); // TEMPORARY! value not used: need a non-sequence clock!
+  const std::string insertionTime = sequence->currDate();
+
+  // Insert a new row in the tag2tag table
+  insertTag2TagTableRow
+    ( parentNodeId, parentTagId, childNodeId, childTagId, insertionTime );
+}
+
+//-----------------------------------------------------------------------------
+
+//void
+UInt32
+RelationalTagMgr::deleteTagRelation( UInt32 parentNodeId,
+                                     const std::string& parentTagName,
+                                     UInt32 childNodeId ) const
+{
+  log() << "Delete tag relation between parent tag '" << parentTagName
+        << "' in node #" << parentNodeId 
+        << " and child tag in node #" << childNodeId << coral::MessageStream::endmsg;
+
+  // Throw ReservedHeadTag if the parent tag is a HEAD tag
+  if ( IHvsNode::isHeadTag( parentTagName ) )
+    throw ReservedHeadTag( parentTagName, "RelationalTagMgr" );
+
+  // Throw TagNotFound if the parent tag does not exist in the parent node
+  const HvsTagRecord tag = __findTagRecord( parentNodeId, parentTagName );
+  UInt32 parentTagId = tag.id();
+
+  // Throw TagIsLocked if the tag is locked
+  // (either LOCKED or PARTIALLYLOCKED - both are equivalent here)
+  if ( tag.lockStatus() != HvsTagLock::UNLOCKED )
+    throw TagIsLocked
+      ( "Cannot delete tag relation to parent tag '" + parentTagName + 
+        "': tag is locked", "RelationalTagMgr" );
+
+  // Throw TagRelationNotFound if the parent tag has no related child tag
+  RelationalTableRow relation =
+    fetchTag2TagTableRow( parentNodeId, parentTagId, childNodeId );
+  UInt32 childTagId =
+    relation[RelationalTag2TagTable::columnNames::childTagId].data<UInt32>();
+
+  // Delete the relation between a parent tag node and a child tag 
+  deleteTag2TagTableRow( parentNodeId, parentTagId, childNodeId );
+
+  // Delete the parent tag if not related to another parent/child tag.
+  // TEMPORARY? Assume the parent can only be a folder set!
+  // All there is to delete in this case is the global tag table row
+  if ( ! existsTagInTag2TagTable( parentNodeId, parentTagId ) )
+    deleteGlobalTagTableRow( parentNodeId, parentTagId );
+
+  // TEMPORARY - this is handled in the calling routine...
+  // Delete the tag in this node if not related to another parent or IOVs.
+  // Throw TagIsLocked if this would lead to deletion of a locked child tag
+  // (either LOCKED or PARTIALLYLOCKED - both are equivalent here).
+
+  // TEMPORARY- return the childTagId
+  return childTagId;
+}
+
+//-----------------------------------------------------------------------------
+
+void 
+RelationalTagMgr::deleteTagRelation( const RelationalHvsNode& childNode,
+                                     const std::string& parentTagName ) const
+{
+  UInt32 parentNodeId = childNode.parentId();
+  UInt32 childNodeId = childNode.id();
+
+  // First delete the tag relation
+  UInt32 childTagId = 
+    deleteTagRelation( parentNodeId, parentTagName, childNodeId );
+
+  // Then, delete also the child tag if this has no IOV or HVS relations left
+  // Throw TagIsLocked if this would lead to deletion of a locked child tag
+  // (either LOCKED or PARTIALLYLOCKED - both are equivalent here)
+  // [this is ALSO implemented in deleteGlobalTagTableRow for extra protection]
+  const HvsTagRecord childTag = 
+    __findTagRecord( childNodeId, childTagId );
+  
+  // Check if this is a folder or a folder set
+  bool isLeaf = childNode.isLeaf();
+  // Folder set - nothing else to check or to delete
+  if ( !isLeaf ) {
+    if ( ! existsTagInTag2TagTable( childNodeId, childTagId ) ) {
+      if ( childTag.lockStatus() != HvsTagLock::UNLOCKED )
+        throw TagIsLocked
+          ( "Cannot delete tag relation to parent tag '" + parentTagName + 
+            "': this would lead to the deletion of locked child tag '"
+            + childTag.name() + "'", "RelationalTagMgr" );
+      deleteGlobalTagTableRow( childNodeId, childTagId );
+    }    
+  }
+  // Folder - check if SV or MV
+  else {
+    const RelationalFolder* pFolder;
+    try {      
+      const RelationalFolder& folder =
+        dynamic_cast<const RelationalFolder&>( childNode );
+      pFolder = &folder;
+    }
+    catch( ... ) {
+      throw RelationalException
+        ( "PANIC! Could not dynamic cast to const RelationalFolder&", 
+          "RelationalTagMgr" );
+    }
+    if ( !pFolder )
+      throw RelationalException
+        ( "PANIC! Null pointer from dynamic cast to const RelationalFolder&", 
+          "RelationalTagMgr" );
+    // SV folder  - nothing else to check or to delete
+    if ( pFolder->versioningMode() != FolderVersioning::MULTI_VERSION ) {
+      if ( ! existsTagInTag2TagTable( childNodeId, childTagId ) ) {
+        if ( childTag.lockStatus() != HvsTagLock::UNLOCKED )
+          throw TagIsLocked
+            ( "Cannot delete tag relation to parent tag '" + parentTagName + 
+              "': this would lead to the deletion of locked child tag '"
+              + childTag.name() + "'", "RelationalTagMgr" );
+        deleteGlobalTagTableRow( childNodeId, childTagId );
+      }
+    }
+    // MV folder - check IOV and IOV2TAG table, delete also from TAG table
+    if ( !existsTagInTag2TagTable( childNodeId, childTagId ) &&
+         !RelationalFolder::existsUserTagInObjectTable
+         ( db().queryMgr(), childTagId, pFolder->objectTableName() ) &&
+         !RelationalFolder::existsTagInObject2TagTable
+         ( db().queryMgr(), childTagId, pFolder->object2TagTableName() ) ) 
+    {
+      if ( childTag.lockStatus() != HvsTagLock::UNLOCKED )
+        throw TagIsLocked
+          ( "Cannot delete tag relation to parent tag '" + parentTagName + 
+            "': this would lead to the deletion of locked child tag '"
+            + childTag.name() + "'", "RelationalTagMgr" );
+      deleteGlobalTagTableRow( childNodeId, childTagId );
+      deleteTagTableRow( pFolder->tagTableName(), childTagId );
+    }
+    // TODO
+  }
+
+}
+
+//-----------------------------------------------------------------------------
+
+UInt32 
+RelationalTagMgr::findTagRelation( UInt32 parentNodeId,
+                                   const std::string& parentTagName,
+                                   UInt32 childNodeId ) const
+{
+  log() << "Find the child tag in node #" << childNodeId 
+        << " related to parent tag '" << parentTagName
+        << " in node '" << parentNodeId << coral::MessageStream::endmsg;
+
+  // Throw ReservedHeadTag if the parent tag is a HEAD tag
+  if ( IHvsNode::isHeadTag( parentTagName ) )
+    throw ReservedHeadTag( parentTagName, "RelationalTagMgr" );
+
+  // Throw TagNotFound if the parent tag does not exist in the parent node
+  UInt32 parentTagId = 
+    __findTagRecord( parentNodeId, parentTagName ).id();
+
+  // Throw TagRelationNotFound if the parent tag has no related child tag
+  RelationalTableRow relation =
+    fetchTag2TagTableRow( parentNodeId, parentTagId, childNodeId );
+
+  // Find the child node tag associated to the given parent node tag.
+  return 
+    relation[RelationalTag2TagTable::columnNames::childTagId].data<UInt32>(); 
+}
+
+//-----------------------------------------------------------------------------
+
+UInt32 
+RelationalTagMgr::resolveTag( const std::string& ancestorTagName,
+                              UInt32 descendantNodeId ) const
+{
+  log() << "Find the descendant tag# in node #" << descendantNodeId 
+        << " related to ancestor tag '" << ancestorTagName << "'"
+        << coral::MessageStream::endmsg;
+
+  // Throw ReservedHeadTag if the ancestor tag is a HEAD tag
+  if ( IHvsNode::isHeadTag( ancestorTagName ) )
+    throw ReservedHeadTag( ancestorTagName, "RelationalTagMgr" );
+
+  // Determine the node where the tag is defined.
+  // Throw TagNotFound if the tag does not exist in any node.
+  RelationalTableRow ancestorTag =
+    fetchGlobalTagTableRowForNode( ancestorTagName );
+  UInt32 ancestorNodeId = 
+    ancestorTag[RelationalGlobalTagTable::columnNames::nodeId].data<UInt32>();
+  UInt32 ancestorTagId = 
+    ancestorTag[RelationalGlobalTagTable::columnNames::tagId].data<UInt32>();
+
+  // Special case: the node where the tag is defined is the 'descendant'
+  // node itself
+  if ( ancestorNodeId == descendantNodeId )
+    return ancestorTagId;
+  
+  // Throw NodeRelationNotFound if the node where the ancestor tag 
+  // is defined is not an ancestor of the descendant node
+  const std::vector<UInt32> dNodes = 
+    nodeMgr().resolveNodeHierarchy( ancestorNodeId, descendantNodeId );
+  UInt32 parentNodeId = ancestorNodeId;
+  UInt32 parentTagId = ancestorTagId; 
+  for ( std::vector<UInt32>::const_iterator
+          dNode = dNodes.begin(); dNode != dNodes.end(); ++dNode ) {
+    UInt32 childNodeId = *dNode;
+    // Throw TagRelationNotFound if the parent tag has no related child tag
+    RelationalTableRow relation = 
+      fetchTag2TagTableRow( parentNodeId, parentTagId, childNodeId );
+    UInt32 childTagId = 
+      relation[RelationalTag2TagTable::columnNames::childTagId].data<UInt32>();
+    if ( childNodeId == descendantNodeId ) {
+      return childTagId;
+    }
+    else {
+      parentNodeId = childNodeId;
+      parentTagId = childTagId;
+    }    
+  }
+  throw RelationalException 
+    ( "PANIC! Descendant node not included in resolved hierarchy???",
+      "RelationalTagMgr" ); 
+}
+
+//-----------------------------------------------------------------------------
+
+void RelationalTagMgr::setTagDescription( const IHvsNode* node,
+                                          const std::string& tagName,
+                                          const std::string& description ) {
+  
+  //if ( IHvsNode::isHeadTag( tagName ) )
+
+  if (description.size() > 255) {
+    throw Exception("Description string exceeds 255 character limit.",
+                    "RelationalFolder");
+  }
+  
+  // We're using the tag lookup in 'findTagRecord' to trigger the
+  // the following exceptions:
+  // - trying to set a description for a non-existing tag
+  // - trying to set a description for tag name not defined for this node
+  // - trying to set a description for the HEAD tag
+  findTagRecord(node->id(), tagName);
+  
+  // prepare update data
+  coral::AttributeList updateData;
+  updateData.extend( 
+    "description",
+    typeIdToCoralType( RelationalTagTable::columnTypeIds::tagDescription )
+  );
+  updateData.extend( 
+    "tagName",
+    typeIdToCoralType( RelationalTagTable::columnTypeIds::tagName )
+  );
+  updateData["description"].setValue( description );
+  updateData["tagName"].setValue( tagName );
+ 
+  std::string setClause =
+    RelationalTagTable::columnNames::tagDescription + " = :description";
+  std::string whereClause = 
+    RelationalTagTable::columnNames::tagName + " = :tagName";
+ 
+  bool readOnly = false;
+  RelationalTransaction transaction( db().transactionMgr(), readOnly );
+ 
+  // update global tag table
+  // NB: we are ignoring / have to ignore the local tag table, because only
+  // leaves (folders, as opposed to foldersets) have one and we can't / don't
+  // want to differentiate between the two here. The duplication of the tag
+  // description in the local tag table should be removed.
+  db().queryMgr().updateTableRows(db().globalTagTableName(),
+                                  setClause,
+                                  whereClause,
+                                  updateData);
+ 
+  transaction.commit();
+}
+
+//-----------------------------------------------------------------------------
diff --git a/RelationalCool/src/RelationalTagMgr.h b/RelationalCool/src/RelationalTagMgr.h
new file mode 100644
index 000000000..3a99196e2
--- /dev/null
+++ b/RelationalCool/src/RelationalTagMgr.h
@@ -0,0 +1,318 @@
+// $Id: RelationalTagMgr.h,v 1.68 2008-11-04 12:39:14 avalassi Exp $
+#ifndef RELATIONALCOOL_RELATIONALTAGMGR_H
+#define RELATIONALCOOL_RELATIONALTAGMGR_H
+
+// Include files
+#include <memory>
+//#include "CoolKernel/IHvsTagMgr.h"
+#include "IHvsTagMgr.h"
+#include "CoralBase/MessageStream.h"
+
+namespace cool {  
+  
+  // Forward declarations
+  class RelationalDatabase;
+  class RelationalNodeMgr;
+  class RelationalQueryMgr;
+  class RelationalTableRow;
+
+  // TEMPORARY
+  class RelationalHvsNode;
+
+  /** @class RelationalTagMgr RelationalTagMgr.h
+   *  
+   *  Abstract base class for a manager of a hierarchy 
+   *  of conditions database tags stored in a relational database.
+   * 
+   *  @author Andrea Valassi and Marco Clemencic
+   *  @date   2006-03-02
+  */
+  
+  class RelationalTagMgr : public IHvsTagMgr {
+    
+  public:
+
+    /// Destructor
+    virtual ~RelationalTagMgr();
+
+    /// Constructor from a relational database
+    RelationalTagMgr( const RelationalDatabase& db );
+
+    /// Return the type of node (inner/leaf) where this tag name can be used.
+    /// Tag names, except for "HEAD", are case sensitive.
+    /// Throws TagNameNotFound if the tag name does not exist.
+    IHvsNode::Type tagNameScope( const std::string& tagName ) const;
+    
+    /// Does a tag with this name exist (in any node)?
+    /// Tag names, except for "HEAD", are case sensitive.
+    /// Returns true for the reserved tags "" and "HEAD".
+    bool existsTag( const std::string& tagName ) const;
+    
+    /// Return the names of the nodes where the tag is defined.
+    /// Throws ReservedHeadTag for the HEAD tag (defined in all folders). 
+    /// Throws TagNotFound if the tag does not exist.
+    const std::vector<std::string> 
+    taggedNodes( const std::string& tagName ) const;
+
+    /// Find a tag record by nodeId and tag name.
+    /// Throws ReservedHeadTag for the HEAD tag (defined in all folders). 
+    /// Throws TagNotFound if the tag does not exist.
+    /// Starts a transaction.
+    const HvsTagRecord findTagRecord( UInt32 nodeId, 
+                                      const std::string& tagName ) const;
+    
+    /// Find a tag record by nodeId and tag name.
+    /// Throws ReservedHeadTag for the HEAD tag (defined in all folders). 
+    /// Throws TagNotFound if the tag does not exist.
+    /// Does not start a transaction (prefix __)
+    const HvsTagRecord __findTagRecord( UInt32 nodeId, 
+                                        const std::string& tagName ) const;
+    
+    /// Find a tag record by nodeId and tagId.
+    /// Throws ReservedHeadTag for the HEAD tag (defined in all folders). 
+    /// Throws TagNotFound if the tag does not exist.
+    /// Starts a transaction.
+    const HvsTagRecord findTagRecord( UInt32 nodeId, 
+                                      UInt32 tagId ) const;
+    
+    /// Find a tag record by nodeId and tagId.
+    /// Throws ReservedHeadTag for the HEAD tag (defined in all folders). 
+    /// Throws TagNotFound if the tag does not exist.
+    /// Does not start a transaction (prefix __)
+    const HvsTagRecord __findTagRecord( UInt32 nodeId, 
+                                        UInt32 tagId ) const;
+    
+    /// Create a relation between tags for a pair of parent/child nodes.
+    /// Create the parent tag in the parent node if not defined yet.
+    /// Create the child tag in the child node if not defined yet.
+    /// Throws ReservedHeadTag if one of the two tags is a HEAD tag.
+    /// Throws NodeIsSingleVersion if either node does not support versioning.
+    /// Throws NodeRelationNotFound if the nodes are not parent and child.
+    /// Throws TagExists if either tag is already used in another node.
+    /// Throws TagRelationExists if a relation to a child tag already exists.
+    void createTagRelation( UInt32 parentNodeId,
+                            const std::string& parentTagName,
+                            UInt32 childNodeId,
+                            const std::string& childTagName ) const;
+    
+    /// Delete the relation between a parent tag node and a child tag.
+    /// Delete the parent tag if not related to another parent/child tag.
+    /// - NOT Delete the child tag if not related to another tag or IOVs.
+    /// Throws ReservedHeadTag if the parent tag is a HEAD tag.
+    /// Throws TagNotFound if the parent tag does not exist in the parent node.
+    /// Throws TagRelationNotFound if the parent tag has no related child tag.
+    /// - NEW returns the id of the deleted childTagId
+    //void
+    UInt32 deleteTagRelation( UInt32 parentNodeId,
+                              const std::string& parentTagName,
+                              UInt32 childNodeId ) const;
+    
+    /// Delete the relation between a parent tag node and a child tag.
+    /// Delete the parent tag if not related to another parent/child tag.
+    /// Delete the child tag if not related to another tag or IOVs.
+    /// Throws ReservedHeadTag if the parent tag is a HEAD tag.
+    /// Throws TagNotFound if the parent tag does not exist in the parent node.
+    /// Throws TagRelationNotFound if the parent tag has no related child tag.
+    void deleteTagRelation( const RelationalHvsNode& childNode,
+                            const std::string& parentTagName ) const;
+
+    /// Find the child node tag associated to the given parent node tag.
+    /// Throws ReservedHeadTag if the parent tag is a HEAD tag.
+    /// Throws TagNotFound if the parent tag does not exist in the parent node.
+    /// Throws TagRelationNotFound if the parent tag has no related child tag.
+    UInt32 findTagRelation( UInt32 parentNodeId,
+                            const std::string& parentTagName,
+                            UInt32 childNodeId ) const;
+
+    /// Main HVS method: determine the descendant node tag that is related to 
+    /// the given ancestor tag (assumed to be defined in an ancestor node).
+    /// The corresponding ancestor node is also internally determined.
+    /// The ancestor tag is returned if defined directly in the descendant.
+    /// Throws ReservedHeadTag if the ancestor tag is a HEAD tag.
+    /// Throws TagNotFound if the tag does not exist in any inner node.
+    /// Throws NodeRelationNotFound if the inner node where the ancestor tag 
+    /// is defined is not an ancestor of the descendant node.
+    /// Throws TagRelationNotFound if no hierarchical tag relation exists.
+    UInt32 resolveTag( const std::string& ancestorTagName,
+                       UInt32 descendantNodeId ) const;
+    
+    /// Fetch the global tag table row for the given tagName.
+    /// Throws TagNotFound if the tag does not exist in any node.
+    const RelationalTableRow
+    fetchGlobalTagTableRowForNode( const std::string& tagName ) const;
+
+    /// Fetch all global tag table rows for the given nodeId.
+    const std::vector<RelationalTableRow>
+    fetchGlobalTagTableRows( UInt32 nodeId ) const;
+
+    /// Fetch all global tag table rows for the given tagName.
+    /// Throws TagNotFound if the tag does not exist in any node.
+    const std::vector<RelationalTableRow>
+    fetchGlobalTagTableRows( const std::string& tagName ) const;
+
+    /// Fetch the global tag table row for the given nodeId and tagName
+    const RelationalTableRow 
+    fetchGlobalTagTableRow( UInt32 nodeId,
+                            const std::string& tagName ) const;
+
+    /// Fetch the global tag table row for the given nodeId and tagId
+    const RelationalTableRow 
+    fetchGlobalTagTableRow( UInt32 nodeId,
+                            UInt32 tagId ) const;
+
+    /// Insertion time of a tag defined for the given node
+    /// (i.e. the time when the tag was first assigned to the node).
+    const Time tagInsertionTime( const IHvsNode* node,
+                                 const std::string& tagName ) const;
+
+    /// Description of a tag defined for the given node.
+    const std::string tagDescription( const IHvsNode* node,
+                                      const std::string& tagName ) const;
+
+    /// Lock status of a tag defined for the given node.
+    void setTagLockStatus( const IHvsNode* node,
+                           const std::string& tagName,
+                           HvsTagLock::Status tagLockStatus );
+
+    /// Lock status of a tag defined for the given node.
+    HvsTagLock::Status tagLockStatus( const IHvsNode* node,
+                                            const std::string& tagName ) const;
+
+    /// This method does not handle transactions.
+    /// Find a tag in an HVS node, else create it if it does not exist yet.
+    const HvsTagRecord findOrCreateTag( UInt32 nodeId,
+                                        const std::string& tagName ) const;
+    
+    /// TEMPORARY! Also fill the local tag table until it is removed.
+    /// This method does not handle transactions.
+    /// Create a tag in an HVS node.
+    /// Throws TagExists if the tag already exists (in this or another node).
+    const HvsTagRecord createTag( UInt32 nodeId,
+                                  const std::string& tagName,
+                                  const std::string& description = "" ) const;
+    
+    /// TEMPORARY! Remove this method when the local tag table is removed.
+    /// Internal method.
+    const HvsTagRecord createTagAndLocalTag
+    ( UInt32 nodeId,
+      const std::string& tagName,
+      const std::string& description,
+      const std::string& localTagTableName ) const;
+    
+    /// This method does not handle transactions.
+    /// Delete a tag in an HVS node.
+    void deleteTag( UInt32 nodeId,
+                    const std::string& tagName ) const;
+    
+    /// Create a new entry in the global tag table.
+    void insertGlobalTagTableRow( UInt32 nodeId,
+                                  UInt32 tagId,
+                                  const std::string& tagName,
+                                  HvsTagLock::Status tagLockStatus,
+                                  const std::string& tagDescription,
+                                  const std::string& insertionTime ) const;
+
+    /// Delete the row indicated by nodeId and tagId from the global tag table.
+    void deleteGlobalTagTableRow( UInt32 nodeId,
+                                  UInt32 tagId ) const;
+
+    /// Delete all rows for nodeId from the global tag table.
+    /// Returns the number of deleted rows.
+    UInt32 deleteGlobalTagTableRowsForNode( const UInt32 nodeId ) const;
+
+    /// TEMPORARY! The local tag table must be removed!
+    /// Creates a new entry in the given local tag table
+    /// Returns the tag id of the new entry
+    void insertTagTableRow( const std::string& tagTableName,
+                            UInt32 tagId,
+                            const std::string& tagName,
+                            const std::string& description,
+                            const std::string& insertionTime ) const;
+    
+    /// TEMPORARY! The local tag table must be removed!
+    /// Delete the row indicated by tagId from the given local tag table.
+    void deleteTagTableRow( const std::string& tagTableName,
+                            UInt32 tagId ) const;
+
+    /// Does this user tag exist in the tag2tag table?
+    bool existsTagInTag2TagTable( UInt32 nodeId,
+                                        UInt32 tagId ) const;
+        
+    /*
+    /// Does this tag defined in this node have any relation (i.e. does 
+    /// it reference a parent tag or is it referenced by any children)?
+    /// Returns false if this tag does not exist in this node.
+    bool isTagUsed( UInt32 nodeId, 
+                          UInt32 tagId ) const;
+    */
+
+    /// Delete all rows for the given node from the tag2tag table.
+    UInt32 deleteTag2TagTableRowsForNode( const UInt32 nodeId ) const;
+
+    /// Set the description of a tag.
+    /// Throws TagNotFound the tag does not exist.
+    /// Throws an Exception if the description is longer than 255 characters.
+    void setTagDescription( const IHvsNode* node,
+                            const std::string& tagName,
+                            const std::string& description );
+
+
+  protected:
+
+    /// Get the RelationalDatabase reference
+    const RelationalDatabase& db() const { return m_db; }
+
+    /// Get a CORAL MessageStream
+    coral::MessageStream& log() const { return *m_log; }
+
+    /// Get a relational query manager
+    RelationalQueryMgr& queryMgr() const;
+
+    /// Get a relational node manager
+    RelationalNodeMgr& nodeMgr() const;
+
+  private:
+
+    /// Standard constructor is private
+    RelationalTagMgr();
+
+    /// Copy constructor is private
+    RelationalTagMgr( const RelationalTagMgr& rhs );
+
+    /// Assignment operator is private
+    RelationalTagMgr& operator=( const RelationalTagMgr& rhs );
+
+    /// Create a new row in the tag2tag table.
+    void insertTag2TagTableRow( UInt32 parentNodeId,
+                                UInt32 parentTagId,
+                                UInt32 childNodeId,
+                                UInt32 childTagId,
+                                const std::string& insertionTime ) const;
+
+    /// Fetch the given row from the tag2tag table.
+    /// Throw RowNotFound if no row was found.
+    const RelationalTableRow
+    fetchTag2TagTableRow( UInt32 parentNodeId,
+                          UInt32 parentTagId,
+                          UInt32 childNodeId ) const;
+    
+    /// Delete the given row row in the tag2tag table.
+    /// Throw RowNotDeleted if no row was deleted.
+    void deleteTag2TagTableRow( UInt32 parentNodeId,
+                                UInt32 parentTagId,
+                                UInt32 childNodeId ) const;
+    
+  protected:
+
+    /// Reference to the RelationalDatabase
+    const RelationalDatabase& m_db;
+
+    /// CORAL MessageStream
+    std::auto_ptr<coral::MessageStream> m_log;
+
+  };
+  
+}
+
+#endif // RELATIONALCOOL_RELATIONALTAGMGR_H
+
diff --git a/RelationalCool/src/RelationalTagSequence.h b/RelationalCool/src/RelationalTagSequence.h
new file mode 100644
index 000000000..d4b9ad6e2
--- /dev/null
+++ b/RelationalCool/src/RelationalTagSequence.h
@@ -0,0 +1,30 @@
+// $Id: RelationalTagSequence.h,v 1.2 2008-11-04 11:52:11 avalassi Exp $
+#ifndef RELATIONALCOOL_RELATIONALTAGSEQUENCE_H
+#define RELATIONALCOOL_RELATIONALTAGSEQUENCE_H
+
+// Local include files
+#include "RelationalTagTable.h"
+
+namespace cool {  
+  
+  /** @namespace cool::RelationalTagSequence RelationalTagSequence.h
+   *  
+   *  Properties of the COOL "sequence" for local tag ID's in each node.
+   *
+   *  @author Andrea Valassi, Sven A. Schmidt and Marco Clemencic
+   *  @date   2006-03-28
+   */
+  
+  namespace RelationalTagSequence {
+    
+    inline const std::string sequenceName( const std::string& prefix, 
+                                           unsigned nodeId ) 
+    {
+      return RelationalTagTable::defaultTableName( prefix, nodeId ) + "_SEQ";
+    }
+
+  }
+  
+}
+
+#endif // RELATIONALCOOL_RELATIONALTAGSEQUENCE_H
diff --git a/RelationalCool/src/RelationalTagSharedSequenceTable.h b/RelationalCool/src/RelationalTagSharedSequenceTable.h
new file mode 100644
index 000000000..fb127a11c
--- /dev/null
+++ b/RelationalCool/src/RelationalTagSharedSequenceTable.h
@@ -0,0 +1,30 @@
+// $Id: RelationalTagSharedSequenceTable.h,v 1.1 2007-02-01 00:28:33 avalassi Exp $
+#ifndef RELATIONALCOOL_RELATIONALTAGSHAREDSEQUENCETABLE_H
+#define RELATIONALCOOL_RELATIONALTAGSHAREDSEQUENCETABLE_H
+
+// Local include files
+#include "uppercaseString.h"
+
+namespace cool {  
+  
+  /** @namespace cool::RelationalTagSharedSequenceTable RelationalTagSharedSequenceTable.h
+   *  
+   *  Relational schema of the shared 'sequence table' for tag PKs.
+   *
+   *  @author Andrea Valassi
+   *  @date   2007-01-31
+   */
+  
+  namespace RelationalTagSharedSequenceTable 
+  {
+    
+    inline const std::string defaultTableName( const std::string& prefix ) 
+    {
+      // Note: presently the input prefix is uppercase anyway...
+      return uppercaseString(prefix) + "TAGS_SEQ";
+    }
+
+  }
+  
+}
+#endif // RELATIONALCOOL_RELATIONALTAGSHAREDSEQUENCETABLE_H
diff --git a/RelationalCool/src/RelationalTagTable.cpp b/RelationalCool/src/RelationalTagTable.cpp
new file mode 100644
index 000000000..24288c9a9
--- /dev/null
+++ b/RelationalCool/src/RelationalTagTable.cpp
@@ -0,0 +1,32 @@
+// $Id: RelationalTagTable.cpp,v 1.6 2006-09-26 22:44:09 avalassi Exp $
+
+// Include files
+#include "CoolKernel/RecordSpecification.h"
+
+// Local include files
+#include "RelationalTagTable.h"
+
+//-----------------------------------------------------------------------------
+
+const cool::IRecordSpecification& 
+cool::RelationalTagTable::tableSpecification()
+{
+
+  static RecordSpecification spec;
+
+  if ( spec.size() == 0 ){
+    spec.extend( RelationalTagTable::columnNames::tagId,
+                 RelationalTagTable::columnTypeIds::tagId );
+    spec.extend( RelationalTagTable::columnNames::tagName,
+                 RelationalTagTable::columnTypeIds::tagName );
+    spec.extend( RelationalTagTable::columnNames::tagDescription,
+                 RelationalTagTable::columnTypeIds::tagDescription );
+    spec.extend( RelationalTagTable::columnNames::sysInsTime,
+                 RelationalTagTable::columnTypeIds::sysInsTime );
+  }
+  
+  return spec;
+
+}
+
+//-----------------------------------------------------------------------------
diff --git a/RelationalCool/src/RelationalTagTable.h b/RelationalCool/src/RelationalTagTable.h
new file mode 100644
index 000000000..3a01f85b7
--- /dev/null
+++ b/RelationalCool/src/RelationalTagTable.h
@@ -0,0 +1,64 @@
+// $Id: RelationalTagTable.h,v 1.15 2008-11-04 11:52:11 avalassi Exp $
+#ifndef RELATIONALCOOL_RELATIONALTAGTABLE_H
+#define RELATIONALCOOL_RELATIONALTAGTABLE_H
+
+// Local include files
+#include "uppercaseString.h"
+
+namespace cool {  
+  
+  // Forward declarations
+  class IRecordSpecification;
+
+  /** @namespace cool::RelationalTagTable RelationalTagTable.h
+   *  
+   *  Relational schema of the table storing COOL local tags.
+   *
+   *  @author Andrea Valassi, Sven A. Schmidt and Marco Clemencic
+   *  @date   2005-02-05
+   */
+  
+  namespace RelationalTagTable {
+    
+    inline const std::string defaultTableName
+    ( const std::string& prefix, unsigned nodeId ) {
+      char tableName[] = "Fxxxx_TAGS";
+      sprintf( tableName, "F%4.4i_TAGS", nodeId );
+      return uppercaseString( prefix ) + std::string( tableName );
+    }    
+
+    inline const std::string sequenceName( const std::string& tableName ) {
+      return uppercaseString(tableName) + "_SEQ";
+    }    
+    
+    namespace columnNames {
+      static const std::string tagId = "TAG_ID";    
+      static const std::string tagName = "TAG_NAME";
+      static const std::string tagDescription = "TAG_DESCRIPTION";
+      static const std::string sysInsTime = "SYS_INSTIME";    
+    }
+
+    namespace columnTypeIds {
+      static const StorageType::TypeId tagId          = StorageType::UInt32;
+      static const StorageType::TypeId tagName        = StorageType::String255;
+      static const StorageType::TypeId tagDescription = StorageType::String255;
+      // TEMPORARY! Should be Time?
+      static const StorageType::TypeId sysInsTime     = StorageType::String255;
+    }
+
+    namespace columnTypes {
+      typedef UInt32 tagId;
+      typedef String255 tagName;
+      typedef String255 tagDescription;
+      // TEMPORARY! Should be Time?
+      typedef String255 sysInsTime;
+    }
+
+    /// Get the RecordSpecification of the tag table
+    const IRecordSpecification& tableSpecification();
+    
+  }
+
+}
+
+#endif // RELATIONALCOOL_RELATIONALTAGTABLE_H
diff --git a/RelationalCool/src/RelationalTransaction.cpp b/RelationalCool/src/RelationalTransaction.cpp
new file mode 100644
index 000000000..eceb8e97d
--- /dev/null
+++ b/RelationalCool/src/RelationalTransaction.cpp
@@ -0,0 +1,56 @@
+// $Id: RelationalTransaction.cpp,v 1.5 2008-11-04 11:52:11 avalassi Exp $
+
+// Include files
+#include <string>
+
+// Local include files
+#include "IRelationalTransactionMgr.h"
+#include "RelationalTransaction.h"
+
+// Namespace
+using namespace cool;
+
+//-----------------------------------------------------------------------------
+
+RelationalTransaction::RelationalTransaction
+( const boost::shared_ptr<IRelationalTransactionMgr>& transactionMgr,
+  bool readOnly )
+  : m_transactionMgr( transactionMgr ) 
+{
+  std::string msg;
+  if( readOnly ) msg = "read-only transaction";
+  else msg = "read-write transaction";  
+  //m_transactionMgr->log() << "Start a new " << msg << seal::flush;  
+  m_transactionMgr->start( readOnly );
+}
+
+//-----------------------------------------------------------------------------
+
+RelationalTransaction::~RelationalTransaction() 
+{
+  rollback();
+}
+
+//-----------------------------------------------------------------------------
+
+void RelationalTransaction::commit() 
+{
+  //m_transactionMgr->log() << "Commit any open transaction" << seal::flush;
+  if ( m_transactionMgr->isActive() ) {
+    m_transactionMgr->commit();
+  }
+}
+
+//-----------------------------------------------------------------------------
+
+void RelationalTransaction::rollback() 
+{
+  //m_transactionMgr->log() << "Rollback any open transaction" << seal::flush;
+  if ( m_transactionMgr->isActive() ) {
+    m_transactionMgr->rollback();
+  }
+}
+
+//-----------------------------------------------------------------------------
+
+
diff --git a/RelationalCool/src/RelationalTransaction.h b/RelationalCool/src/RelationalTransaction.h
new file mode 100644
index 000000000..f8972376b
--- /dev/null
+++ b/RelationalCool/src/RelationalTransaction.h
@@ -0,0 +1,66 @@
+// $Id: RelationalTransaction.h,v 1.9 2008-11-04 11:52:11 avalassi Exp $
+#ifndef RELATIONALCOOL_RELATIONALTRANSACTION_H 
+#define RELATIONALCOOL_RELATIONALTRANSACTION_H
+
+// Include files
+#include <boost/shared_ptr.hpp>
+
+namespace cool 
+{
+  
+  // Forward declarations
+  class IRelationalTransactionMgr;
+
+  /** @class RelationalTransaction RelationalTransaction.h
+   *  
+   *  Generic implementation of a relational database transaction.
+   *
+   *  A transaction is started when this class is instantiated.
+   *  
+   *  An explicit commit() call is necessary for committing the transaction.
+   *  When the instance goes out of scope, the transaction is rolled back.
+   *
+   *  @author Andrea Valassi and Sven A. Schmidt
+   *  @date   2006-03-10
+   */
+  
+  class RelationalTransaction
+  {
+    
+  public:
+    
+    /// Destructor
+    virtual ~RelationalTransaction();
+    
+    /// Constructor from a IRelationalTransactionMgr
+    RelationalTransaction
+    ( const boost::shared_ptr<IRelationalTransactionMgr>& transactionMgr,
+      bool readOnly = false );
+    
+    /// Commit the transaction
+    void commit();
+    
+    /// Rollback the transaction
+    void rollback();
+    
+  private:
+    
+    /// Standard constructor is private
+    RelationalTransaction();
+    
+    /// Copy constructor is private
+    RelationalTransaction( const RelationalTransaction& rhs );
+    
+    /// Assignment operator is private
+    RelationalTransaction& operator=( const RelationalTransaction& rhs );
+
+  private:
+      
+    /// Handle to the IRelationalTransactionMgr (shared ownership)
+    boost::shared_ptr<IRelationalTransactionMgr> m_transactionMgr;
+    
+  };
+  
+} // namespace
+
+#endif
diff --git a/RelationalCool/src/SealBase_TimeInfo.cpp b/RelationalCool/src/SealBase_TimeInfo.cpp
new file mode 100644
index 000000000..4f4604057
--- /dev/null
+++ b/RelationalCool/src/SealBase_TimeInfo.cpp
@@ -0,0 +1,413 @@
+//<<<<<< INCLUDES                                                       >>>>>>
+
+#include "SealBase_TimeInfo.h"
+
+// ==========================================================================
+// #include "SealBase/sysapi/TimeInfo.h"
+# include <cerrno>
+# ifdef _WIN32
+#  include <windows.h>
+#  include <time.h>
+# else
+#  include <unistd.h>
+#  include <fcntl.h>
+#  include <sys/time.h>
+#  include <time.h>
+#  include <sys/times.h>
+#  include <sys/sysctl.h>
+#  include <sys/resource.h>
+# endif
+# include <limits.h>
+# include <stdio.h>
+# include <string.h>
+# include <stdlib.h>
+
+// A gross hack for linux which lies that CLK_TCK is 1000000 when the
+// values are really 100.
+# ifdef __linux
+#  undef CLK_TCK
+#  define CLK_TCK 100
+# endif
+
+// ==========================================================================
+#include "SealBase_sysapi_Windows.h"
+
+// see also http://high-res-timers.sourceforge.net/; linux kernel
+// (arch/*/kernel/time.c; search get_cycles()); netbsd kernel;
+// http://pdplab.trc.rwcp.or.jp/pdperf/timer-collection/; papi
+// (http://icl.cs.utk.edu/projects/papi); gnu nana.
+
+namespace seal {
+
+bool					TimeInfo::s_initialised = false;
+unsigned				TimeInfo::s_features = 0;
+double					TimeInfo::s_ghz = 1.;
+TimeInfo::NanoSecs			TimeInfo::s_clockBase = 0;
+double					TimeInfo::s_hiResFactor = 1.0;
+
+/** Initialise high-resolution time measurement system.
+
+    Determines the processor speed and/or clock resolution.  You
+    should call this method before calling the cycle counter methods
+    (direct cycle counters or the nanosecond counterparts), or the
+    process time methods.  It is safe to call this more than once; all
+    but the first call are ignored.
+
+    This method (and subsequenty the high-resolution timers) will give
+    incorrect results on multi-processor systems that have processors
+    running at different frequencies.
+
+    Records also the current #time() value such that #elapsedTime()
+    can be used to measure monotonic time if the system has no process
+    time accounting.  If a precise process start time is available,
+    records that as the time base instead of the current #time().
+
+    On systems where other means to determine cpu speed fail, uses a
+    calibration spin loop that takes approximately half a second.  */
+void
+TimeInfo::init (void)
+{
+    if (s_initialised)
+	return;
+
+    // Get process real time base for #elapsedTime() and process
+    // idle time calculations.  Note: we want this to be the first
+    // thing we check, since the other things below may take time
+    // (like the calibration loop).
+    //
+    // Assume first that no start time available from the system:
+    // subtract current #processCpuTime() from current #time()
+    // (assumed to use the same epoch!).  This will work reasonably
+    // well if you call #init() early in the program: hopefully the
+    // process will not have idled for too long during the start-up
+    // (though it may have if there are many shared libraries and it
+    // takes a long time to load them, for example due to loading them
+    // from a networked file system).  Note that #processTimes() may
+    // use s_clockBase but that's fine since s_clockBase is
+    // currently zero anyway.
+    s_clockBase = time () - processCpuTime ();
+
+#ifdef __linux
+    bool haveBase = false;
+    FILE *status = 0;
+    if (! haveBase && (status = fopen ("/proc/self/stat", "r")))
+    {
+	// Linux.  22nd field is process starttime %d; the first is
+	// pid, then process name in parens; the rest of the fields
+	// are simple values separated by spaces.  Skip the process
+	// name by hand since it may contain spaces (it might also
+	// contain parens, so we may still get things wrong).
+	// Hopefully future versions do not change the format...
+	static const int	START_TIME_FIELD = 22;
+	int			field = 1;
+	int			ch = 0;
+	int			start;
+
+	// skip first field
+	while (ch != EOF && ch != ' ')
+	    ch = fgetc (status);
+	++field;
+
+	// skip process name
+	if ((ch = fgetc (status)) != '(')
+	    ch = EOF;
+
+	while (ch != EOF && ch != ')')
+	    ch = fgetc (status);
+
+	if ((ch = fgetc (status)) != ' ')
+	    ch = EOF;
+	++field;
+
+	// skip the other fields in between
+	for ( ; ch != EOF && field < START_TIME_FIELD; ++field)
+	    while ((ch = fgetc (status)) != EOF && ch != ' ')
+		;
+
+	// get the start time
+	if (ch != EOF && fscanf (status, "%d", &start) == 1)
+	{
+	    haveBase = true;
+	    s_clockBase = start * (1e9 / CLK_TCK);
+	}
+
+	// done, ignore the rest
+	fclose (status);
+    }
+#endif // __linux
+
+    // Compute various feature bits
+    s_features |= FEATURE_TIME_EPOCH;
+    s_features |= FEATURE_REAL_COUNT_EPOCH;
+    s_features |= FEATURE_PROCESS_TIMES;
+
+#ifdef __linux
+    // Try to determine CPU speed (linux): look for a "cpu MHz :
+    // <float>" line.
+    if (FILE *cpu = fopen("/proc/cpuinfo", "r"))
+    {
+	char buf [512];
+	while (fgets (buf, sizeof (buf), cpu))
+	    if (!strncmp (buf, "cpu MHz", 7))
+		if (char *colon = strchr (buf, ':'))
+		{
+		    s_features |= FEATURE_EXACT_MHZ;
+		    s_ghz = atof (colon + 1) / 1000.;
+	    	    s_hiResFactor = 1e9 / s_ghz;
+		    break;
+		}
+
+	fclose (cpu);
+    }
+#elif defined _WIN32					// (windows)
+    if (! (s_features & FEATURE_EXACT_MHZ))
+    {
+	size_t				sz;
+	SYSTEM_INFO			si;
+	PROCESSOR_POWER_INFORMATION	*info;
+	LARGE_INTEGER			freq;
+
+	// Determine cpu clock speed.  Assume all cpus run at roughly
+	// the same clock speed and that we only care about the full
+	// clock rate -- not whatever the os might have lowered it to.
+	GetSystemInfo (&si);
+	sz = si.dwNumberOfProcessors * sizeof (PROCESSOR_POWER_INFORMATION);
+	info = new PROCESSOR_POWER_INFORMATION [si.dwNumberOfProcessors];
+	if (CallNtPowerInformation (ProcessorInformation, 0, 0, info, sz) == STATUS_SUCCESS)
+	{
+	    s_features |= FEATURE_EXACT_MHZ;
+	    s_ghz = info [0].MaxMhz / 1e3;
+	}
+	delete [] info;
+
+	// Get cycles/tick multiplier
+	QueryPerformanceFrequency (&freq);
+	s_hiResFactor = freq.QuadPart / (s_ghz * 1e9);
+    }
+#endif
+    // There is no way to get a cpu speed estimate: we can't get real
+    // cpu cycle counts to run a calibration loop, nor can we get the
+    // info from the operation system.  Just say we are running at one
+    // gigahertz as this will translate the system timing information
+    // best to cycles.  It won't be true, but hey, you can extend the
+    // code above to deal better with your system and at least we are
+    // not losing any timing data.  (The setting to a gigahertz
+    // already took place in the s_ghz initialiser.)
+
+    s_initialised = true;
+}
+
+/** Return the processor speed in megahertz as determined by #init().  */
+double
+TimeInfo::mhz (void)
+{ return s_ghz * 1000.; }
+
+/** Return the processor speed in gigahertz as determined by #init(). */
+double
+TimeInfo::ghz (void)
+{ return s_ghz; }
+
+/** Return the system capabilities as determined by #init(). */
+unsigned
+TimeInfo::features (void)
+{ return s_features; }
+
+/** Return high-resolution, monotonic system time in nanoseconds from
+    some system- or process-dependent epoch.  Not dependent on
+    #init().  */
+TimeInfo::NanoSecs
+TimeInfo::time (void)
+{
+#ifndef _WIN32
+    struct tms now; return times (&now) * (1e9 / CLK_TCK);
+#else
+    // Do not use process-relative time: we probably can't measure real
+    // time anyway (only user + system), and even if we can, we'll end
+    // up using each other to calcuate the idle time.  FIXME: WIN32?
+    return clock () * (1e9 / CLOCKS_PER_SEC);
+#endif
+}
+
+/** Return high-resolution monotonic virtual time in nanoseconds: like
+    #realNsecs() except counts time only for this process.
+
+    Like with the real-time counterparts, do not mix #virtualNsecs()
+    and #virtualCycles() assuming you can directly map one to the
+    other.  You can still of course convert cycles to nanosecond
+    estimates using #ghz().
+
+    The return value is monotonically growing time in nanoseconds from
+    some system dependent epoch (possibly the process start-up).
+    Unlike #realNsecs(), monotonicity is guaranteed since time is
+    only counted for this process.  Not all systems can provide this
+    information and always return zero. */
+//TimeInfo::NanoSecs
+//TimeInfo::virtualNsecs (void)
+//{
+//#if HAVE_GETHRTIME					// (solaris)
+//    return gethrvtime ();
+//#elif HAVE_CPU_VIRTUAL_CYCLE_COUNTER
+//    return virtualCycles () / s_ghz;
+//#elif HAVE_CLOCK_GETTIME && HAVE_CLOCK_PROCESS_CPUTIME_ID
+//    // FIXME: CLOCK_THREAD_CPUTIME_ID?
+//    struct timespec now; clock_gettime (CLOCK_PROCESS_CPUTIME_ID, &now);
+//    return (now.tv_sec * 1e9) + now.tv_nsec;
+//#elif HAVE_CLOCK_GETTIME && HAVE_CLOCK_PROFILE		// (hp-ux)
+//    struct timespec now; clock_gettime (CLOCK_PROFILE, &now);
+//    return (now.tv_sec * 1e9) + now.tv_nsec;
+//#elif HAVE_CLOCK_GETTIME && HAVE_CLOCK_PROF		// (darwin)
+//    struct timespec now; clock_gettime (CLOCK_PROF, &now);
+//    return (now.tv_sec * 1e9) + now.tv_nsec;
+//#else
+//    return processCpuTime ();
+//#endif
+//}
+
+/** Return high-resolution monotonic virtual time in CPU cycle ticks:
+    like #realCycles() except counts ticks only for this process.
+
+    Like with the real-time counterparts, do not mix #virtualNsecs()
+    and #virtualCycles() assuming you can directly map one to the
+    other.  You can still of course convert cycles to nanosecond
+    estimates using #ghz().
+
+    The return value is monotonically growing time in CPU cycles from
+    some system dependent epoch (possibly the process startup).
+    Unlike #realCycles(), monotonicity is guaranteed since time is
+    only counted for this process.  Not all systems can provide this
+    information and always return zero. */
+//TimeInfo::NanoTicks
+//TimeInfo::virtualCycles (void)
+//{
+//#if defined CPU_VIRTUAL_CYCLES_ASM			// (gcc on alpha)
+//    unsigned low, high; NanoTicks time; __asm__ volatile (CPU_VIRTUAL_CYCLES_ASM);
+//    return CPU_VIRTUAL_CYCLES_VALUE;
+//#else
+//    // #elif HAVE_PMAPI_H
+//    //   Use the pmapi (aix) calls to get events (see real_cycles).
+//
+//    // #elif HAVE_SYS_PSTAT_H
+//    //   // pst_cpticks seems always empty so use the clock_gettime above
+//    //   pst_status stat; pstat_getproc (&stat, sizeof (stat), 0, getpid());
+//    //   return stat.pst_cpticks;
+//    return (NanoTicks) (virtualNsecs () * s_ghz);
+//#endif
+//}
+
+//////////////////////////////////////////////////////////////////////
+/** Get all process time statistics in one go.
+
+    Sets @a user, @a system and @a real to the amount of CPU time
+    consumed by the process in user mode, on its behalf in the kernel,
+    and in real time, respectively.  The real time is monotonic real
+    time, not system wall clock time.  All times are in nanoseconds.
+
+    Not all systems can provide this information.  On such systems @a
+    real will equal to #elapsedTime() and user and system times will
+    be reported to be zero (resulting all time to be reported to be
+    idle).  */
+void
+TimeInfo::processTimes (NanoSecs &user, NanoSecs &system, NanoSecs &real)
+{
+#ifndef _WIN32
+    // HP-UX has clock_gettime with CLOCK_VIRTUAL (user time) and
+    // CLOCK_PROFILE (user + system time) with nsec accuracy, but to
+    // use them we would have to call clock_gettime twice and then
+    // times to get real time so don't bother and get them all through
+    // times -- AFAIK HP-UX only counts clock ticks anyway.
+    //
+    // Note that on linux and hp-ux s_clockBase is precise.  Other
+    // systems resort to estimated real time based on call to init.
+    struct tms now; real = times (&now) * (1e9 / CLK_TCK);
+    user = now.tms_utime * (1e9/CLK_TCK);
+    system = now.tms_stime * (1e9/CLK_TCK);
+    real -= s_clockBase;
+#else
+    // Real time will be based on an estimate from call to init; the
+    // start time reported by GetProcessTimes is based on system wall
+    // clock and can't be trusted to be monotonic.
+    FILETIME ftdummy, ftkernel, ftuser;
+    GetProcessTimes (GetCurrentProcess (), &ftdummy, &ftdummy,
+		     &ftkernel, &ftuser);
+    NanoSecs now = time ();
+    system = static_cast<NanoSecs>(
+		      (((NanoTicks) ftkernel.dwHighDateTime << 32)
+	           + ftkernel.dwLowDateTime) * 100);
+    user   = static_cast<NanoSecs>(
+		      (((NanoTicks) ftuser.dwHighDateTime << 32)
+	           + ftuser.dwLowDateTime) * 100);
+    real   = now - s_clockBase;
+#endif
+}
+
+/** Get user time consumed by the process in nanoseconds.
+
+    Not all systems can provide this information.  On such systems
+    #processRealTime() will equal to #elapsedTime() and user and
+    system times will be reported to be zero (resulting all time to be
+    reported to be idle).  */
+TimeInfo::NanoSecs
+TimeInfo::processUserTime (void)
+{
+    NanoSecs user, system, real;
+    processTimes (user, system, real);
+    return user;
+}
+
+/** Get system time consumed by the process in nanoseconds.
+
+    Not all systems can provide this information.  On such systems
+    #processRealTime() will equal to #elapsedTime() and user and
+    system times will be reported to be zero (resulting all time to be
+    reported to be idle).  */
+TimeInfo::NanoSecs
+TimeInfo::processSystemTime (void)
+{
+    NanoSecs user, system, real;
+    processTimes (user, system, real);
+    return system;
+}
+
+/** Get process cpu time (user + system) in nanoseconds.
+
+    Not all systems can provide this information.  On such systems
+    #processRealTime() will equal to #elapsedTime() and user and
+    system times will be reported to be zero (resulting all time to be
+    reported to be idle).  */
+TimeInfo::NanoSecs
+TimeInfo::processCpuTime (void)
+{
+    NanoSecs user, system, real;
+    processTimes (user, system, real);
+    return user + system;
+}
+
+/** Get process idle time in nanoseconds.
+
+    Not all systems can provide this information.  On such systems
+    #processRealTime() will equal to #elapsedTime() and user and
+    system times will be reported to be zero (resulting all time to be
+    reported to be idle).  */
+TimeInfo::NanoSecs
+TimeInfo::processIdleTime (void)
+{
+    NanoSecs user, system, real;
+    processTimes (user, system, real);
+    return real - (user + system);
+}
+
+/** Get process real time in nanoseconds.
+
+    The process real time is the time from the process start up to now
+    according to the monotonic system clock.  On some systems this
+    information is not available and equals to #elapsedTime() (that
+    is, an estimate based on the first call to #init()).  */
+TimeInfo::NanoSecs
+TimeInfo::processRealTime (void)
+{
+    NanoSecs user, system, real;
+    processTimes (user, system, real);
+    return real;
+}
+
+} // namespace seal
diff --git a/RelationalCool/src/SealBase_TimeInfo.h b/RelationalCool/src/SealBase_TimeInfo.h
new file mode 100644
index 000000000..1b6d52ade
--- /dev/null
+++ b/RelationalCool/src/SealBase_TimeInfo.h
@@ -0,0 +1,135 @@
+#ifndef SEAL_BASE_TIME_INFO_H
+# define SEAL_BASE_TIME_INFO_H
+
+//<<<<<< INCLUDES                                                       >>>>>>
+
+#include "CoolKernel/types.h"
+
+namespace seal {
+//<<<<<< PUBLIC DEFINES                                                 >>>>>>
+//<<<<<< PUBLIC CONSTANTS                                               >>>>>>
+//<<<<<< PUBLIC TYPES                                                   >>>>>>
+//<<<<<< PUBLIC VARIABLES                                               >>>>>>
+//<<<<<< PUBLIC FUNCTIONS                                               >>>>>>
+//<<<<<< CLASS DECLARATIONS                                             >>>>>>
+
+/** Utilities for monotonically growing high-resolution timers.
+
+    This class provides access to, among other things, virtual and
+    real nanosecond-resolution timing info.  The implementation does
+    its best to use the cheapest, most trustworthy time calculation
+    method: system-provided high-resolution clocks or reading CPU
+    cycle counters directly.  If those are not available, falls back
+    to whatever is likely to produce the best data on the system,
+    usually a system call that promises best resolution.
+
+    On systems that do provide accurate monotonic process-specific or
+    system-wide high-resolution clocks (e.g. POSIX CLOCK_MONOTONIC and
+    CLOCK_PROCESS_CPUTIME_ID clocks), they are used in preference to CPU
+    cycle counters.  If no such clock is available, the monotonicity
+    cannot always be guaranteed:
+     - On a SMP system the process may hop from one processor to
+       another, reading cycle counters on different CPUs.
+     - Most multi-processor systems allow CPUs to be taken offline and
+       put back online at any time.  The cycle counters may be reset
+       or slowed down while the processor is offline.
+     - Advanced power saving features can slow down CPU clock rates or
+       put processes or the whole system to sleep or suspend mode.  In
+       such a case the returned cycle counts may still be accurate but
+       cannot be converted to nanoseconds meaningfully.  At any rate
+       it is usually impossible to find out when this has happened.
+       In fact the clock speed reported by the system may not even be
+       right if something (e.g. the user) has put the system in a
+       power-conserving mode that has slowed down the CPU clock rate
+       -- the CPU clock rate may be wrong for the whole duration of
+       the program.
+
+    In most of these cases it is anybody's guess what the timers read
+    after such an event.  Most likely the readings are not linear.
+
+    The clock ticks are represented as a 64-bit signed integral type
+    (see #NanoTicks).  Nanosecond times are represented as a double
+    (see #NanoSecs).  This accomodates some 290 years worth of cycle
+    counter ticks on a 1GHz CPU.  Cycle counters are usually zeroed on
+    boot, so this should be plenty enough for another few years to
+    come.  Please note however that not all systems provide cycle
+    counters with this many significant bits.  */
+class TimeInfo
+{
+public:
+    // FIXME: feature bits for...?
+    //  - whether real cycles are exact or derived
+    //  - whether real nsecs are exact or derived
+    //  - whether real nsecs were derived from cycles and mhz
+    //  - whether real cycles were derived from nsecs and mhz
+    //  - (the above four for virtual)
+    //  - whether virtual nsecs were derived from process times
+    //  - real/virtual resolution
+    //  - sleep resolution
+
+    /** #feature() bit indicating that #mhz() is the exact value
+	provided by the system (for the cycle counts vs. nsecs).  If
+	not set, the speed was estimated with a calibration loop.  */
+    static const int FEATURE_EXACT_MHZ		= 1;
+
+    /** #feature() bit indicating that #time() may not be
+	process-specific but can have system-wide source.  */
+    static const int FEATURE_TIME_EPOCH		= 2;
+
+    /** #feature() bit indicating that #realCycles() and
+	#realNsecs() can have have system-wide source.  */
+    static const int FEATURE_REAL_COUNT_EPOCH	= 4;
+
+    /** #feature() bit indicating that #processUserTime(),
+	#processSystemTime() and #processCpuTime() are
+	meaningful.  */
+    static const int FEATURE_PROCESS_TIMES	= 16;
+
+    /** Type for nanosecond times. */
+    typedef double		NanoSecs;
+
+    /** Type for cpu cycle counters. */
+    typedef cool::Int64	NanoTicks;
+
+    static void		init (void);
+
+    static double	mhz (void);
+    static double	ghz (void);
+    static unsigned	features ();
+
+    // FIXME: Wall clock/real time support?  This really is #Time.
+    // Would be neat however if we can find out accurate process
+    // start-up time.  Do we need more than just processTimes()?
+    //
+    // POSIX systems with clock_gettime() may provide CLOCK_REALTIME
+    // (= wall), CLOCK_MONOTONIC (= real), CLOCK_PROCESS_CPUTIME_ID (=
+    // virtual) and CLOCK_THREAD_CPUTIME_ID (= virtual thread-specific)
+    // -- check.
+
+    // FIXME: Provide estimate of clock read overhead?
+
+    // high-res monotonic process time consumption
+    static void		processTimes (NanoSecs &user, NanoSecs &system,
+				      NanoSecs &real);
+    static NanoSecs	processUserTime (void);
+    static NanoSecs	processSystemTime (void);
+    static NanoSecs	processCpuTime (void);
+    static NanoSecs	processIdleTime (void);
+    static NanoSecs	processRealTime (void);
+
+    // high-res system timer; not (necessarily) anchored to process
+    // time but guaranteed to be monotonic; usually measures system
+    // time since boot or something like that.
+    static NanoSecs	time (void);
+private:
+    static bool		s_initialised;
+    static unsigned	s_features;
+    static double	s_ghz;
+    static double	s_hiResFactor;
+    static NanoSecs	s_clockBase;
+};
+
+//<<<<<< INLINE PUBLIC FUNCTIONS                                        >>>>>>
+
+} // namespace seal
+#endif // SEAL_BASE_TIME_INFO_H
diff --git a/RelationalCool/src/SealBase_sysapi_TimeInfo.h b/RelationalCool/src/SealBase_sysapi_TimeInfo.h
new file mode 100644
index 000000000..2e6577dd1
--- /dev/null
+++ b/RelationalCool/src/SealBase_sysapi_TimeInfo.h
@@ -0,0 +1,97 @@
+#ifndef SEAL_BASE_SYSAPI_TIME_INFO_H
+# define SEAL_BASE_SYSAPI_TIME_INFO_H
+
+//<<<<<< INCLUDES                                                       >>>>>>
+
+# include "SealBase/config.h"
+# include <cerrno>
+
+// FIXME: use the autoconf logic to include time.h and sys/time.h
+# ifdef _WIN32
+#  include <windows.h>
+#  include <time.h>
+# else
+#  include <unistd.h>
+#  include <fcntl.h>
+#  if TIME_WITH_SYS_TIME
+#   include <sys/time.h>
+#   include <time.h>
+#  else
+#   if HAVE_SYS_TIME_H
+#    include <sys/time.h>
+#   else
+#    include <time.h>
+#   endif
+#  endif
+#  if HAVE_SYS_TIMES_H
+#   include <sys/times.h>
+#  endif
+#  if HAVE_SYS_SYSCTL_H
+#   include <sys/sysctl.h>
+#  endif
+#  if HAVE_SYS_PROCESSOR_H
+#   include <sys/processor.h>
+#  endif
+#  if HAVE_SYS_RESOURCE_H
+#   include <sys/resource.h>
+#  endif
+#  if HAVE_PMAPI_H
+#   include <pmapi.h>
+#  endif
+#  if HAVE_INVENT_H
+#   include <invent.h>
+#  endif
+#  if HAVE_MACH_MACH_TIME_H
+#   include <mach/mach_time.h>
+#  endif
+//   #if HAVE_MACHINE_INLINE_H
+//   # include <machine/inline.h>
+//   #endif
+#  if HAVE_SYS_PSTAT_H
+#   define _PSTAT64
+#   include <sys/param.h>
+#   include <sys/pstat.h>
+#  endif
+#  if HAVE_PROCFS_H
+#   include <procfs.h>
+#  endif
+# endif
+# include <limits.h>
+# include <stdio.h>
+# include <string.h>
+# include <stdlib.h>
+
+//<<<<<< PUBLIC DEFINES                                                 >>>>>>
+
+// A gross hack for linux which lies that CLK_TCK is 1000000 when the
+// values are really 100.
+# ifdef __linux
+#  undef CLK_TCK
+#  define CLK_TCK 100
+# endif
+
+// Define some helper states to simplify the logic
+
+#if HAVE_READ_REAL_TIME || defined CPU_REAL_CYCLES_ASM || HAVE_MACH_MACH_TIME_H || defined _WIN32
+# define HAVE_CPU_REAL_CYCLE_COUNTER 1
+#endif
+
+#if (HAVE_GETHRTIME					\
+     || (HAVE_CLOCK_GETTIME && HAVE_CLOCK_SGI_CYCLE)	\
+     || HAVE_CPU_REAL_CYCLE_COUNTER)
+# define HAVE_CPU_REAL_TIME_COUNTER 1
+#endif
+
+#if defined CPU_VIRTUAL_CYCLES_ASM
+# define HAVE_CPU_VIRTUAL_CYCLE_COUNTER 1
+#endif
+
+//<<<<<< PUBLIC CONSTANTS                                               >>>>>>
+//<<<<<< PUBLIC TYPES                                                   >>>>>>
+//<<<<<< PUBLIC VARIABLES                                               >>>>>>
+//<<<<<< PUBLIC FUNCTIONS                                               >>>>>>
+//<<<<<< CLASS DECLARATIONS                                             >>>>>>
+//<<<<<< INLINE PUBLIC FUNCTIONS                                        >>>>>>
+//<<<<<< INLINE MEMBER FUNCTIONS                                        >>>>>>
+
+#endif // SEAL_BASE_SYSAPI_TIME_INFO_H
diff --git a/RelationalCool/src/SealBase_sysapi_Windows.h b/RelationalCool/src/SealBase_sysapi_Windows.h
new file mode 100644
index 000000000..8628ae24c
--- /dev/null
+++ b/RelationalCool/src/SealBase_sysapi_Windows.h
@@ -0,0 +1,92 @@
+#ifndef SEAL_BASE_SYSAPI_WINDOWS_H
+# define SEAL_BASE_SYSAPI_WINDOWS_H
+
+//<<<<<< INCLUDES                                                       >>>>>>
+
+# ifdef _WIN32
+#if 0
+#  include "SealBase/AutoLoad.h"
+#endif
+#  include <windows.h>
+extern "C" {
+#  include <powrprof.h>
+}
+//#  include <ntdef.h>
+
+//<<<<<< PUBLIC DEFINES                                                 >>>>>>
+
+# define STATUS_SUCCESS ((NTSTATUS) 0x0L)
+
+//# define NtQueryInformationProcess	(*MyNtQueryInformationProcess)
+//# define CallNtPowerInformation		(*MyCallNtPowerInformation)
+//# ifndef GetComputerNameEx
+//#  ifdef UNICODE
+//#   define GetComputerNameExW		(*MyGetComputerNameExW)
+//#  else
+//#   define GetComputerNameExA		(*MyGetComputerNameExA)
+//#  endif
+//# endif
+
+
+//<<<<<< PUBLIC CONSTANTS                                               >>>>>>
+//<<<<<< PUBLIC TYPES                                                   >>>>>>
+
+// FIXME: This stuff lives in ntddk.h/ntddl.h, but apparently doesn't
+// necessarily coexist with windows.h very well.  So add the definitions
+// we need here.
+
+enum PROCESSINFOCLASS {
+    ProcessBasicInformation	= 0,
+    ProcessQuotaLimits		= 1,
+    ProcessVmCounters		= 3,
+    ProcessTimes		= 4
+};
+
+typedef LONG  NTSTATUS;
+typedef ULONG KAFFINITY;
+typedef LONG  KPRIORITY;
+
+struct PROCESS_BASIC_INFORMATION {
+    NTSTATUS	ExitStatus;			// MSDN: PVOID Reserved1;
+    void	*PebBaseAddress;		// MSDN: PPEB  PebBaseAddress;
+    KAFFINITY	AffinityMask;			// MSDN: PVOID Reserved2 [2];
+    KPRIORITY	PriorityMask;			//   -- "" --
+    ULONG	UniqueProcessId;
+    ULONG	InheritedFromUniqueProcessId;	// MSDN: PVOID Reserved3
+};
+
+typedef struct _PROCESSOR_POWER_INFORMATION {  
+    ULONG Number;
+    ULONG MaxMhz;
+    ULONG CurrentMhz;
+    ULONG MhzLimit;
+    ULONG MaxIdleState;
+    ULONG CurrentIdleState;
+} PROCESSOR_POWER_INFORMATION, *PPROCESSOR_POWER_INFORMATION;
+
+//<<<<<< PUBLIC VARIABLES                                               >>>>>>
+//<<<<<< PUBLIC FUNCTIONS                                               >>>>>>
+
+// Work around functions we don't have appropriate headers for, or
+// don't want to force everyone to know which libraries to link against.
+#if 0
+extern seal::AutoLoadLib WinStubNTDLL;
+extern seal::AutoLoadLib WinStubKernel32;
+extern seal::AutoLoadLib WinStubPowrprof;
+extern seal::AutoLoad<NTSTATUS (HANDLE hProcess, PROCESSINFOCLASS pic,
+                      PVOID pi, ULONG len, PULONG plen)>
+    MyNtQueryInformationProcess;
+extern seal::AutoLoad<NTSTATUS (POWER_INFORMATION_LEVEL level, PVOID pin,
+                      ULONG nin, PVOID pout, ULONG nout)>
+    MyCallNtPowerInformation;
+extern seal::AutoLoad<BOOL (COMPUTER_NAME_FORMAT fmt, LPWSTR name, LPDWORD size)>
+    MyGetComputerNameExW;
+extern seal::AutoLoad<BOOL (COMPUTER_NAME_FORMAT fmt, LPSTR name, LPDWORD size)>
+    MyGetComputerNameExA;
+#endif
+//<<<<<< CLASS DECLARATIONS                                             >>>>>>
+//<<<<<< INLINE PUBLIC FUNCTIONS                                        >>>>>>
+//<<<<<< INLINE MEMBER FUNCTIONS                                        >>>>>>
+
+# endif // _WIN32
+#endif // SEAL_BASE_SYSAPI_WINDOWS_H
diff --git a/RelationalCool/src/SealUtil_BaseSealChrono.h b/RelationalCool/src/SealUtil_BaseSealChrono.h
new file mode 100644
index 000000000..059c553a9
--- /dev/null
+++ b/RelationalCool/src/SealUtil_BaseSealChrono.h
@@ -0,0 +1,46 @@
+// Project   : LCG
+// Package   : SealUtil
+// Author    : Lorenzo.MONETA@cern.ch 
+// Created by: moneta  at Tue Sep  2 16:03:40 2003
+
+#ifndef SEALUTIL_BASESEALCHRONO_H
+#define SEALUTIL_BASESEALCHRONO_H 1
+
+
+#include <string>
+#include <vector>
+
+namespace seal
+{ 
+
+/**
+ * Basic class for Seal Chronos used by timers and TimingReport
+ */
+class BaseSealChrono 
+{
+
+public: 
+
+  virtual ~BaseSealChrono() {} 
+
+
+  virtual void start() = 0;
+
+  virtual void stop() = 0;
+
+  virtual std::vector<std::string> names() const = 0;
+
+  virtual std::vector<double> values() const = 0; 
+
+  virtual unsigned int nTypes() const = 0; 
+
+
+  enum UnitType { NANOSECONDS = 0, SECONDS = 1, CLOCKTICKS = 2 };
+  //values is nanoseconds
+
+  virtual unsigned int timeUnit() { return BaseSealChrono::NANOSECONDS; } 
+
+}; 
+
+} // end namespace SealUtil
+#endif 
diff --git a/RelationalCool/src/SealUtil_SealTimer.cpp b/RelationalCool/src/SealUtil_SealTimer.cpp
new file mode 100644
index 000000000..461142e5f
--- /dev/null
+++ b/RelationalCool/src/SealUtil_SealTimer.cpp
@@ -0,0 +1,101 @@
+// Project   : LCG
+// Package   : SealUtil
+// Author    : Lorenzo.MONETA@cern.ch 
+// Created by: moneta  at Fri Aug 29 16:05:03 2003
+
+
+#include "TimingReport.h"
+#include "SealUtil_BaseSealChrono.h"
+#include "SealUtil_SealTimer.h"
+
+namespace seal 
+{ 
+
+  // construct only from string. Use default  SealChrono
+  // 
+
+/*
+  SealTimer::SealTimer(const std::string & itemName, bool printResult, std::ostream & out) :  
+    m_printResult(printResult),
+    m_out(out),
+    m_ownItem(true),
+    m_default_chrono(0)
+{
+  // construct a time report item
+  m_default_chrono = new SealChrono(); 
+  m_item = new TimingItem(*m_default_chrono,itemName);
+  // need to add to TimingReport  
+  start(); 
+}
+*/
+  // construct from string and chrono
+  // (item in this case is local and will be destroyed at the end of the loop )
+  // 
+
+
+  SealTimer::SealTimer(BaseSealChrono & chrono, const std::string & itemName, bool printResult, std::ostream & out) :  
+    m_printResult(printResult),
+    m_out(out),
+    m_ownItem(true),
+    m_default_chrono(0)    
+{
+  // construct a time report item
+  m_item = new TimingItem(chrono,itemName);
+  // need to add to TimingReport  
+  start(); 
+}
+
+  // construct from a time report item 
+
+  SealTimer::SealTimer(TimingItem & item, bool printResult, std::ostream & out) :  
+    m_printResult(printResult), 
+    m_out(out),
+    m_item(&item), 
+    m_ownItem(false), 
+    m_default_chrono(0)
+{
+  start(); 
+}
+
+SealTimer::~SealTimer() 
+{
+  //  A) Throwing an exception from a destructor is a Bad Thing.
+  //  B) The progress_timer destructor does output which may throw.
+  //  C) A timer is usually not critical to the application.
+  //  Therefore, wrap the I/O in a try block, catch and ignore all exceptions.
+  try
+    {	
+      stop();
+      if (m_printResult) cool::TimingReport::printLast(*m_item,m_out); 
+    }
+  catch (...) {}  // eat all exceptions 
+
+  if (m_ownItem) { 
+    if (m_item) delete m_item;
+    if (m_default_chrono) delete m_default_chrono; 
+  }
+}
+
+
+
+void SealTimer::start() { 
+  
+  m_item->chrono().start(); 
+
+}
+
+void SealTimer::stop() { 
+
+  m_item->chrono().stop();
+
+  m_item->accumulate(); 
+  
+}
+
+double SealTimer::elapsed(unsigned int i) { 
+  stop();
+  return m_item->lastValue(i); 
+}
+  
+
+} // end namespace seal
diff --git a/RelationalCool/src/SealUtil_SealTimer.h b/RelationalCool/src/SealUtil_SealTimer.h
new file mode 100644
index 000000000..4ea9f2bb5
--- /dev/null
+++ b/RelationalCool/src/SealUtil_SealTimer.h
@@ -0,0 +1,99 @@
+// Project   : LCG
+// Package   : SealUtil
+// Author    : Lorenzo.MONETA@cern.ch 
+// Created by: moneta  at Fri Aug 29 16:05:03 2003
+
+#ifndef SEALUTIL_SEALTIMER_H
+#define SEALUTIL_SEALTIMER_H 1
+
+
+#include <string>
+#include <iostream>
+
+
+namespace seal
+{ 
+
+  class TimingItem;
+  class BaseSealChrono; 
+
+/**
+ * Seal timer class measuring real time, CPU time (separated as user and system)   
+ * and idle time 
+ * Timer starts when constructed and finish at destructions
+ *
+ * NOTE: This class does not support copying.
+ */
+
+  class SealTimer 
+{
+
+public: 
+  // construct using default chrono (SealBaseChrono) 
+  //SealTimer(const std::string & s = "", bool printResult = true, std::ostream & out = std::cout); 
+  // constructors passing a chrono and a string - no connection to report 
+  SealTimer(BaseSealChrono & c, const std::string & s = "", bool printResult = true, std::ostream & out = std::cout); 
+  // construct from item 
+  SealTimer(TimingItem & item, bool printResult = false, std::ostream & out = std::cout); 
+  virtual ~SealTimer(); 
+
+ private:
+  /// copying unimplemented in this class.  
+  SealTimer(const SealTimer&) : m_out (std::cout) { }
+  /// copying unimplemented in this class.  
+  SealTimer & operator = (const SealTimer & rhs) { 
+    if (this == &rhs) return *this;  // time saving self-test     
+    return *this;
+  }
+
+  public : 
+
+  /*
+   * start measuring time. Normally not need to call, it is called automatically 
+   *  in constructors 
+   */ 
+
+  void start(); 
+
+  /*
+   * stop timer and calculate difference from start. 
+   * called automatically in destructor
+   */
+
+  void stop(); 
+
+  /*
+   *  print timing result. Called also automatically from destructors 
+   */ 
+
+  void print(); 
+
+  /*
+   * return elapsed time since start. 
+   * Index i correspond to type of time identified 
+   *  according to the chrono used 
+   */
+ 
+  double elapsed(unsigned int i = 0); 
+
+ protected: 
+
+
+  private : 
+
+    // initial times in nano-seconds
+
+    
+    bool m_printResult; 
+    std::ostream & m_out; 
+
+    TimingItem * m_item;
+    bool m_ownItem; 
+    BaseSealChrono * m_default_chrono; 
+
+}; 
+
+
+
+} // end namespace SealUtil
+#endif 
diff --git a/RelationalCool/src/SealUtil_TimingItem.cpp b/RelationalCool/src/SealUtil_TimingItem.cpp
new file mode 100644
index 000000000..a4a7719b9
--- /dev/null
+++ b/RelationalCool/src/SealUtil_TimingItem.cpp
@@ -0,0 +1,101 @@
+// Project   : LCG
+// Package   : SealUtil
+// Author    : Lorenzo.MONETA@cern.ch 
+// Created by: moneta  at Tue Sep  2 14:06:56 2003
+
+
+#include "SealUtil_TimingItem.h"
+
+#include <math.h>
+#include <assert.h>
+
+
+namespace seal
+{ 
+
+
+TimingItem::TimingItem(Chrono & c, const std::string & name) : 
+  m_name(name), 
+  m_counter(0),
+  m_chrono(c)
+{
+  m_convScale = 1;
+  if (c.timeUnit() == BaseSealChrono::CLOCKTICKS ) {  
+    m_unit = "ticks";
+  } 
+  else { 	  
+    m_unit = "s"; 
+    if (c.timeUnit() == BaseSealChrono::NANOSECONDS ) { 
+      m_convScale = 1.0/static_cast<double>(nsec_per_sec);
+    } 
+  }
+  m_sumV.resize(numberOfTypes()); 	
+  m_sumV2.resize(numberOfTypes()); 	
+
+}
+
+  
+TimingItem::TimingItem(const TimingItem& other) : m_chrono(other.m_chrono)
+{
+}
+
+TimingItem & TimingItem::operator = (const TimingItem &rhs) 
+{
+   if (this == &rhs) return *this;  // time saving self-test
+
+   return *this;
+}
+
+
+
+// TimingItem class 
+
+// collect statistics 
+void TimingItem::accumulate() { 
+  m_counter++;
+  std::vector<double> v = m_chrono.values(); 
+  assert(v.size() == m_sumV.size() ); 
+  assert(m_sumV.size() == m_sumV2.size() ); 
+  
+  for (unsigned int i = 0; i < numberOfTypes(); ++i) { 
+    // assume implicit conversion from time results to doubles 
+    m_sumV[i]  += v[i];
+    m_sumV2[i] += v[i]*v[i]; 
+  }
+}
+
+std::string TimingItem::timeType(unsigned int i ) const { 
+  if ( i < numberOfTypes() ) 
+    return m_chrono.names()[i];
+  
+  return std::string(""); 
+}
+ 
+double TimingItem::mean(unsigned int i) const{ 
+  if (m_counter > 0 && i < numberOfTypes() ) 
+    return (m_sumV[i]/m_counter)*m_convScale; 
+
+  return 0; 
+}
+
+double TimingItem::rms(unsigned int i) const{ 
+  if (m_counter > 0 && i < numberOfTypes() ) { 
+    double rms2 =  ( m_sumV2[i] - m_sumV[i]*m_sumV[i]/m_counter )/m_counter;
+    if (rms2 < 0) return 0; 
+    return sqrt( rms2  )*m_convScale; 
+  }
+  return 0; 
+}
+
+double TimingItem::lastValue(unsigned int i) const { 
+
+  if ( i < numberOfTypes()  ) 
+    return m_chrono.values()[i]*m_convScale;  
+
+  return 0; 
+}
+
+
+
+
+} // end namespace SealUtil
diff --git a/RelationalCool/src/SealUtil_TimingItem.h b/RelationalCool/src/SealUtil_TimingItem.h
new file mode 100644
index 000000000..b5437e516
--- /dev/null
+++ b/RelationalCool/src/SealUtil_TimingItem.h
@@ -0,0 +1,92 @@
+// Project   : LCG
+// Package   : SealUtil
+// Author    : Lorenzo.MONETA@cern.ch 
+// Created by: moneta  at Tue Sep  2 14:06:56 2003
+
+#ifndef SEALUTIL_TIMINGITEM_H
+#define SEALUTIL_TIMINGITEM_H 1
+
+#include "SealUtil_BaseSealChrono.h"
+
+
+namespace seal 
+{ 
+
+/**
+ * class used to collect the timing result and statistics for a specific item 
+ * Used by the TimingReport 
+ * This class does not support copying.
+ */
+
+
+//template <class Chrono=SealChrono> class TimingItem;  
+
+
+class TimingItem 
+{
+
+
+
+  static const long nsec_per_sec = 1000000000;  // nanosec in one second
+  
+  typedef BaseSealChrono Chrono; 
+
+public: 
+
+  TimingItem(Chrono & c, const std::string & name);  
+
+  ~TimingItem() {/* no op */ } 
+
+private:
+  /// copying unimplemented in this class.  
+  TimingItem(const TimingItem &); 
+  /// copying unimplemented in this class.  
+  TimingItem & operator = (const TimingItem &); 
+
+public: 
+
+ 
+     
+  void accumulate(); 
+
+
+  std::string name() { return m_name; }
+  
+  std::string unit() { return m_unit; } 
+  
+  Chrono & chrono() { return m_chrono; } 
+  
+  unsigned int numberOfMeasurements() const { return m_counter; }
+  
+  unsigned int numberOfTypes() const { return  m_chrono.nTypes(); } 
+  
+  std::string timeType(unsigned int i = 0) const; 
+  
+  // unit here are doubles indicating the number of second 
+  
+  double mean(unsigned int i = 0) const;  
+  
+  double rms(unsigned int i = 0)  const;
+
+  double lastValue(unsigned int i=0) const;  
+
+ 
+  private : 
+
+    std::string m_name; 
+  std::string m_unit;
+  unsigned int m_counter; 
+  std::vector<double> m_sumV; 
+  std::vector<double> m_sumV2; 
+  // by default results are in seconds 
+  // conversion from nanosec to seconds
+  double m_convScale; 
+  
+  Chrono & m_chrono; 
+
+
+
+}; 
+
+} // end namespace SealUtil
+#endif 
diff --git a/RelationalCool/src/SimpleObject.h b/RelationalCool/src/SimpleObject.h
new file mode 100644
index 000000000..bba845349
--- /dev/null
+++ b/RelationalCool/src/SimpleObject.h
@@ -0,0 +1,128 @@
+// $Id: SimpleObject.h,v 1.9 2008-11-04 11:52:11 avalassi Exp $
+#ifndef RELATIONALCOOL_SIMPLEOBJECT_H
+#define RELATIONALCOOL_SIMPLEOBJECT_H
+
+// Include files
+#include <boost/shared_ptr.hpp>
+#include <vector>
+#include "CoolKernel/ValidityKey.h"
+
+namespace cool {
+	
+  // Forward declarations
+  class SimpleObject;
+  typedef std::vector<SimpleObject> SOVector;
+  typedef std::vector<SimpleObject>::const_iterator SOIterator;
+  std::ostream &operator<<( std::ostream& s, const SimpleObject& o );
+
+	/** SimpleObject.h
+   *
+   * A basic object 'shell' used for lightweight object comparison/handling.
+   * It encapsulated the key attributes of an object without payload.
+   *  
+   * @author Sven A. Schmidt and Andrea Valassi
+   * @date 2005-02-11
+   */
+	
+  class SimpleObject 
+  {
+  public:
+    
+    unsigned int objectId;
+    ChannelId    channelId;
+    ValidityKey  since;
+    ValidityKey  until;
+    
+    SimpleObject( unsigned int anObjectId, 
+                  const ChannelId& aChannelId,
+                  const ValidityKey& aSince, 
+                  const ValidityKey& anUntil ) 
+    {
+      objectId = anObjectId; 
+      channelId = aChannelId;
+      since = aSince; 
+      until = anUntil; 
+    }
+    
+    /// Only consider the object id in comparison
+    bool operator==( const SimpleObject& rhs ) const 
+    {
+      return objectId == rhs.objectId; 
+    }
+
+    SOVector intersect( const SOVector& objects ) const 
+    {
+      SOVector res;
+      for ( SOIterator obj = objects.begin(); obj != objects.end(); ++obj ) {
+        if ( overlaps( *obj ) ) res.push_back( *obj );
+      }
+      return res;
+    }
+    
+    bool overlaps( const SimpleObject& obj ) const 
+    {
+      if ( channelId != obj.channelId ) {
+        return false;
+      } else {
+        return ( since <= obj.since && obj.since < until )
+            || ( obj.since <= since && since < obj.until );
+      }
+    }
+
+    SOVector filter( const SimpleObject& obj ) const 
+    {
+      SOVector res;
+      if ( ! overlaps( obj ) ) {
+        res.push_back( obj );
+        return res;
+      }
+      if ( obj.since < since ) 
+        res.push_back
+          ( SimpleObject( obj.objectId, obj.channelId, obj.since, since ) );
+      if ( obj.until > until )
+        res.push_back
+          ( SimpleObject( obj.objectId, obj.channelId, until, obj.until ) );
+      return res;
+    }
+    
+    SOVector visibleThrough( const SOVector& objects ) const 
+    {
+      SOVector res( 1, *this );
+      SOVector tmp1, tmp2;
+      for ( SOIterator obj = objects.begin(); obj != objects.end(); ++obj ) {
+        tmp1.clear();
+        for ( SOIterator source = res.begin(); 
+              source != res.end(); 
+              ++source ) {
+          tmp2 = obj->filter( *source );
+          tmp1.insert( tmp1.end(), tmp2.begin(), tmp2.end() );
+        }
+        res.clear();
+        res.insert( res.end(), tmp1.begin(), tmp1.end() );
+      }
+      return res;
+    }
+    
+  };  
+
+  /// Streamer for SimpleObject objects
+  inline std::ostream &operator<<( std::ostream& s, const SimpleObject& o ) 
+  {
+    s << o.objectId << ", " << o.channelId
+      << " [" << o.since << "," << o.until << "]";
+    return s;
+  }
+  
+  /// Less than comparison functor to compare SimpleObject since
+  struct lt_since 
+    : public std::binary_function<SimpleObject, SimpleObject, bool> 
+  {
+    bool operator()( const SimpleObject& lhs,
+                     const SimpleObject& rhs ) const { 
+      return ( lhs.since < rhs.since  ); }
+  };
+  
+} // namespace
+
+#endif
+
diff --git a/RelationalCool/src/TimingReport.cpp b/RelationalCool/src/TimingReport.cpp
new file mode 100644
index 000000000..cbc29798b
--- /dev/null
+++ b/RelationalCool/src/TimingReport.cpp
@@ -0,0 +1,126 @@
+// $Id: TimingReport.cpp,v 1.9 2008-04-11 10:02:46 marcocle Exp $
+
+#include "TimingReport.h"
+
+#include <math.h>
+
+#include <iostream>
+
+namespace cool
+{
+
+  TimingReport::~TimingReport() 
+  {
+    // delete items
+    /*
+      for (std::vector<TimingItem *>::iterator 
+      itr = m_items.begin(); itr != m_items.end(); ++itr) 
+      delete *itr; 
+    */
+    
+    m_items.clear(); 
+
+    // delete chronos - fix bug #9253 (memory leak!)
+    for ( std::vector< CoolChrono* >::iterator 
+            itr = m_chronos.begin(); itr != m_chronos.end(); ++itr ) 
+      delete *itr; 
+
+  }
+  
+  
+  // print reports
+  void TimingReport::printLast( seal::TimingItem& item, std::ostream& out ) 
+  { 
+    out << "Timing in " << item.name() << " : "; 
+    for (unsigned int i = 0; i < item.numberOfTypes(); ++i)  
+      out << item.timeType(i) << " = " << item.lastValue(i) 
+          << " (" << item.unit() << "), ";
+    out << std::endl; 
+  }
+  
+  // print results for all timings
+  /*
+  void TimingReport::dumpFull(std::ostream & out) 
+  { 
+    out << ">>>>>>    Timing Results  <<<<<<<<<< " << std::endl; 
+    for (MapItems::iterator itr = m_items.begin(); 
+         itr != m_items.end(); ++itr) { 
+      STItem  item = itr->second; 
+      out << "----- " << item->name() << " : " 
+          << "       (  n = " << item->numberOfMeasurements() << "  )" 
+          << std::endl; 
+      for (unsigned int i = 0; i < item->numberOfTypes(); ++i) { 
+        out << item->timeType(i) << " :  mean = " << item->mean(i) 
+            << " (" << item->unit() << "), " 
+            << " RMS = " << item->rms(i) <<   " (" << item->unit() << ")" 
+            << std::endl; 
+      }
+      out << std::endl; 
+    }
+  }
+  */
+  
+  void TimingReport::dumpFull(std::ostream & out) 
+  { 
+    out << ">>>>>>    Timing Results  <<<<<<<<<< " << std::endl; 
+    for (MapItems::iterator itr = m_items.begin(); 
+         itr != m_items.end(); ++itr) 
+    { 
+      STItem  item = itr->second; 
+      char formattedOut1[] = 
+        "System Time: 123456.000 +/- 123456.000 s      (n=1234567890)";
+      sprintf( formattedOut1, "%-40.40s      (n=%10.1d)", 
+               item->name().c_str(), item->numberOfMeasurements() );
+      out << "----- " << formattedOut1 << std::endl;
+      for (unsigned int i = 0; i < item->numberOfTypes(); ++i) { 
+        if ( item->timeType(i) != "Cpu Time" ) {
+          /*
+            out << item->timeType(i) << " :  mean = " 
+            << item->mean(i) << " (" << item->unit() << "), " 
+            << " RMS = " << item->rms(i) 
+            <<   " (" << item->unit() << ")" << std::endl;
+          */
+          /*
+            out << item->timeType(i) << " :  total = " 
+            << item->mean(i)*item->numberOfMeasurements() 
+            << " (" << item->unit() << ") " 
+            << " +/- " << item->rms(i)*sqrt(item->numberOfMeasurements())  
+            <<   " (" << item->unit() << ")" << std::endl; 
+          */
+          char formattedOut2[] = "System Time: 123456.000 +/- 123456.000";
+          sprintf( formattedOut2, 
+                   "%-11.11s: %10.3f +/- %10.3f",
+                   (item->timeType(i)).c_str(),
+                   item->mean(i)*item->numberOfMeasurements(),
+                   item->mean(i)*sqrt((double)item->numberOfMeasurements()) );
+          if ( item->timeType(i) != "VmSize incr" && 
+               item->timeType(i) != "VmRSS incr" ) {
+            out << "Total " << formattedOut2 << " " << item->unit() 
+                << std::endl;
+          } else {
+            // WARNING! Memory monitoring slows down performance by factors!
+            if ( getenv ( "COOL_COOLCHRONO_PROCMEMORY" ) ) {
+              out << "Total " << formattedOut2 << " MB" << std::endl;
+            }        
+          }        
+        }
+      }
+      //out << std::endl; 
+    }
+  }
+  
+  void TimingReport::dump(std::ostream & out) 
+  { 
+    for (MapItems::iterator itr = m_items.begin(); 
+         itr != m_items.end(); ++itr) { 
+      STItem  item = itr->second; 
+      out << item->name() << ", n = " << item->numberOfMeasurements() << "  ";
+      for (unsigned int i = 0; i < item->numberOfTypes(); ++i) { 
+        out << item->timeType(i) << " = " << item->mean(i) << " +/- " 
+            << item->rms(i) <<   " (" << item->unit() << ")   "; 
+      }
+      out << std::endl; 
+    }
+  }
+
+}
diff --git a/RelationalCool/src/TimingReport.h b/RelationalCool/src/TimingReport.h
new file mode 100644
index 000000000..a1a9a624e
--- /dev/null
+++ b/RelationalCool/src/TimingReport.h
@@ -0,0 +1,110 @@
+// $Id: TimingReport.h,v 1.6 2008-04-11 10:02:46 marcocle Exp $
+#ifndef RELATIONALCOOL_TIMINGREPORT_H
+#define RELATIONALCOOL_TIMINGREPORT_H 1
+
+// AV Copied from SealUtils
+#include <boost/shared_ptr.hpp>
+#include <iostream>
+#include <string>
+#include <map>
+#include "CoolChrono.h"
+#include "SealUtil_TimingItem.h"
+
+//using namespace seal;
+
+namespace cool
+{ 
+
+  /**
+   * class managing the various timers 
+   * an internal class TimingItem contains the result of the timers 
+   * 
+   * 
+   * This class does not support copying.
+   */
+  
+  class TimingReport 
+  {
+    
+  public: 
+    
+    TimingReport() {} 
+    
+    virtual ~TimingReport();
+    
+  private:
+    
+    /// copying unimplemented in this class.
+    TimingReport( const TimingReport& ) {}
+    
+    /// copying unimplemented in this class.  
+    TimingReport& operator=( const TimingReport& rhs )
+    { 
+      if (this == &rhs) return *this;  // time saving self-test
+      return *this;
+    }
+    
+  public: 
+    
+    /*
+    // generic implemetation  
+    template<class Chrono> seal::TimingItem& item( const std::string& name ) 
+    { 
+      MapItems::iterator itr = m_items.find(name); 
+      // item not found create a new one
+      if (itr == m_items.end() ) { 
+        // create a new Chrono
+        Chrono * c = new Chrono();  
+        STItem  theItem(new seal::TimingItem(*c,name) ); 
+        m_items.insert(std::make_pair(name,theItem) ); 
+        return *theItem; 
+      }
+      else {
+        STItem theItem = itr->second;
+        return *theItem;
+      }   
+    }
+    */
+    
+    // default implementation based on  CoolChrono
+    seal::TimingItem& item( const std::string& name ) 
+    { 
+      MapItems::iterator itr = m_items.find(name); 
+      // item not found create a new one
+      if (itr == m_items.end() ) { 
+        // create a new CoolChrono
+        CoolChrono* c = new CoolChrono();  
+        m_chronos.push_back( c );
+        STItem theItem( new seal::TimingItem( *c, name ) ); 
+        m_items.insert(std::make_pair(name,theItem) ); 
+        return *theItem; 
+      }
+      else {
+        STItem theItem = itr->second;
+        return *theItem;
+      }   
+    }
+    
+    // dump compact info
+    void dump( std::ostream& os = std::cout );
+    
+    // dump in a more extended format 
+    void dumpFull( std::ostream& os = std::cout );
+    
+    // print reports
+    static 
+    void printLast( seal::TimingItem& item, std::ostream& os = std::cout );
+    
+  private: 
+    
+    std::vector<CoolChrono*> m_chronos;
+
+    typedef boost::shared_ptr<seal::TimingItem > STItem; 
+    typedef std::map<std::string, STItem> MapItems;
+    MapItems m_items; 
+    
+  };
+  
+}
+
+#endif 
diff --git a/RelationalCool/src/TimingReportMgr.cpp b/RelationalCool/src/TimingReportMgr.cpp
new file mode 100644
index 000000000..087ae9b24
--- /dev/null
+++ b/RelationalCool/src/TimingReportMgr.cpp
@@ -0,0 +1,118 @@
+// $Id: TimingReportMgr.cpp,v 1.2 2008-11-04 11:52:11 avalassi Exp $
+
+// Include files 
+#include "CoolKernel/Exception.h"
+
+// Local include files 
+#include "TimingReportMgr.h"
+
+// Namespace
+using namespace cool;
+
+//-----------------------------------------------------------------------------
+
+bool TimingReportMgr::isActive()
+{
+  if ( pTimingReport() ) return true;
+  else return false;
+}
+
+//-----------------------------------------------------------------------------
+
+void TimingReportMgr::initialize()
+{
+  if ( pTimingReport() )
+  {
+    throw Exception
+      ( "TimingReportMgr already initialized", "TimingReportMgr" );
+  }
+  else
+  {
+    pTimingReport() = new TimingReport();
+  }
+}
+
+//-----------------------------------------------------------------------------
+
+void TimingReportMgr::finalize()
+{
+  if ( pTimingReport() ) 
+  {
+    pTimingReport()->dumpFull();
+    delete pTimingReport();
+    pTimingReport() = 0;
+  }
+  else 
+  {
+    throw Exception
+      ( "TimingReportMgr not initialized", "TimingReportMgr" );
+  }
+}
+
+//-----------------------------------------------------------------------------
+
+TimingReport& TimingReportMgr::timingReport()
+{
+  if ( pTimingReport() ) 
+  {
+    return *pTimingReport();
+  }
+  else 
+  {
+    throw Exception
+      ( "TimingReportMgr not initialized", "TimingReportMgr" );
+  }
+}
+
+//-----------------------------------------------------------------------------
+
+TimingReport*& TimingReportMgr::pTimingReport()
+{
+  static TimingReport* s_report = 0;
+  return s_report;
+}
+
+//-----------------------------------------------------------------------------
+
+void TimingReportMgr::startTimer( const std::string& name )
+{
+  if ( timerMap().find( name ) != timerMap().end() )
+  {
+    throw Exception
+      ( "Timer already started for item " + name, "TimingReportMgr" );
+  }
+  else
+  {
+    timerMap()[name] = new seal::SealTimer( timingReport().item( name ) );
+  }
+}
+
+//-----------------------------------------------------------------------------
+
+void TimingReportMgr::stopTimer( const std::string& name )
+{
+  if ( timerMap().find( name ) == timerMap().end() )
+  {
+    throw Exception
+      ( "Timer not started for item " + name, "TimingReportMgr" );
+  }
+  else 
+  {
+    if ( timerMap()[name] ) {
+      delete timerMap()[name];
+      timerMap()[name] = 0;
+    }
+    timerMap().erase( timerMap().find( name ) );
+  }
+}
+
+//-----------------------------------------------------------------------------
+
+TimingReportMgr::TimerMap& TimingReportMgr::timerMap()
+{
+  static TimerMap s_map;
+  return s_map;
+}
+
+//-----------------------------------------------------------------------------
+
diff --git a/RelationalCool/src/TimingReportMgr.h b/RelationalCool/src/TimingReportMgr.h
new file mode 100644
index 000000000..30f0c3252
--- /dev/null
+++ b/RelationalCool/src/TimingReportMgr.h
@@ -0,0 +1,48 @@
+// $Id: TimingReportMgr.h,v 1.3 2008-11-04 11:52:11 avalassi Exp $
+#ifndef RELATIONALCOOL_TIMINGREPORTMGR_H 
+#define RELATIONALCOOL_TIMINGREPORTMGR_H 1
+
+// Include files
+#include <map>
+#include "SealUtil_SealTimer.h"
+
+// Local include files
+#include "TimingReport.h"
+
+namespace cool 
+{
+
+  class TimingReportMgr {
+    
+  public: 
+
+    static bool isActive();
+
+    static void initialize();
+    static void finalize();
+
+    static void startTimer( const std::string& name );
+    static void stopTimer( const std::string& name );
+
+  private:
+    
+    TimingReportMgr( );
+    TimingReportMgr( const TimingReportMgr& rhs );
+    TimingReportMgr& operator= ( const TimingReportMgr& rhs );
+    virtual ~TimingReportMgr( );
+    
+  private:
+
+    //static TimingReport* s_report; // Link fails
+    static TimingReport*& pTimingReport();
+
+    static TimingReport& timingReport();
+
+    typedef std::map< std::string, seal::SealTimer* > TimerMap;
+    static TimerMap& timerMap();
+
+  };
+
+}
+
+#endif // RELATIONALCOOL_TIMINGREPORTMGR_H
diff --git a/RelationalCool/src/VersionInfo.h b/RelationalCool/src/VersionInfo.h
new file mode 100644
index 000000000..539b2e68b
--- /dev/null
+++ b/RelationalCool/src/VersionInfo.h
@@ -0,0 +1,28 @@
+// $Id: VersionInfo.h,v 1.38 2009-01-06 12:36:25 avalassi Exp $
+#ifndef RELATIONALCOOL_VERSION_INFO_H
+#define RELATIONALCOOL_VERSION_INFO_H
+
+// Include files
+#include "VersionNumber.h"
+
+namespace cool {
+	
+	/** VersionInfo.h
+   *
+   * Code version number and schema version number for the current release.
+   *  
+   * @author Sven A. Schmidt, Andrea Valassi and Marco Clemencic
+   * @date 2005-04-25
+   */
+	
+  namespace VersionInfo 
+  {
+    const VersionNumber release = "2.7.0";
+    const VersionNumber schemaVersion = "2.0.0";
+    const std::string schemaEvolutionPrefix = "SE_2_2_0_";
+  }
+
+} // namespace
+
+#endif
+
diff --git a/RelationalCool/src/VersionNumber.h b/RelationalCool/src/VersionNumber.h
new file mode 100644
index 000000000..0e00c9a59
--- /dev/null
+++ b/RelationalCool/src/VersionNumber.h
@@ -0,0 +1,116 @@
+// $Id: VersionNumber.h,v 1.6 2008-11-04 11:52:11 avalassi Exp $
+#ifndef VERSIONNUMBER_H 
+#define VERSIONNUMBER_H 1
+
+// Include files
+#include <string>
+#include <sstream>
+#include <stdexcept>
+
+// forward declarations
+class VersionNumber;
+std::ostream& operator<< ( std::ostream& str, const VersionNumber& vers );
+
+/** @class VersionNumber VersionNumber.h
+ *  
+ *  Class used to handle version numbers of format "x.y.z".
+ *  There is no strict format check.
+ * 
+ *  @author Marco Clemencic
+ *  @date   2006-11-09
+ */
+class VersionNumber {
+
+public: 
+
+  /// Standard constructor
+  inline VersionNumber( const std::string &vers ){ initialize(vers); }
+
+  /// Standard constructor (from char array)
+  inline VersionNumber( const char *vers ){ initialize(vers); }
+
+  // accessors
+
+  inline int majorVersion() const { return m_major; }
+  inline int minorVersion() const { return m_minor; }
+  inline int patchVersion() const { return m_patch; }
+
+  // comparison operators
+
+  inline bool operator== (const VersionNumber& rhs) const
+  {
+    return 
+      ( majorVersion() == rhs.majorVersion() ) 
+      && ( minorVersion() == rhs.minorVersion() ) 
+      && ( patchVersion() == rhs.patchVersion() );
+  }
+  
+  inline bool operator!= (const VersionNumber& rhs) const
+  {
+    return ! (*this == rhs );
+  }
+  
+  inline bool operator< (const VersionNumber& rhs) const
+  {
+    return
+      ( majorVersion() < rhs.majorVersion() )
+      || ( ( majorVersion() == rhs.majorVersion() ) 
+           && ( minorVersion() < rhs.minorVersion() ) )
+      || ( ( majorVersion() == rhs.majorVersion() ) 
+           && ( minorVersion() == rhs.minorVersion() ) 
+           && ( patchVersion() < rhs.patchVersion() ) );
+  }
+  
+  inline bool operator<= (const VersionNumber& rhs) const
+  {
+    return *this == rhs || *this < rhs;
+  }
+  
+  inline bool operator> (const VersionNumber& rhs) const 
+  {
+    return !( *this <= rhs );
+  }
+
+  inline bool operator>= (const VersionNumber& rhs) const
+  {
+    return *this == rhs || *this > rhs;
+  }
+  
+  /// Conversion to string
+  inline operator std::string () const 
+  {
+    std::ostringstream s;
+    s << *this;
+    return s.str();
+  }
+
+private:
+  
+  void initialize(const std::string &vers)
+  {
+    m_major = m_minor = m_patch = -1;
+   
+    std::istringstream s(vers);
+    char sep;
+    s >> m_major >> sep >> m_minor >> sep >> m_patch;
+    if ( m_major < 0 || m_minor < 0 || m_patch < 0 ){
+      throw std::runtime_error("Bad version string format: '"+vers+"'");
+    }
+  }
+
+private:
+
+  int m_major;
+  int m_minor;
+  int m_patch;
+
+};
+
+inline std::ostream& operator<< ( std::ostream& str, const VersionNumber& vers)
+{
+  return str << vers.majorVersion() 
+             << '.' << vers.minorVersion() 
+             << '.' << vers.patchVersion();
+}
+
+#endif // VERSIONNUMBER_H
diff --git a/RelationalCool/src/attributeListToString.h b/RelationalCool/src/attributeListToString.h
new file mode 100644
index 000000000..c57aac010
--- /dev/null
+++ b/RelationalCool/src/attributeListToString.h
@@ -0,0 +1,23 @@
+// $Id: attributeListToString.h,v 1.3 2005-12-09 12:10:51 marcocle Exp $
+#ifndef RELATIONALCOOL_ATTRIBUTELISTTOSTRING_H 
+#define RELATIONALCOOL_ATTRIBUTELISTTOSTRING_H
+
+// Include files
+#include <sstream>
+#include <string>
+#include "CoralBase/AttributeList.h"
+
+namespace cool {
+
+  /// Print an AttributeList to a string using AttributeList::print().
+  inline const 
+  std::string attributeListToString( const coral::AttributeList& data ) 
+  {
+    std::ostringstream dataStream;
+    data.toOutputStream( dataStream );
+    return dataStream.str();
+  }
+
+}
+
+#endif // RELATIONALCOOL_ATTRIBUTELISTTOSTRING_H
diff --git a/RelationalCool/src/new/IHvsNodeMgr.h b/RelationalCool/src/new/IHvsNodeMgr.h
new file mode 100644
index 000000000..17cb1ae5b
--- /dev/null
+++ b/RelationalCool/src/new/IHvsNodeMgr.h
@@ -0,0 +1,69 @@
+// $Id: IHvsNodeMgr.h,v 1.2 2007-07-05 09:05:12 avalassi Exp $
+#ifndef COOLKERNEL_IHVSNODEMGR_H
+#define COOLKERNEL_IHVSNODEMGR_H
+
+// Include files
+#include <string>
+#include "CoolKernel/IHvsNodeRecordMgr.h"
+
+namespace cool {  
+  
+  // Forward declarations
+  class IHvsNode;
+
+  /** @class IHvsNodeMgr IHvsNodeMgr.h
+   *  
+   *  Abstract interface for the manager of one HVS node tree.
+   * 
+   *  The HVS node manager handles a single tree of HVS nodes. 
+   *  The tree is a connected (single root), directed (relations are 
+   *  between parent and child), acyclic graph where each vertex has 
+   *  indegree 0 or 1 (all nodes have 1 parent, but the root has none).
+   *  
+   *  HVS nodes can be uniquely identified by their "full path" names
+   *  (following the same syntax used for UNIX files and directories).
+   *  
+   *  Each node is also assigned a unique integer id by the system.
+   *  
+   *  When users create a node, they must specify whether it can have 
+   *  children or not. Nodes that cannot have children are called leaf
+   *  nodes. Nodes that can have children (even if they currently have 
+   *  none) are called inner nodes or internal nodes.
+   *  
+   *  @author Andrea Valassi
+   *  @date   2006-03-02
+  */
+  
+  class IHvsNodeMgr : public IHvsNodeRecordMgr {
+    
+  public:
+
+    /// Destructor
+    virtual ~IHvsNodeMgr() {};
+
+    /// Find a node by (full path) name.
+    /// Throws NodeNotFound if the node does not exist.
+    virtual const IHvsNode& findNode( const std::string& fullPath ) const = 0;
+
+    /// Find a node by id.
+    /// Throws NodeNotFound if the node does not exist.
+    virtual const IHvsNode& findNode( const uInt32 id ) const = 0;
+
+    /// Drop an existing node (leaf node or inner node).
+    /// Return true if the node and all its structures are dropped as expected.
+    /// Return false (without throwing any exception) if the node and
+    /// all its structures do not exist any more on exit from this method,
+    /// but the node or some of its structures did not exist to start with.
+    /// Throw an exception if the node or one of its structures
+    /// cannot be dropped (i.e. continues to exist on exit from this method):
+    /// Throw an exception if the node is a non-empty inner node.
+    /// Also deletes any tags associated to the node
+    /// (throw an exception if such tags cannot be deleted).
+    virtual const bool dropNode( const std::string& fullPath ) = 0;
+
+  };
+  
+}
+
+#endif // COOLKERNEL_IHVSNODEMGR_H
+
diff --git a/RelationalCool/src/new/IHvsNodeRecordMgr.h b/RelationalCool/src/new/IHvsNodeRecordMgr.h
new file mode 100644
index 000000000..bf44c2e58
--- /dev/null
+++ b/RelationalCool/src/new/IHvsNodeRecordMgr.h
@@ -0,0 +1,61 @@
+// $Id: IHvsNodeRecordMgr.h,v 1.1 2006-04-03 11:33:23 avalassi Exp $
+#ifndef COOLKERNEL_IHVSNODERECORDMGR_H
+#define COOLKERNEL_IHVSNODERECORDMGR_H
+
+// Include files
+#include <string>
+
+namespace cool {  
+  
+  // Forward declarations
+  class IHvsNodeRecord;
+
+  /** @class IHvsNodeRecordMgr IHvsNodeRecordMgr.h
+   *  
+   *  Abstract interface for the manager of one HVS node tree.
+   * 
+   *  The HVS node manager handles a single tree of HVS nodes. 
+   *  The tree is a connected (single root), directed (relations are 
+   *  between parent and child), acyclic graph where each vertex has 
+   *  indegree 0 or 1 (all nodes have 1 parent, but the root has none).
+   *  
+   *  HVS nodes can be uniquely identified by their "full path" names
+   *  (following the same syntax used for UNIX files and directories).
+   *  
+   *  Each node is also assigned a unique integer id by the system.
+   *  
+   *  When users create a node, they must specify whether it can have 
+   *  children or not. Nodes that cannot have children are called leaf
+   *  nodes. Nodes that can have children (even if they currently have 
+   *  none) are called inner nodes or internal nodes.
+   *  
+   *  @author Andrea Valassi
+   *  @date   2006-03-02
+  */
+  
+  class IHvsNodeRecordMgr {
+    
+  public:
+
+    /// Destructor
+    virtual ~IHvsNodeRecordMgr() {};
+
+    /// Find a node record by (full path) name.
+    /// Throws NodeNotFound if the node does not exist.
+    virtual const IHvsNodeRecord& 
+    findNodeRecord( const std::string& fullPath ) const = 0;
+
+    /// Find a node record by id.
+    /// Throws NodeNotFound if the node does not exist.
+    virtual const IHvsNodeRecord& 
+    findNodeRecord( const uInt32 id ) const = 0;
+
+    /// Does a node with this (full path) name exist?
+    virtual const bool existsNode( const std::string& nodeName ) const = 0;
+
+  };
+  
+}
+
+#endif // COOLKERNEL_IHVSNODERECORDMGR_H
+
diff --git a/RelationalCool/src/new/IHvsTag.h b/RelationalCool/src/new/IHvsTag.h
new file mode 100644
index 000000000..ebee8a3c1
--- /dev/null
+++ b/RelationalCool/src/new/IHvsTag.h
@@ -0,0 +1,43 @@
+// $Id: IHvsTag.h,v 1.2 2007-07-05 09:05:12 avalassi Exp $
+#ifndef COOLKERNEL_IHVSTAG_H
+#define COOLKERNEL_IHVSTAG_H
+
+// Include files
+#include "CoolKernel/IHvsTagRecord.h"
+
+namespace cool {
+
+  /** @class IHvsTag IHvsTag.h
+   *
+   *  Abstract interface for one tag stored in an HVS tag tree
+   *  (read-only interface to access the properties of existing tags).
+   *
+   *  HVS tags can be uniquely identified by their names.
+   *  The terms "tag" and "tag name" are thus equivalent.
+   *  
+   *  Each tag is also assigned a unique integer id by the system.
+   *  
+   *  When users create a tag, they must specify whether it will be used
+   *  for inner nodes or leaf nodes. A given tag can be used only for one
+   *  inner node or for many leaf nodes: the same tag cannot be used for 
+   *  more than one inner node, or for one inner node and one leaf node.
+   *
+   *  @author Andrea Valassi
+   *  @date   2006-03-03
+   */
+
+  class IHvsTag : public IHvsTagRecord {
+
+  public:
+
+    /// Destructor.
+    virtual ~IHvsTag() {}
+
+    /// Change the tag description stored in the database.
+    virtual void setDescription( const std::string& description ) = 0;
+    
+  };
+
+}
+
+#endif // COOLKERNEL_IHVSTAG_H
diff --git a/RelationalCool/src/new/RelationalHvsTagMgr.cpp b/RelationalCool/src/new/RelationalHvsTagMgr.cpp
new file mode 100644
index 000000000..78eb467ae
--- /dev/null
+++ b/RelationalCool/src/new/RelationalHvsTagMgr.cpp
@@ -0,0 +1,84 @@
+// $Id: RelationalHvsTagMgr.cpp,v 1.1 2006-04-03 11:33:23 avalassi Exp $
+
+// Include files
+#include "CoolKernel/Exception.h"
+#include "CoolKernel/IHvsNodeMgr.h"
+#include "CoolKernel/IHvsNodeRecord.h"
+#include "CoolKernel/IHvsTagRecord.h"
+
+// Local include files
+#include "RelationalHvsTagMgr.h"
+
+// Namespace
+using namespace cool;
+
+//-----------------------------------------------------------------------------
+
+const IHvsTagRecord& 
+RelationalHvsTagMgr::findTagRecord( const std::string& /*tagName*/ ) const
+{
+  throw Exception( "Not yet implemented", "RelationalHvsTagMgr" );
+}
+
+//-----------------------------------------------------------------------------
+
+/*
+const IHvsTag& 
+RelationalHvsTagMgr::findTag( const std::string& tagName ) const
+{
+}
+*/
+
+//-----------------------------------------------------------------------------
+
+const bool 
+RelationalHvsTagMgr::existsTag( const std::string& tagName ) const
+{
+  if ( IHvsNode::isHeadTag( tagName ) ) return true;
+  try {
+    findTagRecord( tagName );
+    return true;
+  } catch ( TagNotFound& /* dummy */ ) {
+    return false;
+  }
+}
+
+//-----------------------------------------------------------------------------
+/*
+const IHvsNode::Type 
+RelationalHvsTagMgr::tagScope( const std::string& tagName ) const
+{
+  const IHvsTagRecord& tag = findTagRecord( tagName );
+  return tag.scope();
+}
+*/
+//-----------------------------------------------------------------------------
+
+const std::string
+RelationalHvsTagMgr::taggedNode( const std::string& tagName ) const
+{
+  const IHvsTagRecord& tag = findTagRecord( tagName );
+  return hvsNodeMgr().findNodeRecord( tag.nodeId() ).fullPath();
+}
+
+//-----------------------------------------------------------------------------
+
+const std::vector<std::string>
+RelationalHvsTagMgr::taggedNodes( const std::string& tagName ) const
+{
+  // TEMPORARY IMPLEMENTATION!
+  std::vector<std::string> nodes;
+  nodes.push_back( taggedNode( tagName ) );
+  return nodes;
+}
+
+//-----------------------------------------------------------------------------
+
+const IHvsNodeMgr& 
+RelationalHvsTagMgr::hvsNodeMgr() const
+{
+  return *m_hvsNodeMgr;
+}
+
+//-----------------------------------------------------------------------------
+
diff --git a/RelationalCool/src/new/RelationalHvsTagMgr.h b/RelationalCool/src/new/RelationalHvsTagMgr.h
new file mode 100644
index 000000000..148f69529
--- /dev/null
+++ b/RelationalCool/src/new/RelationalHvsTagMgr.h
@@ -0,0 +1,107 @@
+// $Id: RelationalHvsTagMgr.h,v 1.1 2006-04-03 11:33:23 avalassi Exp $
+#ifndef RELATIONALCOOL_RELATIONALHVSTAGMGR_H
+#define RELATIONALCOOL_RELATIONALHVSTAGMGR_H
+
+// Include files
+#include "CoolKernel/IHvsTagMgr.h"
+
+namespace cool {  
+  
+  /** @class RelationalHvsTagMgr RelationalHvsTagMgr.h
+   *  
+   *  Abstract interface for the manager of one HVS tag tree.
+   * 
+   *  HVS tags can be uniquely identified by their names.
+   *  The terms "tag" and "tag name" are thus equivalent.
+   *  
+   *  Each tag is also assigned a unique integer id by the system.
+   *  
+   *  When users create a tag, they must specify whether it will be used
+   *  for inner nodes or leaf nodes. A given tag can be used only for one
+   *  inner node or for many leaf nodes: the same tag cannot be used for 
+   *  more than one inner node, or for one inner node and one leaf node.
+   *
+   *  @author Andrea Valassi
+   *  @date   2006-03-02
+  */
+  
+  class RelationalHvsTagMgr {
+    
+  public:
+
+    /// Destructor
+    virtual ~RelationalHvsTagMgr() {};
+
+    /// Get a tag record by name.
+    /// Throws TagNotFound if the tag does not exist.
+    virtual const IHvsTagRecord& 
+    findTagRecord( const std::string& tagName ) const;
+    
+    /*
+    /// Get a tag by name.
+    /// Throws TagNotFound if the tag does not exist.
+    virtual const IHvsTag& findTag( const std::string& tagName );
+    */
+    
+    /// Does a tag with this name exist?
+    /// Tag names, except for "HEAD", are case sensitive.
+    /// Returns true for the reserved tags "" and "HEAD".
+    virtual const bool existsTag( const std::string& tagName ) const;
+    
+    /*
+    /// Return the type of node (inner/leaf) where the tag can be defined.
+    /// Tag names, except for "HEAD", are case sensitive.
+    /// Throws TagNotFound if the tag does not exist.
+    virtual const IHvsNode::Type tagScope( const std::string& tagName ) const;
+    */
+    
+    /// Return the names of the node where the tag is defined.
+    /// Tag names, except for "HEAD", are case sensitive.
+    /// Throws TagNotFound if the tag does not exist.
+    /// Throws ReservedHeadTag for the HEAD tag (defined in all folders). 
+    virtual const std::string taggedNode( const std::string& tagName ) const;
+
+    /// Return the names of the nodes where the tag is defined.
+    /// Tag names, except for "HEAD", are case sensitive.
+    /// Throws TagNotFound if the tag does not exist.
+    /// Throws ReservedHeadTag for the HEAD tag (defined in all folders). 
+    virtual const 
+    std::vector<std::string> taggedNodes( const std::string& tagName ) const;
+
+    /*
+    /// Main HVS method: determine the tag associated to a node, given
+    /// a tag associated to an ancestor of that descendant node.
+    /// The corresponding ancestor node is also internally determined.
+    /// Throw an exception if the tag is not associated to any ancestor node.
+    /// The input 'ancestor' tag is returned if it is directly associated to 
+    /// the node itself, rather than to an ancestor of that node.
+    virtual const 
+    std::string resolveTag( const std::string& descendantNode,
+                            const std::string& ancestorTag );
+    
+    /// Main HVS method: determine the tag associated to a node, given
+    /// an ancestor of that descendant node and a tag associated to it.
+    /// Throw an exception if the tag is not associated to the ancestor node.
+    /// Throw an exception if the two nodes are not ancestor and descendant.
+    virtual const 
+    std::string resolveTag( const std::string& descendantNode,
+                            const std::string& ancestorTag,
+                            const std::string& ancestorNode );
+    */
+
+  private:
+
+    /// Handle to the IHvsNodeMgr 
+    const IHvsNodeMgr& hvsNodeMgr() const;
+
+  private:
+
+    /// Handle to the IHvsNodeMgr 
+    IHvsNodeMgr* m_hvsNodeMgr;
+
+  };
+  
+}
+
+#endif // RELATIONALCOOL_RELATIONALHVSTAGMGR_H
+
diff --git a/RelationalCool/src/sigsegv.cpp b/RelationalCool/src/sigsegv.cpp
new file mode 100644
index 000000000..71728ea43
--- /dev/null
+++ b/RelationalCool/src/sigsegv.cpp
@@ -0,0 +1,296 @@
+// $Id: sigsegv.cpp,v 1.8 2008-05-16 11:29:19 avalassi Exp $
+#ifndef __APPLE__
+#ifndef WIN32
+
+//-----------------------------------------------------------------------------
+// From the SEAL config.h
+//-----------------------------------------------------------------------------
+
+// AV simple workaround for SEAL config - START
+// Compare SEAL config.h for LX32, LX64, MAC, WIN
+#ifndef WIN32
+# define HAVE_POSIX_SIGNALS 1 // ok LX32/LX64/MAC, no WIN
+#endif
+// AV simple workaround for SEAL config - END
+
+//-----------------------------------------------------------------------------
+// From http://tlug.up.ac.za/wiki/index.php/
+//   Obtaining_a_stack_trace_in_C_upon_SIGSEGV
+//-----------------------------------------------------------------------------
+
+/**
+ * This source file is used to print out a stack-trace when your program
+ * segfaults.  It is relatively reliable and spot-on accurate.
+ *
+ * This code is in the public domain.  Use it as you see fit, some credit
+ * would be appreciated, but is not a prerequisite for usage. Feedback
+ * on it's use would encourage further development and maintenance.
+ *
+ * Author:  Jaco Kroon <jaco@kroon.co.za>
+ *
+ * Copyright (C) 2005 - 2006 Jaco Kroon
+ */
+#ifndef WIN32 // AV
+//#define _GNU_SOURCE // AV
+//#define NO_CPP_DEMANGLE // AV
+#include <memory.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <signal.h>
+#include <ucontext.h>
+#include <dlfcn.h>
+#include <execinfo.h>
+#ifndef NO_CPP_DEMANGLE
+#include <cxxabi.h>
+#endif
+
+#if defined(REG_RIP)
+# define SIGSEGV_STACK_IA64
+# define REGFORMAT "%016lx"
+#elif defined(REG_EIP)
+# define SIGSEGV_STACK_X86
+# define REGFORMAT "%08x"
+#else
+# define SIGSEGV_STACK_GENERIC
+# define REGFORMAT "%x"
+#endif
+
+namespace cool
+{
+
+  // Declare SEAL functions
+  const char* seal_describe (int sig, int code);
+
+  static void signal_segv(int signum, siginfo_t* info, void*ptr) 
+  {
+    static const char *si_codes[3] = {"", "SEGV_MAPERR", "SEGV_ACCERR"};
+
+    ucontext_t *ucontext = (ucontext_t*)ptr;
+
+#if defined(SIGSEGV_STACK_X86) || defined(SIGSEGV_STACK_IA64)
+    int f = 0;
+    Dl_info dlinfo;
+    void **bp = 0;
+    void *ip = 0;
+#else
+    void *bt[20];
+    char **strings;
+    size_t sz;
+#endif
+
+    fprintf(stderr, "Segmentation Fault!\n");
+    fprintf(stderr, "info.si_signo = %d\n", signum);
+    fprintf(stderr, "info.si_errno = %d\n", info->si_errno);
+    //fprintf(stderr, "info.si_code  = %d (%s)\n", info->si_code, si_codes[info->si_code]);
+    fprintf(stderr, "info.si_code  = %d (%s: %s)\n", info->si_code, si_codes[info->si_code], seal_describe(signum,info->si_code));
+    fprintf(stderr, "info.si_addr  = %p\n", info->si_addr);
+    // AV skip registry dump - START
+    //size_t i1;
+    //for(i1 = 0; i1 < NGREG; i1++)
+    //    fprintf(stderr, "reg[%02d]       = 0x" REGFORMAT "\n", i1, ucontext->uc_mcontext.gregs[i1]);
+    // AV skip registry dump - END
+
+#if defined(SIGSEGV_STACK_X86) || defined(SIGSEGV_STACK_IA64)
+# if defined(SIGSEGV_STACK_IA64)
+    ip = (void*)ucontext->uc_mcontext.gregs[REG_RIP];
+    bp = (void**)ucontext->uc_mcontext.gregs[REG_RBP];
+# elif defined(SIGSEGV_STACK_X86)
+    ip = (void*)ucontext->uc_mcontext.gregs[REG_EIP];
+    bp = (void**)ucontext->uc_mcontext.gregs[REG_EBP];
+# endif
+
+    fprintf(stderr, "Stack trace:\n");
+    while(bp && ip) {
+        if(!dladdr(ip, &dlinfo))
+            break;
+
+        const char *symname = dlinfo.dli_sname;
+#ifndef NO_CPP_DEMANGLE
+        int status;
+        //char *tmp = __cxa_demangle(symname, NULL, 0, &status);
+        char *tmp = abi::__cxa_demangle(symname, NULL, 0, &status); // AV
+
+        if(status == 0 && tmp)
+            symname = tmp;
+#endif
+
+        fprintf(stderr, "% 2d: %p <%s+%lu> (%s)\n",
+                ++f,
+                ip,
+                symname,
+                (unsigned long)(dlinfo.dli_saddr)-(unsigned long)ip,
+                dlinfo.dli_fname);
+
+#ifndef NO_CPP_DEMANGLE
+        if(tmp)
+            free(tmp);
+#endif
+
+        if(dlinfo.dli_sname && !strcmp(dlinfo.dli_sname, "main"))
+            break;
+
+        ip = bp[1];
+        bp = (void**)bp[0];
+    }
+#else
+    fprintf(stderr, "Stack trace (non-dedicated):\n");
+    sz = backtrace(bt, 20);
+    strings = backtrace_symbols(bt, sz);
+
+    size_t i;
+    for(i = 0; i < sz; ++i)
+        fprintf(stderr, "%s\n", strings[i]);
+#endif
+    fprintf(stderr, "End of stack trace\n");
+    exit (-1);
+  }
+
+  int setup_sigsegv() 
+  {
+    struct sigaction action;
+    memset(&action, 0, sizeof(action));
+    action.sa_sigaction = signal_segv;
+    action.sa_flags = SA_SIGINFO;
+    if(sigaction(SIGSEGV, &action, NULL) < 0) {
+        perror("sigaction");
+        return 0;
+    }
+
+    return 1;
+  }
+
+#define SIGSEGV_NO_AUTO_INIT 1 // AV
+#ifndef SIGSEGV_NO_AUTO_INIT 
+  static void __attribute((constructor)) init(void) {
+    setup_sigsegv();
+  }
+#endif
+#endif // AV
+
+//-----------------------------------------------------------------------------
+// From the SEAL Signal class
+//-----------------------------------------------------------------------------
+
+/** Return the description for signal info code @a code for signal
+    number @a sig.  The code should come from @c siginfo_t::si_code.  */
+  const char* seal_describe (int sig, int code)
+  {
+    static struct { int sig; int code; const char *desc; } s_infos [] = {
+#if HAVE_POSIX_SIGNALS
+      { -1,	   SI_USER,	"user sent: kill, sigsend or raise" },
+# ifdef SI_KERNEL
+      { -1,	   SI_KERNEL,	"kernel" },
+# endif
+      { -1,	   SI_QUEUE,	"sigqueue" },
+      { -1,	   SI_TIMER,	"timer expired" },
+      { -1,	   SI_MESGQ,	"mesq state changed" },
+      { -1,	   SI_ASYNCIO,	"AIO completed" },
+# ifdef SI_SIGIO // not solaris
+      { -1,	   SI_SIGIO,	"queued SIGIO" },
+# endif
+      
+# ifdef ILL_NOOP // darwin
+      { SIGILL,  ILL_NOOP,	"noop" },
+# endif
+      { SIGILL,  ILL_ILLOPC,	"illegal opcode" },
+# ifdef ILL_ILLOPN // not darwin
+      { SIGILL,  ILL_ILLOPN,	"illegal operand" },
+# endif
+# ifdef ILL_ILLADR // not darwin
+      { SIGILL,  ILL_ILLADR,	"illegal addressing mode" },
+# endif
+      { SIGILL,  ILL_ILLTRP,	"illegal trap" },
+      { SIGILL,  ILL_PRVOPC,	"priveleged opcode" },
+# ifdef ILL_PRVREG // not darwin
+      { SIGILL,  ILL_PRVREG,	"privileged register" },
+# endif
+# ifdef ILL_COPROC // not darwin
+      { SIGILL,  ILL_COPROC,	"coprocessor error" },
+# endif
+# ifdef ILL_BADSTK // not darwin
+      { SIGILL,  ILL_BADSTK,	"internal stack error" },
+# endif
+      
+# ifdef FPE_NOOP // darwin
+      { SIGFPE,  FPE_NOOP,	"noop" },
+# endif
+# ifdef FPE_INTDIV // not darwin
+      { SIGFPE,  FPE_INTDIV,	"integer divide by zero" },
+# endif
+# ifdef FPE_INTOVF // not darwin
+      { SIGFPE,  FPE_INTOVF,	"integer overflow" },
+# endif
+      { SIGFPE,  FPE_FLTDIV,	"flaoting point divide by zero" },
+      { SIGFPE,  FPE_FLTOVF,	"floating point overflow" },
+      { SIGFPE,  FPE_FLTUND,	"floating point underflow" },
+      { SIGFPE,  FPE_FLTRES,	"floating point inexact result" },
+      { SIGFPE,  FPE_FLTINV,	"floating point in valid operation" },
+# ifdef FPE_FLTSUB // not darwin
+      { SIGFPE,  FPE_FLTSUB,	"subscript out of range" },
+# endif
+      
+# ifdef SEGV_NOOP // darwin
+      { SIGSEGV, SEGV_NOOP,	"noop" },
+# endif
+      { SIGSEGV, SEGV_MAPERR,	"address not mapped to object" },
+      { SIGSEGV, SEGV_ACCERR,	"invalid permissions for mapped object" },
+      
+# ifdef BUS_NOOP // darwin
+      { SIGBUS,  BUS_NOOP,	"noop" },
+# endif
+      { SIGBUS,  BUS_ADRALN,	"invalid address alignment" },
+# ifdef BUS_ADRERR // not darwin
+      { SIGBUS,  BUS_ADRERR,	"non-existent physical address" },
+# endif
+# ifdef BUS_OBJERR // not darwin
+      { SIGBUS,  BUS_OBJERR,	"object specific hardware error" },
+# endif
+      
+# ifdef TRAP_BRKPT // not darwin
+      { SIGTRAP, TRAP_BRKPT,	"process break point" },
+# endif
+# ifdef TRAP_TRACE // not darwin
+      { SIGTRAP, TRAP_TRACE,	"process trace trap" },
+# endif
+	    
+# ifdef CLD_NOOP // darwin
+      { SIGCHLD, CLD_NOOP,	"noop" },
+# endif
+      { SIGCHLD, CLD_EXITED,	"child has exited" },
+      { SIGCHLD, CLD_KILLED,	"child was killed" },
+      { SIGCHLD, CLD_DUMPED,	"child terminated abnormally" },
+      { SIGCHLD, CLD_TRAPPED,	"traced child has trapped" },
+      { SIGCHLD, CLD_STOPPED,	"child has stopped" },
+      { SIGCHLD, CLD_CONTINUED,"stopped child has continued" },
+      
+# ifdef SIGPOLL // not darwin
+      { SIGPOLL, POLL_IN,	"data input available" },
+      { SIGPOLL, POLL_OUT,	"output buffers available" },
+      { SIGPOLL, POLL_MSG,	"input message available" },
+      { SIGPOLL, POLL_ERR,	"i/o error" },
+      { SIGPOLL, POLL_PRI,	"high priority input available" },
+      { SIGPOLL, POLL_HUP,	"device disconnected" },
+# endif
+#endif  // HAVE_POSIX_SIGNALS
+      
+      { -1,      -1,		0 }
+    };
+    
+    for (unsigned i = 0; s_infos [i].desc; ++i)
+      if ((s_infos [i].sig == -1 || s_infos [i].sig == sig)
+          && s_infos [i].code == code)
+        return s_infos [i].desc;
+    
+    return "*unknown reason*";
+  }
+  
+}
+
+//-----------------------------------------------------------------------------
+#endif // WIN32
+#else // __APPLE__
+namespace cool
+{
+  int setup_sigsegv(){ return 0; }
+}
+#endif // __APPLE__
diff --git a/RelationalCool/src/sigsegv.h b/RelationalCool/src/sigsegv.h
new file mode 100644
index 000000000..203ec3f8d
--- /dev/null
+++ b/RelationalCool/src/sigsegv.h
@@ -0,0 +1,12 @@
+// $Id: sigsegv.h,v 1.2 2008-04-10 10:12:17 avalassi Exp $
+// From http://tlug.up.ac.za/wiki/index.php/Obtaining_a_stack_trace_in_C_upon_SIGSEGV
+#ifndef SIGSEGV_H 
+#define SIGSEGV_H 1
+#ifdef __cplusplus
+//extern "C" // AV
+#endif
+namespace cool
+{
+  int setup_sigsegv();
+}
+#endif
diff --git a/RelationalCool/src/sleep.h b/RelationalCool/src/sleep.h
new file mode 100644
index 000000000..b4d6bec90
--- /dev/null
+++ b/RelationalCool/src/sleep.h
@@ -0,0 +1,19 @@
+#include "boost/thread/xtime.hpp"
+#include <boost/thread.hpp>
+
+namespace cool 
+{
+  void sleep(int sec)
+  {
+    boost::xtime t;
+    if ( boost::xtime_get(&t,boost::TIME_UTC) == boost::TIME_UTC ) 
+    {
+      t.sec += sec;
+      boost::thread::sleep(t);
+    }
+    else
+    {
+      // TODO: (Marco) do something if cannot get the time...
+    }
+  }
+}
diff --git a/RelationalCool/src/timeToString.h b/RelationalCool/src/timeToString.h
new file mode 100644
index 000000000..e566f0476
--- /dev/null
+++ b/RelationalCool/src/timeToString.h
@@ -0,0 +1,92 @@
+// $Id: timeToString.h,v 1.10 2007-03-29 15:57:01 avalassi Exp $
+#ifndef RELATIONALCOOL_TIMETOSTRING_H 
+#define RELATIONALCOOL_TIMETOSTRING_H
+
+// Include files
+#include <iostream>
+#include <sstream>
+#include <string>
+#include "CoolKernel/Exception.h"
+#include "CoolKernel/Time.h"
+
+namespace cool {
+  
+  /// Convert a string date "yyyy-mm-dd_hh:mm:ss.nnnnnnnnn into a Time. 
+  /// The format is the one we used to store dates for both Oracle and MySQL.
+  /// The input string is expected to represent a GMT time and ends with "GMT"
+  inline const Time stringToTime( const std::string& timeString ) 
+  {
+    int year, month, day, hour, min, sec;
+    long nsec;
+    if ( timeString.size() == 
+         std::string( "yyyy-mm-dd_hh:mm:ss.nnnnnnnnn GMT" ).size() 
+         && sscanf( timeString.c_str(), "%4d-%2d-%2d_%2d:%2d:%2d.%9ld GMT",
+                    &year, &month, &day, &hour, &min, &sec, &nsec) == 7
+         && timeString.substr(4,1) == "-"
+         && timeString.substr(7,1) == "-" // Month in [1-12]
+         && timeString.substr(10,1) == "_"
+         && timeString.substr(13,1) == ":"
+         && timeString.substr(16,1) == ":"
+         && timeString.substr(19,1) == "."
+         && timeString.substr(29,4) == " GMT" ) {
+      Time time( year, month, day, hour, min, sec, nsec );
+      /*
+      std::cout<< "__stringToTime ( '" << timeString << "' )" << std::endl;
+      std::cout<<"Year: "<<year<<" -> "<<time.year()<<std::endl;
+      std::cout<<"Month: "<<month<<" -> "<<time.month()<<std::endl;
+      std::cout<<"Day: "<<day<<" -> "<<time.day()<<std::endl;
+      std::cout<<"Hour: "<<hour<<" -> "<<time.hour()<<std::endl;
+      std::cout<<"Min: "<<min<<" -> "<<time.minute()<<std::endl;
+      std::cout<<"Sec: "<<sec<<" -> "<<time.second()<<std::endl;
+      std::cout<<"nSec: "<<nsec<<" -> "<<time.nanosecond()<<std::endl;
+      std::cout<< "__stringToTime = '" << time << "'" << std::endl;
+      */
+      return time;
+    } else {
+      std::stringstream msg;
+      msg << "Error decoding string '" << timeString << "' into Time";
+      throw cool::Exception( msg.str(), "cool::stringToTime" );
+    }
+  }
+
+  /// Convert any ITime into a string in the format expected by stringToTime.
+  /// Useful to print an ITime (there is no default operator<<).
+  /// The output string represents a GMT time and ends with "GMT"
+  inline const std::string timeToString( const ITime& time ) 
+  {
+    int year = time.year();
+    int month = time.month(); // Months are in [1-12]
+    int day = time.day();
+    int hour = time.hour();
+    int min = time.minute();
+    int sec = time.second();
+    long nsec = time.nanosecond();
+    char timeChar[] = "yyyy-mm-dd_hh:mm:ss.nnnnnnnnn GMT";
+    int nChar = std::string(timeChar).size();
+    if ( sprintf( timeChar, "%4.4d-%2.2d-%2.2d_%2.2d:%2.2d:%2.2d.%9.9ld GMT",
+                  year, month, day, hour, min, sec, nsec) == nChar ) {
+      std::string timeString = std::string( timeChar );
+      /*
+      std::cout<< "__timeToString ( '" << time << "' )" << std::endl;
+      std::cout<<"Year: "<<year<<std::endl;
+      std::cout<<"Month(1-12): "<<month<<std::endl;
+      std::cout<<"Day: "<<day<<std::endl;
+      std::cout<<"Hour: "<<hour<<std::endl;
+      std::cout<<"Min: "<<min<<std::endl;
+      std::cout<<"Sec: "<<sec<<std::endl;
+      std::cout<<"nSec: "<<nsec<<std::endl;
+      std::cout<< "__timeToString = '" << timeString << "'" << std::endl;
+      */
+      return timeString;
+    } else {
+      std::stringstream msg;
+      msg << "PANIC! Error encoding ITime into string: "
+          << year << "-" << month << "-" << day << "_"
+          << hour << ":" << min << ":" << sec << "." << nsec;
+      throw cool::Exception( msg.str(), "cool::timeToString" );
+    }
+    
+  }
+
+}
+#endif // RELATIONALCOOL_TIMETOSTRING_H
diff --git a/RelationalCool/src/uppercaseString.h b/RelationalCool/src/uppercaseString.h
new file mode 100644
index 000000000..d806d5152
--- /dev/null
+++ b/RelationalCool/src/uppercaseString.h
@@ -0,0 +1,21 @@
+// $Id: uppercaseString.h,v 1.4 2005-12-09 12:10:51 marcocle Exp $
+#ifndef UPPERCASESTRING_H 
+#define UPPERCASESTRING_H 1
+
+// Include files
+#include <algorithm>
+#include <cctype>
+#include <string>
+
+namespace cool {
+
+  inline const std::string uppercaseString( const std::string& aString ) {
+    std::string aStringUp = aString;
+    std::transform 
+      ( aStringUp.begin(), aStringUp.end(), aStringUp.begin(), toupper );
+    return aStringUp;
+  }
+
+}
+
+#endif // UPPERCASESTRING_H
diff --git a/RelationalCool/tests/AttributeList/test_AttributeList.cpp b/RelationalCool/tests/AttributeList/test_AttributeList.cpp
new file mode 100644
index 000000000..3271ac549
--- /dev/null
+++ b/RelationalCool/tests/AttributeList/test_AttributeList.cpp
@@ -0,0 +1,124 @@
+// PORT -- temporarily disabled: not part of our official test suite
+int main() { return 0; }
+#ifdef NOPORT
+// $Id: test_AttributeList.cpp,v 1.8 2008-08-06 09:33:04 avalassi Exp $
+
+#include <iostream>
+#include <string>
+#include "AttributeList/AttributeList.h"
+#include "../../src/ProcMemory.h"
+#include "../../src/sleep.h"
+
+using namespace std;
+
+//-----------------------------------------------------------------------------
+
+void test_memory_leak() {
+  pool::AttributeListSpecification spec;
+  spec.push_back("I","int");
+  ProcMemory mem;
+  
+  long nObjs = 1*1000*1000;
+  for ( long i = 0; i < nObjs; ++i ) {
+    if ( i % 100000 == 0 ) {
+      std::cout << "object " << i << "\t";
+      mem.printVm();
+      std::cout << std::endl;
+      cool::sleep(1);
+    }
+    pool::AttributeList list( spec );
+  }
+}
+
+//-----------------------------------------------------------------------------
+
+int test_specs() {
+
+  cout << "Entering test_specs" << endl;
+
+  pool::AttributeList* alpFrefCc; // copy-construct AL built from reference
+  pool::AttributeList* alpFrefAs; // assignment of AL built from reference
+  pool::AttributeList* alpFshpCc; // copy-construct AL built from sh pointer
+  pool::AttributeList* alpFshpAs; // assignment of AL built from sh pointer
+
+  {
+    // The two AttributeList specifications
+    pool::AttributeListSpecification alRefSpec;
+    alRefSpec.push_back( "REFERENCE", "string" );
+    boost::shared_ptr<pool::AttributeListSpecification> alShpSpec 
+      ( new pool::AttributeListSpecification() );
+    alShpSpec->push_back( "SHARED", "string" );
+    alShpSpec->push_back( "POINTER", "string" );
+    cout << "Shared pointer - built specification" << endl;
+    cout << "Shared pointer use count = " << alShpSpec.use_count() << endl;
+    // Build AL from reference or shared pointer specification
+    pool::AttributeList alFref( alRefSpec );
+    pool::AttributeList alFshp( alShpSpec );
+    cout << "Shared pointer - built AL from specification" << endl;
+    cout << "Shared pointer use count = " << alShpSpec.use_count() << endl;
+    alFref["REFERENCE"].setValueAsString("---");
+    alFshp["SHARED"].setValueAsString("---");
+    alFshp["POINTER"].setValueAsString("---");
+    // Copy-construct and assign the four pointers
+    alpFrefCc = new pool::AttributeList( alFref ); // PROBLEMS!
+    alpFrefAs = new pool::AttributeList(); *alpFrefAs = alFref; // PROBLEMS!
+    alpFshpCc = new pool::AttributeList( alFshp ); // PROBLEMS!
+    cout << "Shared pointer - built AL from copy constructor" << endl;
+    cout << "Shared pointer use count = " << alShpSpec.use_count() << endl;
+    alpFshpAs = new pool::AttributeList(); *alpFshpAs = alFshp; // OK?
+    cout << "Shared pointer - assigned AL" << endl;
+    cout << "Shared pointer use count = " << alShpSpec.use_count() << endl;
+    // Print the four lists
+    cout << "Size alpFrefCc = " 
+         << alpFrefCc->attributeListSpecification().size() << endl;
+    alpFrefCc->print( cout ); cout << endl;
+    cout << "Size alpFrefAs = " 
+         << alpFrefAs->attributeListSpecification().size() << endl;
+    alpFrefAs->print( cout ); cout << endl;
+    cout << "Size alpFshpCc = " 
+         << alpFshpCc->attributeListSpecification().size() << endl;
+    alpFshpCc->print( cout ); cout << endl;
+    cout << "Size alpFshpAs = " 
+         << alpFshpAs->attributeListSpecification().size() << endl;
+    alpFshpAs->print( cout ); cout << endl;
+  }
+  
+  // Print the four lists again
+  cout << "Size alpFrefCc = " 
+       << alpFrefCc->attributeListSpecification().size() << endl;
+  //alpFrefCc->print( cout ); cout << endl;
+  cout << "Size alpFrefAs = " 
+       << alpFrefAs->attributeListSpecification().size() << endl;
+  //alpFrefAs->print( cout ); cout << endl;
+  cout << "Size alpFshpCc = " 
+       << alpFshpCc->attributeListSpecification().size() << endl;
+  //alpFshpCc->print( cout ); cout << endl;
+  cout << "Size alpFshpAs = " 
+       << alpFshpAs->attributeListSpecification().size() << endl;
+  //alpFshpAs->print( cout ); cout << endl;
+
+  // Delete the AL holding the specification shared pointer
+  delete alpFshpAs;
+  cout << "Size alpFshpCc = " 
+       << alpFshpCc->attributeListSpecification().size() << endl;
+  //alpFshpCc->print( cout ); cout << endl;
+
+  // Delete all other ALs
+  delete alpFrefCc;
+  delete alpFrefAs;
+  delete alpFshpCc;
+
+  cout << "Exiting test_specs" << endl;
+  return 0;
+
+}
+
+//-----------------------------------------------------------------------------
+
+int main() {
+  test_specs();
+  
+  test_memory_leak();
+}
+
+#endif // NOPORT
diff --git a/RelationalCool/tests/AttributeListDump/test_AttributeListDump.cpp b/RelationalCool/tests/AttributeListDump/test_AttributeListDump.cpp
new file mode 100644
index 000000000..c3df9b1ef
--- /dev/null
+++ b/RelationalCool/tests/AttributeListDump/test_AttributeListDump.cpp
@@ -0,0 +1,22 @@
+#include <iostream>
+#include "CoolKernel/types.h"
+#include "CoralBase/AttributeList.h"
+
+#include "../Common/releaser.h"
+
+// These two alone provide "<< AttributeList" functionalities...!?
+// NOT ANY LONGER after making the constructors explicit!
+#include "src/RelationalObjectTableRow.h"
+using namespace cool;
+
+int main() {
+  boost::shared_ptr<coral::AttributeListSpecification>
+    spec( new coral::AttributeListSpecification(), cool::releaser() );
+  spec->extend( "i", "int" );
+  coral::AttributeList dummy( *spec );
+  // The following does not work anymore!
+  //std::cout << "Dummy AttributeList: " << dummy << std::endl;
+  // The following works... but will clearly never be written! :-)
+  std::cout << "Dummy AttributeList: " 
+            << RelationalObjectTableRow( dummy ) << std::endl;
+}
diff --git a/RelationalCool/tests/BoolIO/authentication.xml b/RelationalCool/tests/BoolIO/authentication.xml
new file mode 100755
index 000000000..da8dc0f83
--- /dev/null
+++ b/RelationalCool/tests/BoolIO/authentication.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" ?>
+<connectionlist>
+
+<connection name="oracle://devdb10/lcg_cool">
+  <parameter name="user" value="USER" />
+  <parameter name="password" value="PASSWORD" />
+</connection>
+
+<connection name="mysql://pcitdb59/COOLDB">
+  <parameter name="user" value="USER" />
+  <parameter name="password" value="PASSWORD" />
+</connection>
+
+</connectionlist>
diff --git a/RelationalCool/tests/BoolIO/boolIO.cpp b/RelationalCool/tests/BoolIO/boolIO.cpp
new file mode 100644
index 000000000..a58d7607f
--- /dev/null
+++ b/RelationalCool/tests/BoolIO/boolIO.cpp
@@ -0,0 +1,225 @@
+// PORT -- temporarily disabled: not part of our official test suite
+int main() { return 0; }
+#ifdef NOPORT
+
+#include <iostream>
+#include <stdexcept>
+#include <memory>
+#include "RelationalAccess/RelationalException.h"
+#include "RelationalAccess/IRelationalService.h"
+#include "RelationalAccess/IRelationalDomain.h"
+#include "RelationalAccess/IRelationalSession.h"
+#include "RelationalAccess/IRelationalTransaction.h"
+#include "RelationalAccess/IRelationalSchema.h"
+#include "RelationalAccess/IRelationalTable.h"
+#include "RelationalAccess/RelationalEditableTableDescription.h"
+#include "RelationalAccess/IRelationalTableDataEditor.h"
+#include "RelationalAccess/IRelationalBulkRowInserter.h"
+#include "RelationalAccess/IRelationalCursor.h"
+#include "RelationalAccess/IRelationalQuery.h"
+#include "CoralBase/AttributeList.h"
+#include "POOLCore/POOLContext.h"
+#include "SealKernel/Context.h"
+
+int main( int, char** )
+{
+  try {
+    pool::POOLContext::loadComponent
+      ( "SEAL/Services/MessageService" );
+    pool::POOLContext::loadComponent
+      ( "POOL/Services/XMLAuthenticationService" );
+    pool::POOLContext::loadComponent
+      ( "POOL/Services/RelationalService" );
+    pool::POOLContext::setMessageVerbosityLevel
+      ( seal::Msg::Warning );
+    seal::MessageStream log
+      ( pool::POOLContext::context(), "BoolIO_Test" );
+    seal::IHandle<pool::IRelationalService> 
+      serviceHandle = 
+      pool::POOLContext::context()->query<pool::IRelationalService>
+      ( "POOL/Services/RelationalService" );
+    if ( ! serviceHandle ) {
+      throw std::runtime_error( "Could not retrieve the relational service" );
+    }
+
+    std::string connectionString = "oracle://devdb10/lcg_cool";
+    //std::string connectionString = "mysql://pcitdb59/COOLDB";
+    pool::IRelationalDomain& domain = 
+      serviceHandle->domainForConnection( connectionString );
+
+    // Creating a session
+    std::auto_ptr< pool::IRelationalSession > 
+      session( domain.newSession( connectionString ) );
+
+    // Establish a connection with the server
+    std::cout << "Connecting to " << connectionString << std::endl;
+    if ( ! session->connect() ) {
+      throw std::runtime_error( "Could not connect to the database server." );
+    }
+
+    // Table name
+    std::string tableName = "TEST_BOOL_IO";
+    
+    // INSERT DATA
+    {  
+      // Start a transaction
+      std::cout << "Starting a new transaction" << std::endl;
+      if ( ! session->transaction().start() ) {
+        throw std::runtime_error( "Could not start a new transaction." );
+      }
+      
+      // Droping old table
+      if ( session->userSchema().existsTable( tableName ) ) {
+        std::cout << "Deleting table '" << tableName << "'" << std::endl;
+        if ( ! session->userSchema().dropTable( tableName ) ) {
+          throw std::runtime_error( "Could not drop a table." );
+        }
+      }
+      
+      // Creating the description for the table
+      std::auto_ptr< pool::IRelationalEditableTableDescription > description
+        ( new pool::RelationalAccess::RelationalEditableTableDescription
+          ( log, domain.flavorName() ) );
+      description->insertColumn
+        ( "id", pool::AttributeStaticTypeInfo<int>::type_name() );
+      description->insertColumn
+        ( "flag", pool::AttributeStaticTypeInfo<bool>::type_name() );
+      description->insertColumn
+        ( "comment", pool::AttributeStaticTypeInfo<std::string>::type_name() );
+
+      // Create the table.
+      std::cout << "Creating table '" << tableName << "'" << std::endl;
+      pool::IRelationalTable& table = 
+        session->userSchema().createTable( tableName, *description );
+      
+      // Costructing a row buffer.
+      pool::AttributeListSpecification spec;      
+      spec.push_back
+        ( "id", pool::AttributeStaticTypeInfo<int>::type_name() );
+      spec.push_back
+        ( "flag", pool::AttributeStaticTypeInfo<bool>::type_name() );
+      spec.push_back
+        ( "comment", pool::AttributeStaticTypeInfo<std::string>::type_name() );
+      pool::AttributeList data( spec );
+      // NB This is OK on Oracle but fails on MySQL!
+      //pool::AttributeList data( table.description().columnNamesAndTypes() );
+
+      // Adding new rows
+      std::cout << "Inserting new rows into the table." << std::endl;
+      pool::IRelationalBulkRowInserter& rowInserter = 
+        table.dataEditor().bulkRowInserter();
+      if ( ! rowInserter.setup( data, 500 ) ) {
+        throw std::runtime_error( "Could not bind a new row for inserting." );
+      }    
+      std::cout << "Prepared the bulk row inserter." << std::endl;
+
+      data["id"].setValue<int>( 1 );
+      data["flag"].setValue<bool>( false );
+      data["comment"].setValue<std::string>( "false - bulk" );
+      std::cout << "Insert: "; data.print( std::cout ); std::cout << std::endl;
+      if ( ! rowInserter.insertNewRow() ) 
+        throw std::runtime_error
+          ( "Could not bulk insert a new row into the table." );
+
+      data["id"].setValue<int>( 2 );
+      data["flag"].setValue<bool>( true );
+      data["comment"].setValue<std::string>( "true - bulk" );
+      std::cout << "Insert: "; data.print( std::cout ); std::cout << std::endl;
+      if ( ! rowInserter.insertNewRow() ) 
+        throw std::runtime_error
+          ( "Could not bulk insert a new row into the table." );
+      if ( ! rowInserter.flushCache() ) 
+        throw std::runtime_error
+          ( "Could not flush the remaining rows into the table." );
+
+      data["id"].setValue<int>( 3 );
+      data["flag"].setValue<bool>( false );
+      data["comment"].setValue<std::string>( "false - no bulk" );
+      std::cout << "Insert: "; data.print( std::cout ); std::cout << std::endl;
+      if ( ! table.dataEditor().insertNewRow( data ) )
+        throw std::runtime_error
+          ( "Could not single insert a new row into the table." );
+
+      data["id"].setValue<int>( 4 );
+      data["flag"].setValue<bool>( true );
+      data["comment"].setValue<std::string>( "true - no bulk" );
+      std::cout << "Insert: "; data.print( std::cout ); std::cout << std::endl;
+      if ( ! table.dataEditor().insertNewRow( data ) )
+        throw std::runtime_error
+          ( "Could not single insert a new row into the table." );
+      
+      // Committing the transaction
+      std::cout << "Committing..." << std::endl;
+      if ( ! session->transaction().commit() ) {
+        throw std::runtime_error( "Could not commit the transaction." );
+      }
+    }
+
+    // READ BACK THE DATA
+    {
+
+      // Start a transaction
+      std::cout << "Starting a new transaction" << std::endl;
+      if ( ! session->transaction().start() ) {
+        throw std::runtime_error( "Could not start a new transaction." );
+      }
+
+      // Prepare the query the table
+      pool::IRelationalTable& table = 
+        session->userSchema().tableHandle( tableName );      
+      std::auto_ptr< pool::IRelationalQuery > query( table.createQuery() );
+      query->addToOutputList( "id" );
+      query->addToOutputList( "flag" );
+      query->addToOutputList( "comment" );
+
+      // This is only needed for MySQL (else bool is read back as char)
+      pool::AttributeListSpecification spec;      
+      spec.push_back
+        ( "id", pool::AttributeStaticTypeInfo<int>::type_name() );
+      spec.push_back
+        ( "flag", pool::AttributeStaticTypeInfo<bool>::type_name() );
+      spec.push_back
+        ( "comment", pool::AttributeStaticTypeInfo<std::string>::type_name() );
+      query->defineOutput( spec );
+
+      // Query the table
+      pool::IRelationalCursor& cursor = query->process();
+      if ( cursor.start() ) {
+        while ( cursor.next() ) {
+          const pool::AttributeList& row = cursor.currentRow();
+          std::cout<<"Read back: "; row.print(std::cout); std::cout<<std::endl;
+        }
+      }
+      
+      // Committing the transaction
+      std::cout << "Committing..." << std::endl;
+      if ( ! session->transaction().commit() ) {
+        throw std::runtime_error( "Could not commit the transaction." );
+      }
+
+    }
+
+    // Disconnecting
+    std::cout << "Disconnecting..." << std::endl;
+    session->disconnect();
+
+    std::cout << "Exiting..." << std::endl;
+  }
+  catch ( pool::RelationalException& re ) {
+    std::cerr << "Relational exception from module " 
+              << re.flavorName() << std::endl 
+              << "    " << re.what() << std::endl;
+    return 1;
+  }
+  catch ( std::exception& e ) {
+    std::cerr << "Standard C++ exception : " << e.what() << std::endl;
+    return 1;
+  }
+  catch ( ... ) {
+    std::cerr << "Exception caught (...)" << std::endl;
+    return 1;
+  }
+  return 0;
+}
+
+#endif // NOPORT
diff --git a/RelationalCool/tests/BoolIO/boolIO.txt.MySQL b/RelationalCool/tests/BoolIO/boolIO.txt.MySQL
new file mode 100644
index 000000000..b701e05fe
--- /dev/null
+++ b/RelationalCool/tests/BoolIO/boolIO.txt.MySQL
@@ -0,0 +1,25 @@
+POOL/Services/RelationalService     Info Found plugin for RDBMS technology "mysql" with implementation "odbc"
+POOL/Services/RelationalService     Info Found plugin for RDBMS technology "oracle" with native implementation
+POOL/Services/RelationalService     Info Found plugin for RDBMS technology "sqlite" with native implementation
+POOL/Services/RelationalService     Info Default implementation for RDBMS technology "mysql" is "odbc"
+POOL/Services/RelationalService     Info Default implementation for RDBMS technology "oracle" is native
+POOL/Services/RelationalService     Info Default implementation for RDBMS technology "sqlite" is native
+Connecting to mysql://pcitdb59/COOLDB
+Starting a new transaction
+Deleting table 'TEST_BOOL_IO'
+Creating table 'TEST_BOOL_IO'
+Inserting new rows into the table.
+Prepared the bulk row inserter.
+Insert: attribute list: size = 3 [ 1 as id:int, 0 as flag:bool, false - bulk as comment:string ]
+Insert: attribute list: size = 3 [ 2 as id:int, 1 as flag:bool, true - bulk as comment:string ]
+Insert: attribute list: size = 3 [ 3 as id:int, 0 as flag:bool, false - no bulk as comment:string ]
+Insert: attribute list: size = 3 [ 4 as id:int, 1 as flag:bool, true - no bulk as comment:string ]
+Committing...
+Starting a new transaction
+Read back: attribute list: size = 3 [ 1 as id:int, 1 as flag:bool, false - bulk as comment:string ]
+Read back: attribute list: size = 3 [ 2 as id:int, 1 as flag:bool, true - bulk as comment:string ]
+Read back: attribute list: size = 3 [ 3 as id:int, 0 as flag:bool, false - no bulk as comment:string ]
+Read back: attribute list: size = 3 [ 4 as id:int, 1 as flag:bool, true - no bulk as comment:string ]
+Committing...
+Disconnecting...
+Exiting...
diff --git a/RelationalCool/tests/BoolIO/boolIO.txt.Oracle b/RelationalCool/tests/BoolIO/boolIO.txt.Oracle
new file mode 100644
index 000000000..84eaed991
--- /dev/null
+++ b/RelationalCool/tests/BoolIO/boolIO.txt.Oracle
@@ -0,0 +1,25 @@
+POOL/Services/RelationalService     Info Found plugin for RDBMS technology "mysql" with implementation "odbc"
+POOL/Services/RelationalService     Info Found plugin for RDBMS technology "oracle" with native implementation
+POOL/Services/RelationalService     Info Found plugin for RDBMS technology "sqlite" with native implementation
+POOL/Services/RelationalService     Info Default implementation for RDBMS technology "mysql" is "odbc"
+POOL/Services/RelationalService     Info Default implementation for RDBMS technology "oracle" is native
+POOL/Services/RelationalService     Info Default implementation for RDBMS technology "sqlite" is native
+Connecting to oracle://devdb/conddb_test
+Starting a new transaction
+Deleting table 'TEST_BOOL_IO'
+Creating table 'TEST_BOOL_IO'
+Inserting new rows into the table.
+Prepared the bulk row inserter.
+Insert: attribute list: size = 3 [ 1 as id:int, 0 as flag:bool, false - bulk as comment:string ]
+Insert: attribute list: size = 3 [ 2 as id:int, 1 as flag:bool, true - bulk as comment:string ]
+Insert: attribute list: size = 3 [ 3 as id:int, 0 as flag:bool, false - no bulk as comment:string ]
+Insert: attribute list: size = 3 [ 4 as id:int, 1 as flag:bool, true - no bulk as comment:string ]
+Committing...
+Starting a new transaction
+Read back: attribute list: size = 3 [ 1 as id:int, 1 as flag:bool, false - bulk as comment:string ]
+Read back: attribute list: size = 3 [ 2 as id:int, 1 as flag:bool, true - bulk as comment:string ]
+Read back: attribute list: size = 3 [ 3 as id:int, 0 as flag:bool, false - no bulk as comment:string ]
+Read back: attribute list: size = 3 [ 4 as id:int, 1 as flag:bool, true - no bulk as comment:string ]
+Committing...
+Disconnecting...
+Exiting...
diff --git a/RelationalCool/tests/BuildFile b/RelationalCool/tests/BuildFile
new file mode 100644
index 000000000..b1d4e7701
--- /dev/null
+++ b/RelationalCool/tests/BuildFile
@@ -0,0 +1,31 @@
+<use name=CoolApplication>
+<external ref=cppunit>
+
+# Dependency on CORAL RelationalAccess
+# [Package granularity dropped: inherit dependency on all CORAL via CoolKernel]
+###<external ref=CORAL use=RelationalAccess></external>
+
+# Skip unnecessary SCRAM build to save time
+<skip dir=AttributeList>
+<skip dir=AttributeListDump>
+<skip dir=BoolIO>
+<skip dir=CMS_ECAL>
+<skip dir=CMS_extRef>
+<skip dir=ClobIO>
+<skip dir=CreateDatabase>
+<skip dir=Int64IO>
+<skip dir=MemoryConsumption>
+<skip dir=MyODBCBulkTest>
+<skip dir=MyTest>
+<skip dir=Performance>
+<skip dir=PerformanceAV>
+<skip dir=Privileges>
+<skip dir=ProcMemory>
+<skip dir=RalDatabase_versioning>
+<skip dir=Regression>
+#<skip dir=SchemaDump>
+<skip dir=SchemaEvolution>
+<skip dir=Skeleton>
+<skip dir=StressTest>
+<skip dir=TransactionHandling>
+
diff --git a/RelationalCool/tests/CMS_ECAL/README.CMS_ECAL b/RelationalCool/tests/CMS_ECAL/README.CMS_ECAL
new file mode 100644
index 000000000..5424125d7
--- /dev/null
+++ b/RelationalCool/tests/CMS_ECAL/README.CMS_ECAL
@@ -0,0 +1,3 @@
+Timing for inserting 9.6M rows (12000 channels * 800 keys):
+2080.040u 7.970s 46:52.27 74.2% 0+0k 0+0io 2527pf+0w
+
diff --git a/RelationalCool/tests/CMS_ECAL/testCmsEcal.cpp b/RelationalCool/tests/CMS_ECAL/testCmsEcal.cpp
new file mode 100644
index 000000000..36ee4df97
--- /dev/null
+++ b/RelationalCool/tests/CMS_ECAL/testCmsEcal.cpp
@@ -0,0 +1,254 @@
+// PORT -- temporarily disabled: not part of our official test suite
+int main() { return 0; }
+#ifdef NOPORT
+
+// $Id: testCmsEcal.cpp,v 1.14 2008-08-27 09:34:27 avalassi Exp $
+
+// Include files
+#include <iostream>
+#include <sstream>
+#include <string>
+#include "AttributeList/AttributeList.h"
+#include "CoolKernel/DatabaseId.h"
+#include "CoolKernel/IDatabase.h"
+#include "CoolKernel/IDatabaseSvc.h"
+#include "CoolKernel/IFolder.h"
+#include "CoolKernel/IFolderSet.h"
+#include "CoolKernel/IObject.h"
+#include "CoolKernel/IObjectIterator.h"
+#include "src/CoralApplication.h"
+#include "src/sleep.h"
+#include "src/timeToString.h"
+#include "src/uppercaseString.h"
+
+// Namespace
+using namespace cool;
+
+// Message output
+#define LOG std::cout << "__main "
+
+//-----------------------------------------------------------------------------
+
+int main ( int /* argc */, char* /* argv[] */ )
+{
+
+  LOG << "Entering main" << std::endl;
+  int status = -1;
+
+  // Connection string
+  std::string connectString;
+  if ( getenv( "COOLCMSECALDB" ) ) {
+    connectString = getenv( "COOLCMSECALDB" );
+  } else {
+    std::cout << "Please provide a connect string in "
+              << "the environment variable COOLCMSECALDB, e.g." 
+              << std::endl;
+    std::cout << "setenv COOLCMSECALDB "
+              << "\"oracle://cooldb2;schema=AVALASSICMS;"
+              << "user=avalassicms;password=PASSWORD;dbname=CMS_ECAL\"" 
+              << std::endl;
+    std::cout << "setenv COOLCMSECALDB "
+              << "\"mysql://lxb0771;schema=AVALASSICMS;"
+              << "user=avalassicms;password=PASSWORD;dbname=CMS_ECAL\"" 
+              << std::endl;
+    std::cout << "Aborting test" << std::endl;
+    exit(-1);
+  }
+
+  try {
+    
+    LOG << "Get a handle to the COOL database service" << std::endl;
+    CoralApplication app;
+    IDatabaseSvc& dbSvc = app.databaseService();
+  
+    //------------------------
+    // DEFINE THE DATABASE ID
+    //------------------------
+    
+    cool::DatabaseId dbId = connectString;
+
+    //--------------------------------
+    // DROP THE DATABASE IF IT EXISTS
+    //--------------------------------
+    
+    // Drop the COOL conditions database if it already exists
+    LOG << "Drop if it exists the conditions database: " << dbId << std::endl;
+    dbSvc.dropDatabase( dbId );
+
+    //-----------------------
+    // CREATE A NEW DATABASE
+    //-----------------------
+    
+    // Create a new COOL conditions database
+    LOG << "Create a new conditions database: " << dbId << std::endl;
+    cool::IDatabasePtr db1 = dbSvc.createDatabase( dbId );
+    LOG << "Conditions database created: " << std::endl;
+    LOG << "-> Database ID: " << db1->databaseId() << std::endl;
+    std::ostringstream dbAttr;
+    db1->databaseAttributes().print( dbAttr );
+    LOG << "-> Database attributes: " << dbAttr.str() << std::endl;
+
+    // TEMPORARY? Patch for the ORA-01466 problem: sleep one second
+    cool::sleep(1);
+
+    // Create pedestal folder 
+    pool::AttributeListSpecification folderPedSpec;
+    folderPedSpec.push_back("value00","long");
+    std::string folderPedName( "/cms/ecal/pedestals" );
+    cool::IFolderPtr folderPed = db1->createFolder
+      ( folderPedName, folderPedSpec, "", 
+        FolderVersioning::SINGLE_VERSION, true );
+    LOG << "Folder created: " << std::endl;
+    LOG << "-> Folder name: " << folderPed->fullPath() << std::endl;
+    std::ostringstream folderPedAttr;
+    folderPed->payloadSpecification().print( folderPedAttr );
+    LOG << "-> Folder payload specification: " 
+        << folderPedAttr.str() << std::endl;
+
+    // TEMPORARY? Patch for the ORA-01466 problem: sleep one second
+    cool::sleep(1);
+
+    // Print the list of folders
+    std::vector<std::string> folderList;
+    std::vector<std::string>::iterator folderIt;
+    folderList = db1->getFolderSet( "/cms/ecal" )->listFolders();
+    LOG << "-> List of folders in the database:" << std::endl;
+    for( folderIt = folderList.begin(); 
+         folderIt != folderList.end(); 
+         folderIt++ ) {
+      std::cout << *folderIt << std::endl;
+    }    
+
+    // Bulk insert data into pedestal folder 
+    // In online folders, until=+infinity means valid until next iov
+    //unsigned nChannels = 60000;
+    unsigned nChannels = 12000;
+    unsigned nKeys = 800;
+    //unsigned nKeys = 100;    
+    unsigned chId;
+    ValidityKey key;
+    ValidityKey plusInfinity = ValidityKeyMax;
+    pool::AttributeList folderPedData( folderPedSpec );
+    folderPed->setupStorageBuffer();
+    for ( chId = 1; chId <= nChannels; chId ++ ) {
+      for ( key = 1; key <= nKeys; key ++ ) {
+        folderPedData["value00"].setValue<long>( (long)key*100000+chId );
+        folderPed->storeObject( key*10, plusInfinity, folderPedData, chId );
+      }
+      // Hack: bulk insertion into different channels is not supported yet!
+      folderPed->flushStorageBuffer();
+    }
+    // NO: bulk insertion into different channels is not supported yet!
+    //folderPed->flushStorageBuffer();
+
+    // Dump the object stored for time t=55 in channel 13
+    IObjectPtr objPed_ch13_55 = folderPed->findObject( 55, 13 );
+    LOG << "Retrieved object valid at t=55 in channel 13 of folder "
+        << folderPed->fullPath() << std::endl;
+    LOG << "Object: channelId=" << objPed_ch13_55->channelId() << std::endl;
+    LOG << "Object: since=" << objPed_ch13_55->since() 
+        << ", until=" << objPed_ch13_55->until() << std::endl;
+    LOG << "Object: payload values (true types)"
+        << ": payload[\"value00\"]=" 
+        << objPed_ch13_55->payloadValue<long>("value00")
+        << std::endl;
+    LOG << "Object: payload values (as strings)"
+        << ": payload[\"value00\"]=" 
+        << objPed_ch13_55->payloadValue("value00")
+        << std::endl;
+    if( ! objPed_ch13_55->isStored() ) {
+      LOG << "Object: isStored=false" << std::endl;
+    } else {
+      LOG << "Object: isStored=true" << std::endl;
+      LOG << "Object: insertionTime=" 
+          << timeToString( objPed_ch13_55->insertionTime() ) << std::endl;;
+    }
+
+    // Reset the database pointer: this will close the connection
+    LOG << "Release the conditions database connection" << std::endl;
+    cool::IDatabasePtr dbNull;
+    db1 = dbNull;
+
+    //---------------------------
+    // OPEN AN EXISTING DATABASE
+    //---------------------------
+
+    // Open an existing COOL conditions database
+    LOG << "Open an existing conditions database: " << dbId << std::endl;
+    cool::IDatabasePtr db2 = dbSvc.openDatabase( dbId, false );
+    LOG << "Conditions database opened: " << std::endl;
+    LOG << "-> Database ID: " << db2->databaseId() << std::endl;
+    std::ostringstream db2Attr;
+    db2->databaseAttributes().print( db2Attr );
+    LOG << "-> Database attributes: " << db2Attr.str() << std::endl;
+
+    // Print the list of folders
+    folderList = db2->getFolderSet( "/cms/ecal" )->listFolders();
+    LOG << "-> List of folders in the database:" << std::endl;
+    for( folderIt = folderList.begin(); 
+         folderIt != folderList.end(); 
+         folderIt++ ) {
+      std::cout << *folderIt << std::endl;
+    }    
+
+    // *** WARNING!! ***
+    // You MUST get a new handle to the folder here: the old one is invalid and
+    // causes a segmentation fault. A protection must be added in the code!
+    folderPed = db2->getFolder( folderPedName );
+
+    // Bulk-retrieve the objects stored in channel 13 in [45,95]
+    std::string tag = "";
+    ChannelId channelId = 13;
+    ValidityKey since = 45;
+    ValidityKey until = 95;  
+    IObjectIteratorPtr objIt = 
+      folderPed->browseObjects( since, until, channelId, tag );
+    LOG << "Retrieved object iterator in [45,95] for channel 13 of folder "
+        << folderPed->fullPath() << std::endl;
+    if ( objIt->isEmpty() ) {
+      LOG << "Iterator contains no objects" << std::endl;
+    } else {
+      objIt->goToStart();
+      while( objIt->hasNext() ) {
+        IObjectPtr object = objIt->next();
+        LOG << "Object: channelId=" << object->channelId()
+            << ", since=" << object->since() 
+            << ", until=" << object->until() << std::endl;
+        LOG << "Object: payload values (true types)"
+            << ": payload[\"value00\"]=" 
+            << object->payloadValue<long>("value00")
+            << std::endl;
+        if( ! object->isStored() ) {
+          LOG << "Object: isStored=false" << std::endl;
+        } else {
+          LOG << "Object: isStored=true, insertionTime=" 
+              << timeToString( object->insertionTime() ) << std::endl;;
+        }
+      } 
+    }
+
+    // Successful completion
+    LOG << "Program terminating succesfully" << std::endl;
+    status = 0;
+    
+  }
+  catch(std::exception& e)
+  {
+    LOG << "ERROR! Standard C++ exception: '" << e.what() << "'" << std::endl;
+    status = 1;
+  }
+  catch(...) 
+  {
+    LOG << "ERROR! Unknown exception caught" << std::endl;
+    status = 1;
+  }
+
+  // Program termination
+  LOG << "Exiting main" << std::endl;
+  return status;
+  
+}
+
+//-----------------------------------------------------------------------------
+
+#endif // NOPORT
diff --git a/RelationalCool/tests/CMS_extRef/extraSQL.sql b/RelationalCool/tests/CMS_extRef/extraSQL.sql
new file mode 100644
index 000000000..e107bb977
--- /dev/null
+++ b/RelationalCool/tests/CMS_extRef/extraSQL.sql
@@ -0,0 +1,41 @@
+
+/*
+-- To restart from scratch... 
+alter table CMSCALIB_F0003_IOVS drop constraint CMSCALIB_F0003_IOVS_CHS_FK;
+alter table CMSCALIB_F0003_IOVS drop constraint CMSCALIB_F0003_IOVS_CALSET_FK;
+drop table CMSCALIB_F0003_CHANNELS;
+drop table CMSCALIB_EXT_CALIBSET;
+*/
+
+create table CMSCALIB_F0003_CHANNELS
+( channel_id number(38), channel_description varchar2(1024) );
+
+alter table CMSCALIB_F0003_CHANNELS
+add constraint CMSCALIB_F0003_CHANNELS_PK primary key ( channel_id );
+
+insert into CMSCALIB_F0003_CHANNELS
+select distinct channel_id, 
+'Calibration channel '||channel_id from CMSCALIB_F0003_IOVS;
+
+alter table CMSCALIB_F0003_IOVS
+add constraint CMSCALIB_F0003_IOVS_CHS_FK
+foreign key ( channel_id ) 
+references CMSCALIB_F0003_CHANNELS ( channel_id );
+
+create table CMSCALIB_EXT_CALIBSET
+( calset_id number(38), calibset_description varchar2(1024) );
+
+alter table CMSCALIB_EXT_CALIBSET
+add constraint CMSCALIB_CALIBSET_PK primary key ( calset_id );
+
+insert into CMSCALIB_EXT_CALIBSET
+select distinct calset_id, 
+'Calibration set '||calset_id from CMSCALIB_F0003_IOVS;
+
+alter table CMSCALIB_F0003_IOVS
+add constraint CMSCALIB_F0003_IOVS_CALSET_FK
+foreign key ( calset_id ) 
+references CMSCALIB_EXT_CALIBSET ( calset_id );
+
+
+
diff --git a/RelationalCool/tests/CMS_extRef/testCmsExtRef.cpp b/RelationalCool/tests/CMS_extRef/testCmsExtRef.cpp
new file mode 100644
index 000000000..f8c640e83
--- /dev/null
+++ b/RelationalCool/tests/CMS_extRef/testCmsExtRef.cpp
@@ -0,0 +1,267 @@
+// PORT -- temporarily disabled: not part of our official test suite
+int main() { return 0; }
+#ifdef NOPORT
+
+// $Id: testCmsExtRef.cpp,v 1.13 2008-08-27 09:34:27 avalassi Exp $
+
+// Include files
+#include <iostream>
+#include <sstream>
+#include "AttributeList/AttributeList.h"
+#include "CoolKernel/DatabaseId.h"
+#include "CoolKernel/IDatabase.h"
+#include "CoolKernel/IDatabaseSvc.h"
+#include "CoolKernel/IFolder.h"
+#include "CoolKernel/IFolderSet.h"
+#include "CoolKernel/IObject.h"
+#include "CoolKernel/IObjectIterator.h"
+#include "src/CoralApplication.h"
+#include "src/sleep.h"
+#include "src/timeToString.h"
+#include "src/uppercaseString.h"
+
+// Namespace
+using namespace cool;
+
+// Message output
+#define LOG std::cout << "__main "
+
+//-----------------------------------------------------------------------------
+
+int main ( int /* argc */, char* /* argv[] */ )
+{
+
+  LOG << "Entering main" << std::endl;
+  int status = -1;
+
+  // Connection string
+  std::string connectString;
+  if ( getenv( "COOLCMSEXTDB" ) ) {
+    connectString = getenv( "COOLCMSEXTDB" );
+  } else {
+    std::cout << "Please provide a connect string in "
+              << "the environment variable COOLCMSEXTDB, e.g." 
+              << std::endl;
+    std::cout << "setenv COOLCMSEXTDB "
+              << "\"oracle://cooldb2;schema=AVALASSI;"
+              << "user=avalassi;password=PASSWORD;dbname=CMSCALIB\"" 
+              << std::endl;
+    std::cout << "setenv COOLCMSEXTDB "
+              << "\"mysql://lxb0771;schema=AVALASSI;"
+              << "user=avalassi;password=PASSWORD;dbname=CMSCALIB\"" 
+              << std::endl;
+    std::cout << "Aborting test" << std::endl;
+    exit(-1);
+  }
+
+  try {
+    
+    LOG << "Get a handle to the COOL database service" << std::endl;
+    CoralApplication app;
+    IDatabaseSvc& dbSvc = app.databaseService();
+  
+    //------------------------
+    // DEFINE THE DATABASE ID
+    //------------------------
+    
+    cool::DatabaseId dbId = connectString;
+
+    //--------------------------------
+    // DROP THE DATABASE IF IT EXISTS
+    //--------------------------------
+    
+    // Drop the COOL conditions database if it already exists
+    LOG << "Drop if it exists the conditions database: " << dbId << std::endl;
+    dbSvc.dropDatabase( dbId );
+
+    //-----------------------
+    // CREATE A NEW DATABASE
+    //-----------------------
+    
+    // Create a new COOL conditions database
+    LOG << "Create a new conditions database: " << dbId << std::endl;
+    cool::IDatabasePtr db1 = dbSvc.createDatabase( dbId );
+    LOG << "Conditions database created: " << std::endl;
+    LOG << "-> Database ID: " << db1->databaseId() << std::endl;
+    std::ostringstream dbAttr;
+    db1->databaseAttributes().print( dbAttr );
+    LOG << "-> Database attributes: " << dbAttr.str() << std::endl;
+
+    // TEMPORARY? Patch for the ORA-01466 problem: sleep one second
+    cool::sleep(1);
+
+    // Create calibration folder 
+    pool::AttributeListSpecification folderCalSpec;
+    folderCalSpec.push_back("CALSET_ID","long");
+    std::string folderCalName( "/cms/hcal/calibration" );
+    cool::IFolderPtr folderCal = db1->createFolder
+      ( folderCalName, folderCalSpec, "", 
+        FolderVersioning::MULTI_VERSION, true );
+    LOG << "Folder created: " << std::endl;
+    LOG << "-> Folder name: " << folderCal->fullPath() << std::endl;
+    std::ostringstream folderCalAttr;
+    folderCal->payloadSpecification().print( folderCalAttr );
+    LOG << "-> Folder payload specification: " 
+        << folderCalAttr.str() << std::endl;
+
+    // TEMPORARY? Patch for the ORA-01466 problem: sleep one second
+    cool::sleep(1);
+
+    // Print the list of folders
+    std::vector<std::string> folderList;
+    std::vector<std::string>::iterator folderIt;
+    folderList = db1->getFolderSet( "/cms/hcal" )->listFolders();
+    LOG << "-> List of folders in the database:" << std::endl;
+    for( folderIt = folderList.begin(); 
+         folderIt != folderList.end(); 
+         folderIt++ ) {
+      std::cout << *folderIt << std::endl;
+    }    
+
+    /*
+    // Define an external reference constraint on the folder payload columns
+    std::string constraintName = "CALIBSET";
+    std::vector<std::string> attributes;
+    attributes.push_back( "CALSET_ID" );
+    std::string referencedEntity = 
+      "local://schema=AVALASSI;table=CMS_EXT_CALIBRATION_SETS";    
+    std::vector<std::string> referencedAttributes;
+    referencedAttributes.push_back( "SET_ID" );
+    folderCal->declareExternalReference
+      ( constraintName, attributes, referencedEntity, referencedAttributes );
+    */
+
+    // Bulk insert data into caibration folder 
+    // In online folders, until=+infinity means valid until next iov
+    unsigned nChannels = 10;
+    unsigned nKeys = 20;
+    unsigned chId;
+    unsigned key;
+    ValidityKey plusInfinity = ValidityKeyMax;
+    pool::AttributeList folderCalData( folderCalSpec );
+    folderCal->setupStorageBuffer();
+    for ( chId = 1; chId <= nChannels; chId ++ ) {
+      for ( key = 1; key <= nKeys; key ++ ) {
+        folderCalData["CALSET_ID"].setValue<long>
+          ( (long)10*(key-key/3*3)+chId );
+        folderCal->storeObject( key*10, plusInfinity, folderCalData, chId );
+      }
+      // Hack: bulk insertion into different channels is not supported yet!
+      folderCal->flushStorageBuffer();
+    }
+    // NO: bulk insertion into different channels is not supported yet!
+    //folderCal->flushStorageBuffer();
+
+    // Dump the object stored for time t=55 in channel 7
+    IObjectPtr objPed_ch7_55 = folderCal->findObject( 55, 7 );
+    LOG << "Retrieved object valid at t=55 in channel 7 of folder "
+        << folderCal->fullPath() << std::endl;
+    LOG << "Object: channelId=" << objPed_ch7_55->channelId() << std::endl;
+    LOG << "Object: since=" << objPed_ch7_55->since() 
+        << ", until=" << objPed_ch7_55->until() << std::endl;
+    LOG << "Object: payload values (true types)"
+        << ": payload[\"CALSET_ID\"]=" 
+        << objPed_ch7_55->payloadValue<long>("CALSET_ID")
+        << std::endl;
+    LOG << "Object: payload values (as strings)"
+        << ": payload[\"CALSET_ID\"]=" 
+        << objPed_ch7_55->payloadValue("CALSET_ID")
+        << std::endl;
+    if( ! objPed_ch7_55->isStored() ) {
+      LOG << "Object: isStored=false" << std::endl;
+    } else {
+      LOG << "Object: isStored=true" << std::endl;
+      LOG << "Object: insertionTime=" 
+          << timeToString( objPed_ch7_55->insertionTime() ) << std::endl;;
+    }
+
+    // Reset the database pointer: this will close the connection
+    LOG << "Release the conditions database connection" << std::endl;
+    cool::IDatabasePtr dbNull;
+    db1 = dbNull;
+
+    /*
+    //---------------------------
+    // OPEN AN EXISTING DATABASE
+    //---------------------------
+
+    // Open an existing COOL conditions database
+    LOG << "Open an existing conditions database: " << dbId << std::endl;
+    cool::IDatabasePtr db2 = dbSvc.openDatabase( dbId );
+    LOG << "Conditions database opened: " << std::endl;
+    LOG << "-> Database ID: " << db2->databaseId() << std::endl;
+    std::ostringstream db2Attr;
+    db2->databaseAttributes().print( db2Attr );
+    LOG << "-> Database attributes: " << db2Attr.str() << std::endl;
+
+    // Print the list of folders
+    folderList = db2->listFolders();
+    LOG << "-> List of folders in the database:" << std::endl;
+    for( folderIt = folderList.begin(); 
+         folderIt != folderList.end(); 
+         folderIt++ ) {
+      std::cout << *folderIt << std::endl;
+    }    
+
+    // *** WARNING!! ***
+    // You MUST get a new handle to the folder here: the old one is invalid and
+    // causes a segmentation fault. A protection must be added in the code!
+    folderCal = db2->getFolder( folderCalName );
+
+    // Bulk-retrieve the objects stored in channel 7 in [45,95]
+    std::string tag = "";
+    ChannelId channelId = 7;
+    ValidityKey since = 45;
+    ValidityKey until = 95;  
+    IObjectIteratorPtr objIt = 
+      folderCal->browseObjects( since, until, channelId, tag );
+    LOG << "Retrieved object iterator in [45,95] for channel 7 of folder "
+        << folderCal->fullPath() << std::endl;
+    if ( objIt->isEmpty() ) {
+      LOG << "Iterator contains no objects" << std::endl;
+    } else {
+      objIt->goToStart();
+      while( objIt->hasNext() ) {
+        IObjectPtr object = objIt->next();
+        LOG << "Object: channelId=" << object->channelId()
+            << ", since=" << object->since() 
+            << ", until=" << object->until() << std::endl;
+        LOG << "Object: payload values (true types)"
+            << ": payload[\"CALSET_ID\"]=" 
+            << object->payloadValue<long>("CALSET_ID")
+            << std::endl;
+        if( ! object->isStored() ) {
+          LOG << "Object: isStored=false" << std::endl;
+        } else {
+          LOG << "Object: isStored=true, insertionTime=" 
+              << timeToString( object->insertionTime() ) << std::endl;;
+        }
+      } 
+    }
+    */
+
+    // Successful completion
+    LOG << "Program terminating succesfully" << std::endl;
+    status = 0;
+    
+  }
+  catch(std::exception& e)
+  {
+    LOG << "ERROR! Standard C++ exception: '" << e.what() << "'" << std::endl;
+    status = 1;
+  }
+  catch(...) 
+  {
+    LOG << "ERROR! Unknown exception caught" << std::endl;
+    status = 1;
+  }
+
+  // Program termination
+  LOG << "Exiting main" << std::endl;
+  return status;
+  
+}
+
+//-----------------------------------------------------------------------------
+
+#endif // NOPORT
diff --git a/RelationalCool/tests/ChannelSelection/test_ChannelSelection.cpp b/RelationalCool/tests/ChannelSelection/test_ChannelSelection.cpp
new file mode 100644
index 000000000..d4b879cea
--- /dev/null
+++ b/RelationalCool/tests/ChannelSelection/test_ChannelSelection.cpp
@@ -0,0 +1,356 @@
+// $Id: test_ChannelSelection.cpp,v 1.6 2009-01-06 13:54:38 avalassi Exp $
+/**
+
+@file test_ChannelSelection.cpp
+
+@author Sven A. Schmidt and Marco Clemencic
+
+@date 2006-04-25
+
+*/
+
+#include "CoolUnitTest.h"
+
+#include "CoolKernel/ChannelSelection.h"
+#include "CoolKernel/Exception.h"
+
+namespace cool 
+{
+
+  class ChannelSelectionTest : public CoolUnitTest 
+  {
+
+    CPPUNIT_TEST_SUITE( ChannelSelectionTest );
+
+    CPPUNIT_TEST( test_default_constructor );
+    CPPUNIT_TEST( test_from_int );
+    CPPUNIT_TEST( test_order );
+    CPPUNIT_TEST( test_InvalidChannelRange );
+    CPPUNIT_TEST( test_range );
+    CPPUNIT_TEST( test_range_order );
+    CPPUNIT_TEST( test_all );
+    CPPUNIT_TEST( test_ChannelRange );
+    CPPUNIT_TEST( test_ChannelRange_inRange );
+    CPPUNIT_TEST( test_inSelection );
+    CPPUNIT_TEST( test_addRange );
+    CPPUNIT_TEST( test_addRange_outOfOrder );
+    CPPUNIT_TEST( test_addRange_overlap );
+    CPPUNIT_TEST( test_isContiguous );
+    CPPUNIT_TEST( test_addChannel );
+    CPPUNIT_TEST( test_addChannel_outOfOrder );
+    CPPUNIT_TEST( test_addChannel_overlap );
+    CPPUNIT_TEST( test_channelName_constructor );
+    CPPUNIT_TEST( test_non_numeric_exceptions );
+    CPPUNIT_TEST( test_numeric_exceptions );
+    CPPUNIT_TEST( test_inSelection_string );
+    
+    CPPUNIT_TEST_SUITE_END();
+
+  public:
+
+    void test_default_constructor() {
+      ChannelSelection s;
+      CPPUNIT_ASSERT_EQUAL( (ChannelId)0, s.firstChannel() );
+      CPPUNIT_ASSERT_EQUAL( (ChannelId)4294967295ul, s.lastChannel() );
+      CPPUNIT_ASSERT_EQUAL( ChannelSelection::channelBeforeSince, s.order() );
+      CPPUNIT_ASSERT( s.allChannels() );
+      CPPUNIT_ASSERT( s.isNumeric() );
+    }
+
+
+    void test_from_int() {
+      ChannelSelection s( 5 );
+      CPPUNIT_ASSERT_EQUAL( (ChannelId)5, s.firstChannel() );
+      CPPUNIT_ASSERT_EQUAL( (ChannelId)5, s.lastChannel() );
+      CPPUNIT_ASSERT_EQUAL( ChannelSelection::channelBeforeSince, s.order() );
+      CPPUNIT_ASSERT( ! s.allChannels() );
+      CPPUNIT_ASSERT( s.isNumeric() );
+    }
+
+
+    void test_order() {
+      ChannelSelection s( ChannelSelection::sinceBeforeChannel );
+      CPPUNIT_ASSERT_EQUAL( (ChannelId)0, s.firstChannel() );
+      CPPUNIT_ASSERT_EQUAL( (ChannelId)4294967295ul, s.lastChannel() );
+      CPPUNIT_ASSERT_EQUAL( ChannelSelection::sinceBeforeChannel, s.order() );
+      CPPUNIT_ASSERT( s.allChannels() );
+      CPPUNIT_ASSERT( s.isNumeric() );
+    }
+
+
+    /// Tests exceptional behavior of the ChannelSelection constructor
+    void test_InvalidChannelRange() {
+      CPPUNIT_ASSERT_THROW( ChannelSelection s( 3, 2 ),
+                            InvalidChannelRange );
+    }
+
+    void test_range() {
+      ChannelSelection s( 5, 10 );
+      CPPUNIT_ASSERT_EQUAL( (ChannelId)5, s.firstChannel() );
+      CPPUNIT_ASSERT_EQUAL( (ChannelId)10, s.lastChannel() );
+      CPPUNIT_ASSERT_EQUAL( ChannelSelection::channelBeforeSince, s.order() );
+      CPPUNIT_ASSERT( ! s.allChannels() );
+      CPPUNIT_ASSERT( s.isNumeric() );
+    }
+
+
+    void test_range_order() {
+      ChannelSelection s( 5, 10, ChannelSelection::sinceBeforeChannel );
+      CPPUNIT_ASSERT_EQUAL( (ChannelId)5, s.firstChannel() );
+      CPPUNIT_ASSERT_EQUAL( (ChannelId)10, s.lastChannel() );
+      CPPUNIT_ASSERT_EQUAL( ChannelSelection::sinceBeforeChannel, s.order() );
+      CPPUNIT_ASSERT( ! s.allChannels() );
+      CPPUNIT_ASSERT( s.isNumeric() );
+    }
+
+
+    void test_all() {
+      ChannelSelection s = ChannelSelection::all();
+      CPPUNIT_ASSERT_EQUAL( (ChannelId)0, s.firstChannel() );
+      CPPUNIT_ASSERT_EQUAL( (ChannelId)4294967295ul, s.lastChannel() );
+      CPPUNIT_ASSERT_EQUAL( ChannelSelection::channelBeforeSince, s.order() );
+      CPPUNIT_ASSERT( s.allChannels() );
+      CPPUNIT_ASSERT( s.isNumeric() );
+    }
+
+
+    void test_ChannelRange() {
+      ChannelSelection::ChannelRange r( 2, 4 );
+      CPPUNIT_ASSERT_EQUAL( (ChannelId)2, r.firstChannel() );
+      CPPUNIT_ASSERT_EQUAL( (ChannelId)4, r.lastChannel() );
+    }
+
+
+    void test_ChannelRange_inRange() {
+      ChannelSelection::ChannelRange r( 2, 4 );
+      CPPUNIT_ASSERT( ! r.inRange( 1 ) );
+      CPPUNIT_ASSERT( r.inRange( 2 ) );
+      CPPUNIT_ASSERT( r.inRange( 3 ) );
+      CPPUNIT_ASSERT( r.inRange( 4 ) );
+      CPPUNIT_ASSERT( ! r.inRange( 5 ) );
+    }
+
+
+    void test_inSelection() {
+      ChannelSelection s( 2, 4 );
+      CPPUNIT_ASSERT( ! s.inSelection( 1 ) );
+      CPPUNIT_ASSERT( s.inSelection( 2 ) );
+      CPPUNIT_ASSERT( s.inSelection( 3 ) );
+      CPPUNIT_ASSERT( s.inSelection( 4 ) );
+      CPPUNIT_ASSERT( ! s.inSelection( 5 ) );
+    }
+
+
+    void test_addRange() {
+      ChannelSelection s( 2, 4 );
+      s.addRange( 6, 8 );
+      CPPUNIT_ASSERT( ! s.inSelection( 1 ) );
+      CPPUNIT_ASSERT( s.inSelection( 2 ) );
+      CPPUNIT_ASSERT( s.inSelection( 3 ) );
+      CPPUNIT_ASSERT( s.inSelection( 4 ) );
+      CPPUNIT_ASSERT( ! s.inSelection( 5 ) );
+      CPPUNIT_ASSERT( s.inSelection( 6 ) );
+      CPPUNIT_ASSERT( s.inSelection( 7 ) );
+      CPPUNIT_ASSERT( s.inSelection( 8 ) );
+      CPPUNIT_ASSERT( ! s.inSelection( 9 ) );
+      CPPUNIT_ASSERT( ! s.isContiguous() );
+    }
+
+
+    void test_addRange_outOfOrder() {
+      ChannelSelection s( 6, 8 );
+      s.addRange( 2, 4 );
+      CPPUNIT_ASSERT( ! s.inSelection( 1 ) );
+      CPPUNIT_ASSERT( s.inSelection( 2 ) );
+      CPPUNIT_ASSERT( s.inSelection( 3 ) );
+      CPPUNIT_ASSERT( s.inSelection( 4 ) );
+      CPPUNIT_ASSERT( ! s.inSelection( 5 ) );
+      CPPUNIT_ASSERT( s.inSelection( 6 ) );
+      CPPUNIT_ASSERT( s.inSelection( 7 ) );
+      CPPUNIT_ASSERT( s.inSelection( 8 ) );
+      CPPUNIT_ASSERT( ! s.inSelection( 9 ) );
+      CPPUNIT_ASSERT( ! s.isContiguous() );
+    }
+
+
+    /// Tests isContiguous for multiple ranges
+    void test_isContiguous() {
+      {
+        ChannelSelection s( 5, 7 );
+        CPPUNIT_ASSERT( s.isContiguous() );
+        s.addChannel( 8 );
+        CPPUNIT_ASSERT( s.isContiguous() );
+        s.addRange( 3, 4 );
+        CPPUNIT_ASSERT( s.isContiguous() );
+        s.addRange( 9, 10 );
+        CPPUNIT_ASSERT( s.isContiguous() );
+        s.addRange( 0, 1 );
+        CPPUNIT_ASSERT( ! s.isContiguous() );
+      }
+      {
+        ChannelSelection s( 4, 5 );
+        CPPUNIT_ASSERT( s.isContiguous() );
+        s.addRange( 7,8 );
+        CPPUNIT_ASSERT( ! s.isContiguous() );
+      }
+    }
+
+
+    void test_addRange_overlap() {
+      try {
+        ChannelSelection s( 6, 8 );
+        s.addRange( 2, 7 );
+        CPPUNIT_FAIL( "Exception excepted" );
+      } catch ( Exception& e ) {
+        CPPUNIT_ASSERT_EQUAL( std::string( "Cannot add range [2,7], "
+                                           "because it overlaps with "
+                                           "selection" ),
+                              std::string( e.what() ) );
+      }
+      try {
+        ChannelSelection s( 6, 8 );
+        s.addRange( 7, 9 );
+        CPPUNIT_FAIL( "Exception excepted" );
+      } catch ( Exception& e ) {
+        CPPUNIT_ASSERT_EQUAL( std::string( "Cannot add range [7,9], "
+                                           "because it overlaps with "
+                                           "selection" ),
+                              std::string( e.what() ) );
+      }
+    }
+
+
+    void test_addChannel() {
+      ChannelSelection s( 2, 4 );
+      s.addChannel( 6 );
+      CPPUNIT_ASSERT( ! s.inSelection( 1 ) );
+      CPPUNIT_ASSERT( s.inSelection( 2 ) );
+      CPPUNIT_ASSERT( s.inSelection( 3 ) );
+      CPPUNIT_ASSERT( s.inSelection( 4 ) );
+      CPPUNIT_ASSERT( ! s.inSelection( 5 ) );
+      CPPUNIT_ASSERT( s.inSelection( 6 ) );
+      CPPUNIT_ASSERT( ! s.inSelection( 7 ) );
+      CPPUNIT_ASSERT( ! s.isContiguous() );
+    }
+
+
+    void test_addChannel_outOfOrder() {
+      ChannelSelection s( 4, 6 );
+      s.addChannel( 2 );
+      CPPUNIT_ASSERT( ! s.inSelection( 1 ) );
+      CPPUNIT_ASSERT( s.inSelection( 2 ) );
+      CPPUNIT_ASSERT( ! s.inSelection( 3 ) );
+      CPPUNIT_ASSERT( s.inSelection( 4 ) );
+      CPPUNIT_ASSERT( s.inSelection( 5 ) );
+      CPPUNIT_ASSERT( s.inSelection( 6 ) );
+      CPPUNIT_ASSERT( ! s.inSelection( 7 ) );
+      CPPUNIT_ASSERT( ! s.isContiguous() );
+    }
+
+
+    void test_addChannel_overlap() {
+      try {
+        ChannelSelection s( 6, 8 );
+        s.addChannel( 7 );
+        CPPUNIT_FAIL( "Exception excepted" );
+      } catch ( Exception& e ) {
+        CPPUNIT_ASSERT_EQUAL( std::string( "Cannot add range [7,7], "
+                                           "because it overlaps with "
+                                           "selection" ),
+                              std::string( e.what() ) );
+      }
+    }
+
+
+    void test_channelName_constructor() {
+      ChannelSelection s( "channel A" );
+      CPPUNIT_ASSERT( ! s.isNumeric() );
+      CPPUNIT_ASSERT_EQUAL( ChannelSelection::channelBeforeSince, s.order() );
+      CPPUNIT_ASSERT( ! s.allChannels() );
+      CPPUNIT_ASSERT_EQUAL( std::string("channel A"), s.channelName() );
+    }
+    
+    
+    void test_non_numeric_exceptions() {
+      ChannelSelection s( "channel A" );
+
+      try {
+        s.addChannel( 0 );
+        CPPUNIT_FAIL( "Expected exception" );
+      } catch ( Exception& e ) {
+        CPPUNIT_ASSERT_EQUAL( std::string("Numeric method called for "
+                                          "non-numeric ChannelSelection"),
+                             std::string(e.what()) );
+      }
+      try {
+        s.addRange( 0, 1 );
+        CPPUNIT_FAIL( "Expected exception" );
+      } catch ( Exception& e ) {
+        CPPUNIT_ASSERT_EQUAL( std::string("Numeric method called for "
+                                          "non-numeric ChannelSelection"),
+                             std::string(e.what()) );
+      }
+      try {
+        s.firstChannel();
+        CPPUNIT_FAIL( "Expected exception" );
+      } catch ( Exception& e ) {
+        CPPUNIT_ASSERT_EQUAL( std::string("Numeric method called for "
+                                          "non-numeric ChannelSelection"),
+                             std::string(e.what()) );
+      }
+      try {
+        s.lastChannel();
+        CPPUNIT_FAIL( "Expected exception" );
+      } catch ( Exception& e ) {
+        CPPUNIT_ASSERT_EQUAL( std::string("Numeric method called for "
+                                          "non-numeric ChannelSelection"),
+                             std::string(e.what()) );
+      }
+      try {
+        s.inSelection( 0 );
+        CPPUNIT_FAIL( "Expected exception" );
+      } catch ( Exception& e ) {
+        CPPUNIT_ASSERT_EQUAL( std::string("Numeric method called for "
+                                          "non-numeric ChannelSelection"),
+                              std::string(e.what()) );
+      }
+      try {
+        s.isContiguous();
+        CPPUNIT_FAIL( "Expected exception" );
+      } catch ( Exception& e ) {
+        CPPUNIT_ASSERT_EQUAL( std::string("Numeric method called for "
+                                          "non-numeric ChannelSelection"),
+                             std::string(e.what()) );
+      }
+    }
+    
+    
+    void test_numeric_exceptions() {
+      ChannelSelection s( 0 );
+      
+      try {
+        s.inSelection( "channel 1" );
+        CPPUNIT_FAIL( "Expected exception" );
+      } catch ( Exception& e ) {
+        CPPUNIT_ASSERT_EQUAL( std::string("Non-numeric method called for "
+                                          "numeric ChannelSelection"),
+                             std::string(e.what()) );
+      }
+    }
+    
+    
+    void test_inSelection_string() {
+      ChannelSelection s( "channel 1" );
+      CPPUNIT_ASSERT( ! s.inSelection( "channel 0" ) );
+      CPPUNIT_ASSERT( s.inSelection( "channel 1" ) );
+    }
+    
+    
+  };
+
+CPPUNIT_TEST_SUITE_REGISTRATION( ChannelSelectionTest );
+
+} // namespace
+
+COOLTEST_MAIN( ChannelSelectionTest )
+
diff --git a/RelationalCool/tests/Channels/test_Channels.cpp b/RelationalCool/tests/Channels/test_Channels.cpp
new file mode 100644
index 000000000..63c920f11
--- /dev/null
+++ b/RelationalCool/tests/Channels/test_Channels.cpp
@@ -0,0 +1,685 @@
+/**
+
+@file test_Channels.cpp
+
+*/
+
+#include "CoolDBUnitTest.h"
+
+#include "RelationalAccess/IRelationalService.h"
+#include "CoralBase/Attribute.h"
+#include "CoralBase/AttributeListException.h"
+
+#include "CoolKernel/ChannelSelection.h"
+#include "CoolKernel/IDatabaseSvc.h"
+#include "CoolKernel/IField.h"
+#include "CoolKernel/IFolder.h"
+#include "CoolKernel/IObject.h"
+#include "CoolKernel/IObjectIterator.h"
+#include "CoolKernel/Record.h"
+#include "CoolKernel/RecordException.h"
+#include "CoolKernel/RecordSpecification.h"
+
+#include "src/RalDatabase.h"
+#include "src/RelationalChannelTable.h"
+#include "src/RelationalException.h"
+#include "src/RelationalFolder.h"
+#include "src/RelationalTableRow.h"
+#include "src/RelationalTransaction.h"
+#include "src/timeToString.h"
+
+// ---- this things are needed to force a drop of the connection
+#include "src/RalDatabaseSvc.h"
+#include "RelationalAccess/IConnectionService.h"
+#include "RelationalAccess/IConnectionServiceConfiguration.h"
+
+using coral::AttributeList;
+using coral::AttributeListSpecification;
+
+#include <string>
+using std::cout;
+using std::endl;
+using std::string;
+using std::stringstream;
+
+#include <vector>
+using std::vector;
+
+namespace cool 
+{
+
+  //! \brief Channels test class.
+  class ChannelsTest : public CoolDBUnitTest
+  {
+    
+    CPPUNIT_TEST_SUITE( ChannelsTest );
+
+    CPPUNIT_TEST( test_listChannels );
+    CPPUNIT_TEST( test_listChannels_order );
+    CPPUNIT_TEST( test_listChannelsWithNames );
+    
+    CPPUNIT_TEST( test_createChannel );
+    CPPUNIT_TEST( test_dropChannel );
+    CPPUNIT_TEST( test_dropChannel_exceptionSV );
+    CPPUNIT_TEST( test_dropChannel_exceptionMV );
+    CPPUNIT_TEST( test_existsChannel );
+    CPPUNIT_TEST( test_channelId );
+    CPPUNIT_TEST( test_channelName_exception );
+    CPPUNIT_TEST( test_channelDescription_exception );
+    CPPUNIT_TEST( test_channelId_exception );
+    CPPUNIT_TEST( test_setChannelName );
+    CPPUNIT_TEST( test_setChannelDescription );
+
+    CPPUNIT_TEST( test_channelNameUnique );
+
+    CPPUNIT_TEST( test_setChannelName_sameName );
+
+    CPPUNIT_TEST( test_existsChannelSV_withoutCreateChannel );
+    CPPUNIT_TEST( test_existsChannelMV_withoutCreateChannel );
+    CPPUNIT_TEST( test_setChannelNameSV_withoutCreateChannel );
+    CPPUNIT_TEST( test_setChannelNameMV_withoutCreateChannel );
+    CPPUNIT_TEST( test_setChannelDescSV_withoutCreateChannel );
+    CPPUNIT_TEST( test_setChannelDescMV_withoutCreateChannel );
+    CPPUNIT_TEST( test_channelNameSV_withoutCreateChannel );
+    CPPUNIT_TEST( test_channelNameMV_withoutCreateChannel );
+    CPPUNIT_TEST( test_channelDescSV_withoutCreateChannel );
+    CPPUNIT_TEST( test_channelDescMV_withoutCreateChannel );
+
+    CPPUNIT_TEST( test_existsChannelSV_withCreateChannel_withoutIOVs );
+    CPPUNIT_TEST( test_existsChannelMV_withCreateChannel_withoutIOVs );
+
+    CPPUNIT_TEST( test_listChannelsSV_withoutCreateChannel );
+    CPPUNIT_TEST( test_listChannelsMV_withoutCreateChannel );
+    CPPUNIT_TEST( test_listChannelsSV_withCreateChannel_withoutIOVs );
+    CPPUNIT_TEST( test_listChannelsMV_withCreateChannel_withoutIOVs );
+    CPPUNIT_TEST( test_listChannelsSV_withAndWithoutCreateChannel );
+    CPPUNIT_TEST( test_listChannelsMV_withAndWithoutCreateChannel );
+
+    CPPUNIT_TEST_SUITE_END();
+
+  public:
+
+    RecordSpecification payloadSpec;
+
+    /// Tests setChannelDescription()
+    void test_setChannelDescription() 
+    {
+      IFolderPtr folder = m_db->createFolder( "/f1", payloadSpec );
+      folder->createChannel( 1, "ch 1", "desc 1" );
+      CPPUNIT_ASSERT_EQUAL( std::string("desc 1"),
+                            folder->channelDescription( 1 ) );
+      folder->setChannelDescription( 1, "new desc" );
+      CPPUNIT_ASSERT_EQUAL( std::string("new desc"),
+                            folder->channelDescription( 1 ) );
+      try {
+        folder->setChannelDescription( 2, "new desc" );
+        CPPUNIT_FAIL( "ChannelNotFound exception expected" );
+      } catch ( ChannelNotFound& ) {}
+    }
+
+
+    /// Tests setChannelName()
+    void test_setChannelName() 
+    {
+      IFolderPtr folder = m_db->createFolder( "/f1", payloadSpec );
+      folder->createChannel( 1, "ch 1", "desc 1" );
+      CPPUNIT_ASSERT_EQUAL( std::string("ch 1"),
+                            folder->channelName( 1 ) );
+      folder->setChannelName( 1, "new name 1" );
+      CPPUNIT_ASSERT_EQUAL( std::string("new name 1"),
+                            folder->channelName( 1 ) );
+      try {
+        folder->setChannelName( 2, "new name 2" );
+        CPPUNIT_FAIL( "ChannelNotFound exception expected" );
+      } catch ( ChannelNotFound& ) {}
+      folder->createChannel( 2, "ch 2", "desc 2" );
+      CPPUNIT_ASSERT_EQUAL( std::string("ch 2"),
+                            folder->channelName( 2 ) );
+      try {
+        folder->setChannelName( 2, "new name 1" );
+        CPPUNIT_FAIL( "ChannelExists exception expected" );
+      } catch ( ChannelExists& ) {}
+    }
+
+
+    /// Tests setChannelName() with the same name (bug #23754)
+    void test_setChannelName_sameName() {
+      IFolderPtr folder = m_db->createFolder( "/f1", payloadSpec );
+      folder->createChannel( 1, "ch 1", "desc 1" );
+      CPPUNIT_ASSERT_EQUAL( std::string("ch 1"),
+                            folder->channelName( 1 ) );
+      folder->setChannelName( 1, "ch 1" );
+      CPPUNIT_ASSERT_EQUAL( std::string("ch 1"),
+                            folder->channelName( 1 ) );
+    }
+
+
+    /// Tests existsChannel() for SV folders if createChannel was not called
+    void test_existsChannelSV_withoutCreateChannel() {
+      IFolderPtr folder = m_db->createFolder
+        ( "/f1", payloadSpec, "", FolderVersioning::SINGLE_VERSION );
+      Record payload( payloadSpec );
+      ChannelId chId = 1;
+      folder->storeObject( 0, 10, payload, chId );
+      CPPUNIT_ASSERT_EQUAL
+        ( true, folder->existsChannel( chId ) );
+    }
+
+
+    /// Tests existsChannel() for MV folders if createChannel was not called
+    /// (bug #24449 - also related to bug #23755)
+    void test_existsChannelMV_withoutCreateChannel() {
+      IFolderPtr folder = m_db->createFolder
+        ( "/f1", payloadSpec, "", FolderVersioning::MULTI_VERSION );
+      Record payload( payloadSpec );
+      ChannelId chId = 1;
+      folder->storeObject( 0, 10, payload, chId );
+      CPPUNIT_ASSERT_EQUAL
+        ( true, folder->existsChannel( chId ) );
+    }
+
+
+    /// Tests existsChannel() for SV folders if createChannel was called
+    /// but there are no IOVs
+    void test_existsChannelSV_withCreateChannel_withoutIOVs() {
+      IFolderPtr folder = m_db->createFolder
+        ( "/f1", payloadSpec, "", FolderVersioning::SINGLE_VERSION );
+      Record payload( payloadSpec );
+      ChannelId chId = 1;
+      //folder->storeObject( 0, 10, payload, chId );
+      folder->createChannel( chId, "MyChannel", " A channel" );
+      CPPUNIT_ASSERT_EQUAL
+        ( true, folder->existsChannel( chId ) );
+    }
+
+
+    /// Tests existsChannel() for MV folders if createChannel was called
+    /// but there are no IOVs (bug #30431 - also related to bug #23755)
+    void test_existsChannelMV_withCreateChannel_withoutIOVs() {
+      IFolderPtr folder = m_db->createFolder
+        ( "/f1", payloadSpec, "", FolderVersioning::MULTI_VERSION );
+      Record payload( payloadSpec );
+      ChannelId chId = 1;
+      //folder->storeObject( 0, 10, payload, chId );
+      folder->createChannel( chId, "MyChannel", "A channel" );
+      CPPUNIT_ASSERT_EQUAL
+        ( true, folder->existsChannel( chId ) );
+    }
+
+
+    /// Tests listChannels() for SV folders if createChannel was not called
+    void test_listChannelsSV_withoutCreateChannel() {
+      IFolderPtr folder = m_db->createFolder
+        ( "/f1", payloadSpec, "", FolderVersioning::SINGLE_VERSION );
+      Record payload( payloadSpec );
+      ChannelId chId = 1;
+      folder->storeObject( 0, 10, payload, chId );
+      //folder->createChannel( chId, "MyChannel", " A channel" );
+      std::vector<ChannelId> channels = folder->listChannels();
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "channel count", 1u, (unsigned int)channels.size() );
+    }
+
+
+    /// Tests listChannels() for MV folders if createChannel was not called
+    void test_listChannelsMV_withoutCreateChannel() {
+      IFolderPtr folder = m_db->createFolder
+        ( "/f1", payloadSpec, "", FolderVersioning::MULTI_VERSION );
+      Record payload( payloadSpec );
+      ChannelId chId = 1;
+      folder->storeObject( 0, 10, payload, chId );
+      //folder->createChannel( chId, "MyChannel", "A channel" );
+      std::vector<ChannelId> channels = folder->listChannels();
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "channel count", 1u, (unsigned int)channels.size() );
+    }
+
+
+    /// Tests listChannels() for SV folders if createChannel was called
+    /// but there are no IOVs
+    void test_listChannelsSV_withCreateChannel_withoutIOVs() {
+      IFolderPtr folder = m_db->createFolder
+        ( "/f1", payloadSpec, "", FolderVersioning::SINGLE_VERSION );
+      Record payload( payloadSpec );
+      ChannelId chId = 1;
+      //folder->storeObject( 0, 10, payload, chId );
+      folder->createChannel( chId, "MyChannel", " A channel" );
+      std::vector<ChannelId> channels = folder->listChannels();
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "channel count", 1u, (unsigned int)channels.size() );
+    }
+
+
+    /// Tests listChannels() for MV folders if createChannel was called
+    /// but there are no IOVs (bug #30443)
+    void test_listChannelsMV_withCreateChannel_withoutIOVs() {
+      IFolderPtr folder = m_db->createFolder
+        ( "/f1", payloadSpec, "", FolderVersioning::MULTI_VERSION );
+      Record payload( payloadSpec );
+      ChannelId chId = 1;
+      //folder->storeObject( 0, 10, payload, chId );
+      folder->createChannel( chId, "MyChannel", "A channel" );
+      std::vector<ChannelId> channels = folder->listChannels();
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "channel count", 1u, (unsigned int)channels.size() );
+    }
+
+
+    /// Tests listChannels() for SV folders in a complex case
+    void test_listChannelsSV_withAndWithoutCreateChannel() {
+      IFolderPtr folder = m_db->createFolder
+        ( "/f1", payloadSpec, "", FolderVersioning::SINGLE_VERSION );
+      Record payload( payloadSpec );
+      ChannelId chId1 = 1;
+      folder->storeObject( 0, 10, payload, chId1 );
+      ChannelId chId2 = 2;
+      folder->createChannel( chId2, "MyChannel", " A channel" );
+      std::vector<ChannelId> channels = folder->listChannels();
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "channel count", 2u, (unsigned int)channels.size() );
+    }
+
+
+    /// Tests listChannels() for MV folders in a complex case
+    /// This is also affected by bug #30443 in COOL221
+    void test_listChannelsMV_withAndWithoutCreateChannel() {
+      IFolderPtr folder = m_db->createFolder
+        ( "/f1", payloadSpec, "", FolderVersioning::MULTI_VERSION );
+      Record payload( payloadSpec );
+      ChannelId chId1 = 1;
+      folder->storeObject( 0, 10, payload, chId1 );
+      ChannelId chId2 = 2;
+      folder->createChannel( chId2, "MyChannel", "A channel" );
+      std::vector<ChannelId> channels = folder->listChannels();
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "channel count", 2u, (unsigned int)channels.size() );
+    }
+
+
+    /// Tests setChannelName() for SV folders if createChannel was not called
+    void test_setChannelNameSV_withoutCreateChannel() {
+      IFolderPtr folder = m_db->createFolder
+        ( "/f1", payloadSpec, "", FolderVersioning::SINGLE_VERSION );
+      Record payload( payloadSpec );
+      ChannelId chId = 1;
+      folder->storeObject( 0, 10, payload, chId );
+      folder->setChannelName( chId, "ch 1" );
+      CPPUNIT_ASSERT_EQUAL( std::string("ch 1"), folder->channelName( chId ) );
+    }
+
+
+    /// Tests setChannelName() for MV folders if createChannel was not called
+    /// (bug #24445 - also related to bug #23755)
+    void test_setChannelNameMV_withoutCreateChannel() {
+      IFolderPtr folder = m_db->createFolder
+        ( "/f1", payloadSpec, "", FolderVersioning::MULTI_VERSION );
+      Record payload( payloadSpec );
+      ChannelId chId = 1;
+      folder->storeObject( 0, 10, payload, chId );
+      folder->setChannelName( chId, "ch 1" );
+      CPPUNIT_ASSERT_EQUAL( std::string("ch 1"), folder->channelName( chId ) );
+    }
+
+
+    /// Tests setChannelDescription() for SV if createChannel was not called
+    void test_setChannelDescSV_withoutCreateChannel() {
+      IFolderPtr folder = m_db->createFolder
+        ( "/f1", payloadSpec, "", FolderVersioning::SINGLE_VERSION );
+      Record payload( payloadSpec );
+      ChannelId chId = 1;
+      folder->storeObject( 0, 10, payload, chId );
+      folder->setChannelDescription( chId, "ch 1 desc" );
+      CPPUNIT_ASSERT_EQUAL
+        ( std::string("ch 1 desc"), folder->channelDescription( chId ) );
+    }
+
+
+    /// Tests setChannelDescription() for MV if createChannel was not called
+    /// (bug #244461 - also related to bug #23755)
+    void test_setChannelDescMV_withoutCreateChannel() {
+      IFolderPtr folder = m_db->createFolder
+        ( "/f1", payloadSpec, "", FolderVersioning::MULTI_VERSION );
+      Record payload( payloadSpec );
+      ChannelId chId = 1;
+      folder->storeObject( 0, 10, payload, chId );
+      folder->setChannelDescription( chId, "ch 1 desc" );
+      CPPUNIT_ASSERT_EQUAL
+        ( std::string("ch 1 desc"), folder->channelDescription( chId ) );
+    }
+
+
+    /// Tests channelName() for MV folders if createChannel was not called
+    void test_channelNameSV_withoutCreateChannel() {
+      IFolderPtr folder = m_db->createFolder
+        ( "/f1", payloadSpec, "", FolderVersioning::SINGLE_VERSION );
+      Record payload( payloadSpec );
+      ChannelId chId = 1;
+      folder->storeObject( 0, 10, payload, chId );
+      CPPUNIT_ASSERT_EQUAL
+        ( std::string(""), folder->channelName( chId ) );
+    }
+
+
+    /// Tests channelName() for MV folders if createChannel was not called
+    /// (bug #24463 - also related to bug #23755)
+    void test_channelNameMV_withoutCreateChannel() {
+      IFolderPtr folder = m_db->createFolder
+        ( "/f1", payloadSpec, "", FolderVersioning::MULTI_VERSION );
+      Record payload( payloadSpec );
+      ChannelId chId = 1;
+      folder->storeObject( 0, 10, payload, chId );
+      CPPUNIT_ASSERT_EQUAL
+        ( std::string(""), folder->channelName( chId ) );
+    }
+
+
+    /// Tests channelDesc() for SV folders if createChannel was not called
+    void test_channelDescSV_withoutCreateChannel() {
+      IFolderPtr folder = m_db->createFolder
+        ( "/f1", payloadSpec, "", FolderVersioning::SINGLE_VERSION );
+      Record payload( payloadSpec );
+      ChannelId chId = 1;
+      folder->storeObject( 0, 10, payload, chId );
+      CPPUNIT_ASSERT_EQUAL
+        ( std::string(""), folder->channelDescription( chId ) );
+    }
+
+
+    /// Tests channelDesc() for MV folders if createChannel was not called
+    /// (bug #24463 - also related to bug #23755)
+    void test_channelDescMV_withoutCreateChannel() {
+      IFolderPtr folder = m_db->createFolder
+        ( "/f1", payloadSpec, "", FolderVersioning::MULTI_VERSION );
+      Record payload( payloadSpec );
+      ChannelId chId = 1;
+      folder->storeObject( 0, 10, payload, chId );
+      CPPUNIT_ASSERT_EQUAL
+        ( std::string(""), folder->channelDescription( chId ) );
+    }
+
+
+    /// Tests channelId() exceptional behavior
+    void test_channelId_exception() {
+      IFolderPtr folder = m_db->createFolder( "/f1", payloadSpec );
+      CPPUNIT_ASSERT_THROW( folder->channelId( "unknown channel" ),
+                            ChannelNotFound );
+    }
+
+
+    /// Tests channelDescription() exceptional behavior
+    void test_channelDescription_exception() {
+      IFolderPtr folder = m_db->createFolder( "/f1", payloadSpec );
+      CPPUNIT_ASSERT_THROW( folder->channelDescription( 1 ),
+                            ChannelNotFound );
+    }
+
+
+    /// Tests channelName() exceptional behavior
+    void test_channelName_exception() {
+      IFolderPtr folder = m_db->createFolder( "/f1", payloadSpec );
+      CPPUNIT_ASSERT_THROW( folder->channelName( 1 ),
+                            ChannelNotFound );
+    }
+
+
+    /// Tests channelId( channelName )
+    void test_channelId() {
+      IFolderPtr folder = m_db->createFolder( "/f1", payloadSpec );
+      folder->createChannel( 1, "ch 1", "desc 1" );
+      folder->createChannel( 2, "ch 2", "desc 2" );
+      folder->createChannel( 3, "ch 3", "desc 3" );
+      CPPUNIT_ASSERT_EQUAL( (ChannelId)2,
+                            folder->channelId( "ch 2" ) );
+    }
+
+
+    /// Tests existsChannel()
+    void test_existsChannel() {
+      IFolderPtr folder = m_db->createFolder( "/f1", payloadSpec );
+      folder->createChannel( 1, "ch 1", "desc 1" );
+      CPPUNIT_ASSERT( folder->existsChannel( 1 ) );
+      CPPUNIT_ASSERT( ! folder->existsChannel( 2 ) );
+      CPPUNIT_ASSERT( folder->existsChannel( "ch 1" ) );
+      CPPUNIT_ASSERT( ! folder->existsChannel( "ch 2" ) );
+    }
+
+
+    /// Tests UK on channel name and channel id in createChannel()
+    void test_channelNameUnique() {
+      IFolderPtr folder = m_db->createFolder( "/f1", payloadSpec );
+      std::string name0 = "";
+      std::string name1 = "my channel 1";
+      std::string name2 = "my channel 2";
+      std::string name3 = "my channel 3";
+      std::string desc = "my description";
+
+      folder->createChannel( 0, name0, desc );
+      CPPUNIT_ASSERT_EQUAL( name0, folder->channelName( 0 ) );
+      CPPUNIT_ASSERT_EQUAL( desc, folder->channelDescription( 0 ) );
+
+      folder->createChannel( 1, name1, desc );
+      CPPUNIT_ASSERT_EQUAL( name1, folder->channelName( 1 ) );
+      CPPUNIT_ASSERT_EQUAL( desc, folder->channelDescription( 1 ) );
+
+      folder->createChannel( 2, name2, desc );
+      CPPUNIT_ASSERT_EQUAL( name2, folder->channelName( 2 ) );
+      CPPUNIT_ASSERT_EQUAL( desc, folder->channelDescription( 2 ) );
+
+      std::cout << std::endl;
+
+      try {
+        folder->createChannel( 0, name3, desc );
+        CPPUNIT_FAIL( "Creating channel with duplicate id=0 should fail" );
+      }
+      catch ( ChannelExists& ) {
+      }
+
+      try {
+        folder->createChannel( 3, name0, desc );
+        CPPUNIT_ASSERT_EQUAL( name0, folder->channelName( 3 ) );
+        CPPUNIT_ASSERT_EQUAL( desc, folder->channelDescription( 3 ) );
+      }
+      catch ( std::exception& e ) {
+        std::cout << "ERROR! Exception caught: '"
+                  << e.what() << "'" << std::endl;
+        throw;
+      }
+
+      try {
+        folder->createChannel( 4, name1, desc );
+        CPPUNIT_FAIL
+          ( "Creating channel with duplicate name=" + name1 + " should fail" );
+      }
+      catch ( ChannelExists& ) {
+      }
+
+      try {
+        folder->setChannelName( 1, name2 );
+        CPPUNIT_FAIL
+          ( "Setting channel duplicate name=" + name1 + " should fail" );
+      }
+      catch ( ChannelExists& ) {
+      }
+
+      CPPUNIT_ASSERT_EQUAL( (ChannelId)1, folder->channelId( name1 ) );
+
+    }
+
+
+    /// Tests createChannel(), channelName(), and channelDescription()
+    void test_createChannel() {
+      IFolderPtr folder = m_db->createFolder( "/f1", payloadSpec );
+      folder->createChannel( 1, "ch 1", "desc 1" );
+      CPPUNIT_ASSERT_EQUAL( std::string("ch 1"),
+                            folder->channelName( 1 ) );
+      CPPUNIT_ASSERT_EQUAL( std::string("desc 1"),
+                            folder->channelDescription( 1 ) );
+    }
+
+
+    /// Tests dropChannel()
+    void test_dropChannel()
+    {
+      IFolderPtr folder = m_db->createFolder( "/f1", payloadSpec );
+      folder->createChannel( 1, "ch 1", "desc 1" );
+      CPPUNIT_ASSERT_EQUAL( true, folder->existsChannel( 1 ) );
+      folder->dropChannel( 1 );
+      CPPUNIT_ASSERT_EQUAL( false, folder->existsChannel( 1 ) );
+    }
+
+
+    /// Tests dropChannel() with an exception (SV IOVs)
+    void test_dropChannel_exceptionSV()
+    {
+      IFolderPtr folder = m_db->createFolder
+        ( "/f1", payloadSpec, "",  FolderVersioning::SINGLE_VERSION );
+      coral::AttributeList payload = Record( payloadSpec ).attributeList();
+      folder->storeObject( 0, 1, payload, 1 );
+      CPPUNIT_ASSERT_EQUAL( true, folder->existsChannel( 1 ) );
+      try
+      {
+        folder->dropChannel( 1 );
+        CPPUNIT_FAIL( "exception expected" );
+      }
+      catch ( RelationalException& ) {}
+      CPPUNIT_ASSERT_EQUAL( true, folder->existsChannel( 1 ) );
+    }
+
+
+    /// Tests dropChannel() with an exception (MV IOVs)
+    void test_dropChannel_exceptionMV()
+    {
+      IFolderPtr folder = m_db->createFolder
+        ( "/f1", payloadSpec, "",  FolderVersioning::MULTI_VERSION );
+      coral::AttributeList payload = Record( payloadSpec ).attributeList();
+      folder->storeObject( 0, 1, payload, 1 );
+      CPPUNIT_ASSERT_EQUAL( true, folder->existsChannel( 1 ) );
+      try
+      {
+        folder->dropChannel( 1 );
+        CPPUNIT_FAIL( "exception expected" );
+      }
+      catch ( RelationalException& ) {}
+      CPPUNIT_ASSERT_EQUAL( true, folder->existsChannel( 1 ) );
+    }
+
+
+    /// Tests listChannels (SingleVersion only, MultiVersion test in
+    /// test_RalDatabase)
+    void test_listChannels() {
+      IFolderPtr folder = m_db->createFolder( "/myfolder", payloadSpec );
+      ChannelId channel = 1;
+      folder->storeObject( 0, ValidityKeyMax, dummyPayload( 0 ), channel );
+      channel = 3;
+      folder->storeObject( 0, ValidityKeyMax, dummyPayload( 0 ), channel );
+      channel = 5;
+      folder->storeObject( 0, ValidityKeyMax, dummyPayload( 0 ), channel );
+
+      std::vector<ChannelId> channels = folder->listChannels();
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "channel count", 3u, (unsigned int)channels.size() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "channel 1", (ChannelId)1, channels[0] );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "channel 2", (ChannelId)3, channels[1] );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "channel 3", (ChannelId)5, channels[2] );
+
+      // check exceptional behavior
+      folder = m_db->createFolder( "/empty_folder", payloadSpec );
+
+      // a folder without data has no channels
+      channels = folder->listChannels();
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "channel list size", 0u, (unsigned int)channels.size() );
+    }
+
+
+    /// Test the odering of the list of channels when the highest bit is set.
+    /// Used to fail for SQLite with bug #15128 and later bug #24103.
+    void test_listChannels_order() {
+      IFolderPtr folder = m_db->createFolder( "/myfolder", payloadSpec );
+      ChannelId channel = 1;
+      folder->storeObject( 0, ValidityKeyMax, dummyPayload( 0 ), channel );
+      channel = 2147483648u;
+      folder->storeObject( 0, ValidityKeyMax, dummyPayload( 0 ), channel );
+      //MSG::Level outLvl = application().outputLevel();
+      //application().setOutputLevel( MSG::VERBOSE );
+      std::vector<ChannelId> channels = folder->listChannels();
+      //application().setOutputLevel( outLvl );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "channel list size", 2u, (unsigned int)channels.size() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "channel 1", (ChannelId)1, channels[0] );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "channel 2147483648", (ChannelId)2147483648u, channels[1] );
+    }
+
+
+    /// Tests listChannelsWithNames
+    void test_listChannelsWithNames()
+    {
+      IFolderPtr folder = m_db->createFolder( "/myfolder", payloadSpec );
+      ChannelId channel = 1;
+      folder->storeObject( 0, ValidityKeyMax, dummyPayload( 0 ), channel );
+      channel = 3;
+      folder->storeObject( 0, ValidityKeyMax, dummyPayload( 0 ), channel );
+      channel = 5;
+      folder->storeObject( 0, ValidityKeyMax, dummyPayload( 0 ), channel );
+      folder->setChannelName( 3, "channel 3" );
+      folder->setChannelName( 5, "channel 5" );
+      std::map<ChannelId,std::string> channelsWithNames =
+        folder->listChannelsWithNames();
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "channel count", 3u, (unsigned int)channelsWithNames.size() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "channel 1", std::string(""), channelsWithNames[1] );
+      CPPUNIT_ASSERT_MESSAGE
+        ( "channel 2", channelsWithNames.find(2) == channelsWithNames.end() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "channel 3", std::string("channel 3"), channelsWithNames[3] );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "channel 5", std::string("channel 5"), channelsWithNames[5] );
+
+      // check exceptional behavior
+      folder = m_db->createFolder( "/empty_folder", payloadSpec );
+
+      // a folder without data has no channels
+      channelsWithNames = folder->listChannelsWithNames();
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "channel list size", 0u, (unsigned int)channelsWithNames.size() );
+    }
+
+
+    /// Creates a dummy payload AttributeList for a given index
+    Record dummyPayload( int index )
+    {
+      Record payload( payloadSpec );
+      payload["I"].setValue<Int32>( index );
+      std::stringstream s;
+      s << "Object " << index;
+      payload["S"].setValue<String255>( s.str() );
+      payload["X"].setValue<Float>( (float)(index/1000.) );
+      return payload;
+    }
+
+    ChannelsTest()
+      : CoolDBUnitTest(), payloadSpec()
+    {
+      payloadSpec.extend("I",StorageType::Int32);
+      payloadSpec.extend("S",StorageType::String255);
+      payloadSpec.extend("X",StorageType::Float);
+    }
+
+    void setUp() {
+      dropDB();
+      createDB();
+      openDB();
+    }
+
+    void tearDown() {
+      closeDB(); // Fix for bug #27650 on OSX
+    }
+
+  };
+
+  CPPUNIT_TEST_SUITE_REGISTRATION( ChannelsTest );
+
+} // namespace
+
+COOLTEST_MAIN(ChannelsTest)
diff --git a/RelationalCool/tests/ClobIO/authentication.xml b/RelationalCool/tests/ClobIO/authentication.xml
new file mode 100755
index 000000000..da8dc0f83
--- /dev/null
+++ b/RelationalCool/tests/ClobIO/authentication.xml
@@ -0,0 +1,14 @@
+<?xml version="1.0" ?>
+<connectionlist>
+
+<connection name="oracle://devdb10/lcg_cool">
+  <parameter name="user" value="USER" />
+  <parameter name="password" value="PASSWORD" />
+</connection>
+
+<connection name="mysql://pcitdb59/COOLDB">
+  <parameter name="user" value="USER" />
+  <parameter name="password" value="PASSWORD" />
+</connection>
+
+</connectionlist>
diff --git a/RelationalCool/tests/ClobIO/clobInputOutput.cpp b/RelationalCool/tests/ClobIO/clobInputOutput.cpp
new file mode 100755
index 000000000..7dac711e4
--- /dev/null
+++ b/RelationalCool/tests/ClobIO/clobInputOutput.cpp
@@ -0,0 +1,211 @@
+// PORT -- temporarily disabled: not part of our official test suite
+int main() { return 0; }
+#ifdef NOPORT
+
+#include <iostream>
+#include <stdexcept>
+#include <memory>
+#include "RelationalAccess/RelationalException.h"
+#include "RelationalAccess/IRelationalService.h"
+#include "RelationalAccess/IRelationalDomain.h"
+#include "RelationalAccess/IRelationalSession.h"
+#include "RelationalAccess/IRelationalTransaction.h"
+#include "RelationalAccess/IRelationalSchema.h"
+#include "RelationalAccess/IRelationalTable.h"
+#include "RelationalAccess/IRelationalQuery.h"
+#include "RelationalAccess/IRelationalCursor.h"
+#include "RelationalAccess/RelationalEditableTableDescription.h"
+#include "RelationalAccess/IRelationalTableDataEditor.h"
+#include "RelationalAccess/IRelationalTypeConverter.h"
+#include "AttributeList/AttributeList.h"
+#include "POOLCore/POOLContext.h"
+#include "SealKernel/Context.h"
+#include "../src/sleep.h"
+
+void writeClob( const std::string& connectionString )
+{
+  seal::MessageStream log( pool::POOLContext::context(), "CLOBInputOutput_Test" );
+  seal::IHandle<pool::IRelationalService> serviceHandle = pool::POOLContext::context()->query<pool::IRelationalService>( "POOL/Services/RelationalService" );
+  if ( ! serviceHandle ) {
+    throw std::runtime_error( "Could not retrieve the relational service" );
+  }
+  pool::IRelationalDomain& domain = serviceHandle->domainForConnection( connectionString );
+
+  // Creating a session
+  std::auto_ptr< pool::IRelationalSession > session( domain.newSession( connectionString ) );
+
+  // Establish a connection with the server
+  std::cout << "Connecting..." << std::endl;
+  if ( ! session->connect() ) {
+    throw std::runtime_error( "Could not connect to the database server." );
+  }
+
+  // Start a transaction
+  std::cout << "Starting a new transaction" << std::endl;
+  if ( ! session->transaction().start() ) {
+    throw std::runtime_error( "Could not start a new transaction." );
+  }
+
+
+  if ( session->userSchema().existsTable( "DataTable" ) ) {
+    std::cout << "Deleting table \"DataTable\"" << std::endl;
+    if ( ! session->userSchema().dropTable( "DataTable" ) ) {
+      throw std::runtime_error( "Could not drop a table." );
+    }
+  }
+
+  // Creating the description for the table
+  std::auto_ptr< pool::IRelationalEditableTableDescription > description( new pool::RelationalAccess::RelationalEditableTableDescription( log,
+                                                                                                                                          domain.flavorName() ) );
+  description->insertColumn( "id", pool::AttributeStaticTypeInfo<int>::type_name() );
+  description->insertColumn( "data", pool::AttributeStaticTypeInfo<std::string>::type_name() );
+
+  // Setting the std::string -> CLOB
+  session->typeConverter().setSqlTypeForCppType( "CLOB", pool::AttributeStaticTypeInfo<std::string>::type_name() );
+
+  // Create the first table.
+  std::cout << "Creating table \"DataTable\"" << std::endl;
+  pool::IRelationalTable& table = session->userSchema().createTable( "DataTable", *description );
+
+  // Costructing a row buffer.
+  pool::AttributeList data( table.description().columnNamesAndTypes() );
+
+  // Retrieving the editor object.
+  pool::IRelationalTableDataEditor& dataEditor = table.dataEditor();
+
+  // Adding new rows
+  std::cout << "Adding a row into the table" << std::endl;
+  data["id"].setValue<int>( 1 );
+  std::string input = "Begin";
+  for ( int i = 0; i < 10*1024*1024; ++i ) input += ".";
+  input += "End";
+  data["data"].setValue<std::string>( input );
+
+  if ( ! dataEditor.insertNewRow( data ) ) {
+    throw std::runtime_error( "Could not insert a new row into the table." );
+  }
+
+  std::cout << "Adding a second row into the table" << std::endl;
+  data["id"].setValue<int>( 2 );
+  input = "Begin";
+  for ( int i = 0; i < 20*1024*1024; ++i ) input += "-";
+  input += "End";
+  data["data"].setValue<std::string>( input );
+
+  if ( ! dataEditor.insertNewRow( data ) ) {
+    throw std::runtime_error( "Could not insert a new row into the table." );
+  }
+
+  // Committing the transaction
+  std::cout << "Committing..." << std::endl;
+  if ( ! session->transaction().commit() ) {
+    throw std::runtime_error( "Could not commit the transaction." );
+  }
+
+  // Disconnecting
+  std::cout << "Disconnecting..." << std::endl;
+  session->disconnect();
+}
+
+
+
+void readClob( const std::string& connectionString )
+{
+  seal::MessageStream log( pool::POOLContext::context(), "CLOBInputOutput_Test" );
+  seal::IHandle<pool::IRelationalService> serviceHandle = pool::POOLContext::context()->query<pool::IRelationalService>( "POOL/Services/RelationalService" );
+  if ( ! serviceHandle ) {
+    throw std::runtime_error( "Could not retrieve the relational service" );
+  }
+  pool::IRelationalDomain& domain = serviceHandle->domainForConnection( connectionString );
+
+  // Creating a session
+  std::auto_ptr< pool::IRelationalSession > session( domain.newSession( connectionString ) );
+
+  // Establish a connection with the server
+  std::cout << "Connecting..." << std::endl;
+  if ( ! session->connect() ) {
+    throw std::runtime_error( "Could not connect to the database server." );
+  }
+
+  // Start a transaction
+  std::cout << "Starting a new transaction" << std::endl;
+  if ( ! session->transaction().start( true ) ) {
+    throw std::runtime_error( "Could not start a new transaction." );
+  }
+
+  pool::IRelationalTable& table = session->userSchema().tableHandle( "DataTable" );
+
+  std::auto_ptr< pool::IRelationalQuery > query( table.createQuery() );
+  query->addToOutputList( "id" );
+  query->addToOutputList( "data" );
+  pool::IRelationalCursor& cursor = query->process();
+  if ( cursor.start() ) {
+    int i = 0;
+    while ( cursor.next() ) {
+      const pool::AttributeList& row = cursor.currentRow();
+      pool::AttributeList::const_iterator iAttribute = row.begin();
+      std::string result = (++iAttribute)->getValueAsString();
+      std::string input = "Begin";
+      if ( i == 0 ) {
+        for ( int i = 0; i < 10*1024*1024; ++i ) input += ".";
+      }
+      else {
+        for ( int i = 0; i < 20*1024*1024; ++i ) input += "-";
+      }
+      input += "End";
+
+      std::cout << "Expected : " << input.size() << " retrieved : " << result.size() << std::endl;
+      if ( input != result ) {
+        throw std::runtime_error( "Input and output differ" );
+      }
+      ++i;
+    }
+  }
+
+  // Committing the transaction
+  std::cout << "Committing..." << std::endl;
+  if ( ! session->transaction().commit() ) {
+    throw std::runtime_error( "Could not commit the transaction." );
+  }
+
+  // Disconnecting
+  std::cout << "Disconnecting..." << std::endl;
+  session->disconnect();
+}
+
+
+int main( int, char** )
+{
+  try {
+    pool::POOLContext::loadComponent( "SEAL/Services/MessageService" );
+    pool::POOLContext::loadComponent( "POOL/Services/XMLAuthenticationService" );
+    pool::POOLContext::loadComponent( "POOL/Services/RelationalService" );
+    //pool::POOLContext::setMessageVerbosityLevel( seal::Msg::Info );
+    pool::POOLContext::setMessageVerbosityLevel( seal::Msg::Verbose );
+
+    std::string connectionString = "oracle://devdb10/lcg_cool";
+    writeClob( connectionString );
+
+    cool::sleep(1);
+
+    readClob( connectionString );
+
+    std::cout << "Exiting..." << std::endl;
+  }
+  catch ( pool::RelationalException& re ) {
+    std::cerr << "Relational exception from module " << re.flavorName() << std::endl
+              << "    " << re.what() << std::endl;
+    return 1;
+  }
+  catch ( std::exception& e ) {
+    std::cerr << "Standard C++ exception : " << e.what() << std::endl;
+    return 1;
+  }
+  catch ( ... ) {
+    std::cerr << "Exception caught (...)" << std::endl;
+    return 1;
+  }
+  return 0;
+}
+
+#endif // NOPORT
diff --git a/RelationalCool/tests/Common/CoolDBUnitTest.h b/RelationalCool/tests/Common/CoolDBUnitTest.h
new file mode 100644
index 000000000..328c0c8c5
--- /dev/null
+++ b/RelationalCool/tests/Common/CoolDBUnitTest.h
@@ -0,0 +1,157 @@
+// $Id: CoolDBUnitTest.h,v 1.18 2008-08-06 09:37:43 avalassi Exp $
+#ifndef COMMON_COOLDBUNITTEST_H 
+#define COMMON_COOLDBUNITTEST_H 1
+
+// Include files
+#include "RelationalAccess/IConnectionService.h"
+#include "RelationalAccess/IConnectionServiceConfiguration.h"
+
+// Local include files
+#include "CoolUnitTest.h"
+#include "src/CoralApplication.h"
+#include "src/CoralConnectionServiceProxy.h"
+#include "src/RalDatabaseSvc.h"
+#include "src/RelationalDatabaseId.h"
+#include "src/RelationalException.h"
+#include "src/sleep.h"
+
+namespace cool 
+{
+
+  const char* COOLTESTDB = "COOLTESTDB";
+
+  /** @class CoolDBUnitTest CoolDBUnitTest.h
+   *
+   *  @author Marco Clemencic and Andrea Valassi
+   *  @date   2006-03-13
+   */
+  class CoolDBUnitTest: public CoolUnitTest {
+    
+  public:
+
+    /// Standard constructor
+    CoolDBUnitTest( bool getSvc = true )
+      : m_connectionString( "" )
+      , m_coolDBName( "" )
+      , m_app( new CoralApplication() )
+      , m_db()
+    {
+      if ( getenv( COOLTESTDB ) ) {
+        m_connectionString = getenv( COOLTESTDB );
+      } else {
+        std::cout 
+          << "Please provide a connect string by "
+          << "specifying one in the environment variable COOLTESTDB, e.g." 
+          << std::endl;
+        std::cout 
+          << "setenv COOLTESTDB "
+          << "\"oracle://devdb10;schema=lcg_cool;dbname=COOLTEST\"" 
+          << std::endl;
+        std::cout << "Aborting test" << std::endl;
+        exit(-1);
+      }
+
+      // Decode the COOL database name
+      RelationalDatabaseId id( m_connectionString );
+      m_coolDBName = id.dbName();
+
+      // This is to avoid mixture between SEAL unavoidable
+      // messages and test progress output (now on std::cout)
+      if ( getSvc ) dbs();
+
+    }
+
+    /// Destructor
+    virtual ~CoolDBUnitTest()
+    {
+      delete m_app;
+    }
+
+  protected:
+
+    /// Sleep n seconds (ORA-01466 workaround).
+    inline void sleep( int n ) 
+    { 
+      cool::sleep(n); 
+    }
+    
+    /// Retrieve the database service in the application.
+    inline IApplication& application() 
+    { 
+      return *m_app;
+    }
+    
+    /// Return a reference to the coral::ConnectionService.
+    coral::IConnectionService& connectionSvc() 
+    {
+      return application().connectionSvc();
+    }
+
+    /// Return THE shared pointer to the coral::ConnectionService pointer.
+    CoralConnectionServiceProxyPtr ppConnectionSvc() 
+    {
+      RalDatabaseSvc* ralDbs = dynamic_cast<RalDatabaseSvc*>( &dbs() );
+      if ( !ralDbs ) 
+        throw RelationalException( "PANIC! Not a RalDatabaseSvc in CoolDBUnitTest?", "" );
+      return ralDbs->ppConnectionSvc();
+    }
+
+    /// Retrieve the database service in the application.
+    inline IDatabaseSvc& dbs() 
+    { 
+      return application().databaseService();
+    }
+
+    /// Create an empty database and disconnect.
+    void createDB() 
+    {
+      dropDB();
+      dbs().createDatabase( m_connectionString ); 
+      forceDisconnect();
+    }
+
+
+    /// Open the database (set the pointer "m_db").
+    void openDB( bool readOnly = false ) 
+    {
+      m_db = dbs().openDatabase( m_connectionString, readOnly );
+    }
+
+    /// Close the database (reset the pointer "m_db").
+    void closeDB() 
+    {
+      if ( m_db ) m_db.reset();
+    }
+
+    /// Drop the DB.
+    void dropDB() 
+    {
+      closeDB();
+      dbs().dropDatabase( m_connectionString );
+      forceDisconnect();
+    }
+
+    /// Purge coral ConnectionPool.
+    void forceDisconnect() 
+    {
+      closeDB();
+      static bool first = true;
+      if ( first ) {
+        application().connectionSvc().configuration().setConnectionTimeOut(-1);
+        first = false;
+      }
+      application().connectionSvc().purgeConnectionPool();
+    }
+    
+  protected:
+    
+    std::string m_connectionString;
+    std::string m_coolDBName;    
+    CoralApplication* m_app;
+    IDatabasePtr m_db;
+
+  };
+
+}
+
+#endif // COMMON_COOLDBUNITTEST_H
diff --git a/RelationalCool/tests/Common/CoolUnitTest.h b/RelationalCool/tests/Common/CoolUnitTest.h
new file mode 100644
index 000000000..38a0144a4
--- /dev/null
+++ b/RelationalCool/tests/Common/CoolUnitTest.h
@@ -0,0 +1,367 @@
+// $Id: CoolUnitTest.h,v 1.10 2009-01-13 18:09:23 avalassi Exp $
+#ifndef COMMON_COOLUNITTEST_H
+#define COMMON_COOLUNITTEST_H 1
+
+// Include files
+#include <stdexcept>
+#include <iostream>
+#ifdef _WIN32
+#include <eh.h>
+#include <windows.h>
+#endif
+
+// Local include files
+#include "CppUnit_headers.h"
+
+// Redefine CPPUNIT_TEST
+#undef CPPUNIT_TEST
+#define CPPUNIT_TEST( testMethod ) \
+CPPUNIT_TEST_SUITE_ADD_TEST( \
+  ( new cool::TestCaller<TestFixtureType>( \
+        context.getTestNameFor( #testMethod ), \
+        &TestFixtureType::testMethod, \
+        context.makeFixture() ) ) )
+
+namespace cool 
+{
+
+  //--------------------------------------------------------------------------
+
+#ifdef _WIN32
+  
+  /*
+   *  Windows Structured Exception Handling (SEH) using _set_se_translator.
+   *  See http://msdn.microsoft.com/en-us/library/5z4bw5h5(VS.80).aspx
+   *  
+   *  @author Andrea Valassi
+   *  @date   2009-01-12
+   */
+
+  class SE_Exception : public std::exception
+  {
+  public:
+    SE_Exception( int n = -1 ) : m_nSE( n ) 
+    {
+      std::stringstream msg;
+      msg << "WINDOWS STRUCTURED EXCEPTION";
+      if ( m_nSE >=0 ) msg << " (#" << m_nSE << ")";
+      else msg << " (UNKNOWN)";
+      m_message = msg.str();
+    }
+    virtual ~SE_Exception() {}
+    int getSeNumber() { return m_nSE; }
+    const char* what() const{ return m_message.c_str(); }    
+  private:
+    int m_nSE;
+    std::string m_message;
+  };
+
+  void SE_translator( unsigned int, EXCEPTION_POINTERS* )
+  {
+    std::cout << "__cool::SE_translator WINDOWS SE CAUGHT" << std::endl;
+    throw SE_Exception();
+  }
+
+#endif
+
+  //--------------------------------------------------------------------------
+
+  /** @class TestCaller
+   *
+   *  Simple TestCaller wrapping the execution of each test in a test suite.
+   *  
+   *  @author Andrea Valassi
+   *  @date   2009-01-12
+   */
+
+  template< class Fixture > class TestCaller 
+    : virtual public CppUnit::TestCaller<Fixture>
+  {
+
+    typedef void( Fixture::* TestMethod )();
+
+  public:
+
+    virtual ~TestCaller(){}
+
+    TestCaller( std::string name, TestMethod test )
+      : CppUnit::TestCaller<Fixture>( name, test ){}
+    
+    TestCaller( std::string name, TestMethod test, Fixture& fixture )
+      : CppUnit::TestCaller<Fixture>( name, test, fixture ){}
+    
+    TestCaller( std::string name, TestMethod test, Fixture* fixture )
+      : CppUnit::TestCaller<Fixture>( name, test, fixture ){}
+
+#ifdef _WIN32
+    // See http://msdn.microsoft.com/en-us/library/s58ftw19.aspx
+    int filter( unsigned int code, struct _EXCEPTION_POINTERS* ep ) 
+    {
+      if ( code == EXCEPTION_ACCESS_VIOLATION )
+      {
+        std::cout << "__cool::TestCaller::filter"
+                  << " ERROR! WIN32 Access Violation" << std::endl;
+        return EXCEPTION_EXECUTE_HANDLER;
+      }
+      else 
+      {
+        std::cout << "__cool::TestCaller::filter"
+                  << " ERROR! WIN32 Unknown exception" << std::endl;
+        return EXCEPTION_EXECUTE_HANDLER;
+        //return EXCEPTION_CONTINUE_SEARCH;
+      };      
+    } 
+#endif
+
+    void runTest()
+    {
+      //std::cout << std::endl;
+      //std::cout << "+++ cool::TestCaller::runTest '" 
+      //          << this->getName() << "'..." << std::endl;
+#ifdef _WIN32
+      // This fails to build even when replacing /EHsc by /EHa
+      // (C2712: Cannot use __try in functions that require object unwinding)
+      // See http://msdn.microsoft.com/en-us/library/1deeycx5(VS.80).aspx and
+      // http://http://msdn.microsoft.com/en-us/library/1deeycx5(VS.80).aspx
+      /*
+      __try {
+        CppUnit::TestCaller<Fixture>::runTest();
+      } 
+      __except( filter( GetExceptionCode(), GetExceptionInformation() ) ) { 
+        std::cout << "__cool::TestCaller::runTest"
+                  << " ERROR! WIN32 Structured exception caught" << std::endl;
+      }
+      */
+      try
+      {    
+        CppUnit::TestCaller<Fixture>::runTest();
+      }
+      catch (...)
+      {
+        //std::cout << "+++ cool::TestCaller::runTest '" << this->getName() 
+        //          << "'... EXCEPTION CAUGHT!" << std::endl;
+        throw;
+      }
+#else
+      CppUnit::TestCaller<Fixture>::runTest();
+#endif
+      //std::cout << "--- cool::TestCaller::runTest '" 
+      //          << this->getName() << "'... DONE" << std::endl;
+    }
+    
+  private:
+
+    TestCaller<Fixture>();
+    
+  };
+
+  //--------------------------------------------------------------------------
+
+  /** @class TextTestRunner
+   *
+   *  Simple TextTestRunner wrapping the execution of a test suite.
+   *  
+   *  @author Andrea Valassi
+   *  @date   2009-01-12
+   */
+
+  class TextTestRunner : virtual public CppUnit::TextTestRunner
+  {
+
+  public:
+
+    virtual ~TextTestRunner(){}
+
+    TextTestRunner() : CppUnit::TextTestRunner() {}
+
+    void run( CppUnit::TestResult& controller, const std::string& testPath="" )
+    {
+      // Avoid compilation warning (virtual function was hidden...) on osx
+      CppUnit::TextTestRunner::run( controller, testPath );
+    }    
+
+    bool run( std::string testName = "",  
+              bool doWait = false,  
+              bool doPrintResult = true,  
+              bool doPrintProgress = true )
+    {
+      //std::cout << "+++ cool::TextTestRunner::run '" 
+      //          << testName << "'..." << std::endl;
+      bool status = CppUnit::TextTestRunner::run( testName, 
+                                                  doWait, 
+                                                  doPrintResult, 
+                                                  doPrintProgress );
+      //std::cout << "--- cool::TextTestRunner::run '" 
+      //          << testName << "'... DONE" << std::endl;
+      return status;
+    }
+
+  };
+  
+  //--------------------------------------------------------------------------
+
+  /** @class ProgressListener
+   *
+   *  Simple TestListener printing one line per test in the standard output.
+   *  
+   *  Based on  CppUnit::BriefTestProgressListener (copy and paste) 
+   *  using std::cout instead of std::cerr.
+   *
+   *  @author Marco Clemencic
+   *  @date   2006-11-13
+   */
+
+  class ProgressListener : public CppUnit::TestListener
+  {
+
+  public:
+
+    /// Default constructor.
+    ProgressListener(): m_lastTestFailed(false) {}
+    
+    /// Destructor.
+    virtual ~ProgressListener() {}
+    
+    void startTest( CppUnit::Test *test )
+    {
+      std::cout << test->getName();
+      std::cout.flush();      
+      m_lastTestFailed = false;
+    }
+
+    void addFailure( const CppUnit::TestFailure &failure )
+    {
+      std::cout << " : " << (failure.isError() ? "error" : "assertion");
+      m_lastTestFailed  = true;
+    }
+    
+    void endTest( CppUnit::Test * /*test*/ )
+    {
+      if ( !m_lastTestFailed )
+        std::cout  <<  " : OK";
+      std::cout << std::endl;
+    }
+    
+  private:
+
+    bool m_lastTestFailed;
+
+  };
+
+
+  //---------------------------------------------------------------------------
+
+  /** @class CoolUnitTest CoolUnitTest.h Common/CoolUnitTest.h
+   *
+   *  Base class for COOL tests that does not use a database
+   *  (use CoolDBUnitTest for tests involving databases).
+   *
+   *  @author Marco Clemencic
+   *  @date   2006-05-09
+   */
+  class CoolUnitTest: public CppUnit::TestFixture {
+
+  public:
+
+    /// Standard constructor
+    CoolUnitTest(){}
+
+    /// Destructor
+    virtual ~CoolUnitTest(){}
+
+    /// Program main
+    static int Main( int argc, char* argv[] );
+
+  };
+
+  int CoolUnitTest::Main( int argc, char* argv[] )
+  {
+    //std::cout << "+++ cool::CoolUnitTest::Main..." << std::endl;
+#ifdef _WIN32      
+    _set_se_translator( cool::SE_translator );
+#endif
+    // Retrieve test path from command line first argument.
+    // Default to "" which resolve to the top level suite.
+    std::string testPath =
+      (argc > 1) ? std::string(argv[1]) : std::string("");
+
+    // Add a listener that colllects test result
+    //CppUnit::TestResultCollector result;
+    //controller.addListener( &result );
+
+    /// Get the top level suite from the registry
+    CppUnit::Test *suite =
+      CppUnit::TestFactoryRegistry::getRegistry().makeTest();
+
+    /// Adds the test to the list of test to run
+    // CppUnit::TestRunner runner;
+    // CppUnit::TextTestRunner runner;
+    cool::TextTestRunner runner;
+    runner.addTest( suite );
+
+    // Change the default outputter to a compiler error format outputter
+    // uncomment the following line if you need a compiler outputter.
+    runner.setOutputter( new CppUnit::CompilerOutputter( &runner.result(), 
+                                                         std::cout ) );
+
+    // Change the default outputter to a xml error format outputter
+    // uncomment the following line if you need a xml outputter.
+    //runner.setOutputter( new CppUnit::XmlOutputter( &runner.result(),
+    //                                                    std::cout ) );
+
+    runner.eventManager().addListener( new cool::ProgressListener() );
+
+    //CppUnit::TestResultCollector *collector = 
+    //  new CppUnit::TestResultCollector();
+    //runner.eventManager().addListener(collector);
+
+    bool wasSuccessful = false;
+
+    try 
+    {
+      wasSuccessful = runner.run( testPath, false, true, false );
+    }
+
+    // Test path not resolved
+    catch ( std::invalid_argument &e )
+    {
+      std::cout  << std::endl << "ERROR: " << e.what() << std::endl;
+      return 0;
+    }
+
+    // Should never happen?
+    catch ( std::exception& e )
+    {
+      std::cout  << std::endl
+                 << "UNEXPECTED STD EXCEPTION CAUGHT in CoolUnitTest: "
+                 << e.what() << std::endl;
+      return 0;
+    }
+
+    // Should never happen?
+    catch ( ... )
+    {
+      std::cout  << std::endl
+                 << "UNKNOWN EXCEPTION CAUGHT in CoolUnitTest" << std::endl;
+      return 0;
+    }
+
+    // Return error code 1 if the one of tests failed.
+    // Print a message on standard error if something failed (for QMTest)
+    if ( ! wasSuccessful ) std::cerr << "Error: CppUnit Failures" << std::endl;
+    int retcode = wasSuccessful ? 0 : 1;
+    // Uncomment the next line if you want to integrate CppUnit with Oval
+    std::cout << "[OVAL] Cppunit-result =" << retcode << std::endl;
+    //std::cout << "--- cool::CoolUnitTest::Main... DONE" << std::endl;
+    return retcode;
+
+  }
+
+  //---------------------------------------------------------------------------
+
+}
+
+#define COOLTEST_MAIN(CLASS) int main( int argc, char* argv[] ) \
+  { return cool::CLASS::Main( argc, argv ); }
+
+#endif // COMMON_COOLUNITTEST_H
diff --git a/RelationalCool/tests/Common/CppUnit_headers.h b/RelationalCool/tests/Common/CppUnit_headers.h
new file mode 100644
index 000000000..d093ca404
--- /dev/null
+++ b/RelationalCool/tests/Common/CppUnit_headers.h
@@ -0,0 +1,45 @@
+// $Id: CppUnit_headers.h,v 1.4 2008-02-28 14:19:46 avalassi Exp $
+#ifndef COMMON_CPPUNIT_HEADERS_H 
+#define COMMON_CPPUNIT_HEADERS_H 1
+
+// Disable warnings triggered by the CppUnit headers
+// See http://wiki.services.openoffice.org/wiki/Writing_warning-free_code
+// See also http://www.artima.com/cppsource/codestandards.html
+// See also http://gcc.gnu.org/onlinedocs/gcc-4.1.1/cpp/System-Headers.html
+// See also http://gcc.gnu.org/ml/gcc-help/2007-01/msg00172.html
+#if defined __GNUC__
+#pragma GCC system_header
+#endif
+
+// Include files
+
+// from SPI version of the testdriver
+#include <cppunit/extensions/TestFactoryRegistry.h> 
+#include <cppunit/TextTestRunner.h> 
+#include <cppunit/CompilerOutputter.h> 
+#include <cppunit/TextOutputter.h> 
+#include <cppunit/XmlOutputter.h> 
+
+// to produce one line per test
+#include <cppunit/TestResult.h>
+//#include <cppunit/BriefTestProgressListener.h>
+//#include <cppunit/TestResultCollector.h>
+
+// needed by the implementation of cool::ProgressListener
+#include <cppunit/Test.h>
+#include <cppunit/TestFailure.h>
+#include <cppunit/TestListener.h>
+
+// provides macros for the tests
+#include <cppunit/extensions/HelperMacros.h>
+
+// try (unsuccessfully) to avoid some warnings in test_RelationalFolder.cpp
+// - these lines force instantiation here, but the warning does happen here too
+// - even moving these lines to another included file did not remove warnings
+//#include <cppunit/extensions/ExceptionTestCaseDecorator.h>
+//namespace cool { class Exception; }
+//template class CppUnit::ExceptionTestCaseDecorator<cool::Exception>;
+//namespace cool { class TagNotFound; }
+//template class CppUnit::ExceptionTestCaseDecorator<cool::TagNotFound>;
+
+#endif // COMMON_CPPUNIT_HEADERS_H
diff --git a/RelationalCool/tests/Common/CppUnit_testdriver.icpp b/RelationalCool/tests/Common/CppUnit_testdriver.icpp
new file mode 100644
index 000000000..04643a516
--- /dev/null
+++ b/RelationalCool/tests/Common/CppUnit_testdriver.icpp
@@ -0,0 +1,4 @@
+
+#include "CoolUnitTest.h"
+
+COOLTEST_MAIN(CoolUnitTest)
diff --git a/RelationalCool/tests/Common/cppunit/TestListener.h b/RelationalCool/tests/Common/cppunit/TestListener.h
new file mode 100644
index 000000000..7dc14d9b5
--- /dev/null
+++ b/RelationalCool/tests/Common/cppunit/TestListener.h
@@ -0,0 +1,23 @@
+#ifndef CPPUNIT_TESTLISTENER_H
+#define CPPUNIT_TESTLISTENER_H
+namespace CppUnit
+{
+  class Test;
+  class TestFailure;
+  class TestResult;  
+  class TestListener
+  {  
+  public:
+    virtual ~TestListener() {}
+    virtual void startTest( Test* ){}
+    virtual void addFailure( const TestFailure& ){}
+    virtual void endTest( Test* ){}    
+    virtual void startSuite( Test* ){}
+    virtual void endSuite( Test* ){}
+    virtual void startTestRun( Test*, TestResult* ){}
+    virtual void endTestRun( Test*, TestResult* ){}
+  };
+}
+#endif // CPPUNIT_TESTLISTENER_H
+
+
diff --git a/RelationalCool/tests/Common/releaser.h b/RelationalCool/tests/Common/releaser.h
new file mode 100644
index 000000000..2f33d85db
--- /dev/null
+++ b/RelationalCool/tests/Common/releaser.h
@@ -0,0 +1,18 @@
+// $Id: releaser.h,v 1.1 2006-11-15 16:18:25 avalassi Exp $
+#ifndef RELATIONALCOOL_RELEASER_H 
+#define RELATIONALCOOL_RELEASER_H 1
+
+// Include files
+#include "CoralBase/AttributeListSpecification.h"
+
+namespace cool 
+{
+
+  class releaser {
+  public:
+    void operator()( coral::AttributeListSpecification* p ) { p->release(); }
+  };
+
+}
+
+#endif // RELEASER_H
diff --git a/RelationalCool/tests/CoolCppUnitTestDriver.cpp b/RelationalCool/tests/CoolCppUnitTestDriver.cpp
new file mode 100644
index 000000000..1ddc07405
--- /dev/null
+++ b/RelationalCool/tests/CoolCppUnitTestDriver.cpp
@@ -0,0 +1,72 @@
+// From /afs/cern.ch/sw/lcg/external/CppUnit/1.8.0/slc3_ia32_gcc323/include
+#include <cppunit/extensions/TestFactoryRegistry.h> 
+#include <cppunit/ui/text/TestRunner.h> 
+#include <cppunit/CompilerOutputter.h> 
+#include <cppunit/TextOutputter.h> 
+#include <cppunit/XmlOutputter.h> 
+#include <iostream>
+
+#include <cppunit/TestResult.h> 
+#include <cppunit/TextTestProgressListener.h>
+namespace cool {
+  // See http://kmymoney2.sourceforge.net/phb/test-container-example.html
+  // See http://cppunit.sourceforge.net/doc/lastest/cppunit_cookbook.html
+  // See http://cppunit.sourceforge.net/cppunit-wiki/FrequentlyAskedQuestions
+  class CoolProgressListener : public CppUnit::TextTestProgressListener
+  {
+    void startTest(CppUnit::Test *test) {
+      std::string name = test->getName().c_str();
+      if(m_name != name) {
+        std::cout << "Running: " << name << std::endl;
+        m_name = name;
+      }
+    }
+  private:
+    std::string m_name;
+  };
+}
+
+/**  Main class for all the CppUnit test classes  
+*
+*  This will be the driver class of all your CppUnit test classes.
+*  - All registered CppUnit test classes will be run. 
+*  - You can also modify the output (text, compiler, XML). 
+*  - This class will also integrate CppUnit test with Oval
+*/
+
+
+int main( int /*argc*/, char /* **argv */)
+ {
+   /// Get the top level suite from the registry
+   CppUnit::Test *suite = CppUnit::TestFactoryRegistry::getRegistry().makeTest();
+
+   /// Adds the test to the list of test to run
+   CppUnit::TextUi::TestRunner runner;
+   runner.addTest( suite );
+
+   // Change the default outputter to a compiler error format outputter 
+   // uncomment the following line if you need a compiler outputter.
+       runner.setOutputter(new CppUnit::CompilerOutputter( &runner.result(),
+                                                            std::cout ) );
+
+   // Change the default outputter to a xml error format outputter 
+   // uncomment the following line if you need a xml outputter.
+   //runner.setOutputter( new CppUnit::XmlOutputter( &runner.result(),
+   //                                                    std::cerr ) );
+
+       // Print out the name of each test before its execution
+       cool::CoolProgressListener progress;
+       runner.eventManager().addListener(&progress);
+
+   /// Run the tests.
+   //  bool wasSuccessful = runner.run();
+   // If you want to avoid the CppUnit typical output change the line above 
+   // by the following one: 
+       bool wasSuccessful = runner.run("",false,true,false);
+
+   // Return error code 1 if the one of test failed.
+   // Uncomment the next line if you want to integrate CppUnit with Oval
+       if(!wasSuccessful !=0) std::cerr <<"Error: CppUnit Failures"<<std::endl;
+       std::cout <<"[OVAL] Cppunit-result ="<<!wasSuccessful<<std::endl;
+     return 0;
+ }
diff --git a/RelationalCool/tests/CreateDatabase/createDatabase.cpp b/RelationalCool/tests/CreateDatabase/createDatabase.cpp
new file mode 100644
index 000000000..d9b3049b7
--- /dev/null
+++ b/RelationalCool/tests/CreateDatabase/createDatabase.cpp
@@ -0,0 +1,446 @@
+// PORT -- temporarily disabled: not part of our official test suite
+int main() { return 0; }
+#ifdef NOPORT
+
+// $Id: createDatabase.cpp,v 1.69 2008-08-27 09:34:28 avalassi Exp $
+
+// Include files
+#include <iostream>
+#include <sstream>
+#include <string>
+#include "AttributeList/AttributeList.h"
+#include "CoolKernel/DatabaseId.h"
+#include "CoolKernel/IDatabase.h"
+#include "CoolKernel/IDatabaseSvc.h"
+#include "CoolKernel/IFolder.h"
+#include "CoolKernel/IFolderSet.h"
+#include "CoolKernel/IObject.h"
+#include "CoolKernel/IObjectIterator.h"
+#include "src/CoralApplication.h"
+#include "src/sleep.h"
+#include "src/timeToString.h"
+#include "src/uppercaseString.h"
+
+// Namespace
+using namespace cool;
+
+// Message output
+#define LOG std::cout << "__main "
+
+//-----------------------------------------------------------------------------
+
+int main ( int argc, char* argv[] )
+{
+
+  LOG << "Entering main" << std::endl;
+  int status = -1;
+
+  // User name
+  std::string userName;
+  if ( getenv( "USER" ) ) 
+    userName = uppercaseString( getenv( "USER" ) );
+  else if ( getenv( "USERNAME" ) ) 
+    userName = uppercaseString( getenv( "USERNAME" ) );
+  else {
+    LOG << "ERROR! Environment variables USER and USERNAME both undefined" 
+        << std::endl;
+    return status;
+  }
+  std::string dbName = userName + "2";
+  if ( dbName == "AVALASSI2" ) dbName = "COOLTSTA";
+  if ( dbName == "SAS2" ) dbName = "COOLTSTS";
+
+  // Default connection strings
+  std::string dbIdOracle = 
+    std::string( "oracle://devdb10;schema=lcg_cool;dbname=" ) + dbName;
+  std::string dbIdMySQL = 
+    std::string( "mysql://pcitdb59;schema=COOLDB;dbname=" ) + dbName;
+
+  // Command line input: connection string
+  std::string dbIdString;
+  if ( argc == 1 || argc > 2 ) {    
+    LOG << "Usage: " << argv[0] << " dbId|'oracle'|'mysql'" << std:: endl;
+    LOG << "Example: " << argv[0] << " oracle"<< std::endl;
+    LOG << "Example: " << argv[0] << " mysql"<< std::endl;
+    LOG << "Example: " << argv[0] << " \"" << dbIdOracle << "\""<< std::endl;
+    LOG << "Example: " << argv[0] << " \"" << dbIdMySQL << "\""<< std::endl;
+    return 1;
+  } else { 
+    dbIdString = argv[1];
+    if ( dbIdString == "oracle" ) dbIdString = dbIdOracle;
+    if ( dbIdString == "mysql" ) dbIdString = dbIdMySQL;
+  }  
+
+  try {
+    
+    LOG << "Get a handle to the COOL database service" << std::endl;
+    CoralApplication app;
+    IDatabaseSvc& dbSvc = app.databaseService();
+  
+    //------------------------
+    // DEFINE THE DATABASE ID
+    //------------------------
+    
+    cool::DatabaseId dbId = dbIdString;
+
+    //--------------------------------
+    // DROP THE DATABASE IF IT EXISTS
+    //--------------------------------
+    
+    // Drop the COOL conditions database if it already exists
+    LOG << "Drop if it exists the conditions database: " << dbId << std::endl;
+    dbSvc.dropDatabase( dbId );
+
+    //-----------------------
+    // CREATE A NEW DATABASE
+    //-----------------------
+    
+    // Create a new COOL conditions database
+    LOG << "Create a new conditions database: " << dbId << std::endl;
+    cool::IDatabasePtr db = dbSvc.createDatabase( dbId );
+    LOG << "Conditions database created: " << std::endl;
+    LOG << "-> Database ID: " << db->databaseId() << std::endl;
+    std::ostringstream dbAttr;
+    db->databaseAttributes().print( dbAttr );
+    LOG << "-> Database attributes: " << dbAttr.str() << std::endl;
+
+    // TEMPORARY? Patch for the ORA-01466 problem: sleep one second
+    cool::sleep(1);
+
+    // Create two new COOL conditions folders with the same payload spec
+    pool::AttributeListSpecification payloadSpec1;
+    payloadSpec1.push_back("I","int");
+    payloadSpec1.push_back("S","string");
+    payloadSpec1.push_back("X","float");
+    payloadSpec1.push_back("UI64","unsigned long long");
+    //payloadSpec1.push_back("SI64","long long");
+
+    // Create folder 1a
+    std::string folderName1a( "/my/folder1a" );
+    cool::IFolderPtr folder1a = db->createFolder
+      ( folderName1a, payloadSpec1, "", 
+        FolderVersioning::SINGLE_VERSION, true );
+    LOG << "Folder created: " << std::endl;
+    LOG << "-> Folder name: " << folder1a->fullPath() << std::endl;
+    std::ostringstream folderAttr1a;
+    folder1a->payloadSpecification().print( folderAttr1a );
+    LOG << "-> Folder payload specification: " 
+        << folderAttr1a.str() << std::endl;
+
+    // Create folder 1b
+    std::string folderName1b( "/my/folder1b" );
+    cool::IFolderPtr folder1b = db->createFolder
+      ( folderName1b, payloadSpec1, "", 
+        FolderVersioning::SINGLE_VERSION, true );
+    LOG << "Folder created: " << std::endl;
+    LOG << "-> Folder name: " << folder1b->fullPath() << std::endl;
+    std::ostringstream folderAttr1b;
+    folder1b->payloadSpecification().print( folderAttr1b );
+    LOG << "-> Folder payload specification: " 
+        << folderAttr1b.str() << std::endl;
+
+    // Create folder 1c
+    std::string folderName1c( "/my/folder1c" );
+    cool::IFolderPtr folder1c = db->createFolder
+      ( folderName1c, payloadSpec1, "", 
+        FolderVersioning::SINGLE_VERSION, true );
+    LOG << "Folder created: " << std::endl;
+    LOG << "-> Folder name: " << folder1c->fullPath() << std::endl;
+    std::ostringstream folderAttr1c;
+    folder1c->payloadSpecification().print( folderAttr1c );
+    LOG << "-> Folder payload specification: " 
+        << folderAttr1c.str() << std::endl;
+
+    // TEMPORARY? Patch for the ORA-01466 problem: sleep one second
+    cool::sleep(1);
+
+    // Print the list of folders
+    std::vector<std::string> folderList;
+    std::vector<std::string>::iterator folderIt;
+    folderList = db->getFolderSet( "/my" )->listFolders();
+    LOG << "-> List of folders in the database:" << std::endl;
+    for( folderIt = folderList.begin(); 
+         folderIt != folderList.end(); 
+         folderIt++ ) {
+      std::cout << *folderIt << std::endl;
+    }    
+
+    // In online folders, until=+infinity means valid until next iov
+    ValidityKey plusInfinity = ValidityKeyMax;
+
+    // Insert some data into folder 1a
+    pool::AttributeList payload1( payloadSpec1 );
+    payload1["I"].setValue<int>( 1 );
+    payload1["S"].setValue<std::string>( "Object 1" );
+    payload1["X"].setValue<float>( 0.001 );    
+    payload1["UI64"].setValue<unsigned long long>( 64 );
+    //payload1["SI64"].setValue<long long>( -64 );
+    folder1a->storeObject( 0, 10, payload1, 1 );
+    folder1a->storeObject( 10, 20, payload1, 1 );
+    folder1a->storeObject( 0, plusInfinity, payload1, 2 );
+    folder1a->storeObject( 10, plusInfinity, payload1, 2 );
+    folder1a->storeObject( 20, plusInfinity, payload1, 2 );
+    folder1a->storeObject( 30, plusInfinity, payload1, 2 );
+
+    // Try to insert data with online IOV overlap: this will throw an exception
+    try {      
+      folder1a->storeObject( 5, 15, payload1, 1 );
+    } catch ( std::exception& e ) {
+      LOG << "Exception caught as expected: " << e.what() << std::endl;
+    }
+
+    // Store a valid IOV - test that the previous invalid IOV was discarded
+    folder1a->storeObject( 40, plusInfinity, payload1, 2 );
+    
+    // Print the list of channels
+    std::vector<ChannelId> channelList = folder1a->listChannels();
+    LOG << "-> List of channels in folder " 
+        << folder1a->fullPath() << std::endl;
+    std::vector<ChannelId>::const_iterator channelIt;
+    for( channelIt = channelList.begin(); 
+         channelIt != channelList.end(); 
+         channelIt++ ) {
+      std::cout << *channelIt << std::endl;
+    }
+
+    // Dump the object stored for time t=5 in channel 1
+    IObjectPtr obj1a_ch1_5 = folder1a->findObject( 5, 1 );
+    LOG << "Retrieved object valid at t=5 in channel 1 of folder "
+        << folder1a->fullPath() << std::endl;
+    LOG << "Object: channelId=" << obj1a_ch1_5->channelId() << std::endl;
+    LOG << "Object: since=" << obj1a_ch1_5->since() 
+        << ", until=" << obj1a_ch1_5->until() << std::endl;
+    LOG << "Object: payload values (true types)"
+        << ": payload[\"I\"]=" << obj1a_ch1_5->payloadValue<int>("I")
+        << ", payload[\"S\"]=" << obj1a_ch1_5->payloadValue<std::string>("S")
+        << ", payload[\"X\"]=" << obj1a_ch1_5->payloadValue<float>("X")
+        << ", payload[\"UI64\"]=" 
+        << obj1a_ch1_5->payloadValue<unsigned long long>("UI64")
+      //<< ", payload[\"SI64\"]=" 
+      //<< obj1a_ch1_5->payloadValue<long long>("SI64")
+        << std::endl;
+    LOG << "Object: payload values (as strings)"
+        << ": payload[\"I\"]=" << obj1a_ch1_5->payloadValue("I")
+        << ", payload[\"S\"]=" << obj1a_ch1_5->payloadValue("S")
+        << ", payload[\"X\"]=" << obj1a_ch1_5->payloadValue("X")
+        << ", payload[\"UI64\"]=" << obj1a_ch1_5->payloadValue("UI64")
+      //<< ", payload[\"SI64\"]=" << obj1a_ch1_5->payloadValue("SI64")
+        << std::endl;
+    if( ! obj1a_ch1_5->isStored() ) {
+      LOG << "Object: isStored=false" << std::endl;
+    } else {
+      LOG << "Object: isStored=true" << std::endl;
+      LOG << "Object: insertionTime=" 
+          << timeToString( obj1a_ch1_5->insertionTime() ) << std::endl;;
+    }
+
+    // Try to insert data with since>until: this will throw an exception
+    try {      
+      folder1a->storeObject( 30, 20, payload1 );
+    } catch ( std::exception& e ) {
+      LOG << "Exception caught as expected: " << e.what() << std::endl;
+    }
+
+    // Try to insert data with until>MAX: this will throw an exception
+    try {      
+      ValidityKey since = ValidityKeyMax;
+      // Split the following line on two lines (Windows compiler warning) 
+      //ValidityKey until = ValidityKeyMax+1;
+      ValidityKey until = ValidityKeyMax;
+      until = until+1;
+      // NB: Now (ValidityKey=long_long, ValidityKeyMax=LONG_LONG_MAX)
+      //     ==> LONG_LONG_MAX+1 is an invalid int64 LONG_LONG_MIN < since
+      // NB: Previously (ValidityKey=long_long, ValidityKeyMax=LONG_MAX)
+      //     ==> LONG_MAX+1 is an invalid int64 > LONG_MAX=ValidityKeyMax
+      folder1a->storeObject( since, until, payload1 );
+    } catch ( std::exception& e ) {
+      LOG << "Exception caught as expected: " << e.what() << std::endl;
+    }
+
+    // Insert some data into folder 1b
+    folder1b->storeObject( 0, 10, payload1 );
+
+    // Drop folder 1b
+    db->dropNode( folderName1b );
+
+    // Print the list of folders again
+    folderList = db->getFolderSet( "/my" )->listFolders();
+    LOG << "-> List of folders in the database:" << std::endl;
+    for( folderIt = folderList.begin(); 
+         folderIt != folderList.end(); 
+         folderIt++ ) {
+      std::cout << *folderIt << std::endl;
+    }
+
+    // Try to insert data into deleted folder 1b: this will throw an exception
+    // Try to insert data with since>until: this will throw an exception
+    try {      
+      folder1b->storeObject( 10, 20, payload1 );
+    } catch ( std::exception& e ) {
+      LOG << "Exception caught as expected: " << e.what() << std::endl;
+    }
+
+    // Bulk-insert some data into folder 1c
+    ValidityKey bulkSince;
+    folder1c->setupStorageBuffer();
+    for ( bulkSince=0; bulkSince<100; bulkSince++ ) {
+      folder1c->storeObject( bulkSince*10, plusInfinity, payload1, 1 );
+    }
+    folder1c->flushStorageBuffer();
+
+    // Reset the database pointer: this will close the connection
+    LOG << "Release the conditions database connection" << std::endl;
+    cool::IDatabasePtr dbNull;
+    db = dbNull;
+
+    //---------------------------
+    // OPEN AN EXISTING DATABASE
+    //---------------------------
+
+    // Open an existing COOL conditions database
+    LOG << "Open an existing conditions database: " << dbId << std::endl;
+    cool::IDatabasePtr db2 = dbSvc.openDatabase( dbId, false );
+    LOG << "Conditions database opened: " << std::endl;
+    LOG << "-> Database ID: " << db2->databaseId() << std::endl;
+    std::ostringstream db2Attr;
+    db2->databaseAttributes().print( db2Attr );
+    LOG << "-> Database attributes: " << db2Attr.str() << std::endl;
+
+    // Print the list of folders
+    folderList = db2->getFolderSet( "/my" )->listFolders();
+    LOG << "-> List of folders in the database:" << std::endl;
+    for( folderIt = folderList.begin(); 
+         folderIt != folderList.end(); 
+         folderIt++ ) {
+      std::cout << *folderIt << std::endl;
+    }    
+
+    // *** WARNING!! ***
+    // You MUST get a new handle to folder 1c here: the old one is invalid and
+    // causes a segmentation fault. A protection must be added in the code!
+    folder1c = db2->getFolder( folderName1c );
+
+    // Bulk-retrieve the objects stored in channel 1 of folder 1c in [245,295]
+    std::string tag = "";
+    ChannelId channelId = 1;
+    ValidityKey since = 245;
+    ValidityKey until = 295;  
+    IObjectIteratorPtr objIt = 
+      folder1c->browseObjects( since, until, channelId, tag );
+    LOG << "Retrieved object iterator in [245,295] for channel 1 of folder "
+        << folder1c->fullPath() << std::endl;
+    if ( objIt->isEmpty() ) {
+      LOG << "Iterator contains no objects" << std::endl;
+    } else {
+      objIt->goToStart();
+      while( objIt->hasNext() ) {
+        IObjectPtr object = objIt->next();
+        LOG << "Object: channelId=" << object->channelId()
+            << ", since=" << object->since() 
+            << ", until=" << object->until() << std::endl;
+        LOG << "Object: payload values (true types)"
+            << ": payload[\"I\"]=" << object->payloadValue<int>("I")
+            << ", payload[\"S\"]=" << object->payloadValue<std::string>("S")
+            << ", payload[\"X\"]=" << object->payloadValue<float>("X")
+            << ", payload[\"UI64\"]=" 
+            << object->payloadValue<unsigned long long>("UI64")
+          //<< ", payload[\"SI64\"]=" 
+          //<< object->payloadValue<long long>("SI64")
+            << std::endl;
+        if( ! object->isStored() ) {
+          LOG << "Object: isStored=false" << std::endl;
+        } else {
+          LOG << "Object: isStored=true, insertionTime=" 
+              << timeToString( object->insertionTime() ) << std::endl;;
+        }
+      } 
+    }
+
+    // Create folder 1d
+    std::string folderName1d( "/my/folder1d" );
+    cool::IFolderPtr folder1d = db2->createFolder
+      ( folderName1d, payloadSpec1, "", 
+        FolderVersioning::MULTI_VERSION, true );
+    LOG << "Folder created: " << std::endl;
+    LOG << "-> Folder name: " << folder1d->fullPath() << std::endl;
+    std::ostringstream folderAttr1d;
+    folder1c->payloadSpecification().print( folderAttr1d );
+    LOG << "-> Folder payload specification: " 
+        << folderAttr1d.str() << std::endl;
+
+    // Print the list of folders again
+    folderList = db2->getFolderSet( "/my" )->listFolders();
+    LOG << "-> List of folders in the database:" << std::endl;
+    for( folderIt = folderList.begin(); 
+         folderIt != folderList.end(); 
+         folderIt++ ) {
+      std::cout << *folderIt << std::endl;
+    }    
+
+    // Insert some data into folder 1d
+    folder1d->storeObject( 1, 8, payload1, 1 );
+    folder1d->storeObject( 2, 5, payload1, 1 );
+    folder1d->storeObject( 3, 6, payload1, 1 );
+    folder1d->storeObject( 4, 7, payload1, 1 );
+
+    // Bulk-retrieve the objects stored in channel 1 of folder 1d
+    tag = "";
+    channelId = 1;
+    since = ValidityKeyMin;
+    until = ValidityKeyMax;
+    objIt = 
+      folder1d->browseObjects( since, until, channelId, tag );
+    LOG << "Retrieved object iterator in [-inf,+inf] for channel 1 of folder "
+        << folder1d->fullPath() << std::endl;
+    if ( objIt->isEmpty() ) {
+      LOG << "Iterator contains no objects" << std::endl;
+    } else {
+      objIt->goToStart();
+      while( objIt->hasNext() ) {
+        IObjectPtr object = objIt->next();
+        LOG << "Object: channelId=" << object->channelId()
+            << ", since=" << object->since() 
+            << ", until=" << object->until() << std::endl;
+        LOG << "Object: payload values (true types)"
+            << ": payload[\"I\"]=" << object->payloadValue<int>("I")
+            << ", payload[\"S\"]=" << object->payloadValue<std::string>("S")
+            << ", payload[\"X\"]=" << object->payloadValue<float>("X")
+            << ", payload[\"UI64\"]=" 
+            << object->payloadValue<unsigned long long>("UI64")
+          //<< ", payload[\"SI64\"]=" 
+          //<< object->payloadValue<long long>("SI64")
+            << std::endl;
+        if( ! object->isStored() ) {
+          LOG << "Object: isStored=false" << std::endl;
+        } else {
+          LOG << "Object: isStored=true, insertionTime=" 
+              << timeToString( object->insertionTime() ) << std::endl;;
+        }
+      } 
+    }
+
+    // Successful completion
+    LOG << "Program terminating succesfully" << std::endl;
+    status = 0;
+    
+  }
+  catch(std::exception& e)
+  {
+    LOG << "ERROR! Standard C++ exception: '" << e.what() << "'" << std::endl;
+    status = 1;
+  }
+  catch(...) 
+  {
+    LOG << "ERROR! Unknown exception caught" << std::endl;
+    status = 1;
+  }
+
+  // Program termination
+  LOG << "Exiting main" << std::endl;
+  return status;
+  
+}
+
+//-----------------------------------------------------------------------------
+
+#endif // NOPORT
diff --git a/RelationalCool/tests/HvsPathHandler/test_HvsPathHandler.cpp b/RelationalCool/tests/HvsPathHandler/test_HvsPathHandler.cpp
new file mode 100644
index 000000000..da003170b
--- /dev/null
+++ b/RelationalCool/tests/HvsPathHandler/test_HvsPathHandler.cpp
@@ -0,0 +1,230 @@
+// $Id: test_HvsPathHandler.cpp,v 1.7 2007-04-02 11:53:33 marcocle Exp $
+
+// Include files
+#include "../Common/CppUnit_headers.h" // Disable CppUnit header warnings
+
+// Local include files
+#include "src/HvsPathHandler.h"
+#include "src/HvsPathHandlerException.h"
+
+namespace cool {
+  // This line is to avoid error "qualified name does not name a class"
+  // on gcc 4.1
+  class HvsPathHandlerTest;
+}
+
+//-----------------------------------------------------------------------------
+
+class cool::HvsPathHandlerTest : public CppUnit::TestFixture {
+		
+  CPPUNIT_TEST_SUITE( HvsPathHandlerTest );
+  CPPUNIT_TEST( test_removeTrailingSeparators );
+  CPPUNIT_TEST( test_removeDoubleSeparators );
+  CPPUNIT_TEST( test_splitFullPath );
+  CPPUNIT_TEST( test_decodeFullPath );
+  CPPUNIT_TEST( test_encodeFullPath );
+  CPPUNIT_TEST_SUITE_END();
+  
+public:
+  
+  void setUp() {  
+  }
+		
+  void tearDown() {
+  }
+  
+  //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+  typedef std::string S;
+  typedef std::pair<S,S> P;
+  typedef std::vector<S> V;
+  const V newV( const int nS, const S& s1, const S& s2="", const S& s3="", 
+                const S& s4="", const S& s5="", const S& s6="" ) {
+    V v;
+    if ( nS<1 || nS >6 ) 
+      throw HvsPathHandlerException( "Wrong arguments to newV" );
+    if ( nS>=1 ) v.push_back( s1 );
+    if ( nS>=2 ) v.push_back( s2 );
+    if ( nS>=3 ) v.push_back( s3 );
+    if ( nS>=4 ) v.push_back( s4 );
+    if ( nS>=5 ) v.push_back( s5 );
+    if ( nS>=6 ) v.push_back( s6 );
+    return v;
+  }
+
+  //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+  void test_removeTrailingSeparators() {
+    HvsPathHandler h;
+    CPPUNIT_ASSERT_MESSAGE
+      ( "Test '/a/b/c'", 
+        "/a/b/c" == h.removeTrailingSeparators("/a/b/c") );
+    CPPUNIT_ASSERT_MESSAGE
+      ( "Test '/a/b/c/'", 
+        "/a/b/c" == h.removeTrailingSeparators("/a/b/c/") );
+    CPPUNIT_ASSERT_MESSAGE
+      ( "Test '/a/b/c//'", 
+        "/a/b/c" == h.removeTrailingSeparators("/a/b/c//") );
+    CPPUNIT_ASSERT_MESSAGE
+      ( "Test '/'", 
+        "/" == h.removeTrailingSeparators("/") );
+    CPPUNIT_ASSERT_MESSAGE
+      ( "Test '//'", 
+        "/" == h.removeTrailingSeparators("//") );
+    CPPUNIT_ASSERT_MESSAGE
+      ( "Test ''", 
+        "" == h.removeTrailingSeparators("") );
+    CPPUNIT_ASSERT_MESSAGE
+      ( "Test 'a//b/c//'", 
+        "a//b/c" == h.removeTrailingSeparators("a//b/c//") );
+  }
+
+  //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+  void test_removeDoubleSeparators() {
+    HvsPathHandler h;
+    CPPUNIT_ASSERT_MESSAGE
+      ( "Test '/a/b/c'", 
+        "/a/b/c" == h.removeDoubleSeparators("/a/b/c") );
+    CPPUNIT_ASSERT_MESSAGE
+      ( "Test '/a/b/c/'", 
+        "/a/b/c/" == h.removeDoubleSeparators("/a/b/c/") );
+    CPPUNIT_ASSERT_MESSAGE
+      ( "Test '/a/b/c//'", 
+        "/a/b/c/" == h.removeDoubleSeparators("/a/b/c//") );
+    CPPUNIT_ASSERT_MESSAGE
+      ( "Test '/a/b//c'", 
+        "/a/b/c" == h.removeDoubleSeparators("/a/b//c") );
+    CPPUNIT_ASSERT_MESSAGE
+      ( "Test '///a/b///c//'", 
+        "/a/b/c/" == h.removeDoubleSeparators("///a///b/c//") );
+    CPPUNIT_ASSERT_MESSAGE
+      ( "Test '/'", 
+        "/" == h.removeDoubleSeparators("/") );
+    CPPUNIT_ASSERT_MESSAGE
+      ( "Test '//'", 
+        "/" == h.removeDoubleSeparators("//") );
+    CPPUNIT_ASSERT_MESSAGE
+      ( "Test ''", 
+        "" == h.removeDoubleSeparators("") );
+    CPPUNIT_ASSERT_MESSAGE
+      ( "Test 'a//b/c'", 
+        "a/b/c" == h.removeDoubleSeparators("a//b/c") );
+  }
+
+  //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+  void test_splitFullPath() {
+
+    HvsPathHandler h;
+
+    // Test retrieving pairs
+    CPPUNIT_ASSERT_MESSAGE
+      ( "Test '/a/b/c'", 
+        P( "/a/b", "c" ) == h.splitFullPath("/a/b/c") );
+    CPPUNIT_ASSERT_MESSAGE
+      ( "Test '/a'", 
+        P( "/", "a" ) == h.splitFullPath("/a") );
+
+    // Test catching exceptions
+    bool caught;
+    std::vector<std::string> excPaths;
+    excPaths.push_back("");
+    excPaths.push_back("/");
+    excPaths.push_back("/a/b/");
+    excPaths.push_back("/a//b");
+    excPaths.push_back("//");
+    std::vector<std::string>::const_iterator iPath;
+    for ( iPath = excPaths.begin(); iPath != excPaths.end(); iPath++ ) {
+      std::string excPath = *iPath;
+      try { caught = false; h.splitFullPath(excPath); }
+      catch ( HvsPathHandlerException& /* dummy */ ) { caught = true; }
+      CPPUNIT_ASSERT_MESSAGE( std::string("Test ")+excPath, caught == true );
+    }
+  }
+
+  //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+  void test_decodeFullPath() {
+
+    HvsPathHandler h;
+
+    // Test retrieving vectors
+    CPPUNIT_ASSERT_MESSAGE
+      ( "Test '/a/b/c'", 
+        newV( 4, "", "a", "b", "c" ) == h.decodeFullPath("/a/b/c") );
+    CPPUNIT_ASSERT_MESSAGE
+      ( "Test '/a'", 
+        newV( 2, "", "a" ) == h.decodeFullPath("/a") );
+    CPPUNIT_ASSERT_MESSAGE
+      ( "Test '/", 
+        newV( 1, "" ) == h.decodeFullPath("/") );
+
+    // Test catching exceptions
+    bool caught;
+    std::vector<std::string> excPaths;
+    excPaths.push_back("");
+    excPaths.push_back("a");
+    excPaths.push_back("/a/b/");
+    excPaths.push_back("/a//b");
+    excPaths.push_back("//");
+    std::vector<std::string>::const_iterator iPath;
+    for ( iPath = excPaths.begin(); iPath != excPaths.end(); iPath++ ) {
+      std::string excPath = *iPath;
+      try { caught = false; h.decodeFullPath(excPath); }
+      catch ( HvsPathHandlerException& /* dummy */ ) { caught = true; }
+      CPPUNIT_ASSERT_MESSAGE( std::string("Test ")+excPath, caught == true );
+    }
+
+  }
+
+  //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+  void test_encodeFullPath() {
+
+    HvsPathHandler h;
+
+    // Test building full paths
+    CPPUNIT_ASSERT_MESSAGE
+      ( "Test '/a/b/c'", 
+        "/a/b/c" == h.encodeFullPath( newV(4,"","a","b","c") ) );
+    CPPUNIT_ASSERT_MESSAGE
+      ( "Test '/'", 
+        "/" == h.encodeFullPath( newV(1,"") ) );
+
+    // Test catching exceptions
+    bool caught;
+    std::vector<V> excLists;
+    excLists.push_back(newV(1,"a"));
+    excLists.push_back(newV(1,"/"));
+    excLists.push_back(newV(2,"/","a"));
+    excLists.push_back(newV(2,"","/"));
+    excLists.push_back(newV(2,"","/a"));
+    excLists.push_back(newV(2,"","a/"));
+    std::vector<V>::const_iterator iList;
+    for ( iList = excLists.begin(); iList != excLists.end(); iList++ ) {
+      V excList = *iList;
+      try { caught = false; h.encodeFullPath(excList); }
+      catch ( HvsPathHandlerException& /* dummy */ ) { caught = true; }
+      std::ostringstream msg;
+      msg << "Test " << excList.size();
+      for ( V::const_iterator iS = (*iList).begin(); iS != (*iList).end(); 
+            iS++ ) { msg << ", '" << *iS << "'"; }
+      CPPUNIT_ASSERT_MESSAGE( msg.str(), caught == true );
+    }
+
+  }
+
+  //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+};
+
+CPPUNIT_TEST_SUITE_REGISTRATION( cool::HvsPathHandlerTest );
+
+//-----------------------------------------------------------------------------
+
+// Include CppUnit test driver
+#include<CppUnit_testdriver.icpp>
+
+
+
diff --git a/RelationalCool/tests/HvsTags/test_HvsTags.cpp b/RelationalCool/tests/HvsTags/test_HvsTags.cpp
new file mode 100644
index 000000000..31205a9c6
--- /dev/null
+++ b/RelationalCool/tests/HvsTags/test_HvsTags.cpp
@@ -0,0 +1,2738 @@
+// $Id: test_HvsTags.cpp,v 1.67 2008-11-03 12:20:15 avalassi Exp $
+
+// Include files
+#include <iostream>
+#include "../Common/CppUnit_headers.h" // Disable CppUnit header warnings
+#include "src/CoralApplication.h"
+#include "CoolKernel/IDatabaseSvc.h"
+#include "CoolKernel/IDatabase.h"
+#include "CoolKernel/IFolder.h"
+#include "CoolKernel/IFolderSet.h"
+#include "CoolKernel/IObject.h"
+#include "CoolKernel/Record.h"
+#include "CoolKernel/RecordSpecification.h"
+#include "CoolKernel/Time.h"
+#include "CoralBase/Attribute.h"
+#include "CoralBase/MessageStream.h"
+
+// Namespace
+namespace cool {
+  const char* COOLTESTDB = "COOLTESTDB";
+  class HvsTagTest;
+}
+
+//-----------------------------------------------------------------------------
+
+class cool::HvsTagTest : public CppUnit::TestFixture {
+
+  CPPUNIT_TEST_SUITE( HvsTagTest );
+
+  CPPUNIT_TEST( test_hvsTags );
+  CPPUNIT_TEST( test_iovHeadAndUserTags );
+  CPPUNIT_TEST( test_iovAndHvsTags );
+  CPPUNIT_TEST( test_userAndHvsTags );
+  CPPUNIT_TEST( test_hvsAndIovTags );
+  CPPUNIT_TEST( test_hvsAndUserTags );
+  CPPUNIT_TEST( test_createParentsTrue );
+  CPPUNIT_TEST( test_createParentsFalse );
+  CPPUNIT_TEST( test_svFolder );
+  CPPUNIT_TEST( test_listTags );
+  CPPUNIT_TEST( test_resolveLocalTag );
+  CPPUNIT_TEST( test_resolveTagFails );
+  CPPUNIT_TEST( test_tagRelationExists );
+
+  CPPUNIT_TEST( test_lockTag_fails );
+  CPPUNIT_TEST( test_tagLocked_dropNode );
+  CPPUNIT_TEST( test_tagLocked_storeObjectWithUserTag );
+  CPPUNIT_TEST( test_tagLocked_tagCurrentHead );
+  CPPUNIT_TEST( test_tagLocked_tagHeadAsOfDate );
+  CPPUNIT_TEST( test_tagLocked_deleteTag );
+  CPPUNIT_TEST( test_tagLocked_createTagRelation );
+  CPPUNIT_TEST( test_tagLocked_deleteTagRelation );
+
+  CPPUNIT_TEST( test_partiallyLockTag_fails );
+  CPPUNIT_TEST( test_tagPartiallyLocked_dropNode );
+  CPPUNIT_TEST( test_tagPartiallyLocked_storeObjectWithUserTag );
+  CPPUNIT_TEST( test_tagPartiallyLocked_tagCurrentHead );
+  CPPUNIT_TEST( test_tagPartiallyLocked_tagHeadAsOfDate );
+  CPPUNIT_TEST( test_tagPartiallyLocked_deleteTag );
+  CPPUNIT_TEST( test_tagPartiallyLocked_createTagRelation );
+  CPPUNIT_TEST( test_tagPartiallyLocked_deleteTagRelation );
+  CPPUNIT_TEST( test_tagPartiallyLocked_storeObjectWithUserTagNoOverlap );
+
+  CPPUNIT_TEST( test_emptyTag );
+
+  CPPUNIT_TEST_SUITE_END();
+
+public:
+
+  std::string connectString;
+  IDatabasePtr db;
+
+  RecordSpecification payloadSpec;
+  
+  //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+  void test_hvsTags() 
+  {
+
+    try {
+      
+      // Node hierarchy
+      // -> fldset /
+      // -> fldset /A
+      // -> folder /A/fX
+      // -> folder /A/fY
+      IFolderSetPtr sA  = db->createFolderSet( "/A" );
+      IFolderPtr fAX  = createAndFillMVFolder( "/A/fX" );
+      IFolderPtr fAY  = createAndFillMVFolder( "/A/fY" );
+      
+      // Tag hierarchy for "/A    version #1"
+      // -> fldset '/A    version #1'
+      // -> folder '/A/fX version #1'
+      // -> folder '/A/fY version #1'
+      std::string tA_1  = "/A    version #1";
+      std::string tAX_1 = "/A/fX version #1";
+      std::string tAY_1 = "/A/fY version #1";
+      fAX->createTagRelation( tA_1,  tAX_1 );
+      fAY->createTagRelation( tA_1,  tAY_1 );
+      
+      // Query parent-child tag relations
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "Find /A/fX tag for " + tA_1, tAX_1, fAX->findTagRelation( tA_1 ) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "Find /A/fY tag for " + tA_1, tAY_1, fAY->findTagRelation( tA_1 ) );
+      
+      // Tag hierarchy for "/A    version #2"
+      // -> fldset '/A    version #2'
+      // -> folder '/A/fX version #2'
+      // -> folder '/A/fY version #2'
+      std::string tA_2  = "/A    version #2";
+      std::string tAX_2 = "/A/fX version #2";
+      std::string tAY_2 = "/A/fY version #2";
+      fAX->createTagRelation( tA_2,  tAX_2 );
+      fAY->createTagRelation( tA_2,  tAY_2 );
+      
+      // Query parent-child tag relations
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "Find /A/fX tag for " + tA_2, tAX_2, fAX->findTagRelation( tA_2 ) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "Find /A/fY tag for " + tA_2, tAY_2, fAY->findTagRelation( tA_2 ) );
+      
+      // Tag hierarchy for "/     version PROD"
+      // -> fldset '/     version PROD'
+      // -> fldset '/A    version PROD'
+      // -> folder '/A/fX version #2'
+      // -> folder '/A/fY version #1'
+      std::string tA_PR = "/A    version PROD";
+      std::string t_PR  = "/     version PROD";
+      
+      // Test existance of tags in any node
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "Does tag " + tA_PR + " exist?", false, db->existsTag( tA_PR ) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "Does tag " + t_PR + " exist?", false, db->existsTag( t_PR ) );
+      
+      // Create tag relations for /A PROD version
+      fAX->createTagRelation( tA_PR, tAX_2 );
+      fAY->createTagRelation( tA_PR, tAY_1 );
+      
+      // Test existance of tags in any node
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "Does tag " + tA_PR + " exist?", true, db->existsTag( tA_PR ) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "Does tag " + t_PR + " exist?", false, db->existsTag( t_PR ) );
+      
+      // Create tag relations for / PROD version
+      sA->createTagRelation(  t_PR,  tA_PR );
+      
+      // Test existance of tags in any node
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "Does tag " + tA_PR + " exist?", true, db->existsTag( tA_PR ) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "Does tag " + t_PR + " exist?", true, db->existsTag( t_PR ) );
+      
+      // Query parent-child tag relations
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "Find /A/fX tag for " + tA_PR, 
+          tAX_2, fAX->findTagRelation( tA_PR ) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "Find /A/fY tag for " + tA_PR, 
+          tAY_1, fAY->findTagRelation( tA_PR ) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "Find /A tag for " + t_PR, tA_PR, sA->findTagRelation( t_PR ) );
+
+      // Resolve parent-child tag relations (w/o assuming parent-child nodes)
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "Find /A/fX tag for " + tA_PR, tAX_2, fAX->resolveTag( tA_PR ) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "Find /A/fY tag for " + tA_PR, tAY_1, fAY->resolveTag( tA_PR ) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "Find /A tag for " + t_PR, tA_PR, sA->resolveTag( t_PR ) );
+      
+      // Resolve ancestor-descendant tag relations
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "Find /A/fX tag for " + t_PR, tAX_2, fAX->resolveTag( t_PR ) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "Find /A/fY tag for " + t_PR, tAY_1, fAY->resolveTag( t_PR ) );
+      
+      // Test existance of tags in any node
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "Does tag " + tA_PR + " exist?", true, db->existsTag( tA_PR ) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "Does tag " + t_PR + " exist?", true, db->existsTag( t_PR ) );
+
+      // Delete tag relation for / PROD version 
+      sA->deleteTagRelation( t_PR );
+      
+      // Test existance of tag relation
+      try {
+        sA->findTagRelation( t_PR );
+        CPPUNIT_FAIL( "Find /A tag for " + t_PR + " should fail" );
+      } 
+      catch ( TagNotFound& ) {} 
+      catch ( TagRelationNotFound& ) {
+        CPPUNIT_FAIL( "Find /A tag for " + t_PR + " TagNotFound expected" );
+      } 
+      
+      // Test existance of tags in any node
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "Does tag " + tA_PR + " exist?", true, db->existsTag( tA_PR ) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "Does tag " + t_PR + " exist?", false, db->existsTag( t_PR ) );
+      
+      // Create tag relations for / PROD version - again
+      sA->createTagRelation(  t_PR,  tA_PR );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "Find /A tag for " + t_PR, tA_PR, sA->findTagRelation( t_PR ) );
+      
+      // Delete tag relation for / PROD version - again
+      sA->deleteTagRelation( t_PR );
+      try {
+        sA->findTagRelation( t_PR );
+        CPPUNIT_FAIL( "Find /A tag for " + t_PR + " should fail" );
+      } 
+      catch ( TagNotFound& ) {} 
+      catch ( TagRelationNotFound& ) {
+        CPPUNIT_FAIL( "Find /A tag for " + t_PR + " TagNotFound expected" );
+      } 
+
+      // Test existance of tags in any node
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "Does tag " + tA_PR + " exist?", true, db->existsTag( tA_PR ) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "Does tag " + t_PR + " exist?", false, db->existsTag( t_PR ) );
+      
+      // Delete /A/fX tag relation for /A PROD version 
+      fAX->deleteTagRelation( tA_PR );
+      try {
+        fAX->findTagRelation( tA_PR );
+        CPPUNIT_FAIL( "Find /A/fX tag for " + tA_PR + " should fail" );
+      } 
+      catch ( TagRelationNotFound& ) {}
+
+      // Test existance of tags in any node
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "Does tag " + tAX_2 + " exist?", true, db->existsTag( tAX_2 ) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "Does tag " + tA_PR + " exist?", true, db->existsTag( tA_PR ) );
+      
+      // Delete /A/fY tag relation for /A PROD version 
+      fAY->deleteTagRelation( tA_PR );
+      try {
+        fAY->findTagRelation( tA_PR );
+        CPPUNIT_FAIL( "Find /A/fY tag for " + tA_PR + " should fail" );
+      } 
+      catch ( TagNotFound& ) {} 
+      catch ( TagRelationNotFound& ) {
+        CPPUNIT_FAIL( "Find /A/fY tag for " + t_PR + " TagNotFound expected" );
+      } 
+
+      // Test existance of tags in any node
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "Does tag " + tAY_1 + " exist?", true, db->existsTag( tAY_1 ) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "Does tag " + tA_PR + " exist?", false, db->existsTag( tA_PR ) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "Does tag " + tA_1 + " exist?", true, db->existsTag( tA_1 ) );
+      
+      // Delete /A/fY tag relation for /A version #1
+      fAY->deleteTagRelation( tA_1 );
+      try {
+        fAY->findTagRelation( tA_1 );
+        CPPUNIT_FAIL( "Find /A/fY tag for " + tA_1 + " should fail" );
+      } 
+      catch ( TagRelationNotFound& ) {}
+
+      // Test existance of tags in any node
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "Does tag " + tAY_1 + " exist?", false, db->existsTag( tAY_1 ) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "Does tag " + tA_1 + " exist?", true, db->existsTag( tA_1 ) );
+      
+    }
+
+    catch ( std::exception& e ) { 
+      std::cout << "Exception caught: '" << e.what() << "'" << std::endl;
+      throw;
+    }
+    
+  }
+
+  //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+  void test_iovHeadAndUserTags() 
+  {
+    bool debug = false;
+    try {
+
+      // Folder /fA
+      if ( debug ) std::cout << "Test A" << std::endl;
+      IFolderPtr fa = createAndFillMVFolder( "/fA" );
+      std::string ah1 = "AH1";
+      std::string ad1 = "AD1";
+      std::string au1 = "AU1";
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "1 Exist "+ah1, false, db->existsTag(ah1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "1 Exist "+ad1, false, db->existsTag(ad1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "1 Exist "+au1, false, db->existsTag(au1) );
+      if ( debug ) std::cout << "Test A count AH1" << std::endl;
+      CPPUNIT_ASSERT_THROW
+        ( fa->countObjects(0,100,0,ah1), TagNotFound );
+      if ( debug ) std::cout << "Test A count AD1" << std::endl;
+      CPPUNIT_ASSERT_THROW
+        ( fa->countObjects(0,100,0,ad1), TagNotFound );
+      if ( debug ) std::cout << "Test A count AU1" << std::endl;
+      CPPUNIT_ASSERT_THROW
+        ( fa->countObjects(0,100,0,au1), TagNotFound );
+
+      // - create AH1 as IOV head tag 
+      //   > using AH1 as IOV date tag fails
+      //   > using AH1 as IOV user tag fails
+      if ( debug ) std::cout << "Test AH1" << std::endl;
+      fa->tagCurrentHead( ah1 );
+      Time date = fa->findObject( 20, 0 )->insertionTime();
+      Record payload = dummyPayload( 10 );
+      try {
+        fa->tagHeadAsOfDate( date, ah1 );
+        CPPUNIT_FAIL( "Using AH1 as date tag should fail" );
+      } catch ( TagExists& ) {}      
+      try {
+        fa->storeObject( 5, 15, payload, 0, ah1 );
+        CPPUNIT_FAIL( "Using AH1 as user tag should fail" );
+      } catch ( TagExists& ) {}      
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "2 Exist "+ah1, true, db->existsTag(ah1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "2 Exist "+ad1, false, db->existsTag(ad1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "2 Exist "+au1, false, db->existsTag(au1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "2 # "+ah1, 3u, fa->countObjects(0,100,0,ah1) );
+      CPPUNIT_ASSERT_THROW
+        ( fa->countObjects(0,100,0,ad1), TagNotFound );
+      CPPUNIT_ASSERT_THROW
+        ( fa->countObjects(0,100,0,au1), TagNotFound );
+
+      // - create AD1 as IOV date tag 
+      //   > using AD1 as IOV head tag fails
+      //   > using AD1 as IOV user tag fails
+      if ( debug ) std::cout << "Test AD1" << std::endl;
+      fa->tagHeadAsOfDate( date, ad1 );
+      try {
+        fa->tagCurrentHead( ad1 );
+        CPPUNIT_FAIL( "Using AD1 as head tag should fail" );
+      } catch ( TagExists& ) {}      
+      try {
+        fa->storeObject( 5, 15, payload, 0, ad1 );
+        CPPUNIT_FAIL( "Using AD1 as user tag should fail" );
+      } catch ( TagExists& ) {}      
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "3 Exist "+ah1, true, db->existsTag(ah1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "3 Exist "+ad1, true, db->existsTag(ad1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "3 Exist "+au1, false, db->existsTag(au1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "3 # "+ah1, 3u, fa->countObjects(0,100,0,ah1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "3 # "+ad1, 3u, fa->countObjects(0,100,0,ad1) );
+      CPPUNIT_ASSERT_THROW
+        ( fa->countObjects(0,100,0,au1), TagNotFound );
+
+      // - create AU1 as IOV user tag 
+      //   > using AU1 as IOV head tag fails
+      //   > using AU1 as IOV date tag fails
+      if ( debug ) std::cout << "Test AU1" << std::endl;
+      fa->storeObject( 5, 15, payload, 0, au1 );
+      try {
+        fa->tagCurrentHead( au1 );
+        CPPUNIT_FAIL( "Using AU1 as head tag should fail" );
+      } catch ( TagExists& ) {}      
+      try {
+        fa->tagHeadAsOfDate( date, au1 );
+        CPPUNIT_FAIL( "Using AU1 as date tag should fail" );
+      } catch ( TagExists& ) {}      
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "4 Exist "+ah1, true, db->existsTag(ah1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "4 Exist "+ad1, true, db->existsTag(ad1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "4 Exist "+au1, true, db->existsTag(au1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "4 # "+ah1, 3u, fa->countObjects(0,100,0,ah1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "4 # "+ad1, 3u, fa->countObjects(0,100,0,ad1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "4 # "+au1, 1u, fa->countObjects(0,100,0,au1) );
+    }
+
+    catch ( std::exception& e ) { 
+      std::cout << "Exception caught: '" << e.what() << "'" << std::endl;
+      throw;
+    }
+
+  }
+
+  //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+  void test_iovAndHvsTags() 
+  {
+
+    try {
+      Record payload = dummyPayload( 10 );
+      // Folder /fA
+      // - create A1 as IOV head tag 
+      //   > using A1 as IOV user tag fails
+      // - create A1 as HVS tag (create relation) 
+      // - delete A1 as IOV tag
+      // - delete A1 as HVS tag (delete relation)
+      IFolderPtr fa = createAndFillMVFolder( "/fA" );
+      std::string prod = "PROD";
+      std::string a1 = "A1";
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 Exist "+a1, false, db->existsTag(a1) );
+      CPPUNIT_ASSERT_THROW( fa->countObjects(0,100,0,a1), TagNotFound );
+      fa->tagCurrentHead( a1 );
+      try {
+        fa->storeObject( 5, 15, payload, 0, a1 );
+        CPPUNIT_FAIL( "Using A1 as user tag should fail" );
+      } catch ( TagExists& ) {}      
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 Exist "+a1, true, db->existsTag(a1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 #", 3u, fa->countObjects(0,100,0,a1) );
+      fa->createTagRelation( prod, a1 );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 Exist "+a1, true, db->existsTag(a1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 - "+a1, a1, fa->findTagRelation(prod) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 #", 3u, fa->countObjects(0,100,0,a1) );
+      // This may be a bit confusing: the tag still exists after being deleted!
+      // A better name for this method may be 'untag' (remove IOV2TAG links).
+      fa->deleteTag( a1 );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "4 Exist "+a1, true, db->existsTag(a1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "4 - "+a1, a1, fa->findTagRelation(prod) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "4 #", 0u, fa->countObjects(0,100,0,a1) );
+      fa->deleteTagRelation( prod );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "5 Exist "+a1, false, db->existsTag(a1) );
+    }
+
+    catch ( std::exception& e ) { 
+      std::cout << "Exception caught: '" << e.what() << "'" << std::endl;
+      throw;
+    }
+
+  }
+
+  //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+  void test_userAndHvsTags() 
+  {
+
+    try {
+      Record payload = dummyPayload( 10 );
+      // Folder /fA
+      // - create A1 as IOV user tag 
+      //   > using A1 as IOV head tag fails
+      // - create A1 as HVS tag (create relation) 
+      // - delete A1 as IOV tag
+      // - delete A1 as HVS tag (delete relation)
+      IFolderPtr fa = createAndFillMVFolder( "/fA" );
+      std::string prod = "PROD";
+      std::string a1 = "A1";
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 Exist "+a1, false, db->existsTag(a1) );
+      CPPUNIT_ASSERT_THROW( fa->countObjects(0,100,0,a1), TagNotFound );
+      fa->storeObject( 5, 15, payload, 0, a1 );
+      try {
+        fa->tagCurrentHead( a1 );
+        CPPUNIT_FAIL( "Using A1 as head tag should fail" );
+      } catch ( TagExists& ) {}      
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 Exist "+a1, true, db->existsTag(a1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 #", 1u, fa->countObjects(0,100,0,a1) );
+      fa->createTagRelation( prod, a1 );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 Exist "+a1, true, db->existsTag(a1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 - "+a1, a1, fa->findTagRelation(prod) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 #", 1u, fa->countObjects(0,100,0,a1) );
+      fa->deleteTag( a1 );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "4 Exist "+a1, true, db->existsTag(a1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "4 - "+a1, a1, fa->findTagRelation(prod) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "4 #", 0u, fa->countObjects(0,100,0,a1) );
+      fa->deleteTagRelation( prod );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "5 Exist "+a1, false, db->existsTag(a1) );
+    }
+
+    catch ( std::exception& e ) { 
+      std::cout << "Exception caught: '" << e.what() << "'" << std::endl;
+      throw;
+    }
+
+  }
+
+  //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+  void test_hvsAndIovTags() 
+  {
+
+    try {
+      Record payload = dummyPayload( 10 );
+      // Folder /fA
+      // - create A1 as HVS tag (create relation) 
+      // - create A1 as IOV head tag 
+      //   > using A1 as IOV user tag fails
+      // - delete A1 as HVS tag (delete relation)
+      // - delete A1 as IOV tag
+      IFolderPtr fa = createAndFillMVFolder( "/fA" );
+      std::string prod = "PROD";
+      std::string a1 = "A1";
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 Exist "+a1, false, db->existsTag(a1) );
+      fa->createTagRelation( prod, a1 );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 Exist "+a1, true, db->existsTag(a1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 - "+a1, a1, fa->findTagRelation(prod) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 #", 0u, fa->countObjects(0,100,0,a1) );
+      fa->tagCurrentHead( a1 );
+      try {
+        fa->storeObject( 5, 15, payload, 0, a1 );
+        CPPUNIT_FAIL( "Using A1 as user tag should fail" );
+      } catch ( TagExists& ) {}      
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 Exist "+a1, true, db->existsTag(a1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 #", 3u, fa->countObjects(0,100,0,a1) );
+      fa->deleteTagRelation( prod );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "4 Exist "+a1, true, db->existsTag(a1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "4 #", 3u, fa->countObjects(0,100,0,a1) );
+      try {        
+        fa->findTagRelation(prod);
+        CPPUNIT_FAIL( "Solving the PROD-A1 relation should fail" );
+      } catch ( TagNotFound& ) {}
+      fa->deleteTag( a1 );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "5 Exist "+a1, false, db->existsTag(a1) );
+      CPPUNIT_ASSERT_THROW( fa->countObjects(0,100,0,a1), TagNotFound );
+    }
+
+    catch ( std::exception& e ) { 
+      std::cout << "Exception caught: '" << e.what() << "'" << std::endl;
+      throw;
+    }
+
+  }
+
+  //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+  void test_hvsAndUserTags() 
+  {
+
+    try {
+      Record payload = dummyPayload( 10 );
+      // Folder /fA
+      // - create A1 as HVS tag (create relation) 
+      // - create A1 as IOV user tag 
+      //   > using A1 as IOV head tag fails
+      // - delete A1 as HVS tag (delete relation)
+      // - delete A1 as IOV tag
+      IFolderPtr fa = createAndFillMVFolder( "/fA" );
+      std::string prod = "PROD";
+      std::string a1 = "A1";
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 Exist "+a1, false, db->existsTag(a1) );
+      fa->createTagRelation( prod, a1 );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 Exist "+a1, true, db->existsTag(a1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 #", 0u, fa->countObjects(0,100,0,a1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 - "+a1, a1, fa->findTagRelation(prod) );
+      fa->storeObject( 5, 15, payload, 0, a1 );
+      try {
+        fa->tagCurrentHead( a1 );
+        CPPUNIT_FAIL( "Using A1 as head tag should fail" );
+      } catch ( TagExists& ) {}      
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 Exist "+a1, true, db->existsTag(a1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 #", 1u, fa->countObjects(0,100,0,a1) );
+      fa->deleteTagRelation( prod );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "4 Exist "+a1, true, db->existsTag(a1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "4 #", 1u, fa->countObjects(0,100,0,a1) );
+      try {        
+        fa->findTagRelation(prod);
+        CPPUNIT_FAIL( "Solving the PROD-A1 relation should fail" );
+      } catch ( TagNotFound& ) {}
+      fa->deleteTag( a1 );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "5 Exist "+a1, false, db->existsTag(a1) );
+      CPPUNIT_ASSERT_THROW( fa->countObjects(0,100,0,a1), TagNotFound );
+    }
+
+    catch ( std::exception& e ) { 
+      std::cout << "Exception caught: '" << e.what() << "'" << std::endl;
+      throw;
+    }
+
+  }
+
+  //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+  
+  /// Tests that the tag sequence table is created for folder sets that are
+  /// not automatically generated (control sample for bug #16257)
+  void test_createParentsFalse()
+  {
+    try {
+      bool createParents = false;
+      db->createFolderSet( "/top" );
+      IFolderPtr fa = db->createFolder
+        ( "/top/A1", payloadSpec, "desc", 
+          FolderVersioning::MULTI_VERSION, createParents );
+      Record payload = dummyPayload( 10 );
+      fa->storeObject( 5, 15, payload, 0, "user tag" );
+      fa->createTagRelation( "PROD", "user tag" );
+      CPPUNIT_ASSERT_EQUAL( std::string("user tag"), 
+                            fa->resolveTag( "PROD" ) );
+    } catch ( std::exception& e ) { 
+      std::cout << "Exception caught: '" << e.what() << "'" << std::endl;
+      throw;
+    }
+  }
+  
+  //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+  /// Tests that the tag sequence table is created also for folder sets
+  /// that are automatically generated for createParents=true (bug #16257)
+  void test_createParentsTrue()
+  {
+    try {
+      bool createParents = true;
+      IFolderPtr fa = db->createFolder
+        ( "/top/A1", payloadSpec, "desc", 
+          FolderVersioning::MULTI_VERSION, createParents );
+      Record payload = dummyPayload( 10 );
+      fa->storeObject( 5, 15, payload, 0, "user tag" );
+      fa->createTagRelation( "PROD", "user tag" );
+      CPPUNIT_ASSERT_EQUAL( std::string("user tag"), 
+                            fa->resolveTag( "PROD" ) );
+    } catch ( std::exception& e ) { 
+      std::cout << "Exception caught: '" << e.what() << "'" << std::endl;
+      throw;
+    }
+  }
+  
+  //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+  void test_svFolder() 
+  {
+
+    try {      
+      // Node hierarchy
+      // -> fldset /
+      // -> folder /mv
+      // -> folder /sv
+      IFolderPtr fmv  = createAndFillMVFolder( "/mv" );
+      IFolderPtr fsv  = createAndFillSVFolder( "/sv" );
+      std::string prod = "PROD";
+      std::string s1 = "S1";
+      std::string m1 = "M1";
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 Exist "+s1, false, db->existsTag(s1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 Exist "+m1, false, db->existsTag(m1) );
+      fmv->createTagRelation( prod, m1 );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 Exist "+s1, false, db->existsTag(s1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 Exist "+m1, true, db->existsTag(m1) );
+      try {
+        fsv->createTagRelation( prod, s1 );
+        CPPUNIT_FAIL( "Creating HVS relation for SV folder should fail" );
+      } 
+      catch ( FolderIsSingleVersion& ) {} 
+    }
+
+    catch ( std::exception& e ) { 
+      std::cout << "Exception caught: '" << e.what() << "'" << std::endl;
+      throw;
+    }    
+
+  }
+    
+  //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+  void test_listTags()
+  {
+
+    try {      
+
+      // Node hierarchy
+      // -> fldset /
+      // -> fldset /A
+      // -> folder /A/mv
+      // -> folder /A/sv
+      IFolderSetPtr sA  = db->createFolderSet( "/A" );
+      IFolderPtr fAM  = createAndFillMVFolder( "/A/mv" );
+      IFolderPtr fAS  = createAndFillSVFolder( "/A/sv" );
+      
+      // Tag hierarchy for "/A    version #1"
+      // -> fldset '/A    version #1'
+      // -> folder '/A/mv version #1'
+      std::string tA_1  = "/A    version #1";
+      std::string tAM_1 = "/A/mv version #1";
+      fAM->createTagRelation( tA_1,  tAM_1 );
+      
+      // Tag hierarchy for "/A    version #2"
+      // -> fldset '/A    version #2'
+      // -> folder '/A/mv version #2'
+      std::string tA_2  = "/A    version #2";
+      std::string tAM_2 = "/A/mv version #2";
+      fAM->createTagRelation( tA_2,  tAM_2 );
+      
+      // Tag hierarchy for "/     version PROD"
+      // -> fldset '/     version PROD'
+      // -> fldset '/A    version PROD'
+      // -> folder '/A/mv version #1'
+      std::string t_PR  = "/     version PROD";
+      std::string tA_PR = "/A    version PROD";      
+      sA->createTagRelation(  t_PR,  tA_PR );
+      fAM->createTagRelation( tA_PR, tAM_1 );
+
+      // List tags for MV folder "/A/mv"
+      std::vector<std::string> tagsAM = fAM->listTags();
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "/A/mv tag count", 2u, (unsigned int)tagsAM.size() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "/A/mv tag 1", tAM_1, tagsAM[0] );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "/A/mv tag 2", tAM_2, tagsAM[1] );
+
+      // List tags for SV folder "/A/sv"
+      std::vector<std::string> tagsAS = fAS->listTags();
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "/A/sv tag count", 0u, (unsigned int)tagsAS.size() );
+
+      // List tags for folder set "/A"
+      std::vector<std::string> tagsA = sA->listTags();
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "/A tag count", 3u, (unsigned int)tagsA.size() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "/A tag 1", tA_1, tagsA[0] );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "/A tag 2", tA_2, tagsA[1] );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "/A tag 3", tA_PR, tagsA[2] );
+ 
+      // List tags for folder set "/"
+      IFolderSetPtr sROOT  = db->getFolderSet( "/" );
+      std::vector<std::string> tagsROOT = sROOT->listTags();
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "/ tag count", 1u, (unsigned int)tagsROOT.size() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "/ tag 1", t_PR, tagsROOT[0] );    
+ 
+    }
+
+    catch ( std::exception& e ) { 
+      std::cout << "Exception caught: '" << e.what() << "'" << std::endl;
+      throw;
+    }
+    
+  }
+
+  //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+  // Test for bug #16566
+  void test_resolveLocalTag() 
+  {
+
+    try {      
+
+      IFolderPtr f = createAndFillMVFolder( "/folder" );
+      std::string folderTag = "local_tag_1";
+      std::string folderSetTag = "prod_v1";
+      f->tagCurrentHead( folderTag );
+      // COOL_1_3_1 exception: "Tag 'local_tag_1' not found in any inner node"
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "Resolve (1) " + folderTag, 
+          folderTag, f->resolveTag( folderTag ) );
+      f->createTagRelation( folderSetTag, folderTag );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "Resolve (2) " + folderTag, 
+          folderTag, f->resolveTag( folderTag ) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "Resolve " + folderSetTag, 
+          folderTag, f->resolveTag( folderSetTag ) );
+      std::vector<std::string> fTags = f->listTags();
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "/folder tag count", 1u, (unsigned int)fTags.size() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "/folder tag 1", folderTag, fTags[0] );
+      IFolderSetPtr rf = db->getFolderSet("/");
+      std::vector<std::string> rfTags = rf->listTags();      
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "/ tag count", 1u, (unsigned int)rfTags.size() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "/ tag 1", folderSetTag, rfTags[0] );
+
+    }
+
+    catch ( std::exception& e ) { 
+      std::cout << "Exception caught: '" << e.what() << "'" << std::endl;
+      throw;
+    }    
+
+  }
+    
+  //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+  void test_resolveTagFails() 
+  {
+
+    try {
+      
+      // Node hierarchy
+      // -> fldset /
+      // -> fldset /A
+      // -> folder /A/fX
+      IFolderSetPtr sA  = db->createFolderSet( "/A" );
+      IFolderPtr fAX  = createAndFillMVFolder( "/A/fX" );
+      
+      // Tag hierarchy for "/     version PROD"
+      // -> fldset '/     version PROD'
+      // -> fldset '/A    version #1'
+      std::string tA_1 = "/A    version #1";
+      std::string t_PR = "/     version PROD";
+      
+      // Create tag relations for / PROD version
+      sA->createTagRelation( t_PR, tA_1 );
+      
+      // Test that resolveTag should fail at this stage
+      try {
+        fAX->resolveTag( t_PR );
+        CPPUNIT_FAIL( "Resolve /A/fX tag for " + t_PR + " should fail" );
+      } 
+      catch ( TagRelationNotFound& ) {}
+      
+    }
+
+    catch ( std::exception& e ) { 
+      std::cout << "Exception caught: '" << e.what() << "'" << std::endl;
+      throw;
+    }
+    
+  }
+
+  //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+  // Test for bug #18201
+  void test_tagRelationExists() 
+  {
+
+    try {
+      
+      // Node hierarchy
+      // -> fldset /
+      // -> fldset /A
+      IFolderSetPtr sA  = db->createFolderSet( "/A" );
+      
+      // Tag hierarchy for "/     version PROD"
+      // -> fldset '/     version PROD'
+      // -> fldset '/A    version #1'
+      // OR fldset '/A    version #2'
+      std::string tA_1 = "/A    version #1";
+      std::string tA_2 = "/A    version #2";
+      std::string t_PR = "/     version PROD";
+      
+      // Create tag relations for / PROD version
+      sA->createTagRelation( t_PR, tA_1 );
+      
+      // Test that resolveTag should fail at this stage
+      try {
+        sA->createTagRelation( t_PR, tA_2 );
+        CPPUNIT_FAIL( "Creating tag relation between " + t_PR + " and " + tA_2 
+                      + " should fail" );
+      } 
+      catch ( TagRelationExists& ) {}      
+
+    }
+
+    catch ( std::exception& e ) { 
+      std::cout << "Exception caught: '" << e.what() << "'" << std::endl;
+      throw;
+    }
+    
+  }
+
+  //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+  void test_lockTag_fails() 
+  {
+
+    try {
+      
+      // Node hierarchy
+      // -> fldset /
+      // -> fldset /A
+      // -> folder /A/fX
+      std::string nameA = "/A";
+      std::string nameAX = "/A/fX";
+      IFolderSetPtr sA  = db->createFolderSet( nameA );
+      IFolderPtr fAX  = createAndFillMVFolder( nameAX );
+
+      // Tag hierarchy for "/A    version #1"
+      // -> fldset '/A    version #1'
+      // -> folder '/A/fX version #1'
+      std::string a1  = "/A    version #1";
+      std::string x1 = "/A/fX version #1";
+
+      // Attempt to lock tags before they are created fails
+      // (fails with private RowNotUpdated exception)
+      CPPUNIT_ASSERT_THROW
+        ( sA->setTagLockStatus( a1, HvsTagLock::LOCKED ), Exception );
+      CPPUNIT_ASSERT_THROW
+        ( fAX->setTagLockStatus( x1, HvsTagLock::LOCKED ), Exception );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "1 Exist "+a1, false, db->existsTag(a1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "1 Exist "+x1, false, db->existsTag(x1) );
+      CPPUNIT_ASSERT_THROW( sA->tagLockStatus( a1 ), TagNotFound );
+      CPPUNIT_ASSERT_THROW( fAX->tagLockStatus( x1 ), TagNotFound );
+
+      // Attempt to lock tags after they are created succeds
+      fAX->createTagRelation( a1, x1 );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "2 Exist "+a1, true, db->existsTag(a1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "2 Exist "+x1, true, db->existsTag(x1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "2 Locked "+a1, 
+          (int)HvsTagLock::UNLOCKED, (int)sA->tagLockStatus(a1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "2 Locked "+x1, 
+          (int)HvsTagLock::UNLOCKED, (int)fAX->tagLockStatus(x1) );
+      sA->setTagLockStatus( a1, HvsTagLock::LOCKED );
+      fAX->setTagLockStatus( x1, HvsTagLock::LOCKED );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "3 Exist "+a1, true, db->existsTag(a1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "3 Exist "+x1, true, db->existsTag(x1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "3 Locked "+a1, 
+          (int)HvsTagLock::LOCKED, (int)sA->tagLockStatus(a1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "3 Locked "+x1, 
+          (int)HvsTagLock::LOCKED, (int)fAX->tagLockStatus(x1) );
+
+      // Cleanup - unlock all tags
+      sA->setTagLockStatus( a1, HvsTagLock::UNLOCKED );
+      fAX->setTagLockStatus( x1, HvsTagLock::UNLOCKED );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "4 Exist "+a1, true, db->existsTag(a1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "4 Exist "+x1, true, db->existsTag(x1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "4 Locked "+a1, 
+          (int)HvsTagLock::UNLOCKED, (int)sA->tagLockStatus(a1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "4 Locked "+x1, 
+          (int)HvsTagLock::UNLOCKED, (int)fAX->tagLockStatus(x1) );
+
+      // Attempt to lock HEAD tag always fails - HEAD is always unlocked
+      std::string h1 = "HEAD";
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "5 Exist "+h1, true, db->existsTag(h1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "5 Locked "+h1, 
+          (int)HvsTagLock::UNLOCKED, (int)fAX->tagLockStatus(h1) );
+      CPPUNIT_ASSERT_THROW
+        ( fAX->setTagLockStatus( h1, HvsTagLock::LOCKED ), ReservedHeadTag );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "6 Exist "+h1, true, db->existsTag(h1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "6 Locked "+h1, 
+          (int)HvsTagLock::UNLOCKED, (int)fAX->tagLockStatus(h1) );
+
+    }
+
+    catch ( std::exception& e ) { 
+      std::cout << "Exception caught: '" << e.what() << "'" << std::endl;
+      throw;
+    }
+    
+  }
+
+  //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+  void test_tagLocked_dropNode() 
+  {
+
+    try {
+      
+      // Node hierarchy
+      // -> fldset /
+      // -> fldset /A
+      // -> folder /A/fX
+      // -> folder /A/fY
+      std::string nameA = "/A";
+      std::string nameAX = "/A/fX";
+      std::string nameAY = "/A/fY";      
+      IFolderSetPtr sA  = db->createFolderSet( nameA );
+      IFolderPtr fAX  = createAndFillMVFolder( nameAX );
+      IFolderPtr fAY  = createAndFillMVFolder( nameAY );
+
+      // Tag hierarchy for "/A    version #1"
+      // -> fldset '/A    version #1'
+      // -> folder '/A/fX version #1'
+      // -> folder '/A/fY version #1'
+      std::string tA_1  = "/A    version #1";
+      std::string tAX_1 = "/A/fX version #1";
+      std::string tAY_1 = "/A/fY version #1";
+      fAX->createTagRelation( tA_1,  tAX_1 );
+      fAY->createTagRelation( tA_1,  tAY_1 );
+      
+      // Lock a tag in /A/fY
+      fAY->setTagLockStatus( tAY_1, HvsTagLock::LOCKED );
+
+      // Attempt to drop nodes
+      db->dropNode( nameAX );
+      CPPUNIT_ASSERT_THROW( db->dropNode( nameAY ), TagIsLocked );
+      CPPUNIT_ASSERT_THROW( db->dropNode( nameA ), Exception ); // not empty
+
+      // Unlock all tags in /A/fY
+      fAY->setTagLockStatus( tAY_1, HvsTagLock::UNLOCKED );
+
+      // Lock a tag in /A
+      sA->setTagLockStatus( tA_1, HvsTagLock::LOCKED );
+
+      // Attempt to drop nodes again
+      db->dropNode( nameAY );
+      CPPUNIT_ASSERT_THROW( db->dropNode( nameA ), TagIsLocked );
+
+      // Unlock all tags in /A
+      sA->setTagLockStatus( tA_1, HvsTagLock::UNLOCKED );
+
+      // Attempt to drop nodes again
+      db->dropNode( nameA );
+
+    }
+
+    catch ( std::exception& e ) { 
+      std::cout << "Exception caught: '" << e.what() << "'" << std::endl;
+      throw;
+    }
+    
+  }
+
+  //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+  void test_tagLocked_storeObjectWithUserTag()
+  {
+
+    try {      
+
+      // Folder /fA
+      // - create A1 as child HVS tag (create relation) 
+      // - create A1 as IOV user tag 
+      //   > attempt to use A1 as IOV head tag fails
+      IFolderPtr fA = createAndFillMVFolder( "/fA" );
+      std::string prod = "PROD";
+      std::string a1 = "A1";
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 Exist "+a1, false, db->existsTag(a1) );
+      fA->createTagRelation( prod, a1 );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 Exist "+a1, true, db->existsTag(a1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 #", 0u, fA->countObjects(0,100,0,a1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 - "+a1, a1, fA->findTagRelation(prod) );
+      Record payload = dummyPayload( 10 );
+      fA->storeObject( 5, 15, payload, 0, a1 );
+      try {
+        fA->tagCurrentHead( a1 );
+        CPPUNIT_FAIL( "Using A1 as head tag should fail" );
+      } catch ( TagExists& ) {}      
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 Exist "+a1, true, db->existsTag(a1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 #", 1u, fA->countObjects(0,100,0,a1) );
+
+      // - lock A1 user tag 
+      // - delete A1 as child HVS tag (delete relation)
+      // - attempt to add another object to A1 user tag fails
+      // - attempt to delete A1 as IOV tag fails
+      fA->setTagLockStatus( a1, HvsTagLock::LOCKED );
+      fA->deleteTagRelation( prod );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "4 Exist "+a1, true, db->existsTag(a1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "4 #", 1u, fA->countObjects(0,100,0,a1) );
+      CPPUNIT_ASSERT_THROW
+        ( fA->storeObject( 15, 25, payload, 0, a1 ), TagIsLocked );
+      CPPUNIT_ASSERT_THROW
+        ( fA->deleteTag( a1 ), TagIsLocked );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "5 Exist "+a1, true, db->existsTag(a1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "5 #", 1u, fA->countObjects(0,100,0,a1) );
+
+      // - unlock A1 user tag 
+      // - attempt to add another object to A1 user tag succeeds
+      // - attempt to delete A1 as IOV tag succeeds
+      fA->setTagLockStatus( a1, HvsTagLock::UNLOCKED );
+      fA->storeObject( 15, 25, payload, 0, a1 );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "6 Exist "+a1, true, db->existsTag(a1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "6 #", 2u, fA->countObjects(0,100,0,a1) );
+      fA->deleteTag( a1 );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "7 Exist "+a1, false, db->existsTag(a1) );
+      CPPUNIT_ASSERT_THROW( fA->countObjects(0,100,0,a1), TagNotFound );
+
+    }
+
+    catch ( std::exception& e ) { 
+      std::cout << "Exception caught: '" << e.what() << "'" << std::endl;
+      throw;
+    }
+    
+  }
+
+  //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+  void test_tagLocked_tagCurrentHead()
+  {
+
+    try {      
+
+      // Node hierarchy
+      // -> fldset /
+      // -> fldset /A
+      // -> folder /A/fX
+      std::string nameA = "/A";
+      std::string nameAX = "/A/fX";
+      IFolderSetPtr sA  = db->createFolderSet( nameA );
+      IFolderPtr fAX  = createAndFillMVFolder( nameAX );
+
+      // Tag hierarchy for "/A    version #1"
+      // -> fldset '/A    version #1'
+      // -> folder '/A/fX version #1'
+      std::string a1 = "/A    version #1";
+      std::string x1 = "/A/fX version #1";
+      
+      // - create X1 as IOV head tag 
+      //   > using X1 as IOV user tag fails
+      // - create X1 as HVS tag (create relation) 
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 Exist "+x1, false, db->existsTag(x1) );
+      CPPUNIT_ASSERT_THROW( fAX->countObjects(0,100,0,x1), TagNotFound );
+      fAX->tagCurrentHead( x1 );
+      Record payload = dummyPayload( 10 );
+      try {
+        fAX->storeObject( 5, 15, payload, 0, x1 );
+        CPPUNIT_FAIL( "Using X1 as user tag should fail" );
+      } catch ( TagExists& ) {}
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 Exist "+x1, true, db->existsTag(x1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 #", 3u, fAX->countObjects(0,100,0,x1) );
+      fAX->createTagRelation( a1, x1 );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 Exist "+x1, true, db->existsTag(x1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 - "+x1, x1, fAX->findTagRelation(a1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 #", 3u, fAX->countObjects(0,100,0,x1) );
+
+      // - lock folder set A1 tag
+      // - lock folder X1 head tag 
+      // - attempt to add another object to HEAD succeeds
+      // - attempt to delete X1 as IOV tag fails
+      // - attempt to retag the current HEAD fails
+      sA->setTagLockStatus( a1, HvsTagLock::LOCKED );
+      fAX->setTagLockStatus( x1, HvsTagLock::LOCKED );
+      fAX->storeObject( 5, 15, payload, 0 );
+      CPPUNIT_ASSERT_THROW( fAX->deleteTag( x1 ), TagIsLocked );
+      CPPUNIT_ASSERT_THROW( fAX->tagCurrentHead( x1 ), TagExists );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "4 Exist "+x1, true, db->existsTag(x1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "4 - "+x1, x1, fAX->findTagRelation(a1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "4 #", 3u, fAX->countObjects(0,100,0,x1) );
+
+      // - unlock folder X1 head tag 
+      // - attempt to delete X1 as IOV tag succeeds
+      //   > tag X1 still exists as HVS tag
+      // - attempt to retag the current HEAD succeeds
+      fAX->setTagLockStatus( x1, HvsTagLock::UNLOCKED );
+      fAX->deleteTag( x1 );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "5 Exist "+x1, true, db->existsTag(x1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "5 - "+x1, x1, fAX->findTagRelation(a1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "5 #", 0u, fAX->countObjects(0,100,0,x1) );
+      fAX->tagCurrentHead( x1 );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "6 Exist "+x1, true, db->existsTag(x1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "6 - "+x1, x1, fAX->findTagRelation(a1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "6 #", 4u, fAX->countObjects(0,100,0,x1) );
+
+      // - attempt to delete A1 as folder set tag fails
+      // - unlock folder set tag A1 
+      // - attempt to delete A1 as folder set tag succeeds
+      // - attempt to delete X1 as IOV tag succeeds
+      CPPUNIT_ASSERT_THROW( fAX->deleteTagRelation( a1 ), TagIsLocked ); 
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "7 Exist "+a1, true, db->existsTag(a1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "7 Exist "+x1, true, db->existsTag(x1) );
+      sA->setTagLockStatus( a1, HvsTagLock::UNLOCKED );
+      fAX->deleteTagRelation( a1 );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "8 Exist "+a1, false, db->existsTag(a1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "8 Exist "+x1, true, db->existsTag(x1) );
+      fAX->deleteTag( x1 );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "9 Exist "+a1, false, db->existsTag(a1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "9 Exist "+x1, false, db->existsTag(x1) );
+
+    }
+
+    catch ( std::exception& e ) { 
+      std::cout << "Exception caught: '" << e.what() << "'" << std::endl;
+      throw;
+    }
+    
+  }
+
+  //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+  void test_tagLocked_tagHeadAsOfDate()
+  {
+
+    try {      
+
+      // Node hierarchy
+      // -> fldset /
+      // -> fldset /A
+      // -> folder /A/fX
+      std::string nameA = "/A";
+      std::string nameAX = "/A/fX";
+      IFolderSetPtr sA  = db->createFolderSet( nameA );
+      IFolderPtr fAX  = createAndFillMVFolder( nameAX );
+
+      // Tag hierarchy for "/A    version #1"
+      // -> fldset '/A    version #1'
+      // -> folder '/A/fX version #1'
+      std::string a1 = "/A    version #1";
+      std::string x1 = "/A/fX version #1";
+      
+      // - create X1 as IOV date tag 
+      //   > using X1 as IOV user tag fails
+      // - create X1 as HVS tag (create relation) 
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 Exist "+x1, false, db->existsTag(x1) );
+      CPPUNIT_ASSERT_THROW( fAX->countObjects(0,100,0,x1), TagNotFound );
+      Time date = fAX->findObject( 20, 0 )->insertionTime();
+      fAX->tagHeadAsOfDate( date, x1 );
+      Record payload = dummyPayload( 10 );
+      try {
+        fAX->storeObject( 5, 15, payload, 0, x1 );
+        CPPUNIT_FAIL( "Using X1 as user tag should fail" );
+      } catch ( TagExists& ) {}
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 Exist "+x1, true, db->existsTag(x1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 #", 3u, fAX->countObjects(0,100,0,x1) );
+      fAX->createTagRelation( a1, x1 );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 Exist "+x1, true, db->existsTag(x1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 - "+x1, x1, fAX->findTagRelation(a1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 #", 3u, fAX->countObjects(0,100,0,x1) );
+
+      // - lock folder set A1 tag
+      // - lock folder X1 head tag 
+      // - attempt to add another object to HEAD succeeds
+      // - attempt to delete X1 as IOV tag fails
+      // - attempt to retag at new date fails
+      sA->setTagLockStatus( a1, HvsTagLock::LOCKED );
+      fAX->setTagLockStatus( x1, HvsTagLock::LOCKED );
+      fAX->storeObject( 5, 15, payload, 0 );
+      date = fAX->findObject( 5, 0 )->insertionTime();
+      CPPUNIT_ASSERT_THROW( fAX->deleteTag( x1 ), TagIsLocked );
+      CPPUNIT_ASSERT_THROW
+        ( fAX->tagHeadAsOfDate( date, x1 ), TagExists );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "4 Exist "+x1, true, db->existsTag(x1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "4 - "+x1, x1, fAX->findTagRelation(a1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "4 #", 3u, fAX->countObjects(0,100,0,x1) );
+
+      // - unlock folder X1 head tag 
+      // - attempt to delete X1 as IOV tag succeeds
+      //   > tag X1 still exists as HVS tag
+      // - attempt to retag at new date succeeds
+      fAX->setTagLockStatus( x1, HvsTagLock::UNLOCKED );
+      fAX->deleteTag( x1 );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "5 Exist "+x1, true, db->existsTag(x1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "5 - "+x1, x1, fAX->findTagRelation(a1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "5 #", 0u, fAX->countObjects(0,100,0,x1) );
+      fAX->tagHeadAsOfDate( date, x1 );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "6 Exist "+x1, true, db->existsTag(x1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "6 - "+x1, x1, fAX->findTagRelation(a1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "6 #", 4u, fAX->countObjects(0,100,0,x1) );
+
+      // - attempt to delete A1 as folder set tag fails
+      // - unlock folder set tag A1 
+      // - attempt to delete A1 as folder set tag succeeds
+      // - attempt to delete X1 as IOV tag succeeds
+      CPPUNIT_ASSERT_THROW( fAX->deleteTagRelation( a1 ), TagIsLocked ); 
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "7 Exist "+a1, true, db->existsTag(a1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "7 Exist "+x1, true, db->existsTag(x1) );
+      sA->setTagLockStatus( a1, HvsTagLock::UNLOCKED );
+      fAX->deleteTagRelation( a1 );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "8 Exist "+a1, false, db->existsTag(a1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "8 Exist "+x1, true, db->existsTag(x1) );
+      fAX->deleteTag( x1 );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "9 Exist "+a1, false, db->existsTag(a1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "9 Exist "+x1, false, db->existsTag(x1) );
+
+    }
+
+    catch ( std::exception& e ) { 
+      std::cout << "Exception caught: '" << e.what() << "'" << std::endl;
+      throw;
+    }
+    
+  }
+
+  //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+  void test_tagLocked_deleteTag() 
+  {
+
+    try {
+      
+      // Node hierarchy
+      // -> fldset /
+      // -> fldset /A
+      // -> folder /A/fX
+      // -> folder /A/fY
+      std::string nameA = "/A";
+      std::string nameAX = "/A/fX";
+      std::string nameAY = "/A/fY";      
+      IFolderSetPtr sA  = db->createFolderSet( nameA );
+      IFolderPtr fAX  = createAndFillMVFolder( nameAX );
+      IFolderPtr fAY  = createAndFillMVFolder( nameAY );
+
+      // Tag hierarchy for "/A    version #1"
+      // -> fldset '/A    version #1'
+      // -> folder '/A/fX version #1'
+      // -> folder '/A/fY version #1'
+      std::string a1 = "/A    version #1";
+      std::string x1 = "/A/fX version #1";
+      std::string y1 = "/A/fY version #1";
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 Exist "+a1, false, db->existsTag(a1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 Exist "+x1, false, db->existsTag(x1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 Exist "+y1, false, db->existsTag(y1) );
+      CPPUNIT_ASSERT_THROW( fAX->findTagRelation(a1), TagNotFound );
+      CPPUNIT_ASSERT_THROW( fAX->countObjects(0,100,0,x1), TagNotFound );
+      CPPUNIT_ASSERT_THROW( fAY->findTagRelation(a1), TagNotFound );
+      CPPUNIT_ASSERT_THROW( fAY->countObjects(0,100,0,y1), TagNotFound );
+
+      // Create tag relations
+      fAX->createTagRelation( a1, x1 );
+      fAY->createTagRelation( a1, y1 );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 Exist "+a1, true, db->existsTag(a1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 Exist "+x1, true, db->existsTag(x1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 Exist "+y1, true, db->existsTag(y1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 - "+x1, x1, fAX->findTagRelation(a1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 #", 0u, fAX->countObjects(0,100,0,x1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 - "+y1, y1, fAY->findTagRelation(a1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 #", 0u, fAY->countObjects(0,100,0,y1) );
+      
+      // Lock a tag in /A/fY
+      fAY->setTagLockStatus( y1, HvsTagLock::LOCKED );
+
+      // Attempt to delete folder tags
+      // Note that actually these folder tags have no IOVs associated... even
+      // if deleteTag( x1 ) succceds, it actually does nothing because the
+      // relation to a1 still exists (hence do not attempt to recreate it!)
+      fAX->deleteTag( x1 ); 
+      CPPUNIT_ASSERT_THROW( fAY->deleteTag( y1 ), TagIsLocked );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 Exist "+a1, true, db->existsTag(a1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 Exist "+x1, true, db->existsTag(x1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 Exist "+y1, true, db->existsTag(y1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 - "+x1, x1, fAX->findTagRelation(a1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 #", 0u, fAX->countObjects(0,100,0,x1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 - "+y1, y1, fAY->findTagRelation(a1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 #", 0u, fAY->countObjects(0,100,0,y1) );
+
+      // Unlock all tags in /A/fY
+      fAY->setTagLockStatus( y1, HvsTagLock::UNLOCKED );
+
+      // Lock a tag in /A
+      sA->setTagLockStatus( a1, HvsTagLock::LOCKED );
+
+      // Attempt to delete folder tags again
+      fAX->deleteTag( x1 );
+      fAY->deleteTag( y1 );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "4 Exist "+a1, true, db->existsTag(a1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "4 Exist "+x1, true, db->existsTag(x1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "4 Exist "+y1, true, db->existsTag(y1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "4 - "+x1, x1, fAX->findTagRelation(a1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "4 #", 0u, fAX->countObjects(0,100,0,x1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "4 - "+y1, y1, fAY->findTagRelation(a1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "4 #", 0u, fAY->countObjects(0,100,0,y1) );
+
+      // Unlock all tags in /A
+      sA->setTagLockStatus( a1, HvsTagLock::UNLOCKED );
+
+      // Delete all tag relations
+      fAX->deleteTagRelation( a1 );
+      fAY->deleteTagRelation( a1 );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "5 Exist "+a1, false, db->existsTag(a1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "5 Exist "+x1, false, db->existsTag(x1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "5 Exist "+y1, false, db->existsTag(y1) );
+      CPPUNIT_ASSERT_THROW( fAX->findTagRelation(a1), TagNotFound );
+      CPPUNIT_ASSERT_THROW( fAX->countObjects(0,100,0,x1), TagNotFound );
+      CPPUNIT_ASSERT_THROW( fAY->findTagRelation(a1), TagNotFound );
+      CPPUNIT_ASSERT_THROW( fAY->countObjects(0,100,0,y1), TagNotFound );
+
+      // Tag current HEAD in /A/fY
+      fAY->tagCurrentHead( y1 );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "6 Exist "+a1, false, db->existsTag(a1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "6 Exist "+x1, false, db->existsTag(x1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "6 Exist "+y1, true, db->existsTag(y1) );
+      CPPUNIT_ASSERT_THROW( fAX->findTagRelation(a1), TagNotFound );
+      CPPUNIT_ASSERT_THROW( fAX->countObjects(0,100,0,x1), TagNotFound );
+      CPPUNIT_ASSERT_THROW( fAY->findTagRelation(a1), TagNotFound );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "6 #", 3u, fAY->countObjects(0,100,0,y1) );
+
+      // Lock a tag in /A/fY
+      fAY->setTagLockStatus( y1, HvsTagLock::LOCKED );
+
+      // Attempt to delete folder tags
+      // Note that actually these folder tags have no IOVs associated... even
+      // if deleteTag( x1 ) succceds, it actually does nothing because the
+      // relation to a1 still exists (hence do not attempt to recreate it!)
+      CPPUNIT_ASSERT_THROW( fAY->deleteTag( y1 ), TagIsLocked );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "7 Exist "+y1, true, db->existsTag(y1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "7 #", 3u, fAY->countObjects(0,100,0,y1) );
+
+      // Unlock all tags in /A/fY
+      fAY->setTagLockStatus( y1, HvsTagLock::UNLOCKED );
+
+      // Attempt to delete folder tags again
+      fAY->deleteTag( y1 );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "8 Exist "+y1, false, db->existsTag(y1) );
+      CPPUNIT_ASSERT_THROW( fAY->countObjects(0,100,0,y1), TagNotFound );
+
+    }
+
+    catch ( std::exception& e ) { 
+      std::cout << "Exception caught: '" << e.what() << "'" << std::endl;
+      throw;
+    }
+    
+  }
+
+  //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+  void test_tagLocked_createTagRelation() 
+  {
+
+    try {
+      
+      // Node hierarchy
+      // -> fldset /
+      // -> fldset /A
+      // -> folder /A/fX
+      // -> folder /A/fY
+      std::string nameA = "/A";
+      std::string nameAX = "/A/fX";
+      std::string nameAY = "/A/fY";      
+      IFolderSetPtr sA  = db->createFolderSet( nameA );
+      IFolderPtr fAX  = createAndFillMVFolder( nameAX );
+      IFolderPtr fAY  = createAndFillMVFolder( nameAY );
+
+      // Tag hierarchy for "/A    version #1"
+      // -> fldset '/A    version #1'
+      // -> folder '/A/fX version #1'
+      // -> folder '/A/fY version #1'
+      std::string a1 = "/A    version #1";
+      std::string x1 = "/A/fX version #1";
+      std::string y1 = "/A/fY version #1";
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 Exist "+a1, false, db->existsTag(a1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 Exist "+x1, false, db->existsTag(x1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 Exist "+y1, false, db->existsTag(y1) );
+      CPPUNIT_ASSERT_THROW( fAX->findTagRelation(a1), TagNotFound );
+      CPPUNIT_ASSERT_THROW( fAY->findTagRelation(a1), TagNotFound );
+
+      // Create tag relations
+      fAX->createTagRelation( a1, x1 );
+      fAY->createTagRelation( a1, y1 );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 Exist "+a1, true, db->existsTag(a1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 Exist "+x1, true, db->existsTag(x1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 Exist "+y1, true, db->existsTag(y1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 - "+x1, x1, fAX->findTagRelation(a1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 - "+y1, y1, fAY->findTagRelation(a1) );
+
+      // Delete tag relations
+      fAX->deleteTagRelation( a1 );
+      fAY->deleteTagRelation( a1 );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 Exist "+a1, false, db->existsTag(a1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 Exist "+x1, false, db->existsTag(x1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 Exist "+y1, false, db->existsTag(y1) );
+      CPPUNIT_ASSERT_THROW( fAX->findTagRelation(a1), TagNotFound );
+      CPPUNIT_ASSERT_THROW( fAY->findTagRelation(a1), TagNotFound );
+
+      // Lock a tag in /A/fY
+      // You must create the tag first (eg by tagCurrentHead)
+      fAY->tagCurrentHead( y1 );
+      fAY->setTagLockStatus( y1, HvsTagLock::LOCKED );
+
+      // Create tag relations
+      fAX->createTagRelation( a1, x1 );
+      fAY->createTagRelation( a1, y1 );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "4 Exist "+a1, true, db->existsTag(a1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "4 Exist "+x1, true, db->existsTag(x1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "4 Exist "+y1, true, db->existsTag(y1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "4 - "+x1, x1, fAX->findTagRelation(a1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "4 - "+y1, y1, fAY->findTagRelation(a1) );
+
+      // Delete tag relations
+      fAX->deleteTagRelation( a1 );
+      fAY->deleteTagRelation( a1 );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "5 Exist "+a1, false, db->existsTag(a1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "5 Exist "+x1, false, db->existsTag(x1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "5 Exist "+y1, true, db->existsTag(y1) );
+      CPPUNIT_ASSERT_THROW( fAX->findTagRelation(a1), TagNotFound );
+      CPPUNIT_ASSERT_THROW( fAY->findTagRelation(a1), TagNotFound );
+
+      // Attempt to delete the /A/fY tag will fail
+      CPPUNIT_ASSERT_THROW( fAY->deleteTag(y1), TagIsLocked );
+
+      // Unlock all tags in /A/fY (and delete them)
+      fAY->setTagLockStatus( y1, HvsTagLock::UNLOCKED );
+      fAY->deleteTag(y1);
+
+      // Attempt to lock a tag in /A
+      // This will fail because the tag does not exist, i.e. has no associated 
+      // child node tags (and note that it throws Exception, not TagNotFound)
+      CPPUNIT_ASSERT_THROW
+        ( sA->setTagLockStatus( a1, HvsTagLock::LOCKED ), Exception );
+
+      // Create /A/fX tag relation - this will create the /A tag
+      fAX->createTagRelation( a1, x1 );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "6 Exist "+a1, true, db->existsTag(a1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "6 Exist "+x1, true, db->existsTag(x1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "6 Exist "+y1, false, db->existsTag(y1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "6 - "+x1, x1, fAX->findTagRelation(a1) );
+      CPPUNIT_ASSERT_THROW( fAY->findTagRelation(a1), TagRelationNotFound );
+
+      // Lock a tag in /A
+      sA->setTagLockStatus( a1, HvsTagLock::LOCKED );
+
+      // Attempt to create tag relations
+      CPPUNIT_ASSERT_THROW( fAY->createTagRelation( a1, y1 ), TagIsLocked );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "7 Exist "+a1, true, db->existsTag(a1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "7 Exist "+x1, true, db->existsTag(x1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "7 Exist "+y1, false, db->existsTag(y1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "7 - "+x1, x1, fAX->findTagRelation(a1) );
+      CPPUNIT_ASSERT_THROW( fAY->findTagRelation(a1), TagRelationNotFound );
+
+      // Unlock all tags in /A
+      sA->setTagLockStatus( a1, HvsTagLock::UNLOCKED );
+
+    }
+
+    catch ( std::exception& e ) { 
+      std::cout << "Exception caught: '" << e.what() << "'" << std::endl;
+      throw;
+    }
+    
+  }
+
+  //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+  void test_tagLocked_deleteTagRelation() 
+  {
+
+    try {
+      
+      // Node hierarchy
+      // -> fldset /
+      // -> fldset /A
+      // -> folder /A/fX
+      // -> folder /A/fY
+      std::string nameA = "/A";
+      std::string nameAX = "/A/fX";
+      std::string nameAY = "/A/fY";      
+      IFolderSetPtr sA  = db->createFolderSet( nameA );
+      IFolderPtr fAX  = createAndFillMVFolder( nameAX );
+      IFolderPtr fAY  = createAndFillMVFolder( nameAY );
+
+      // Tag hierarchy for "/A    version #1"
+      // -> fldset '/A    version #1'
+      // -> folder '/A/fX version #1'
+      // -> folder '/A/fY version #1'
+      std::string a1 = "/A    version #1";
+      std::string x1 = "/A/fX version #1";
+      std::string y1 = "/A/fY version #1";
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 Exist "+a1, false, db->existsTag(a1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 Exist "+x1, false, db->existsTag(x1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 Exist "+y1, false, db->existsTag(y1) );
+      CPPUNIT_ASSERT_THROW( fAX->findTagRelation(a1), TagNotFound );
+      CPPUNIT_ASSERT_THROW( fAY->findTagRelation(a1), TagNotFound );
+
+      // Create tag relations
+      fAX->createTagRelation( a1, x1 );
+      fAY->createTagRelation( a1, y1 );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 Exist "+a1, true, db->existsTag(a1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 Exist "+x1, true, db->existsTag(x1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 Exist "+y1, true, db->existsTag(y1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 - "+x1, x1, fAX->findTagRelation(a1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 - "+y1, y1, fAY->findTagRelation(a1) );
+
+      // Lock a tag in /A/fY
+      fAY->setTagLockStatus( y1, HvsTagLock::LOCKED );
+
+      // Attempt to delete tag relations
+      // Deleting the /A/fY tag relation fails because the child tag would
+      // be deleted and is locked (it would not fail if the child tag were
+      // locked but deleteTagRelation would not lead to deleting the tag)
+      fAX->deleteTagRelation( a1 );
+      CPPUNIT_ASSERT_THROW( fAY->deleteTagRelation( a1 ), TagIsLocked );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 Exist "+a1, true, db->existsTag(a1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 Exist "+x1, false, db->existsTag(x1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 Exist "+y1, true, db->existsTag(y1) );
+      CPPUNIT_ASSERT_THROW( fAX->findTagRelation(a1), TagRelationNotFound );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 - "+y1, y1, fAY->findTagRelation(a1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 #", 0u, fAY->countObjects(0,100,0,y1) );
+
+      // Unlock all tags in /A/fY
+      fAY->setTagLockStatus( y1, HvsTagLock::UNLOCKED );
+
+      // Use tags in /A/fY for the current HEAD and lock them again
+      fAY->tagCurrentHead( y1 );
+      fAY->setTagLockStatus( y1, HvsTagLock::LOCKED );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "4 Exist "+a1, true, db->existsTag(a1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "4 Exist "+x1, false, db->existsTag(x1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "4 Exist "+y1, true, db->existsTag(y1) );
+      CPPUNIT_ASSERT_THROW( fAX->findTagRelation(a1), TagRelationNotFound );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "4 - "+y1, y1, fAY->findTagRelation(a1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "4 #", 3u, fAY->countObjects(0,100,0,y1) );
+
+      // Attempt to delete tag relations again
+      // Deleting the /A/fY tag relation does NOT fail even if the child tag is
+      // locked, because deleteTagRelation would not lead to deleting the tag
+      fAY->deleteTagRelation( a1 );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "5 Exist "+a1, false, db->existsTag(a1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "5 Exist "+x1, false, db->existsTag(x1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "5 Exist "+y1, true, db->existsTag(y1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "5 #", 3u, fAY->countObjects(0,100,0,y1) );
+      CPPUNIT_ASSERT_THROW( fAX->findTagRelation(a1), TagNotFound );
+      CPPUNIT_ASSERT_THROW( fAY->findTagRelation(a1), TagNotFound );
+
+      // Unlock all tags in /A/fY (and delete them)
+      fAY->setTagLockStatus( y1, HvsTagLock::UNLOCKED );
+      fAY->deleteTag( y1 );
+
+      // Create tag relations again
+      fAX->createTagRelation( a1, x1 );
+      fAY->createTagRelation( a1, y1 );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "6 Exist "+a1, true, db->existsTag(a1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "6 Exist "+x1, true, db->existsTag(x1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "6 Exist "+y1, true, db->existsTag(y1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "6 - "+x1, x1, fAX->findTagRelation(a1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "6 - "+y1, y1, fAY->findTagRelation(a1) );
+
+      // Lock a tag in /A
+      sA->setTagLockStatus( a1, HvsTagLock::LOCKED );
+
+      // Attempt to delete tag relations - will fail as parent tag is locked
+      CPPUNIT_ASSERT_THROW( fAX->deleteTagRelation( a1 ), TagIsLocked );
+      CPPUNIT_ASSERT_THROW( fAY->deleteTagRelation( a1 ), TagIsLocked );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "7 Exist "+a1, true, db->existsTag(a1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "7 Exist "+x1, true, db->existsTag(x1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "7 Exist "+y1, true, db->existsTag(y1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "7 - "+x1, x1, fAX->findTagRelation(a1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "7 #", 0u, fAX->countObjects(0,100,0,x1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "7 - "+y1, y1, fAY->findTagRelation(a1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "7 #", 0u, fAY->countObjects(0,100,0,y1) );
+
+      // Unlock all tags in /A
+      sA->setTagLockStatus( a1, HvsTagLock::UNLOCKED );
+
+      // Delete tag relations again
+      fAX->deleteTagRelation( a1 );
+      fAY->deleteTagRelation( a1 );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "8 Exist "+a1, false, db->existsTag(a1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "8 Exist "+x1, false, db->existsTag(x1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "8 Exist "+y1, false, db->existsTag(y1) );
+      CPPUNIT_ASSERT_THROW( fAX->findTagRelation(a1), TagNotFound );
+      CPPUNIT_ASSERT_THROW( fAX->countObjects(0,100,0,x1), TagNotFound );
+      CPPUNIT_ASSERT_THROW( fAY->findTagRelation(a1), TagNotFound );
+      CPPUNIT_ASSERT_THROW( fAY->countObjects(0,100,0,y1), TagNotFound );
+
+    }
+
+    catch ( std::exception& e ) { 
+      std::cout << "Exception caught: '" << e.what() << "'" << std::endl;
+      throw;
+    }
+    
+  }
+
+  //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+  void test_partiallyLockTag_fails() 
+  {
+
+    try {
+      
+      // Node hierarchy
+      // -> fldset /
+      // -> fldset /A
+      // -> folder /A/fX
+      std::string nameA = "/A";
+      std::string nameAX = "/A/fX";
+      IFolderSetPtr sA  = db->createFolderSet( nameA );
+      IFolderPtr fAX  = createAndFillMVFolder( nameAX );
+
+      // Tag hierarchy for "/A    version #1"
+      // -> fldset '/A    version #1'
+      // -> folder '/A/fX version #1'
+      std::string a1  = "/A    version #1";
+      std::string x1 = "/A/fX version #1";
+
+      // Attempt to lock tags before they are created fails
+      // (fails with private RowNotUpdated exception)
+      CPPUNIT_ASSERT_THROW
+        ( sA->setTagLockStatus( a1, HvsTagLock::PARTIALLYLOCKED ), Exception );
+      CPPUNIT_ASSERT_THROW
+        ( fAX->setTagLockStatus( x1, HvsTagLock::PARTIALLYLOCKED ), Exception );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "1 Exist "+a1, false, db->existsTag(a1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "1 Exist "+x1, false, db->existsTag(x1) );
+      CPPUNIT_ASSERT_THROW( sA->tagLockStatus( a1 ), TagNotFound );
+      CPPUNIT_ASSERT_THROW( fAX->tagLockStatus( x1 ), TagNotFound );
+
+      // Attempt to lock tags after they are created succeds
+      fAX->createTagRelation( a1, x1 );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "2 Exist "+a1, true, db->existsTag(a1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "2 Exist "+x1, true, db->existsTag(x1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "2 Locked "+a1, 
+          (int)HvsTagLock::UNLOCKED, (int)sA->tagLockStatus(a1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "2 Locked "+x1, 
+          (int)HvsTagLock::UNLOCKED, (int)fAX->tagLockStatus(x1) );
+      sA->setTagLockStatus( a1, HvsTagLock::PARTIALLYLOCKED );
+      fAX->setTagLockStatus( x1, HvsTagLock::PARTIALLYLOCKED );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "3 Exist "+a1, true, db->existsTag(a1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "3 Exist "+x1, true, db->existsTag(x1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "3 Locked "+a1, 
+          (int)HvsTagLock::PARTIALLYLOCKED, (int)sA->tagLockStatus(a1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "3 Locked "+x1, 
+          (int)HvsTagLock::PARTIALLYLOCKED, (int)fAX->tagLockStatus(x1) );
+
+      // Cleanup - unlock all tags
+      sA->setTagLockStatus( a1, HvsTagLock::UNLOCKED );
+      fAX->setTagLockStatus( x1, HvsTagLock::UNLOCKED );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "4 Exist "+a1, true, db->existsTag(a1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "4 Exist "+x1, true, db->existsTag(x1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "4 Locked "+a1, 
+          (int)HvsTagLock::UNLOCKED, (int)sA->tagLockStatus(a1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "4 Locked "+x1, 
+          (int)HvsTagLock::UNLOCKED, (int)fAX->tagLockStatus(x1) );
+
+      // Attempt to lock HEAD tag always fails - HEAD is always unlocked
+      std::string h1 = "HEAD";
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "5 Exist "+h1, true, db->existsTag(h1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "5 Locked "+h1, 
+          (int)HvsTagLock::UNLOCKED, (int)fAX->tagLockStatus(h1) );
+      CPPUNIT_ASSERT_THROW
+        ( fAX->setTagLockStatus( h1, HvsTagLock::PARTIALLYLOCKED ), ReservedHeadTag );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "6 Exist "+h1, true, db->existsTag(h1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "6 Locked "+h1, 
+          (int)HvsTagLock::UNLOCKED, (int)fAX->tagLockStatus(h1) );
+
+    }
+
+    catch ( std::exception& e ) { 
+      std::cout << "Exception caught: '" << e.what() << "'" << std::endl;
+      throw;
+    }
+    
+  }
+
+  //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+  void test_tagPartiallyLocked_dropNode() 
+  {
+
+    try {
+      
+      // Node hierarchy
+      // -> fldset /
+      // -> fldset /A
+      // -> folder /A/fX
+      // -> folder /A/fY
+      std::string nameA = "/A";
+      std::string nameAX = "/A/fX";
+      std::string nameAY = "/A/fY";      
+      IFolderSetPtr sA  = db->createFolderSet( nameA );
+      IFolderPtr fAX  = createAndFillMVFolder( nameAX );
+      IFolderPtr fAY  = createAndFillMVFolder( nameAY );
+
+      // Tag hierarchy for "/A    version #1"
+      // -> fldset '/A    version #1'
+      // -> folder '/A/fX version #1'
+      // -> folder '/A/fY version #1'
+      std::string tA_1  = "/A    version #1";
+      std::string tAX_1 = "/A/fX version #1";
+      std::string tAY_1 = "/A/fY version #1";
+      fAX->createTagRelation( tA_1,  tAX_1 );
+      fAY->createTagRelation( tA_1,  tAY_1 );
+      
+      // Lock a tag in /A/fY
+      fAY->setTagLockStatus( tAY_1, HvsTagLock::PARTIALLYLOCKED );
+
+      // Attempt to drop nodes
+      db->dropNode( nameAX );
+      CPPUNIT_ASSERT_THROW( db->dropNode( nameAY ), TagIsLocked );
+      CPPUNIT_ASSERT_THROW( db->dropNode( nameA ), Exception ); // not empty
+
+      // Unlock all tags in /A/fY
+      fAY->setTagLockStatus( tAY_1, HvsTagLock::UNLOCKED );
+
+      // Lock a tag in /A
+      sA->setTagLockStatus( tA_1, HvsTagLock::PARTIALLYLOCKED );
+
+      // Attempt to drop nodes again
+      db->dropNode( nameAY );
+      CPPUNIT_ASSERT_THROW( db->dropNode( nameA ), TagIsLocked );
+
+      // Unlock all tags in /A
+      sA->setTagLockStatus( tA_1, HvsTagLock::UNLOCKED );
+
+      // Attempt to drop nodes again
+      db->dropNode( nameA );
+
+    }
+
+    catch ( std::exception& e ) { 
+      std::cout << "Exception caught: '" << e.what() << "'" << std::endl;
+      throw;
+    }
+    
+  }
+
+  //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+  void test_tagPartiallyLocked_storeObjectWithUserTag()
+  {
+
+    try {      
+
+      // Folder /fA
+      // - create A1 as child HVS tag (create relation) 
+      // - create A1 as IOV user tag 
+      //   > attempt to use A1 as IOV head tag fails
+      IFolderPtr fA = createAndFillMVFolder( "/fA" );
+      std::string prod = "PROD";
+      std::string a1 = "A1";
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 Exist "+a1, false, db->existsTag(a1) );
+      fA->createTagRelation( prod, a1 );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 Exist "+a1, true, db->existsTag(a1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 #", 0u, fA->countObjects(0,100,0,a1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 - "+a1, a1, fA->findTagRelation(prod) );
+      Record payload = dummyPayload( 10 );
+      fA->storeObject( 5, 15, payload, 0, a1 );
+      try {
+        fA->tagCurrentHead( a1 );
+        CPPUNIT_FAIL( "Using A1 as head tag should fail" );
+      } catch ( TagExists& ) {}      
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 Exist "+a1, true, db->existsTag(a1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 #", 1u, fA->countObjects(0,100,0,a1) );
+
+      // - lock A1 user tag 
+      // - delete A1 as child HVS tag (delete relation)
+      // - attempt to add another object to A1 user tag fails
+      // - attempt to delete A1 as IOV tag fails
+      fA->setTagLockStatus( a1, HvsTagLock::PARTIALLYLOCKED );
+      fA->deleteTagRelation( prod );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "4 Exist "+a1, true, db->existsTag(a1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "4 #", 1u, fA->countObjects(0,100,0,a1) );
+      CPPUNIT_ASSERT_THROW
+        ( fA->storeObject( 14, 25, payload, 0, a1 ), TagIsLocked );
+      CPPUNIT_ASSERT_THROW
+        ( fA->deleteTag( a1 ), TagIsLocked );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "5 Exist "+a1, true, db->existsTag(a1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "5 #", 1u, fA->countObjects(0,100,0,a1) );
+
+      // - unlock A1 user tag 
+      // - attempt to add another object to A1 user tag succeeds
+      // - attempt to delete A1 as IOV tag succeeds
+      fA->setTagLockStatus( a1, HvsTagLock::UNLOCKED );
+      fA->storeObject( 15, 25, payload, 0, a1 );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "6 Exist "+a1, true, db->existsTag(a1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "6 #", 2u, fA->countObjects(0,100,0,a1) );
+      fA->deleteTag( a1 );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "7 Exist "+a1, false, db->existsTag(a1) );
+      CPPUNIT_ASSERT_THROW( fA->countObjects(0,100,0,a1), TagNotFound );
+
+    }
+
+    catch ( std::exception& e ) { 
+      std::cout << "Exception caught: '" << e.what() << "'" << std::endl;
+      throw;
+    }
+    
+  }
+  
+  void test_tagPartiallyLocked_storeObjectWithUserTagNoOverlap()
+  {
+
+    // Folder /fA
+    // - create A1 as child HVS tag (create relation) 
+    // - create A1 as IOV user tag 
+    std::string prod = "PROD";
+    std::string a1 = "A1";
+    IFolderPtr fA = db->createFolder
+      ( "/fA1martin", payloadSpec, "desc", FolderVersioning::MULTI_VERSION );
+      
+    try 
+    {
+
+      Record payload = dummyPayload( 510 );
+      // only store into user tag
+      fA->storeObject( 5, 10, payload, 0, a1, true );
+      //coral::MsgLevel coralLevel = coral::MessageStream::msgVerbosity();
+      //coral::MessageStream::setMsgVerbosity( coral::Verbose );
+      fA->storeObject( 7, 20, dummyPayload(720), 0, a1, true );
+      //coral::MessageStream::setMsgVerbosity( coralLevel );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 Count objects ", 2u, 
+                                    fA->countObjects(0,200,0, a1) );
+      fA->storeObject(20, 30, dummyPayload(2030), 0, a1, true );
+      // leave a hole from 30 to 40
+      fA->storeObject(40, 50, dummyPayload(4050), 0, a1, true );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 Count objects ", 4u, 
+                                    fA->countObjects(0,200,0, a1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 Exist "+a1, true, db->existsTag(a1) );
+      
+      // - partially lock A1 user tag 
+      // - attempt to add another object with overlapping IOVs 
+      //   to A1 user tag fails
+      // - attempt to add another object with no overlapping IOVs 
+      //   to A1 user tag succeeds
+      fA->setTagLockStatus( a1, HvsTagLock::PARTIALLYLOCKED );
+ 
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 Exist "+a1, true, db->existsTag(a1) );
+      
+      // IOV covering all existing IOVs fails
+      CPPUNIT_ASSERT_THROW
+        ( fA->storeObject( 0, 80, payload, 0, a1 ), TagIsLocked );
+      
+      // since is one before the hole -> failure
+      CPPUNIT_ASSERT_THROW
+        ( fA->storeObject( 29, 35, payload, 0, a1 ), TagIsLocked );
+      // until one after the hole -> failure
+      CPPUNIT_ASSERT_THROW
+        ( fA->storeObject( 30, 41, payload, 0, a1 ), TagIsLocked );
+      // inside one IOV -> failure
+      CPPUNIT_ASSERT_THROW
+        ( fA->storeObject( 15, 18, payload, 0, a1 ), TagIsLocked );
+      CPPUNIT_ASSERT_THROW
+        ( fA->storeObject( 7, 15, payload, 0, a1 ), TagIsLocked );
+      
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "2 Count objects ", 4u, fA->countObjects(0,200,0, a1) );
+      
+      // no overlap succeeds
+      // into the hole
+      fA->storeObject(30, 40, payload, 0, a1, true);
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "3 Count objects ", 5u, fA->countObjects(0,200,0, a1) );
+      // at the end
+      fA->storeObject(50, 60, dummyPayload(5060), 0, a1, true );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "4 Count objects ", 6u, fA->countObjects(0,200,0, a1) );
+      // at the beginning
+      fA->storeObject( 0, 5, payload, 0, a1, true );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "5 Count objects ", 7u, fA->countObjects(0,200,0, a1) );
+      
+      // storing into head succeeds
+      fA->storeObject( 0, 40, dummyPayload(2), 0);
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "6 Count objects ", 1u, fA->countObjects(0,200,0) );
+ 
+      // store into user tag and head with overlaping head
+      fA->storeObject(65, 75, payload, 0);
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ("7 Count objects ", 2u, fA->countObjects(0, 200, 0));
+      fA->storeObject(60, 70, dummyPayload(3141), 0, a1, false);
+
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ("8 Count objects ", 8u, fA->countObjects(0, 200, 0, a1));
+      
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ("9 Count objects ", 3u, fA->countObjects(0, 200, 0));
+
+      // the same IOVs again fail now
+      CPPUNIT_ASSERT_THROW
+        ( fA->storeObject( 30, 40, payload, 0, a1 ), TagIsLocked );
+      CPPUNIT_ASSERT_THROW
+        ( fA->storeObject( 50, 60, payload, 0, a1 ), TagIsLocked );
+      CPPUNIT_ASSERT_THROW
+        ( fA->storeObject(  0, 5, payload, 0, a1 ), TagIsLocked );
+      
+      CPPUNIT_ASSERT_THROW( fA->deleteTag( a1 ), TagIsLocked );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "5 Exist "+a1, true, db->existsTag(a1) );
+      
+      // test bulk storage
+      fA->setupStorageBuffer( true );
+      
+      // overlap of objects to store
+      fA->storeObject(90, 120, payload, 0, a1 );
+      fA->storeObject(110, 130, payload, 0, a1 );
+      fA->storeObject( 80, 90, payload, 0, a1 );
+
+      CPPUNIT_ASSERT_THROW( fA->flushStorageBuffer(), TagIsLocked);     
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "9 Count objects ", 8u, fA->countObjects(0,200,0, a1) );
+      
+      // no overlap of objects to store
+      fA->storeObject(90, 120, payload, 0, a1 );
+      fA->storeObject(120, 130, payload, 0, a1 );
+      fA->storeObject( 80, 90, payload, 0, a1 );
+
+      fA->flushStorageBuffer();     
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "10 Count objects ", 11u, fA->countObjects(0,200,0, a1) );   
+      
+      fA->setupStorageBuffer( false );
+      
+      // unlock tag
+      fA->setTagLockStatus( a1, HvsTagLock::UNLOCKED );
+      
+      // storing is again possible
+      fA->storeObject( 0, 80, payload, 0, a1 );
+      fA->storeObject( 10, 11, payload, 0, a1 );
+      fA->storeObject( 15, 18, payload, 0, a1 );
+      fA->storeObject( 15, 25, payload, 0, a1 );
+      
+      fA->deleteTag( a1 );
+
+    }
+
+    catch ( std::exception& e ) { 
+      std::cout << "Exception caught: '" << e.what() << "'" << std::endl;
+      fA->setTagLockStatus( a1, HvsTagLock::UNLOCKED );
+      throw;
+    }
+    
+  }
+
+  //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+  void test_tagPartiallyLocked_tagCurrentHead()
+  {
+
+    try {      
+
+      // Node hierarchy
+      // -> fldset /
+      // -> fldset /A
+      // -> folder /A/fX
+      std::string nameA = "/A";
+      std::string nameAX = "/A/fX";
+      IFolderSetPtr sA  = db->createFolderSet( nameA );
+      IFolderPtr fAX  = createAndFillMVFolder( nameAX );
+
+      // Tag hierarchy for "/A    version #1"
+      // -> fldset '/A    version #1'
+      // -> folder '/A/fX version #1'
+      std::string a1 = "/A    version #1";
+      std::string x1 = "/A/fX version #1";
+      
+      // - create X1 as IOV head tag 
+      //   > using X1 as IOV user tag fails
+      // - create X1 as HVS tag (create relation) 
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 Exist "+x1, false, db->existsTag(x1) );
+      CPPUNIT_ASSERT_THROW( fAX->countObjects(0,100,0,x1), TagNotFound );
+      fAX->tagCurrentHead( x1 );
+      Record payload = dummyPayload( 10 );
+      try {
+        fAX->storeObject( 5, 15, payload, 0, x1 );
+        CPPUNIT_FAIL( "Using X1 as user tag should fail" );
+      } catch ( TagExists& ) {}
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 Exist "+x1, true, db->existsTag(x1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 #", 3u, fAX->countObjects(0,100,0,x1) );
+      fAX->createTagRelation( a1, x1 );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 Exist "+x1, true, db->existsTag(x1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 - "+x1, x1, fAX->findTagRelation(a1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 #", 3u, fAX->countObjects(0,100,0,x1) );
+
+      // - lock folder set A1 tag
+      // - lock folder X1 head tag 
+      // - attempt to add another object to HEAD succeeds
+      // - attempt to delete X1 as IOV tag fails
+      // - attempt to retag the current HEAD fails
+      sA->setTagLockStatus( a1, HvsTagLock::PARTIALLYLOCKED );
+      fAX->setTagLockStatus( x1, HvsTagLock::PARTIALLYLOCKED );
+      fAX->storeObject( 5, 15, payload, 0 );
+      CPPUNIT_ASSERT_THROW( fAX->deleteTag( x1 ), TagIsLocked );
+      CPPUNIT_ASSERT_THROW( fAX->tagCurrentHead( x1 ), TagExists );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "4 Exist "+x1, true, db->existsTag(x1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "4 - "+x1, x1, fAX->findTagRelation(a1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "4 #", 3u, fAX->countObjects(0,100,0,x1) );
+
+      // - unlock folder X1 head tag 
+      // - attempt to delete X1 as IOV tag succeeds
+      //   > tag X1 still exists as HVS tag
+      // - attempt to retag the current HEAD succeeds
+      fAX->setTagLockStatus( x1, HvsTagLock::UNLOCKED );
+      fAX->deleteTag( x1 );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "5 Exist "+x1, true, db->existsTag(x1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "5 - "+x1, x1, fAX->findTagRelation(a1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "5 #", 0u, fAX->countObjects(0,100,0,x1) );
+      fAX->tagCurrentHead( x1 );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "6 Exist "+x1, true, db->existsTag(x1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "6 - "+x1, x1, fAX->findTagRelation(a1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "6 #", 4u, fAX->countObjects(0,100,0,x1) );
+
+      // - attempt to delete A1 as folder set tag fails
+      // - unlock folder set tag A1 
+      // - attempt to delete A1 as folder set tag succeeds
+      // - attempt to delete X1 as IOV tag succeeds
+      CPPUNIT_ASSERT_THROW( fAX->deleteTagRelation( a1 ), TagIsLocked ); 
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "7 Exist "+a1, true, db->existsTag(a1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "7 Exist "+x1, true, db->existsTag(x1) );
+      sA->setTagLockStatus( a1, HvsTagLock::UNLOCKED );
+      fAX->deleteTagRelation( a1 );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "8 Exist "+a1, false, db->existsTag(a1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "8 Exist "+x1, true, db->existsTag(x1) );
+      fAX->deleteTag( x1 );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "9 Exist "+a1, false, db->existsTag(a1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "9 Exist "+x1, false, db->existsTag(x1) );
+
+    }
+
+    catch ( std::exception& e ) { 
+      std::cout << "Exception caught: '" << e.what() << "'" << std::endl;
+      throw;
+    }
+    
+  }
+
+  //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+  void test_tagPartiallyLocked_tagHeadAsOfDate()
+  {
+
+    try {      
+
+      // Node hierarchy
+      // -> fldset /
+      // -> fldset /A
+      // -> folder /A/fX
+      std::string nameA = "/A";
+      std::string nameAX = "/A/fX";
+      IFolderSetPtr sA  = db->createFolderSet( nameA );
+      IFolderPtr fAX  = createAndFillMVFolder( nameAX );
+
+      // Tag hierarchy for "/A    version #1"
+      // -> fldset '/A    version #1'
+      // -> folder '/A/fX version #1'
+      std::string a1 = "/A    version #1";
+      std::string x1 = "/A/fX version #1";
+      
+      // - create X1 as IOV date tag 
+      //   > using X1 as IOV user tag fails
+      // - create X1 as HVS tag (create relation) 
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 Exist "+x1, false, db->existsTag(x1) );
+      CPPUNIT_ASSERT_THROW( fAX->countObjects(0,100,0,x1), TagNotFound );
+      Time date = fAX->findObject( 20, 0 )->insertionTime();
+      fAX->tagHeadAsOfDate( date, x1 );
+      Record payload = dummyPayload( 10 );
+      try {
+        fAX->storeObject( 5, 15, payload, 0, x1 );
+        CPPUNIT_FAIL( "Using X1 as user tag should fail" );
+      } catch ( TagExists& ) {}
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 Exist "+x1, true, db->existsTag(x1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 #", 3u, fAX->countObjects(0,100,0,x1) );
+      fAX->createTagRelation( a1, x1 );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 Exist "+x1, true, db->existsTag(x1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 - "+x1, x1, fAX->findTagRelation(a1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 #", 3u, fAX->countObjects(0,100,0,x1) );
+
+      // - lock folder set A1 tag
+      // - lock folder X1 head tag 
+      // - attempt to add another object to HEAD succeeds
+      // - attempt to delete X1 as IOV tag fails
+      // - attempt to retag at new date fails
+      sA->setTagLockStatus( a1, HvsTagLock::PARTIALLYLOCKED );
+      fAX->setTagLockStatus( x1, HvsTagLock::PARTIALLYLOCKED );
+      fAX->storeObject( 5, 15, payload, 0 );
+      date = fAX->findObject( 5, 0 )->insertionTime();
+      CPPUNIT_ASSERT_THROW( fAX->deleteTag( x1 ), TagIsLocked );
+      CPPUNIT_ASSERT_THROW
+        ( fAX->tagHeadAsOfDate( date, x1 ), TagExists );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "4 Exist "+x1, true, db->existsTag(x1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "4 - "+x1, x1, fAX->findTagRelation(a1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "4 #", 3u, fAX->countObjects(0,100,0,x1) );
+
+      // - unlock folder X1 head tag 
+      // - attempt to delete X1 as IOV tag succeeds
+      //   > tag X1 still exists as HVS tag
+      // - attempt to retag at new date succeeds
+      fAX->setTagLockStatus( x1, HvsTagLock::UNLOCKED );
+      fAX->deleteTag( x1 );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "5 Exist "+x1, true, db->existsTag(x1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "5 - "+x1, x1, fAX->findTagRelation(a1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "5 #", 0u, fAX->countObjects(0,100,0,x1) );
+      fAX->tagHeadAsOfDate( date, x1 );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "6 Exist "+x1, true, db->existsTag(x1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "6 - "+x1, x1, fAX->findTagRelation(a1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "6 #", 4u, fAX->countObjects(0,100,0,x1) );
+
+      // - attempt to delete A1 as folder set tag fails
+      // - unlock folder set tag A1 
+      // - attempt to delete A1 as folder set tag succeeds
+      // - attempt to delete X1 as IOV tag succeeds
+      CPPUNIT_ASSERT_THROW( fAX->deleteTagRelation( a1 ), TagIsLocked ); 
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "7 Exist "+a1, true, db->existsTag(a1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "7 Exist "+x1, true, db->existsTag(x1) );
+      sA->setTagLockStatus( a1, HvsTagLock::UNLOCKED );
+      fAX->deleteTagRelation( a1 );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "8 Exist "+a1, false, db->existsTag(a1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "8 Exist "+x1, true, db->existsTag(x1) );
+      fAX->deleteTag( x1 );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "9 Exist "+a1, false, db->existsTag(a1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "9 Exist "+x1, false, db->existsTag(x1) );
+
+    }
+
+    catch ( std::exception& e ) { 
+      std::cout << "Exception caught: '" << e.what() << "'" << std::endl;
+      throw;
+    }
+    
+  }
+
+  //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+  void test_tagPartiallyLocked_deleteTag() 
+  {
+
+    try {
+      
+      // Node hierarchy
+      // -> fldset /
+      // -> fldset /A
+      // -> folder /A/fX
+      // -> folder /A/fY
+      std::string nameA = "/A";
+      std::string nameAX = "/A/fX";
+      std::string nameAY = "/A/fY";      
+      IFolderSetPtr sA  = db->createFolderSet( nameA );
+      IFolderPtr fAX  = createAndFillMVFolder( nameAX );
+      IFolderPtr fAY  = createAndFillMVFolder( nameAY );
+
+      // Tag hierarchy for "/A    version #1"
+      // -> fldset '/A    version #1'
+      // -> folder '/A/fX version #1'
+      // -> folder '/A/fY version #1'
+      std::string a1 = "/A    version #1";
+      std::string x1 = "/A/fX version #1";
+      std::string y1 = "/A/fY version #1";
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 Exist "+a1, false, db->existsTag(a1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 Exist "+x1, false, db->existsTag(x1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 Exist "+y1, false, db->existsTag(y1) );
+      CPPUNIT_ASSERT_THROW( fAX->findTagRelation(a1), TagNotFound );
+      CPPUNIT_ASSERT_THROW( fAX->countObjects(0,100,0,x1), TagNotFound );
+      CPPUNIT_ASSERT_THROW( fAY->findTagRelation(a1), TagNotFound );
+      CPPUNIT_ASSERT_THROW( fAY->countObjects(0,100,0,y1), TagNotFound );
+
+      // Create tag relations
+      fAX->createTagRelation( a1, x1 );
+      fAY->createTagRelation( a1, y1 );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 Exist "+a1, true, db->existsTag(a1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 Exist "+x1, true, db->existsTag(x1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 Exist "+y1, true, db->existsTag(y1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 - "+x1, x1, fAX->findTagRelation(a1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 #", 0u, fAX->countObjects(0,100,0,x1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 - "+y1, y1, fAY->findTagRelation(a1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 #", 0u, fAY->countObjects(0,100,0,y1) );
+      
+      // Lock a tag in /A/fY
+      fAY->setTagLockStatus( y1, HvsTagLock::PARTIALLYLOCKED );
+
+      // Attempt to delete folder tags
+      // Note that actually these folder tags have no IOVs associated... even
+      // if deleteTag( x1 ) succceds, it actually does nothing because the
+      // relation to a1 still exists (hence do not attempt to recreate it!)
+      fAX->deleteTag( x1 ); 
+      CPPUNIT_ASSERT_THROW( fAY->deleteTag( y1 ), TagIsLocked );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 Exist "+a1, true, db->existsTag(a1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 Exist "+x1, true, db->existsTag(x1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 Exist "+y1, true, db->existsTag(y1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 - "+x1, x1, fAX->findTagRelation(a1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 #", 0u, fAX->countObjects(0,100,0,x1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 - "+y1, y1, fAY->findTagRelation(a1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 #", 0u, fAY->countObjects(0,100,0,y1) );
+
+      // Unlock all tags in /A/fY
+      fAY->setTagLockStatus( y1, HvsTagLock::UNLOCKED );
+
+      // Lock a tag in /A
+      sA->setTagLockStatus( a1, HvsTagLock::PARTIALLYLOCKED );
+
+      // Attempt to delete folder tags again
+      fAX->deleteTag( x1 );
+      fAY->deleteTag( y1 );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "4 Exist "+a1, true, db->existsTag(a1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "4 Exist "+x1, true, db->existsTag(x1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "4 Exist "+y1, true, db->existsTag(y1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "4 - "+x1, x1, fAX->findTagRelation(a1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "4 #", 0u, fAX->countObjects(0,100,0,x1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "4 - "+y1, y1, fAY->findTagRelation(a1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "4 #", 0u, fAY->countObjects(0,100,0,y1) );
+
+      // Unlock all tags in /A
+      sA->setTagLockStatus( a1, HvsTagLock::UNLOCKED );
+
+      // Delete all tag relations
+      fAX->deleteTagRelation( a1 );
+      fAY->deleteTagRelation( a1 );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "5 Exist "+a1, false, db->existsTag(a1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "5 Exist "+x1, false, db->existsTag(x1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "5 Exist "+y1, false, db->existsTag(y1) );
+      CPPUNIT_ASSERT_THROW( fAX->findTagRelation(a1), TagNotFound );
+      CPPUNIT_ASSERT_THROW( fAX->countObjects(0,100,0,x1), TagNotFound );
+      CPPUNIT_ASSERT_THROW( fAY->findTagRelation(a1), TagNotFound );
+      CPPUNIT_ASSERT_THROW( fAY->countObjects(0,100,0,y1), TagNotFound );
+
+      // Tag current HEAD in /A/fY
+      fAY->tagCurrentHead( y1 );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "6 Exist "+a1, false, db->existsTag(a1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "6 Exist "+x1, false, db->existsTag(x1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "6 Exist "+y1, true, db->existsTag(y1) );
+      CPPUNIT_ASSERT_THROW( fAX->findTagRelation(a1), TagNotFound );
+      CPPUNIT_ASSERT_THROW( fAX->countObjects(0,100,0,x1), TagNotFound );
+      CPPUNIT_ASSERT_THROW( fAY->findTagRelation(a1), TagNotFound );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "6 #", 3u, fAY->countObjects(0,100,0,y1) );
+
+      // Lock a tag in /A/fY
+      fAY->setTagLockStatus( y1, HvsTagLock::PARTIALLYLOCKED );
+
+      // Attempt to delete folder tags
+      // Note that actually these folder tags have no IOVs associated... even
+      // if deleteTag( x1 ) succceds, it actually does nothing because the
+      // relation to a1 still exists (hence do not attempt to recreate it!)
+      CPPUNIT_ASSERT_THROW( fAY->deleteTag( y1 ), TagIsLocked );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "7 Exist "+y1, true, db->existsTag(y1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "7 #", 3u, fAY->countObjects(0,100,0,y1) );
+
+      // Unlock all tags in /A/fY
+      fAY->setTagLockStatus( y1, HvsTagLock::UNLOCKED );
+
+      // Attempt to delete folder tags again
+      fAY->deleteTag( y1 );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "8 Exist "+y1, false, db->existsTag(y1) );
+      CPPUNIT_ASSERT_THROW( fAY->countObjects(0,100,0,y1), TagNotFound );
+
+    }
+
+    catch ( std::exception& e ) { 
+      std::cout << "Exception caught: '" << e.what() << "'" << std::endl;
+      throw;
+    }
+    
+  }
+
+  //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+  void test_tagPartiallyLocked_createTagRelation() 
+  {
+
+    try {
+      
+      // Node hierarchy
+      // -> fldset /
+      // -> fldset /A
+      // -> folder /A/fX
+      // -> folder /A/fY
+      std::string nameA = "/A";
+      std::string nameAX = "/A/fX";
+      std::string nameAY = "/A/fY";      
+      IFolderSetPtr sA  = db->createFolderSet( nameA );
+      IFolderPtr fAX  = createAndFillMVFolder( nameAX );
+      IFolderPtr fAY  = createAndFillMVFolder( nameAY );
+
+      // Tag hierarchy for "/A    version #1"
+      // -> fldset '/A    version #1'
+      // -> folder '/A/fX version #1'
+      // -> folder '/A/fY version #1'
+      std::string a1 = "/A    version #1";
+      std::string x1 = "/A/fX version #1";
+      std::string y1 = "/A/fY version #1";
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 Exist "+a1, false, db->existsTag(a1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 Exist "+x1, false, db->existsTag(x1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 Exist "+y1, false, db->existsTag(y1) );
+      CPPUNIT_ASSERT_THROW( fAX->findTagRelation(a1), TagNotFound );
+      CPPUNIT_ASSERT_THROW( fAY->findTagRelation(a1), TagNotFound );
+
+      // Create tag relations
+      fAX->createTagRelation( a1, x1 );
+      fAY->createTagRelation( a1, y1 );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 Exist "+a1, true, db->existsTag(a1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 Exist "+x1, true, db->existsTag(x1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 Exist "+y1, true, db->existsTag(y1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 - "+x1, x1, fAX->findTagRelation(a1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 - "+y1, y1, fAY->findTagRelation(a1) );
+
+      // Delete tag relations
+      fAX->deleteTagRelation( a1 );
+      fAY->deleteTagRelation( a1 );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 Exist "+a1, false, db->existsTag(a1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 Exist "+x1, false, db->existsTag(x1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 Exist "+y1, false, db->existsTag(y1) );
+      CPPUNIT_ASSERT_THROW( fAX->findTagRelation(a1), TagNotFound );
+      CPPUNIT_ASSERT_THROW( fAY->findTagRelation(a1), TagNotFound );
+
+      // Lock a tag in /A/fY
+      // You must create the tag first (eg by tagCurrentHead)
+      fAY->tagCurrentHead( y1 );
+      fAY->setTagLockStatus( y1, HvsTagLock::PARTIALLYLOCKED );
+
+      // Create tag relations
+      fAX->createTagRelation( a1, x1 );
+      fAY->createTagRelation( a1, y1 );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "4 Exist "+a1, true, db->existsTag(a1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "4 Exist "+x1, true, db->existsTag(x1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "4 Exist "+y1, true, db->existsTag(y1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "4 - "+x1, x1, fAX->findTagRelation(a1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "4 - "+y1, y1, fAY->findTagRelation(a1) );
+
+      // Delete tag relations
+      fAX->deleteTagRelation( a1 );
+      fAY->deleteTagRelation( a1 );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "5 Exist "+a1, false, db->existsTag(a1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "5 Exist "+x1, false, db->existsTag(x1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "5 Exist "+y1, true, db->existsTag(y1) );
+      CPPUNIT_ASSERT_THROW( fAX->findTagRelation(a1), TagNotFound );
+      CPPUNIT_ASSERT_THROW( fAY->findTagRelation(a1), TagNotFound );
+
+      // Attempt to delete the /A/fY tag will fail
+      CPPUNIT_ASSERT_THROW( fAY->deleteTag(y1), TagIsLocked );
+
+      // Unlock all tags in /A/fY (and delete them)
+      fAY->setTagLockStatus( y1, HvsTagLock::UNLOCKED );
+      fAY->deleteTag(y1);
+
+      // Attempt to lock a tag in /A
+      // This will fail because the tag does not exist, i.e. has no associated 
+      // child node tags (and note that it throws Exception, not TagNotFound)
+      CPPUNIT_ASSERT_THROW
+        ( sA->setTagLockStatus( a1, HvsTagLock::PARTIALLYLOCKED ), Exception );
+
+      // Create /A/fX tag relation - this will create the /A tag
+      fAX->createTagRelation( a1, x1 );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "6 Exist "+a1, true, db->existsTag(a1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "6 Exist "+x1, true, db->existsTag(x1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "6 Exist "+y1, false, db->existsTag(y1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "6 - "+x1, x1, fAX->findTagRelation(a1) );
+      CPPUNIT_ASSERT_THROW( fAY->findTagRelation(a1), TagRelationNotFound );
+
+      // Lock a tag in /A
+      sA->setTagLockStatus( a1, HvsTagLock::PARTIALLYLOCKED );
+
+      // Create tag relations
+      // Here LOCKED and PARTIALLYLOCKED behave differently!
+      fAY->createTagRelation( a1, y1 );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "7 Exist "+a1, true, db->existsTag(a1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "7 Exist "+x1, true, db->existsTag(x1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "7 Exist "+y1, true, db->existsTag(y1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "7 - "+x1, x1, fAX->findTagRelation(a1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "7 - "+y1, y1, fAY->findTagRelation(a1) );
+
+      // Unlock all tags in /A
+      sA->setTagLockStatus( a1, HvsTagLock::UNLOCKED );
+
+    }
+
+    catch ( std::exception& e ) { 
+      std::cout << "Exception caught: '" << e.what() << "'" << std::endl;
+      throw;
+    }
+    
+  }
+
+  //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+  void test_tagPartiallyLocked_deleteTagRelation() 
+  {
+
+    try {
+      
+      // Node hierarchy
+      // -> fldset /
+      // -> fldset /A
+      // -> folder /A/fX
+      // -> folder /A/fY
+      std::string nameA = "/A";
+      std::string nameAX = "/A/fX";
+      std::string nameAY = "/A/fY";      
+      IFolderSetPtr sA  = db->createFolderSet( nameA );
+      IFolderPtr fAX  = createAndFillMVFolder( nameAX );
+      IFolderPtr fAY  = createAndFillMVFolder( nameAY );
+
+      // Tag hierarchy for "/A    version #1"
+      // -> fldset '/A    version #1'
+      // -> folder '/A/fX version #1'
+      // -> folder '/A/fY version #1'
+      std::string a1 = "/A    version #1";
+      std::string x1 = "/A/fX version #1";
+      std::string y1 = "/A/fY version #1";
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 Exist "+a1, false, db->existsTag(a1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 Exist "+x1, false, db->existsTag(x1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 Exist "+y1, false, db->existsTag(y1) );
+      CPPUNIT_ASSERT_THROW( fAX->findTagRelation(a1), TagNotFound );
+      CPPUNIT_ASSERT_THROW( fAY->findTagRelation(a1), TagNotFound );
+
+      // Create tag relations
+      fAX->createTagRelation( a1, x1 );
+      fAY->createTagRelation( a1, y1 );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 Exist "+a1, true, db->existsTag(a1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 Exist "+x1, true, db->existsTag(x1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 Exist "+y1, true, db->existsTag(y1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 - "+x1, x1, fAX->findTagRelation(a1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 - "+y1, y1, fAY->findTagRelation(a1) );
+
+      // Lock a tag in /A/fY
+      fAY->setTagLockStatus( y1, HvsTagLock::PARTIALLYLOCKED );
+
+      // Attempt to delete tag relations
+      // Deleting the /A/fY tag relation fails because the child tag would
+      // be deleted and is locked (it would not fail if the child tag were
+      // locked but deleteTagRelation would not lead to deleting the tag)
+      fAX->deleteTagRelation( a1 );
+      CPPUNIT_ASSERT_THROW( fAY->deleteTagRelation( a1 ), TagIsLocked );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 Exist "+a1, true, db->existsTag(a1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 Exist "+x1, false, db->existsTag(x1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 Exist "+y1, true, db->existsTag(y1) );
+      CPPUNIT_ASSERT_THROW( fAX->findTagRelation(a1), TagRelationNotFound );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 - "+y1, y1, fAY->findTagRelation(a1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 #", 0u, fAY->countObjects(0,100,0,y1) );
+
+      // Unlock all tags in /A/fY
+      fAY->setTagLockStatus( y1, HvsTagLock::UNLOCKED );
+
+      // Use tags in /A/fY for the current HEAD and lock them again
+      fAY->tagCurrentHead( y1 );
+      fAY->setTagLockStatus( y1, HvsTagLock::PARTIALLYLOCKED );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "4 Exist "+a1, true, db->existsTag(a1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "4 Exist "+x1, false, db->existsTag(x1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "4 Exist "+y1, true, db->existsTag(y1) );
+      CPPUNIT_ASSERT_THROW( fAX->findTagRelation(a1), TagRelationNotFound );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "4 - "+y1, y1, fAY->findTagRelation(a1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "4 #", 3u, fAY->countObjects(0,100,0,y1) );
+
+      // Attempt to delete tag relations again
+      // Deleting the /A/fY tag relation does NOT fail even if the child tag is
+      // locked, because deleteTagRelation would not lead to deleting the tag
+      fAY->deleteTagRelation( a1 );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "5 Exist "+a1, false, db->existsTag(a1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "5 Exist "+x1, false, db->existsTag(x1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "5 Exist "+y1, true, db->existsTag(y1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "5 #", 3u, fAY->countObjects(0,100,0,y1) );
+      CPPUNIT_ASSERT_THROW( fAX->findTagRelation(a1), TagNotFound );
+      CPPUNIT_ASSERT_THROW( fAY->findTagRelation(a1), TagNotFound );
+
+      // Unlock all tags in /A/fY (and delete them)
+      fAY->setTagLockStatus( y1, HvsTagLock::UNLOCKED );
+      fAY->deleteTag( y1 );
+
+      // Create tag relations again
+      fAX->createTagRelation( a1, x1 );
+      fAY->createTagRelation( a1, y1 );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "6 Exist "+a1, true, db->existsTag(a1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "6 Exist "+x1, true, db->existsTag(x1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "6 Exist "+y1, true, db->existsTag(y1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "6 - "+x1, x1, fAX->findTagRelation(a1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "6 - "+y1, y1, fAY->findTagRelation(a1) );
+
+      // Lock a tag in /A
+      sA->setTagLockStatus( a1, HvsTagLock::PARTIALLYLOCKED );
+
+      // Attempt to delete tag relations - will fail as parent tag is locked
+      CPPUNIT_ASSERT_THROW( fAX->deleteTagRelation( a1 ), TagIsLocked );
+      CPPUNIT_ASSERT_THROW( fAY->deleteTagRelation( a1 ), TagIsLocked );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "7 Exist "+a1, true, db->existsTag(a1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "7 Exist "+x1, true, db->existsTag(x1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "7 Exist "+y1, true, db->existsTag(y1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "7 - "+x1, x1, fAX->findTagRelation(a1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "7 #", 0u, fAX->countObjects(0,100,0,x1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "7 - "+y1, y1, fAY->findTagRelation(a1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "7 #", 0u, fAY->countObjects(0,100,0,y1) );
+
+      // Unlock all tags in /A
+      sA->setTagLockStatus( a1, HvsTagLock::UNLOCKED );
+
+      // Delete tag relations again
+      fAX->deleteTagRelation( a1 );
+      fAY->deleteTagRelation( a1 );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "8 Exist "+a1, false, db->existsTag(a1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "8 Exist "+x1, false, db->existsTag(x1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "8 Exist "+y1, false, db->existsTag(y1) );
+      CPPUNIT_ASSERT_THROW( fAX->findTagRelation(a1), TagNotFound );
+      CPPUNIT_ASSERT_THROW( fAX->countObjects(0,100,0,x1), TagNotFound );
+      CPPUNIT_ASSERT_THROW( fAY->findTagRelation(a1), TagNotFound );
+      CPPUNIT_ASSERT_THROW( fAY->countObjects(0,100,0,y1), TagNotFound );
+
+    }
+
+    catch ( std::exception& e ) { 
+      std::cout << "Exception caught: '" << e.what() << "'" << std::endl;
+      throw;
+    }
+    
+  }
+
+  //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+  // Tests for the issues discussed in bug #22951
+  void test_emptyTag() 
+  {
+
+    try {
+      
+      // Node hierarchy
+      // -> fldset /
+      // -> fldset /A
+      // -> folder /A/fX
+      // -> folder /A/fY
+      std::string nameA = "/A";
+      std::string nameAX = "/A/fX";
+      std::string nameAY = "/A/fY";
+      IFolderSetPtr sA = db->createFolderSet( nameA );
+      IFolderPtr fAX = db->createFolder
+        ( nameAX, payloadSpec, "desc", FolderVersioning::MULTI_VERSION );
+      IFolderPtr fAY = createAndFillMVFolder( nameAY );
+
+      // Tag hierarchy for "/A    version #1"
+      // -> fldset '/A    version #1'
+      // -> folder '/A/fX version #1'
+      // -> folder '/A/fY version #1'
+      std::string a1 = "/A    version #1";
+      std::string x1 = "/A/fX version #1";
+      std::string y1 = "/A/fY version #1";
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 Exist "+a1, false, db->existsTag(a1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 Exist "+x1, false, db->existsTag(x1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 Exist "+y1, false, db->existsTag(y1) );
+      CPPUNIT_ASSERT_THROW( fAX->findTagRelation(a1), TagNotFound );
+      CPPUNIT_ASSERT_THROW( fAX->countObjects(0,100,0,x1), TagNotFound );
+      CPPUNIT_ASSERT_THROW( fAY->findTagRelation(a1), TagNotFound );
+      CPPUNIT_ASSERT_THROW( fAY->countObjects(0,100,0,y1), TagNotFound );
+
+      // Attempt to tag current HEAD of /A/fX (with 0 objects) fails
+      CPPUNIT_ASSERT_THROW( fAX->tagCurrentHead(x1), Exception );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 Exist "+a1, false, db->existsTag(a1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 Exist "+x1, false, db->existsTag(x1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 Exist "+y1, false, db->existsTag(y1) );
+      CPPUNIT_ASSERT_THROW( fAX->findTagRelation(a1), TagNotFound );
+      CPPUNIT_ASSERT_THROW( fAX->countObjects(0,100,0,x1), TagNotFound );
+      CPPUNIT_ASSERT_THROW( fAY->findTagRelation(a1), TagNotFound );
+      CPPUNIT_ASSERT_THROW( fAY->countObjects(0,100,0,y1), TagNotFound );
+
+      // Create a tag relation between /A and /A/fY
+      fAY->createTagRelation( a1, y1 );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 Exist "+a1, true, db->existsTag(a1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 Exist "+x1, false, db->existsTag(x1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 Exist "+y1, true, db->existsTag(y1) );
+      CPPUNIT_ASSERT_THROW( fAX->findTagRelation(a1), TagRelationNotFound );
+      CPPUNIT_ASSERT_THROW( fAX->countObjects(0,100,0,x1), TagNotFound );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 - "+y1, y1, fAY->findTagRelation(a1) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 #", 0u, fAY->countObjects(0,100,0,y1) );
+
+    }
+
+    catch ( std::exception& e ) { 
+      std::cout << "Exception caught: '" << e.what() << "'" << std::endl;
+      throw;
+    }
+    
+  }
+
+  //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+  IFolderPtr createAndFillMVFolder( const std::string& folderName ) 
+  {
+    IFolderPtr folder = db->createFolder
+      ( folderName, payloadSpec, "desc", FolderVersioning::MULTI_VERSION );
+    for ( int i = 0; i < 3; ++i ) {
+      ValidityKey since = i*10;
+      ValidityKey until = ValidityKeyMax;
+      Record payload = dummyPayload( i );
+      folder->storeObject( since, until, payload, 0 );
+    }
+    return folder;
+  }  
+
+  IFolderPtr createAndFillSVFolder( const std::string& folderName ) 
+  {
+    IFolderPtr folder = db->createFolder
+      ( folderName, payloadSpec, "desc", FolderVersioning::SINGLE_VERSION );
+    for ( int i = 0; i < 3; ++i ) {
+      ValidityKey since = i*10;
+      ValidityKey until = ValidityKeyMax;
+      Record payload = dummyPayload( i );
+      folder->storeObject( since, until, payload, 0 );
+    }
+    return folder;
+  }  
+
+  Record dummyPayload( int index ) 
+  {
+    Record payload( payloadSpec );
+    payload["I"].setValue<Int32>( index );
+    std::stringstream s;
+    s << "Object " << index;
+    payload["S"].setValue<String255>( s.str() );
+    payload["X"].setValue<Float>( (float)(index/1000.) );
+    return payload;
+  }
+
+  HvsTagTest()
+    : payloadSpec() 
+  {  
+    payloadSpec.extend("I",StorageType::Int32);
+    payloadSpec.extend("S",StorageType::String255);
+    payloadSpec.extend("X",StorageType::Float);
+    if ( getenv( COOLTESTDB ) ) {
+      connectString = getenv( COOLTESTDB );
+    } else {
+      std::cout 
+        << "Please provide a connect string by "
+        << "specifying one in the environment variable COOLTESTDB, e.g." 
+        << std::endl;
+      std::cout 
+        << "setenv COOLTESTDB "
+        << "\"oracle://devdb10;schema=lcg_cool;dbname=COOLTEST\"" << std::endl;
+      std::cout << "Aborting test" << std::endl;
+      exit(-1);
+    }
+  }
+  
+  ~HvsTagTest() {}
+
+  void setUp() 
+  {
+    try 
+    {
+      CoralApplication app;
+      IDatabaseSvc& dbSvc = app.databaseService();
+      dbSvc.dropDatabase( connectString );
+      db = dbSvc.createDatabase( connectString );
+    } 
+    catch ( std::exception& e ) 
+    {
+      std::cout << e.what() << std::endl;
+      throw;
+    }
+  }
+
+  void tearDown() 
+  {
+    db.reset();
+  }
+
+};
+
+CPPUNIT_TEST_SUITE_REGISTRATION( cool::HvsTagTest );
+
+//-----------------------------------------------------------------------------
+
+// Include CppUnit test driver
+#include <CppUnit_testdriver.icpp>
+
diff --git a/RelationalCool/tests/Int64IO/Int64InputOutput.cpp b/RelationalCool/tests/Int64IO/Int64InputOutput.cpp
new file mode 100755
index 000000000..a143612f4
--- /dev/null
+++ b/RelationalCool/tests/Int64IO/Int64InputOutput.cpp
@@ -0,0 +1,275 @@
+// PORT -- temporarily disabled: not part of our official test suite
+int main() { return 0; }
+#ifdef NOPORT
+
+#include <iostream>
+#include <stdexcept>
+#include <memory>
+#include "RelationalAccess/RelationalException.h"
+#include "RelationalAccess/IRelationalService.h"
+#include "RelationalAccess/IRelationalDomain.h"
+#include "RelationalAccess/IRelationalSession.h"
+#include "RelationalAccess/IRelationalTransaction.h"
+#include "RelationalAccess/IRelationalSchema.h"
+#include "RelationalAccess/IRelationalTable.h"
+#include "RelationalAccess/IRelationalQuery.h"
+#include "RelationalAccess/IRelationalCursor.h"
+#include "RelationalAccess/RelationalEditableTableDescription.h"
+#include "RelationalAccess/IRelationalTableDataEditor.h"
+#include "RelationalAccess/IRelationalTypeConverter.h"
+#include "AttributeList/AttributeList.h"
+#include "POOLCore/POOLContext.h"
+#include "SealKernel/Context.h"
+#include "SealBase/IntBits.h"
+// Max and Min in SealBase/IntTraits.h are broken on Win32
+//#include "SealBase/IntTraits.h"
+#include "CoolKernel/types.h"
+#include "src/sleep.h"
+
+static const int nbits = 63;
+
+int main( int, char** )
+{
+  try {
+    pool::POOLContext::loadComponent( "SEAL/Services/MessageService" );
+    pool::POOLContext::loadComponent( "POOL/Services/XMLAuthenticationService" );
+    pool::POOLContext::loadComponent( "POOL/Services/RelationalService" );
+    pool::POOLContext::setMessageVerbosityLevel( seal::Msg::Debug );
+    seal::MessageStream log( pool::POOLContext::context(), "TableDataEditor_Test" );
+    seal::IHandle<pool::IRelationalService> serviceHandle = pool::POOLContext::context()->query<pool::IRelationalService>( "POOL/Services/RelationalService" );
+    if ( ! serviceHandle ) {
+      throw std::runtime_error( "Could not retrieve the relational service" );
+    }
+
+    std::string connectionString = "oracle://devdb10/lcg_cool";
+    pool::IRelationalDomain& domain = serviceHandle->domainForConnection( connectionString );
+
+    // Creating a session
+    std::auto_ptr< pool::IRelationalSession > session( domain.newSession( connectionString ) );
+
+    // Establish a connection with the server
+    std::cout << "Connecting..." << std::endl;
+    if ( ! session->connect() ) {
+      throw std::runtime_error( "Could not connect to the database server." );
+    }
+
+    // Start a transaction
+    std::cout << "Starting a new transaction" << std::endl;
+    if ( ! session->transaction().start() ) {
+      throw std::runtime_error( "Could not start a new transaction." );
+    }
+
+    // Dropping the old table
+    session->userSchema().dropIfExistsTable( "DATATABLE64" );
+
+    // Creating the description for the table
+    std::auto_ptr< pool::IRelationalEditableTableDescription > description( new pool::RelationalAccess::RelationalEditableTableDescription( log,
+                                                                                                                                            domain.flavorName() ) );
+    std::cout << "Defining a column of type " << pool::AttributeStaticTypeInfo<int>::type_name() << std::endl;
+    description->insertColumn( "ID", pool::AttributeStaticTypeInfo<int>::type_name() );
+    std::cout << "Defining a column of type " << pool::AttributeStaticTypeInfo<seal::IntBits<64>::ULeast>::type_name() << std::endl;
+    description->insertColumn( "U64", pool::AttributeStaticTypeInfo<seal::IntBits<64>::ULeast>::type_name() );
+    description->insertColumn( "S64", pool::AttributeStaticTypeInfo<seal::IntBits<64>::SLeast>::type_name() );
+
+    /*
+    // CHANGE THE RAL DEFAULT TO TRY TO AVOID THE SEGMENTATION FAULT
+    // But it is not enough...
+    if ( ! session->typeConverter().setSqlTypeForCppType
+         ( "NUMBER(20)", "unsigned long long" ) )
+      throw std::runtime_error( "Could not change the u long long SQL type" );
+    if ( ! session->typeConverter().setSqlTypeForCppType
+         ( "NUMBER(20)", "long long" ) )
+      throw std::runtime_error( "Could not change the long long SQL type" );
+    */
+
+    // Create the first table.
+    std::cout << "Creating table \"DATATABLE64\"" << std::endl;
+    pool::IRelationalTable& table = session->userSchema().createTable( "DATATABLE64", *description );
+
+    std::cout << "About to insert new rows" << std::endl;
+
+    // Costructing a row buffer.
+    pool::AttributeListSpecification specForData;
+    specForData.push_back< int >( "ID" );
+    specForData.push_back< seal::IntBits<64>::ULeast >( "U64" );
+    specForData.push_back< seal::IntBits<64>::SLeast >( "S64" );
+
+    pool::AttributeList data( specForData );
+
+    // Retrieving the editor object.
+    pool::IRelationalTableDataEditor& dataEditor = table.dataEditor();
+
+    // Adding new rows
+    std::cout << "Adding five rows into the table" << std::endl;
+    data["ID"].setValue<int>( 1 );
+    data["U64"].setValue<seal::IntBits<64>::ULeast>( 10 );
+    data["S64"].setValue<seal::IntBits<64>::SLeast>
+      ( cool::sInt64Min + 1 ); // OK!
+    //( seal::sInt64Min ); // OCI-22053
+    std::cout << "Adding row: ";
+    data.print( std::cout );
+    std::cout << std::endl;
+
+    if ( ! dataEditor.insertNewRow( data ) ) {
+      throw std::runtime_error( "Could not insert a new row into the table." );
+    }
+
+    data["ID"].setValue<int>( 2 );
+    seal::IntBits<64>::ULeast udata = 1;
+    udata <<= nbits;
+    data["U64"].setValue<seal::IntBits<64>::ULeast>( udata );
+    data["S64"].setValue<seal::IntBits<64>::SLeast>
+      ( cool::sInt64Max );
+
+    std::cout << "Adding row: ";
+    data.print( std::cout );
+    std::cout << std::endl;
+
+    if ( ! dataEditor.insertNewRow( data ) ) {
+      throw std::runtime_error( "Could not insert a new row into the table." );
+    }
+
+    // Committing the transaction
+    std::cout << "Committing..." << std::endl;
+    if ( ! session->transaction().commit() ) {
+      throw std::runtime_error( "Could not commit the transaction." );
+    }
+    
+    // Disconnecting
+    std::cout << "Disconnecting..." << std::endl;
+    session->disconnect();
+
+    cool::sleep(1);
+
+    // Performing a query...
+    // Establish a connection with the server
+    std::cout << "Re-connecting..." << std::endl;
+    if ( ! session->connect() ) {
+      throw std::runtime_error( "Could not connect to the database server." );
+    }
+
+    // Start a transaction
+    std::cout << "Starting a read-only transaction" << std::endl;
+    if ( ! session->transaction().start( true ) ) {
+      throw std::runtime_error( "Could not start a new transaction." );
+    }
+
+    std::auto_ptr<pool::IRelationalQuery> query( session->userSchema().tableHandle( "DATATABLE64" ).createQuery() );
+    query->addToOutputList( "ID" );
+    query->addToOutputList( "U64" );
+    query->addToOutputList( "S64" );
+    query->addToOrderList( "ID" );
+    query->defineOutput( specForData );
+    pool::IRelationalCursor& cursor = query->process();
+    if ( ! cursor.start() ) throw std::runtime_error( "Could not start the iteration over the result set" );
+    int numberOfRows = 0;
+    while ( cursor.next() ) {
+      std::cout << "Read back : ";
+      cursor.currentRow().print( std::cout );
+      std::cout << std::endl;
+
+      pool::AttributeList::const_iterator iData = cursor.currentRow().begin();
+
+      int id = 0;
+      iData->getValue<int>( id );
+      if ( id != numberOfRows + 1 ) throw std::runtime_error( "Unexpected data for id" );
+
+      ++iData;
+      seal::IntBits<64>::ULeast udata = 0;
+      iData->getValue<seal::IntBits<64>::ULeast>( udata );
+
+      seal::IntBits<64>::ULeast refdata = 1;
+      if ( id == 1 ) refdata = 10;
+      else refdata <<= nbits;
+      if ( udata != refdata ) throw std::runtime_error( "Unexpected data for u64" );
+
+      numberOfRows++;
+    }
+    if ( numberOfRows != 2 ) throw std::runtime_error( "Number of rows received different than those expected" );
+
+
+    // Committing the transaction
+    std::cout << "Committing..." << std::endl;
+    if ( ! session->transaction().commit() ) {
+      throw std::runtime_error( "Could not commit the transaction." );
+    }
+  
+    // AV - START - March 2005 - test the numeric values
+    // Update the data
+    std::cout << "Starting a read-write transaction" << std::endl;
+    if ( ! session->transaction().start( false ) ) {
+      throw std::runtime_error( "Could not start a new transaction." );
+    }
+    pool::AttributeListSpecification dummySpec;
+    pool::AttributeList dummyList( dummySpec );    
+    std::cout << "Update both rows: set U64 = U64 - 1" << std::endl;
+    long updatedRows = session->userSchema().tableHandle( "DATATABLE64" )
+      .dataEditor().updateRows( "U64=U64-1", "", dummyList );
+    std::cout << "Updated " << updatedRows << " rows" << std::endl;
+    std::cout << "Committing..." << std::endl;
+    if ( ! session->transaction().commit() ) {
+      throw std::runtime_error( "Could not commit the transaction." );
+    }
+    
+    // Read back updated data
+    std::cout << "Starting a read-only transaction" << std::endl;
+    if ( ! session->transaction().start( true ) ) {
+      throw std::runtime_error( "Could not start a new transaction." );
+    }
+    std::auto_ptr<pool::IRelationalQuery> query1( session->userSchema().tableHandle( "DATATABLE64" ).createQuery() );
+    query1->addToOutputList( "ID" );
+    query1->addToOutputList( "U64" );
+    query1->addToOutputList( "S64" );
+    query1->addToOrderList( "ID" );
+    query1->defineOutput( specForData );
+    pool::IRelationalCursor& cursor1 = query1->process();
+    if ( ! cursor1.start() ) throw std::runtime_error( "Could not start the iteration over the result set" );
+    int numberOfRows1 = 0;
+    while ( cursor1.next() ) {
+      std::cout << "Read back : ";
+      cursor1.currentRow().print( std::cout );
+      std::cout << std::endl;
+      pool::AttributeList::const_iterator iData = cursor1.currentRow().begin();
+      int id = 0;
+      iData->getValue<int>( id );
+      if ( id != numberOfRows1 + 1 ) throw std::runtime_error( "Unexpected data for id" );
+      ++iData;
+      seal::IntBits<64>::ULeast udata = 0;
+      iData->getValue<seal::IntBits<64>::ULeast>( udata );
+      seal::IntBits<64>::ULeast refdata = 1;
+      if ( id == 1 ) refdata = 9;
+      else { refdata <<= nbits; refdata--; }
+      if ( udata != refdata ) throw std::runtime_error( "Unexpected data for u64" );
+      numberOfRows1++;
+    }
+    if ( numberOfRows1 != 2 ) throw std::runtime_error( "Number of rows received different than those expected" );
+    std::cout << "Committing..." << std::endl;
+    if ( ! session->transaction().commit() ) {
+      throw std::runtime_error( "Could not commit the transaction." );
+    }
+    // AV -  END  - March 2005
+
+    // Disconnecting
+    std::cout << "Disconnecting..." << std::endl;
+    session->disconnect();
+
+
+    std::cout << "Exiting..." << std::endl;
+  }
+  catch ( pool::RelationalException& re ) {
+    std::cerr << "Relational exception from module " << re.flavorName() << std::endl
+              << "    " << re.what() << std::endl;
+    return 1;
+  }
+  catch ( std::exception& e ) {
+    std::cerr << "Standard C++ exception : " << e.what() << std::endl;
+    return 1;
+  }
+  catch ( ... ) {
+    std::cerr << "Exception caught (...)" << std::endl;
+    return 1;
+  }
+  return 0;
+}
+
+#endif // NOPORT
diff --git a/RelationalCool/tests/Int64IO/Int64InputOutput.txt b/RelationalCool/tests/Int64IO/Int64InputOutput.txt
new file mode 100644
index 000000000..49069d0b2
--- /dev/null
+++ b/RelationalCool/tests/Int64IO/Int64InputOutput.txt
@@ -0,0 +1,43 @@
+POOL/Services/RelationalService     Info Found plugin for RDBMS technology "mysql" with implementation "odbc"
+POOL/Services/RelationalService     Info Found plugin for RDBMS technology "oracle" with native implementation
+POOL/Services/RelationalService     Info Found plugin for RDBMS technology "sqlite" with native implementation
+POOL/Services/RelationalService     Info Default implementation for RDBMS technology "mysql" is "odbc"
+POOL/Services/RelationalService     Info Default implementation for RDBMS technology "oracle" is native
+POOL/Services/RelationalService     Info Default implementation for RDBMS technology "sqlite" is native
+Connecting...
+POOL/RelationalPlugins/oracle     Info Connected to a server running Oracle version 9.2.0.6.0
+Starting a new transaction
+POOL/RelationalPlugins/oracle    Debug Prepared statement : "SELECT TABLE_NAME FROM ALL_TABLES WHERE OWNER = 'CONDDB_TEST'"
+POOL/RelationalPlugins/oracle    Debug Prepared statement : "DROP TABLE "CONDDB_TEST"."DATATABLE64""
+Defining a column of type int
+Defining a column of type unsigned long long
+Creating table "DATATABLE64"
+POOL/RelationalPlugins/oracle    Debug Prepared statement : "CREATE TABLE "CONDDB_TEST"."DATATABLE64" ( "ID" NUMBER(10), "U64" NUMBER, "S64" NUMBER )"
+About to insert new rows
+Adding five rows into the table
+Adding row: attribute list: size = 3 [ 1 as ID:int, 10 as U64:unsigned long long, -9223372036854775807 as S64:long long ]
+POOL/RelationalPlugins/oracle    Debug Prepared statement : "INSERT INTO "CONDDB_TEST"."DATATABLE64" ("ID","U64","S64") VALUES (:"ID",:"U64",:"S64")"
+Adding row: attribute list: size = 3 [ 2 as ID:int, 9223372036854775808 as U64:unsigned long long, 9223372036854775807 as S64:long long ]
+POOL/RelationalPlugins/oracle    Debug Prepared statement : "INSERT INTO "CONDDB_TEST"."DATATABLE64" ("ID","U64","S64") VALUES (:"ID",:"U64",:"S64")"
+Committing...
+Disconnecting...
+Re-connecting...
+POOL/RelationalPlugins/oracle     Info Connected to a server running Oracle version 9.2.0.6.0
+Starting a read-only transaction
+POOL/RelationalPlugins/oracle    Debug Prepared statement : "SELECT TABLE_NAME FROM ALL_TABLES WHERE OWNER = 'CONDDB_TEST'"
+POOL/RelationalPlugins/oracle    Debug Prepared statement : "SELECT "ID", "U64", "S64" FROM "CONDDB_TEST"."DATATABLE64" ORDER BY "ID""
+Read back : attribute list: size = 3 [ 1 as ID:int, 10 as U64:unsigned long long, -9223372036854775807 as S64:long long ]
+Read back : attribute list: size = 3 [ 2 as ID:int, 9223372036854775808 as U64:unsigned long long, 9223372036854775807 as S64:long long ]
+Committing...
+Starting a read-write transaction
+Update both rows: set U64 = U64 - 1
+POOL/RelationalPlugins/oracle    Debug Prepared statement : "UPDATE "CONDDB_TEST"."DATATABLE64" SET "U64"="U64"-1"
+Updated 2 rows
+Committing...
+Starting a read-only transaction
+POOL/RelationalPlugins/oracle    Debug Prepared statement : "SELECT "ID", "U64", "S64" FROM "CONDDB_TEST"."DATATABLE64" ORDER BY "ID""
+Read back : attribute list: size = 3 [ 1 as ID:int, 9 as U64:unsigned long long, -9223372036854775807 as S64:long long ]
+Read back : attribute list: size = 3 [ 2 as ID:int, 9223372036854775807 as U64:unsigned long long, 9223372036854775807 as S64:long long ]
+Committing...
+Disconnecting...
+Exiting...
diff --git a/RelationalCool/tests/MemoryConsumption/execTest.sh b/RelationalCool/tests/MemoryConsumption/execTest.sh
new file mode 100755
index 000000000..898343c22
--- /dev/null
+++ b/RelationalCool/tests/MemoryConsumption/execTest.sh
@@ -0,0 +1,25 @@
+#!/bin/sh
+
+test=unitTest_RelationalCool_MemoryConsumption
+# call $test without arguments to get the tests
+tests=`$test`
+outdir=/tmp/$USER
+outfile=$outdir/COOLTEST.db
+mkdir -p $outdir
+export COOLTESTDB="sqlite://none;schema=$outfile;dbname=COOLTEST"
+
+echo `date`
+echo Connection: $COOLTESTDB
+\rm -f $outfile
+
+export POOL_OUTMSG_LEVEL="E"
+
+\rm -f $test.out.$SCRAM_ARCH
+
+for t in $tests; do
+    # Run the tests inside the unit test suite in isolation and append
+    # the results to the output file.
+    # We run the tests in isolation, because otherwise not all memory
+    # leaks are visible.
+    $test $t | tee -a $test.out.$SCRAM_ARCH 2>&1
+done
diff --git a/RelationalCool/tests/MemoryConsumption/test_MemoryConsumption.cpp b/RelationalCool/tests/MemoryConsumption/test_MemoryConsumption.cpp
new file mode 100755
index 000000000..001b95991
--- /dev/null
+++ b/RelationalCool/tests/MemoryConsumption/test_MemoryConsumption.cpp
@@ -0,0 +1,729 @@
+// PORT -- temporarily disabled: not part of our official test suite
+int main() { return 0; }
+#ifdef NOPORT
+
+/**
+
+@file test_MemoryConsumption.cpp
+
+@author Sven A. Schmidt
+
+@date 2005-09-15
+
+*/
+
+
+#include<cppunit/extensions/HelperMacros.h>
+#include <cppunit/TestSuite.h> 
+
+#include "CoolKernel/IFolder.h"
+#include "CoolKernel/IObject.h"
+#include "CoolKernel/IObjectIterator.h"
+#include "CoolKernel/IDatabaseSvc.h"
+#include "CoolKernel/Exception.h"
+#include "CoolKernel/ChannelSelection.h"
+
+#include "SealUtil/SealTimer.h"
+#include "SealUtil/TimingItem.h"
+
+// we need some of the private header for the low level tests
+#include "src/CoralApplication.h"
+#include "src/RalDatabase.h"
+#include "src/RelationalTransaction.h"
+#include "src/RelationalFolder.h"
+#include "src/ProcMemory.h"
+#include "src/RelationalObjectTable.h"
+#include "src/TimingReport.h"
+#include "src/RalObjectTable.h"
+
+#include "RelationalAccess/IRelationalTable.h"
+#include "RelationalAccess/IRelationalQuery.h"
+#include "RelationalAccess/IRelationalCursor.h"
+#include "RelationalAccess/IRelationalSchema.h"
+
+#include "AttributeList/AttributeValueAccessor.h"
+using pool::AttributeList;
+using pool::AttributeListSpecification;
+typedef boost::shared_ptr<AttributeListSpecification> SpecPtr;
+
+#include <string>
+using std::cout;
+using std::endl;
+using std::string;
+using std::stringstream;
+
+#include <vector>
+using std::vector;
+
+namespace cool {
+
+const char* COOLTESTDB = "COOLTESTDB";
+
+/// MemoryConsumption test class
+///
+/// NB: To get reliable results, run these tests in isolation!
+/// A memory leak will most likely not be visible if the leak
+/// does not increase the total memory requirement of the process
+/// beyond what the process has already requested (especially if
+/// there's already been a leak in a previous test and the process
+/// can't even free that memory).
+///
+class MemoryConsumptionTest : public CppUnit::TestFixture {
+  
+  CPPUNIT_TEST_SUITE( MemoryConsumptionTest );
+
+  CPPUNIT_TEST( test_seal_TimingItem );
+  
+  CPPUNIT_TEST( test_AttributeListSpecification );
+  CPPUNIT_TEST( test_AttributeList );
+
+  CPPUNIT_TEST( test_storeObject_bulk );
+  CPPUNIT_TEST( test_browseObjects );
+  
+  CPPUNIT_TEST( test_fetchRowsSV );
+  CPPUNIT_TEST( test_fetchRowsSV_detail );
+  
+  CPPUNIT_TEST( test_RelationalObjectTableRow );
+  CPPUNIT_TEST( test_RelationalObjectTableRow_vector );
+
+   CPPUNIT_TEST_SUITE_END();
+		
+public:
+    
+  AttributeListSpecification mixedPayloadSpec;
+  string connectString;
+  IDatabasePtr db;
+  
+  //------------------------------------------------------------------------
+  
+  void test_seal_TimingItem() {
+    ProcMemory mem;
+    std::cout << "\nStart test_seal_TimingItem "; 
+    mem.printVm();
+    
+    int nObjs = 10 * 1000;
+    
+    for ( int i = 0; i < nObjs; ++i ) {
+      cool::TimingReport timeReport;
+      seal::TimingItem& timeItem = timeReport.item("timeReport item"); 
+      
+      if ( i % 1000 == 0 ) {
+        cout << "object # " << i << "\t";
+        mem.printVm();
+      }
+      
+      // silence the comiler...
+      timeItem.accumulate();
+    }
+    
+    std::cout << "End ";
+    mem.printVm();
+  }
+  
+  //------------------------------------------------------------------------
+  
+  /// Tests memory consumption of a vector of RelationalObjectTableRow objects
+  void test_RelationalObjectTableRow_vector() {
+    
+    ProcMemory mem;
+    std::cout << "\nStart test_RelationalObjectTableRow_vector "; 
+    mem.printVm();
+    
+    RalDatabase* ralDb = dynamic_cast<RalDatabase*>(db.get());
+    
+    boost::shared_ptr<pool::AttributeListSpecification> 
+      spec = ralDb->attrListSpecToAttrListSpecPtr( mixedPayloadSpec );
+    pool::AttributeList payload = mixedPayload( 0 );
+    
+    
+    int nObjs = 10 * 1000;
+    
+    for ( int i = 0; i < nObjs; ++i ) {
+      vector<RelationalObjectTableRow> rows;
+      for ( int j = 0; j < 10; ++j ) {
+        RelationalObjectTableRow row( payload, spec );
+        rows.push_back( row );
+      }
+      
+      if ( i % 1000 == 0 ) {
+        cout << "object # " << i << "\t";
+        mem.printVm();
+      }
+    }
+    
+    std::cout << "End ";
+    mem.printVm();
+  }    
+  
+  //------------------------------------------------------------------------
+  
+  /// Tests memory consumption of RelationalObjectTableRow objects
+  void test_RelationalObjectTableRow() {
+    
+    ProcMemory mem;
+    std::cout << "\nStart test_RelationalObjectTableRow "; 
+    mem.printVm();
+    
+    RalDatabase* ralDb = dynamic_cast<RalDatabase*>(db.get());
+    
+    boost::shared_ptr<pool::AttributeListSpecification> 
+      spec = ralDb->attrListSpecToAttrListSpecPtr( mixedPayloadSpec );
+    pool::AttributeList payload = mixedPayload( 0 );
+
+    
+    int nObjs = 100 * 1000;
+    
+    for ( int i = 0; i < nObjs; ++i ) {
+      RelationalObjectTableRow row( payload, spec );
+
+      if ( i % 10000 == 0 ) {
+        cout << "object # " << i << "\t";
+        mem.printVm();
+      }
+    }
+    
+    std::cout << "End ";
+    mem.printVm();
+  }    
+  
+  //------------------------------------------------------------------------
+ 
+  //----------------------------------------------------------------------
+  // The following is a (trimmed to essentials) copy of 
+  // RalObjectTable::fetchRowsSV
+  //----------------------------------------------------------------------
+  
+  vector<RelationalObjectTableRow>
+    fetch( const std::string& objectTableName,
+           const pool::AttributeListSpecification& payloadSpec,
+           const ValidityKey& since,
+           const ValidityKey& until,
+           const ChannelSelection& channels ) {
+
+      RalDatabase* ralDb = dynamic_cast<RalDatabase*>(db.get());
+
+      // Prepare the result vector
+      std::vector<RelationalObjectTableRow> rset;
+      {
+      
+      // Create a query on the IOV table
+      pool::IRelationalTable& objectTable = 
+      ralDb->session().userSchema().tableHandle( objectTableName );
+      std::auto_ptr<pool::IRelationalQuery> query( objectTable.createQuery() );
+      
+      // Add all table columns to the output list and define the output format
+      boost::shared_ptr<pool::AttributeListSpecification> objectTableSpec =
+      RelationalObjectTable::tableSpecification( payloadSpec );  
+      pool::AttributeListSpecification::const_iterator iColumn;
+      for ( iColumn = objectTableSpec->begin(); 
+            iColumn != objectTableSpec->end(); 
+            iColumn++ ) {
+        query->addToOutputList( iColumn->name() );
+      }
+      query->defineOutput( *objectTableSpec );  
+      
+      // Define the WHERE clause for the selection using bind variables
+      pool::AttributeListSpecification whereSpec;
+      // Only specify a channel selection if *not* all channels are selected
+      if ( ! channels.allChannels() ) {
+        if ( channels.firstChannel() == channels.lastChannel() ) {
+          whereSpec.push_back( "channel", 
+                               RelationalObjectTable::columnTypes::channelId() );
+        } else {
+          whereSpec.push_back( "firstChannel", 
+                               RelationalObjectTable::columnTypes::channelId() );
+          whereSpec.push_back( "lastChannel", 
+                               RelationalObjectTable::columnTypes::channelId() );
+        }
+      }
+      whereSpec.push_back( "since1", 
+                           RelationalObjectTable::columnTypes::iovSince() );
+      whereSpec.push_back( "since2", 
+                           RelationalObjectTable::columnTypes::iovSince() );
+      whereSpec.push_back( "since3", 
+                           RelationalObjectTable::columnTypes::iovSince() );
+      whereSpec.push_back( "until", 
+                           RelationalObjectTable::columnTypes::iovUntil() );
+      pool::AttributeList whereData( whereSpec );
+      // Only specify a channel selection if *not* all channels are selected
+      if ( ! channels.allChannels() ) {
+        if ( channels.firstChannel() == channels.lastChannel() ) {
+          whereData["channel"].setValue( channels.firstChannel() );
+        } else {
+          whereData["firstChannel"].setValue( channels.firstChannel() );
+          whereData["lastChannel"].setValue( channels.lastChannel() );
+        }
+      }
+      whereData["since1"].setValue( since );
+      whereData["since2"].setValue( since );
+      whereData["since3"].setValue( since );
+      whereData["until"].setValue( until );
+      
+      std::string whereClause;
+      // Only provide a channel selection clause if *not* all channels
+      // are selected in 'channels'
+      if ( ! channels.allChannels() ) {
+        // Tailor the where clause to the actual range
+        if ( channels.firstChannel() == channels.lastChannel() ) {
+          whereClause += RelationalObjectTable::columnNames::channelId();
+          whereClause += "= :channel";
+        } else {
+          whereClause = ":firstChannel <= ";
+          whereClause += RelationalObjectTable::columnNames::channelId();
+          whereClause += " and ";
+          whereClause += RelationalObjectTable::columnNames::channelId();
+          whereClause += " <= :lastChannel";
+        }
+        whereClause += " AND ";
+      }
+      
+      std::string s  = RelationalObjectTable::columnNames::iovSince();
+      std::string u  = RelationalObjectTable::columnNames::iovUntil();
+      
+      // Also see SimpleObject::overlaps for this clause
+      // but note that the upper end is *included* (<= :until)
+      whereClause += "(";
+      whereClause += " ( ( " + s + " <= :since1 )";
+      whereClause += "   AND ( :since2 < " + u + " ) )";
+      whereClause += " OR ";
+      whereClause += " ( ( :since3 <= " + s + " )";
+      whereClause += "   AND ( " + s + " <= :until ) )";
+      whereClause += ")";
+      
+      query->setCondition( whereClause, whereData );
+      
+      if ( channels.firstChannel() == channels.lastChannel() ) {
+        // Only one channel, skip 'channelId' in order clause
+        query->addToOrderList
+        ( RelationalObjectTable::columnNames::iovSince() + " ASC" );
+      } else {
+        if ( channels.order() == ChannelSelection::channelBeforeSince ) {
+          query->addToOrderList
+          ( RelationalObjectTable::columnNames::channelId() + " ASC" );
+          query->addToOrderList
+            ( RelationalObjectTable::columnNames::iovSince() + " ASC" );
+        } else {
+          query->addToOrderList
+          ( RelationalObjectTable::columnNames::iovSince() + " ASC" );
+          query->addToOrderList
+            ( RelationalObjectTable::columnNames::channelId() + " ASC" );
+        }
+      }
+      
+      // Set the row cache size
+      long newRowCacheSize = 100;
+      query->setRowCacheSize( newRowCacheSize );
+      
+      // Retrieve a cursor over the result set
+      pool::IRelationalCursor& cursor = query->process();
+      if ( ! cursor.start() )
+        throw RelationalException
+          ( "Could not start cursor loop", "RalDatabase" );
+      
+      while ( cursor.next() ) {
+        RelationalObjectTableRow row( cursor.currentRow(), objectTableSpec );
+        rset.push_back( row );
+      }
+      }
+      
+      return rset;
+    }
+  
+  
+  
+  /// Tests memory consumption of fetchRowsSV
+  void test_fetchRowsSV_detail() {
+    IFolderPtr folder = db->createFolder( "/myfolder", mixedPayloadSpec );
+    
+    int index = 0;
+    for ( int i = 0; i < 3; ++i ) {
+      folder->storeObject(  0, 10, mixedPayload( index++ ), (ChannelId)i );
+      folder->storeObject( 10, 20, mixedPayload( index++ ), (ChannelId)i );
+      folder->storeObject( 20, ValidityKeyMax, 
+                           mixedPayload( index++ ), (ChannelId)i );
+    }
+    
+    RalDatabase* ralDb = dynamic_cast<RalDatabase*>(db.get());
+    RelationalFolder* relfolder = 
+      dynamic_cast<RelationalFolder*>( folder.get() );
+    
+    ProcMemory mem;
+    std::cout << "\nStart test_fetchObjectTableRowsSV_detail "; 
+    mem.printVm();
+    
+    int nObjs = 3 * 1000;
+    
+    for ( int i = 0; i < nObjs; ++i ) {
+      
+      RelationalTransaction transaction( ralDb->transactionMgr() );
+
+      std::vector<RelationalObjectTableRow> rows
+      = fetch( relfolder->objectTableName(),
+               relfolder->payloadSpecification(), 
+               ValidityKeyMin, 
+               ValidityKeyMax, 
+               ChannelSelection::all() );
+        
+      if ( i % 1000 == 0 ) {
+        cout << "object # " << i << "\t";
+        mem.printVm();
+      }
+    }
+    
+    std::cout << "End ";
+    mem.printVm();
+    
+  }
+  
+  //------------------------------------------------------------------------
+  
+  /// Tests memory consumption of fetchRowsSV
+  void test_fetchRowsSV() {
+    IFolderPtr folder = db->createFolder( "/myfolder", mixedPayloadSpec );
+    
+    int index = 0;
+    for ( int i = 0; i < 3; ++i ) {
+      folder->storeObject(  0, 10, mixedPayload( index++ ), (ChannelId)i );
+      folder->storeObject( 10, 20, mixedPayload( index++ ), (ChannelId)i );
+      folder->storeObject( 20, ValidityKeyMax, 
+                           mixedPayload( index++ ), (ChannelId)i );
+    }
+
+    RalDatabase* ralDb = dynamic_cast<RalDatabase*>(db.get());
+    RelationalFolder* relfolder = 
+      dynamic_cast<RelationalFolder*>( folder.get() );
+    RalObjectTable objectTable( ralDb->ralDbPtr(), *relfolder );
+
+    ProcMemory mem;
+    std::cout << "\nStart test_fetchObjectTableRowsSV "; 
+    mem.printVm();
+    
+    int nObjs = 3 * 1000;
+    
+    for ( int i = 0; i < nObjs; ++i ) {
+      RelationalTransaction transaction( ralDb->transactionMgr() );
+
+      std::vector<RelationalObjectTableRow> rows =
+      objectTable.fetchRowsSV( relfolder->payloadSpecification(), 
+                               ValidityKeyMin, 
+                               ValidityKeyMax, 
+                               ChannelSelection::all() );
+      if ( i % 1000 == 0 ) {
+        cout << "object # " << i << "\t";
+        mem.printVm();
+      }
+    }
+    
+    std::cout << "End ";
+    mem.printVm();
+    
+  }
+  
+  //------------------------------------------------------------------------
+
+  /// Tests memory consumption of browseObjects
+  void test_browseObjects() {
+    IFolderPtr folder = db->createFolder( "/myfolder", 
+                                          mixedPayloadSpec,
+                                          "my description",
+                                          FolderVersioning::SINGLE_VERSION );
+    
+    int index = 0;
+    for ( int i = 0; i < 3; ++i ) {
+      folder->storeObject(  0, 10, mixedPayload( index++ ), (ChannelId)i );
+      folder->storeObject( 10, 20, mixedPayload( index++ ), (ChannelId)i );
+      folder->storeObject( 20, ValidityKeyMax, 
+                           mixedPayload( index++ ), (ChannelId)i );
+    }
+    
+    ProcMemory mem;
+    std::cout << "\nStart test_browseObjects "; 
+    mem.printVm();
+    
+    int nObjs = 10 * 1000;
+    
+    for ( int i = 0; i < nObjs; ++i ) 
+    {
+      ValidityKey since = 5;
+      ValidityKey until = 15;
+      IObjectIteratorPtr 
+        objs = folder->browseObjects( since, until,
+                                      ChannelSelection::all() );
+      if ( i % 1000 == 0 ) {
+        cout << "object # " << i << "\t";
+        mem.printVm();
+      }
+    }
+    
+    std::cout << "End ";
+    mem.printVm();
+    
+  }
+  
+  //------------------------------------------------------------------------
+  
+  /// Tests memory consumption of bulk storeObjects
+  void test_storeObject_bulk() {
+
+    ProcMemory mem;
+    std::cout << "\nStart test_storeObject_bulk ";
+    mem.printVm();
+
+    long nObjs = 50 * 1000;
+
+    {
+      IFolderPtr folder = db->createFolder( "/myfolder", mixedPayloadSpec );
+      
+      folder->setupStorageBuffer();
+      for ( long i = 0; i < nObjs; ++i ) {
+        folder->storeObject( i, ValidityKeyMax, mixedPayload( i ) );
+        if ( i % 10000 == 0 ) {
+          cout << "object # " << i << "\t";
+          mem.printVm();
+          folder->flushStorageBuffer();
+        }
+      }
+      
+      std::cout << "Before flushing ";
+      mem.printVm();
+
+      folder->flushStorageBuffer();
+      
+      cout << "\n----------------------------------------------------" << endl;
+      cout << "** wrote " << nObjs << " objects (150 bytes mixed) **" << endl;
+    }
+    
+    std::cout << "End ";
+    mem.printVm();
+    
+  }
+  
+  //------------------------------------------------------------------------
+  
+  void test_AttributeList() {
+    pool::AttributeListSpecification spec;
+    spec.push_back("I","int");
+    
+    ProcMemory mem;
+    std::cout << "\nStart test_AttributeList ";
+    mem.printVm();
+    
+    long nObjs = 1*1000*1000;
+    for ( long i = 0; i < nObjs; ++i ) {
+      if ( i % 100000 == 0 ) {
+        std::cout << "object " << i << "\t";
+        mem.printVm();
+      }
+      pool::AttributeList list( spec );
+    }
+  }
+  
+  //------------------------------------------------------------------------
+  
+  void test_AttributeListSpecification() {
+    ProcMemory mem;
+    std::cout << "\nStart test_AttributeListSpecification ";
+    mem.printVm();
+    
+    long nObjs = 1*1000*1000;
+    for ( long i = 0; i < nObjs; ++i ) {
+      if ( i % 100000 == 0 ) {
+        std::cout << "object " << i << "\t";
+        mem.printVm();
+      }
+      pool::AttributeListSpecification spec;
+      spec.push_back("I","int");
+    }
+  }
+  
+  //------------------------------------------------------------------------		
+  
+  /// Creates a dummy payload AttributeList for a given index
+  AttributeList mixedPayload( int index ) {
+    AttributeList payload( mixedPayloadSpec );
+    payload["I"].setValue<int>( index );
+    stringstream s;
+    s << "Object " << index;
+    payload["S"].setValue<string>( s.str() );
+    payload["X0"].setValue<float>( (float)(index/1000.) );
+    payload["X1"].setValue<float>( (float)(index/1000.) );
+    payload["X2"].setValue<float>( (float)(index/1000.) );
+    payload["X3"].setValue<float>( (float)(index/1000.) );
+    payload["X4"].setValue<float>( (float)(index/1000.) );
+    payload["X5"].setValue<float>( (float)(index/1000.) );
+    payload["X6"].setValue<float>( (float)(index/1000.) );
+    payload["X7"].setValue<float>( (float)(index/1000.) );
+    payload["X8"].setValue<float>( (float)(index/1000.) );
+    payload["X9"].setValue<float>( (float)(index/1000.) );
+    payload["P"].setValue<string>( "0123456789"
+                                   "0123456789"
+                                   "0123456789"
+                                   "0123456789"
+                                   "0123456789"
+                                   "0123456789"
+                                   "0123456789"
+                                   "0123456789"
+                                   "0123456789"
+                                   "0123456789"
+                                   );
+    return payload;
+  }
+		
+  
+  /// Creates a uniform payload specification for nFields fields
+  SpecPtr uniformSpec( int nFields, const string & type ) {
+    SpecPtr spec( new AttributeListSpecification() );
+    for ( int i = 0; i < nFields; ++i ) {
+      stringstream s;
+      s << "X" << i;
+      spec->push_back( s.str(), type );
+    }
+    return spec;
+  }
+  
+  
+  /// Creates a dummy 4kB string AttributeList
+  AttributeList string4kbPayload( SpecPtr & spec ) {
+    stringstream payloadString;
+    int bytes = 4000;
+    for ( int i = 0; i < bytes; ++i ) payloadString << "a";
+    
+    int nFields = spec->size();
+    AttributeList payload( spec );
+    for ( int i = 0; i < nFields; ++i ) {
+      stringstream s;
+      s << "X" << i;
+      payload[ s.str() ].setValue<string>( payloadString.str() );
+    }
+    return payload;
+  }
+		
+  
+  /// Creates a dummy float AttributeList for a given index
+  AttributeList floatPayload( int index, SpecPtr & spec ) {
+    int nFields = spec->size();
+    AttributeList payload( spec );
+    for ( int i = 0; i < nFields; ++i ) {
+      stringstream s;
+      s << "X" << i;
+      payload[ s.str() ].setValue<float>( (float)(index/1000.) );
+    }
+    return payload;
+  }
+		
+  
+  void setUp() {
+    if ( mixedPayloadSpec.size() == 0 ) {
+      mixedPayloadSpec.push_back("I","int");
+      mixedPayloadSpec.push_back("S","string");
+      mixedPayloadSpec.push_back("X0","float");
+      mixedPayloadSpec.push_back("X1","float");
+      mixedPayloadSpec.push_back("X2","float");
+      mixedPayloadSpec.push_back("X3","float");
+      mixedPayloadSpec.push_back("X4","float");
+      mixedPayloadSpec.push_back("X5","float");
+      mixedPayloadSpec.push_back("X6","float");
+      mixedPayloadSpec.push_back("X7","float");
+      mixedPayloadSpec.push_back("X8","float");
+      mixedPayloadSpec.push_back("X9","float");
+      mixedPayloadSpec.push_back("P","string");
+    }
+    
+    if ( getenv( COOLTESTDB ) ) {
+      connectString = getenv( COOLTESTDB );
+    } else {
+      cout << "Please provide a connect string by "
+      << "specifying one in the environment variable COOLTESTDB, e.g." 
+      << endl;
+      cout << "setenv COOLTESTDB "
+        << "\"oracle://devdb10;schema=lcg_cool;dbname=COOLTEST\"" << endl;
+      cout << "Aborting test" << endl;
+      exit(-1);
+    }
+    
+    static CoralApplication app;
+    IDatabaseSvc& dbSvc = app.databaseService();
+    dbSvc.dropDatabase( connectString );
+    db = dbSvc.createDatabase( connectString );
+  }
+		
+		void tearDown() {
+      db.reset();
+		}
+  
+  // Make the private suite() available to main()
+  // MemoryConsumptionTest::suite() is generated by CPPUNIT_TEST_SUITE_END
+  static CppUnit::TestSuite* theSuite() { return suite(); }
+  
+};
+
+CPPUNIT_TEST_SUITE_REGISTRATION( MemoryConsumptionTest );
+
+} // namespace
+
+
+#include <cppunit/ui/text/TestRunner.h> 
+#include <cppunit/CompilerOutputter.h> 
+
+
+int main( int argc, char **argv ) {
+  
+  string command;
+  
+  if ( argc == 1 ) {
+    command = "showTests";
+  } else if ( argc == 2 ) {
+    command = argv[1];
+  } else {
+    cout << "Usage:\n" << argv[0] << " [test]" << endl;
+    cout << "Runs the given test. If called without arguments returns a list "
+            "of available tests." << endl;
+    exit(-1);
+  }
+    
+  
+  CppUnit::TestSuite* suite = cool::MemoryConsumptionTest::theSuite();
+
+  if ( command == "showTests" ) {
+    std::vector<CppUnit::Test*> tests = suite->getTests();
+    bool first = true;
+    for ( std::vector<CppUnit::Test*>::const_iterator 
+          test = tests.begin(); test != tests.end(); ++test ) {
+      if ( first ) {
+        cout << (*test)->getName();
+        first = false;
+      } else {
+        cout << " " << (*test)->getName();
+      }
+    }
+    cout << endl;
+    return 0;
+    
+  } else {
+    
+    string testname = command;    
+    
+    /// Adds the test to the list of test to run
+    CppUnit::TextUi::TestRunner runner;
+    std::vector<CppUnit::Test*> tests = suite->getTests();
+    for ( std::vector<CppUnit::Test*>::const_iterator 
+          test = tests.begin(); test != tests.end(); ++test ) {
+      runner.addTest( *test );
+    }
+  
+    // Change the default outputter to a compiler error format outputter 
+    // uncomment the following line if you need a compiler outputter.
+    runner.setOutputter(new CppUnit::CompilerOutputter( &runner.result(),
+                                                        std::cout ) );
+  
+    bool wasSuccessful = runner.run(testname,false,true,false);
+    
+    // Return error code 1 if the one of test failed.
+    // Uncomment the next line if you want to integrate CppUnit with Oval
+    if(!wasSuccessful !=0) std::cerr <<"Error: CppUnit Failures"<<std::endl;
+    std::cout <<"[OVAL] Cppunit-result ="<<!wasSuccessful<<std::endl;
+    return 0;
+  }
+}
+
+#endif // NOPORT
diff --git a/RelationalCool/tests/MemoryConsumption/unitTest_RelationalCool_MemoryConsumption.out.osx103_gcc33 b/RelationalCool/tests/MemoryConsumption/unitTest_RelationalCool_MemoryConsumption.out.osx103_gcc33
new file mode 100644
index 000000000..5194eee23
--- /dev/null
+++ b/RelationalCool/tests/MemoryConsumption/unitTest_RelationalCool_MemoryConsumption.out.osx103_gcc33
@@ -0,0 +1,127 @@
+
+Start test_seal_TimingItem VSZ=130872 RSS=11692
+object # 0	VSZ=130872 RSS=11740
+object # 1000	VSZ=130948 RSS=12268
+object # 2000	VSZ=131228 RSS=12800
+object # 3000	VSZ=131628 RSS=13340
+object # 4000	VSZ=132052 RSS=13884
+object # 5000	VSZ=132532 RSS=14420
+object # 6000	VSZ=133008 RSS=14960
+object # 7000	VSZ=133420 RSS=15488
+object # 8000	VSZ=133984 RSS=16024
+object # 9000	VSZ=134476 RSS=16544
+End VSZ=134796 RSS=17072
+
+OK (1)
+[OVAL] Cppunit-result =0
+
+Start test_AttributeListSpecification VSZ=130872 RSS=14004
+object 0	VSZ=130872 RSS=14004
+object 100000	VSZ=132292 RSS=15608
+object 200000	VSZ=134036 RSS=17200
+object 300000	VSZ=135508 RSS=18772
+object 400000	VSZ=137212 RSS=20344
+object 500000	VSZ=139000 RSS=21916
+object 600000	VSZ=140652 RSS=23492
+object 700000	VSZ=141932 RSS=25056
+object 800000	VSZ=143376 RSS=26620
+object 900000	VSZ=145008 RSS=28188
+
+OK (1)
+[OVAL] Cppunit-result =0
+
+Start test_AttributeList VSZ=130872 RSS=11664
+object 0	VSZ=130872 RSS=11664
+object 100000	VSZ=130872 RSS=11664
+object 200000	VSZ=130872 RSS=11664
+object 300000	VSZ=130872 RSS=11664
+object 400000	VSZ=130872 RSS=11664
+object 500000	VSZ=130872 RSS=11664
+object 600000	VSZ=130872 RSS=11664
+object 700000	VSZ=130872 RSS=11664
+object 800000	VSZ=130872 RSS=11664
+object 900000	VSZ=130872 RSS=11664
+
+OK (1)
+[OVAL] Cppunit-result =0
+
+Start test_storeObject_bulk VSZ=130872 RSS=11668
+object # 0	VSZ=130872 RSS=11880
+object # 10000	VSZ=145924 RSS=27208
+object # 20000	VSZ=185980 RSS=62092
+object # 30000	VSZ=193264 RSS=69200
+object # 40000	VSZ=199992 RSS=75952
+Before flushing VSZ=207608 RSS=82196
+
+----------------------------------------------------
+** wrote 50000 objects (150 bytes mixed) **
+End VSZ=211988 RSS=82524
+
+OK (1)
+[OVAL] Cppunit-result =0
+
+Start test_browseObjects VSZ=130872 RSS=14880
+object # 0	VSZ=130872 RSS=14904
+object # 1000	VSZ=132100 RSS=16080
+object # 2000	VSZ=133872 RSS=17788
+object # 3000	VSZ=135504 RSS=19472
+object # 4000	VSZ=137372 RSS=21144
+object # 5000	VSZ=139112 RSS=22804
+object # 6000	VSZ=140884 RSS=24468
+object # 7000	VSZ=142524 RSS=26128
+object # 8000	VSZ=144092 RSS=27772
+object # 9000	VSZ=145864 RSS=29424
+End VSZ=147472 RSS=31068
+
+OK (1)
+[OVAL] Cppunit-result =0
+
+Start test_fetchObjectTableRowsSV VSZ=130872 RSS=11992
+object # 0	VSZ=130872 RSS=12032
+object # 1000	VSZ=132672 RSS=14356
+object # 2000	VSZ=134988 RSS=16648
+End VSZ=137392 RSS=18896
+
+OK (1)
+[OVAL] Cppunit-result =0
+
+Start test_fetchObjectTableRowsSV_detail VSZ=130872 RSS=12000
+object # 0	VSZ=130872 RSS=12032
+object # 1000	VSZ=132632 RSS=14352
+object # 2000	VSZ=134764 RSS=16628
+End VSZ=137156 RSS=18896
+
+OK (1)
+[OVAL] Cppunit-result =0
+
+Start test_RelationalObjectTableRow VSZ=130872 RSS=11672
+object # 0	VSZ=130872 RSS=11700
+object # 10000	VSZ=130872 RSS=11700
+object # 20000	VSZ=130872 RSS=11700
+object # 30000	VSZ=130872 RSS=11700
+object # 40000	VSZ=130872 RSS=11700
+object # 50000	VSZ=130872 RSS=11700
+object # 60000	VSZ=130872 RSS=11700
+object # 70000	VSZ=130872 RSS=11700
+object # 80000	VSZ=130872 RSS=11700
+object # 90000	VSZ=130872 RSS=11700
+End VSZ=130872 RSS=11700
+
+OK (1)
+[OVAL] Cppunit-result =0
+
+Start test_RelationalObjectTableRow_vector VSZ=130872 RSS=11668
+object # 0	VSZ=130872 RSS=11716
+object # 1000	VSZ=130872 RSS=11716
+object # 2000	VSZ=130872 RSS=11716
+object # 3000	VSZ=130872 RSS=11716
+object # 4000	VSZ=130872 RSS=11716
+object # 5000	VSZ=130872 RSS=11716
+object # 6000	VSZ=130872 RSS=11716
+object # 7000	VSZ=130872 RSS=11716
+object # 8000	VSZ=130872 RSS=11716
+object # 9000	VSZ=130872 RSS=11716
+End VSZ=130872 RSS=11716
+
+OK (1)
+[OVAL] Cppunit-result =0
diff --git a/RelationalCool/tests/MemoryConsumption/unitTest_RelationalCool_MemoryConsumption.out.slc3_ia32_gcc323 b/RelationalCool/tests/MemoryConsumption/unitTest_RelationalCool_MemoryConsumption.out.slc3_ia32_gcc323
new file mode 100644
index 000000000..04211c9a3
--- /dev/null
+++ b/RelationalCool/tests/MemoryConsumption/unitTest_RelationalCool_MemoryConsumption.out.slc3_ia32_gcc323
@@ -0,0 +1,151 @@
+Property Catalogue: level[Info] Adding property: OutputLevel = 5 in scope "SEAL/Services/MessageService"
+Property Catalogue: level[Info] Adding property: Format =  "%-36s %-8s %s" in scope "SEAL/Services/MessageService"
+Property Catalogue: level[Info] Adding property: AuthenticationFile =  "/home/sas/Projects/Atlas/myLCG/cool_extras/authentication.xml" in scope "POOL/Services/XMLAuthenticationService"
+
+Start test_seal_TimingItem VSZ=10180 RSS=5956
+object # 0	VSZ=10180 RSS=5972
+object # 1000	VSZ=10580 RSS=6268
+object # 2000	VSZ=10852 RSS=6608
+object # 3000	VSZ=11168 RSS=6940
+object # 4000	VSZ=11500 RSS=7280
+object # 5000	VSZ=11832 RSS=7612
+object # 6000	VSZ=12312 RSS=7952
+object # 7000	VSZ=12616 RSS=8288
+object # 8000	VSZ=12920 RSS=8620
+object # 9000	VSZ=13348 RSS=8960
+End VSZ=13508 RSS=9300
+
+OK (1)
+[OVAL] Cppunit-result =0
+Property Catalogue: level[Info] Adding property: OutputLevel = 5 in scope "SEAL/Services/MessageService"
+Property Catalogue: level[Info] Adding property: Format =  "%-36s %-8s %s" in scope "SEAL/Services/MessageService"
+Property Catalogue: level[Info] Adding property: AuthenticationFile =  "/home/sas/Projects/Atlas/myLCG/cool_extras/authentication.xml" in scope "POOL/Services/XMLAuthenticationService"
+
+Start test_AttributeList VSZ=10180 RSS=5996
+object 0	VSZ=10180 RSS=5996
+object 100000	VSZ=10180 RSS=5996
+object 200000	VSZ=10180 RSS=5996
+object 300000	VSZ=10180 RSS=5996
+object 400000	VSZ=10180 RSS=5996
+object 500000	VSZ=10180 RSS=5996
+object 600000	VSZ=10180 RSS=5996
+object 700000	VSZ=10180 RSS=5996
+object 800000	VSZ=10180 RSS=5996
+object 900000	VSZ=10180 RSS=5996
+
+OK (1)
+[OVAL] Cppunit-result =0
+Property Catalogue: level[Info] Adding property: OutputLevel = 5 in scope "SEAL/Services/MessageService"
+Property Catalogue: level[Info] Adding property: Format =  "%-36s %-8s %s" in scope "SEAL/Services/MessageService"
+Property Catalogue: level[Info] Adding property: AuthenticationFile =  "/home/sas/Projects/Atlas/myLCG/cool_extras/authentication.xml" in scope "POOL/Services/XMLAuthenticationService"
+
+Start test_storeObject_bulk VSZ=10176 RSS=5992
+object # 0	VSZ=10176 RSS=6152
+object # 10000	VSZ=22964 RSS=18940
+object # 20000	VSZ=41108 RSS=37148
+object # 30000	VSZ=41752 RSS=37792
+object # 40000	VSZ=41936 RSS=37976
+object # 50000	VSZ=42080 RSS=38120
+object # 60000	VSZ=42104 RSS=38144
+object # 70000	VSZ=42104 RSS=38144
+object # 80000	VSZ=42104 RSS=38144
+object # 90000	VSZ=42112 RSS=38152
+object # 100000	VSZ=41524 RSS=37564
+object # 110000	VSZ=41832 RSS=37872
+object # 120000	VSZ=42000 RSS=38040
+object # 130000	VSZ=42108 RSS=38148
+object # 140000	VSZ=42108 RSS=38148
+object # 150000	VSZ=42112 RSS=38152
+object # 160000	VSZ=41920 RSS=37960
+object # 170000	VSZ=42068 RSS=38108
+object # 180000	VSZ=42116 RSS=38156
+object # 190000	VSZ=41108 RSS=37148
+Before flushing VSZ=41764 RSS=37804
+
+----------------------------------------------------
+** wrote 200000 objects (150 bytes mixed) **
+End VSZ=41812 RSS=37904
+
+OK (1)
+[OVAL] Cppunit-result =0
+Property Catalogue: level[Info] Adding property: OutputLevel = 5 in scope "SEAL/Services/MessageService"
+Property Catalogue: level[Info] Adding property: Format =  "%-36s %-8s %s" in scope "SEAL/Services/MessageService"
+Property Catalogue: level[Info] Adding property: AuthenticationFile =  "/home/sas/Projects/Atlas/myLCG/cool_extras/authentication.xml" in scope "POOL/Services/XMLAuthenticationService"
+
+Start test_browseObjects VSZ=10224 RSS=6304
+object # 0	VSZ=10224 RSS=6324
+object # 1000	VSZ=10224 RSS=6324
+object # 2000	VSZ=10224 RSS=6324
+object # 3000	VSZ=10224 RSS=6324
+object # 4000	VSZ=10224 RSS=6324
+object # 5000	VSZ=10224 RSS=6324
+object # 6000	VSZ=10224 RSS=6324
+object # 7000	VSZ=10224 RSS=6324
+object # 8000	VSZ=10224 RSS=6324
+object # 9000	VSZ=10224 RSS=6324
+End VSZ=10224 RSS=6324
+
+OK (1)
+[OVAL] Cppunit-result =0
+Property Catalogue: level[Info] Adding property: OutputLevel = 5 in scope "SEAL/Services/MessageService"
+Property Catalogue: level[Info] Adding property: Format =  "%-36s %-8s %s" in scope "SEAL/Services/MessageService"
+Property Catalogue: level[Info] Adding property: AuthenticationFile =  "/home/sas/Projects/Atlas/myLCG/cool_extras/authentication.xml" in scope "POOL/Services/XMLAuthenticationService"
+
+Start test_fetchObjectTableRowsSV VSZ=10300 RSS=6260
+object # 0	VSZ=10300 RSS=6276
+object # 1000	VSZ=10300 RSS=6276
+object # 2000	VSZ=10300 RSS=6276
+End VSZ=10300 RSS=6276
+
+OK (1)
+[OVAL] Cppunit-result =0
+Property Catalogue: level[Info] Adding property: OutputLevel = 5 in scope "SEAL/Services/MessageService"
+Property Catalogue: level[Info] Adding property: Format =  "%-36s %-8s %s" in scope "SEAL/Services/MessageService"
+Property Catalogue: level[Info] Adding property: AuthenticationFile =  "/home/sas/Projects/Atlas/myLCG/cool_extras/authentication.xml" in scope "POOL/Services/XMLAuthenticationService"
+
+Start test_fetchObjectTableRowsSV_detail VSZ=10284 RSS=6256
+object # 0	VSZ=10284 RSS=6268
+object # 1000	VSZ=10284 RSS=6268
+object # 2000	VSZ=10284 RSS=6268
+End VSZ=10284 RSS=6268
+
+OK (1)
+[OVAL] Cppunit-result =0
+Property Catalogue: level[Info] Adding property: OutputLevel = 5 in scope "SEAL/Services/MessageService"
+Property Catalogue: level[Info] Adding property: Format =  "%-36s %-8s %s" in scope "SEAL/Services/MessageService"
+Property Catalogue: level[Info] Adding property: AuthenticationFile =  "/home/sas/Projects/Atlas/myLCG/cool_extras/authentication.xml" in scope "POOL/Services/XMLAuthenticationService"
+
+Start test_RelationalObjectTableRow VSZ=10176 RSS=6008
+object # 0	VSZ=10176 RSS=6024
+object # 10000	VSZ=10176 RSS=6024
+object # 20000	VSZ=10176 RSS=6024
+object # 30000	VSZ=10176 RSS=6024
+object # 40000	VSZ=10176 RSS=6024
+object # 50000	VSZ=10176 RSS=6024
+object # 60000	VSZ=10176 RSS=6024
+object # 70000	VSZ=10176 RSS=6024
+object # 80000	VSZ=10176 RSS=6024
+object # 90000	VSZ=10176 RSS=6024
+End VSZ=10176 RSS=6024
+
+OK (1)
+[OVAL] Cppunit-result =0
+Property Catalogue: level[Info] Adding property: OutputLevel = 5 in scope "SEAL/Services/MessageService"
+Property Catalogue: level[Info] Adding property: Format =  "%-36s %-8s %s" in scope "SEAL/Services/MessageService"
+Property Catalogue: level[Info] Adding property: AuthenticationFile =  "/home/sas/Projects/Atlas/myLCG/cool_extras/authentication.xml" in scope "POOL/Services/XMLAuthenticationService"
+
+Start test_RelationalObjectTableRow_vector VSZ=10176 RSS=5996
+object # 0	VSZ=10176 RSS=6012
+object # 1000	VSZ=10176 RSS=6012
+object # 2000	VSZ=10176 RSS=6012
+object # 3000	VSZ=10176 RSS=6012
+object # 4000	VSZ=10176 RSS=6012
+object # 5000	VSZ=10176 RSS=6012
+object # 6000	VSZ=10176 RSS=6012
+object # 7000	VSZ=10176 RSS=6012
+object # 8000	VSZ=10176 RSS=6012
+object # 9000	VSZ=10176 RSS=6012
+End VSZ=10176 RSS=6012
+
+OK (1)
+[OVAL] Cppunit-result =0
diff --git a/RelationalCool/tests/MyODBCBulkTest/README b/RelationalCool/tests/MyODBCBulkTest/README
new file mode 100644
index 000000000..44b51ceb1
--- /dev/null
+++ b/RelationalCool/tests/MyODBCBulkTest/README
@@ -0,0 +1,128 @@
+Summary table (strings only)
+-----------------------------
+
+#chars  #cols   #rows   Result          (#chars+2)*(#cols)
+
+8186    1       1       OK              8188
+8187    1       1       ERROR #1        8189
+
+4091    2       1       OK              8186
+4092    2       1       ERROR #1        8188
+
+1020    8       1       OK              8176
+1021    8       1       ERROR #1        8184
+
+10      674     1       OK              8088
+10      675     1       ERROR #2        8100
+
+8       809     1       OK              8090
+8       810     1       ERROR #2        8100
+
+100     79      1       OK              8058
+100     80      1       ERROR #3        8160
+
+98      80      1       OK              8000
+98      81      1       ERROR #4        8100
+
+7       899     1       OK              8091
+7       900     1       ERROR #2        8100
+
+6       1000    1       OK              8000
+6       1001    1       ERROR #5        -- too many columns --
+
+Looks like:
+=> OK if ( #chars + 2 ) * ( #cols ) <= 8000
+=> May (or may not) fail otherwise
+
+NB:
+- checked that the names of the columns are irrelevant (eg "sXXX" vs "ssXXX")
+- checked that the name of the table is irrelevant (eg "DataTable" vs "Table")
+
+Error messages
+---------------
+
+* ERROR #1
+
+POOL/RelationalPlugins/mysql/odbc: level[Info] Bulk rowset SQL: SELECT "s0"...
+
+POOL/RelationalPlugins/mysql/odbc: level[Error] /afs/cern.ch/sw/lcg/app/releases/POOL/POOL_2_1_2/src/ODBCAccess/src/ODBCBulkRowInserter.cpp:316:pcitdb59.cern.ch:HY000:Affected rows 0:-1:1064:[MySQL][ODBC 3.51 Driver][mysqld-4.0.25-standard-log]You have an error in your SQL syntax.  Check the manual that corresponds to your MySQL server version for the right syntax to use near '' at line 1
+
+Segmentation fault
+
+* ERROR #2
+
+POOL/RelationalPlugins/mysql/odbc: level[Info] Bulk rowset SQL: SELECT "s0"...
+
+POOL/RelationalPlugins/mysql/odbc: level[Error] /afs/cern.ch/sw/lcg/app/releases/POOL/POOL_2_1_2/src/ODBCAccess/src/ODBCBulkRowInserter.cpp:316:pcitdb59.cern.ch:HY000:Affected rows 0:-1:1030:[MySQL][ODBC 3.51 Driver][mysqld-4.0.25-standard-log]Got error 139 from table handler
+
+Standard C++ exception : Could not flush the remaining rows into the table.
+
+* ERROR #3
+
+POOL/RelationalPlugins/mysql/odbc: level[Info] Bulk rowset SQL: SELECT "s0"...
+
+Out of memory (Needed 2924090368 bytes)
+
+POOL/RelationalPlugins/mysql/odbc: level[Error] /afs/cern.ch/sw/lcg/app/releases/POOL/POOL_2_1_2/src/ODBCAccess/src/ODBCBulkRowInserter.cpp:316:pcitdb59.cern.ch:HY000:Affected rows 0:-1:1136:[MySQL][ODBC 3.51 Driver][mysqld-4.0.25-standard-log]Column count doesn't match value count at row 1
+
+Standard C++ exception : Could not flush the remaining rows into the table.
+
+* ERROR #4
+
+POOL/RelationalPlugins/mysql/odbc: level[Info] Bulk rowset SQL: SELECT "s0"...
+
+POOL/RelationalPlugins/mysql/odbc: level[Error] /afs/cern.ch/sw/lcg/app/releases/POOL/POOL_2_1_2/src/ODBCAccess/src/ODBCBulkRowInserter.cpp:316:pcitdb59.cern.ch:HY000:Affected rows 0:-1:1136:[MySQL][ODBC 3.51 Driver][mysqld-4.0.25-standard-log]Column count doesn't match value count at row 1
+
+Standard C++ exception : Could not flush the remaining rows into the table.
+
+* ERROR #5
+
+POOL/RelationalPlugins/mysql/odbc: level[Debug] Prepared statement: CREATE TABLE
+
+POOL/RelationalPlugins/mysql/odbc: level[Error] /afs/cern.ch/sw/lcg/app/releases/POOL/POOL_2_1_2/src/ODBCAccess/src/ODBCStatement.cpp:335:pcitdb59.cern.ch:HY000:Affected rows 0:-1:1005:[MySQL][ODBC 3.51 Driver][mysqld-4.0.25-standard-log]Can't create table './COOLDB/DataTable.frm' (errno: 139)
+
+Relational exception from module MySQL/ODBC
+    Could not create a table named "DataTable"
+
+Summary table (strings and integers)
+-------------------------------------
+
+#chars  #cols   #rows   Result    intValue #intCols  
+
+8186    1       1       OK        0          0         
+8187    1       1       ERROR #1  0          0         
+
+8183    1       1       OK        1          1        
+8184    1       1       ERROR #1  1          1         
+
+8183    1       1       OK        9999       1        
+8183    1       1       ERROR #1  10000      1         
+8182    1       1       OK        10000      1         
+8182    1       1       OK        99999      1         
+8182    1       1       ERROR #1  100000     1         
+8181    1       1       OK        100000     1         
+
+8178    1       1       OK        999999999  1         
+8178    1       1       ERROR #1  1000000000 1         
+8177    1       1       OK        1000000000 1         
+
+So, clearly integer columns ALSO take up space, and they take up a space 
+that ALSO depends on the integer value (although it is not a simple
+count of the decimal representation string length).
+
+eg "1" takes up 2 (overhead) + 1 byte
+eg "1000" takes up 2 (overhead) + 1 byte
+eg "10000" takes up 2 (overhead) + 2 bytes
+eg "100000000" takes up 2 (overhead) + 6 bytes
+
+MyODBC code
+------------
+
+According to Marco: the problem is in cursor.c, lines 1048-1049:
+
+    dynstr_append_mem(ext_query, net->buff, length-1);
+    dynstr_append_mem(ext_query, "),", 2);
+
+This shows that bind variables are not used (and could be analysed 
+to understand what exactly is done - but we will not bother!).
+
diff --git a/RelationalCool/tests/MyODBCBulkTest/test_MyODBCBulkOp.cpp b/RelationalCool/tests/MyODBCBulkTest/test_MyODBCBulkOp.cpp
new file mode 100755
index 000000000..320a3ec09
--- /dev/null
+++ b/RelationalCool/tests/MyODBCBulkTest/test_MyODBCBulkOp.cpp
@@ -0,0 +1,213 @@
+// PORT -- temporarily disabled: not part of our official test suite
+int main() { return 0; }
+#ifdef NOPORT
+
+#include <iostream>
+#include <stdexcept>
+#include <memory>
+#include "RelationalAccess/RelationalException.h"
+#include "RelationalAccess/IRelationalService.h"
+#include "RelationalAccess/IRelationalDomain.h"
+#include "RelationalAccess/IRelationalSession.h"
+#include "RelationalAccess/IRelationalTransaction.h"
+#include "RelationalAccess/IRelationalSchema.h"
+#include "RelationalAccess/IRelationalTable.h"
+#include "RelationalAccess/RelationalEditableTableDescription.h"
+#include "RelationalAccess/IRelationalTableDataEditor.h"
+#include "RelationalAccess/IRelationalBulkRowInserter.h"
+#include "RelationalAccess/IRelationalQuery.h"
+#include "RelationalAccess/IRelationalCursor.h"
+#include "AttributeList/AttributeList.h"
+#include "POOLCore/POOLContext.h"
+#include "SealKernel/Context.h"
+#include "RelationalAccess/IRelationalTypeConverter.h"
+#include <sstream>
+
+#include <cstdlib>
+
+int main( int argc, char *argv[] )
+{
+  
+  if ( argc != 4 && argc != 6 ) {
+    std::cout << "Usage " << argv[0] 
+              << " n_chars n_charCols n_rows [intValue n_intCols]" 
+              << std::endl;
+    return 1;
+  }
+
+  try {
+    std::string charCol_name = "s"; // No difference if changed to "ss"
+    std::string intCol_name = "i";
+    std::string tab_name = "DataTable"; // No difference if changed to "Table"
+    size_t n_chars;
+    int n_charCols;
+    int n_rows;
+    int intValue = 0;
+    int n_intCols = 0;
+    
+    {
+      std::istringstream a1(argv[1]); a1 >> n_chars;
+      std::istringstream a2(argv[2]); a2 >> n_charCols;
+      std::istringstream a3(argv[3]); a3 >> n_rows;
+      if ( argc == 6 ) 
+      { std::istringstream a4(argv[4]); a4 >> intValue;
+        std::istringstream a5(argv[5]); a5 >> n_intCols; }      
+    }
+    
+    pool::POOLContext::loadComponent( "SEAL/Services/Message Service" );
+    pool::POOLContext::loadComponent( "POOL/Services/XMLAuthenticationService" );
+    pool::POOLContext::loadComponent( "POOL/Services/RelationalService" );
+    pool::POOLContext::setMessageVerbosityLevel( seal::Msg::Debug );
+    seal::MessageStream log( pool::POOLContext::context(), "TableDataEditor_Test" );
+    seal::IHandle<pool::IRelationalService> serviceHandle = 
+      pool::POOLContext::context()->query<pool::IRelationalService>( "POOL/Services/RelationalService" );
+    if ( ! serviceHandle ) {
+      throw std::runtime_error( "Could not retrieve the relational service" );
+    }
+
+    std::string connectionString = "mysql://pcitdb59.cern.ch/COOLDB";
+    pool::IRelationalDomain& domain = serviceHandle->domainForConnection( connectionString );
+
+    // Creating a session
+    std::auto_ptr< pool::IRelationalSession > session( domain.newSession( connectionString ) );
+
+    // Establish a connection with the server
+    std::cout << "Connecting..." << std::endl;
+    if ( ! session->connect() ) {
+      throw std::runtime_error( "Could not connect to the database server." );
+    }
+
+    // Start a transaction
+    std::cout << "Starting a new transaction" << std::endl;
+    if ( ! session->transaction().start() ) {
+      throw std::runtime_error( "Could not start a new transaction." );
+    }
+
+    // Droping old tables
+    if ( session->userSchema().existsTable( tab_name ) ) {
+      std::cout << "Deleting table \"" << tab_name << "\"" << std::endl;
+      if ( ! session->userSchema().dropTable( tab_name ) ) {
+        throw std::runtime_error( "Could not drop a table." );
+      }
+    }
+
+    session->typeConverter().setSqlTypeForCppType("TEXT",pool::AttributeStaticTypeInfo<std::string>::type_name());
+
+    // Creating the description for the table
+    std::auto_ptr< pool::IRelationalEditableTableDescription >
+      description1( new pool::RelationalAccess::RelationalEditableTableDescription( log,
+                                                                                    domain.flavorName() ));
+    for ( int j = 0 ; j < n_charCols ; ++j ){
+      std::ostringstream cn;
+      cn << charCol_name << j;
+      description1->insertColumn( cn.str(), pool::AttributeStaticTypeInfo<std::string>::type_name() );
+    }
+    for ( int j = 0 ; j < n_intCols ; ++j ){
+      std::ostringstream cn;
+      cn << intCol_name << j;
+      description1->insertColumn( cn.str(), pool::AttributeStaticTypeInfo<int>::type_name() );
+    }
+    
+    // Create the first table.
+    std::cout << "Creating table \"" << tab_name << "\"" << std::endl;
+    pool::IRelationalTable& table1 = session->userSchema().createTable( tab_name, *description1 );
+
+    // Costructing a row buffer.
+    pool::AttributeList data1( table1.description().columnNamesAndTypes() );
+
+    // Adding new rows
+    std::cout << "Inserting new rows into the table." << std::endl;
+    pool::IRelationalBulkRowInserter& rowInserter1 = table1.dataEditor().bulkRowInserter();
+    if ( ! rowInserter1.setup( data1, 50 ) )
+    {
+      throw std::runtime_error( "Could not bind a new row for inserting." );
+    }
+
+    for ( int i = 0; i < n_rows; ++i )
+    {
+      for ( int j = 0 ; j < n_charCols ; ++j ){
+        std::ostringstream cn;
+        cn << charCol_name << j;
+        data1[cn.str()].setValue<std::string>( std::string(n_chars,'x') );
+      }
+      for ( int j = 0 ; j < n_intCols ; ++j ){
+        std::ostringstream cn;
+        cn << intCol_name << j;
+        data1[cn.str()].setValue<int>( intValue );
+      }
+      
+      if ( ! rowInserter1.insertNewRow() )
+      {
+        throw std::runtime_error( "Could not insert a new row into the table." );
+      }
+    }
+
+    if ( ! rowInserter1.flushCache() ) {
+      throw std::runtime_error( "Could not flush the remaining rows into the table." );
+    }
+
+    // Committing the transaction
+    std::cout << "Committing..." << std::endl;
+    if ( ! session->transaction().commit() ) {
+      throw std::runtime_error( "Could not commit the transaction." );
+    }
+
+    // Read back some first 255 rows from the table
+    std::cout << "Querying : SELECT * FROM " << tab_name << " LIMIT 255" << std::endl;
+    std::auto_ptr< pool::IRelationalQuery > query1( table1.createQuery() );
+    query1->setRowCacheSize( 5 );
+    query1->limitReturnedRows( 255 );
+    pool::AttributeList emptyBindVariableList;
+    pool::IRelationalCursor& cursor1 = query1->process();
+
+    if ( cursor1.start() )
+    {
+      while( cursor1.next() )
+      {
+        const pool::AttributeList& row = cursor1.currentRow();
+        for ( pool::AttributeList::const_iterator iColumn = row.begin();
+              iColumn != row.end(); ++iColumn )
+        {
+          if( iColumn->spec().type_name() == "unsigned char" )
+          {
+            unsigned char ucval = 0;
+            iColumn->getValue( ucval );
+            std::cout << iColumn->spec().name() << " : " << (unsigned short)ucval  << "\t";            
+          }
+          else
+            std::cout << iColumn->spec().name() << " : " << iColumn->getValueAsString().size() << "\t";
+          
+        }
+        std::cout << std::endl;
+      }
+    }
+
+    std::cout << cursor1.numberOfRows() << " row(s) selected." << std::endl;
+      
+    // Disconnecting
+    std::cout << "Disconnecting..." << std::endl;
+    session->disconnect();
+
+    std::cout << "Exiting..." << std::endl;
+  }
+  catch ( pool::RelationalException& re ) {
+    std::cerr << "Relational exception from module " << re.flavorName() << std::endl
+	      << "    " << re.what() << std::endl;
+    return 1;
+  }
+  catch ( seal::Exception& se ) {
+    std::cerr << "Seal Exception : " << se.what() << std::endl;
+    return 1;
+  }
+  catch ( std::exception& e ) {
+    std::cerr << "Standard C++ exception : " << e.what() << std::endl;
+    return 1;
+  }
+  catch ( ... ) {
+    std::cerr << "Exception caught (...)" << std::endl;
+    return 1;
+  }
+  return 0;
+}
+
+#endif // NOPORT
diff --git a/RelationalCool/tests/MyTest/DO_NOT_DELETE_ME b/RelationalCool/tests/MyTest/DO_NOT_DELETE_ME
new file mode 100644
index 000000000..e69de29bb
diff --git a/RelationalCool/tests/ObjectId/test_ObjectId.cpp b/RelationalCool/tests/ObjectId/test_ObjectId.cpp
new file mode 100644
index 000000000..da4dbd5b7
--- /dev/null
+++ b/RelationalCool/tests/ObjectId/test_ObjectId.cpp
@@ -0,0 +1,306 @@
+// $Id: test_ObjectId.cpp,v 1.11 2006-11-22 12:45:53 marcocle Exp $
+
+// Include files
+#include "CoolUnitTest.h"
+
+// Local include files
+#include "src/ObjectId.h"
+
+//-----------------------------------------------------------------------------
+
+class cool::ObjectIdTest : public cool::CoolUnitTest {
+		
+  CPPUNIT_TEST_SUITE( ObjectIdTest );
+  CPPUNIT_TEST( test_ObjectId1 );
+  CPPUNIT_TEST( test_ObjectId2 );
+  CPPUNIT_TEST( test_ObjectId3 );
+  CPPUNIT_TEST( test_ObjectId4 );
+  CPPUNIT_TEST( test_ObjectId5 );
+  CPPUNIT_TEST( test_ObjectId6 );
+  CPPUNIT_TEST( test_ObjectId7 );
+  CPPUNIT_TEST( test_ObjectId8 );
+  CPPUNIT_TEST( test_ObjectId9 );
+  CPPUNIT_TEST( test_maxId );
+  CPPUNIT_TEST( test_maxId_overflow );
+  CPPUNIT_TEST_SUITE_END();
+  
+public:
+  
+  //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+  void test_ObjectId1() {
+    ObjectId id = 1;
+    CPPUNIT_ASSERT_MESSAGE
+      ( "isUserObject", ObjectIdHandler::isUserObject(id) == true );
+    CPPUNIT_ASSERT_MESSAGE
+      ( "isLSysObject", ObjectIdHandler::isLSysObject(id) == false );
+    CPPUNIT_ASSERT_MESSAGE
+      ( "isRSysObject", ObjectIdHandler::isRSysObject(id) == false );
+    CPPUNIT_ASSERT_MESSAGE
+      ( "userObject", ObjectIdHandler::userObject(id) == 1 );
+    CPPUNIT_ASSERT_MESSAGE
+      ( "lSysObject", ObjectIdHandler::lSysObject(id) == 2 );
+    CPPUNIT_ASSERT_MESSAGE
+      ( "rSysObject", ObjectIdHandler::rSysObject(id) == 3 );
+    CPPUNIT_ASSERT_MESSAGE
+      ( "nextUserObject", ObjectIdHandler::nextUserObject(id) == 7 );
+    try {
+      ObjectIdHandler::prevUserObject(id);
+      CPPUNIT_ASSERT_MESSAGE( "exception expected", false );
+    } catch ( Exception& e ) {
+      std::ostringstream msg;
+      msg << "ObjectId '" << id << "' has no previous user object";
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "exception caught",  msg.str(), std::string( e.what() ) );
+    }
+  }
+
+  //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+  void test_ObjectId2() {
+    ObjectId id = 2;
+    CPPUNIT_ASSERT_MESSAGE
+      ( "isUserObject", ObjectIdHandler::isUserObject(id) == false );
+    CPPUNIT_ASSERT_MESSAGE
+      ( "isLSysObject", ObjectIdHandler::isLSysObject(id) == true );
+    CPPUNIT_ASSERT_MESSAGE
+      ( "isRSysObject", ObjectIdHandler::isRSysObject(id) == false );
+    CPPUNIT_ASSERT_MESSAGE
+      ( "userObject", ObjectIdHandler::userObject(id) == 1 );
+    CPPUNIT_ASSERT_MESSAGE
+      ( "lSysObject", ObjectIdHandler::lSysObject(id) == 2 );
+    CPPUNIT_ASSERT_MESSAGE
+      ( "rSysObject", ObjectIdHandler::rSysObject(id) == 3 );
+    CPPUNIT_ASSERT_MESSAGE
+      ( "nextUserObject", ObjectIdHandler::nextUserObject(id) == 7 );
+    try {
+      ObjectIdHandler::prevUserObject(id);
+      CPPUNIT_ASSERT_MESSAGE( "exception expected", false );
+    } catch ( Exception& e ) {
+      std::ostringstream msg;
+      msg << "ObjectId '" << id << "' has no previous user object";
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "exception caught", std::string( e.what() ), msg.str() );
+    }
+  }
+
+  //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+  void test_ObjectId3() {
+    ObjectId id = 3;
+    CPPUNIT_ASSERT_MESSAGE
+      ( "isUserObject", ObjectIdHandler::isUserObject(id) == false );
+    CPPUNIT_ASSERT_MESSAGE
+      ( "isLSysObject", ObjectIdHandler::isLSysObject(id) == false );
+    CPPUNIT_ASSERT_MESSAGE
+      ( "isRSysObject", ObjectIdHandler::isRSysObject(id) == true );
+    CPPUNIT_ASSERT_MESSAGE
+      ( "userObject", ObjectIdHandler::userObject(id) == 1 );
+    CPPUNIT_ASSERT_MESSAGE
+      ( "lSysObject", ObjectIdHandler::lSysObject(id) == 2 );
+    CPPUNIT_ASSERT_MESSAGE
+      ( "rSysObject", ObjectIdHandler::rSysObject(id) == 3 );
+    CPPUNIT_ASSERT_MESSAGE
+      ( "nextUserObject", ObjectIdHandler::nextUserObject(id) == 7 );
+    try {
+      ObjectIdHandler::prevUserObject(id);
+      CPPUNIT_ASSERT_MESSAGE( "exception expected", false );
+    } catch ( Exception& e ) {
+      std::ostringstream msg;
+      msg << "ObjectId '" << id << "' has no previous user object";
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "exception caught", std::string( e.what() ), msg.str() );
+    }
+  }
+
+  //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+  void test_ObjectId4() {
+    ObjectId id = 4; // this is unused and reserved for user tag related ids
+    CPPUNIT_ASSERT_MESSAGE
+      ( "isUserObject", ObjectIdHandler::isUserObject(id) == false );
+    CPPUNIT_ASSERT_MESSAGE
+      ( "isLSysObject", ObjectIdHandler::isLSysObject(id) == false );
+    CPPUNIT_ASSERT_MESSAGE
+      ( "isRSysObject", ObjectIdHandler::isRSysObject(id) == false );
+    CPPUNIT_ASSERT_MESSAGE
+      ( "userObject", ObjectIdHandler::userObject(id) == 1 );
+    CPPUNIT_ASSERT_MESSAGE
+      ( "lSysObject", ObjectIdHandler::lSysObject(id) == 2 );
+    CPPUNIT_ASSERT_MESSAGE
+      ( "rSysObject", ObjectIdHandler::rSysObject(id) == 3 );
+    CPPUNIT_ASSERT_MESSAGE
+      ( "nextUserObject", ObjectIdHandler::nextUserObject(id) == 7 );
+    try {
+      ObjectIdHandler::prevUserObject(id);
+      CPPUNIT_ASSERT_MESSAGE( "exception expected", false );
+    } catch ( Exception& e ) {
+      std::ostringstream msg;
+      msg << "ObjectId '" << id << "' has no previous user object";
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "exception caught", std::string( e.what() ), msg.str() );
+    }
+  }
+
+  //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+  void test_ObjectId5() {
+    ObjectId id = 5; // this is unused and reserved for user tag related ids
+    CPPUNIT_ASSERT_MESSAGE
+      ( "isUserObject", ObjectIdHandler::isUserObject(id) == false );
+    CPPUNIT_ASSERT_MESSAGE
+      ( "isLSysObject", ObjectIdHandler::isLSysObject(id) == false );
+    CPPUNIT_ASSERT_MESSAGE
+      ( "isRSysObject", ObjectIdHandler::isRSysObject(id) == false );
+    CPPUNIT_ASSERT_MESSAGE
+      ( "userObject", ObjectIdHandler::userObject(id) == 1 );
+    CPPUNIT_ASSERT_MESSAGE
+      ( "lSysObject", ObjectIdHandler::lSysObject(id) == 2 );
+    CPPUNIT_ASSERT_MESSAGE
+      ( "rSysObject", ObjectIdHandler::rSysObject(id) == 3 );
+    CPPUNIT_ASSERT_MESSAGE
+      ( "nextUserObject", ObjectIdHandler::nextUserObject(id) == 7 );
+    try {
+      ObjectIdHandler::prevUserObject(id);
+      CPPUNIT_ASSERT_MESSAGE( "exception expected", false );
+    } catch ( Exception& e ) {
+      std::ostringstream msg;
+      msg << "ObjectId '" << id << "' has no previous user object";
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "exception caught", std::string( e.what() ), msg.str() );
+    }
+  }
+
+  //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+  void test_ObjectId6() {
+    ObjectId id = 6; // this is unused and reserved for user tag related ids
+    CPPUNIT_ASSERT_MESSAGE
+      ( "isUserObject", ObjectIdHandler::isUserObject(id) == false );
+    CPPUNIT_ASSERT_MESSAGE
+      ( "isLSysObject", ObjectIdHandler::isLSysObject(id) == false );
+    CPPUNIT_ASSERT_MESSAGE
+      ( "isRSysObject", ObjectIdHandler::isRSysObject(id) == false );
+    CPPUNIT_ASSERT_MESSAGE
+      ( "userObject", ObjectIdHandler::userObject(id) == 1 );
+    CPPUNIT_ASSERT_MESSAGE
+      ( "lSysObject", ObjectIdHandler::lSysObject(id) == 2 );
+    CPPUNIT_ASSERT_MESSAGE
+      ( "rSysObject", ObjectIdHandler::rSysObject(id) == 3 );
+    CPPUNIT_ASSERT_MESSAGE
+      ( "nextUserObject", ObjectIdHandler::nextUserObject(id) == 7 );
+    try {
+      ObjectIdHandler::prevUserObject(id);
+      CPPUNIT_ASSERT_MESSAGE( "exception expected", false );
+    } catch ( Exception& e ) {
+      std::ostringstream msg;
+      msg << "ObjectId '" << id << "' has no previous user object";
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "exception caught", std::string( e.what() ), msg.str() );
+    }
+  }
+
+  //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+  
+  void test_ObjectId7() {
+    ObjectId id = 7;
+    CPPUNIT_ASSERT_MESSAGE
+      ( "isUserObject", ObjectIdHandler::isUserObject(id) == true );
+    CPPUNIT_ASSERT_MESSAGE
+      ( "isLSysObject", ObjectIdHandler::isLSysObject(id) == false );
+    CPPUNIT_ASSERT_MESSAGE
+      ( "isRSysObject", ObjectIdHandler::isRSysObject(id) == false );
+    CPPUNIT_ASSERT_MESSAGE
+      ( "userObject", ObjectIdHandler::userObject(id) == 7 );
+    CPPUNIT_ASSERT_MESSAGE
+      ( "lSysObject", ObjectIdHandler::lSysObject(id) == 8 );
+    CPPUNIT_ASSERT_MESSAGE
+      ( "rSysObject", ObjectIdHandler::rSysObject(id) == 9 );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE
+      ( "nextUserObject", 13u, ObjectIdHandler::nextUserObject(id) );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE
+      ( "prevUserObject", 1u, ObjectIdHandler::prevUserObject(id) );
+  }
+  
+  //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+  
+  void test_ObjectId8() {
+    ObjectId id = 8;
+    CPPUNIT_ASSERT_MESSAGE
+      ( "isUserObject", ObjectIdHandler::isUserObject(id) == false );
+    CPPUNIT_ASSERT_MESSAGE
+      ( "isLSysObject", ObjectIdHandler::isLSysObject(id) == true );
+    CPPUNIT_ASSERT_MESSAGE
+      ( "isRSysObject", ObjectIdHandler::isRSysObject(id) == false );
+    CPPUNIT_ASSERT_MESSAGE
+      ( "userObject", ObjectIdHandler::userObject(id) == 7 );
+    CPPUNIT_ASSERT_MESSAGE
+      ( "lSysObject", ObjectIdHandler::lSysObject(id) == 8 );
+    CPPUNIT_ASSERT_MESSAGE
+      ( "rSysObject", ObjectIdHandler::rSysObject(id) == 9 );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE
+      ( "nextUserObject", 13u, ObjectIdHandler::nextUserObject(id) );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE
+      ( "prevUserObject", 1u, ObjectIdHandler::prevUserObject(id) );
+  }
+  
+  //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+  
+  void test_ObjectId9() {
+    ObjectId id = 9;
+    CPPUNIT_ASSERT_MESSAGE
+      ( "isUserObject", ObjectIdHandler::isUserObject(id) == false );
+    CPPUNIT_ASSERT_MESSAGE
+      ( "isLSysObject", ObjectIdHandler::isLSysObject(id) == false );
+    CPPUNIT_ASSERT_MESSAGE
+      ( "isRSysObject", ObjectIdHandler::isRSysObject(id) == true );
+    CPPUNIT_ASSERT_MESSAGE
+      ( "userObject", ObjectIdHandler::userObject(id) == 7 );
+    CPPUNIT_ASSERT_MESSAGE
+      ( "lSysObject", ObjectIdHandler::lSysObject(id) == 8 );
+    CPPUNIT_ASSERT_MESSAGE
+      ( "rSysObject", ObjectIdHandler::rSysObject(id) == 9 );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE
+      ( "nextUserObject", 13u, ObjectIdHandler::nextUserObject(id) );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE
+      ( "prevUserObject", 1u, ObjectIdHandler::prevUserObject(id) );
+  }
+  
+  //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+  
+  void test_maxId() {
+    ObjectId id = UINT_MAX; // == 4294967295
+    CPPUNIT_ASSERT_MESSAGE
+      ( "isUserObject", ObjectIdHandler::isUserObject(id) == false );
+    CPPUNIT_ASSERT_MESSAGE
+      ( "isLSysObject", ObjectIdHandler::isLSysObject(id) == false );
+    CPPUNIT_ASSERT_MESSAGE
+      ( "isRSysObject", ObjectIdHandler::isRSysObject(id) == true );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE
+      ( "userObject", 4294967293u, ObjectIdHandler::userObject(id) );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE
+      ( "lSysObject", 4294967294u, ObjectIdHandler::lSysObject(id) );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE
+      ( "rSysObject", 4294967295u, ObjectIdHandler::rSysObject(id) );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE
+      ( "prevUserObject", 4294967287u, ObjectIdHandler::prevUserObject(id) );
+  }
+  
+  //++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+  
+  
+  void test_maxId_overflow() {
+    ObjectId id = UINT_MAX;
+    CPPUNIT_ASSERT_THROW(ObjectIdHandler::nextUserObject(id) , ObjectIdException);
+  }
+  
+};
+
+CPPUNIT_TEST_SUITE_REGISTRATION( cool::ObjectIdTest );
+
+//-----------------------------------------------------------------------------
+
+COOLTEST_MAIN(ObjectIdTest)
+
+
diff --git a/RelationalCool/tests/PayloadSpecification/test_PayloadSpecification.cpp b/RelationalCool/tests/PayloadSpecification/test_PayloadSpecification.cpp
new file mode 100644
index 000000000..e56388843
--- /dev/null
+++ b/RelationalCool/tests/PayloadSpecification/test_PayloadSpecification.cpp
@@ -0,0 +1,474 @@
+// $Id: test_PayloadSpecification.cpp,v 1.13 2006-12-14 12:04:46 avalassi Exp $
+#include "CoolUnitTest.h"
+
+// Include files 
+#include "CoralBase/Attribute.h" 
+#include "CoolKernel/Record.h"
+#include "CoolKernel/RecordException.h"
+#include "CoolKernel/RecordSpecification.h"
+#include "../../src/RelationalDatabase.h"
+#include "../../src/RelationalException.h"
+#include "../../src/RelationalQueryMgr.h"
+
+namespace cool {
+
+  class PayloadSpecificationTest : public CoolUnitTest {
+    
+    CPPUNIT_TEST_SUITE( PayloadSpecificationTest );
+
+    CPPUNIT_TEST( test_extend );
+    CPPUNIT_TEST( test_cannot_extend );
+
+    CPPUNIT_TEST( test_copy_constructor );
+
+    CPPUNIT_TEST( test_sum );
+
+    CPPUNIT_TEST( test_size );
+    CPPUNIT_TEST( test_empty );
+
+    CPPUNIT_TEST( test_extend_AL );
+    CPPUNIT_TEST( test_create_AL );
+
+    CPPUNIT_TEST( test_check_AL );
+    CPPUNIT_TEST( test_check_AL_bad_size );
+    CPPUNIT_TEST( test_check_AL_bad_string_size );
+    CPPUNIT_TEST( test_check_AL_good_string_size );
+    CPPUNIT_TEST( test_check_AL_bad_UInt63 );
+    CPPUNIT_TEST( test_check_AL_good_UInt63 );
+    CPPUNIT_TEST( test_check_AL_unexpected_type );
+    
+    // Tests coming from RelationalDatabase tests
+    CPPUNIT_TEST( test_encode_decode );
+    CPPUNIT_TEST( test_decodeEmptySpec );
+    CPPUNIT_TEST( test_decodeNoColon );
+    CPPUNIT_TEST( test_decodeTrailingComma );
+
+    CPPUNIT_TEST_SUITE_END();
+		
+  public:
+    
+    void setUp() {
+      /// prepare for the test
+    }
+
+    void tearDown(){
+      /// clean up after the test
+    }
+
+    // ------------------------------------------------------
+    // The tests
+    // ------------------------------------------------------
+
+    // ------------------------------------------------------
+    void test_extend() {
+    // ------------------------------------------------------
+      // -- allowed macros
+      // CPPUNIT_ASSERT(condition)
+      // CPPUNIT_ASSERT_MESSAGE(message,condition)
+      // CPPUNIT_ASSERT_EQUAL(expected,actual)
+      // CPPUNIT_ASSERT_EQUAL_MESSAGE(message,expected,actual)
+      // CPPUNIT_ASSERT_DOUBLES_EQUAL(expected,actual,delta)
+      // CPPUNIT_ASSERT_THROW( expression, ExceptionType )
+      // CPPUNIT_ASSERT_NO_THROW( expression )
+
+      // Test the signatures of the RecordSpecification::extend method
+      RecordSpecification pls;
+      
+      // void extend( const std::string&, const StorageType::TypeId );
+      pls.extend( "I", cool::StorageType::Int32 );
+            
+      // void extend( const std::string&, const StorageType& );
+      pls.extend
+        ( "X", cool::StorageType::storageType( cool::StorageType::Float ) );
+
+      // void extend( const IFieldSpecification& );
+      RecordSpecification tmp_pls1;
+      tmp_pls1.extend( "S255", cool::StorageType::String255 );
+      pls.extend( tmp_pls1["S255"] );
+
+      // void extend( const IRecordSpecification& );
+      RecordSpecification tmp_pls2;
+      tmp_pls2.extend( "A", cool::StorageType::UInt32 );
+      tmp_pls2.extend( "B", cool::StorageType::String4k );
+      pls.extend( tmp_pls2 );
+
+      // Check that the final specification is as expected
+      CPPUNIT_ASSERT_MESSAGE
+        ("RecordSpec::extend(const std::string&, StorageType::TypeId) failed",
+         pls["I"].storageType() == cool::StorageType::Int32);
+      CPPUNIT_ASSERT_MESSAGE
+        ("RecordSpec::extend(const std::string&, const StorageType&) failed",
+         pls["X"].storageType() == cool::StorageType::Float);
+      CPPUNIT_ASSERT_MESSAGE
+        ("RecordSpec::extend(const IFieldSpecification&) failed",
+         pls["S255"].storageType() == cool::StorageType::String255);
+      
+      CPPUNIT_ASSERT_MESSAGE
+        ("RecordSpec::extend(const IRecordSpecification&)failed",
+         (pls["A"].storageType() == cool::StorageType::UInt32) &&
+         (pls["B"].storageType() == cool::StorageType::String4k));
+      
+    }
+    
+    // ------------------------------------------------------
+    void test_cannot_extend() {
+    // ------------------------------------------------------
+      RecordSpecification pls;
+      
+      pls.extend( "A", cool::StorageType::UInt32 );
+      pls.extend( "B", cool::StorageType::String4k );
+
+      CPPUNIT_ASSERT_THROW
+        ( pls.extend( "A", cool::StorageType::String255 ),
+          RecordSpecificationCannotExtend );
+
+    }
+    
+    // ------------------------------------------------------
+    void test_copy_constructor() {
+    // ------------------------------------------------------
+      RecordSpecification pls;
+      
+      pls.extend( "A", cool::StorageType::UInt32 );
+      pls.extend( "B", cool::StorageType::String4k );
+
+      RecordSpecification pls2(pls);
+      
+      CPPUNIT_ASSERT_MESSAGE
+        ("RecordSpec::extend(const IRecordSpecification&) failed",
+         (pls2["A"].storageType() == cool::StorageType::UInt32) &&
+         (pls2["B"].storageType() == cool::StorageType::String4k));
+      
+    }
+    
+    // ------------------------------------------------------
+    void test_sum() {
+    // ------------------------------------------------------
+      RecordSpecification pls1;
+      
+      pls1.extend( "A", cool::StorageType::UInt32 );
+      pls1.extend( "B", cool::StorageType::String4k );
+
+      RecordSpecification pls2;
+      
+      pls2.extend( "C", cool::StorageType::Float );
+      pls2.extend( "D", cool::StorageType::Double );
+
+      RecordSpecification pls = pls1;
+      pls.extend( pls2 );
+      
+      CPPUNIT_ASSERT_MESSAGE
+        ("RecordSpec::extend(const IRecordSpecification&) failed",
+         (pls["A"].storageType() == cool::StorageType::UInt32) &&
+         (pls["B"].storageType() == cool::StorageType::String4k) &&
+         (pls["C"].storageType() == cool::StorageType::Float) &&
+         (pls["D"].storageType() == cool::StorageType::Double));
+      
+    }
+    
+    // ------------------------------------------------------
+    void test_size() {
+    // ------------------------------------------------------
+      RecordSpecification pls;
+      
+      CPPUNIT_ASSERT_EQUAL((UInt32)0,pls.size());
+      
+      pls.extend( "A", cool::StorageType::UInt32 );
+
+      CPPUNIT_ASSERT_EQUAL((UInt32)1,pls.size());
+       
+      pls.extend( "B", cool::StorageType::String4k );
+     
+      CPPUNIT_ASSERT_EQUAL((UInt32)2,pls.size());
+    }
+
+    // ------------------------------------------------------
+    void test_empty() {
+    // ------------------------------------------------------
+      RecordSpecification pls;
+
+      CPPUNIT_ASSERT(pls.size()==0);
+      
+      pls.extend( "TEST", cool::StorageType::Double );
+      
+      CPPUNIT_ASSERT(pls.size()!=0);
+    }
+
+    // ------------------------------------------------------
+    void test_extend_AL() {
+    // ------------------------------------------------------
+      RecordSpecification pls;
+      
+      pls.extend( "A", cool::StorageType::UInt32 );
+      pls.extend( "B", cool::StorageType::String4k );
+
+      coral::AttributeList al = Record( pls ).attributeList();
+      
+      CPPUNIT_ASSERT_MESSAGE
+        ("Test_extend_AL failed",
+         (al["A"].specification().type() == 
+          typeIdToCoralType(cool::StorageType::UInt32)) &&
+         (al["B"].specification().type() == 
+          typeIdToCoralType(cool::StorageType::String4k)));
+    }
+    
+    // ------------------------------------------------------
+    void test_create_AL() {
+    // ------------------------------------------------------
+      RecordSpecification pls;
+      
+      pls.extend( "A", cool::StorageType::UInt32 );
+      pls.extend( "B", cool::StorageType::String4k );
+
+      coral::AttributeList al = Record( pls ).attributeList();
+      
+      CPPUNIT_ASSERT_MESSAGE
+        ("Test_create_AL failed",
+         (al["A"].specification().type() == 
+          typeIdToCoralType(cool::StorageType::UInt32)) &&
+         (al["B"].specification().type() == 
+          typeIdToCoralType(cool::StorageType::String4k)));
+    }
+
+    // ------------------------------------------------------
+    void test_check_AL() {
+    // ------------------------------------------------------
+      std::vector<StorageType::TypeId> all_types;
+
+      all_types.push_back(StorageType::Bool);
+      //all_types.push_back(StorageType::Char);
+      all_types.push_back(StorageType::UChar);
+      all_types.push_back(StorageType::Int16);
+      all_types.push_back(StorageType::UInt16);
+      all_types.push_back(StorageType::Int32);
+      all_types.push_back(StorageType::UInt32);
+      all_types.push_back(StorageType::UInt63);
+      all_types.push_back(StorageType::Int64);
+      //all_types.push_back(StorageType::UInt64);
+      all_types.push_back(StorageType::Float);
+      all_types.push_back(StorageType::Double);
+      all_types.push_back(StorageType::String255);
+      all_types.push_back(StorageType::String4k);
+      all_types.push_back(StorageType::String64k);
+      all_types.push_back(StorageType::String16M);      
+ 
+      RecordSpecification pls;
+      std::vector<StorageType::TypeId>::iterator i;
+      for(i = all_types.begin(); i != all_types.end(); ++i ){
+        pls.extend( StorageType::storageType(*i).name(),*i);
+      }
+
+      coral::AttributeList al = Record( pls ).attributeList();
+
+      CPPUNIT_ASSERT_NO_THROW(pls.validate(al));
+    }
+    
+    // ------------------------------------------------------
+    void test_check_AL_bad_size() {
+    // ------------------------------------------------------
+
+      std::vector<StorageType::TypeId> all_types;
+      all_types.push_back(StorageType::Int32);
+      all_types.push_back(StorageType::UInt32);
+      all_types.push_back(StorageType::UInt63);
+      all_types.push_back(StorageType::Float);      
+
+      RecordSpecification pls;
+      std::vector<StorageType::TypeId>::iterator i;
+      for(i = all_types.begin(); i != all_types.end(); ++i )
+        pls.extend(StorageType::storageType(*i).name(),*i);
+        
+      coral::AttributeList al = Record( pls ).attributeList();
+      al.extend("AnotherOne","double");
+      
+      CPPUNIT_ASSERT_THROW(pls.validate(al),
+                           RecordSpecificationWrongSize);
+
+    }
+    
+    // ------------------------------------------------------
+    void test_check_AL_bad_string_size() {
+    // ------------------------------------------------------
+
+      std::vector<StorageType::TypeId> all_types;
+      all_types.push_back(StorageType::String255);
+      all_types.push_back(StorageType::String4k);
+      all_types.push_back(StorageType::String64k);
+      all_types.push_back(StorageType::String16M);      
+
+      std::vector<StorageType::TypeId>::iterator i;
+      for(i = all_types.begin(); i != all_types.end(); ++i ){
+
+        RecordSpecification pls;
+
+        pls.extend("S",*i);
+        
+        coral::AttributeList al = Record( pls ).attributeList();
+
+        al["S"].data<std::string>().append
+          (StorageType::storageType(*i).maxSize()+1,'x');
+        
+        CPPUNIT_ASSERT_THROW(pls.validate(al),
+                             StorageTypeInvalidValue);
+        
+      }
+    }
+    
+    // ------------------------------------------------------
+    void test_check_AL_good_string_size() {
+    // ------------------------------------------------------
+
+      std::vector<StorageType::TypeId> all_types;
+      all_types.push_back(StorageType::String255);
+      all_types.push_back(StorageType::String4k);
+      all_types.push_back(StorageType::String64k);
+      all_types.push_back(StorageType::String16M);      
+
+      std::vector<StorageType::TypeId>::iterator i;
+      for(i = all_types.begin(); i != all_types.end(); ++i ){
+
+        RecordSpecification pls;
+
+        pls.extend("S",*i);
+        
+        coral::AttributeList al = Record( pls ).attributeList();
+
+        al["S"].data<std::string>()
+          .append(StorageType::storageType(*i).maxSize(),'x');
+        
+        CPPUNIT_ASSERT_NO_THROW(pls.validate(al));
+        
+      }
+      
+    }
+
+    // ------------------------------------------------------
+    void test_check_AL_bad_UInt63() {
+    // ------------------------------------------------------
+      RecordSpecification pls;
+      pls.extend("I", StorageType::UInt63);
+      
+      coral::AttributeList al = Record( pls ).attributeList();
+ 
+      al["I"].data<UInt63>() = 9223372036854775808ULL;
+
+      CPPUNIT_ASSERT_THROW(pls.validate(al),
+                           StorageTypeInvalidValue);
+
+    }
+    
+    // ------------------------------------------------------
+    void test_check_AL_good_UInt63() {
+    // ------------------------------------------------------
+      RecordSpecification pls;
+      pls.extend("I", StorageType::UInt63);
+      
+      coral::AttributeList al = Record( pls ).attributeList();
+
+      al["I"].data<UInt63>() = 9223372036854775807ULL;
+
+      CPPUNIT_ASSERT_NO_THROW(pls.validate(al));
+      
+    }
+    
+    // ------------------------------------------------------
+    void test_check_AL_unexpected_type() {
+    // ------------------------------------------------------
+      RecordSpecification pls;
+      pls.extend( "A", cool::StorageType::UInt32 );
+      pls.extend( "B", cool::StorageType::String4k );
+
+      coral::AttributeList al;
+      al.extend<cool::UInt32>("A");
+      al.extend<float>("B");
+      
+      CPPUNIT_ASSERT_THROW(pls.validate(al),
+                           StorageTypeWrongCppType);
+        
+    }
+    
+
+    // ------------------------------------------------------
+    void test_encode_decode() {
+    // ------------------------------------------------------
+      typedef std::pair<std::string,StorageType::TypeId> pair_type;
+      std::vector<pair_type> all_types;
+      
+      all_types.push_back(pair_type("Bool",StorageType::Bool));
+      //all_types.push_back(pair_type("Char",StorageType::Char));
+      all_types.push_back(pair_type("UChar",StorageType::UChar));
+      all_types.push_back(pair_type("Int16",StorageType::Int16));
+      all_types.push_back(pair_type("UInt16",StorageType::UInt16));
+      all_types.push_back(pair_type("Int32",StorageType::Int32));
+      all_types.push_back(pair_type("UInt32",StorageType::UInt32));
+      all_types.push_back(pair_type("UInt63",StorageType::UInt63));
+      all_types.push_back(pair_type("Int64",StorageType::Int64));
+      //all_types.push_back(pair_type("UInt64",StorageType::UInt64));
+      all_types.push_back(pair_type("Float",StorageType::Float));
+      all_types.push_back(pair_type("Double",StorageType::Double));
+      all_types.push_back(pair_type("String255",StorageType::String255));
+      all_types.push_back(pair_type("String4k",StorageType::String4k));
+      all_types.push_back(pair_type("String64k",StorageType::String64k));
+      all_types.push_back(pair_type("String16M",StorageType::String16M));
+  
+      RecordSpecification pls;
+      std::ostringstream expected;
+      
+      std::vector<pair_type>::iterator i;
+      for(i = all_types.begin(); i != all_types.end(); ++i ){
+        pls.extend(i->first,i->second);
+        if (i != all_types.begin()) expected << ",";
+        expected << i->first << ":" 
+                 << StorageType::storageType(i->second).name();
+      }
+
+      CPPUNIT_ASSERT_EQUAL
+        ( expected.str(), RelationalDatabase::encodeRecordSpecification(pls) );
+
+      std::string pls2 =
+        RelationalDatabase::encodeRecordSpecification(pls);
+
+      CPPUNIT_ASSERT_MESSAGE
+        ("encoded and decoded payloads do not match", 
+         pls == RelationalDatabase::decodeRecordSpecification(pls2));
+
+    }
+
+    // ------------------------------------------------------
+    void test_decodeEmptySpec() {
+    // ------------------------------------------------------
+    
+      std::string encodedSpec = "";
+      RecordSpecification spec =
+        RelationalDatabase::decodeRecordSpecification(encodedSpec);
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+      ( std::string( "RecordSpecification size" ), 
+        (UInt32)0,spec.size() );
+    }
+
+    // Tests exception in decoding spec with no ":" colon
+    // (missing type - "name" instead of "name:type")
+    // ------------------------------------------------------
+    void test_decodeNoColon() {
+    // ------------------------------------------------------
+      CPPUNIT_ASSERT_THROW
+        ( RelationalDatabase::decodeRecordSpecification("I/Int32"),
+          RelationalException );
+    }
+    
+    
+    // ------------------------------------------------------
+    void test_decodeTrailingComma() {
+    // ------------------------------------------------------
+      CPPUNIT_ASSERT_THROW
+        ( RelationalDatabase::decodeRecordSpecification("I:Int32,"),
+          RelationalException );
+    }
+    
+  };
+
+CPPUNIT_TEST_SUITE_REGISTRATION( PayloadSpecificationTest );
+  
+}
+
+COOLTEST_MAIN( PayloadSpecificationTest )
diff --git a/RelationalCool/tests/Performance/Benchmark.h b/RelationalCool/tests/Performance/Benchmark.h
new file mode 100644
index 000000000..6f69b71cd
--- /dev/null
+++ b/RelationalCool/tests/Performance/Benchmark.h
@@ -0,0 +1,52 @@
+/**
+ @file Benchmark.h 
+ 
+ @author Sven A. Schmidt
+ 
+ @date 2004-08-19
+*/
+
+
+#ifndef BENCHMARK_H
+#define BENCHMARK_H
+
+//#include <sys/time.h>
+#include "boost/timer.hpp"
+
+#include <iostream>
+
+/// Utility class to benchmark code
+///
+/// The current implementation has a resolution of seconds and measures
+/// elapsed real time.
+class Benchmark {
+  boost::timer m_timer;
+public:
+  
+  /// Starts the timer
+  void start() {
+    m_timer.restart();
+  }
+  
+  /// Stops the timer and returns the number of seconds since the timer
+  /// was started
+  double stop() {
+    return elapsed();
+  }
+  
+  /// Returns the number of seconds since the timer was started
+  double elapsed() {
+    return m_timer.elapsed();
+  }
+  
+};
+
+/*
+inline ostream &operator<<( ostream &s, Benchmark &b ) {
+  s << "elapsed: " << b.elapsed() << " seconds";
+  return s;
+}
+*/
+
+#endif
+
diff --git a/RelationalCool/tests/Performance/performance_test.txt b/RelationalCool/tests/Performance/performance_test.txt
new file mode 100644
index 000000000..2727fd3dc
--- /dev/null
+++ b/RelationalCool/tests/Performance/performance_test.txt
@@ -0,0 +1,67 @@
+These are 'ballpark' figures. The benchmark measures real time, therefore the
+tests are subject to additional load on the machine. They skew by
+several seconds even under the same conditions on the same machine. Only use
+these to monitor performance evolution, not for performance comparison.
+
+------------------------------------------------------------------------
+
+2005-01-04, Powerbook sas (G4 1.5 GHz, 1GB RAM, Oracle 10 prerelease, -g)
+
+** writing 10k objects (150 bytes mixed) **
+sec total: 15
+obj/s:     666.667
+** reading 25k objects (150 bytes mixed) **
+read back 10000 objects
+sec total: 26
+obj/s:     384.615
+
+** writing 25k objects (20 floats) **
+wrote 25000 objects
+sec total: 45
+obj/s:     555.556
+** reading 25k objects (20 floats) **
+read back 25000 objects
+sec total: 85
+obj/s:     294.118
+
+------------------------------------------------------------------------
+
+2005-01-04, Powermac sas (G5 2GHz, 1GB RAM, Oracle 10 prerelease, -g)
+
+** writing 10k objects (150 bytes mixed) **
+sec total: 14
+obj/s:     714.286
+** reading 25k objects (150 bytes mixed) **
+read back 10000 objects
+sec total: 20
+obj/s:     500
+
+** writing 25k objects (20 floats) **
+wrote 25000 objects
+sec total: 33
+obj/s:     757.576
+** reading 25k objects (20 floats) **
+read back 25000 objects
+sec total: 63
+obj/s:     396.825
+
+------------------------------------------------------------------------
+
+2005-01-08, Powermac sas (G5 2GHz, 1GB RAM, Oracle 10 Production, -g)
+
+** writing 10k objects (150 bytes mixed) **
+sec total: 10
+obj/s:     1000
+** reading 25k objects (150 bytes mixed) **
+read back 10000 objects
+sec total: 19
+obj/s:     526.316
+
+** writing 25k objects (20 floats) **
+wrote 25000 objects
+sec total: 32
+obj/s:     781.25
+** reading 25k objects (20 floats) **
+read back 25000 objects
+sec total: 61
+obj/s:     409.836
diff --git a/RelationalCool/tests/Performance/test_Performance.cpp b/RelationalCool/tests/Performance/test_Performance.cpp
new file mode 100644
index 000000000..281b7262e
--- /dev/null
+++ b/RelationalCool/tests/Performance/test_Performance.cpp
@@ -0,0 +1,998 @@
+// PORT -- temporarily disabled: not part of our official test suite
+int main() { return 0; }
+#ifdef NOPORT
+/**
+
+@file test_Performance.cpp
+
+@author Sven A. Schmidt
+
+@date 2005-01-03
+
+*/
+
+
+#include<cppunit/extensions/HelperMacros.h>
+
+#include "CoolKernel/IFolder.h"
+#include "CoolKernel/IObject.h"
+#include "CoolKernel/IObjectIterator.h"
+#include "CoolKernel/IDatabaseSvc.h"
+#include "CoolKernel/Exception.h"
+
+#include "Benchmark.h"
+
+#include "src/CoralApplication.h"
+#include "src/ProcMemory.h"
+
+#include "AttributeList/AttributeValueAccessor.h"
+using coral::AttributeList;
+using coral::AttributeListSpecification;
+typedef boost::shared_ptr<AttributeListSpecification> SpecPtr;
+
+// include for 'sleep' (ORA-01466 workaround)
+#include "src/sleep.h"
+
+#include <string>
+using std::cout;
+using std::endl;
+using std::string;
+using std::stringstream;
+
+#include <vector>
+using std::vector;
+
+namespace cool {
+
+const char* COOLTESTDB = "COOLTESTDB";
+
+// set this to true to have a quick run through all tests
+// tests should initialize their iteration count like this:
+//    long iterations = quick ? 1 : 10000;
+const bool quick = true;
+
+// uncomment this to enable memory profiling
+//#define MEMTEST
+
+
+/// Performace test class
+class PerformanceTest : public CppUnit::TestFixture {
+		
+  CPPUNIT_TEST_SUITE( PerformanceTest );
+
+  CPPUNIT_TEST( test_bulk_rw_mixed );
+  CPPUNIT_TEST( test_bulk_rw_mixed_MV );
+  CPPUNIT_TEST( test_bulk_rw_mixed_MV_withHEAD );
+
+  CPPUNIT_TEST( test_bulk_w_mixed_multichannel );
+  CPPUNIT_TEST( test_bulk_w_mixed_multichannel_update );
+  CPPUNIT_TEST( test_bulk_w_mixed_multichannel_old );
+
+  CPPUNIT_TEST( test_bulk_rw_float_1 );
+  CPPUNIT_TEST( test_bulk_rw_float_20 );
+  CPPUNIT_TEST( test_bulk_rw_float_100 );
+  CPPUNIT_TEST( test_bulk_rw_float_200 );
+
+  CPPUNIT_TEST( test_bulk_rw_string4kb_1 );
+  CPPUNIT_TEST( test_bulk_rw_string4kb_100 );
+  CPPUNIT_TEST( test_bulk_rw_string4kb_200 );
+
+  CPPUNIT_TEST( test_boost_shared_ptr );
+  CPPUNIT_TEST( test_boost_shared_ptr_2 );  
+  
+  CPPUNIT_TEST_SUITE_END();
+		
+public:
+    
+  AttributeListSpecification mixedPayloadSpec;
+  string connectString;
+  IDatabasePtr db;
+  
+  /// Tests boost::shared_ptr performance
+  void test_boost_shared_ptr_2() {
+    int nObjs = quick ? 1 : 1000 * 1000;
+    
+    cout << "\ntest_boost_shared_ptr_2" << endl;
+    
+    cout << "\nsingle object, referenced " << nObjs << " times" << endl;
+    
+    {
+      SpecPtr spec( new coral::AttributeListSpecification() );
+      
+      Benchmark b, b_delete;
+      b.start();
+      {
+        vector<SpecPtr> specs;
+        for ( int i = 0; i < nObjs; ++i ) {
+          specs.push_back( spec );
+        }
+        b_delete.start();
+      }
+      cout << "boost vector:  " << b.stop() << endl;
+      cout << "      delete:  " << b_delete.stop() << endl;
+    }
+    
+    {
+      coral::AttributeListSpecification* spec 
+        = new coral::AttributeListSpecification();
+      
+      Benchmark b, b_delete;
+      b.start();
+      {
+        vector<coral::AttributeListSpecification*> specs;
+        for ( int i = 0; i < nObjs; ++i ) {
+          specs.push_back( spec );
+        }
+        b_delete.start();
+      }
+      cout << "bare pointers: " << b.stop() << endl;
+      cout << "       delete: " << b_delete.stop() << endl;
+      
+      delete spec;
+    }
+    
+    cout << "\n" << nObjs << " individual objects" << endl;
+
+    {
+      Benchmark b, b_delete;
+      b.start();
+      {
+        vector<SpecPtr> specs;
+        for ( int i = 0; i < nObjs; ++i ) {
+          SpecPtr spec( new coral::AttributeListSpecification() );
+          specs.push_back( spec );
+        }
+        b_delete.start();
+      }
+      cout << "boost vector:  " << b.stop() << endl;
+      cout << "      delete:  " << b_delete.stop() << endl;
+    }
+    
+    {
+      Benchmark b, b_delete;
+      b.start();
+      {
+        vector<coral::AttributeListSpecification*> specs;
+        for ( int i = 0; i < nObjs; ++i ) {
+          coral::AttributeListSpecification* spec 
+          = new coral::AttributeListSpecification();
+          
+          specs.push_back( spec );
+        }
+        b_delete.start();
+        for ( vector<coral::AttributeListSpecification*>::iterator 
+              spec = specs.begin();
+              spec != specs.end();
+              ++spec ) {
+          delete *spec;
+        }
+      }
+      cout << "bare pointers: " << b.stop() << endl;
+      cout << "       delete: " << b_delete.stop() << endl;
+    }
+    
+    
+  }
+  
+  
+  //----------------------------------------------------------------------------
+  
+  boost::shared_ptr<coral::AttributeList>
+    copyAttributeList( const coral::AttributeList& list ) 
+  {
+      
+      // Instantiate a new AttributeListSpecification by performing
+      // a deep copy of the individual Attribute specifications
+      const coral::AttributeListSpecification& 
+      spec = list.attributeListSpecification();  
+      boost::shared_ptr<coral::AttributeListSpecification> 
+      newSpec( new coral::AttributeListSpecification() );
+      coral::AttributeListSpecification::const_iterator itSpec;
+      for ( itSpec = spec.begin(); itSpec != spec.end(); ++itSpec ) {
+        newSpec->push_back( itSpec->name(), itSpec->type_name() );
+      }
+      
+      // Instantiate a new AttributeList owning the new specification
+      // Copy the individual Attribute values into the new List
+      return copyAttributeList( list, newSpec );  
+      
+  }
+  
+  //----------------------------------------------------------------------------
+  
+  boost::shared_ptr<coral::AttributeList> copyAttributeList
+    ( const coral::AttributeList& oldList,
+      boost::shared_ptr<coral::AttributeListSpecification>& specPtr ) 
+  {
+      // Instantiate a new AttributeList owning the specification
+      boost::shared_ptr<coral::AttributeList> 
+      newList( new coral::AttributeList( specPtr ) );
+      
+      coral::AttributeList::const_iterator oldAttr;
+      coral::AttributeList::iterator newAttr = newList->begin();
+      for ( oldAttr = oldList.begin(); 
+            oldAttr != oldList.end(); 
+            oldAttr++, newAttr++ ) {
+        coral::AttributeValueAccessor( *newAttr ).setValueFromData
+        ( coral::AttributeValueAccessor( *oldAttr ).getMemoryAddress() );
+      }
+      
+      return newList;
+      
+  }
+  
+  //----------------------------------------------------------------------------
+  
+  
+  void test_boost_shared_ptr() {
+    cout << "\ntest_boost_shared_ptr_2" << endl;
+
+    int * i;
+    cout << "size of *int:                                                "
+      << sizeof(i) << endl;
+    
+    cout << "size of boost::shared_ptr<coral::AttributeList>:              "
+      << sizeof(boost::shared_ptr<coral::AttributeList>) << endl;
+    
+    cout << "size of boost::shared_ptr<coral::AttributeListSpecification>: "
+      << sizeof(boost::shared_ptr<coral::AttributeListSpecification>) << endl;
+    
+    cout << "size of coral::AttributeList:                                 "
+      << sizeof(coral::AttributeList) << endl;
+    
+    cout << "size of coral::AttributeListSpecification:                    "
+      << sizeof(coral::AttributeListSpecification) << endl;
+  
+
+    int nRows = quick ? 1 : 10 * 1000;
+
+    Benchmark b1, b1_delete;
+    b1.start();
+    {
+      // copy mixedPayloadSpec to a shared_ptr
+      boost::shared_ptr<coral::AttributeListSpecification> 
+      spec( new coral::AttributeListSpecification() );
+      for ( coral::AttributeListSpecification::const_iterator 
+            i = mixedPayloadSpec.begin(); 
+            i != mixedPayloadSpec.end(); 
+            ++i ) {
+        spec->push_back( i->name(), i->type_name() );
+      }  
+      
+      std::vector< boost::shared_ptr<coral::AttributeList> > objs;
+      for ( int i = 0; i < nRows; ++i ) {
+        coral::AttributeList payload( mixedPayload( i ) );
+        objs.push_back( copyAttributeList( payload, spec ) );
+      }
+      
+      b1_delete.start();
+    }
+    cout << "new version: " << b1.stop() << endl;
+    cout << "     delete: " << b1_delete.stop() << endl;
+        
+    Benchmark b2, b2_delete;
+    b2.start();
+    {
+      std::vector< boost::shared_ptr<coral::AttributeList> > objs;
+      for ( int i = 0; i < nRows; ++i ) {
+        coral::AttributeList payload( mixedPayload( i ) );
+        objs.push_back( copyAttributeList( payload ) );
+      }
+
+      b2_delete.start();
+    }
+    cout << "old version: " << b2.stop() << endl;
+    cout << "     delete: " << b2_delete.stop() << endl;
+    
+  }
+  
+  
+  void test_bulk_rw_string4kb_1() {
+    int nFields = 1;
+    long nObjs = quick ? 1 : 25000;
+    rw_string4kb( nFields, nObjs );
+  }
+  
+  void test_bulk_rw_string4kb_100() {
+    int nFields = 100;
+    long nObjs = quick ? 1 : 200; // reduced row count, each obj is 400kB
+                                  // 25k objects would allocate 10GB of memory
+                                  // could run several batches instead
+    rw_string4kb( nFields, nObjs );
+  }
+  
+  void test_bulk_rw_string4kb_200() {
+    int nFields = 200;
+    long nObjs = quick ? 1 : 100; // reduced row count, each obj is 400kB
+                                  // 25k objects would allocate 20GB of memory
+                                  // could run several batches instead
+    rw_string4kb( nFields, nObjs );
+  }
+  
+  
+  void rw_string4kb( int nFields, long nObjs ) {
+    
+    SpecPtr spec = uniformSpec( nFields, "string" );
+    AttributeList payload = string4kbPayload( spec );		
+    
+    IFolderPtr folder = db->createFolder( "/myfolder", *spec );
+    
+    mysleep();
+        
+    {
+      Benchmark b;
+      b.start();
+      
+      folder->setupStorageBuffer();
+      
+      for ( long i = 0; i < nObjs; ++i ) {
+        folder->storeObject( i, ValidityKeyMax, payload );
+      }
+      
+      folder->flushStorageBuffer();
+      
+      double secElapsed = b.stop();
+      
+      cout << "\n----------------------------------------------------" << endl;
+      cout << "** writing " << nObjs << " objects ("
+        << nFields << " 4kb strings) **" << endl;
+      cout << "wrote " << nObjs << " objects" << endl;
+      cout << "sec total: " << secElapsed << endl;
+      cout << "obj/s:     " << nObjs/secElapsed << endl << endl;
+    }
+    
+    
+    {
+      Benchmark b;
+      b.start();
+      
+      IObjectIteratorPtr objs = 
+        folder->browseObjects( ValidityKeyMin, ValidityKeyMax, 0, "" );
+
+      long nReadObjects = objs->size();
+      
+      double secElapsed = b.stop();
+      
+      cout << "** reading " << nObjs << " objects ("
+        << nFields << " 4kb strings) **" << endl;
+      cout << "read back " << nReadObjects << " objects" << endl;
+      cout << "sec total: " << secElapsed << endl;
+      cout << "obj/s:     " << nReadObjects/secElapsed << endl;
+    }
+    
+  }
+  
+  
+  
+  
+  void test_bulk_rw_float_1() {
+    int nFields = 1;
+    long nObjs = quick ? 1 : 25000;
+    rw_floats( nFields, nObjs );
+  }
+  
+  void test_bulk_rw_float_100() {
+    int nFields = 100;
+    long nObjs = quick ? 1 : 25000;
+    rw_floats( nFields, nObjs );
+  }
+  
+  void test_bulk_rw_float_200() {
+    int nFields = 200;
+    long nObjs = quick ? 1 : 25000;
+    rw_floats( nFields, nObjs );
+  }
+  
+  void test_bulk_rw_float_20() {
+    int nFields = 20;
+    long nObjs = quick ? 1 : 25000;
+    rw_floats( nFields, nObjs );
+  }
+  
+  
+  void rw_floats( int nFields, long nObjs ) {
+    
+    SpecPtr spec = uniformSpec( nFields, "float" );
+    IFolderPtr folder = db->createFolder( "/myfolder", *spec );
+    
+    {
+      Benchmark b;
+      b.start();
+      
+      folder->setupStorageBuffer();
+      
+      for ( long i = 0; i < nObjs; ++i ) {
+        folder->storeObject( i, ValidityKeyMax, floatPayload( i, spec ) );
+      }
+      
+      folder->flushStorageBuffer();
+      
+      double secElapsed = b.stop();
+      
+      cout << "\n----------------------------------------------------" << endl;
+      cout << "** writing " << nObjs << " objects ("
+        << nFields << " floats) **" << endl;
+      cout << "wrote " << nObjs << " objects" << endl;
+      cout << "sec total: " << secElapsed << endl;
+      cout << "obj/s:     " << nObjs/secElapsed << endl << endl;
+    }
+    
+    
+    {
+      Benchmark b;
+      b.start();
+      
+      IObjectIteratorPtr objs = 
+        folder->browseObjects( ValidityKeyMin, ValidityKeyMax, 0, "" );
+
+      long nReadObjects = objs->size();
+      
+      double secElapsed = b.stop();
+      
+      cout << "** reading " << nObjs << " objects ("
+        << nFields << " floats) **" << endl;
+      cout << "read back " << nReadObjects << " objects" << endl;
+      cout << "sec total: " << secElapsed << endl;
+      cout << "obj/s:     " << nReadObjects/secElapsed << endl;
+    }
+    
+  }
+  
+  
+  /// Tests writing mixed payloads in MULTI_VERSION mode
+  /// This case adds a persistent object to the HEAD before executing the
+  /// bulk storage
+  void test_bulk_rw_mixed_MV_withHEAD() {
+    
+    Benchmark fullRun;
+    fullRun.start();
+    {
+      
+#ifdef MEMTEST
+      ProcMemory* mem = new ProcMemory();
+      std::cout << "START of TEST" << std::endl; mem->printVm();
+#endif
+      
+      long nObjs = quick ? 1 : 10 * 100;
+      
+      {
+        IFolderPtr folder = db->createFolder( "/myfolder", 
+                                              mixedPayloadSpec,
+                                              "my description",
+                                              FolderVersioning::MULTI_VERSION );
+        mysleep();
+        
+        Benchmark b;
+        b.start();      
+        
+        // add one persistent HEAD object first
+        folder->storeObject( 0, ValidityKeyMax, mixedPayload( 0 ) );
+        
+        folder->setupStorageBuffer();
+        for ( long i = 0; i < nObjs; ++i ) {
+          folder->storeObject( i, i+1, mixedPayload( i ) );
+        }
+        
+#ifdef MEMTEST
+        std::cout << "Before flushing" << std::endl; mem->printVm();
+#endif
+        
+        folder->flushStorageBuffer();
+        
+        double secElapsed = b.stop();
+        
+        cout << "\n----------------------------------------------------" << endl;
+        cout << "** writing " << nObjs 
+          << " objects (150 bytes mixed, MULTI_VERSION mode w/HEAD) **" << endl;
+        cout << "sec total: " << secElapsed << endl;
+        cout << "obj/s:     " << nObjs/secElapsed << endl << endl;
+      }
+      
+#ifdef MEMTEST
+      std::cout << "After flushing" << std::endl; mem->printVm();
+#endif
+      
+      Benchmark bFull;
+      bFull.start();
+      
+      if (0) { // reading not implemented yet
+        IFolderPtr folder = db->getFolder( "/myfolder" );
+        
+        Benchmark b;
+        b.start();
+        
+        IObjectIteratorPtr objs =
+          folder->browseObjects( ValidityKeyMin, ValidityKeyMax, 0, "" );
+        
+#ifdef MEMTEST
+        std::cout << "After reading" << std::endl; mem->printVm();
+#endif
+        
+        long nReadObjects = objs->size();
+        
+        double secElapsed = b.stop();
+        
+        cout << "** reading " << nObjs 
+          << " objects (150 bytes mixed, MULTI_VERSION mode w/HEAD) **" << endl;
+        cout << "read back " << nReadObjects << " objects" << endl;
+        cout << "sec total: " << secElapsed << endl;
+        cout << "obj/s:     " << nReadObjects/secElapsed << endl;
+      }      
+      
+      cout << "sec total (INCLUDING DELETE): " << bFull.stop() << endl;
+      
+#ifdef MEMTEST
+      std::cout << "END OF TEST" << std::endl; mem->printVm();
+#endif
+      
+    }
+    cout << "sec total (full test): " << fullRun.stop() << endl;
+    
+  }
+  
+  
+  
+  /// Tests writing mixed payloads in MULTI_VERSION mode
+  void test_bulk_rw_mixed_MV() {
+    
+    Benchmark fullRun;
+    fullRun.start();
+    {
+      
+#ifdef MEMTEST
+      ProcMemory* mem = new ProcMemory();
+      std::cout << "START of TEST" << std::endl; mem->printVm();
+#endif
+      
+      long nObjs = quick ? 1 : 10 * 100;
+      
+      {
+        IFolderPtr folder = db->createFolder( "/myfolder", 
+                                              mixedPayloadSpec,
+                                              "my description",
+                                              FolderVersioning::MULTI_VERSION );
+        mysleep();
+        
+        Benchmark b;
+        b.start();      
+        
+        folder->setupStorageBuffer();
+        for ( long i = 0; i < nObjs; ++i ) {
+          folder->storeObject( i, i+1, mixedPayload( i ) );
+        }
+        
+#ifdef MEMTEST
+        std::cout << "Before flushing" << std::endl; mem->printVm();
+#endif
+        
+        folder->flushStorageBuffer();
+        
+        double secElapsed = b.stop();
+        
+        cout << "\n----------------------------------------------------" << endl;
+        cout << "** writing " << nObjs 
+          << " objects (150 bytes mixed, MULTI_VERSION mode) **" << endl;
+        cout << "sec total: " << secElapsed << endl;
+        cout << "obj/s:     " << nObjs/secElapsed << endl << endl;
+      }
+      
+#ifdef MEMTEST
+      std::cout << "After flushing" << std::endl; mem->printVm();
+#endif
+      
+      Benchmark bFull;
+      bFull.start();
+      
+      if (0) { // reading not implemented yet
+        IFolderPtr folder = db->getFolder( "/myfolder" );
+        
+        Benchmark b;
+        b.start();
+        
+        IObjectIteratorPtr objs =
+          folder->browseObjects( ValidityKeyMin, ValidityKeyMax, 0, "" );
+        
+#ifdef MEMTEST
+        std::cout << "After reading" << std::endl; mem->printVm();
+#endif
+        
+        long nReadObjects = objs->size();
+        
+        double secElapsed = b.stop();
+        
+        cout << "** reading " << nObjs 
+          << " objects (150 bytes mixed, MULTI_VERSION mode) **" << endl;
+        cout << "read back " << nReadObjects << " objects" << endl;
+        cout << "sec total: " << secElapsed << endl;
+        cout << "obj/s:     " << nReadObjects/secElapsed << endl;
+      }      
+      
+      cout << "sec total (INCLUDING DELETE): " << bFull.stop() << endl;
+      
+#ifdef MEMTEST
+      std::cout << "END OF TEST" << std::endl; mem->printVm();
+#endif
+      
+    }
+    cout << "sec total (full test): " << fullRun.stop() << endl;
+    
+  }
+  
+
+  /// Tests the performance of the multichannel bulk storage
+  /// with existing data in the channels: This will require IOV updates
+  /// in those channels. Compare performance to test_bulk_w_mixed_multichannel.
+  void test_bulk_w_mixed_multichannel_update() {
+  
+    long nObjs = quick ? 1 : 10 * 1000;
+    
+    IFolderPtr folder = db->createFolder( "/myfolder", mixedPayloadSpec );
+    mysleep();
+    
+    // Preload data into channels
+    {
+      folder->setupStorageBuffer();
+      for ( long i = 0; i < nObjs; ++i ) {
+        folder->storeObject( 0, ValidityKeyMax, mixedPayload( i ), i );
+      }
+      folder->flushStorageBuffer();
+    }
+    
+    {
+      
+#ifdef MEMTEST
+      ProcMemory* mem = new ProcMemory();
+      std::cout << "START of TEST" << std::endl; mem->printVm();
+#endif
+      
+      {
+        Benchmark b;
+        b.start();      
+        
+        folder->setupStorageBuffer();
+        for ( long i = 0; i < nObjs; ++i ) {
+          folder->storeObject( 5, ValidityKeyMax, mixedPayload( i ), i );
+        }
+        
+#ifdef MEMTEST
+        std::cout << "Before flushing" << std::endl; mem->printVm();
+#endif
+        
+        folder->flushStorageBuffer();
+        
+        double secElapsed = b.stop();
+        
+        cout << "\n----------------------------------------------------" << endl;
+        cout << "** writing " << nObjs << " objects (150 bytes mixed) **" << endl;
+        cout << "sec total: " << secElapsed << endl;
+        cout << "obj/s:     " << nObjs/secElapsed << endl << endl;
+      }
+      
+#ifdef MEMTEST
+      std::cout << "After flushing" << std::endl; mem->printVm();
+#endif
+      
+    }
+  }
+  
+  
+  /// Tests the performance of the multichannel bulk storage (compare to
+  /// write performance of test_bulk_rw_mixed)
+  void test_bulk_w_mixed_multichannel() {
+    
+    {
+      
+#ifdef MEMTEST
+      ProcMemory* mem = new ProcMemory();
+      std::cout << "START of TEST" << std::endl; mem->printVm();
+#endif
+      
+      long nObjs = quick ? 1 : 10 * 1000;
+      
+      {
+        IFolderPtr folder = db->createFolder( "/myfolder", mixedPayloadSpec );
+        mysleep();
+        
+        Benchmark b;
+        b.start();      
+        
+        folder->setupStorageBuffer();
+        for ( long i = 0; i < nObjs; ++i ) {
+          folder->storeObject( i, ValidityKeyMax, mixedPayload( i ), i );
+        }
+        
+#ifdef MEMTEST
+        std::cout << "Before flushing" << std::endl; mem->printVm();
+#endif
+        
+        folder->flushStorageBuffer();
+        
+        double secElapsed = b.stop();
+        
+        cout << "\n----------------------------------------------------" << endl;
+        cout << "** writing " << nObjs << " objects (150 bytes mixed) **" << endl;
+        cout << "sec total: " << secElapsed << endl;
+        cout << "obj/s:     " << nObjs/secElapsed << endl << endl;
+      }
+      
+#ifdef MEMTEST
+      std::cout << "After flushing" << std::endl; mem->printVm();
+#endif
+    
+    }
+  }
+  
+		
+  
+  /// Tests the performance of the multichannel bulk storage in the workaround
+  /// mode of the 'old' implementation (i.e. prior to the multi channel
+  /// extension)
+  void test_bulk_w_mixed_multichannel_old() {
+    
+    long nObjs = quick ? 1 : 10 * 1000;
+    
+    IFolderPtr folder = db->createFolder( "/myfolder", mixedPayloadSpec );
+    {
+      for ( long i = 0; i < nObjs; ++i ) {
+        folder->setupStorageBuffer();
+        folder->storeObject( (ValidityKey)0, ValidityKeyMax, 
+                             mixedPayload( i ), i );
+        folder->flushStorageBuffer();
+      }
+    }
+      
+#ifdef MEMTEST
+    ProcMemory* mem = new ProcMemory();
+    std::cout << "START of TEST" << std::endl; mem->printVm();
+#endif
+    
+    {
+      Benchmark b;
+      b.start();      
+      
+      for ( long i = 0; i < nObjs; ++i ) {
+        folder->setupStorageBuffer();
+        folder->storeObject( (ValidityKey)5, ValidityKeyMax, 
+                             mixedPayload( i ), i );
+        folder->flushStorageBuffer();
+      }
+      
+#ifdef MEMTEST
+      std::cout << "Before flushing" << std::endl; mem->printVm();
+#endif
+      
+      double secElapsed = b.stop();
+      
+      cout << "\n----------------------------------------------------" << endl;
+      cout << "** writing " << nObjs << " objects (150 bytes mixed) **" << endl;
+      cout << "sec total: " << secElapsed << endl;
+      cout << "obj/s:     " << nObjs/secElapsed << endl << endl;
+    }
+    
+#ifdef MEMTEST
+    std::cout << "After flushing" << std::endl; mem->printVm();
+#endif
+    
+  }
+  
+		
+  
+  void test_bulk_rw_mixed() {
+
+    Benchmark fullRun;
+    fullRun.start();
+    {
+    
+#ifdef MEMTEST
+    ProcMemory* mem = new ProcMemory();
+    std::cout << "START of TEST" << std::endl; mem->printVm();
+#endif
+
+    long nObjs = quick ? 1 : 10 * 1000;
+
+    {
+      IFolderPtr folder = db->createFolder( "/myfolder", mixedPayloadSpec );
+      mysleep();
+      
+      Benchmark b;
+      b.start();      
+      
+      folder->setupStorageBuffer();
+      for ( long i = 0; i < nObjs; ++i ) {
+        folder->storeObject( i, ValidityKeyMax, mixedPayload( i ) );
+      }
+      
+#ifdef MEMTEST
+      std::cout << "Before flushing" << std::endl; mem->printVm();
+#endif
+
+      folder->flushStorageBuffer();
+      
+      double secElapsed = b.stop();
+      
+      cout << "\n----------------------------------------------------" << endl;
+      cout << "** writing " << nObjs << " objects (150 bytes mixed) **" << endl;
+      cout << "sec total: " << secElapsed << endl;
+      cout << "obj/s:     " << nObjs/secElapsed << endl << endl;
+    }
+    
+#ifdef MEMTEST
+    std::cout << "After flushing" << std::endl; mem->printVm();
+#endif
+
+    Benchmark bFull;
+    bFull.start();
+    
+    {
+      IFolderPtr folder = db->getFolder( "/myfolder" );
+      
+      Benchmark b;
+      b.start();
+      
+      IObjectIteratorPtr objs = 
+        folder->browseObjects( ValidityKeyMin, ValidityKeyMax, 0, "" );
+
+#ifdef MEMTEST
+      std::cout << "After reading" << std::endl; mem->printVm();
+#endif
+
+      long nReadObjects = objs->size();
+      
+      double secElapsed = b.stop();
+      
+      cout << "** reading " << nObjs << " objects (150 bytes mixed) **" << endl;
+      cout << "read back " << nReadObjects << " objects" << endl;
+      cout << "sec total: " << secElapsed << endl;
+      cout << "obj/s:     " << nReadObjects/secElapsed << endl;
+    }      
+
+    cout << "sec total (INCLUDING DELETE): " << bFull.stop() << endl;
+    
+#ifdef MEMTEST
+    std::cout << "END OF TEST" << std::endl; mem->printVm();
+#endif
+    
+    }
+    cout << "sec total (full test): " << fullRun.stop() << endl;
+    
+  }
+  
+  
+		
+  
+  /// Creates a dummy payload AttributeList for a given index
+  AttributeList mixedPayload( int index ) {
+    AttributeList payload( mixedPayloadSpec );
+    payload["I"].setValue<int>( index );
+    stringstream s;
+    s << "Object " << index;
+    payload["S"].setValue<string>( s.str() );
+    payload["X0"].setValue<float>( (float)(index/1000.) );
+    payload["X1"].setValue<float>( (float)(index/1000.) );
+    payload["X2"].setValue<float>( (float)(index/1000.) );
+    payload["X3"].setValue<float>( (float)(index/1000.) );
+    payload["X4"].setValue<float>( (float)(index/1000.) );
+    payload["X5"].setValue<float>( (float)(index/1000.) );
+    payload["X6"].setValue<float>( (float)(index/1000.) );
+    payload["X7"].setValue<float>( (float)(index/1000.) );
+    payload["X8"].setValue<float>( (float)(index/1000.) );
+    payload["X9"].setValue<float>( (float)(index/1000.) );
+    payload["P"].setValue<string>( "0123456789"
+                                   "0123456789"
+                                   "0123456789"
+                                   "0123456789"
+                                   "0123456789"
+                                   "0123456789"
+                                   "0123456789"
+                                   "0123456789"
+                                   "0123456789"
+                                   "0123456789"
+                                   );
+    return payload;
+  }
+		
+  
+  /// Creates a uniform payload specification for nFields fields
+  SpecPtr uniformSpec( int nFields, const string & type ) {
+    SpecPtr spec( new AttributeListSpecification() );
+    for ( int i = 0; i < nFields; ++i ) {
+      stringstream s;
+      s << "X" << i;
+      spec->push_back( s.str(), type );
+    }
+    return spec;
+  }
+  
+  
+  /// Creates a dummy 4kB string AttributeList
+  AttributeList string4kbPayload( SpecPtr & spec ) {
+    stringstream payloadString;
+    int bytes = 4000;
+    for ( int i = 0; i < bytes; ++i ) payloadString << "a";
+    
+    int nFields = spec->size();
+    AttributeList payload( spec );
+    for ( int i = 0; i < nFields; ++i ) {
+      stringstream s;
+      s << "X" << i;
+      payload[ s.str() ].setValue<string>( payloadString.str() );
+    }
+    return payload;
+  }
+		
+  
+  /// Creates a dummy float AttributeList for a given index
+  AttributeList floatPayload( int index, SpecPtr & spec ) {
+    int nFields = spec->size();
+    AttributeList payload( spec );
+    for ( int i = 0; i < nFields; ++i ) {
+      stringstream s;
+      s << "X" << i;
+      payload[ s.str() ].setValue<float>( (float)(index/1000.) );
+    }
+    return payload;
+  }
+		
+  
+  void mysleep() {
+    const int sleep_timeout = 0;
+    if ( sleep_timeout > 0 ) {
+      cout << "temporary 'sleep()' to work aound ORA-01466 problem" << endl;
+      cool::sleep(sleep_timeout);
+    }
+  }
+  
+  
+  void setUp() {
+    if ( mixedPayloadSpec.size() == 0 ) {
+      mixedPayloadSpec.push_back("I","int");
+      mixedPayloadSpec.push_back("S","string");
+      mixedPayloadSpec.push_back("X0","float");
+      mixedPayloadSpec.push_back("X1","float");
+      mixedPayloadSpec.push_back("X2","float");
+      mixedPayloadSpec.push_back("X3","float");
+      mixedPayloadSpec.push_back("X4","float");
+      mixedPayloadSpec.push_back("X5","float");
+      mixedPayloadSpec.push_back("X6","float");
+      mixedPayloadSpec.push_back("X7","float");
+      mixedPayloadSpec.push_back("X8","float");
+      mixedPayloadSpec.push_back("X9","float");
+      mixedPayloadSpec.push_back("P","string");
+    }
+    
+    if ( getenv( COOLTESTDB ) ) {
+      connectString = getenv( COOLTESTDB );
+    } else {
+      cout << "Please provide a connect string by "
+      << "specifying one in the environment variable COOLTESTDB, e.g." 
+      << endl;
+      cout << "setenv COOLTESTDB "
+        << "\"oracle://devdb10;schema=lcg_cool;dbname=COOLTEST\"" << endl;
+      cout << "Aborting test" << endl;
+      exit(-1);
+    }
+    
+    static CoralApplication app;
+    IDatabaseSvc& dbSvc = app.databaseService();
+    dbSvc.dropDatabase( connectString );
+    db = dbSvc.createDatabase( connectString );
+    
+    mysleep();
+  }
+		
+		void tearDown() {
+      db.reset();
+		}
+  
+};
+
+CPPUNIT_TEST_SUITE_REGISTRATION( PerformanceTest );
+
+} // namespace
+
+// sas: This file is from the OPAL package I believe. It allows for
+// shorter test classes and prepares the test class for OPAL
+#include<CppUnit_testdriver.icpp>
+
+
+#endif // NOPORT
diff --git a/RelationalCool/tests/PerformanceAV/README.Performance b/RelationalCool/tests/PerformanceAV/README.Performance
new file mode 100644
index 000000000..20bca538e
--- /dev/null
+++ b/RelationalCool/tests/PerformanceAV/README.Performance
@@ -0,0 +1,242 @@
+--------------------------
+ServerCache (31-Jan-2005)
+--------------------------
+
+Only reading, 100k mixed rows (Oracle table not yet analyzed).
+This is the same exact table used the next day for 10k tests.
+The version of the software is slightly older but the results are firm.
+
+Two interesting points tested:
+- is there any effect from server-side in-memory caching?
+- what is the maximum perfromance that can be reached using Benthic/mysql?
+
+Typical numbers for both Oracle and MySQL:
+~100 seconds to retrieve 100k rows 
+(~40 seconds from fetching, ~60 seconds from client side handling).
+
+Results for server-side caching
+(this is achieved by shutting down and restarting the Oracle
+or MySQL database before running the test: if there is any
+in-memory cache, this is emptied at server restart)
+- No effect observed! Out of the ~100 seconds, the reading from disk 
+  of the ~30MB data for 100k rows takes a fraction of a second.
+- In Oracle, the trace file confirms that data need to be read
+  from disk the first time the test is executed.
+
+Results for the comparison COOL to Benthic for Oracle
+- Benthic takes approximately ~5 seconds on my Windows 500MB memory PC.
+  The trace file shows that the server returns the query in 1.5 seconds!
+- Something very weird goes on inside the SQL processing within COOL/RAL:
+  not only it takes ~40 seconds to return the query, but especially
+  the number of rows processed by the server is 195k instead of 100k!!!
+  This was first observed thanks to help from Bjorn.
+- THIS SHOWS THAT THE RAL PROCESSING COULD GO DOWN FROM 40 to ~5 SECONDS.
+
+Results for the comparison COOL to mysql tool for MySQL
+- The mysql tool takes approximately ~7.5 seconds (2.5 seconds user time
+  plus 5 seconds idle/network time), which is similar to Benthic/Oracle
+- Again the numbers observed for COOL are ~40 seconds for the RAL fetching,
+  plus ~60 seconds overhead from COOL.
+
+--------------------------
+TestNewCopy (01-Feb-2005)
+--------------------------
+
+Only reading, 10k mixed rows, on a table not yet analyzed.
+Test done for Oracle using cooldb2.
+
+Typical numbers for Oracle:
+~10 seconds to retrieve 10k rows 
+(~4 seconds from fetching, ~6 seconds from client side handling).
+
+Compare the "old" copyAttributeList algorithm to Sven's "new" 
+copyAttributeList algorithm that takes an AttributeListSpecification
+shared pointer as extra argument.
+
+Very strange results:
+- On my private RH73 node (500MB memory) and on lxplus7 (1GB memory),
+  the net result is slower because deleting objects wrapped with
+  boost shared pointers takes very long (the effect is devastating
+  for 100k rows - not studied here -, it takes very very long).
+  That is to say, the ~10 seconds increases to ~14 seconds.
+- On lxplus (SLC with 2GB memory), the net results is faster. Deleting
+  takes a negligible time, the copying itself is faster. This is in line
+  with what originally observed by Sven.
+- The memory usage is negligible for both cases.
+
+CONCLUSION: For the moment, keep the old algorithm.
+The use of boost pointers and the performance implications 
+need to be better understood.
+
+--------------------------
+TestRalOnly (01-Feb-2005)
+--------------------------
+
+Only reading, 10k mixed rows, on a table not yet analyzed.
+Test done for Oracle using cooldb2.
+
+Typical numbers for Oracle:
+~10 seconds to retrieve 10k rows 
+(~4 seconds from fetching, ~6 seconds from client side handling).
+
+Switch off all internal COOL data handling, measure the
+intrinsic RAL performance.
+
+Results:
+- The COOL overhead is large, more than 60%. Work is needed
+  to reduce this significantly.
+- The RAL numbers are only 40% of the total, but may still be
+  significant in absolute terms (when compared to Benthic, for 
+  instance - for which numbers are not given here).
+
+In other words: the ~4 seconds inside the "fetch" portion are 
+essentially dictated by RAL and not affected by COOL, while the 
+remaining ~6 seconds in all other parts are indeed a COOL-only overhead.
+
+-----------------------------------
+TestRalOnly (01-Feb-2005) ANALYZED
+-----------------------------------
+
+The test was repeated after analyzing the table.
+
+Good point: the correct execution plan is used
+(see the trace files filtered through tkprof).
+QUESTION: why is it necessary to analyze the table?
+
+No improvement in time performance was observed, however.
+This is interesting because it means that also the
+results of previous tests (eg vs Benthic) can be trusted
+even if the wrong execution plan was used.
+
+----------------------------
+TestShareData (01-Feb-2005)
+----------------------------
+
+Only reading, 10k mixed rows, on a table previously analyzed.
+Test done for Oracle using cooldb2.
+
+The previous tests wre using COOL_0_0_3-pre1-alpha.
+In COOL_0_0_3-pre1-beta I just changed the interface to use iterators again.
+This test uses COOL_0_0_3-pre1-gamma.
+
+The tested feature is now the default: copy attributes using
+shareData() instead of the setValueAsString() method.
+This dramatically improves the COOL performance.
+The COOL overhead is reduced by a factor 3!
+Thanks to Ioannis who originally mentioned copyData()!
+
+Typical numbers for Oracle:
+From ~10 down to ~6 seconds for retrieving 10k rows 
+(~4 seconds from fetching remains unchanged and is now the bottleneck, 
+from ~6 seconds down to ~2 seconds for client side handling).
+
+THE INTRINSIC PERFORMANCE FROM RAL IS NOW THE BOTTLENECK (~70% TOTAL).
+
+Note also that the use of shareData() reduces memory usage by a factor 2.
+
+------------------------------------
+TestScrollableCursors (02-Feb-2005)
+------------------------------------
+
+Only reading, 10k mixed rows, on a table previously analyzed.
+Test done for Oracle using cooldb2.
+
+No changes to the COOL code.
+These tests are included in version tagged as COOL_0_0_3-pre1-delta.
+
+After discussing with Ioannis about the weird tkprof output from RAL,
+he suggested to disable scrollable cursors in RAL. 
+Code changes with respect to POOL_2_0_0-iota:
+  diff -r1.5 OracleCursor.cpp
+  19c19,20
+  <   if ( ! ( m_statement.execute( true ) ) ) {
+  ---
+  >   bool scrollableCursors = getenv( "RAL_SCROLLABLECURSORS" );
+  >   if ( ! ( m_statement.execute( scrollableCursors ) ) ) {
+  47c48,49
+  <   if ( ! ( m_statement.execute( true ) ) ) {
+  ---
+  >   bool scrollableCursors = getenv( "RAL_SCROLLABLECURSORS" );
+  >   if ( ! ( m_statement.execute( scrollableCursors ) ) ) {
+
+The tested feature is now the default in this private version of POOL:
+queries return cursors that are not backwards-scrollable
+(they can only be looped on in the forward direction).
+
+This dramatically improves the RAL performance by a factor 5!
+More importantly, the CPU consumption on the server goes down
+by a factor 20 (!!) and the tkprof output looks much better, only 10k 
+rows are analyzed if 10k rows are returned, just like in Benthic.
+
+This means that there are now good prospects to further improve
+COOL/RAL performance by improving the client side data manipulation.
+
+Typical numbers for Oracle:
+From ~6 seconds down to ~3.8 seconds for retrieving 10k rows 
+(~4 seconds from fetching goes down to ~0.8 seconds in RAL,
+~3 seconds for COOL client side handling remains unchanged).
+
+THE COOL OVERHEAD IS NOW AGAIN THE BOTTLENECK (~80% TOTAL).
+
+Note also that the .trc files on the server 
+(from which the tkprof .prf files are produced)
+have roughly half the size than with scrollable cursors.
+
+Thanks a lot to Ioannis for the quick and efficient help!!
+
+----------------------------
+TestShareData (02-Feb-2005)
+----------------------------
+
+Ooops. The use of shareData() is much faster but it does not work!
+Thanks to Marco Clemencic for pointing this out.
+Essentially all objects in the iterator end up having the same data.
+
+This is now shown in the output of the test.
+I rerun all tests using COOL_0_0_3-pre1-epsilon and commit this test again.
+
+By the way, from COOL_0_0_3-pre1-epsilon onwards POOL has been 
+updated from POOL_2_0_0-iota to POOL_2_0_0-kappa.
+
+-----------------------------------------
+TestAttributeValueAccessor (02-Feb-2005)
+-----------------------------------------
+
+Only reading, 10k mixed rows, on a table previously analyzed.
+Test done for Oracle using cooldb2.
+
+This test is commiteed as COOL_0_0_3-pre1-zeta.
+
+The tested feature is now the default: copy attributes using
+the AttributeValueAccessor instead of the setValueAsString() method.
+
+The performance is equivalent to that observed
+using the (wrong) shareData() method.
+This dramatically improves the COOL performance
+with respect to the setValueAsString solution, by a factor 3.
+
+And especially this works (the attribute data are correct!).
+
+Thanks to Ioannis who suggested the complete AttributeValueAccessor recipe!
+
+Typical numbers for Oracle are now
+~3.8 seconds for retrieving 10k rows 
+(~0.8 seconds from fetching in RAL, 
+~3 seconds for client side handling).
+
+THE COOL OVERHEAD IS NOW AGAIN THE BOTTLENECK (~80% TOTAL).
+
+Note also that, in contrast to what happened with shareData(),
+the usage of the AttributeValueAccessor does not reduce memory usage.
+
+----------------------------
+Minor changes (02-Feb-2005)
+----------------------------
+
+Cleaned up the copyAttributeList implementation using two iterators
+as suggested by Ioannis. No major performance improvement.
+
+Committed code and tests as the final COOL_0_0_3-pre1.
+
+
+
diff --git a/RelationalCool/tests/PerformanceAV/README.sqlTrace b/RelationalCool/tests/PerformanceAV/README.sqlTrace
new file mode 100644
index 000000000..67e8acd01
--- /dev/null
+++ b/RelationalCool/tests/PerformanceAV/README.sqlTrace
@@ -0,0 +1,5 @@
+# Copy trc files from /ORA/dbs00/oracle/admin/cooldb2/udump/
+# Use level 12 SQL_TRACE
+
+tkprof file.trc file.prf sort=exeela,fchela
+
diff --git a/RelationalCool/tests/PerformanceAV/ServerCache/100k-my-cool-first.out b/RelationalCool/tests/PerformanceAV/ServerCache/100k-my-cool-first.out
new file mode 100644
index 000000000..608e6b98e
--- /dev/null
+++ b/RelationalCool/tests/PerformanceAV/ServerCache/100k-my-cool-first.out
@@ -0,0 +1,91 @@
+Property Catalogue: level[Info] Adding property: OutputLevel = 2 in scope "SEAL/Services/MessageService"
+Property Catalogue: level[Info] Adding property: Format =  "%-36s %-8s %s" in scope "SEAL/Services/MessageService"
+MessageService callback    Debug MessageService output level changed to Debug
+ConfigurationService    Debug Setting property: "Format" to value " "%-36s %-8s %s"" in scope "SEAL/Services/MessageService"
+POOL/Services/RelationalService      Info     Found plugin for RDBMS technology "mysql" with implementation "odbc"
+POOL/Services/RelationalService      Info     Found plugin for RDBMS technology "oracle" with native implementation
+POOL/Services/RelationalService      Info     Default implementation for RDBMS technology "mysql" is "odbc"
+POOL/Services/RelationalService      Info     Default implementation for RDBMS technology "oracle" is native
+RelationalDatabase                   Debug    Instantiate a RelationalDatabase for 'mysql://lxb0771;schema=AVALASSI;user=avalassi;password=andrea;dbname=COOLTEST'
+RelationalDatabase                   Info     Instantiate a RalDatabase for 'mysql://lxb0771;schema=AVALASSI;user=avalassi;password=andrea;dbname=COOLTEST'
+POOL/odbc/ODBCDriverSelector         Info     ODBC Drivers found:
+POOL/odbc/ODBCDriverSelector         Info     [MyODBC]
+POOL/odbc/ODBCDriverSelector         Info       Description = MySQL ODBC 3.51 driver for Linux;
+POOL/odbc/ODBCDriverSelector         Info       Driver = libmyodbc3.so;
+POOL/odbc/ODBCDriverSelector         Info       FileUsage = 1;
+POOL/odbc/ODBCDriverSelector         Info     [MySQL]
+POOL/odbc/ODBCDriverSelector         Info       Description = MySQL ODBC 3.51 driver for Linux;
+POOL/odbc/ODBCDriverSelector         Info       Driver = libmyodbc3.so;
+POOL/odbc/ODBCDriverSelector         Info       FileUsage = 1;
+POOL/RelationalPlugins/mysql/odbc    Info     Connection URI   : mysql://lxb0771/AVALASSI
+POOL/RelationalPlugins/mysql/odbc    Info     Connection string: DRIVER={MySQL};SERVER=lxb0771;DATABASE=AVALASSI;USER=avalassi;PASSWORD=andrea;OPTION=0;
+POOL/RelationalPlugins/mysql/odbc    Info     Connected via MySQL driver
+POOL/RelationalPlugins/mysql/odbc    Info     Connected using full connection string: DRIVER={MySQL ODBC 3.51 Driver};DB=AVALASSI;SERVER=lxb0771;UID=avalassi;PASSWORD=andrea;PORT=3306;SOCKET=;OPTION=0;STMT=;
+2Preparing statement: SELECT "DB_ATTRIBUTE_NAME", "DB_ATTRIBUTE_VALUE" FROM "AVALASSI"."COOLTEST_DB_ATTRIBUTES"
+2Preparing statement: SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_ISLEAF", "NODE_INSTIME", "FOLDER_PAYLOADSPEC", "FOLDER_VERSIONING", "FOLDER_IOVTABLENAME" FROM "AVALASSI"."COOLTEST_FOLDERS" WHERE "NODE_FULLPATH"=?          
+RelationalFolder                     Debug    Instantiate a RelationalFolder for '/myfolder'
+2Preparing statement: SELECT "OBJECT_ID", "CHANNEL_ID", "IOV_SINCE", "IOV_UNTIL", "SYS_INSTIME", "I", "S", "X0", "X1", "X2", "X3", "X4", "X5", "X6", "X7", "X8", "X9", "P" FROM "AVALASSI"."COOLTEST_F0001_IOVS" WHERE "CHANNEL_ID"=?          AND "IOV_SINCE">=?        AND "IOV_UNTIL"<=?       ORDER BY "CHANNEL_ID" ASC,"IOV_SINCE" ASC
+>>>>>>    Timing Results  <<<<<<<<<< 
+----- 1.PrepareQuery----------- :                              ( n=1 )
+Total Real Time  :      0.060 +/-      0.060 s
+Total User Time  :      0.000 +/-      0.000 s
+Total System Time:      0.000 +/-      0.000 s
+Total Idle Time  :      0.060 +/-      0.060 s
+----- 2.ProcessQuery----------- :                              ( n=1 )
+Total Real Time  :      6.610 +/-      6.610 s
+Total User Time  :      0.210 +/-      0.210 s
+Total System Time:      0.470 +/-      0.470 s
+Total Idle Time  :      5.930 +/-      5.930 s
+----- 3.FetchRows-------------- :                              ( n=100001 )
+Total Real Time  :     33.520 +/-      0.106 s
+Total User Time  :     18.140 +/-      0.057 s
+Total System Time:     15.790 +/-      0.050 s
+Total Idle Time  :     -0.390 +/-     -0.001 s
+----- 4.CopyAttributeList------ :                              ( n=100000 )
+Total Real Time  :     61.080 +/-      0.193 s
+Total User Time  :     60.430 +/-      0.191 s
+Total System Time:      0.570 +/-      0.002 s
+Total Idle Time  :      0.160 +/-      0.001 s
+----- 5.CloseQuery------------- :                              ( n=1 )
+Total Real Time  :      0.010 +/-      0.010 s
+Total User Time  :      0.010 +/-      0.010 s
+Total System Time:      0.000 +/-      0.000 s
+Total Idle Time  :      0.000 +/-      0.000 s
+----- TOTAL FetchObjRowsByVal-- :                              ( n=1 )
+Total Real Time  :    102.670 +/-    102.670 s
+Total User Time  :     79.750 +/-     79.750 s
+Total System Time:     16.910 +/-     16.910 s
+Total Idle Time  :      6.010 +/-      6.010 s
+>>>>>>    Timing Results  <<<<<<<<<< 
+----- 1.FetchObjRowsByVal----- :                              ( n=1 )
+Total Real Time  :    102.670 +/-    102.670 s
+Total User Time  :     79.750 +/-     79.750 s
+Total System Time:     16.910 +/-     16.910 s
+Total Idle Time  :      6.010 +/-      6.010 s
+----- 2.DecodeRow------------- :                              ( n=1 )
+Total Real Time  :      9.860 +/-      9.860 s
+Total User Time  :      9.410 +/-      9.410 s
+Total System Time:      0.170 +/-      0.170 s
+Total Idle Time  :      0.280 +/-      0.280 s
+----- 3.DeleteOld------------- :                              ( n=1 )
+Total Real Time  :      1.610 +/-      1.610 s
+Total User Time  :      1.570 +/-      1.570 s
+Total System Time:      0.000 +/-      0.000 s
+Total Idle Time  :      0.040 +/-      0.040 s
+----- TOTAL BrowseObjInTag---- :                              ( n=1 )
+Total Real Time  :    114.140 +/-    114.140 s
+Total User Time  :     90.730 +/-     90.730 s
+Total System Time:     17.080 +/-     17.080 s
+Total Idle Time  :      6.330 +/-      6.330 s
+** reading 100000 objects (150 bytes mixed) **
+read back 100000 objects
+sec total: 114.161
+obj/s:     875.956
+RelationalFolder                     Debug    Delete the RelationalFolder for '/myfolder'
+sec total (INCLUDING DELETE): 115.409
+
+OK (1)
+[OVAL] Cppunit-result =0
+RelationalDatabase                   Info     Delete the RalDatabase for 'mysql://lxb0771;schema=AVALASSI;user=avalassi;password=andrea;dbname=COOLTEST'
+POOL/RelationalPlugins/mysql/odbc    Warning  No active transaction to roll back
+RelationalDatabase                   Debug    Delete the RelationalDatabase for 'mysql://lxb0771;schema=AVALASSI;user=avalassi;password=andrea;dbname=COOLTEST'
diff --git a/RelationalCool/tests/PerformanceAV/ServerCache/100k-my-cool-next.out b/RelationalCool/tests/PerformanceAV/ServerCache/100k-my-cool-next.out
new file mode 100644
index 000000000..14b72b978
--- /dev/null
+++ b/RelationalCool/tests/PerformanceAV/ServerCache/100k-my-cool-next.out
@@ -0,0 +1,91 @@
+Property Catalogue: level[Info] Adding property: OutputLevel = 2 in scope "SEAL/Services/MessageService"
+Property Catalogue: level[Info] Adding property: Format =  "%-36s %-8s %s" in scope "SEAL/Services/MessageService"
+MessageService callback    Debug MessageService output level changed to Debug
+ConfigurationService    Debug Setting property: "Format" to value " "%-36s %-8s %s"" in scope "SEAL/Services/MessageService"
+POOL/Services/RelationalService      Info     Found plugin for RDBMS technology "mysql" with implementation "odbc"
+POOL/Services/RelationalService      Info     Found plugin for RDBMS technology "oracle" with native implementation
+POOL/Services/RelationalService      Info     Default implementation for RDBMS technology "mysql" is "odbc"
+POOL/Services/RelationalService      Info     Default implementation for RDBMS technology "oracle" is native
+RelationalDatabase                   Debug    Instantiate a RelationalDatabase for 'mysql://lxb0771;schema=AVALASSI;user=avalassi;password=andrea;dbname=COOLTEST'
+RelationalDatabase                   Info     Instantiate a RalDatabase for 'mysql://lxb0771;schema=AVALASSI;user=avalassi;password=andrea;dbname=COOLTEST'
+POOL/odbc/ODBCDriverSelector         Info     ODBC Drivers found:
+POOL/odbc/ODBCDriverSelector         Info     [MyODBC]
+POOL/odbc/ODBCDriverSelector         Info       Description = MySQL ODBC 3.51 driver for Linux;
+POOL/odbc/ODBCDriverSelector         Info       Driver = libmyodbc3.so;
+POOL/odbc/ODBCDriverSelector         Info       FileUsage = 1;
+POOL/odbc/ODBCDriverSelector         Info     [MySQL]
+POOL/odbc/ODBCDriverSelector         Info       Description = MySQL ODBC 3.51 driver for Linux;
+POOL/odbc/ODBCDriverSelector         Info       Driver = libmyodbc3.so;
+POOL/odbc/ODBCDriverSelector         Info       FileUsage = 1;
+POOL/RelationalPlugins/mysql/odbc    Info     Connection URI   : mysql://lxb0771/AVALASSI
+POOL/RelationalPlugins/mysql/odbc    Info     Connection string: DRIVER={MySQL};SERVER=lxb0771;DATABASE=AVALASSI;USER=avalassi;PASSWORD=andrea;OPTION=0;
+POOL/RelationalPlugins/mysql/odbc    Info     Connected via MySQL driver
+POOL/RelationalPlugins/mysql/odbc    Info     Connected using full connection string: DRIVER={MySQL ODBC 3.51 Driver};DB=AVALASSI;SERVER=lxb0771;UID=avalassi;PASSWORD=andrea;PORT=3306;SOCKET=;OPTION=0;STMT=;
+2Preparing statement: SELECT "DB_ATTRIBUTE_NAME", "DB_ATTRIBUTE_VALUE" FROM "AVALASSI"."COOLTEST_DB_ATTRIBUTES"
+2Preparing statement: SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_ISLEAF", "NODE_INSTIME", "FOLDER_PAYLOADSPEC", "FOLDER_VERSIONING", "FOLDER_IOVTABLENAME" FROM "AVALASSI"."COOLTEST_FOLDERS" WHERE "NODE_FULLPATH"=?          
+RelationalFolder                     Debug    Instantiate a RelationalFolder for '/myfolder'
+2Preparing statement: SELECT "OBJECT_ID", "CHANNEL_ID", "IOV_SINCE", "IOV_UNTIL", "SYS_INSTIME", "I", "S", "X0", "X1", "X2", "X3", "X4", "X5", "X6", "X7", "X8", "X9", "P" FROM "AVALASSI"."COOLTEST_F0001_IOVS" WHERE "CHANNEL_ID"=?          AND "IOV_SINCE">=?        AND "IOV_UNTIL"<=?       ORDER BY "CHANNEL_ID" ASC,"IOV_SINCE" ASC
+>>>>>>    Timing Results  <<<<<<<<<< 
+----- 1.PrepareQuery----------- :                              ( n=1 )
+Total Real Time  :      0.130 +/-      0.130 s
+Total User Time  :      0.010 +/-      0.010 s
+Total System Time:      0.000 +/-      0.000 s
+Total Idle Time  :      0.120 +/-      0.120 s
+----- 2.ProcessQuery----------- :                              ( n=1 )
+Total Real Time  :      6.080 +/-      6.080 s
+Total User Time  :      0.200 +/-      0.200 s
+Total System Time:      0.490 +/-      0.490 s
+Total Idle Time  :      5.390 +/-      5.390 s
+----- 3.FetchRows-------------- :                              ( n=100001 )
+Total Real Time  :     33.180 +/-      0.105 s
+Total User Time  :     16.830 +/-      0.053 s
+Total System Time:     15.650 +/-      0.049 s
+Total Idle Time  :      1.020 +/-      0.003 s
+----- 4.CopyAttributeList------ :                              ( n=100000 )
+Total Real Time  :     59.960 +/-      0.190 s
+Total User Time  :     60.460 +/-      0.191 s
+Total System Time:      0.440 +/-      0.001 s
+Total Idle Time  :     -0.970 +/-     -0.003 s
+----- 5.CloseQuery------------- :                              ( n=1 )
+Total Real Time  :      0.010 +/-      0.010 s
+Total User Time  :      0.000 +/-      0.000 s
+Total System Time:      0.010 +/-      0.010 s
+Total Idle Time  :      0.000 +/-      0.000 s
+----- TOTAL FetchObjRowsByVal-- :                              ( n=1 )
+Total Real Time  :    100.680 +/-    100.680 s
+Total User Time  :     78.420 +/-     78.420 s
+Total System Time:     16.660 +/-     16.660 s
+Total Idle Time  :      5.600 +/-      5.600 s
+>>>>>>    Timing Results  <<<<<<<<<< 
+----- 1.FetchObjRowsByVal----- :                              ( n=1 )
+Total Real Time  :    100.690 +/-    100.690 s
+Total User Time  :     78.420 +/-     78.420 s
+Total System Time:     16.660 +/-     16.660 s
+Total Idle Time  :      5.610 +/-      5.610 s
+----- 2.DecodeRow------------- :                              ( n=1 )
+Total Real Time  :     10.110 +/-     10.110 s
+Total User Time  :      9.470 +/-      9.470 s
+Total System Time:      0.200 +/-      0.200 s
+Total Idle Time  :      0.440 +/-      0.440 s
+----- 3.DeleteOld------------- :                              ( n=1 )
+Total Real Time  :      1.570 +/-      1.570 s
+Total User Time  :      1.550 +/-      1.550 s
+Total System Time:      0.000 +/-      0.000 s
+Total Idle Time  :      0.020 +/-      0.020 s
+----- TOTAL BrowseObjInTag---- :                              ( n=1 )
+Total Real Time  :    112.370 +/-    112.370 s
+Total User Time  :     89.440 +/-     89.440 s
+Total System Time:     16.860 +/-     16.860 s
+Total Idle Time  :      6.070 +/-      6.070 s
+** reading 100000 objects (150 bytes mixed) **
+read back 100000 objects
+sec total: 112.375
+obj/s:     889.881
+RelationalFolder                     Debug    Delete the RelationalFolder for '/myfolder'
+sec total (INCLUDING DELETE): 113.62
+
+OK (1)
+[OVAL] Cppunit-result =0
+RelationalDatabase                   Info     Delete the RalDatabase for 'mysql://lxb0771;schema=AVALASSI;user=avalassi;password=andrea;dbname=COOLTEST'
+POOL/RelationalPlugins/mysql/odbc    Warning  No active transaction to roll back
+RelationalDatabase                   Debug    Delete the RelationalDatabase for 'mysql://lxb0771;schema=AVALASSI;user=avalassi;password=andrea;dbname=COOLTEST'
diff --git a/RelationalCool/tests/PerformanceAV/ServerCache/100k-ora-benthic-first.prf b/RelationalCool/tests/PerformanceAV/ServerCache/100k-ora-benthic-first.prf
new file mode 100644
index 000000000..abe7a7fb8
--- /dev/null
+++ b/RelationalCool/tests/PerformanceAV/ServerCache/100k-ora-benthic-first.prf
@@ -0,0 +1,680 @@
+
+TKPROF: Release 10.1.0.2.0 - Production on Mon Jan 31 11:46:22 2005
+
+Copyright (c) 1982, 2004, Oracle.  All rights reserved.
+
+Trace file: benthic1.trc
+Sort options: exeela  fchela  
+********************************************************************************
+count    = number of times OCI procedure was executed
+cpu      = cpu time in seconds executing 
+elapsed  = elapsed time in seconds executing
+disk     = number of physical reads of buffers from disk
+query    = number of buffers gotten for consistent read
+current  = number of buffers gotten in current mode (usually for update)
+rows     = number of rows processed by the fetch or execute call
+********************************************************************************
+
+SELECT * FROM COOLTEST_F0001_IOVS
+WHERE "CHANNEL_ID"=0 AND "IOV_SINCE">=0 AND "IOV_UNTIL"<=100001
+ORDER BY "CHANNEL_ID" ASC,"IOV_SINCE" ASC
+
+call     count       cpu    elapsed       disk      query    current        rows
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+Parse        1      0.04       0.01          0          0          0           0
+Execute      1      0.00       0.00          0          0          0           0
+Fetch     1000      1.43       1.43       4089       6055          0       99999
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+total     1002      1.47       1.45       4089       6055          0       99999
+
+Misses in library cache during parse: 1
+Optimizer mode: CHOOSE
+Parsing user id: 25  
+
+Rows     Row Source Operation
+-------  ---------------------------------------------------
+  99999  TABLE ACCESS BY INDEX ROWID COOLTEST_F0001_IOVS 
+  99999   INDEX RANGE SCAN COOLTEST_F0001_IOVS_CSU_3INDX (object id 8142)
+
+
+Elapsed times include waiting on following events:
+  Event waited on                             Times   Max. Wait  Total Waited
+  ----------------------------------------   Waited  ----------  ------------
+  SQL*Net message to client                    1001        0.00          0.00
+  SQL*Net message from client                  1001        0.01          3.85
+  db file sequential read                      4089        0.00          0.18
+  SQL*Net more data to client                  6000        0.00          0.15
+********************************************************************************
+
+select /*+ rule */ bucket_cnt, row_cnt, cache_cnt, null_cnt, timestamp#, 
+  sample_size, minimum, maximum, distcnt, lowval, hival, density, col#, 
+  spare1, spare2, avgcln 
+from
+ hist_head$ where obj#=:1 and intcol#=:2
+
+
+call     count       cpu    elapsed       disk      query    current        rows
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+Parse        1      0.00       0.00          0          0          0           0
+Execute     18      0.00       0.00          0          0          0           0
+Fetch       18      0.00       0.00          2         36          0          18
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+total       37      0.00       0.00          2         36          0          18
+
+Misses in library cache during parse: 1
+Optimizer mode: RULE
+Parsing user id: SYS   (recursive depth: 1)
+
+Elapsed times include waiting on following events:
+  Event waited on                             Times   Max. Wait  Total Waited
+  ----------------------------------------   Waited  ----------  ------------
+  db file sequential read                         2        0.00          0.00
+********************************************************************************
+
+select i.obj#,i.ts#,i.file#,i.block#,i.intcols,i.type#,i.flags, i.property,
+  i.pctfree$,i.initrans,i.maxtrans,i.blevel,i.leafcnt,i.distkey, i.lblkkey,
+  i.dblkkey,i.clufac,i.cols,i.analyzetime,i.samplesize,i.dataobj#, 
+  nvl(i.degree,1),nvl(i.instances,1),i.rowcnt,mod(i.pctthres$,256),
+  i.indmethod#,i.trunccnt,nvl(c.unicols,0),nvl(c.deferrable#+c.valid#,0), 
+  nvl(i.spare1,i.intcols),i.spare4,spare2,spare6, decode(i.pctthres$,null,
+  null, mod(trunc(i.pctthres$/256),256)) 
+from
+ ind$ i, (select enabled, min(cols) unicols, min(to_number(bitand(defer,1))) 
+  deferrable#, min(to_number(bitand(defer,4))) valid# from cdef$ where obj#=
+  :1 and enabled > 1 group by enabled) c where i.obj#=c.enabled(+) and i.bo#=
+  :1
+
+
+call     count       cpu    elapsed       disk      query    current        rows
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+Parse        1      0.00       0.00          0          0          0           0
+Execute      1      0.00       0.00          0          0          0           0
+Fetch        4      0.00       0.00          1          6          0           3
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+total        6      0.00       0.00          1          6          0           3
+
+Misses in library cache during parse: 1
+Optimizer mode: CHOOSE
+Parsing user id: SYS   (recursive depth: 1)
+
+Elapsed times include waiting on following events:
+  Event waited on                             Times   Max. Wait  Total Waited
+  ----------------------------------------   Waited  ----------  ------------
+  db file sequential read                         1        0.00          0.00
+********************************************************************************
+
+select o.owner#,o.name,o.namespace,o.remoteowner,o.linkname,o.subname,
+  o.dataobj#,o.flags 
+from
+ obj$ o where o.obj#=:1
+
+
+call     count       cpu    elapsed       disk      query    current        rows
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+Parse        3      0.00       0.00          0          0          0           0
+Execute      7      0.00       0.00          0          0          0           0
+Fetch        7      0.00       0.00          0         21          0           7
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+total       17      0.00       0.00          0         21          0           7
+
+Misses in library cache during parse: 1
+Optimizer mode: CHOOSE
+Parsing user id: SYS   (recursive depth: 1)
+********************************************************************************
+
+select tc.type#,tc.intcol#,tc.position#,c.type#, c.length,c.scale,
+  c.precision#,c.charsetid,c.charsetform 
+from
+ triggercol$ tc,col$ c ,trigger$ tr where tc.obj#=:1 and c.obj#=:2 and 
+  tc.intcol#=c.intcol# and tr.obj# = tc.obj# and (bitand(tr.property,32) != 
+  32 or bitand(tc.type#,20) = 20) union select type#,intcol#,position#,69,0,0,
+  0,0,0 from triggercol$ where obj#=:3 and intcol#=1001 union select tc.type#,
+  tc.intcol#,tc.position#,121,0,0,0,0,0 from triggercol$ tc,trigger$ tr where 
+  tr.obj# = tc.obj# and bitand(tr.property,32) = 32 and tc.obj# = :4 and 
+  bitand(tc.type#,20) != 20
+
+
+call     count       cpu    elapsed       disk      query    current        rows
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+Parse        1      0.01       0.00          0          0          0           0
+Execute      1      0.00       0.00          0          0          0           0
+Fetch        1      0.00       0.00          0          4          0           0
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+total        3      0.01       0.00          0          4          0           0
+
+Misses in library cache during parse: 1
+Optimizer mode: CHOOSE
+Parsing user id: SYS   (recursive depth: 1)
+
+Rows     Row Source Operation
+-------  ---------------------------------------------------
+      0  SORT UNIQUE 
+      0   UNION-ALL  
+      0    NESTED LOOPS  
+      0     NESTED LOOPS  
+      0      TABLE ACCESS CLUSTER COL$ 
+      0       INDEX UNIQUE SCAN I_OBJ# (object id 3)
+      0      INDEX RANGE SCAN I_TRIGGERCOL2 (object id 133)
+      0     TABLE ACCESS BY INDEX ROWID TRIGGER$ 
+      0      INDEX UNIQUE SCAN I_TRIGGER2 (object id 131)
+      0    INDEX RANGE SCAN I_TRIGGERCOL2 (object id 133)
+      0    NESTED LOOPS  
+      0     INDEX RANGE SCAN I_TRIGGERCOL2 (object id 133)
+      0     TABLE ACCESS BY INDEX ROWID TRIGGER$ 
+      0      INDEX UNIQUE SCAN I_TRIGGER2 (object id 131)
+
+********************************************************************************
+
+select type#,blocks,extents,minexts,maxexts,extsize,extpct,user#,iniexts,
+  NVL(lists,65535),NVL(groups,65535),cachehint,hwmincr, NVL(spare1,0) 
+from
+ seg$ where ts#=:1 and file#=:2 and block#=:3
+
+
+call     count       cpu    elapsed       disk      query    current        rows
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+Parse        4      0.00       0.00          0          0          0           0
+Execute      4      0.00       0.00          0          0          0           0
+Fetch        4      0.00       0.00          0         12          0           4
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+total       12      0.00       0.00          0         12          0           4
+
+Misses in library cache during parse: 1
+Optimizer mode: CHOOSE
+Parsing user id: SYS   (recursive depth: 1)
+
+Rows     Row Source Operation
+-------  ---------------------------------------------------
+      1  TABLE ACCESS CLUSTER SEG$ 
+      1   INDEX UNIQUE SCAN I_FILE#_BLOCK# (object id 9)
+
+********************************************************************************
+
+select owner#,name,namespace,remoteowner,linkname,p_timestamp,p_obj#, 
+  d_owner#, nvl(property,0),subname 
+from
+ dependency$,obj$ where d_obj#=:1 and p_obj#=obj#(+) order by order#
+
+
+call     count       cpu    elapsed       disk      query    current        rows
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+Parse        1      0.00       0.00          0          0          0           0
+Execute      1      0.01       0.00          0          0          0           0
+Fetch        4      0.00       0.00          1         11          0           3
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+total        6      0.01       0.00          1         11          0           3
+
+Misses in library cache during parse: 1
+Optimizer mode: CHOOSE
+Parsing user id: SYS   (recursive depth: 1)
+
+Rows     Row Source Operation
+-------  ---------------------------------------------------
+      3  SORT ORDER BY 
+      3   NESTED LOOPS OUTER 
+      3    TABLE ACCESS BY INDEX ROWID DEPENDENCY$ 
+      3     INDEX RANGE SCAN I_DEPENDENCY1 (object id 127)
+      3    TABLE ACCESS BY INDEX ROWID OBJ$ 
+      3     INDEX UNIQUE SCAN I_OBJ1 (object id 36)
+
+
+Elapsed times include waiting on following events:
+  Event waited on                             Times   Max. Wait  Total Waited
+  ----------------------------------------   Waited  ----------  ------------
+  db file sequential read                         1        0.00          0.00
+********************************************************************************
+
+select name,intcol#,segcol#,type#,length,nvl(precision#,0),decode(type#,2,
+  nvl(scale,-127/*MAXSB1MINAL*/),178,scale,179,scale,180,scale,181,scale,182,
+  scale,183,scale,231,scale,0),null$,fixedstorage,nvl(deflength,0),default$,
+  rowid,col#,property, nvl(charsetid,0),nvl(charsetform,0),spare1,spare2,
+  nvl(spare3,0) 
+from
+ col$ where obj#=:1 order by intcol#
+
+
+call     count       cpu    elapsed       disk      query    current        rows
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+Parse        1      0.00       0.00          0          0          0           0
+Execute      1      0.00       0.00          0          0          0           0
+Fetch       19      0.00       0.00          0          3          0          18
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+total       21      0.00       0.00          0          3          0          18
+
+Misses in library cache during parse: 1
+Optimizer mode: CHOOSE
+Parsing user id: SYS   (recursive depth: 1)
+********************************************************************************
+
+select pos#,intcol#,col#,spare1,bo#,spare2 
+from
+ icol$ where obj#=:1
+
+
+call     count       cpu    elapsed       disk      query    current        rows
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+Parse        1      0.00       0.00          0          0          0           0
+Execute      3      0.00       0.00          0          0          0           0
+Fetch        9      0.00       0.00          1         18          0           6
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+total       13      0.00       0.00          1         18          0           6
+
+Misses in library cache during parse: 1
+Optimizer mode: CHOOSE
+Parsing user id: SYS   (recursive depth: 1)
+
+Elapsed times include waiting on following events:
+  Event waited on                             Times   Max. Wait  Total Waited
+  ----------------------------------------   Waited  ----------  ------------
+  db file sequential read                         1        0.00          0.00
+********************************************************************************
+
+select obj#,type#,ctime,mtime,stime,status,dataobj#,flags,oid$, spare1, 
+  spare2 
+from
+ obj$ where owner#=:1 and name=:2 and namespace=:3 and remoteowner is null 
+  and linkname is null and subname is null
+
+
+call     count       cpu    elapsed       disk      query    current        rows
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+Parse        2      0.00       0.00          0          0          0           0
+Execute      2      0.01       0.00          0          0          0           0
+Fetch        2      0.00       0.00          0          6          0           2
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+total        6      0.01       0.00          0          6          0           2
+
+Misses in library cache during parse: 1
+Optimizer mode: CHOOSE
+Parsing user id: SYS   (recursive depth: 1)
+
+Rows     Row Source Operation
+-------  ---------------------------------------------------
+      1  TABLE ACCESS BY INDEX ROWID OBJ#(18) 
+      1   INDEX RANGE SCAN OBJ#(37) (object id 37)
+
+********************************************************************************
+
+select col#, grantee#, privilege#,max(mod(nvl(option$,0),2)) 
+from
+ objauth$ where obj#=:1 and col# is not null group by privilege#, col#, 
+  grantee# order by col#, grantee#
+
+
+call     count       cpu    elapsed       disk      query    current        rows
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+Parse        1      0.00       0.00          0          0          0           0
+Execute      1      0.00       0.00          0          0          0           0
+Fetch        1      0.00       0.00          1          2          0           0
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+total        3      0.00       0.00          1          2          0           0
+
+Misses in library cache during parse: 1
+Optimizer mode: CHOOSE
+Parsing user id: SYS   (recursive depth: 1)
+
+Elapsed times include waiting on following events:
+  Event waited on                             Times   Max. Wait  Total Waited
+  ----------------------------------------   Waited  ----------  ------------
+  db file sequential read                         1        0.00          0.00
+********************************************************************************
+
+select ts#,file#,block#,nvl(bobj#,0),nvl(tab#,0),intcols,nvl(clucols,0),
+  audit$,flags,pctfree$,pctused$,initrans,maxtrans,rowcnt,blkcnt,empcnt,
+  avgspc,chncnt,avgrln,analyzetime, samplesize,cols,property,nvl(degree,1),
+  nvl(instances,1),avgspc_flb,flbcnt,kernelcols,nvl(trigflag, 0),nvl(spare1,0)
+  ,nvl(spare2,0),spare4,spare6 
+from
+ tab$ where obj#=:1
+
+
+call     count       cpu    elapsed       disk      query    current        rows
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+Parse        1      0.00       0.00          0          0          0           0
+Execute      1      0.00       0.00          0          0          0           0
+Fetch        1      0.00       0.00          1          3          0           1
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+total        3      0.00       0.00          1          3          0           1
+
+Misses in library cache during parse: 1
+Optimizer mode: CHOOSE
+Parsing user id: SYS   (recursive depth: 1)
+
+Rows     Row Source Operation
+-------  ---------------------------------------------------
+      1  TABLE ACCESS CLUSTER OBJ#(4) 
+      1   INDEX UNIQUE SCAN OBJ#(3) (object id 3)
+
+
+Elapsed times include waiting on following events:
+  Event waited on                             Times   Max. Wait  Total Waited
+  ----------------------------------------   Waited  ----------  ------------
+  db file sequential read                         1        0.00          0.00
+********************************************************************************
+
+select grantee#,privilege#,nvl(col#,0),max(mod(nvl(option$,0),2))
+from
+ objauth$ where obj#=:1 group by grantee#,privilege#,nvl(col#,0) order by 
+  grantee#
+
+
+call     count       cpu    elapsed       disk      query    current        rows
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+Parse        1      0.00       0.00          0          0          0           0
+Execute      1      0.00       0.00          0          0          0           0
+Fetch        1      0.00       0.00          0          2          0           0
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+total        3      0.00       0.00          0          2          0           0
+
+Misses in library cache during parse: 1
+Optimizer mode: CHOOSE
+Parsing user id: SYS   (recursive depth: 1)
+********************************************************************************
+
+select intcol#,nvl(pos#,0),col# 
+from
+ ccol$ where con#=:1
+
+
+call     count       cpu    elapsed       disk      query    current        rows
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+Parse        1      0.00       0.00          0          0          0           0
+Execute      1      0.00       0.00          0          0          0           0
+Fetch        2      0.00       0.00          1          4          0           1
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+total        4      0.00       0.00          1          4          0           1
+
+Misses in library cache during parse: 1
+Optimizer mode: CHOOSE
+Parsing user id: SYS   (recursive depth: 1)
+
+Elapsed times include waiting on following events:
+  Event waited on                             Times   Max. Wait  Total Waited
+  ----------------------------------------   Waited  ----------  ------------
+  db file sequential read                         1        0.00          0.00
+********************************************************************************
+
+select con#,type#,condlength,intcols,robj#,rcon#,match#,refact,nvl(enabled,0),
+  rowid,cols,nvl(defer,0),mtime,nvl(spare1,0) 
+from
+ cdef$ where obj#=:1
+
+
+call     count       cpu    elapsed       disk      query    current        rows
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+Parse        1      0.00       0.00          0          0          0           0
+Execute      1      0.00       0.00          0          0          0           0
+Fetch        2      0.00       0.00          0          4          0           1
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+total        4      0.00       0.00          0          4          0           1
+
+Misses in library cache during parse: 1
+Optimizer mode: CHOOSE
+Parsing user id: SYS   (recursive depth: 1)
+********************************************************************************
+
+select order#,columns,types 
+from
+ access$ where d_obj#=:1
+
+
+call     count       cpu    elapsed       disk      query    current        rows
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+Parse        1      0.00       0.00          0          0          0           0
+Execute      1      0.00       0.00          0          0          0           0
+Fetch        3      0.00       0.00          0          6          0           2
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+total        5      0.00       0.00          0          6          0           2
+
+Misses in library cache during parse: 1
+Optimizer mode: CHOOSE
+Parsing user id: SYS   (recursive depth: 1)
+
+Rows     Row Source Operation
+-------  ---------------------------------------------------
+      2  TABLE ACCESS BY INDEX ROWID ACCESS$ 
+      2   INDEX RANGE SCAN I_ACCESS1 (object id 129)
+
+********************************************************************************
+
+select con#,obj#,rcon#,enabled,nvl(defer,0) 
+from
+ cdef$ where robj#=:1
+
+
+call     count       cpu    elapsed       disk      query    current        rows
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+Parse        1      0.00       0.00          0          0          0           0
+Execute      1      0.00       0.00          0          0          0           0
+Fetch        1      0.00       0.00          0          1          0           0
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+total        3      0.00       0.00          0          1          0           0
+
+Misses in library cache during parse: 1
+Optimizer mode: CHOOSE
+Parsing user id: SYS   (recursive depth: 1)
+********************************************************************************
+
+select baseobject,type#,update$,insert$,delete$,refnewname,refoldname,
+  whenclause,definition,enabled,property,sys_evts,nttrigcol,nttrigatt,
+  refprtname,rowid 
+from
+ trigger$ where obj# =:1
+
+
+call     count       cpu    elapsed       disk      query    current        rows
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+Parse        1      0.00       0.00          0          0          0           0
+Execute      1      0.00       0.00          0          0          0           0
+Fetch        1      0.00       0.00          0          2          0           1
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+total        3      0.00       0.00          0          2          0           1
+
+Misses in library cache during parse: 1
+Optimizer mode: CHOOSE
+Parsing user id: SYS   (recursive depth: 1)
+
+Rows     Row Source Operation
+-------  ---------------------------------------------------
+      1  TABLE ACCESS BY INDEX ROWID TRIGGER$ 
+      1   INDEX UNIQUE SCAN I_TRIGGER2 (object id 131)
+
+********************************************************************************
+
+select action# 
+from
+ trigger$ where obj# = :1
+
+
+call     count       cpu    elapsed       disk      query    current        rows
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+Parse        1      0.00       0.00          0          0          0           0
+Execute      1      0.00       0.00          0          0          0           0
+Fetch        1      0.00       0.00          0          3          0           1
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+total        3      0.00       0.00          0          3          0           1
+
+Misses in library cache during parse: 1
+Optimizer mode: CHOOSE
+Parsing user id: SYS   (recursive depth: 1)
+
+Rows     Row Source Operation
+-------  ---------------------------------------------------
+      1  TABLE ACCESS BY INDEX ROWID TRIGGER$ 
+      1   INDEX UNIQUE SCAN I_TRIGGER2 (object id 131)
+
+********************************************************************************
+
+select audit$,options 
+from
+ procedure$ where obj#=:1
+
+
+call     count       cpu    elapsed       disk      query    current        rows
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+Parse        1      0.00       0.00          0          0          0           0
+Execute      1      0.00       0.00          0          0          0           0
+Fetch        1      0.00       0.00          0          3          0           1
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+total        3      0.00       0.00          0          3          0           1
+
+Misses in library cache during parse: 1
+Optimizer mode: CHOOSE
+Parsing user id: SYS   (recursive depth: 1)
+
+Rows     Row Source Operation
+-------  ---------------------------------------------------
+      1  TABLE ACCESS BY INDEX ROWID PROCEDURE$ 
+      1   INDEX UNIQUE SCAN I_PROCEDURE1 (object id 115)
+
+********************************************************************************
+
+select actionsize 
+from
+ trigger$ where obj# = :1
+
+
+call     count       cpu    elapsed       disk      query    current        rows
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+Parse        1      0.00       0.00          0          0          0           0
+Execute      1      0.00       0.00          0          0          0           0
+Fetch        1      0.00       0.00          0          2          0           1
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+total        3      0.00       0.00          0          2          0           1
+
+Misses in library cache during parse: 1
+Optimizer mode: CHOOSE
+Parsing user id: SYS   (recursive depth: 1)
+
+Rows     Row Source Operation
+-------  ---------------------------------------------------
+      1  TABLE ACCESS BY INDEX ROWID TRIGGER$ 
+      1   INDEX UNIQUE SCAN I_TRIGGER2 (object id 131)
+
+********************************************************************************
+
+commit
+
+
+call     count       cpu    elapsed       disk      query    current        rows
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+Parse        2      0.00       0.00          0          0          0           0
+Execute      2      0.00       0.00          0          0          0           0
+Fetch        0      0.00       0.00          0          0          0           0
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+total        4      0.00       0.00          0          0          0           0
+
+Misses in library cache during parse: 1
+Optimizer mode: CHOOSE
+Parsing user id: 25  
+
+Elapsed times include waiting on following events:
+  Event waited on                             Times   Max. Wait  Total Waited
+  ----------------------------------------   Waited  ----------  ------------
+  SQL*Net message to client                       2        0.00          0.00
+  SQL*Net message from client                     2        6.92          6.94
+********************************************************************************
+
+alter session set events '10046 trace name context level 12, forever'
+
+
+call     count       cpu    elapsed       disk      query    current        rows
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+Parse        0      0.00       0.00          0          0          0           0
+Execute      1      0.00       0.00          0          0          0           0
+Fetch        0      0.00       0.00          0          0          0           0
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+total        1      0.00       0.00          0          0          0           0
+
+Misses in library cache during parse: 0
+Misses in library cache during execute: 1
+Optimizer mode: CHOOSE
+Parsing user id: 25  
+
+Elapsed times include waiting on following events:
+  Event waited on                             Times   Max. Wait  Total Waited
+  ----------------------------------------   Waited  ----------  ------------
+  SQL*Net message to client                       1        0.00          0.00
+  SQL*Net message from client                     1        0.00          0.00
+********************************************************************************
+
+set transaction read only
+
+
+call     count       cpu    elapsed       disk      query    current        rows
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+Parse        1      0.00       0.00          0          0          0           0
+Execute      1      0.00       0.00          0          0          0           0
+Fetch        0      0.00       0.00          0          0          0           0
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+total        2      0.00       0.00          0          0          0           0
+
+Misses in library cache during parse: 1
+Optimizer mode: CHOOSE
+Parsing user id: 25  
+
+Elapsed times include waiting on following events:
+  Event waited on                             Times   Max. Wait  Total Waited
+  ----------------------------------------   Waited  ----------  ------------
+  SQL*Net message to client                       1        0.00          0.00
+  SQL*Net message from client                     1        0.01          0.01
+
+
+
+********************************************************************************
+
+OVERALL TOTALS FOR ALL NON-RECURSIVE STATEMENTS
+
+call     count       cpu    elapsed       disk      query    current        rows
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+Parse        4      0.04       0.01          0          0          0           0
+Execute      5      0.00       0.00          0          0          0           0
+Fetch     1000      1.43       1.43       4089       6055          0       99999
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+total     1009      1.47       1.45       4089       6055          0       99999
+
+Misses in library cache during parse: 3
+Misses in library cache during execute: 1
+
+Elapsed times include waiting on following events:
+  Event waited on                             Times   Max. Wait  Total Waited
+  ----------------------------------------   Waited  ----------  ------------
+  SQL*Net message to client                    1005        0.00          0.00
+  SQL*Net message from client                  1005        6.92         10.81
+  db file sequential read                      4089        0.00          0.18
+  SQL*Net more data to client                  6000        0.00          0.15
+
+
+OVERALL TOTALS FOR ALL RECURSIVE STATEMENTS
+
+call     count       cpu    elapsed       disk      query    current        rows
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+Parse       26      0.01       0.01          0          0          0           0
+Execute     49      0.02       0.01          0          0          0           0
+Fetch       83      0.00       0.00          8        149          0          70
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+total      158      0.03       0.03          8        149          0          70
+
+Misses in library cache during parse: 20
+
+Elapsed times include waiting on following events:
+  Event waited on                             Times   Max. Wait  Total Waited
+  ----------------------------------------   Waited  ----------  ------------
+  db file sequential read                         8        0.00          0.00
+
+    5  user  SQL statements in session.
+   26  internal SQL statements in session.
+   31  SQL statements in session.
+********************************************************************************
+Trace file: benthic1.trc
+Trace file compatibility: 9.02.00
+Sort options: exeela  fchela  
+       1  session in tracefile.
+       5  user  SQL statements in trace file.
+      26  internal SQL statements in trace file.
+      31  SQL statements in trace file.
+      24  unique SQL statements in trace file.
+   13762  lines in trace file.
+      12  elapsed seconds in trace file.
+
+
diff --git a/RelationalCool/tests/PerformanceAV/ServerCache/100k-ora-benthic-next.prf b/RelationalCool/tests/PerformanceAV/ServerCache/100k-ora-benthic-next.prf
new file mode 100644
index 000000000..b93cce94f
--- /dev/null
+++ b/RelationalCool/tests/PerformanceAV/ServerCache/100k-ora-benthic-next.prf
@@ -0,0 +1,164 @@
+
+TKPROF: Release 10.1.0.2.0 - Production on Mon Jan 31 11:46:17 2005
+
+Copyright (c) 1982, 2004, Oracle.  All rights reserved.
+
+Trace file: benthic2.trc
+Sort options: exeela  fchela  
+********************************************************************************
+count    = number of times OCI procedure was executed
+cpu      = cpu time in seconds executing 
+elapsed  = elapsed time in seconds executing
+disk     = number of physical reads of buffers from disk
+query    = number of buffers gotten for consistent read
+current  = number of buffers gotten in current mode (usually for update)
+rows     = number of rows processed by the fetch or execute call
+********************************************************************************
+
+SELECT * FROM COOLTEST_F0001_IOVS
+WHERE "CHANNEL_ID"=0 AND "IOV_SINCE">=0 AND "IOV_UNTIL"<=100001
+ORDER BY "CHANNEL_ID" ASC,"IOV_SINCE" ASC
+
+call     count       cpu    elapsed       disk      query    current        rows
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+Parse        1      0.00       0.00          0          0          0           0
+Execute      1      0.00       0.00          0          0          0           0
+Fetch     1000      1.22       1.13          0       6055          0       99999
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+total     1002      1.22       1.13          0       6055          0       99999
+
+Misses in library cache during parse: 0
+Optimizer mode: CHOOSE
+Parsing user id: 25  
+
+Rows     Row Source Operation
+-------  ---------------------------------------------------
+  99999  TABLE ACCESS BY INDEX ROWID COOLTEST_F0001_IOVS 
+  99999   INDEX RANGE SCAN COOLTEST_F0001_IOVS_CSU_3INDX (object id 8142)
+
+
+Elapsed times include waiting on following events:
+  Event waited on                             Times   Max. Wait  Total Waited
+  ----------------------------------------   Waited  ----------  ------------
+  SQL*Net message to client                    1001        0.00          0.00
+  SQL*Net message from client                  1001        0.02          4.29
+  SQL*Net more data to client                  6000        0.00          0.12
+********************************************************************************
+
+commit
+
+
+call     count       cpu    elapsed       disk      query    current        rows
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+Parse        2      0.00       0.00          0          0          0           0
+Execute      2      0.00       0.00          0          0          0           0
+Fetch        0      0.00       0.00          0          0          0           0
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+total        4      0.00       0.00          0          0          0           0
+
+Misses in library cache during parse: 0
+Optimizer mode: CHOOSE
+Parsing user id: 25  
+
+Elapsed times include waiting on following events:
+  Event waited on                             Times   Max. Wait  Total Waited
+  ----------------------------------------   Waited  ----------  ------------
+  SQL*Net message to client                       2        0.00          0.00
+  SQL*Net message from client                     2        4.06          4.07
+********************************************************************************
+
+alter session set events '10046 trace name context level 12, forever'
+
+
+call     count       cpu    elapsed       disk      query    current        rows
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+Parse        0      0.00       0.00          0          0          0           0
+Execute      1      0.00       0.00          0          0          0           0
+Fetch        0      0.00       0.00          0          0          0           0
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+total        1      0.00       0.00          0          0          0           0
+
+Misses in library cache during parse: 0
+Optimizer mode: CHOOSE
+Parsing user id: 25  
+
+Elapsed times include waiting on following events:
+  Event waited on                             Times   Max. Wait  Total Waited
+  ----------------------------------------   Waited  ----------  ------------
+  SQL*Net message to client                       1        0.00          0.00
+  SQL*Net message from client                     1        0.00          0.00
+********************************************************************************
+
+set transaction read only
+
+
+call     count       cpu    elapsed       disk      query    current        rows
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+Parse        1      0.00       0.00          0          0          0           0
+Execute      1      0.00       0.00          0          0          0           0
+Fetch        0      0.00       0.00          0          0          0           0
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+total        2      0.00       0.00          0          0          0           0
+
+Misses in library cache during parse: 0
+Optimizer mode: CHOOSE
+Parsing user id: 25  
+
+Elapsed times include waiting on following events:
+  Event waited on                             Times   Max. Wait  Total Waited
+  ----------------------------------------   Waited  ----------  ------------
+  SQL*Net message to client                       1        0.00          0.00
+  SQL*Net message from client                     1        0.01          0.01
+
+
+
+********************************************************************************
+
+OVERALL TOTALS FOR ALL NON-RECURSIVE STATEMENTS
+
+call     count       cpu    elapsed       disk      query    current        rows
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+Parse        4      0.00       0.00          0          0          0           0
+Execute      5      0.00       0.00          0          0          0           0
+Fetch     1000      1.22       1.13          0       6055          0       99999
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+total     1009      1.22       1.13          0       6055          0       99999
+
+Misses in library cache during parse: 0
+
+Elapsed times include waiting on following events:
+  Event waited on                             Times   Max. Wait  Total Waited
+  ----------------------------------------   Waited  ----------  ------------
+  SQL*Net message to client                    1005        0.00          0.00
+  SQL*Net message from client                  1005        4.06          8.39
+  SQL*Net more data to client                  6000        0.00          0.12
+
+
+OVERALL TOTALS FOR ALL RECURSIVE STATEMENTS
+
+call     count       cpu    elapsed       disk      query    current        rows
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+Parse        0      0.00       0.00          0          0          0           0
+Execute      0      0.00       0.00          0          0          0           0
+Fetch        0      0.00       0.00          0          0          0           0
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+total        0      0.00       0.00          0          0          0           0
+
+Misses in library cache during parse: 0
+
+    5  user  SQL statements in session.
+    0  internal SQL statements in session.
+    5  SQL statements in session.
+********************************************************************************
+Trace file: benthic2.trc
+Trace file compatibility: 9.02.00
+Sort options: exeela  fchela  
+       1  session in tracefile.
+       5  user  SQL statements in trace file.
+       0  internal SQL statements in trace file.
+       5  SQL statements in trace file.
+       4  unique SQL statements in trace file.
+    9066  lines in trace file.
+       5  elapsed seconds in trace file.
+
+
diff --git a/RelationalCool/tests/PerformanceAV/ServerCache/100k-ora-cool-first.out b/RelationalCool/tests/PerformanceAV/ServerCache/100k-ora-cool-first.out
new file mode 100644
index 000000000..baa58c2de
--- /dev/null
+++ b/RelationalCool/tests/PerformanceAV/ServerCache/100k-ora-cool-first.out
@@ -0,0 +1,82 @@
+Property Catalogue: level[Info] Adding property: OutputLevel = 2 in scope "SEAL/Services/MessageService"
+Property Catalogue: level[Info] Adding property: Format =  "%-36s %-8s %s" in scope "SEAL/Services/MessageService"
+MessageService callback    Debug MessageService output level changed to Debug
+ConfigurationService    Debug Setting property: "Format" to value " "%-36s %-8s %s"" in scope "SEAL/Services/MessageService"
+POOL/Services/RelationalService      Info     Found plugin for RDBMS technology "mysql" with implementation "odbc"
+POOL/Services/RelationalService      Info     Found plugin for RDBMS technology "oracle" with native implementation
+POOL/Services/RelationalService      Info     Default implementation for RDBMS technology "mysql" is "odbc"
+POOL/Services/RelationalService      Info     Default implementation for RDBMS technology "oracle" is native
+RelationalDatabase                   Debug    Instantiate a RelationalDatabase for 'oracle://cooldb2;schema=AVALASSI;user=avalassi;password=andrea;dbname=COOLTEST'
+RelationalDatabase                   Info     Instantiate a RalDatabase for 'oracle://cooldb2;schema=AVALASSI;user=avalassi;password=andrea;dbname=COOLTEST'
+POOL/RelationalPlugins/oracle        Info     Connected to a server running Oracle version 9.2.0.6.0
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "alter session set events '10046 trace name context forever, level 12'"
+POOL/RelationalPlugins/oracle        Warning  SQL_TRACE enabled
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT TABLE_NAME FROM ALL_TABLES WHERE OWNER = 'AVALASSI'"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT "DB_ATTRIBUTE_NAME", "DB_ATTRIBUTE_VALUE" FROM "AVALASSI"."COOLTEST_DB_ATTRIBUTES""
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_ISLEAF", "NODE_INSTIME", "FOLDER_PAYLOADSPEC", "FOLDER_VERSIONING", "FOLDER_IOVTABLENAME" FROM "AVALASSI"."COOLTEST_FOLDERS" WHERE "NODE_FULLPATH"=:"fullName""
+RelationalFolder                     Debug    Instantiate a RelationalFolder for '/myfolder'
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT "OBJECT_ID", "CHANNEL_ID", "IOV_SINCE", "IOV_UNTIL", "SYS_INSTIME", "I", "S", "X0", "X1", "X2", "X3", "X4", "X5", "X6", "X7", "X8", "X9", "P" FROM "AVALASSI"."COOLTEST_F0001_IOVS" WHERE "CHANNEL_ID"=:"channel" AND "IOV_SINCE">=:"since" AND "IOV_UNTIL"<=:"till" ORDER BY "CHANNEL_ID" ASC,"IOV_SINCE" ASC"
+>>>>>>    Timing Results  <<<<<<<<<< 
+----- 1.PrepareQuery----------- :                              ( n=1 )
+Total Real Time  :      0.010 +/-      0.010 s
+Total User Time  :      0.000 +/-      0.000 s
+Total System Time:      0.000 +/-      0.000 s
+Total Idle Time  :      0.010 +/-      0.010 s
+----- 2.ProcessQuery----------- :                              ( n=1 )
+Total Real Time  :      4.980 +/-      4.980 s
+Total User Time  :      0.230 +/-      0.230 s
+Total System Time:      0.210 +/-      0.210 s
+Total Idle Time  :      4.540 +/-      4.540 s
+----- 3.FetchRows-------------- :                              ( n=100001 )
+Total Real Time  :     41.630 +/-      0.132 s
+Total User Time  :      6.290 +/-      0.020 s
+Total System Time:      0.440 +/-      0.001 s
+Total Idle Time  :     35.010 +/-      0.111 s
+----- 4.CopyAttributeList------ :                              ( n=100000 )
+Total Real Time  :     58.130 +/-      0.184 s
+Total User Time  :     57.540 +/-      0.182 s
+Total System Time:      0.830 +/-      0.003 s
+Total Idle Time  :     -0.260 +/-     -0.001 s
+----- 5.CloseQuery------------- :                              ( n=1 )
+Total Real Time  :      0.010 +/-      0.010 s
+Total User Time  :      0.010 +/-      0.010 s
+Total System Time:      0.000 +/-      0.000 s
+Total Idle Time  :      0.000 +/-      0.000 s
+----- TOTAL FetchObjRowsByVal-- :                              ( n=1 )
+Total Real Time  :    105.760 +/-    105.760 s
+Total User Time  :     64.740 +/-     64.740 s
+Total System Time:      1.610 +/-      1.610 s
+Total Idle Time  :     39.410 +/-     39.410 s
+>>>>>>    Timing Results  <<<<<<<<<< 
+----- 1.FetchObjRowsByVal----- :                              ( n=1 )
+Total Real Time  :    105.760 +/-    105.760 s
+Total User Time  :     64.740 +/-     64.740 s
+Total System Time:      1.610 +/-      1.610 s
+Total Idle Time  :     39.410 +/-     39.410 s
+----- 2.DecodeRow------------- :                              ( n=1 )
+Total Real Time  :      9.780 +/-      9.780 s
+Total User Time  :      9.470 +/-      9.470 s
+Total System Time:      0.210 +/-      0.210 s
+Total Idle Time  :      0.100 +/-      0.100 s
+----- 3.DeleteOld------------- :                              ( n=1 )
+Total Real Time  :      1.560 +/-      1.560 s
+Total User Time  :      1.550 +/-      1.550 s
+Total System Time:      0.000 +/-      0.000 s
+Total Idle Time  :      0.010 +/-      0.010 s
+----- TOTAL BrowseObjInTag---- :                              ( n=1 )
+Total Real Time  :    117.100 +/-    117.100 s
+Total User Time  :     75.760 +/-     75.760 s
+Total System Time:      1.820 +/-      1.820 s
+Total Idle Time  :     39.520 +/-     39.520 s
+** reading 100000 objects (150 bytes mixed) **
+read back 100000 objects
+sec total: 117.115
+obj/s:     853.865
+RelationalFolder                     Debug    Delete the RelationalFolder for '/myfolder'
+sec total (INCLUDING DELETE): 118.388
+
+OK (1)
+[OVAL] Cppunit-result =0
+RelationalDatabase                   Info     Delete the RalDatabase for 'oracle://cooldb2;schema=AVALASSI;user=avalassi;password=andrea;dbname=COOLTEST'
+POOL/RelationalPlugins/oracle        Warning  No active transaction to roll back
+RelationalDatabase                   Debug    Delete the RelationalDatabase for 'oracle://cooldb2;schema=AVALASSI;user=avalassi;password=andrea;dbname=COOLTEST'
diff --git a/RelationalCool/tests/PerformanceAV/ServerCache/100k-ora-cool-first.prf b/RelationalCool/tests/PerformanceAV/ServerCache/100k-ora-cool-first.prf
new file mode 100644
index 000000000..390a7b353
--- /dev/null
+++ b/RelationalCool/tests/PerformanceAV/ServerCache/100k-ora-cool-first.prf
@@ -0,0 +1,898 @@
+
+TKPROF: Release 10.1.0.2.0 - Production on Mon Jan 31 11:39:28 2005
+
+Copyright (c) 1982, 2004, Oracle.  All rights reserved.
+
+Trace file: pluto1.trc
+Sort options: exeela  fchela  
+********************************************************************************
+count    = number of times OCI procedure was executed
+cpu      = cpu time in seconds executing 
+elapsed  = elapsed time in seconds executing
+disk     = number of physical reads of buffers from disk
+query    = number of buffers gotten for consistent read
+current  = number of buffers gotten in current mode (usually for update)
+rows     = number of rows processed by the fetch or execute call
+********************************************************************************
+
+SELECT "OBJECT_ID", "CHANNEL_ID", "IOV_SINCE", "IOV_UNTIL", "SYS_INSTIME", 
+  "I", "S", "X0", "X1", "X2", "X3", "X4", "X5", "X6", "X7", "X8", "X9", "P" 
+FROM
+ "AVALASSI"."COOLTEST_F0001_IOVS" WHERE "CHANNEL_ID"=:"channel" AND 
+  "IOV_SINCE">=:"since" AND "IOV_UNTIL"<=:"till" ORDER BY "CHANNEL_ID" ASC,
+  "IOV_SINCE" ASC
+
+
+call     count       cpu    elapsed       disk      query    current        rows
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+Parse        1      0.00       0.00          0         30          0           0
+Execute      1      0.00       0.00          0          0          0           0
+Fetch       20     39.80      40.15       7409     298624    1445689      194981
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+total       22     39.80      40.15       7409     298654    1445689      194981
+
+Misses in library cache during parse: 1
+Optimizer mode: CHOOSE
+Parsing user id: 25  
+
+Rows     Row Source Operation
+-------  ---------------------------------------------------
+ 100000  SORT ORDER BY 
+ 100000   TABLE ACCESS FULL COOLTEST_F0001_IOVS 
+
+
+Elapsed times include waiting on following events:
+  Event waited on                             Times   Max. Wait  Total Waited
+  ----------------------------------------   Waited  ----------  ------------
+  SQL*Net message to client                      20        0.00          0.00
+  db file sequential read                         1        0.00          0.00
+  db file scattered read                        252        0.00          0.24
+  direct path write                               4        0.00          0.00
+  direct path read                               69        0.00          0.00
+  SQL*Net more data to client                 13468        0.00          0.51
+  SQL*Net message from client                    20        6.10         63.10
+********************************************************************************
+
+select i.obj#,i.ts#,i.file#,i.block#,i.intcols,i.type#,i.flags, i.property,
+  i.pctfree$,i.initrans,i.maxtrans,i.blevel,i.leafcnt,i.distkey, i.lblkkey,
+  i.dblkkey,i.clufac,i.cols,i.analyzetime,i.samplesize,i.dataobj#, 
+  nvl(i.degree,1),nvl(i.instances,1),i.rowcnt,mod(i.pctthres$,256),
+  i.indmethod#,i.trunccnt,nvl(c.unicols,0),nvl(c.deferrable#+c.valid#,0), 
+  nvl(i.spare1,i.intcols),i.spare4,spare2,spare6, decode(i.pctthres$,null,
+  null, mod(trunc(i.pctthres$/256),256)) 
+from
+ ind$ i, (select enabled, min(cols) unicols, min(to_number(bitand(defer,1))) 
+  deferrable#, min(to_number(bitand(defer,4))) valid# from cdef$ where obj#=
+  :1 and enabled > 1 group by enabled) c where i.obj#=c.enabled(+) and i.bo#=
+  :1
+
+
+call     count       cpu    elapsed       disk      query    current        rows
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+Parse        4      0.01       0.00          0          0          0           0
+Execute      5      0.00       0.00          0          0          0           0
+Fetch       13      0.00       0.00          1         30          0           8
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+total       22      0.01       0.00          1         30          0           8
+
+Misses in library cache during parse: 1
+Optimizer mode: CHOOSE
+Parsing user id: SYS   (recursive depth: 2)
+
+Rows     Row Source Operation
+-------  ---------------------------------------------------
+      2  MERGE JOIN OUTER 
+      2   SORT JOIN 
+      2    TABLE ACCESS CLUSTER OBJ#(19) 
+      2     INDEX UNIQUE SCAN OBJ#(3) (object id 3)
+      0   SORT JOIN 
+      0    VIEW  
+      0     SORT GROUP BY 
+      0      TABLE ACCESS CLUSTER OBJ#(31) 
+      2       INDEX UNIQUE SCAN OBJ#(30) (object id 30)
+
+
+Elapsed times include waiting on following events:
+  Event waited on                             Times   Max. Wait  Total Waited
+  ----------------------------------------   Waited  ----------  ------------
+  db file sequential read                         1        0.00          0.00
+********************************************************************************
+
+select name,intcol#,segcol#,type#,length,nvl(precision#,0),decode(type#,2,
+  nvl(scale,-127/*MAXSB1MINAL*/),178,scale,179,scale,180,scale,181,scale,182,
+  scale,183,scale,231,scale,0),null$,fixedstorage,nvl(deflength,0),default$,
+  rowid,col#,property, nvl(charsetid,0),nvl(charsetform,0),spare1,spare2,
+  nvl(spare3,0) 
+from
+ col$ where obj#=:1 order by intcol#
+
+
+call     count       cpu    elapsed       disk      query    current        rows
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+Parse        4      0.00       0.00          0          0          0           0
+Execute      6      0.00       0.00          0          0          0           0
+Fetch       94      0.00       0.00          1         19          0          88
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+total      104      0.00       0.00          1         19          0          88
+
+Misses in library cache during parse: 1
+Optimizer mode: CHOOSE
+Parsing user id: SYS   (recursive depth: 1)
+
+Rows     Row Source Operation
+-------  ---------------------------------------------------
+     59  SORT ORDER BY 
+     59   TABLE ACCESS CLUSTER OBJ#(21) 
+      3    INDEX UNIQUE SCAN OBJ#(3) (object id 3)
+
+
+Elapsed times include waiting on following events:
+  Event waited on                             Times   Max. Wait  Total Waited
+  ----------------------------------------   Waited  ----------  ------------
+  db file sequential read                         1        0.00          0.00
+********************************************************************************
+
+select /*+ rule */ bucket_cnt, row_cnt, cache_cnt, null_cnt, timestamp#, 
+  sample_size, minimum, maximum, distcnt, lowval, hival, density, col#, 
+  spare1, spare2, avgcln 
+from
+ hist_head$ where obj#=:1 and intcol#=:2
+
+
+call     count       cpu    elapsed       disk      query    current        rows
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+Parse        1      0.00       0.00          0          0          0           0
+Execute     18      0.00       0.00          0          0          0           0
+Fetch       18      0.00       0.00          2         36          0          18
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+total       37      0.00       0.00          2         36          0          18
+
+Misses in library cache during parse: 1
+Optimizer mode: RULE
+Parsing user id: SYS   (recursive depth: 1)
+
+Elapsed times include waiting on following events:
+  Event waited on                             Times   Max. Wait  Total Waited
+  ----------------------------------------   Waited  ----------  ------------
+  db file sequential read                         2        0.00          0.00
+********************************************************************************
+
+select obj#,type#,ctime,mtime,stime,status,dataobj#,flags,oid$, spare1, 
+  spare2 
+from
+ obj$ where owner#=:1 and name=:2 and namespace=:3 and remoteowner is null 
+  and linkname is null and subname is null
+
+
+call     count       cpu    elapsed       disk      query    current        rows
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+Parse        4      0.00       0.00          0          0          0           0
+Execute     10      0.00       0.00          0          0          0           0
+Fetch       10      0.00       0.00          3         27          0           7
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+total       24      0.00       0.00          3         27          0           7
+
+Misses in library cache during parse: 1
+Optimizer mode: CHOOSE
+Parsing user id: SYS   (recursive depth: 1)
+
+Elapsed times include waiting on following events:
+  Event waited on                             Times   Max. Wait  Total Waited
+  ----------------------------------------   Waited  ----------  ------------
+  db file sequential read                         3        0.00          0.00
+********************************************************************************
+
+select type#,blocks,extents,minexts,maxexts,extsize,extpct,user#,iniexts,
+  NVL(lists,65535),NVL(groups,65535),cachehint,hwmincr, NVL(spare1,0) 
+from
+ seg$ where ts#=:1 and file#=:2 and block#=:3
+
+
+call     count       cpu    elapsed       disk      query    current        rows
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+Parse       11      0.00       0.00          0          0          0           0
+Execute     11      0.00       0.00          0          0          0           0
+Fetch       11      0.00       0.00          0         33          0          11
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+total       33      0.00       0.00          0         33          0          11
+
+Misses in library cache during parse: 1
+Optimizer mode: CHOOSE
+Parsing user id: SYS   (recursive depth: 2)
+
+Rows     Row Source Operation
+-------  ---------------------------------------------------
+      1  TABLE ACCESS CLUSTER SEG$ 
+      1   INDEX UNIQUE SCAN I_FILE#_BLOCK# (object id 9)
+
+********************************************************************************
+
+select o.owner#,o.name,o.namespace,o.remoteowner,o.linkname,o.subname,
+  o.dataobj#,o.flags 
+from
+ obj$ o where o.obj#=:1
+
+
+call     count       cpu    elapsed       disk      query    current        rows
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+Parse        7      0.00       0.00          0          0          0           0
+Execute     15      0.00       0.00          0          0          0           0
+Fetch       15      0.00       0.00          0         45          0          15
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+total       37      0.00       0.00          0         45          0          15
+
+Misses in library cache during parse: 1
+Optimizer mode: CHOOSE
+Parsing user id: SYS   (recursive depth: 1)
+********************************************************************************
+
+select pos#,intcol#,col#,spare1,bo#,spare2 
+from
+ icol$ where obj#=:1
+
+
+call     count       cpu    elapsed       disk      query    current        rows
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+Parse        4      0.00       0.00          0          0          0           0
+Execute      8      0.00       0.00          0          0          0           0
+Fetch       19      0.00       0.00          1         38          0          11
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+total       31      0.00       0.00          1         38          0          11
+
+Misses in library cache during parse: 1
+Optimizer mode: CHOOSE
+Parsing user id: SYS   (recursive depth: 2)
+
+Rows     Row Source Operation
+-------  ---------------------------------------------------
+      2  TABLE ACCESS BY INDEX ROWID OBJ#(20) 
+      2   INDEX RANGE SCAN OBJ#(40) (object id 40)
+
+
+Elapsed times include waiting on following events:
+  Event waited on                             Times   Max. Wait  Total Waited
+  ----------------------------------------   Waited  ----------  ------------
+  db file sequential read                         1        0.00          0.00
+********************************************************************************
+
+select col#, grantee#, privilege#,max(mod(nvl(option$,0),2)) 
+from
+ objauth$ where obj#=:1 and col# is not null group by privilege#, col#, 
+  grantee# order by col#, grantee#
+
+
+call     count       cpu    elapsed       disk      query    current        rows
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+Parse        4      0.00       0.00          0          0          0           0
+Execute      4      0.01       0.00          0          0          0           0
+Fetch        4      0.01       0.00          2          8          0           0
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+total       12      0.02       0.00          2          8          0           0
+
+Misses in library cache during parse: 1
+Optimizer mode: CHOOSE
+Parsing user id: SYS   (recursive depth: 1)
+
+Elapsed times include waiting on following events:
+  Event waited on                             Times   Max. Wait  Total Waited
+  ----------------------------------------   Waited  ----------  ------------
+  db file sequential read                         2        0.00          0.00
+********************************************************************************
+
+SELECT "DB_ATTRIBUTE_NAME", "DB_ATTRIBUTE_VALUE" 
+FROM
+ "AVALASSI"."COOLTEST_DB_ATTRIBUTES"
+
+
+call     count       cpu    elapsed       disk      query    current        rows
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+Parse        1      0.00       0.00          1         15          0           0
+Execute      1      0.00       0.00          0          0          0           0
+Fetch        3      0.01       0.00          5         10         19           2
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+total        5      0.01       0.00          6         25         19           2
+
+Misses in library cache during parse: 1
+Optimizer mode: CHOOSE
+Parsing user id: 25  
+
+Rows     Row Source Operation
+-------  ---------------------------------------------------
+      2  TABLE ACCESS FULL COOLTEST_DB_ATTRIBUTES 
+
+
+Elapsed times include waiting on following events:
+  Event waited on                             Times   Max. Wait  Total Waited
+  ----------------------------------------   Waited  ----------  ------------
+  SQL*Net message to client                       3        0.00          0.00
+  db file scattered read                          1        0.00          0.00
+  SQL*Net message from client                     3        0.00          0.00
+********************************************************************************
+
+select grantee#,privilege#,nvl(col#,0),max(mod(nvl(option$,0),2))
+from
+ objauth$ where obj#=:1 group by grantee#,privilege#,nvl(col#,0) order by 
+  grantee#
+
+
+call     count       cpu    elapsed       disk      query    current        rows
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+Parse        4      0.00       0.00          0          0          0           0
+Execute      4      0.00       0.00          0          0          0           0
+Fetch        5      0.00       0.00          1          9          0           1
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+total       13      0.00       0.00          1          9          0           1
+
+Misses in library cache during parse: 1
+Optimizer mode: CHOOSE
+Parsing user id: SYS   (recursive depth: 1)
+
+Elapsed times include waiting on following events:
+  Event waited on                             Times   Max. Wait  Total Waited
+  ----------------------------------------   Waited  ----------  ------------
+  db file sequential read                         1        0.00          0.00
+********************************************************************************
+
+SELECT TABLE_NAME 
+FROM
+ ALL_TABLES WHERE OWNER = 'AVALASSI'
+
+
+call     count       cpu    elapsed       disk      query    current        rows
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+Parse        1      0.03       0.02          0          9          0           0
+Execute      1      0.00       0.00          0          0          0           0
+Fetch        1      0.00       0.00          4        122          0           8
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+total        3      0.03       0.02          4        131          0           8
+
+Misses in library cache during parse: 1
+Optimizer mode: CHOOSE
+Parsing user id: 25  
+
+Rows     Row Source Operation
+-------  ---------------------------------------------------
+      8  FILTER  
+      8   NESTED LOOPS  
+      8    NESTED LOOPS OUTER 
+      8     NESTED LOOPS OUTER 
+      8      NESTED LOOPS OUTER 
+      8       NESTED LOOPS OUTER 
+      8        NESTED LOOPS  
+     16         NESTED LOOPS  
+      1          TABLE ACCESS BY INDEX ROWID USER$ 
+      1           INDEX UNIQUE SCAN I_USER1 (object id 44)
+     16          TABLE ACCESS BY INDEX ROWID OBJ$ 
+     16           INDEX RANGE SCAN I_OBJ2 (object id 37)
+      8         TABLE ACCESS CLUSTER TAB$ 
+      8          INDEX UNIQUE SCAN I_OBJ# (object id 3)
+      8        TABLE ACCESS BY INDEX ROWID OBJ$ 
+      8         INDEX UNIQUE SCAN I_OBJ1 (object id 36)
+      0       INDEX UNIQUE SCAN I_OBJ1 (object id 36)
+      8      TABLE ACCESS CLUSTER USER$ 
+      8       INDEX UNIQUE SCAN I_USER# (object id 11)
+      8     TABLE ACCESS CLUSTER SEG$ 
+      8      INDEX UNIQUE SCAN I_FILE#_BLOCK# (object id 9)
+      8    TABLE ACCESS CLUSTER TS$ 
+      8     INDEX UNIQUE SCAN I_TS# (object id 7)
+      0   NESTED LOOPS  
+      0    FIXED TABLE FULL X$KZSRO 
+      0    INDEX RANGE SCAN I_OBJAUTH2 (object id 109)
+      0   FIXED TABLE FULL X$KZSPR 
+
+
+Elapsed times include waiting on following events:
+  Event waited on                             Times   Max. Wait  Total Waited
+  ----------------------------------------   Waited  ----------  ------------
+  SQL*Net message to client                       1        0.00          0.00
+  db file sequential read                         4        0.00          0.00
+  SQL*Net message from client                     1        0.00          0.00
+********************************************************************************
+
+select ts#,file#,block#,nvl(bobj#,0),nvl(tab#,0),intcols,nvl(clucols,0),
+  audit$,flags,pctfree$,pctused$,initrans,maxtrans,rowcnt,blkcnt,empcnt,
+  avgspc,chncnt,avgrln,analyzetime, samplesize,cols,property,nvl(degree,1),
+  nvl(instances,1),avgspc_flb,flbcnt,kernelcols,nvl(trigflag, 0),nvl(spare1,0)
+  ,nvl(spare2,0),spare4,spare6 
+from
+ tab$ where obj#=:1
+
+
+call     count       cpu    elapsed       disk      query    current        rows
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+Parse        4      0.01       0.00          0          0          0           0
+Execute      5      0.00       0.00          0          0          0           0
+Fetch        5      0.00       0.00          0         15          0           5
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+total       14      0.01       0.00          0         15          0           5
+
+Misses in library cache during parse: 1
+Optimizer mode: CHOOSE
+Parsing user id: SYS   (recursive depth: 2)
+
+Rows     Row Source Operation
+-------  ---------------------------------------------------
+      2  TABLE ACCESS CLUSTER OBJ#(4) 
+      2   INDEX UNIQUE SCAN OBJ#(3) (object id 3)
+
+********************************************************************************
+
+select owner#,name,namespace,remoteowner,linkname,p_timestamp,p_obj#, 
+  d_owner#, nvl(property,0),subname 
+from
+ dependency$,obj$ where d_obj#=:1 and p_obj#=obj#(+) order by order#
+
+
+call     count       cpu    elapsed       disk      query    current        rows
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+Parse        1      0.00       0.00          0          0          0           0
+Execute      1      0.00       0.00          0          0          0           0
+Fetch       10      0.00       0.00          3         21          0           9
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+total       12      0.00       0.00          3         21          0           9
+
+Misses in library cache during parse: 1
+Optimizer mode: CHOOSE
+Parsing user id: SYS   (recursive depth: 1)
+
+Rows     Row Source Operation
+-------  ---------------------------------------------------
+      9  SORT ORDER BY 
+      9   NESTED LOOPS OUTER 
+      9    TABLE ACCESS BY INDEX ROWID DEPENDENCY$ 
+      9     INDEX RANGE SCAN I_DEPENDENCY1 (object id 127)
+      7    TABLE ACCESS BY INDEX ROWID OBJ$ 
+      7     INDEX UNIQUE SCAN I_OBJ1 (object id 36)
+
+
+Elapsed times include waiting on following events:
+  Event waited on                             Times   Max. Wait  Total Waited
+  ----------------------------------------   Waited  ----------  ------------
+  db file sequential read                         3        0.00          0.00
+********************************************************************************
+
+select intcol#,nvl(pos#,0),col# 
+from
+ ccol$ where con#=:1
+
+
+call     count       cpu    elapsed       disk      query    current        rows
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+Parse        3      0.00       0.00          0          0          0           0
+Execute      4      0.00       0.00          0          0          0           0
+Fetch        8      0.00       0.00          1         16          0           4
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+total       15      0.00       0.00          1         16          0           4
+
+Misses in library cache during parse: 1
+Optimizer mode: CHOOSE
+Parsing user id: SYS   (recursive depth: 1)
+
+Elapsed times include waiting on following events:
+  Event waited on                             Times   Max. Wait  Total Waited
+  ----------------------------------------   Waited  ----------  ------------
+  db file sequential read                         1        0.00          0.00
+********************************************************************************
+
+select con#,type#,condlength,intcols,robj#,rcon#,match#,refact,nvl(enabled,0),
+  rowid,cols,nvl(defer,0),mtime,nvl(spare1,0) 
+from
+ cdef$ where obj#=:1
+
+
+call     count       cpu    elapsed       disk      query    current        rows
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+Parse        3      0.00       0.00          0          0          0           0
+Execute      3      0.00       0.00          0          0          0           0
+Fetch        7      0.00       0.00          0         13          0           4
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+total       13      0.00       0.00          0         13          0           4
+
+Misses in library cache during parse: 1
+Optimizer mode: CHOOSE
+Parsing user id: SYS   (recursive depth: 1)
+********************************************************************************
+
+select col#,intcol#,charsetid,charsetform 
+from
+ col$ where obj#=:1 order by intcol# asc
+
+
+call     count       cpu    elapsed       disk      query    current        rows
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+Parse        1      0.00       0.00          0          0          0           0
+Execute      1      0.00       0.00          0          0          0           0
+Fetch       48      0.00       0.00          0          4          0          47
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+total       50      0.00       0.00          0          4          0          47
+
+Misses in library cache during parse: 1
+Optimizer mode: CHOOSE
+Parsing user id: SYS   (recursive depth: 1)
+********************************************************************************
+
+select con#,obj#,rcon#,enabled,nvl(defer,0) 
+from
+ cdef$ where robj#=:1
+
+
+call     count       cpu    elapsed       disk      query    current        rows
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+Parse        3      0.00       0.00          0          0          0           0
+Execute      3      0.00       0.00          0          0          0           0
+Fetch        4      0.00       0.00          0          5          0           1
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+total       10      0.00       0.00          0          5          0           1
+
+Misses in library cache during parse: 1
+Optimizer mode: CHOOSE
+Parsing user id: SYS   (recursive depth: 1)
+********************************************************************************
+
+select order#,columns,types 
+from
+ access$ where d_obj#=:1
+
+
+call     count       cpu    elapsed       disk      query    current        rows
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+Parse        1      0.00       0.00          0          0          0           0
+Execute      1      0.00       0.00          0          0          0           0
+Fetch        9      0.00       0.00          2         18          0           8
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+total       11      0.00       0.00          2         18          0           8
+
+Misses in library cache during parse: 1
+Optimizer mode: CHOOSE
+Parsing user id: SYS   (recursive depth: 1)
+
+Rows     Row Source Operation
+-------  ---------------------------------------------------
+      8  TABLE ACCESS BY INDEX ROWID ACCESS$ 
+      8   INDEX RANGE SCAN I_ACCESS1 (object id 129)
+
+
+Elapsed times include waiting on following events:
+  Event waited on                             Times   Max. Wait  Total Waited
+  ----------------------------------------   Waited  ----------  ------------
+  db file sequential read                         2        0.00          0.00
+********************************************************************************
+
+select col#,intcol#,toid,version#,packed,intcols,intcol#s,flags, synobj#, 
+  nvl(typidcol#, 0) 
+from
+ coltype$ where obj#=:1 order by intcol# desc
+
+
+call     count       cpu    elapsed       disk      query    current        rows
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+Parse        1      0.00       0.00          0          0          0           0
+Execute      1      0.00       0.00          0          0          0           0
+Fetch        1      0.00       0.00          0          4          0           0
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+total        3      0.00       0.00          0          4          0           0
+
+Misses in library cache during parse: 1
+Optimizer mode: CHOOSE
+Parsing user id: SYS   (recursive depth: 1)
+********************************************************************************
+
+select cols,audit$,textlength,intcols,property,flags,rowid 
+from
+ view$ where obj#=:1
+
+
+call     count       cpu    elapsed       disk      query    current        rows
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+Parse        1      0.00       0.00          1          1          0           0
+Execute      1      0.00       0.00          0          0          0           0
+Fetch        1      0.00       0.00          3          3          0           1
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+total        3      0.00       0.00          4          4          0           1
+
+Misses in library cache during parse: 1
+Optimizer mode: CHOOSE
+Parsing user id: SYS   (recursive depth: 1)
+
+Rows     Row Source Operation
+-------  ---------------------------------------------------
+      1  TABLE ACCESS BY INDEX ROWID OBJ#(62) 
+      1   INDEX UNIQUE SCAN OBJ#(104) (object id 104)
+
+
+Elapsed times include waiting on following events:
+  Event waited on                             Times   Max. Wait  Total Waited
+  ----------------------------------------   Waited  ----------  ------------
+  db file sequential read                         4        0.00          0.00
+********************************************************************************
+
+SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", 
+  "NODE_ISLEAF", "NODE_INSTIME", "FOLDER_PAYLOADSPEC", "FOLDER_VERSIONING", 
+  "FOLDER_IOVTABLENAME" 
+FROM
+ "AVALASSI"."COOLTEST_FOLDERS" WHERE "NODE_FULLPATH"=:"fullName"
+
+
+call     count       cpu    elapsed       disk      query    current        rows
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+Parse        1      0.00       0.00          0         28          0           0
+Execute      1      0.00       0.00          0          0          0           0
+Fetch        2      0.00       0.00          2          2          7           1
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+total        4      0.00       0.00          2         30          7           1
+
+Misses in library cache during parse: 1
+Optimizer mode: CHOOSE
+Parsing user id: 25  
+
+Rows     Row Source Operation
+-------  ---------------------------------------------------
+      1  TABLE ACCESS BY INDEX ROWID COOLTEST_FOLDERS 
+      1   INDEX RANGE SCAN COOLTEST_FOLDERS_FULN_1INDX (object id 8136)
+
+
+Elapsed times include waiting on following events:
+  Event waited on                             Times   Max. Wait  Total Waited
+  ----------------------------------------   Waited  ----------  ------------
+  SQL*Net message to client                       2        0.00          0.00
+  db file sequential read                         2        0.00          0.00
+  SQL*Net message from client                     2        0.00          0.00
+********************************************************************************
+
+select node,owner,name 
+from
+ syn$ where obj#=:1
+
+
+call     count       cpu    elapsed       disk      query    current        rows
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+Parse        1      0.01       0.00          1          1          0           0
+Execute      1      0.00       0.00          0          0          0           0
+Fetch        1      0.00       0.00          3          3          0           1
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+total        3      0.01       0.00          4          4          0           1
+
+Misses in library cache during parse: 1
+Optimizer mode: CHOOSE
+Parsing user id: SYS   (recursive depth: 1)
+
+Rows     Row Source Operation
+-------  ---------------------------------------------------
+      1  TABLE ACCESS BY INDEX ROWID OBJ#(61) 
+      1   INDEX UNIQUE SCAN OBJ#(106) (object id 106)
+
+
+Elapsed times include waiting on following events:
+  Event waited on                             Times   Max. Wait  Total Waited
+  ----------------------------------------   Waited  ----------  ------------
+  db file sequential read                         4        0.00          0.00
+********************************************************************************
+
+select l.col#, l.intcol#, l.lobj#, l.ind#, l.ts#, l.file#, l.block#, l.chunk, 
+  l.pctversion$, l.flags, l.property, l.retention, l.freepools 
+from
+ lob$ l where l.obj# = :1 order by l.intcol# asc
+
+
+call     count       cpu    elapsed       disk      query    current        rows
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+Parse        1      0.00       0.00          0          0          0           0
+Execute      1      0.00       0.00          0          0          0           0
+Fetch        1      0.00       0.00          0          4          0           0
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+total        3      0.00       0.00          0          4          0           0
+
+Misses in library cache during parse: 1
+Optimizer mode: CHOOSE
+Parsing user id: SYS   (recursive depth: 1)
+
+Rows     Row Source Operation
+-------  ---------------------------------------------------
+      0  SORT ORDER BY 
+      0   TABLE ACCESS CLUSTER LOB$ 
+      1    INDEX UNIQUE SCAN I_OBJ# (object id 3)
+
+********************************************************************************
+
+select intcol#, toid, version#, intcols, intcol#s, flags, synobj# 
+from
+ subcoltype$ where obj#=:1 order by intcol# asc
+
+
+call     count       cpu    elapsed       disk      query    current        rows
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+Parse        1      0.00       0.00          0          0          0           0
+Execute      1      0.00       0.00          0          0          0           0
+Fetch        1      0.00       0.00          0          4          0           0
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+total        3      0.00       0.00          0          4          0           0
+
+Misses in library cache during parse: 1
+Optimizer mode: CHOOSE
+Parsing user id: SYS   (recursive depth: 1)
+********************************************************************************
+
+select intcol#,type,flags,lobcol,objcol,extracol,schemaoid,  elemnum 
+from
+ opqtype$ where obj# = :1 order by intcol# asc
+
+
+call     count       cpu    elapsed       disk      query    current        rows
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+Parse        1      0.00       0.00          0          0          0           0
+Execute      1      0.00       0.00          0          0          0           0
+Fetch        1      0.00       0.00          0          4          0           0
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+total        3      0.00       0.00          0          4          0           0
+
+Misses in library cache during parse: 1
+Optimizer mode: CHOOSE
+Parsing user id: SYS   (recursive depth: 1)
+********************************************************************************
+
+select col#,intcol#,ntab# 
+from
+ ntab$ where obj#=:1 order by intcol# asc
+
+
+call     count       cpu    elapsed       disk      query    current        rows
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+Parse        1      0.00       0.00          0          0          0           0
+Execute      1      0.00       0.00          0          0          0           0
+Fetch        1      0.00       0.00          0          4          0           0
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+total        3      0.00       0.00          0          4          0           0
+
+Misses in library cache during parse: 1
+Optimizer mode: CHOOSE
+Parsing user id: SYS   (recursive depth: 1)
+********************************************************************************
+
+select col#,intcol#,reftyp,stabid,expctoid 
+from
+ refcon$ where obj#=:1 order by intcol# asc
+
+
+call     count       cpu    elapsed       disk      query    current        rows
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+Parse        1      0.01       0.00          0          0          0           0
+Execute      1      0.00       0.00          0          0          0           0
+Fetch        1      0.00       0.00          0          4          0           0
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+total        3      0.01       0.00          0          4          0           0
+
+Misses in library cache during parse: 1
+Optimizer mode: CHOOSE
+Parsing user id: SYS   (recursive depth: 1)
+********************************************************************************
+
+select text 
+from
+ view$ where rowid=:1
+
+
+call     count       cpu    elapsed       disk      query    current        rows
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+Parse        1      0.00       0.00          0          0          0           0
+Execute      1      0.01       0.00          0          0          0           0
+Fetch        1      0.00       0.00          0          2          0           1
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+total        3      0.01       0.00          0          2          0           1
+
+Misses in library cache during parse: 1
+Optimizer mode: CHOOSE
+Parsing user id: SYS   (recursive depth: 1)
+
+Rows     Row Source Operation
+-------  ---------------------------------------------------
+      1  TABLE ACCESS BY USER ROWID VIEW$ 
+
+********************************************************************************
+
+select p.value$, lengthb(p.value$) 
+from
+ sys.props$ p   where p.name = 'BACK_END_DB'
+
+
+call     count       cpu    elapsed       disk      query    current        rows
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+Parse        1      0.00       0.00          0          0          0           0
+Execute      1      0.00       0.00          0          0          0           0
+Fetch        1      0.00       0.00          0          3          0           0
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+total        3      0.00       0.00          0          3          0           0
+
+Misses in library cache during parse: 1
+Optimizer mode: CHOOSE
+Parsing user id: SYS   (recursive depth: 1)
+
+Rows     Row Source Operation
+-------  ---------------------------------------------------
+      0  TABLE ACCESS FULL PROPS$ 
+
+********************************************************************************
+
+alter session set events '10046 trace name context forever, level 12'
+
+
+call     count       cpu    elapsed       disk      query    current        rows
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+Parse        0      0.00       0.00          0          0          0           0
+Execute      1      0.00       0.00          0          0          0           0
+Fetch        0      0.00       0.00          0          0          0           0
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+total        1      0.00       0.00          0          0          0           0
+
+Misses in library cache during parse: 0
+Misses in library cache during execute: 1
+Optimizer mode: CHOOSE
+Parsing user id: 25  
+
+Elapsed times include waiting on following events:
+  Event waited on                             Times   Max. Wait  Total Waited
+  ----------------------------------------   Waited  ----------  ------------
+  SQL*Net message to client                       1        0.00          0.00
+  SQL*Net message from client                     1        0.00          0.00
+
+
+
+********************************************************************************
+
+OVERALL TOTALS FOR ALL NON-RECURSIVE STATEMENTS
+
+call     count       cpu    elapsed       disk      query    current        rows
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+Parse        4      0.03       0.03          1         82          0           0
+Execute      5      0.00       0.00          0          0          0           0
+Fetch       26     39.81      40.15       7420     298758    1445715      194992
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+total       35     39.84      40.19       7421     298840    1445715      194992
+
+Misses in library cache during parse: 4
+Misses in library cache during execute: 1
+
+Elapsed times include waiting on following events:
+  Event waited on                             Times   Max. Wait  Total Waited
+  ----------------------------------------   Waited  ----------  ------------
+  SQL*Net message to client                      39        0.00          0.00
+  SQL*Net message from client                    39       12.18         76.30
+  db file sequential read                        11        0.00          0.00
+  db file scattered read                        253        0.00          0.24
+  SQL*Net more data to client                 13469        0.00          0.51
+  direct path write                               4        0.00          0.00
+  direct path read                               69        0.00          0.00
+
+
+OVERALL TOTALS FOR ALL RECURSIVE STATEMENTS
+
+call     count       cpu    elapsed       disk      query    current        rows
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+Parse       69      0.04       0.03          2          2          0           0
+Execute    109      0.02       0.02          0          0          0           0
+Fetch      290      0.01       0.01         23        372          0         240
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+total      468      0.07       0.07         25        374          0         240
+
+Misses in library cache during parse: 26
+
+Elapsed times include waiting on following events:
+  Event waited on                             Times   Max. Wait  Total Waited
+  ----------------------------------------   Waited  ----------  ------------
+  db file sequential read                        23        0.00          0.00
+
+    5  user  SQL statements in session.
+   69  internal SQL statements in session.
+   74  SQL statements in session.
+********************************************************************************
+Trace file: pluto1.trc
+Trace file compatibility: 9.02.00
+Sort options: exeela  fchela  
+       1  session in tracefile.
+       5  user  SQL statements in trace file.
+      69  internal SQL statements in trace file.
+      74  SQL statements in trace file.
+      31  unique SQL statements in trace file.
+   15449  lines in trace file.
+     104  elapsed seconds in trace file.
+
+
diff --git a/RelationalCool/tests/PerformanceAV/ServerCache/100k-ora-cool-next.out b/RelationalCool/tests/PerformanceAV/ServerCache/100k-ora-cool-next.out
new file mode 100644
index 000000000..b244b188c
--- /dev/null
+++ b/RelationalCool/tests/PerformanceAV/ServerCache/100k-ora-cool-next.out
@@ -0,0 +1,82 @@
+Property Catalogue: level[Info] Adding property: OutputLevel = 2 in scope "SEAL/Services/MessageService"
+Property Catalogue: level[Info] Adding property: Format =  "%-36s %-8s %s" in scope "SEAL/Services/MessageService"
+MessageService callback    Debug MessageService output level changed to Debug
+ConfigurationService    Debug Setting property: "Format" to value " "%-36s %-8s %s"" in scope "SEAL/Services/MessageService"
+POOL/Services/RelationalService      Info     Found plugin for RDBMS technology "mysql" with implementation "odbc"
+POOL/Services/RelationalService      Info     Found plugin for RDBMS technology "oracle" with native implementation
+POOL/Services/RelationalService      Info     Default implementation for RDBMS technology "mysql" is "odbc"
+POOL/Services/RelationalService      Info     Default implementation for RDBMS technology "oracle" is native
+RelationalDatabase                   Debug    Instantiate a RelationalDatabase for 'oracle://cooldb2;schema=AVALASSI;user=avalassi;password=andrea;dbname=COOLTEST'
+RelationalDatabase                   Info     Instantiate a RalDatabase for 'oracle://cooldb2;schema=AVALASSI;user=avalassi;password=andrea;dbname=COOLTEST'
+POOL/RelationalPlugins/oracle        Info     Connected to a server running Oracle version 9.2.0.6.0
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "alter session set events '10046 trace name context forever, level 12'"
+POOL/RelationalPlugins/oracle        Warning  SQL_TRACE enabled
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT TABLE_NAME FROM ALL_TABLES WHERE OWNER = 'AVALASSI'"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT "DB_ATTRIBUTE_NAME", "DB_ATTRIBUTE_VALUE" FROM "AVALASSI"."COOLTEST_DB_ATTRIBUTES""
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_ISLEAF", "NODE_INSTIME", "FOLDER_PAYLOADSPEC", "FOLDER_VERSIONING", "FOLDER_IOVTABLENAME" FROM "AVALASSI"."COOLTEST_FOLDERS" WHERE "NODE_FULLPATH"=:"fullName""
+RelationalFolder                     Debug    Instantiate a RelationalFolder for '/myfolder'
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT "OBJECT_ID", "CHANNEL_ID", "IOV_SINCE", "IOV_UNTIL", "SYS_INSTIME", "I", "S", "X0", "X1", "X2", "X3", "X4", "X5", "X6", "X7", "X8", "X9", "P" FROM "AVALASSI"."COOLTEST_F0001_IOVS" WHERE "CHANNEL_ID"=:"channel" AND "IOV_SINCE">=:"since" AND "IOV_UNTIL"<=:"till" ORDER BY "CHANNEL_ID" ASC,"IOV_SINCE" ASC"
+>>>>>>    Timing Results  <<<<<<<<<< 
+----- 1.PrepareQuery----------- :                              ( n=1 )
+Total Real Time  :      0.010 +/-      0.010 s
+Total User Time  :      0.000 +/-      0.000 s
+Total System Time:      0.000 +/-      0.000 s
+Total Idle Time  :      0.010 +/-      0.010 s
+----- 2.ProcessQuery----------- :                              ( n=1 )
+Total Real Time  :      4.590 +/-      4.590 s
+Total User Time  :      0.230 +/-      0.230 s
+Total System Time:      0.130 +/-      0.130 s
+Total Idle Time  :      4.230 +/-      4.230 s
+----- 3.FetchRows-------------- :                              ( n=100001 )
+Total Real Time  :     42.540 +/-      0.135 s
+Total User Time  :      6.110 +/-      0.019 s
+Total System Time:      0.370 +/-      0.001 s
+Total Idle Time  :     36.090 +/-      0.114 s
+----- 4.CopyAttributeList------ :                              ( n=100000 )
+Total Real Time  :     57.530 +/-      0.182 s
+Total User Time  :     56.910 +/-      0.180 s
+Total System Time:      0.880 +/-      0.003 s
+Total Idle Time  :     -0.210 +/-     -0.001 s
+----- 5.CloseQuery------------- :                              ( n=1 )
+Total Real Time  :      0.000 +/-      0.000 s
+Total User Time  :      0.010 +/-      0.010 s
+Total System Time:      0.000 +/-      0.000 s
+Total Idle Time  :     -0.010 +/-     -0.010 s
+----- TOTAL FetchObjRowsByVal-- :                              ( n=1 )
+Total Real Time  :    105.810 +/-    105.810 s
+Total User Time  :     64.230 +/-     64.230 s
+Total System Time:      1.450 +/-      1.450 s
+Total Idle Time  :     40.130 +/-     40.130 s
+>>>>>>    Timing Results  <<<<<<<<<< 
+----- 1.FetchObjRowsByVal----- :                              ( n=1 )
+Total Real Time  :    105.820 +/-    105.820 s
+Total User Time  :     64.230 +/-     64.230 s
+Total System Time:      1.450 +/-      1.450 s
+Total Idle Time  :     40.140 +/-     40.140 s
+----- 2.DecodeRow------------- :                              ( n=1 )
+Total Real Time  :      9.690 +/-      9.690 s
+Total User Time  :      9.540 +/-      9.540 s
+Total System Time:      0.080 +/-      0.080 s
+Total Idle Time  :      0.070 +/-      0.070 s
+----- 3.DeleteOld------------- :                              ( n=1 )
+Total Real Time  :      1.570 +/-      1.570 s
+Total User Time  :      1.570 +/-      1.570 s
+Total System Time:      0.000 +/-      0.000 s
+Total Idle Time  :      0.000 +/-      0.000 s
+----- TOTAL BrowseObjInTag---- :                              ( n=1 )
+Total Real Time  :    117.080 +/-    117.080 s
+Total User Time  :     75.340 +/-     75.340 s
+Total System Time:      1.530 +/-      1.530 s
+Total Idle Time  :     40.210 +/-     40.210 s
+** reading 100000 objects (150 bytes mixed) **
+read back 100000 objects
+sec total: 117.093
+obj/s:     854.021
+RelationalFolder                     Debug    Delete the RelationalFolder for '/myfolder'
+sec total (INCLUDING DELETE): 118.316
+
+OK (1)
+[OVAL] Cppunit-result =0
+RelationalDatabase                   Info     Delete the RalDatabase for 'oracle://cooldb2;schema=AVALASSI;user=avalassi;password=andrea;dbname=COOLTEST'
+POOL/RelationalPlugins/oracle        Warning  No active transaction to roll back
+RelationalDatabase                   Debug    Delete the RelationalDatabase for 'oracle://cooldb2;schema=AVALASSI;user=avalassi;password=andrea;dbname=COOLTEST'
diff --git a/RelationalCool/tests/PerformanceAV/ServerCache/100k-ora-cool-next.prf b/RelationalCool/tests/PerformanceAV/ServerCache/100k-ora-cool-next.prf
new file mode 100644
index 000000000..1ecedb1d6
--- /dev/null
+++ b/RelationalCool/tests/PerformanceAV/ServerCache/100k-ora-cool-next.prf
@@ -0,0 +1,246 @@
+
+TKPROF: Release 10.1.0.2.0 - Production on Mon Jan 31 11:39:22 2005
+
+Copyright (c) 1982, 2004, Oracle.  All rights reserved.
+
+Trace file: pluto2.trc
+Sort options: exeela  fchela  
+********************************************************************************
+count    = number of times OCI procedure was executed
+cpu      = cpu time in seconds executing 
+elapsed  = elapsed time in seconds executing
+disk     = number of physical reads of buffers from disk
+query    = number of buffers gotten for consistent read
+current  = number of buffers gotten in current mode (usually for update)
+rows     = number of rows processed by the fetch or execute call
+********************************************************************************
+
+SELECT "OBJECT_ID", "CHANNEL_ID", "IOV_SINCE", "IOV_UNTIL", "SYS_INSTIME", 
+  "I", "S", "X0", "X1", "X2", "X3", "X4", "X5", "X6", "X7", "X8", "X9", "P" 
+FROM
+ "AVALASSI"."COOLTEST_F0001_IOVS" WHERE "CHANNEL_ID"=:"channel" AND 
+  "IOV_SINCE">=:"since" AND "IOV_UNTIL"<=:"till" ORDER BY "CHANNEL_ID" ASC,
+  "IOV_SINCE" ASC
+
+
+call     count       cpu    elapsed       disk      query    current        rows
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+Parse        1      0.00       0.00          0          0          0           0
+Execute      1      0.00       0.00          0          0          0           0
+Fetch       20     40.48      40.71       4632     298624    1445635      194981
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+total       22     40.48      40.71       4632     298624    1445635      194981
+
+Misses in library cache during parse: 0
+Optimizer mode: CHOOSE
+Parsing user id: 25  
+
+Rows     Row Source Operation
+-------  ---------------------------------------------------
+ 100000  SORT ORDER BY 
+ 100000   TABLE ACCESS FULL COOLTEST_F0001_IOVS 
+
+
+Elapsed times include waiting on following events:
+  Event waited on                             Times   Max. Wait  Total Waited
+  ----------------------------------------   Waited  ----------  ------------
+  SQL*Net message to client                      20        0.00          0.00
+  db file scattered read                         68        0.00          0.06
+  direct path write                               4        0.00          0.00
+  direct path read                               48        0.00          0.00
+  SQL*Net more data to client                 13468        0.00          0.51
+  SQL*Net message from client                    20        6.03         62.61
+********************************************************************************
+
+SELECT "DB_ATTRIBUTE_NAME", "DB_ATTRIBUTE_VALUE" 
+FROM
+ "AVALASSI"."COOLTEST_DB_ATTRIBUTES"
+
+
+call     count       cpu    elapsed       disk      query    current        rows
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+Parse        1      0.00       0.00          0          0          0           0
+Execute      1      0.00       0.00          0          0          0           0
+Fetch        3      0.00       0.00          0         10         19           2
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+total        5      0.00       0.00          0         10         19           2
+
+Misses in library cache during parse: 0
+Optimizer mode: CHOOSE
+Parsing user id: 25  
+
+Rows     Row Source Operation
+-------  ---------------------------------------------------
+      2  TABLE ACCESS FULL COOLTEST_DB_ATTRIBUTES 
+
+
+Elapsed times include waiting on following events:
+  Event waited on                             Times   Max. Wait  Total Waited
+  ----------------------------------------   Waited  ----------  ------------
+  SQL*Net message to client                       3        0.00          0.00
+  SQL*Net message from client                     3        0.00          0.00
+********************************************************************************
+
+SELECT TABLE_NAME 
+FROM
+ ALL_TABLES WHERE OWNER = 'AVALASSI'
+
+
+call     count       cpu    elapsed       disk      query    current        rows
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+Parse        1      0.00       0.00          0          0          0           0
+Execute      1      0.00       0.00          0          0          0           0
+Fetch        1      0.00       0.00          0        122          0           8
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+total        3      0.00       0.00          0        122          0           8
+
+Misses in library cache during parse: 0
+Optimizer mode: CHOOSE
+Parsing user id: 25  
+
+Rows     Row Source Operation
+-------  ---------------------------------------------------
+      8  FILTER  
+      8   NESTED LOOPS  
+      8    NESTED LOOPS OUTER 
+      8     NESTED LOOPS OUTER 
+      8      NESTED LOOPS OUTER 
+      8       NESTED LOOPS OUTER 
+      8        NESTED LOOPS  
+     16         NESTED LOOPS  
+      1          TABLE ACCESS BY INDEX ROWID USER$ 
+      1           INDEX UNIQUE SCAN I_USER1 (object id 44)
+     16          TABLE ACCESS BY INDEX ROWID OBJ$ 
+     16           INDEX RANGE SCAN I_OBJ2 (object id 37)
+      8         TABLE ACCESS CLUSTER TAB$ 
+      8          INDEX UNIQUE SCAN I_OBJ# (object id 3)
+      8        TABLE ACCESS BY INDEX ROWID OBJ$ 
+      8         INDEX UNIQUE SCAN I_OBJ1 (object id 36)
+      0       INDEX UNIQUE SCAN I_OBJ1 (object id 36)
+      8      TABLE ACCESS CLUSTER USER$ 
+      8       INDEX UNIQUE SCAN I_USER# (object id 11)
+      8     TABLE ACCESS CLUSTER SEG$ 
+      8      INDEX UNIQUE SCAN I_FILE#_BLOCK# (object id 9)
+      8    TABLE ACCESS CLUSTER TS$ 
+      8     INDEX UNIQUE SCAN I_TS# (object id 7)
+      0   NESTED LOOPS  
+      0    FIXED TABLE FULL X$KZSRO 
+      0    INDEX RANGE SCAN I_OBJAUTH2 (object id 109)
+      0   FIXED TABLE FULL X$KZSPR 
+
+
+Elapsed times include waiting on following events:
+  Event waited on                             Times   Max. Wait  Total Waited
+  ----------------------------------------   Waited  ----------  ------------
+  SQL*Net message to client                       1        0.00          0.00
+  SQL*Net message from client                     1        0.00          0.00
+********************************************************************************
+
+SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", 
+  "NODE_ISLEAF", "NODE_INSTIME", "FOLDER_PAYLOADSPEC", "FOLDER_VERSIONING", 
+  "FOLDER_IOVTABLENAME" 
+FROM
+ "AVALASSI"."COOLTEST_FOLDERS" WHERE "NODE_FULLPATH"=:"fullName"
+
+
+call     count       cpu    elapsed       disk      query    current        rows
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+Parse        1      0.00       0.00          0          0          0           0
+Execute      1      0.00       0.00          0          0          0           0
+Fetch        2      0.01       0.00          0          2          7           1
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+total        4      0.01       0.00          0          2          7           1
+
+Misses in library cache during parse: 0
+Optimizer mode: CHOOSE
+Parsing user id: 25  
+
+Rows     Row Source Operation
+-------  ---------------------------------------------------
+      1  TABLE ACCESS BY INDEX ROWID COOLTEST_FOLDERS 
+      1   INDEX RANGE SCAN COOLTEST_FOLDERS_FULN_1INDX (object id 8136)
+
+
+Elapsed times include waiting on following events:
+  Event waited on                             Times   Max. Wait  Total Waited
+  ----------------------------------------   Waited  ----------  ------------
+  SQL*Net message to client                       2        0.00          0.00
+  SQL*Net message from client                     2        0.00          0.00
+********************************************************************************
+
+alter session set events '10046 trace name context forever, level 12'
+
+
+call     count       cpu    elapsed       disk      query    current        rows
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+Parse        0      0.00       0.00          0          0          0           0
+Execute      1      0.00       0.00          0          0          0           0
+Fetch        0      0.00       0.00          0          0          0           0
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+total        1      0.00       0.00          0          0          0           0
+
+Misses in library cache during parse: 0
+Optimizer mode: CHOOSE
+Parsing user id: 25  
+
+Elapsed times include waiting on following events:
+  Event waited on                             Times   Max. Wait  Total Waited
+  ----------------------------------------   Waited  ----------  ------------
+  SQL*Net message to client                       1        0.00          0.00
+  SQL*Net message from client                     1        0.00          0.00
+
+
+
+********************************************************************************
+
+OVERALL TOTALS FOR ALL NON-RECURSIVE STATEMENTS
+
+call     count       cpu    elapsed       disk      query    current        rows
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+Parse        4      0.00       0.00          0          0          0           0
+Execute      5      0.00       0.00          0          0          0           0
+Fetch       26     40.49      40.72       4632     298758    1445661      194992
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+total       35     40.49      40.72       4632     298758    1445661      194992
+
+Misses in library cache during parse: 0
+
+Elapsed times include waiting on following events:
+  Event waited on                             Times   Max. Wait  Total Waited
+  ----------------------------------------   Waited  ----------  ------------
+  SQL*Net message to client                      39        0.00          0.00
+  SQL*Net message from client                    39       12.07         75.70
+  SQL*Net more data to client                 13469        0.00          0.51
+  db file scattered read                         68        0.00          0.06
+  direct path write                               4        0.00          0.00
+  direct path read                               48        0.00          0.00
+
+
+OVERALL TOTALS FOR ALL RECURSIVE STATEMENTS
+
+call     count       cpu    elapsed       disk      query    current        rows
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+Parse        0      0.00       0.00          0          0          0           0
+Execute      0      0.00       0.00          0          0          0           0
+Fetch        0      0.00       0.00          0          0          0           0
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+total        0      0.00       0.00          0          0          0           0
+
+Misses in library cache during parse: 0
+
+    5  user  SQL statements in session.
+    0  internal SQL statements in session.
+    5  SQL statements in session.
+********************************************************************************
+Trace file: pluto2.trc
+Trace file compatibility: 9.02.00
+Sort options: exeela  fchela  
+       1  session in tracefile.
+       5  user  SQL statements in trace file.
+       0  internal SQL statements in trace file.
+       5  SQL statements in trace file.
+       5  unique SQL statements in trace file.
+   13792  lines in trace file.
+     104  elapsed seconds in trace file.
+
+
diff --git a/RelationalCool/tests/PerformanceAV/TODO.Performance b/RelationalCool/tests/PerformanceAV/TODO.Performance
new file mode 100644
index 000000000..62f51a85e
--- /dev/null
+++ b/RelationalCool/tests/PerformanceAV/TODO.Performance
@@ -0,0 +1,38 @@
+* Make sure that the best execution plan is used in COOL in the trace file.
+  The first example with Bjorn used the indexes, but later examples did not.
+  Although this does not seem to explain the performance penalty,
+  it is annoying. Can it be because in Bjorn's example I was both
+  writing and reading? 
+  > DONE: after 'analyze table compute statistics' the index is used
+
+* Instrument the writing code to test how much time is lost in the
+  bad select for the last inserted IOV. Improve on that (quite easy...).
+
+* Clearly document and study the effect of RAL itself.
+  Instrument the RAL code to check where the overhead is
+  and why the trace file looks so weird.
+
+* Document all previous points:
+  - scaling of results between 1k to 200k rows
+  - different payload types
+  - writing
+  - reading cache size and memory size
+  - MyISAM vs InnoDB
+
+* Test Radovan's native MySQL implementation instead of ODBC
+  [PS: It may be more important to disable scrollable cursors in ODBC!]
+
+* Change the vector iterator implementation into one using an 'AttributeTable'.
+  The steps should be:
+  - copy the results from RAL into an AttributeTable
+    that returns to the user an AttributeList reference (or shared ptr)
+  - create a class implementing IObject that is just a wrapper
+    for an AttributeList reference (or shared ptr)
+  - create a class implementin IObjectIterator that is just a
+    wrapper for an AttributeTable instance
+  - the AttributeTable belongs to the iterator and is destroyed
+    when the iterator goes out of scope
+  - there is only one AttributeListSpecification in the system
+
+* Test whether string manipulation in RAL introduces a client overhead.
+  Numbers may be better if an integer-only patylaod is used.
\ No newline at end of file
diff --git a/RelationalCool/tests/PerformanceAV/TestAttributeValueAccessor/doNotUseAccessor-memory.rh73.501MB.oracle.out.ANALYZED b/RelationalCool/tests/PerformanceAV/TestAttributeValueAccessor/doNotUseAccessor-memory.rh73.501MB.oracle.out.ANALYZED
new file mode 100644
index 000000000..518538bb1
--- /dev/null
+++ b/RelationalCool/tests/PerformanceAV/TestAttributeValueAccessor/doNotUseAccessor-memory.rh73.501MB.oracle.out.ANALYZED
@@ -0,0 +1,109 @@
+Property Catalogue: level[Info] Adding property: OutputLevel = 2 in scope "SEAL/Services/MessageService"
+Property Catalogue: level[Info] Adding property: Format =  "%-36s %-8s %s" in scope "SEAL/Services/MessageService"
+MessageService callback    Debug MessageService output level changed to Debug
+ConfigurationService    Debug Setting property: "Format" to value " "%-36s %-8s %s"" in scope "SEAL/Services/MessageService"
+POOL/Services/RelationalService      Info     Found plugin for RDBMS technology "mysql" with implementation "odbc"
+POOL/Services/RelationalService      Info     Found plugin for RDBMS technology "oracle" with native implementation
+POOL/Services/RelationalService      Info     Default implementation for RDBMS technology "mysql" is "odbc"
+POOL/Services/RelationalService      Info     Default implementation for RDBMS technology "oracle" is native
+RelationalDatabase                   Debug    Instantiate a RelationalDatabase for 'oracle://cooldb2;schema=AVALASSI;user=avalassi;password=andrea;dbname=COOLTEST'
+RelationalDatabase                   Info     Instantiate a RalDatabase for 'oracle://cooldb2;schema=AVALASSI;user=avalassi;password=andrea;dbname=COOLTEST'
+POOL/RelationalPlugins/oracle        Info     Connected to a server running Oracle version 9.2.0.6.0
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT TABLE_NAME FROM ALL_TABLES WHERE OWNER = 'AVALASSI'"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT "DB_ATTRIBUTE_NAME", "DB_ATTRIBUTE_VALUE" FROM "AVALASSI"."COOLTEST_DB_ATTRIBUTES""
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_INSTIME", "FOLDER_PAYLOADSPEC", "FOLDER_VERSIONING", "FOLDER_IOVTABLENAME" FROM "AVALASSI"."COOLTEST_FOLDERS" WHERE "NODE_FULLPATH"=:"fullName""
+RelationalFolder                     Debug    Instantiate a RelationalFolder for '/myfolder'
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT "OBJECT_ID", "CHANNEL_ID", "IOV_SINCE", "IOV_UNTIL", "SYS_INSTIME", "I", "S", "X0", "X1", "X2", "X3", "X4", "X5", "X6", "X7", "X8", "X9", "P" FROM "AVALASSI"."COOLTEST_F0001_IOVS" WHERE "CHANNEL_ID"=:"channel" AND "IOV_SINCE">=:"since" AND "IOV_UNTIL"<=:"till" ORDER BY "CHANNEL_ID" ASC,"IOV_SINCE" ASC"
+>>>>>>    Timing Results  <<<<<<<<<< 
+----- 1.PrepareQuery----------- :                              ( n=1 )
+Total Real Time  :      0.010 +/-      0.010 s
+Total User Time  :      0.000 +/-      0.000 s
+Total System Time:      0.000 +/-      0.000 s
+Total Idle Time  :      0.010 +/-      0.010 s
+Total VmSize incr:      0.000 +/-      0.000 MB
+Total VmRSS incr :      0.000 +/-      0.000 MB
+----- 2.ProcessQuery----------- :                              ( n=1 )
+Total Real Time  :      0.000 +/-      0.000 s
+Total User Time  :      0.010 +/-      0.010 s
+Total System Time:      0.000 +/-      0.000 s
+Total Idle Time  :     -0.010 +/-     -0.010 s
+Total VmSize incr:      0.400 +/-      0.400 MB
+Total VmRSS incr :      0.408 +/-      0.408 MB
+----- 3.FetchRows-------------- :                              ( n=10001 )
+Total Real Time  :      7.460 +/-      0.075 s
+Total User Time  :      5.190 +/-      0.052 s
+Total System Time:      1.650 +/-      0.016 s
+Total Idle Time  :      0.660 +/-      0.007 s
+Total VmSize incr:      0.172 +/-      0.002 MB
+Total VmRSS incr :      1.552 +/-      0.016 MB
+----- 4.CopyAttributeList------ :                              ( n=10000 )
+Total Real Time  :     11.620 +/-      0.116 s
+Total User Time  :      9.570 +/-      0.096 s
+Total System Time:      1.700 +/-      0.017 s
+Total Idle Time  :      0.350 +/-      0.004 s
+Total VmSize incr:     24.512 +/-      0.245 MB
+Total VmRSS incr :     23.780 +/-      0.238 MB
+----- 5.CloseQuery------------- :                              ( n=1 )
+Total Real Time  :      0.000 +/-      0.000 s
+Total User Time  :      0.010 +/-      0.010 s
+Total System Time:      0.000 +/-      0.000 s
+Total Idle Time  :     -0.010 +/-     -0.010 s
+Total VmSize incr:      0.000 +/-      0.000 MB
+Total VmRSS incr :      0.000 +/-      0.000 MB
+----- TOTAL FetchObjRowsByVal-- :                              ( n=1 )
+Total Real Time  :     31.030 +/-     31.030 s
+Total User Time  :     23.360 +/-     23.360 s
+Total System Time:      7.310 +/-      7.310 s
+Total Idle Time  :      0.360 +/-      0.360 s
+Total VmSize incr:     25.788 +/-     25.788 MB
+Total VmRSS incr :     25.740 +/-     25.740 MB
+>>>>>>    Timing Results  <<<<<<<<<< 
+----- 1.FetchObjRowsByVal----- :                              ( n=1 )
+Total Real Time  :     31.030 +/-     31.030 s
+Total User Time  :     23.360 +/-     23.360 s
+Total System Time:      7.310 +/-      7.310 s
+Total Idle Time  :      0.360 +/-      0.360 s
+Total VmSize incr:     25.788 +/-     25.788 MB
+Total VmRSS incr :     25.748 +/-     25.748 MB
+----- 2.DecodeRow------------- :                              ( n=1 )
+Total Real Time  :      0.970 +/-      0.970 s
+Total User Time  :      0.970 +/-      0.970 s
+Total System Time:      0.000 +/-      0.000 s
+Total Idle Time  :      0.000 +/-      0.000 s
+Total VmSize incr:      3.036 +/-      3.036 MB
+Total VmRSS incr :      2.984 +/-      2.984 MB
+----- 3.DeleteOld------------- :                              ( n=1 )
+Total Real Time  :      0.160 +/-      0.160 s
+Total User Time  :      0.160 +/-      0.160 s
+Total System Time:      0.000 +/-      0.000 s
+Total Idle Time  :      0.000 +/-      0.000 s
+Total VmSize incr:     -0.132 +/-     -0.132 MB
+Total VmRSS incr :     -0.080 +/-     -0.080 MB
+----- 4.FillIterator---------- :                              ( n=1 )
+Total Real Time  :      0.000 +/-      0.000 s
+Total User Time  :      0.000 +/-      0.000 s
+Total System Time:      0.000 +/-      0.000 s
+Total Idle Time  :      0.000 +/-      0.000 s
+Total VmSize incr:      0.028 +/-      0.028 MB
+Total VmRSS incr :      0.076 +/-      0.076 MB
+----- TOTAL BrowseObjInTag---- :                              ( n=1 )
+Total Real Time  :     32.160 +/-     32.160 s
+Total User Time  :     24.490 +/-     24.490 s
+Total System Time:      7.320 +/-      7.320 s
+Total Idle Time  :      0.350 +/-      0.350 s
+Total VmSize incr:     28.720 +/-     28.720 MB
+Total VmRSS incr :     28.728 +/-     28.728 MB
+==> First object: since=0
+==> Last  object: since=9999
+** reading 100000 objects (150 bytes mixed) **
+read back 10000 objects
+sec total: 32.1738
+obj/s:     310.812
+RelationalFolder                     Debug    Delete the RelationalFolder for '/myfolder'
+sec total (INCLUDING DELETE): 32.309
+
+OK (1)
+[OVAL] Cppunit-result =0
+RelationalDatabase                   Info     Delete the RalDatabase for 'oracle://cooldb2;schema=AVALASSI;user=avalassi;password=andrea;dbname=COOLTEST'
+POOL/RelationalPlugins/oracle        Warning  No active transaction to roll back
+RelationalDatabase                   Debug    Delete the RelationalDatabase for 'oracle://cooldb2;schema=AVALASSI;user=avalassi;password=andrea;dbname=COOLTEST'
diff --git a/RelationalCool/tests/PerformanceAV/TestAttributeValueAccessor/doNotUseAccessor-time.rh73.501MB.oracle.out.ANALYZED b/RelationalCool/tests/PerformanceAV/TestAttributeValueAccessor/doNotUseAccessor-time.rh73.501MB.oracle.out.ANALYZED
new file mode 100644
index 000000000..2c944faa0
--- /dev/null
+++ b/RelationalCool/tests/PerformanceAV/TestAttributeValueAccessor/doNotUseAccessor-time.rh73.501MB.oracle.out.ANALYZED
@@ -0,0 +1,87 @@
+Property Catalogue: level[Info] Adding property: OutputLevel = 2 in scope "SEAL/Services/MessageService"
+Property Catalogue: level[Info] Adding property: Format =  "%-36s %-8s %s" in scope "SEAL/Services/MessageService"
+MessageService callback    Debug MessageService output level changed to Debug
+ConfigurationService    Debug Setting property: "Format" to value " "%-36s %-8s %s"" in scope "SEAL/Services/MessageService"
+POOL/Services/RelationalService      Info     Found plugin for RDBMS technology "mysql" with implementation "odbc"
+POOL/Services/RelationalService      Info     Found plugin for RDBMS technology "oracle" with native implementation
+POOL/Services/RelationalService      Info     Default implementation for RDBMS technology "mysql" is "odbc"
+POOL/Services/RelationalService      Info     Default implementation for RDBMS technology "oracle" is native
+RelationalDatabase                   Debug    Instantiate a RelationalDatabase for 'oracle://cooldb2;schema=AVALASSI;user=avalassi;password=andrea;dbname=COOLTEST'
+RelationalDatabase                   Info     Instantiate a RalDatabase for 'oracle://cooldb2;schema=AVALASSI;user=avalassi;password=andrea;dbname=COOLTEST'
+POOL/RelationalPlugins/oracle        Info     Connected to a server running Oracle version 9.2.0.6.0
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT TABLE_NAME FROM ALL_TABLES WHERE OWNER = 'AVALASSI'"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT "DB_ATTRIBUTE_NAME", "DB_ATTRIBUTE_VALUE" FROM "AVALASSI"."COOLTEST_DB_ATTRIBUTES""
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_INSTIME", "FOLDER_PAYLOADSPEC", "FOLDER_VERSIONING", "FOLDER_IOVTABLENAME" FROM "AVALASSI"."COOLTEST_FOLDERS" WHERE "NODE_FULLPATH"=:"fullName""
+RelationalFolder                     Debug    Instantiate a RelationalFolder for '/myfolder'
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT "OBJECT_ID", "CHANNEL_ID", "IOV_SINCE", "IOV_UNTIL", "SYS_INSTIME", "I", "S", "X0", "X1", "X2", "X3", "X4", "X5", "X6", "X7", "X8", "X9", "P" FROM "AVALASSI"."COOLTEST_F0001_IOVS" WHERE "CHANNEL_ID"=:"channel" AND "IOV_SINCE">=:"since" AND "IOV_UNTIL"<=:"till" ORDER BY "CHANNEL_ID" ASC,"IOV_SINCE" ASC"
+>>>>>>    Timing Results  <<<<<<<<<< 
+----- 1.PrepareQuery----------- :                              ( n=1 )
+Total Real Time  :      0.000 +/-      0.000 s
+Total User Time  :      0.000 +/-      0.000 s
+Total System Time:      0.000 +/-      0.000 s
+Total Idle Time  :      0.000 +/-      0.000 s
+----- 2.ProcessQuery----------- :                              ( n=1 )
+Total Real Time  :      0.010 +/-      0.010 s
+Total User Time  :      0.000 +/-      0.000 s
+Total System Time:      0.000 +/-      0.000 s
+Total Idle Time  :      0.010 +/-      0.010 s
+----- 3.FetchRows-------------- :                              ( n=10001 )
+Total Real Time  :      0.870 +/-      0.009 s
+Total User Time  :      0.590 +/-      0.006 s
+Total System Time:      0.020 +/-      0.000 s
+Total Idle Time  :      0.220 +/-      0.002 s
+----- 4.CopyAttributeList------ :                              ( n=10000 )
+Total Real Time  :      5.270 +/-      0.053 s
+Total User Time  :      5.220 +/-      0.052 s
+Total System Time:      0.090 +/-      0.001 s
+Total Idle Time  :     -0.010 +/-     -0.000 s
+----- 5.CloseQuery------------- :                              ( n=1 )
+Total Real Time  :      0.000 +/-      0.000 s
+Total User Time  :      0.000 +/-      0.000 s
+Total System Time:      0.000 +/-      0.000 s
+Total Idle Time  :      0.000 +/-      0.000 s
+----- TOTAL FetchObjRowsByVal-- :                              ( n=1 )
+Total Real Time  :      6.330 +/-      6.330 s
+Total User Time  :      5.900 +/-      5.900 s
+Total System Time:      0.140 +/-      0.140 s
+Total Idle Time  :      0.290 +/-      0.290 s
+>>>>>>    Timing Results  <<<<<<<<<< 
+----- 1.FetchObjRowsByVal----- :                              ( n=1 )
+Total Real Time  :      6.330 +/-      6.330 s
+Total User Time  :      5.900 +/-      5.900 s
+Total System Time:      0.140 +/-      0.140 s
+Total Idle Time  :      0.290 +/-      0.290 s
+----- 2.DecodeRow------------- :                              ( n=1 )
+Total Real Time  :      0.970 +/-      0.970 s
+Total User Time  :      0.970 +/-      0.970 s
+Total System Time:      0.000 +/-      0.000 s
+Total Idle Time  :      0.000 +/-      0.000 s
+----- 3.DeleteOld------------- :                              ( n=1 )
+Total Real Time  :      0.160 +/-      0.160 s
+Total User Time  :      0.160 +/-      0.160 s
+Total System Time:      0.000 +/-      0.000 s
+Total Idle Time  :      0.000 +/-      0.000 s
+----- 4.FillIterator---------- :                              ( n=1 )
+Total Real Time  :      0.000 +/-      0.000 s
+Total User Time  :      0.010 +/-      0.010 s
+Total System Time:      0.000 +/-      0.000 s
+Total Idle Time  :     -0.010 +/-     -0.010 s
+----- TOTAL BrowseObjInTag---- :                              ( n=1 )
+Total Real Time  :      7.460 +/-      7.460 s
+Total User Time  :      7.040 +/-      7.040 s
+Total System Time:      0.140 +/-      0.140 s
+Total Idle Time  :      0.280 +/-      0.280 s
+==> First object: since=0
+==> Last  object: since=9999
+** reading 100000 objects (150 bytes mixed) **
+read back 10000 objects
+sec total: 7.47047
+obj/s:     1338.6
+RelationalFolder                     Debug    Delete the RelationalFolder for '/myfolder'
+sec total (INCLUDING DELETE): 7.60483
+
+OK (1)
+[OVAL] Cppunit-result =0
+RelationalDatabase                   Info     Delete the RalDatabase for 'oracle://cooldb2;schema=AVALASSI;user=avalassi;password=andrea;dbname=COOLTEST'
+POOL/RelationalPlugins/oracle        Warning  No active transaction to roll back
+RelationalDatabase                   Debug    Delete the RelationalDatabase for 'oracle://cooldb2;schema=AVALASSI;user=avalassi;password=andrea;dbname=COOLTEST'
diff --git a/RelationalCool/tests/PerformanceAV/TestAttributeValueAccessor/execTestAttributeValueAccessor.rh73.501MB.oracle.out.ANALYZED b/RelationalCool/tests/PerformanceAV/TestAttributeValueAccessor/execTestAttributeValueAccessor.rh73.501MB.oracle.out.ANALYZED
new file mode 100644
index 000000000..5a40b31ce
--- /dev/null
+++ b/RelationalCool/tests/PerformanceAV/TestAttributeValueAccessor/execTestAttributeValueAccessor.rh73.501MB.oracle.out.ANALYZED
@@ -0,0 +1,4 @@
+3.410u 0.190s 0:05.00 72.0%     0+0k 0+0io 2278pf+0w
+7.340u 0.190s 0:08.90 84.6%     0+0k 0+0io 2282pf+0w
+20.380u 7.300s 0:29.12 95.0%    0+0k 0+0io 2277pf+0w
+24.810u 7.350s 0:33.61 95.6%    0+0k 0+0io 2282pf+0w
diff --git a/RelationalCool/tests/PerformanceAV/TestAttributeValueAccessor/useAccessor-memory.rh73.501MB.oracle.out.ANALYZED b/RelationalCool/tests/PerformanceAV/TestAttributeValueAccessor/useAccessor-memory.rh73.501MB.oracle.out.ANALYZED
new file mode 100644
index 000000000..bc588f13a
--- /dev/null
+++ b/RelationalCool/tests/PerformanceAV/TestAttributeValueAccessor/useAccessor-memory.rh73.501MB.oracle.out.ANALYZED
@@ -0,0 +1,109 @@
+Property Catalogue: level[Info] Adding property: OutputLevel = 2 in scope "SEAL/Services/MessageService"
+Property Catalogue: level[Info] Adding property: Format =  "%-36s %-8s %s" in scope "SEAL/Services/MessageService"
+MessageService callback    Debug MessageService output level changed to Debug
+ConfigurationService    Debug Setting property: "Format" to value " "%-36s %-8s %s"" in scope "SEAL/Services/MessageService"
+POOL/Services/RelationalService      Info     Found plugin for RDBMS technology "mysql" with implementation "odbc"
+POOL/Services/RelationalService      Info     Found plugin for RDBMS technology "oracle" with native implementation
+POOL/Services/RelationalService      Info     Default implementation for RDBMS technology "mysql" is "odbc"
+POOL/Services/RelationalService      Info     Default implementation for RDBMS technology "oracle" is native
+RelationalDatabase                   Debug    Instantiate a RelationalDatabase for 'oracle://cooldb2;schema=AVALASSI;user=avalassi;password=andrea;dbname=COOLTEST'
+RelationalDatabase                   Info     Instantiate a RalDatabase for 'oracle://cooldb2;schema=AVALASSI;user=avalassi;password=andrea;dbname=COOLTEST'
+POOL/RelationalPlugins/oracle        Info     Connected to a server running Oracle version 9.2.0.6.0
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT TABLE_NAME FROM ALL_TABLES WHERE OWNER = 'AVALASSI'"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT "DB_ATTRIBUTE_NAME", "DB_ATTRIBUTE_VALUE" FROM "AVALASSI"."COOLTEST_DB_ATTRIBUTES""
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_INSTIME", "FOLDER_PAYLOADSPEC", "FOLDER_VERSIONING", "FOLDER_IOVTABLENAME" FROM "AVALASSI"."COOLTEST_FOLDERS" WHERE "NODE_FULLPATH"=:"fullName""
+RelationalFolder                     Debug    Instantiate a RelationalFolder for '/myfolder'
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT "OBJECT_ID", "CHANNEL_ID", "IOV_SINCE", "IOV_UNTIL", "SYS_INSTIME", "I", "S", "X0", "X1", "X2", "X3", "X4", "X5", "X6", "X7", "X8", "X9", "P" FROM "AVALASSI"."COOLTEST_F0001_IOVS" WHERE "CHANNEL_ID"=:"channel" AND "IOV_SINCE">=:"since" AND "IOV_UNTIL"<=:"till" ORDER BY "CHANNEL_ID" ASC,"IOV_SINCE" ASC"
+>>>>>>    Timing Results  <<<<<<<<<< 
+----- 1.PrepareQuery----------- :                              ( n=1 )
+Total Real Time  :      0.010 +/-      0.010 s
+Total User Time  :      0.000 +/-      0.000 s
+Total System Time:      0.000 +/-      0.000 s
+Total Idle Time  :      0.010 +/-      0.010 s
+Total VmSize incr:      0.000 +/-      0.000 MB
+Total VmRSS incr :      0.000 +/-      0.000 MB
+----- 2.ProcessQuery----------- :                              ( n=1 )
+Total Real Time  :      0.000 +/-      0.000 s
+Total User Time  :      0.000 +/-      0.000 s
+Total System Time:      0.010 +/-      0.010 s
+Total Idle Time  :     -0.010 +/-     -0.010 s
+Total VmSize incr:      0.396 +/-      0.396 MB
+Total VmRSS incr :      0.404 +/-      0.404 MB
+----- 3.FetchRows-------------- :                              ( n=10001 )
+Total Real Time  :      6.910 +/-      0.069 s
+Total User Time  :      4.730 +/-      0.047 s
+Total System Time:      1.860 +/-      0.019 s
+Total Idle Time  :      0.300 +/-      0.003 s
+Total VmSize incr:      0.172 +/-      0.002 MB
+Total VmRSS incr :      1.584 +/-      0.016 MB
+----- 4.CopyAttributeList------ :                              ( n=10000 )
+Total Real Time  :      7.210 +/-      0.072 s
+Total User Time  :      5.800 +/-      0.058 s
+Total System Time:      1.720 +/-      0.017 s
+Total Idle Time  :     -0.300 +/-     -0.003 s
+Total VmSize incr:     24.060 +/-      0.241 MB
+Total VmRSS incr :     23.712 +/-      0.237 MB
+----- 5.CloseQuery------------- :                              ( n=1 )
+Total Real Time  :      0.000 +/-      0.000 s
+Total User Time  :      0.000 +/-      0.000 s
+Total System Time:      0.000 +/-      0.000 s
+Total Idle Time  :      0.000 +/-      0.000 s
+Total VmSize incr:      0.000 +/-      0.000 MB
+Total VmRSS incr :      0.000 +/-      0.000 MB
+----- TOTAL FetchObjRowsByVal-- :                              ( n=1 )
+Total Real Time  :     26.510 +/-     26.510 s
+Total User Time  :     18.930 +/-     18.930 s
+Total System Time:      7.230 +/-      7.230 s
+Total Idle Time  :      0.350 +/-      0.350 s
+Total VmSize incr:     25.776 +/-     25.776 MB
+Total VmRSS incr :     25.700 +/-     25.700 MB
+>>>>>>    Timing Results  <<<<<<<<<< 
+----- 1.FetchObjRowsByVal----- :                              ( n=1 )
+Total Real Time  :     26.510 +/-     26.510 s
+Total User Time  :     18.930 +/-     18.930 s
+Total System Time:      7.230 +/-      7.230 s
+Total Idle Time  :      0.350 +/-      0.350 s
+Total VmSize incr:     25.776 +/-     25.776 MB
+Total VmRSS incr :     25.720 +/-     25.720 MB
+----- 2.DecodeRow------------- :                              ( n=1 )
+Total Real Time  :      0.980 +/-      0.980 s
+Total User Time  :      0.960 +/-      0.960 s
+Total System Time:      0.020 +/-      0.020 s
+Total Idle Time  :      0.000 +/-      0.000 s
+Total VmSize incr:      3.008 +/-      3.008 MB
+Total VmRSS incr :      2.956 +/-      2.956 MB
+----- 3.DeleteOld------------- :                              ( n=1 )
+Total Real Time  :      0.160 +/-      0.160 s
+Total User Time  :      0.160 +/-      0.160 s
+Total System Time:      0.000 +/-      0.000 s
+Total Idle Time  :      0.000 +/-      0.000 s
+Total VmSize incr:     -0.132 +/-     -0.132 MB
+Total VmRSS incr :     -0.080 +/-     -0.080 MB
+----- 4.FillIterator---------- :                              ( n=1 )
+Total Real Time  :      0.010 +/-      0.010 s
+Total User Time  :      0.010 +/-      0.010 s
+Total System Time:      0.000 +/-      0.000 s
+Total Idle Time  :      0.000 +/-      0.000 s
+Total VmSize incr:      0.028 +/-      0.028 MB
+Total VmRSS incr :      0.076 +/-      0.076 MB
+----- TOTAL BrowseObjInTag---- :                              ( n=1 )
+Total Real Time  :     27.660 +/-     27.660 s
+Total User Time  :     20.060 +/-     20.060 s
+Total System Time:      7.250 +/-      7.250 s
+Total Idle Time  :      0.350 +/-      0.350 s
+Total VmSize incr:     28.692 +/-     28.692 MB
+Total VmRSS incr :     28.672 +/-     28.672 MB
+==> First object: since=0
+==> Last  object: since=9999
+** reading 100000 objects (150 bytes mixed) **
+read back 10000 objects
+sec total: 27.6715
+obj/s:     361.383
+RelationalFolder                     Debug    Delete the RelationalFolder for '/myfolder'
+sec total (INCLUDING DELETE): 27.8057
+
+OK (1)
+[OVAL] Cppunit-result =0
+RelationalDatabase                   Info     Delete the RalDatabase for 'oracle://cooldb2;schema=AVALASSI;user=avalassi;password=andrea;dbname=COOLTEST'
+POOL/RelationalPlugins/oracle        Warning  No active transaction to roll back
+RelationalDatabase                   Debug    Delete the RelationalDatabase for 'oracle://cooldb2;schema=AVALASSI;user=avalassi;password=andrea;dbname=COOLTEST'
diff --git a/RelationalCool/tests/PerformanceAV/TestAttributeValueAccessor/useAccessor-time.rh73.501MB.oracle.out.ANALYZED b/RelationalCool/tests/PerformanceAV/TestAttributeValueAccessor/useAccessor-time.rh73.501MB.oracle.out.ANALYZED
new file mode 100644
index 000000000..ab8cfb557
--- /dev/null
+++ b/RelationalCool/tests/PerformanceAV/TestAttributeValueAccessor/useAccessor-time.rh73.501MB.oracle.out.ANALYZED
@@ -0,0 +1,87 @@
+Property Catalogue: level[Info] Adding property: OutputLevel = 2 in scope "SEAL/Services/MessageService"
+Property Catalogue: level[Info] Adding property: Format =  "%-36s %-8s %s" in scope "SEAL/Services/MessageService"
+MessageService callback    Debug MessageService output level changed to Debug
+ConfigurationService    Debug Setting property: "Format" to value " "%-36s %-8s %s"" in scope "SEAL/Services/MessageService"
+POOL/Services/RelationalService      Info     Found plugin for RDBMS technology "mysql" with implementation "odbc"
+POOL/Services/RelationalService      Info     Found plugin for RDBMS technology "oracle" with native implementation
+POOL/Services/RelationalService      Info     Default implementation for RDBMS technology "mysql" is "odbc"
+POOL/Services/RelationalService      Info     Default implementation for RDBMS technology "oracle" is native
+RelationalDatabase                   Debug    Instantiate a RelationalDatabase for 'oracle://cooldb2;schema=AVALASSI;user=avalassi;password=andrea;dbname=COOLTEST'
+RelationalDatabase                   Info     Instantiate a RalDatabase for 'oracle://cooldb2;schema=AVALASSI;user=avalassi;password=andrea;dbname=COOLTEST'
+POOL/RelationalPlugins/oracle        Info     Connected to a server running Oracle version 9.2.0.6.0
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT TABLE_NAME FROM ALL_TABLES WHERE OWNER = 'AVALASSI'"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT "DB_ATTRIBUTE_NAME", "DB_ATTRIBUTE_VALUE" FROM "AVALASSI"."COOLTEST_DB_ATTRIBUTES""
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_INSTIME", "FOLDER_PAYLOADSPEC", "FOLDER_VERSIONING", "FOLDER_IOVTABLENAME" FROM "AVALASSI"."COOLTEST_FOLDERS" WHERE "NODE_FULLPATH"=:"fullName""
+RelationalFolder                     Debug    Instantiate a RelationalFolder for '/myfolder'
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT "OBJECT_ID", "CHANNEL_ID", "IOV_SINCE", "IOV_UNTIL", "SYS_INSTIME", "I", "S", "X0", "X1", "X2", "X3", "X4", "X5", "X6", "X7", "X8", "X9", "P" FROM "AVALASSI"."COOLTEST_F0001_IOVS" WHERE "CHANNEL_ID"=:"channel" AND "IOV_SINCE">=:"since" AND "IOV_UNTIL"<=:"till" ORDER BY "CHANNEL_ID" ASC,"IOV_SINCE" ASC"
+>>>>>>    Timing Results  <<<<<<<<<< 
+----- 1.PrepareQuery----------- :                              ( n=1 )
+Total Real Time  :      0.000 +/-      0.000 s
+Total User Time  :      0.000 +/-      0.000 s
+Total System Time:      0.000 +/-      0.000 s
+Total Idle Time  :      0.000 +/-      0.000 s
+----- 2.ProcessQuery----------- :                              ( n=1 )
+Total Real Time  :      0.010 +/-      0.010 s
+Total User Time  :      0.000 +/-      0.000 s
+Total System Time:      0.010 +/-      0.010 s
+Total Idle Time  :      0.000 +/-      0.000 s
+----- 3.FetchRows-------------- :                              ( n=10001 )
+Total Real Time  :      0.770 +/-      0.008 s
+Total User Time  :      0.510 +/-      0.005 s
+Total System Time:      0.060 +/-      0.001 s
+Total Idle Time  :      0.220 +/-      0.002 s
+----- 4.CopyAttributeList------ :                              ( n=10000 )
+Total Real Time  :      1.520 +/-      0.015 s
+Total User Time  :      1.370 +/-      0.014 s
+Total System Time:      0.040 +/-      0.000 s
+Total Idle Time  :      0.110 +/-      0.001 s
+----- 5.CloseQuery------------- :                              ( n=1 )
+Total Real Time  :      0.000 +/-      0.000 s
+Total User Time  :      0.000 +/-      0.000 s
+Total System Time:      0.000 +/-      0.000 s
+Total Idle Time  :      0.000 +/-      0.000 s
+----- TOTAL FetchObjRowsByVal-- :                              ( n=1 )
+Total Real Time  :      2.390 +/-      2.390 s
+Total User Time  :      1.960 +/-      1.960 s
+Total System Time:      0.130 +/-      0.130 s
+Total Idle Time  :      0.300 +/-      0.300 s
+>>>>>>    Timing Results  <<<<<<<<<< 
+----- 1.FetchObjRowsByVal----- :                              ( n=1 )
+Total Real Time  :      2.390 +/-      2.390 s
+Total User Time  :      1.960 +/-      1.960 s
+Total System Time:      0.130 +/-      0.130 s
+Total Idle Time  :      0.300 +/-      0.300 s
+----- 2.DecodeRow------------- :                              ( n=1 )
+Total Real Time  :      0.960 +/-      0.960 s
+Total User Time  :      0.940 +/-      0.940 s
+Total System Time:      0.010 +/-      0.010 s
+Total Idle Time  :      0.010 +/-      0.010 s
+----- 3.DeleteOld------------- :                              ( n=1 )
+Total Real Time  :      0.160 +/-      0.160 s
+Total User Time  :      0.160 +/-      0.160 s
+Total System Time:      0.000 +/-      0.000 s
+Total Idle Time  :      0.000 +/-      0.000 s
+----- 4.FillIterator---------- :                              ( n=1 )
+Total Real Time  :      0.010 +/-      0.010 s
+Total User Time  :      0.000 +/-      0.000 s
+Total System Time:      0.000 +/-      0.000 s
+Total Idle Time  :      0.010 +/-      0.010 s
+----- TOTAL BrowseObjInTag---- :                              ( n=1 )
+Total Real Time  :      3.520 +/-      3.520 s
+Total User Time  :      3.060 +/-      3.060 s
+Total System Time:      0.140 +/-      0.140 s
+Total Idle Time  :      0.320 +/-      0.320 s
+==> First object: since=0
+==> Last  object: since=9999
+** reading 100000 objects (150 bytes mixed) **
+read back 10000 objects
+sec total: 3.52561
+obj/s:     2836.38
+RelationalFolder                     Debug    Delete the RelationalFolder for '/myfolder'
+sec total (INCLUDING DELETE): 3.66015
+
+OK (1)
+[OVAL] Cppunit-result =0
+RelationalDatabase                   Info     Delete the RalDatabase for 'oracle://cooldb2;schema=AVALASSI;user=avalassi;password=andrea;dbname=COOLTEST'
+POOL/RelationalPlugins/oracle        Warning  No active transaction to roll back
+RelationalDatabase                   Debug    Delete the RelationalDatabase for 'oracle://cooldb2;schema=AVALASSI;user=avalassi;password=andrea;dbname=COOLTEST'
diff --git a/RelationalCool/tests/PerformanceAV/TestNewCopy/execTestNewCopy.rh73.1006MB.out b/RelationalCool/tests/PerformanceAV/TestNewCopy/execTestNewCopy.rh73.1006MB.out
new file mode 100644
index 000000000..46aa75c73
--- /dev/null
+++ b/RelationalCool/tests/PerformanceAV/TestNewCopy/execTestNewCopy.rh73.1006MB.out
@@ -0,0 +1,5 @@
+8.170u 0.330s 0:13.50 62.9%     0+0k 0+0io 2271pf+0w
+20.720u 0.240s 0:25.24 83.0%    0+0k 0+0io 2271pf+0w
+25.180u 7.720s 0:37.63 87.4%    0+0k 0+0io 2271pf+0w
+36.560u 7.410s 0:49.07 89.6%    0+0k 0+0io 2271pf+0w
+
diff --git a/RelationalCool/tests/PerformanceAV/TestNewCopy/execTestNewCopy.rh73.501MB.out b/RelationalCool/tests/PerformanceAV/TestNewCopy/execTestNewCopy.rh73.501MB.out
new file mode 100644
index 000000000..dc2964e82
--- /dev/null
+++ b/RelationalCool/tests/PerformanceAV/TestNewCopy/execTestNewCopy.rh73.501MB.out
@@ -0,0 +1,5 @@
+7.730u 0.160s 0:12.29 64.1%     0+0k 0+0io 2272pf+0w
+20.540u 0.130s 0:25.04 82.5%    0+0k 0+0io 2272pf+0w
+25.040u 7.760s 0:37.04 88.5%    0+0k 0+0io 2272pf+0w
+36.630u 7.090s 0:47.92 91.2%    0+0k 0+0io 2272pf+0w
+
diff --git a/RelationalCool/tests/PerformanceAV/TestNewCopy/execTestNewCopy.slc3.2006MB.out b/RelationalCool/tests/PerformanceAV/TestNewCopy/execTestNewCopy.slc3.2006MB.out
new file mode 100644
index 000000000..1befd9ed5
--- /dev/null
+++ b/RelationalCool/tests/PerformanceAV/TestNewCopy/execTestNewCopy.slc3.2006MB.out
@@ -0,0 +1,5 @@
+7.520u 0.260s 0:19.21 40.4%     0+0k 0+0io 2480pf+0w
+5.760u 0.170s 0:12.18 48.6%     0+0k 0+0io 2479pf+0w
+18.680u 5.110s 0:39.16 60.7%    0+0k 0+0io 2480pf+0w
+17.260u 4.920s 0:29.91 74.1%    0+0k 0+0io 2479pf+0w
+
diff --git a/RelationalCool/tests/PerformanceAV/TestNewCopy/newCopy-memory.rh73.1006MB.out b/RelationalCool/tests/PerformanceAV/TestNewCopy/newCopy-memory.rh73.1006MB.out
new file mode 100644
index 000000000..f6900bbee
--- /dev/null
+++ b/RelationalCool/tests/PerformanceAV/TestNewCopy/newCopy-memory.rh73.1006MB.out
@@ -0,0 +1,102 @@
+Property Catalogue: level[Info] Adding property: OutputLevel = 2 in scope "SEAL/Services/MessageService"
+Property Catalogue: level[Info] Adding property: Format =  "%-36s %-8s %s" in scope "SEAL/Services/MessageService"
+MessageService callback    Debug MessageService output level changed to Debug
+ConfigurationService    Debug Setting property: "Format" to value " "%-36s %-8s %s"" in scope "SEAL/Services/MessageService"
+POOL/Services/RelationalService      Info     Found plugin for RDBMS technology "mysql" with implementation "odbc"
+POOL/Services/RelationalService      Info     Found plugin for RDBMS technology "oracle" with native implementation
+POOL/Services/RelationalService      Info     Found plugin for RDBMS technology "sqlite" with native implementation
+POOL/Services/RelationalService      Info     Default implementation for RDBMS technology "mysql" is "odbc"
+POOL/Services/RelationalService      Info     Default implementation for RDBMS technology "oracle" is native
+POOL/Services/RelationalService      Info     Default implementation for RDBMS technology "sqlite" is native
+RelationalDatabase                   Debug    Instantiate a RelationalDatabase for 'oracle://cooldb2;schema=AVALASSI;user=avalassi;password=andrea;dbname=COOLTEST'
+RelationalDatabase                   Info     Instantiate a RalDatabase for 'oracle://cooldb2;schema=AVALASSI;user=avalassi;password=andrea;dbname=COOLTEST'
+POOL/RelationalPlugins/oracle        Info     Connected to a server running Oracle version 9.2.0.6.0
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT TABLE_NAME FROM ALL_TABLES WHERE OWNER = 'AVALASSI'"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT "DB_ATTRIBUTE_NAME", "DB_ATTRIBUTE_VALUE" FROM "AVALASSI"."COOLTEST_DB_ATTRIBUTES""
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_ISLEAF", "NODE_INSTIME", "FOLDER_PAYLOADSPEC", "FOLDER_VERSIONING", "FOLDER_IOVTABLENAME" FROM "AVALASSI"."COOLTEST_FOLDERS" WHERE "NODE_FULLPATH"=:"fullName""
+RelationalFolder                     Debug    Instantiate a RelationalFolder for '/myfolder'
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT "OBJECT_ID", "CHANNEL_ID", "IOV_SINCE", "IOV_UNTIL", "SYS_INSTIME", "I", "S", "X0", "X1", "X2", "X3", "X4", "X5", "X6", "X7", "X8", "X9", "P" FROM "AVALASSI"."COOLTEST_F0001_IOVS" WHERE "CHANNEL_ID"=:"channel" AND "IOV_SINCE">=:"since" AND "IOV_UNTIL"<=:"till" ORDER BY "CHANNEL_ID" ASC,"IOV_SINCE" ASC"
+>>>>>>    Timing Results  <<<<<<<<<< 
+----- 1.PrepareQuery----------- :                              ( n=1 )
+Total Real Time  :      0.000 +/-      0.000 s
+Total User Time  :      0.000 +/-      0.000 s
+Total System Time:      0.000 +/-      0.000 s
+Total Idle Time  :      0.000 +/-      0.000 s
+Total VmSize incr:      0.000 +/-      0.000 MB
+Total VmRSS incr :      0.012 +/-      0.012 MB
+----- 2.ProcessQuery----------- :                              ( n=1 )
+Total Real Time  :      0.010 +/-      0.010 s
+Total User Time  :      0.010 +/-      0.010 s
+Total System Time:      0.000 +/-      0.000 s
+Total Idle Time  :      0.000 +/-      0.000 s
+Total VmSize incr:      0.412 +/-      0.412 MB
+Total VmRSS incr :      0.412 +/-      0.412 MB
+----- 3.FetchRows-------------- :                              ( n=10001 )
+Total Real Time  :     10.350 +/-      0.103 s
+Total User Time  :      5.130 +/-      0.051 s
+Total System Time:      1.730 +/-      0.017 s
+Total Idle Time  :      3.480 +/-      0.035 s
+Total VmSize incr:      0.796 +/-      0.008 MB
+Total VmRSS incr :      1.560 +/-      0.016 MB
+----- 4.CopyAttributeList------ :                              ( n=10000 )
+Total Real Time  :     10.650 +/-      0.106 s
+Total User Time  :      9.040 +/-      0.090 s
+Total System Time:      1.760 +/-      0.018 s
+Total Idle Time  :     -0.120 +/-     -0.001 s
+Total VmSize incr:     16.028 +/-      0.160 MB
+Total VmRSS incr :     16.080 +/-      0.161 MB
+----- 5.CloseQuery------------- :                              ( n=1 )
+Total Real Time  :      0.000 +/-      0.000 s
+Total User Time  :      0.000 +/-      0.000 s
+Total System Time:      0.000 +/-      0.000 s
+Total Idle Time  :      0.000 +/-      0.000 s
+Total VmSize incr:      0.000 +/-      0.000 MB
+Total VmRSS incr :      0.000 +/-      0.000 MB
+----- TOTAL FetchObjRowsByVal-- :                              ( n=1 )
+Total Real Time  :     33.550 +/-     33.550 s
+Total User Time  :     22.660 +/-     22.660 s
+Total System Time:      7.270 +/-      7.270 s
+Total Idle Time  :      3.620 +/-      3.620 s
+Total VmSize incr:     18.132 +/-     18.132 MB
+Total VmRSS incr :     18.064 +/-     18.064 MB
+>>>>>>    Timing Results  <<<<<<<<<< 
+----- 1.FetchObjRowsByVal----- :                              ( n=1 )
+Total Real Time  :     33.550 +/-     33.550 s
+Total User Time  :     22.660 +/-     22.660 s
+Total System Time:      7.280 +/-      7.280 s
+Total Idle Time  :      3.610 +/-      3.610 s
+Total VmSize incr:     18.132 +/-     18.132 MB
+Total VmRSS incr :     18.072 +/-     18.072 MB
+----- 2.DecodeRow------------- :                              ( n=1 )
+Total Real Time  :      1.000 +/-      1.000 s
+Total User Time  :      0.960 +/-      0.960 s
+Total System Time:      0.010 +/-      0.010 s
+Total Idle Time  :      0.030 +/-      0.030 s
+Total VmSize incr:      3.016 +/-      3.016 MB
+Total VmRSS incr :      2.956 +/-      2.956 MB
+----- 3.DeleteOld------------- :                              ( n=1 )
+Total Real Time  :      4.440 +/-      4.440 s
+Total User Time  :      4.360 +/-      4.360 s
+Total System Time:      0.020 +/-      0.020 s
+Total Idle Time  :      0.060 +/-      0.060 s
+Total VmSize incr:     -0.132 +/-     -0.132 MB
+Total VmRSS incr :     -0.080 +/-     -0.080 MB
+----- TOTAL BrowseObjInTag---- :                              ( n=1 )
+Total Real Time  :     39.000 +/-     39.000 s
+Total User Time  :     27.990 +/-     27.990 s
+Total System Time:      7.310 +/-      7.310 s
+Total Idle Time  :      3.700 +/-      3.700 s
+Total VmSize incr:     21.016 +/-     21.016 MB
+Total VmRSS incr :     20.948 +/-     20.948 MB
+** reading 100000 objects (150 bytes mixed) **
+read back 10000 objects
+sec total: 39.0098
+obj/s:     256.346
+RelationalFolder                     Debug    Delete the RelationalFolder for '/myfolder'
+sec total (INCLUDING DELETE): 47.4793
+
+OK (1)
+[OVAL] Cppunit-result =0
+RelationalDatabase                   Info     Delete the RalDatabase for 'oracle://cooldb2;schema=AVALASSI;user=avalassi;password=andrea;dbname=COOLTEST'
+POOL/RelationalPlugins/oracle        Warning  No active transaction to roll back
+RelationalDatabase                   Debug    Delete the RelationalDatabase for 'oracle://cooldb2;schema=AVALASSI;user=avalassi;password=andrea;dbname=COOLTEST'
diff --git a/RelationalCool/tests/PerformanceAV/TestNewCopy/newCopy-memory.rh73.501MB.out b/RelationalCool/tests/PerformanceAV/TestNewCopy/newCopy-memory.rh73.501MB.out
new file mode 100644
index 000000000..197da322d
--- /dev/null
+++ b/RelationalCool/tests/PerformanceAV/TestNewCopy/newCopy-memory.rh73.501MB.out
@@ -0,0 +1,102 @@
+Property Catalogue: level[Info] Adding property: OutputLevel = 2 in scope "SEAL/Services/MessageService"
+Property Catalogue: level[Info] Adding property: Format =  "%-36s %-8s %s" in scope "SEAL/Services/MessageService"
+MessageService callback    Debug MessageService output level changed to Debug
+ConfigurationService    Debug Setting property: "Format" to value " "%-36s %-8s %s"" in scope "SEAL/Services/MessageService"
+POOL/Services/RelationalService      Info     Found plugin for RDBMS technology "mysql" with implementation "odbc"
+POOL/Services/RelationalService      Info     Found plugin for RDBMS technology "oracle" with native implementation
+POOL/Services/RelationalService      Info     Found plugin for RDBMS technology "sqlite" with native implementation
+POOL/Services/RelationalService      Info     Default implementation for RDBMS technology "mysql" is "odbc"
+POOL/Services/RelationalService      Info     Default implementation for RDBMS technology "oracle" is native
+POOL/Services/RelationalService      Info     Default implementation for RDBMS technology "sqlite" is native
+RelationalDatabase                   Debug    Instantiate a RelationalDatabase for 'oracle://cooldb2;schema=AVALASSI;user=avalassi;password=andrea;dbname=COOLTEST'
+RelationalDatabase                   Info     Instantiate a RalDatabase for 'oracle://cooldb2;schema=AVALASSI;user=avalassi;password=andrea;dbname=COOLTEST'
+POOL/RelationalPlugins/oracle        Info     Connected to a server running Oracle version 9.2.0.6.0
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT TABLE_NAME FROM ALL_TABLES WHERE OWNER = 'AVALASSI'"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT "DB_ATTRIBUTE_NAME", "DB_ATTRIBUTE_VALUE" FROM "AVALASSI"."COOLTEST_DB_ATTRIBUTES""
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_ISLEAF", "NODE_INSTIME", "FOLDER_PAYLOADSPEC", "FOLDER_VERSIONING", "FOLDER_IOVTABLENAME" FROM "AVALASSI"."COOLTEST_FOLDERS" WHERE "NODE_FULLPATH"=:"fullName""
+RelationalFolder                     Debug    Instantiate a RelationalFolder for '/myfolder'
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT "OBJECT_ID", "CHANNEL_ID", "IOV_SINCE", "IOV_UNTIL", "SYS_INSTIME", "I", "S", "X0", "X1", "X2", "X3", "X4", "X5", "X6", "X7", "X8", "X9", "P" FROM "AVALASSI"."COOLTEST_F0001_IOVS" WHERE "CHANNEL_ID"=:"channel" AND "IOV_SINCE">=:"since" AND "IOV_UNTIL"<=:"till" ORDER BY "CHANNEL_ID" ASC,"IOV_SINCE" ASC"
+>>>>>>    Timing Results  <<<<<<<<<< 
+----- 1.PrepareQuery----------- :                              ( n=1 )
+Total Real Time  :      0.010 +/-      0.010 s
+Total User Time  :      0.000 +/-      0.000 s
+Total System Time:      0.000 +/-      0.000 s
+Total Idle Time  :      0.010 +/-      0.010 s
+Total VmSize incr:      0.000 +/-      0.000 MB
+Total VmRSS incr :      0.012 +/-      0.012 MB
+----- 2.ProcessQuery----------- :                              ( n=1 )
+Total Real Time  :      0.010 +/-      0.010 s
+Total User Time  :      0.010 +/-      0.010 s
+Total System Time:      0.000 +/-      0.000 s
+Total Idle Time  :      0.000 +/-      0.000 s
+Total VmSize incr:      0.412 +/-      0.412 MB
+Total VmRSS incr :      0.412 +/-      0.412 MB
+----- 3.FetchRows-------------- :                              ( n=10001 )
+Total Real Time  :      9.800 +/-      0.098 s
+Total User Time  :      5.100 +/-      0.051 s
+Total System Time:      1.550 +/-      0.015 s
+Total Idle Time  :      3.150 +/-      0.031 s
+Total VmSize incr:      0.796 +/-      0.008 MB
+Total VmRSS incr :      1.560 +/-      0.016 MB
+----- 4.CopyAttributeList------ :                              ( n=10000 )
+Total Real Time  :     10.510 +/-      0.105 s
+Total User Time  :      9.150 +/-      0.091 s
+Total System Time:      1.560 +/-      0.016 s
+Total Idle Time  :     -0.200 +/-     -0.002 s
+Total VmSize incr:     16.028 +/-      0.160 MB
+Total VmRSS incr :     16.080 +/-      0.161 MB
+----- 5.CloseQuery------------- :                              ( n=1 )
+Total Real Time  :      0.000 +/-      0.000 s
+Total User Time  :      0.000 +/-      0.000 s
+Total System Time:      0.000 +/-      0.000 s
+Total Idle Time  :      0.000 +/-      0.000 s
+Total VmSize incr:      0.000 +/-      0.000 MB
+Total VmRSS incr :      0.000 +/-      0.000 MB
+----- TOTAL FetchObjRowsByVal-- :                              ( n=1 )
+Total Real Time  :     32.750 +/-     32.750 s
+Total User Time  :     22.680 +/-     22.680 s
+Total System Time:      7.000 +/-      7.000 s
+Total Idle Time  :      3.070 +/-      3.070 s
+Total VmSize incr:     18.132 +/-     18.132 MB
+Total VmRSS incr :     18.064 +/-     18.064 MB
+>>>>>>    Timing Results  <<<<<<<<<< 
+----- 1.FetchObjRowsByVal----- :                              ( n=1 )
+Total Real Time  :     32.760 +/-     32.760 s
+Total User Time  :     22.680 +/-     22.680 s
+Total System Time:      7.000 +/-      7.000 s
+Total Idle Time  :      3.080 +/-      3.080 s
+Total VmSize incr:     18.132 +/-     18.132 MB
+Total VmRSS incr :     18.072 +/-     18.072 MB
+----- 2.DecodeRow------------- :                              ( n=1 )
+Total Real Time  :      0.970 +/-      0.970 s
+Total User Time  :      0.960 +/-      0.960 s
+Total System Time:      0.000 +/-      0.000 s
+Total Idle Time  :      0.010 +/-      0.010 s
+Total VmSize incr:      3.016 +/-      3.016 MB
+Total VmRSS incr :      2.956 +/-      2.956 MB
+----- 3.DeleteOld------------- :                              ( n=1 )
+Total Real Time  :      4.190 +/-      4.190 s
+Total User Time  :      4.210 +/-      4.210 s
+Total System Time:      0.000 +/-      0.000 s
+Total Idle Time  :     -0.020 +/-     -0.020 s
+Total VmSize incr:     -0.132 +/-     -0.132 MB
+Total VmRSS incr :     -0.080 +/-     -0.080 MB
+----- TOTAL BrowseObjInTag---- :                              ( n=1 )
+Total Real Time  :     37.920 +/-     37.920 s
+Total User Time  :     27.860 +/-     27.860 s
+Total System Time:      7.000 +/-      7.000 s
+Total Idle Time  :      3.060 +/-      3.060 s
+Total VmSize incr:     21.016 +/-     21.016 MB
+Total VmRSS incr :     20.948 +/-     20.948 MB
+** reading 100000 objects (150 bytes mixed) **
+read back 10000 objects
+sec total: 37.9256
+obj/s:     263.674
+RelationalFolder                     Debug    Delete the RelationalFolder for '/myfolder'
+sec total (INCLUDING DELETE): 46.4649
+
+OK (1)
+[OVAL] Cppunit-result =0
+RelationalDatabase                   Info     Delete the RalDatabase for 'oracle://cooldb2;schema=AVALASSI;user=avalassi;password=andrea;dbname=COOLTEST'
+POOL/RelationalPlugins/oracle        Warning  No active transaction to roll back
+RelationalDatabase                   Debug    Delete the RelationalDatabase for 'oracle://cooldb2;schema=AVALASSI;user=avalassi;password=andrea;dbname=COOLTEST'
diff --git a/RelationalCool/tests/PerformanceAV/TestNewCopy/newCopy-memory.slc3.2006MB.out b/RelationalCool/tests/PerformanceAV/TestNewCopy/newCopy-memory.slc3.2006MB.out
new file mode 100644
index 000000000..653429ae2
--- /dev/null
+++ b/RelationalCool/tests/PerformanceAV/TestNewCopy/newCopy-memory.slc3.2006MB.out
@@ -0,0 +1,102 @@
+Property Catalogue: level[Info] Adding property: OutputLevel = 2 in scope "SEAL/Services/MessageService"
+Property Catalogue: level[Info] Adding property: Format =  "%-36s %-8s %s" in scope "SEAL/Services/MessageService"
+MessageService callback    Debug MessageService output level changed to Debug
+ConfigurationService    Debug Setting property: "Format" to value " "%-36s %-8s %s"" in scope "SEAL/Services/MessageService"
+POOL/Services/RelationalService      Info     Found plugin for RDBMS technology "mysql" with implementation "odbc"
+POOL/Services/RelationalService      Info     Found plugin for RDBMS technology "oracle" with native implementation
+POOL/Services/RelationalService      Info     Found plugin for RDBMS technology "sqlite" with native implementation
+POOL/Services/RelationalService      Info     Default implementation for RDBMS technology "mysql" is "odbc"
+POOL/Services/RelationalService      Info     Default implementation for RDBMS technology "oracle" is native
+POOL/Services/RelationalService      Info     Default implementation for RDBMS technology "sqlite" is native
+RelationalDatabase                   Debug    Instantiate a RelationalDatabase for 'oracle://cooldb2;schema=AVALASSI;user=avalassi;password=andrea;dbname=COOLTEST'
+RelationalDatabase                   Info     Instantiate a RalDatabase for 'oracle://cooldb2;schema=AVALASSI;user=avalassi;password=andrea;dbname=COOLTEST'
+POOL/RelationalPlugins/oracle        Info     Connected to a server running Oracle version 9.2.0.6.0
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT TABLE_NAME FROM ALL_TABLES WHERE OWNER = 'AVALASSI'"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT "DB_ATTRIBUTE_NAME", "DB_ATTRIBUTE_VALUE" FROM "AVALASSI"."COOLTEST_DB_ATTRIBUTES""
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_ISLEAF", "NODE_INSTIME", "FOLDER_PAYLOADSPEC", "FOLDER_VERSIONING", "FOLDER_IOVTABLENAME" FROM "AVALASSI"."COOLTEST_FOLDERS" WHERE "NODE_FULLPATH"=:"fullName""
+RelationalFolder                     Debug    Instantiate a RelationalFolder for '/myfolder'
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT "OBJECT_ID", "CHANNEL_ID", "IOV_SINCE", "IOV_UNTIL", "SYS_INSTIME", "I", "S", "X0", "X1", "X2", "X3", "X4", "X5", "X6", "X7", "X8", "X9", "P" FROM "AVALASSI"."COOLTEST_F0001_IOVS" WHERE "CHANNEL_ID"=:"channel" AND "IOV_SINCE">=:"since" AND "IOV_UNTIL"<=:"till" ORDER BY "CHANNEL_ID" ASC,"IOV_SINCE" ASC"
+>>>>>>    Timing Results  <<<<<<<<<< 
+----- 1.PrepareQuery----------- :                              ( n=1 )
+Total Real Time  :      0.010 +/-      0.010 s
+Total User Time  :      0.000 +/-      0.000 s
+Total System Time:      0.000 +/-      0.000 s
+Total Idle Time  :      0.010 +/-      0.010 s
+Total VmSize incr:      0.000 +/-      0.000 MB
+Total VmRSS incr :      0.000 +/-      0.000 MB
+----- 2.ProcessQuery----------- :                              ( n=1 )
+Total Real Time  :      0.010 +/-      0.010 s
+Total User Time  :      0.000 +/-      0.000 s
+Total System Time:      0.000 +/-      0.000 s
+Total Idle Time  :      0.010 +/-      0.010 s
+Total VmSize incr:      1.024 +/-      1.024 MB
+Total VmRSS incr :      0.420 +/-      0.420 MB
+----- 3.FetchRows-------------- :                              ( n=10001 )
+Total Real Time  :      9.330 +/-      0.093 s
+Total User Time  :      3.240 +/-      0.032 s
+Total System Time:      1.080 +/-      0.011 s
+Total Idle Time  :      5.050 +/-      0.050 s
+Total VmSize incr:      1.024 +/-      0.010 MB
+Total VmRSS incr :      1.524 +/-      0.015 MB
+----- 4.CopyAttributeList------ :                              ( n=10000 )
+Total Real Time  :      8.100 +/-      0.081 s
+Total User Time  :      6.620 +/-      0.066 s
+Total System Time:      1.290 +/-      0.013 s
+Total Idle Time  :      0.170 +/-      0.002 s
+Total VmSize incr:     15.360 +/-      0.154 MB
+Total VmRSS incr :     16.416 +/-      0.164 MB
+----- 5.CloseQuery------------- :                              ( n=1 )
+Total Real Time  :      0.000 +/-      0.000 s
+Total User Time  :      0.000 +/-      0.000 s
+Total System Time:      0.000 +/-      0.000 s
+Total Idle Time  :      0.000 +/-      0.000 s
+Total VmSize incr:      0.000 +/-      0.000 MB
+Total VmRSS incr :      0.000 +/-      0.000 MB
+----- TOTAL FetchObjRowsByVal-- :                              ( n=1 )
+Total Real Time  :     26.860 +/-     26.860 s
+Total User Time  :     15.390 +/-     15.390 s
+Total System Time:      4.860 +/-      4.860 s
+Total Idle Time  :      6.610 +/-      6.610 s
+Total VmSize incr:     18.432 +/-     18.432 MB
+Total VmRSS incr :     18.368 +/-     18.368 MB
+>>>>>>    Timing Results  <<<<<<<<<< 
+----- 1.FetchObjRowsByVal----- :                              ( n=1 )
+Total Real Time  :     26.870 +/-     26.870 s
+Total User Time  :     15.390 +/-     15.390 s
+Total System Time:      4.860 +/-      4.860 s
+Total Idle Time  :      6.620 +/-      6.620 s
+Total VmSize incr:     18.432 +/-     18.432 MB
+Total VmRSS incr :     18.376 +/-     18.376 MB
+----- 2.DecodeRow------------- :                              ( n=1 )
+Total Real Time  :      1.460 +/-      1.460 s
+Total User Time  :      1.420 +/-      1.420 s
+Total System Time:      0.020 +/-      0.020 s
+Total Idle Time  :      0.020 +/-      0.020 s
+Total VmSize incr:      3.072 +/-      3.072 MB
+Total VmRSS incr :      3.196 +/-      3.196 MB
+----- 3.DeleteOld------------- :                              ( n=1 )
+Total Real Time  :      0.090 +/-      0.090 s
+Total User Time  :      0.100 +/-      0.100 s
+Total System Time:      0.000 +/-      0.000 s
+Total Idle Time  :     -0.010 +/-     -0.010 s
+Total VmSize incr:      0.000 +/-      0.000 MB
+Total VmRSS incr :      0.000 +/-      0.000 MB
+----- TOTAL BrowseObjInTag---- :                              ( n=1 )
+Total Real Time  :     28.430 +/-     28.430 s
+Total User Time  :     16.920 +/-     16.920 s
+Total System Time:      4.880 +/-      4.880 s
+Total Idle Time  :      6.630 +/-      6.630 s
+Total VmSize incr:     21.504 +/-     21.504 MB
+Total VmRSS incr :     21.572 +/-     21.572 MB
+** reading 100000 objects (150 bytes mixed) **
+read back 10000 objects
+sec total: 28.4342
+obj/s:     351.689
+RelationalFolder                     Debug    Delete the RelationalFolder for '/myfolder'
+sec total (INCLUDING DELETE): 28.5795
+
+OK (1)
+[OVAL] Cppunit-result =0
+RelationalDatabase                   Info     Delete the RalDatabase for 'oracle://cooldb2;schema=AVALASSI;user=avalassi;password=andrea;dbname=COOLTEST'
+POOL/RelationalPlugins/oracle        Warning  No active transaction to roll back
+RelationalDatabase                   Debug    Delete the RelationalDatabase for 'oracle://cooldb2;schema=AVALASSI;user=avalassi;password=andrea;dbname=COOLTEST'
diff --git a/RelationalCool/tests/PerformanceAV/TestNewCopy/newCopy-time.rh73.1006MB.out b/RelationalCool/tests/PerformanceAV/TestNewCopy/newCopy-time.rh73.1006MB.out
new file mode 100644
index 000000000..f88c2aa3a
--- /dev/null
+++ b/RelationalCool/tests/PerformanceAV/TestNewCopy/newCopy-time.rh73.1006MB.out
@@ -0,0 +1,82 @@
+Property Catalogue: level[Info] Adding property: OutputLevel = 2 in scope "SEAL/Services/MessageService"
+Property Catalogue: level[Info] Adding property: Format =  "%-36s %-8s %s" in scope "SEAL/Services/MessageService"
+MessageService callback    Debug MessageService output level changed to Debug
+ConfigurationService    Debug Setting property: "Format" to value " "%-36s %-8s %s"" in scope "SEAL/Services/MessageService"
+POOL/Services/RelationalService      Info     Found plugin for RDBMS technology "mysql" with implementation "odbc"
+POOL/Services/RelationalService      Info     Found plugin for RDBMS technology "oracle" with native implementation
+POOL/Services/RelationalService      Info     Found plugin for RDBMS technology "sqlite" with native implementation
+POOL/Services/RelationalService      Info     Default implementation for RDBMS technology "mysql" is "odbc"
+POOL/Services/RelationalService      Info     Default implementation for RDBMS technology "oracle" is native
+POOL/Services/RelationalService      Info     Default implementation for RDBMS technology "sqlite" is native
+RelationalDatabase                   Debug    Instantiate a RelationalDatabase for 'oracle://cooldb2;schema=AVALASSI;user=avalassi;password=andrea;dbname=COOLTEST'
+RelationalDatabase                   Info     Instantiate a RalDatabase for 'oracle://cooldb2;schema=AVALASSI;user=avalassi;password=andrea;dbname=COOLTEST'
+POOL/RelationalPlugins/oracle        Info     Connected to a server running Oracle version 9.2.0.6.0
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT TABLE_NAME FROM ALL_TABLES WHERE OWNER = 'AVALASSI'"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT "DB_ATTRIBUTE_NAME", "DB_ATTRIBUTE_VALUE" FROM "AVALASSI"."COOLTEST_DB_ATTRIBUTES""
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_ISLEAF", "NODE_INSTIME", "FOLDER_PAYLOADSPEC", "FOLDER_VERSIONING", "FOLDER_IOVTABLENAME" FROM "AVALASSI"."COOLTEST_FOLDERS" WHERE "NODE_FULLPATH"=:"fullName""
+RelationalFolder                     Debug    Instantiate a RelationalFolder for '/myfolder'
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT "OBJECT_ID", "CHANNEL_ID", "IOV_SINCE", "IOV_UNTIL", "SYS_INSTIME", "I", "S", "X0", "X1", "X2", "X3", "X4", "X5", "X6", "X7", "X8", "X9", "P" FROM "AVALASSI"."COOLTEST_F0001_IOVS" WHERE "CHANNEL_ID"=:"channel" AND "IOV_SINCE">=:"since" AND "IOV_UNTIL"<=:"till" ORDER BY "CHANNEL_ID" ASC,"IOV_SINCE" ASC"
+>>>>>>    Timing Results  <<<<<<<<<< 
+----- 1.PrepareQuery----------- :                              ( n=1 )
+Total Real Time  :      0.000 +/-      0.000 s
+Total User Time  :      0.010 +/-      0.010 s
+Total System Time:      0.000 +/-      0.000 s
+Total Idle Time  :     -0.010 +/-     -0.010 s
+----- 2.ProcessQuery----------- :                              ( n=1 )
+Total Real Time  :      0.010 +/-      0.010 s
+Total User Time  :      0.010 +/-      0.010 s
+Total System Time:      0.000 +/-      0.000 s
+Total Idle Time  :      0.000 +/-      0.000 s
+----- 3.FetchRows-------------- :                              ( n=10001 )
+Total Real Time  :      3.900 +/-      0.039 s
+Total User Time  :      0.750 +/-      0.007 s
+Total System Time:      0.060 +/-      0.001 s
+Total Idle Time  :      3.120 +/-      0.031 s
+----- 4.CopyAttributeList------ :                              ( n=10000 )
+Total Real Time  :      4.640 +/-      0.046 s
+Total User Time  :      4.610 +/-      0.046 s
+Total System Time:      0.080 +/-      0.001 s
+Total Idle Time  :     -0.020 +/-     -0.000 s
+----- 5.CloseQuery------------- :                              ( n=1 )
+Total Real Time  :      0.000 +/-      0.000 s
+Total User Time  :      0.000 +/-      0.000 s
+Total System Time:      0.000 +/-      0.000 s
+Total Idle Time  :      0.000 +/-      0.000 s
+----- TOTAL FetchObjRowsByVal-- :                              ( n=1 )
+Total Real Time  :      8.730 +/-      8.730 s
+Total User Time  :      5.450 +/-      5.450 s
+Total System Time:      0.160 +/-      0.160 s
+Total Idle Time  :      3.120 +/-      3.120 s
+>>>>>>    Timing Results  <<<<<<<<<< 
+----- 1.FetchObjRowsByVal----- :                              ( n=1 )
+Total Real Time  :      8.730 +/-      8.730 s
+Total User Time  :      5.450 +/-      5.450 s
+Total System Time:      0.170 +/-      0.170 s
+Total Idle Time  :      3.110 +/-      3.110 s
+----- 2.DecodeRow------------- :                              ( n=1 )
+Total Real Time  :      0.980 +/-      0.980 s
+Total User Time  :      0.950 +/-      0.950 s
+Total System Time:      0.010 +/-      0.010 s
+Total Idle Time  :      0.020 +/-      0.020 s
+----- 3.DeleteOld------------- :                              ( n=1 )
+Total Real Time  :      4.640 +/-      4.640 s
+Total User Time  :      4.620 +/-      4.620 s
+Total System Time:      0.000 +/-      0.000 s
+Total Idle Time  :      0.020 +/-      0.020 s
+----- TOTAL BrowseObjInTag---- :                              ( n=1 )
+Total Real Time  :     14.350 +/-     14.350 s
+Total User Time  :     11.020 +/-     11.020 s
+Total System Time:      0.180 +/-      0.180 s
+Total Idle Time  :      3.150 +/-      3.150 s
+** reading 100000 objects (150 bytes mixed) **
+read back 10000 objects
+sec total: 14.3532
+obj/s:     696.709
+RelationalFolder                     Debug    Delete the RelationalFolder for '/myfolder'
+sec total (INCLUDING DELETE): 23.9338
+
+OK (1)
+[OVAL] Cppunit-result =0
+RelationalDatabase                   Info     Delete the RalDatabase for 'oracle://cooldb2;schema=AVALASSI;user=avalassi;password=andrea;dbname=COOLTEST'
+POOL/RelationalPlugins/oracle        Warning  No active transaction to roll back
+RelationalDatabase                   Debug    Delete the RelationalDatabase for 'oracle://cooldb2;schema=AVALASSI;user=avalassi;password=andrea;dbname=COOLTEST'
diff --git a/RelationalCool/tests/PerformanceAV/TestNewCopy/newCopy-time.rh73.501MB.out b/RelationalCool/tests/PerformanceAV/TestNewCopy/newCopy-time.rh73.501MB.out
new file mode 100644
index 000000000..4ba875cf7
--- /dev/null
+++ b/RelationalCool/tests/PerformanceAV/TestNewCopy/newCopy-time.rh73.501MB.out
@@ -0,0 +1,82 @@
+Property Catalogue: level[Info] Adding property: OutputLevel = 2 in scope "SEAL/Services/MessageService"
+Property Catalogue: level[Info] Adding property: Format =  "%-36s %-8s %s" in scope "SEAL/Services/MessageService"
+MessageService callback    Debug MessageService output level changed to Debug
+ConfigurationService    Debug Setting property: "Format" to value " "%-36s %-8s %s"" in scope "SEAL/Services/MessageService"
+POOL/Services/RelationalService      Info     Found plugin for RDBMS technology "mysql" with implementation "odbc"
+POOL/Services/RelationalService      Info     Found plugin for RDBMS technology "oracle" with native implementation
+POOL/Services/RelationalService      Info     Found plugin for RDBMS technology "sqlite" with native implementation
+POOL/Services/RelationalService      Info     Default implementation for RDBMS technology "mysql" is "odbc"
+POOL/Services/RelationalService      Info     Default implementation for RDBMS technology "oracle" is native
+POOL/Services/RelationalService      Info     Default implementation for RDBMS technology "sqlite" is native
+RelationalDatabase                   Debug    Instantiate a RelationalDatabase for 'oracle://cooldb2;schema=AVALASSI;user=avalassi;password=andrea;dbname=COOLTEST'
+RelationalDatabase                   Info     Instantiate a RalDatabase for 'oracle://cooldb2;schema=AVALASSI;user=avalassi;password=andrea;dbname=COOLTEST'
+POOL/RelationalPlugins/oracle        Info     Connected to a server running Oracle version 9.2.0.6.0
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT TABLE_NAME FROM ALL_TABLES WHERE OWNER = 'AVALASSI'"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT "DB_ATTRIBUTE_NAME", "DB_ATTRIBUTE_VALUE" FROM "AVALASSI"."COOLTEST_DB_ATTRIBUTES""
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_ISLEAF", "NODE_INSTIME", "FOLDER_PAYLOADSPEC", "FOLDER_VERSIONING", "FOLDER_IOVTABLENAME" FROM "AVALASSI"."COOLTEST_FOLDERS" WHERE "NODE_FULLPATH"=:"fullName""
+RelationalFolder                     Debug    Instantiate a RelationalFolder for '/myfolder'
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT "OBJECT_ID", "CHANNEL_ID", "IOV_SINCE", "IOV_UNTIL", "SYS_INSTIME", "I", "S", "X0", "X1", "X2", "X3", "X4", "X5", "X6", "X7", "X8", "X9", "P" FROM "AVALASSI"."COOLTEST_F0001_IOVS" WHERE "CHANNEL_ID"=:"channel" AND "IOV_SINCE">=:"since" AND "IOV_UNTIL"<=:"till" ORDER BY "CHANNEL_ID" ASC,"IOV_SINCE" ASC"
+>>>>>>    Timing Results  <<<<<<<<<< 
+----- 1.PrepareQuery----------- :                              ( n=1 )
+Total Real Time  :      0.000 +/-      0.000 s
+Total User Time  :      0.000 +/-      0.000 s
+Total System Time:      0.000 +/-      0.000 s
+Total Idle Time  :      0.000 +/-      0.000 s
+----- 2.ProcessQuery----------- :                              ( n=1 )
+Total Real Time  :      0.020 +/-      0.020 s
+Total User Time  :      0.000 +/-      0.000 s
+Total System Time:      0.000 +/-      0.000 s
+Total Idle Time  :      0.020 +/-      0.020 s
+----- 3.FetchRows-------------- :                              ( n=10001 )
+Total Real Time  :      3.760 +/-      0.038 s
+Total User Time  :      0.700 +/-      0.007 s
+Total System Time:      0.030 +/-      0.000 s
+Total Idle Time  :      3.050 +/-      0.030 s
+----- 4.CopyAttributeList------ :                              ( n=10000 )
+Total Real Time  :      4.800 +/-      0.048 s
+Total User Time  :      4.550 +/-      0.046 s
+Total System Time:      0.060 +/-      0.001 s
+Total Idle Time  :      0.180 +/-      0.002 s
+----- 5.CloseQuery------------- :                              ( n=1 )
+Total Real Time  :      0.000 +/-      0.000 s
+Total User Time  :      0.000 +/-      0.000 s
+Total System Time:      0.000 +/-      0.000 s
+Total Idle Time  :      0.000 +/-      0.000 s
+----- TOTAL FetchObjRowsByVal-- :                              ( n=1 )
+Total Real Time  :      8.690 +/-      8.690 s
+Total User Time  :      5.360 +/-      5.360 s
+Total System Time:      0.090 +/-      0.090 s
+Total Idle Time  :      3.240 +/-      3.240 s
+>>>>>>    Timing Results  <<<<<<<<<< 
+----- 1.FetchObjRowsByVal----- :                              ( n=1 )
+Total Real Time  :      8.700 +/-      8.700 s
+Total User Time  :      5.360 +/-      5.360 s
+Total System Time:      0.090 +/-      0.090 s
+Total Idle Time  :      3.250 +/-      3.250 s
+----- 2.DecodeRow------------- :                              ( n=1 )
+Total Real Time  :      0.970 +/-      0.970 s
+Total User Time  :      0.930 +/-      0.930 s
+Total System Time:      0.020 +/-      0.020 s
+Total Idle Time  :      0.020 +/-      0.020 s
+----- 3.DeleteOld------------- :                              ( n=1 )
+Total Real Time  :      4.460 +/-      4.460 s
+Total User Time  :      4.460 +/-      4.460 s
+Total System Time:      0.000 +/-      0.000 s
+Total Idle Time  :      0.000 +/-      0.000 s
+----- TOTAL BrowseObjInTag---- :                              ( n=1 )
+Total Real Time  :     14.130 +/-     14.130 s
+Total User Time  :     10.750 +/-     10.750 s
+Total System Time:      0.110 +/-      0.110 s
+Total Idle Time  :      3.270 +/-      3.270 s
+** reading 100000 objects (150 bytes mixed) **
+read back 10000 objects
+sec total: 14.1329
+obj/s:     707.567
+RelationalFolder                     Debug    Delete the RelationalFolder for '/myfolder'
+sec total (INCLUDING DELETE): 23.7273
+
+OK (1)
+[OVAL] Cppunit-result =0
+RelationalDatabase                   Info     Delete the RalDatabase for 'oracle://cooldb2;schema=AVALASSI;user=avalassi;password=andrea;dbname=COOLTEST'
+POOL/RelationalPlugins/oracle        Warning  No active transaction to roll back
+RelationalDatabase                   Debug    Delete the RelationalDatabase for 'oracle://cooldb2;schema=AVALASSI;user=avalassi;password=andrea;dbname=COOLTEST'
diff --git a/RelationalCool/tests/PerformanceAV/TestNewCopy/newCopy-time.slc3.2006MB.out b/RelationalCool/tests/PerformanceAV/TestNewCopy/newCopy-time.slc3.2006MB.out
new file mode 100644
index 000000000..58be89f95
--- /dev/null
+++ b/RelationalCool/tests/PerformanceAV/TestNewCopy/newCopy-time.slc3.2006MB.out
@@ -0,0 +1,82 @@
+Property Catalogue: level[Info] Adding property: OutputLevel = 2 in scope "SEAL/Services/MessageService"
+Property Catalogue: level[Info] Adding property: Format =  "%-36s %-8s %s" in scope "SEAL/Services/MessageService"
+MessageService callback    Debug MessageService output level changed to Debug
+ConfigurationService    Debug Setting property: "Format" to value " "%-36s %-8s %s"" in scope "SEAL/Services/MessageService"
+POOL/Services/RelationalService      Info     Found plugin for RDBMS technology "mysql" with implementation "odbc"
+POOL/Services/RelationalService      Info     Found plugin for RDBMS technology "oracle" with native implementation
+POOL/Services/RelationalService      Info     Found plugin for RDBMS technology "sqlite" with native implementation
+POOL/Services/RelationalService      Info     Default implementation for RDBMS technology "mysql" is "odbc"
+POOL/Services/RelationalService      Info     Default implementation for RDBMS technology "oracle" is native
+POOL/Services/RelationalService      Info     Default implementation for RDBMS technology "sqlite" is native
+RelationalDatabase                   Debug    Instantiate a RelationalDatabase for 'oracle://cooldb2;schema=AVALASSI;user=avalassi;password=andrea;dbname=COOLTEST'
+RelationalDatabase                   Info     Instantiate a RalDatabase for 'oracle://cooldb2;schema=AVALASSI;user=avalassi;password=andrea;dbname=COOLTEST'
+POOL/RelationalPlugins/oracle        Info     Connected to a server running Oracle version 9.2.0.6.0
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT TABLE_NAME FROM ALL_TABLES WHERE OWNER = 'AVALASSI'"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT "DB_ATTRIBUTE_NAME", "DB_ATTRIBUTE_VALUE" FROM "AVALASSI"."COOLTEST_DB_ATTRIBUTES""
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_ISLEAF", "NODE_INSTIME", "FOLDER_PAYLOADSPEC", "FOLDER_VERSIONING", "FOLDER_IOVTABLENAME" FROM "AVALASSI"."COOLTEST_FOLDERS" WHERE "NODE_FULLPATH"=:"fullName""
+RelationalFolder                     Debug    Instantiate a RelationalFolder for '/myfolder'
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT "OBJECT_ID", "CHANNEL_ID", "IOV_SINCE", "IOV_UNTIL", "SYS_INSTIME", "I", "S", "X0", "X1", "X2", "X3", "X4", "X5", "X6", "X7", "X8", "X9", "P" FROM "AVALASSI"."COOLTEST_F0001_IOVS" WHERE "CHANNEL_ID"=:"channel" AND "IOV_SINCE">=:"since" AND "IOV_UNTIL"<=:"till" ORDER BY "CHANNEL_ID" ASC,"IOV_SINCE" ASC"
+>>>>>>    Timing Results  <<<<<<<<<< 
+----- 1.PrepareQuery----------- :                              ( n=1 )
+Total Real Time  :      0.000 +/-      0.000 s
+Total User Time  :      0.000 +/-      0.000 s
+Total System Time:      0.000 +/-      0.000 s
+Total Idle Time  :      0.000 +/-      0.000 s
+----- 2.ProcessQuery----------- :                              ( n=1 )
+Total Real Time  :      0.010 +/-      0.010 s
+Total User Time  :      0.000 +/-      0.000 s
+Total System Time:      0.000 +/-      0.000 s
+Total Idle Time  :      0.010 +/-      0.010 s
+----- 3.FetchRows-------------- :                              ( n=10001 )
+Total Real Time  :      4.120 +/-      0.041 s
+Total User Time  :      0.530 +/-      0.005 s
+Total System Time:      0.050 +/-      0.000 s
+Total Idle Time  :      3.540 +/-      0.035 s
+----- 4.CopyAttributeList------ :                              ( n=10000 )
+Total Real Time  :      4.760 +/-      0.048 s
+Total User Time  :      3.320 +/-      0.033 s
+Total System Time:      0.060 +/-      0.001 s
+Total Idle Time  :      1.390 +/-      0.014 s
+----- 5.CloseQuery------------- :                              ( n=1 )
+Total Real Time  :      0.000 +/-      0.000 s
+Total User Time  :      0.000 +/-      0.000 s
+Total System Time:      0.000 +/-      0.000 s
+Total Idle Time  :      0.000 +/-      0.000 s
+----- TOTAL FetchObjRowsByVal-- :                              ( n=1 )
+Total Real Time  :      9.150 +/-      9.150 s
+Total User Time  :      3.960 +/-      3.960 s
+Total System Time:      0.130 +/-      0.130 s
+Total Idle Time  :      5.060 +/-      5.060 s
+>>>>>>    Timing Results  <<<<<<<<<< 
+----- 1.FetchObjRowsByVal----- :                              ( n=1 )
+Total Real Time  :      9.150 +/-      9.150 s
+Total User Time  :      3.960 +/-      3.960 s
+Total System Time:      0.130 +/-      0.130 s
+Total Idle Time  :      5.060 +/-      5.060 s
+----- 2.DecodeRow------------- :                              ( n=1 )
+Total Real Time  :      1.460 +/-      1.460 s
+Total User Time  :      1.410 +/-      1.410 s
+Total System Time:      0.000 +/-      0.000 s
+Total Idle Time  :      0.050 +/-      0.050 s
+----- 3.DeleteOld------------- :                              ( n=1 )
+Total Real Time  :      0.080 +/-      0.080 s
+Total User Time  :      0.080 +/-      0.080 s
+Total System Time:      0.000 +/-      0.000 s
+Total Idle Time  :      0.000 +/-      0.000 s
+----- TOTAL BrowseObjInTag---- :                              ( n=1 )
+Total Real Time  :     10.690 +/-     10.690 s
+Total User Time  :      5.450 +/-      5.450 s
+Total System Time:      0.130 +/-      0.130 s
+Total Idle Time  :      5.110 +/-      5.110 s
+** reading 100000 objects (150 bytes mixed) **
+read back 10000 objects
+sec total: 10.6924
+obj/s:     935.247
+RelationalFolder                     Debug    Delete the RelationalFolder for '/myfolder'
+sec total (INCLUDING DELETE): 10.861
+
+OK (1)
+[OVAL] Cppunit-result =0
+RelationalDatabase                   Info     Delete the RalDatabase for 'oracle://cooldb2;schema=AVALASSI;user=avalassi;password=andrea;dbname=COOLTEST'
+POOL/RelationalPlugins/oracle        Warning  No active transaction to roll back
+RelationalDatabase                   Debug    Delete the RelationalDatabase for 'oracle://cooldb2;schema=AVALASSI;user=avalassi;password=andrea;dbname=COOLTEST'
diff --git a/RelationalCool/tests/PerformanceAV/TestNewCopy/oldCopy-memory.rh73.1006MB.out b/RelationalCool/tests/PerformanceAV/TestNewCopy/oldCopy-memory.rh73.1006MB.out
new file mode 100644
index 000000000..5d8d9f898
--- /dev/null
+++ b/RelationalCool/tests/PerformanceAV/TestNewCopy/oldCopy-memory.rh73.1006MB.out
@@ -0,0 +1,102 @@
+Property Catalogue: level[Info] Adding property: OutputLevel = 2 in scope "SEAL/Services/MessageService"
+Property Catalogue: level[Info] Adding property: Format =  "%-36s %-8s %s" in scope "SEAL/Services/MessageService"
+MessageService callback    Debug MessageService output level changed to Debug
+ConfigurationService    Debug Setting property: "Format" to value " "%-36s %-8s %s"" in scope "SEAL/Services/MessageService"
+POOL/Services/RelationalService      Info     Found plugin for RDBMS technology "mysql" with implementation "odbc"
+POOL/Services/RelationalService      Info     Found plugin for RDBMS technology "oracle" with native implementation
+POOL/Services/RelationalService      Info     Found plugin for RDBMS technology "sqlite" with native implementation
+POOL/Services/RelationalService      Info     Default implementation for RDBMS technology "mysql" is "odbc"
+POOL/Services/RelationalService      Info     Default implementation for RDBMS technology "oracle" is native
+POOL/Services/RelationalService      Info     Default implementation for RDBMS technology "sqlite" is native
+RelationalDatabase                   Debug    Instantiate a RelationalDatabase for 'oracle://cooldb2;schema=AVALASSI;user=avalassi;password=andrea;dbname=COOLTEST'
+RelationalDatabase                   Info     Instantiate a RalDatabase for 'oracle://cooldb2;schema=AVALASSI;user=avalassi;password=andrea;dbname=COOLTEST'
+POOL/RelationalPlugins/oracle        Info     Connected to a server running Oracle version 9.2.0.6.0
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT TABLE_NAME FROM ALL_TABLES WHERE OWNER = 'AVALASSI'"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT "DB_ATTRIBUTE_NAME", "DB_ATTRIBUTE_VALUE" FROM "AVALASSI"."COOLTEST_DB_ATTRIBUTES""
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_ISLEAF", "NODE_INSTIME", "FOLDER_PAYLOADSPEC", "FOLDER_VERSIONING", "FOLDER_IOVTABLENAME" FROM "AVALASSI"."COOLTEST_FOLDERS" WHERE "NODE_FULLPATH"=:"fullName""
+RelationalFolder                     Debug    Instantiate a RelationalFolder for '/myfolder'
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT "OBJECT_ID", "CHANNEL_ID", "IOV_SINCE", "IOV_UNTIL", "SYS_INSTIME", "I", "S", "X0", "X1", "X2", "X3", "X4", "X5", "X6", "X7", "X8", "X9", "P" FROM "AVALASSI"."COOLTEST_F0001_IOVS" WHERE "CHANNEL_ID"=:"channel" AND "IOV_SINCE">=:"since" AND "IOV_UNTIL"<=:"till" ORDER BY "CHANNEL_ID" ASC,"IOV_SINCE" ASC"
+>>>>>>    Timing Results  <<<<<<<<<< 
+----- 1.PrepareQuery----------- :                              ( n=1 )
+Total Real Time  :      0.000 +/-      0.000 s
+Total User Time  :      0.000 +/-      0.000 s
+Total System Time:      0.000 +/-      0.000 s
+Total Idle Time  :      0.000 +/-      0.000 s
+Total VmSize incr:      0.000 +/-      0.000 MB
+Total VmRSS incr :      0.012 +/-      0.012 MB
+----- 2.ProcessQuery----------- :                              ( n=1 )
+Total Real Time  :      0.020 +/-      0.020 s
+Total User Time  :      0.020 +/-      0.020 s
+Total System Time:      0.000 +/-      0.000 s
+Total Idle Time  :      0.000 +/-      0.000 s
+Total VmSize incr:      0.412 +/-      0.412 MB
+Total VmRSS incr :      0.412 +/-      0.412 MB
+----- 3.FetchRows-------------- :                              ( n=10001 )
+Total Real Time  :     10.140 +/-      0.101 s
+Total User Time  :      5.030 +/-      0.050 s
+Total System Time:      1.950 +/-      0.019 s
+Total Idle Time  :      3.190 +/-      0.032 s
+Total VmSize incr:      0.024 +/-      0.000 MB
+Total VmRSS incr :      1.460 +/-      0.015 MB
+----- 4.CopyAttributeList------ :                              ( n=10000 )
+Total Real Time  :     12.330 +/-      0.123 s
+Total User Time  :     10.130 +/-      0.101 s
+Total System Time:      1.910 +/-      0.019 s
+Total Idle Time  :      0.320 +/-      0.003 s
+Total VmSize incr:     25.344 +/-      0.253 MB
+Total VmRSS incr :     23.880 +/-      0.239 MB
+----- 5.CloseQuery------------- :                              ( n=1 )
+Total Real Time  :      0.000 +/-      0.000 s
+Total User Time  :      0.000 +/-      0.000 s
+Total System Time:      0.000 +/-      0.000 s
+Total Idle Time  :      0.000 +/-      0.000 s
+Total VmSize incr:      0.000 +/-      0.000 MB
+Total VmRSS incr :      0.000 +/-      0.000 MB
+----- TOTAL FetchObjRowsByVal-- :                              ( n=1 )
+Total Real Time  :     35.010 +/-     35.010 s
+Total User Time  :     23.730 +/-     23.730 s
+Total System Time:      7.660 +/-      7.660 s
+Total Idle Time  :      3.620 +/-      3.620 s
+Total VmSize incr:     25.824 +/-     25.824 MB
+Total VmRSS incr :     25.764 +/-     25.764 MB
+>>>>>>    Timing Results  <<<<<<<<<< 
+----- 1.FetchObjRowsByVal----- :                              ( n=1 )
+Total Real Time  :     35.010 +/-     35.010 s
+Total User Time  :     23.730 +/-     23.730 s
+Total System Time:      7.660 +/-      7.660 s
+Total Idle Time  :      3.620 +/-      3.620 s
+Total VmSize incr:     25.824 +/-     25.824 MB
+Total VmRSS incr :     25.772 +/-     25.772 MB
+----- 2.DecodeRow------------- :                              ( n=1 )
+Total Real Time  :      1.000 +/-      1.000 s
+Total User Time  :      0.980 +/-      0.980 s
+Total System Time:      0.020 +/-      0.020 s
+Total Idle Time  :      0.000 +/-      0.000 s
+Total VmSize incr:      3.012 +/-      3.012 MB
+Total VmRSS incr :      2.952 +/-      2.952 MB
+----- 3.DeleteOld------------- :                              ( n=1 )
+Total Real Time  :      0.160 +/-      0.160 s
+Total User Time  :      0.160 +/-      0.160 s
+Total System Time:      0.000 +/-      0.000 s
+Total Idle Time  :      0.000 +/-      0.000 s
+Total VmSize incr:     -0.132 +/-     -0.132 MB
+Total VmRSS incr :     -0.080 +/-     -0.080 MB
+----- TOTAL BrowseObjInTag---- :                              ( n=1 )
+Total Real Time  :     36.170 +/-     36.170 s
+Total User Time  :     24.870 +/-     24.870 s
+Total System Time:      7.680 +/-      7.680 s
+Total Idle Time  :      3.620 +/-      3.620 s
+Total VmSize incr:     28.704 +/-     28.704 MB
+Total VmRSS incr :     28.644 +/-     28.644 MB
+** reading 100000 objects (150 bytes mixed) **
+read back 10000 objects
+sec total: 36.1765
+obj/s:     276.422
+RelationalFolder                     Debug    Delete the RelationalFolder for '/myfolder'
+sec total (INCLUDING DELETE): 36.309
+
+OK (1)
+[OVAL] Cppunit-result =0
+RelationalDatabase                   Info     Delete the RalDatabase for 'oracle://cooldb2;schema=AVALASSI;user=avalassi;password=andrea;dbname=COOLTEST'
+POOL/RelationalPlugins/oracle        Warning  No active transaction to roll back
+RelationalDatabase                   Debug    Delete the RelationalDatabase for 'oracle://cooldb2;schema=AVALASSI;user=avalassi;password=andrea;dbname=COOLTEST'
diff --git a/RelationalCool/tests/PerformanceAV/TestNewCopy/oldCopy-memory.rh73.501MB.out b/RelationalCool/tests/PerformanceAV/TestNewCopy/oldCopy-memory.rh73.501MB.out
new file mode 100644
index 000000000..2e199cc2f
--- /dev/null
+++ b/RelationalCool/tests/PerformanceAV/TestNewCopy/oldCopy-memory.rh73.501MB.out
@@ -0,0 +1,102 @@
+Property Catalogue: level[Info] Adding property: OutputLevel = 2 in scope "SEAL/Services/MessageService"
+Property Catalogue: level[Info] Adding property: Format =  "%-36s %-8s %s" in scope "SEAL/Services/MessageService"
+MessageService callback    Debug MessageService output level changed to Debug
+ConfigurationService    Debug Setting property: "Format" to value " "%-36s %-8s %s"" in scope "SEAL/Services/MessageService"
+POOL/Services/RelationalService      Info     Found plugin for RDBMS technology "mysql" with implementation "odbc"
+POOL/Services/RelationalService      Info     Found plugin for RDBMS technology "oracle" with native implementation
+POOL/Services/RelationalService      Info     Found plugin for RDBMS technology "sqlite" with native implementation
+POOL/Services/RelationalService      Info     Default implementation for RDBMS technology "mysql" is "odbc"
+POOL/Services/RelationalService      Info     Default implementation for RDBMS technology "oracle" is native
+POOL/Services/RelationalService      Info     Default implementation for RDBMS technology "sqlite" is native
+RelationalDatabase                   Debug    Instantiate a RelationalDatabase for 'oracle://cooldb2;schema=AVALASSI;user=avalassi;password=andrea;dbname=COOLTEST'
+RelationalDatabase                   Info     Instantiate a RalDatabase for 'oracle://cooldb2;schema=AVALASSI;user=avalassi;password=andrea;dbname=COOLTEST'
+POOL/RelationalPlugins/oracle        Info     Connected to a server running Oracle version 9.2.0.6.0
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT TABLE_NAME FROM ALL_TABLES WHERE OWNER = 'AVALASSI'"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT "DB_ATTRIBUTE_NAME", "DB_ATTRIBUTE_VALUE" FROM "AVALASSI"."COOLTEST_DB_ATTRIBUTES""
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_ISLEAF", "NODE_INSTIME", "FOLDER_PAYLOADSPEC", "FOLDER_VERSIONING", "FOLDER_IOVTABLENAME" FROM "AVALASSI"."COOLTEST_FOLDERS" WHERE "NODE_FULLPATH"=:"fullName""
+RelationalFolder                     Debug    Instantiate a RelationalFolder for '/myfolder'
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT "OBJECT_ID", "CHANNEL_ID", "IOV_SINCE", "IOV_UNTIL", "SYS_INSTIME", "I", "S", "X0", "X1", "X2", "X3", "X4", "X5", "X6", "X7", "X8", "X9", "P" FROM "AVALASSI"."COOLTEST_F0001_IOVS" WHERE "CHANNEL_ID"=:"channel" AND "IOV_SINCE">=:"since" AND "IOV_UNTIL"<=:"till" ORDER BY "CHANNEL_ID" ASC,"IOV_SINCE" ASC"
+>>>>>>    Timing Results  <<<<<<<<<< 
+----- 1.PrepareQuery----------- :                              ( n=1 )
+Total Real Time  :      0.010 +/-      0.010 s
+Total User Time  :      0.000 +/-      0.000 s
+Total System Time:      0.000 +/-      0.000 s
+Total Idle Time  :      0.010 +/-      0.010 s
+Total VmSize incr:      0.000 +/-      0.000 MB
+Total VmRSS incr :      0.012 +/-      0.012 MB
+----- 2.ProcessQuery----------- :                              ( n=1 )
+Total Real Time  :      0.010 +/-      0.010 s
+Total User Time  :      0.000 +/-      0.000 s
+Total System Time:      0.000 +/-      0.000 s
+Total Idle Time  :      0.010 +/-      0.010 s
+Total VmSize incr:      0.412 +/-      0.412 MB
+Total VmRSS incr :      0.412 +/-      0.412 MB
+----- 3.FetchRows-------------- :                              ( n=10001 )
+Total Real Time  :     10.030 +/-      0.100 s
+Total User Time  :      5.040 +/-      0.050 s
+Total System Time:      1.920 +/-      0.019 s
+Total Idle Time  :      3.070 +/-      0.031 s
+Total VmSize incr:      0.024 +/-      0.000 MB
+Total VmRSS incr :      1.460 +/-      0.015 MB
+----- 4.CopyAttributeList------ :                              ( n=10000 )
+Total Real Time  :     11.700 +/-      0.117 s
+Total User Time  :      9.790 +/-      0.098 s
+Total System Time:      1.900 +/-      0.019 s
+Total Idle Time  :      0.010 +/-      0.000 s
+Total VmSize incr:     25.344 +/-      0.253 MB
+Total VmRSS incr :     23.880 +/-      0.239 MB
+----- 5.CloseQuery------------- :                              ( n=1 )
+Total Real Time  :      0.000 +/-      0.000 s
+Total User Time  :      0.000 +/-      0.000 s
+Total System Time:      0.000 +/-      0.000 s
+Total Idle Time  :      0.000 +/-      0.000 s
+Total VmSize incr:      0.000 +/-      0.000 MB
+Total VmRSS incr :      0.000 +/-      0.000 MB
+----- TOTAL FetchObjRowsByVal-- :                              ( n=1 )
+Total Real Time  :     34.280 +/-     34.280 s
+Total User Time  :     23.580 +/-     23.580 s
+Total System Time:      7.680 +/-      7.680 s
+Total Idle Time  :      3.020 +/-      3.020 s
+Total VmSize incr:     25.824 +/-     25.824 MB
+Total VmRSS incr :     25.764 +/-     25.764 MB
+>>>>>>    Timing Results  <<<<<<<<<< 
+----- 1.FetchObjRowsByVal----- :                              ( n=1 )
+Total Real Time  :     34.280 +/-     34.280 s
+Total User Time  :     23.580 +/-     23.580 s
+Total System Time:      7.680 +/-      7.680 s
+Total Idle Time  :      3.020 +/-      3.020 s
+Total VmSize incr:     25.824 +/-     25.824 MB
+Total VmRSS incr :     25.772 +/-     25.772 MB
+----- 2.DecodeRow------------- :                              ( n=1 )
+Total Real Time  :      0.990 +/-      0.990 s
+Total User Time  :      0.980 +/-      0.980 s
+Total System Time:      0.000 +/-      0.000 s
+Total Idle Time  :      0.010 +/-      0.010 s
+Total VmSize incr:      3.012 +/-      3.012 MB
+Total VmRSS incr :      2.952 +/-      2.952 MB
+----- 3.DeleteOld------------- :                              ( n=1 )
+Total Real Time  :      0.160 +/-      0.160 s
+Total User Time  :      0.160 +/-      0.160 s
+Total System Time:      0.000 +/-      0.000 s
+Total Idle Time  :      0.000 +/-      0.000 s
+Total VmSize incr:     -0.132 +/-     -0.132 MB
+Total VmRSS incr :     -0.080 +/-     -0.080 MB
+----- TOTAL BrowseObjInTag---- :                              ( n=1 )
+Total Real Time  :     35.430 +/-     35.430 s
+Total User Time  :     24.720 +/-     24.720 s
+Total System Time:      7.680 +/-      7.680 s
+Total Idle Time  :      3.030 +/-      3.030 s
+Total VmSize incr:     28.704 +/-     28.704 MB
+Total VmRSS incr :     28.644 +/-     28.644 MB
+** reading 100000 objects (150 bytes mixed) **
+read back 10000 objects
+sec total: 35.4379
+obj/s:     282.184
+RelationalFolder                     Debug    Delete the RelationalFolder for '/myfolder'
+sec total (INCLUDING DELETE): 35.576
+
+OK (1)
+[OVAL] Cppunit-result =0
+RelationalDatabase                   Info     Delete the RalDatabase for 'oracle://cooldb2;schema=AVALASSI;user=avalassi;password=andrea;dbname=COOLTEST'
+POOL/RelationalPlugins/oracle        Warning  No active transaction to roll back
+RelationalDatabase                   Debug    Delete the RelationalDatabase for 'oracle://cooldb2;schema=AVALASSI;user=avalassi;password=andrea;dbname=COOLTEST'
diff --git a/RelationalCool/tests/PerformanceAV/TestNewCopy/oldCopy-memory.slc3.2006MB.out b/RelationalCool/tests/PerformanceAV/TestNewCopy/oldCopy-memory.slc3.2006MB.out
new file mode 100644
index 000000000..37c6ab28f
--- /dev/null
+++ b/RelationalCool/tests/PerformanceAV/TestNewCopy/oldCopy-memory.slc3.2006MB.out
@@ -0,0 +1,102 @@
+Property Catalogue: level[Info] Adding property: OutputLevel = 2 in scope "SEAL/Services/MessageService"
+Property Catalogue: level[Info] Adding property: Format =  "%-36s %-8s %s" in scope "SEAL/Services/MessageService"
+MessageService callback    Debug MessageService output level changed to Debug
+ConfigurationService    Debug Setting property: "Format" to value " "%-36s %-8s %s"" in scope "SEAL/Services/MessageService"
+POOL/Services/RelationalService      Info     Found plugin for RDBMS technology "mysql" with implementation "odbc"
+POOL/Services/RelationalService      Info     Found plugin for RDBMS technology "oracle" with native implementation
+POOL/Services/RelationalService      Info     Found plugin for RDBMS technology "sqlite" with native implementation
+POOL/Services/RelationalService      Info     Default implementation for RDBMS technology "mysql" is "odbc"
+POOL/Services/RelationalService      Info     Default implementation for RDBMS technology "oracle" is native
+POOL/Services/RelationalService      Info     Default implementation for RDBMS technology "sqlite" is native
+RelationalDatabase                   Debug    Instantiate a RelationalDatabase for 'oracle://cooldb2;schema=AVALASSI;user=avalassi;password=andrea;dbname=COOLTEST'
+RelationalDatabase                   Info     Instantiate a RalDatabase for 'oracle://cooldb2;schema=AVALASSI;user=avalassi;password=andrea;dbname=COOLTEST'
+POOL/RelationalPlugins/oracle        Info     Connected to a server running Oracle version 9.2.0.6.0
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT TABLE_NAME FROM ALL_TABLES WHERE OWNER = 'AVALASSI'"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT "DB_ATTRIBUTE_NAME", "DB_ATTRIBUTE_VALUE" FROM "AVALASSI"."COOLTEST_DB_ATTRIBUTES""
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_ISLEAF", "NODE_INSTIME", "FOLDER_PAYLOADSPEC", "FOLDER_VERSIONING", "FOLDER_IOVTABLENAME" FROM "AVALASSI"."COOLTEST_FOLDERS" WHERE "NODE_FULLPATH"=:"fullName""
+RelationalFolder                     Debug    Instantiate a RelationalFolder for '/myfolder'
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT "OBJECT_ID", "CHANNEL_ID", "IOV_SINCE", "IOV_UNTIL", "SYS_INSTIME", "I", "S", "X0", "X1", "X2", "X3", "X4", "X5", "X6", "X7", "X8", "X9", "P" FROM "AVALASSI"."COOLTEST_F0001_IOVS" WHERE "CHANNEL_ID"=:"channel" AND "IOV_SINCE">=:"since" AND "IOV_UNTIL"<=:"till" ORDER BY "CHANNEL_ID" ASC,"IOV_SINCE" ASC"
+>>>>>>    Timing Results  <<<<<<<<<< 
+----- 1.PrepareQuery----------- :                              ( n=1 )
+Total Real Time  :      0.000 +/-      0.000 s
+Total User Time  :      0.000 +/-      0.000 s
+Total System Time:      0.000 +/-      0.000 s
+Total Idle Time  :      0.000 +/-      0.000 s
+Total VmSize incr:      0.000 +/-      0.000 MB
+Total VmRSS incr :      0.000 +/-      0.000 MB
+----- 2.ProcessQuery----------- :                              ( n=1 )
+Total Real Time  :      0.010 +/-      0.010 s
+Total User Time  :      0.000 +/-      0.000 s
+Total System Time:      0.000 +/-      0.000 s
+Total Idle Time  :      0.010 +/-      0.010 s
+Total VmSize incr:      0.396 +/-      0.396 MB
+Total VmRSS incr :      0.416 +/-      0.416 MB
+----- 3.FetchRows-------------- :                              ( n=10001 )
+Total Real Time  :     13.060 +/-      0.131 s
+Total User Time  :      3.450 +/-      0.034 s
+Total System Time:      1.230 +/-      0.012 s
+Total Idle Time  :      8.360 +/-      0.084 s
+Total VmSize incr:      0.236 +/-      0.002 MB
+Total VmRSS incr :      1.508 +/-      0.015 MB
+----- 4.CopyAttributeList------ :                              ( n=10000 )
+Total Real Time  :     11.050 +/-      0.111 s
+Total User Time  :      7.860 +/-      0.079 s
+Total System Time:      1.160 +/-      0.012 s
+Total Idle Time  :      2.060 +/-      0.021 s
+Total VmSize incr:     27.544 +/-      0.275 MB
+Total VmRSS incr :     24.276 +/-      0.243 MB
+----- 5.CloseQuery------------- :                              ( n=1 )
+Total Real Time  :      0.000 +/-      0.000 s
+Total User Time  :      0.000 +/-      0.000 s
+Total System Time:      0.000 +/-      0.000 s
+Total Idle Time  :      0.000 +/-      0.000 s
+Total VmSize incr:      0.000 +/-      0.000 MB
+Total VmRSS incr :      0.000 +/-      0.000 MB
+----- TOTAL FetchObjRowsByVal-- :                              ( n=1 )
+Total Real Time  :     35.960 +/-     35.960 s
+Total User Time  :     16.850 +/-     16.850 s
+Total System Time:      5.000 +/-      5.000 s
+Total Idle Time  :     14.110 +/-     14.110 s
+Total VmSize incr:     26.596 +/-     26.596 MB
+Total VmRSS incr :     26.208 +/-     26.208 MB
+>>>>>>    Timing Results  <<<<<<<<<< 
+----- 1.FetchObjRowsByVal----- :                              ( n=1 )
+Total Real Time  :     35.960 +/-     35.960 s
+Total User Time  :     16.850 +/-     16.850 s
+Total System Time:      5.000 +/-      5.000 s
+Total Idle Time  :     14.110 +/-     14.110 s
+Total VmSize incr:     26.596 +/-     26.596 MB
+Total VmRSS incr :     26.216 +/-     26.216 MB
+----- 2.DecodeRow------------- :                              ( n=1 )
+Total Real Time  :      1.470 +/-      1.470 s
+Total User Time  :      1.370 +/-      1.370 s
+Total System Time:      0.020 +/-      0.020 s
+Total Idle Time  :      0.080 +/-      0.080 s
+Total VmSize incr:      3.300 +/-      3.300 MB
+Total VmRSS incr :      3.192 +/-      3.192 MB
+----- 3.DeleteOld------------- :                              ( n=1 )
+Total Real Time  :      0.140 +/-      0.140 s
+Total User Time  :      0.140 +/-      0.140 s
+Total System Time:      0.000 +/-      0.000 s
+Total Idle Time  :      0.000 +/-      0.000 s
+Total VmSize incr:     -0.132 +/-     -0.132 MB
+Total VmRSS incr :     -0.080 +/-     -0.080 MB
+----- TOTAL BrowseObjInTag---- :                              ( n=1 )
+Total Real Time  :     37.610 +/-     37.610 s
+Total User Time  :     18.390 +/-     18.390 s
+Total System Time:      5.020 +/-      5.020 s
+Total Idle Time  :     14.200 +/-     14.200 s
+Total VmSize incr:     29.764 +/-     29.764 MB
+Total VmRSS incr :     29.328 +/-     29.328 MB
+** reading 100000 objects (150 bytes mixed) **
+read back 10000 objects
+sec total: 37.6132
+obj/s:     265.864
+RelationalFolder                     Debug    Delete the RelationalFolder for '/myfolder'
+sec total (INCLUDING DELETE): 37.7453
+
+OK (1)
+[OVAL] Cppunit-result =0
+RelationalDatabase                   Info     Delete the RalDatabase for 'oracle://cooldb2;schema=AVALASSI;user=avalassi;password=andrea;dbname=COOLTEST'
+POOL/RelationalPlugins/oracle        Warning  No active transaction to roll back
+RelationalDatabase                   Debug    Delete the RelationalDatabase for 'oracle://cooldb2;schema=AVALASSI;user=avalassi;password=andrea;dbname=COOLTEST'
diff --git a/RelationalCool/tests/PerformanceAV/TestNewCopy/oldCopy-time.rh73.1006MB.out b/RelationalCool/tests/PerformanceAV/TestNewCopy/oldCopy-time.rh73.1006MB.out
new file mode 100644
index 000000000..a4d408c08
--- /dev/null
+++ b/RelationalCool/tests/PerformanceAV/TestNewCopy/oldCopy-time.rh73.1006MB.out
@@ -0,0 +1,82 @@
+Property Catalogue: level[Info] Adding property: OutputLevel = 2 in scope "SEAL/Services/MessageService"
+Property Catalogue: level[Info] Adding property: Format =  "%-36s %-8s %s" in scope "SEAL/Services/MessageService"
+MessageService callback    Debug MessageService output level changed to Debug
+ConfigurationService    Debug Setting property: "Format" to value " "%-36s %-8s %s"" in scope "SEAL/Services/MessageService"
+POOL/Services/RelationalService      Info     Found plugin for RDBMS technology "mysql" with implementation "odbc"
+POOL/Services/RelationalService      Info     Found plugin for RDBMS technology "oracle" with native implementation
+POOL/Services/RelationalService      Info     Found plugin for RDBMS technology "sqlite" with native implementation
+POOL/Services/RelationalService      Info     Default implementation for RDBMS technology "mysql" is "odbc"
+POOL/Services/RelationalService      Info     Default implementation for RDBMS technology "oracle" is native
+POOL/Services/RelationalService      Info     Default implementation for RDBMS technology "sqlite" is native
+RelationalDatabase                   Debug    Instantiate a RelationalDatabase for 'oracle://cooldb2;schema=AVALASSI;user=avalassi;password=andrea;dbname=COOLTEST'
+RelationalDatabase                   Info     Instantiate a RalDatabase for 'oracle://cooldb2;schema=AVALASSI;user=avalassi;password=andrea;dbname=COOLTEST'
+POOL/RelationalPlugins/oracle        Info     Connected to a server running Oracle version 9.2.0.6.0
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT TABLE_NAME FROM ALL_TABLES WHERE OWNER = 'AVALASSI'"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT "DB_ATTRIBUTE_NAME", "DB_ATTRIBUTE_VALUE" FROM "AVALASSI"."COOLTEST_DB_ATTRIBUTES""
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_ISLEAF", "NODE_INSTIME", "FOLDER_PAYLOADSPEC", "FOLDER_VERSIONING", "FOLDER_IOVTABLENAME" FROM "AVALASSI"."COOLTEST_FOLDERS" WHERE "NODE_FULLPATH"=:"fullName""
+RelationalFolder                     Debug    Instantiate a RelationalFolder for '/myfolder'
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT "OBJECT_ID", "CHANNEL_ID", "IOV_SINCE", "IOV_UNTIL", "SYS_INSTIME", "I", "S", "X0", "X1", "X2", "X3", "X4", "X5", "X6", "X7", "X8", "X9", "P" FROM "AVALASSI"."COOLTEST_F0001_IOVS" WHERE "CHANNEL_ID"=:"channel" AND "IOV_SINCE">=:"since" AND "IOV_UNTIL"<=:"till" ORDER BY "CHANNEL_ID" ASC,"IOV_SINCE" ASC"
+>>>>>>    Timing Results  <<<<<<<<<< 
+----- 1.PrepareQuery----------- :                              ( n=1 )
+Total Real Time  :      0.000 +/-      0.000 s
+Total User Time  :      0.010 +/-      0.010 s
+Total System Time:      0.000 +/-      0.000 s
+Total Idle Time  :     -0.010 +/-     -0.010 s
+----- 2.ProcessQuery----------- :                              ( n=1 )
+Total Real Time  :      0.010 +/-      0.010 s
+Total User Time  :      0.000 +/-      0.000 s
+Total System Time:      0.000 +/-      0.000 s
+Total Idle Time  :      0.010 +/-      0.010 s
+----- 3.FetchRows-------------- :                              ( n=10001 )
+Total Real Time  :      3.930 +/-      0.039 s
+Total User Time  :      0.790 +/-      0.008 s
+Total System Time:      0.110 +/-      0.001 s
+Total Idle Time  :      3.020 +/-      0.030 s
+----- 4.CopyAttributeList------ :                              ( n=10000 )
+Total Real Time  :      5.800 +/-      0.058 s
+Total User Time  :      5.840 +/-      0.058 s
+Total System Time:      0.100 +/-      0.001 s
+Total Idle Time  :     -0.150 +/-     -0.002 s
+----- 5.CloseQuery------------- :                              ( n=1 )
+Total Real Time  :      0.000 +/-      0.000 s
+Total User Time  :      0.000 +/-      0.000 s
+Total System Time:      0.000 +/-      0.000 s
+Total Idle Time  :      0.000 +/-      0.000 s
+----- TOTAL FetchObjRowsByVal-- :                              ( n=1 )
+Total Real Time  :      9.910 +/-      9.910 s
+Total User Time  :      6.730 +/-      6.730 s
+Total System Time:      0.210 +/-      0.210 s
+Total Idle Time  :      2.970 +/-      2.970 s
+>>>>>>    Timing Results  <<<<<<<<<< 
+----- 1.FetchObjRowsByVal----- :                              ( n=1 )
+Total Real Time  :      9.910 +/-      9.910 s
+Total User Time  :      6.740 +/-      6.740 s
+Total System Time:      0.210 +/-      0.210 s
+Total Idle Time  :      2.960 +/-      2.960 s
+----- 2.DecodeRow------------- :                              ( n=1 )
+Total Real Time  :      0.990 +/-      0.990 s
+Total User Time  :      0.980 +/-      0.980 s
+Total System Time:      0.000 +/-      0.000 s
+Total Idle Time  :      0.010 +/-      0.010 s
+----- 3.DeleteOld------------- :                              ( n=1 )
+Total Real Time  :      0.170 +/-      0.170 s
+Total User Time  :      0.160 +/-      0.160 s
+Total System Time:      0.000 +/-      0.000 s
+Total Idle Time  :      0.010 +/-      0.010 s
+----- TOTAL BrowseObjInTag---- :                              ( n=1 )
+Total Real Time  :     11.070 +/-     11.070 s
+Total User Time  :      7.880 +/-      7.880 s
+Total System Time:      0.210 +/-      0.210 s
+Total Idle Time  :      2.980 +/-      2.980 s
+** reading 100000 objects (150 bytes mixed) **
+read back 10000 objects
+sec total: 11.0703
+obj/s:     903.317
+RelationalFolder                     Debug    Delete the RelationalFolder for '/myfolder'
+sec total (INCLUDING DELETE): 11.2085
+
+OK (1)
+[OVAL] Cppunit-result =0
+RelationalDatabase                   Info     Delete the RalDatabase for 'oracle://cooldb2;schema=AVALASSI;user=avalassi;password=andrea;dbname=COOLTEST'
+POOL/RelationalPlugins/oracle        Warning  No active transaction to roll back
+RelationalDatabase                   Debug    Delete the RelationalDatabase for 'oracle://cooldb2;schema=AVALASSI;user=avalassi;password=andrea;dbname=COOLTEST'
diff --git a/RelationalCool/tests/PerformanceAV/TestNewCopy/oldCopy-time.rh73.501MB.out b/RelationalCool/tests/PerformanceAV/TestNewCopy/oldCopy-time.rh73.501MB.out
new file mode 100644
index 000000000..4a073d9dc
--- /dev/null
+++ b/RelationalCool/tests/PerformanceAV/TestNewCopy/oldCopy-time.rh73.501MB.out
@@ -0,0 +1,82 @@
+Property Catalogue: level[Info] Adding property: OutputLevel = 2 in scope "SEAL/Services/MessageService"
+Property Catalogue: level[Info] Adding property: Format =  "%-36s %-8s %s" in scope "SEAL/Services/MessageService"
+MessageService callback    Debug MessageService output level changed to Debug
+ConfigurationService    Debug Setting property: "Format" to value " "%-36s %-8s %s"" in scope "SEAL/Services/MessageService"
+POOL/Services/RelationalService      Info     Found plugin for RDBMS technology "mysql" with implementation "odbc"
+POOL/Services/RelationalService      Info     Found plugin for RDBMS technology "oracle" with native implementation
+POOL/Services/RelationalService      Info     Found plugin for RDBMS technology "sqlite" with native implementation
+POOL/Services/RelationalService      Info     Default implementation for RDBMS technology "mysql" is "odbc"
+POOL/Services/RelationalService      Info     Default implementation for RDBMS technology "oracle" is native
+POOL/Services/RelationalService      Info     Default implementation for RDBMS technology "sqlite" is native
+RelationalDatabase                   Debug    Instantiate a RelationalDatabase for 'oracle://cooldb2;schema=AVALASSI;user=avalassi;password=andrea;dbname=COOLTEST'
+RelationalDatabase                   Info     Instantiate a RalDatabase for 'oracle://cooldb2;schema=AVALASSI;user=avalassi;password=andrea;dbname=COOLTEST'
+POOL/RelationalPlugins/oracle        Info     Connected to a server running Oracle version 9.2.0.6.0
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT TABLE_NAME FROM ALL_TABLES WHERE OWNER = 'AVALASSI'"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT "DB_ATTRIBUTE_NAME", "DB_ATTRIBUTE_VALUE" FROM "AVALASSI"."COOLTEST_DB_ATTRIBUTES""
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_ISLEAF", "NODE_INSTIME", "FOLDER_PAYLOADSPEC", "FOLDER_VERSIONING", "FOLDER_IOVTABLENAME" FROM "AVALASSI"."COOLTEST_FOLDERS" WHERE "NODE_FULLPATH"=:"fullName""
+RelationalFolder                     Debug    Instantiate a RelationalFolder for '/myfolder'
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT "OBJECT_ID", "CHANNEL_ID", "IOV_SINCE", "IOV_UNTIL", "SYS_INSTIME", "I", "S", "X0", "X1", "X2", "X3", "X4", "X5", "X6", "X7", "X8", "X9", "P" FROM "AVALASSI"."COOLTEST_F0001_IOVS" WHERE "CHANNEL_ID"=:"channel" AND "IOV_SINCE">=:"since" AND "IOV_UNTIL"<=:"till" ORDER BY "CHANNEL_ID" ASC,"IOV_SINCE" ASC"
+>>>>>>    Timing Results  <<<<<<<<<< 
+----- 1.PrepareQuery----------- :                              ( n=1 )
+Total Real Time  :      0.000 +/-      0.000 s
+Total User Time  :      0.000 +/-      0.000 s
+Total System Time:      0.000 +/-      0.000 s
+Total Idle Time  :      0.000 +/-      0.000 s
+----- 2.ProcessQuery----------- :                              ( n=1 )
+Total Real Time  :      0.010 +/-      0.010 s
+Total User Time  :      0.000 +/-      0.000 s
+Total System Time:      0.000 +/-      0.000 s
+Total Idle Time  :      0.010 +/-      0.010 s
+----- 3.FetchRows-------------- :                              ( n=10001 )
+Total Real Time  :      3.880 +/-      0.039 s
+Total User Time  :      0.610 +/-      0.006 s
+Total System Time:      0.010 +/-      0.000 s
+Total Idle Time  :      3.310 +/-      0.033 s
+----- 4.CopyAttributeList------ :                              ( n=10000 )
+Total Real Time  :      5.550 +/-      0.056 s
+Total User Time  :      5.570 +/-      0.056 s
+Total System Time:      0.100 +/-      0.001 s
+Total Idle Time  :     -0.070 +/-     -0.001 s
+----- 5.CloseQuery------------- :                              ( n=1 )
+Total Real Time  :      0.000 +/-      0.000 s
+Total User Time  :      0.000 +/-      0.000 s
+Total System Time:      0.000 +/-      0.000 s
+Total Idle Time  :      0.000 +/-      0.000 s
+----- TOTAL FetchObjRowsByVal-- :                              ( n=1 )
+Total Real Time  :      9.620 +/-      9.620 s
+Total User Time  :      6.280 +/-      6.280 s
+Total System Time:      0.120 +/-      0.120 s
+Total Idle Time  :      3.220 +/-      3.220 s
+>>>>>>    Timing Results  <<<<<<<<<< 
+----- 1.FetchObjRowsByVal----- :                              ( n=1 )
+Total Real Time  :      9.630 +/-      9.630 s
+Total User Time  :      6.280 +/-      6.280 s
+Total System Time:      0.120 +/-      0.120 s
+Total Idle Time  :      3.230 +/-      3.230 s
+----- 2.DecodeRow------------- :                              ( n=1 )
+Total Real Time  :      0.980 +/-      0.980 s
+Total User Time  :      0.970 +/-      0.970 s
+Total System Time:      0.000 +/-      0.000 s
+Total Idle Time  :      0.010 +/-      0.010 s
+----- 3.DeleteOld------------- :                              ( n=1 )
+Total Real Time  :      0.160 +/-      0.160 s
+Total User Time  :      0.160 +/-      0.160 s
+Total System Time:      0.000 +/-      0.000 s
+Total Idle Time  :      0.000 +/-      0.000 s
+----- TOTAL BrowseObjInTag---- :                              ( n=1 )
+Total Real Time  :     10.770 +/-     10.770 s
+Total User Time  :      7.410 +/-      7.410 s
+Total System Time:      0.120 +/-      0.120 s
+Total Idle Time  :      3.240 +/-      3.240 s
+** reading 100000 objects (150 bytes mixed) **
+read back 10000 objects
+sec total: 10.7714
+obj/s:     928.382
+RelationalFolder                     Debug    Delete the RelationalFolder for '/myfolder'
+sec total (INCLUDING DELETE): 10.9092
+
+OK (1)
+[OVAL] Cppunit-result =0
+RelationalDatabase                   Info     Delete the RalDatabase for 'oracle://cooldb2;schema=AVALASSI;user=avalassi;password=andrea;dbname=COOLTEST'
+POOL/RelationalPlugins/oracle        Warning  No active transaction to roll back
+RelationalDatabase                   Debug    Delete the RelationalDatabase for 'oracle://cooldb2;schema=AVALASSI;user=avalassi;password=andrea;dbname=COOLTEST'
diff --git a/RelationalCool/tests/PerformanceAV/TestNewCopy/oldCopy-time.slc3.2006MB.out b/RelationalCool/tests/PerformanceAV/TestNewCopy/oldCopy-time.slc3.2006MB.out
new file mode 100644
index 000000000..6f3b75576
--- /dev/null
+++ b/RelationalCool/tests/PerformanceAV/TestNewCopy/oldCopy-time.slc3.2006MB.out
@@ -0,0 +1,82 @@
+Property Catalogue: level[Info] Adding property: OutputLevel = 2 in scope "SEAL/Services/MessageService"
+Property Catalogue: level[Info] Adding property: Format =  "%-36s %-8s %s" in scope "SEAL/Services/MessageService"
+MessageService callback    Debug MessageService output level changed to Debug
+ConfigurationService    Debug Setting property: "Format" to value " "%-36s %-8s %s"" in scope "SEAL/Services/MessageService"
+POOL/Services/RelationalService      Info     Found plugin for RDBMS technology "mysql" with implementation "odbc"
+POOL/Services/RelationalService      Info     Found plugin for RDBMS technology "oracle" with native implementation
+POOL/Services/RelationalService      Info     Found plugin for RDBMS technology "sqlite" with native implementation
+POOL/Services/RelationalService      Info     Default implementation for RDBMS technology "mysql" is "odbc"
+POOL/Services/RelationalService      Info     Default implementation for RDBMS technology "oracle" is native
+POOL/Services/RelationalService      Info     Default implementation for RDBMS technology "sqlite" is native
+RelationalDatabase                   Debug    Instantiate a RelationalDatabase for 'oracle://cooldb2;schema=AVALASSI;user=avalassi;password=andrea;dbname=COOLTEST'
+RelationalDatabase                   Info     Instantiate a RalDatabase for 'oracle://cooldb2;schema=AVALASSI;user=avalassi;password=andrea;dbname=COOLTEST'
+POOL/RelationalPlugins/oracle        Info     Connected to a server running Oracle version 9.2.0.6.0
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT TABLE_NAME FROM ALL_TABLES WHERE OWNER = 'AVALASSI'"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT "DB_ATTRIBUTE_NAME", "DB_ATTRIBUTE_VALUE" FROM "AVALASSI"."COOLTEST_DB_ATTRIBUTES""
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_ISLEAF", "NODE_INSTIME", "FOLDER_PAYLOADSPEC", "FOLDER_VERSIONING", "FOLDER_IOVTABLENAME" FROM "AVALASSI"."COOLTEST_FOLDERS" WHERE "NODE_FULLPATH"=:"fullName""
+RelationalFolder                     Debug    Instantiate a RelationalFolder for '/myfolder'
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT "OBJECT_ID", "CHANNEL_ID", "IOV_SINCE", "IOV_UNTIL", "SYS_INSTIME", "I", "S", "X0", "X1", "X2", "X3", "X4", "X5", "X6", "X7", "X8", "X9", "P" FROM "AVALASSI"."COOLTEST_F0001_IOVS" WHERE "CHANNEL_ID"=:"channel" AND "IOV_SINCE">=:"since" AND "IOV_UNTIL"<=:"till" ORDER BY "CHANNEL_ID" ASC,"IOV_SINCE" ASC"
+>>>>>>    Timing Results  <<<<<<<<<< 
+----- 1.PrepareQuery----------- :                              ( n=1 )
+Total Real Time  :      0.010 +/-      0.010 s
+Total User Time  :      0.000 +/-      0.000 s
+Total System Time:      0.000 +/-      0.000 s
+Total Idle Time  :      0.010 +/-      0.010 s
+----- 2.ProcessQuery----------- :                              ( n=1 )
+Total Real Time  :      0.010 +/-      0.010 s
+Total User Time  :      0.000 +/-      0.000 s
+Total System Time:      0.010 +/-      0.010 s
+Total Idle Time  :      0.000 +/-      0.000 s
+----- 3.FetchRows-------------- :                              ( n=10001 )
+Total Real Time  :      7.560 +/-      0.076 s
+Total User Time  :      0.490 +/-      0.005 s
+Total System Time:      0.040 +/-      0.000 s
+Total Idle Time  :      7.060 +/-      0.071 s
+----- 4.CopyAttributeList------ :                              ( n=10000 )
+Total Real Time  :      7.070 +/-      0.071 s
+Total User Time  :      4.870 +/-      0.049 s
+Total System Time:      0.120 +/-      0.001 s
+Total Idle Time  :      2.080 +/-      0.021 s
+----- 5.CloseQuery------------- :                              ( n=1 )
+Total Real Time  :      0.000 +/-      0.000 s
+Total User Time  :      0.000 +/-      0.000 s
+Total System Time:      0.000 +/-      0.000 s
+Total Idle Time  :      0.000 +/-      0.000 s
+----- TOTAL FetchObjRowsByVal-- :                              ( n=1 )
+Total Real Time  :     15.210 +/-     15.210 s
+Total User Time  :      5.520 +/-      5.520 s
+Total System Time:      0.180 +/-      0.180 s
+Total Idle Time  :      9.510 +/-      9.510 s
+>>>>>>    Timing Results  <<<<<<<<<< 
+----- 1.FetchObjRowsByVal----- :                              ( n=1 )
+Total Real Time  :     15.210 +/-     15.210 s
+Total User Time  :      5.520 +/-      5.520 s
+Total System Time:      0.180 +/-      0.180 s
+Total Idle Time  :      9.510 +/-      9.510 s
+----- 2.DecodeRow------------- :                              ( n=1 )
+Total Real Time  :      2.020 +/-      2.020 s
+Total User Time  :      1.500 +/-      1.500 s
+Total System Time:      0.020 +/-      0.020 s
+Total Idle Time  :      0.500 +/-      0.500 s
+----- 3.DeleteOld------------- :                              ( n=1 )
+Total Real Time  :      0.140 +/-      0.140 s
+Total User Time  :      0.140 +/-      0.140 s
+Total System Time:      0.000 +/-      0.000 s
+Total Idle Time  :      0.000 +/-      0.000 s
+----- TOTAL BrowseObjInTag---- :                              ( n=1 )
+Total Real Time  :     17.370 +/-     17.370 s
+Total User Time  :      7.160 +/-      7.160 s
+Total System Time:      0.200 +/-      0.200 s
+Total Idle Time  :     10.010 +/-     10.010 s
+** reading 100000 objects (150 bytes mixed) **
+read back 10000 objects
+sec total: 17.3679
+obj/s:     575.775
+RelationalFolder                     Debug    Delete the RelationalFolder for '/myfolder'
+sec total (INCLUDING DELETE): 17.5473
+
+OK (1)
+[OVAL] Cppunit-result =0
+RelationalDatabase                   Info     Delete the RalDatabase for 'oracle://cooldb2;schema=AVALASSI;user=avalassi;password=andrea;dbname=COOLTEST'
+POOL/RelationalPlugins/oracle        Warning  No active transaction to roll back
+RelationalDatabase                   Debug    Delete the RelationalDatabase for 'oracle://cooldb2;schema=AVALASSI;user=avalassi;password=andrea;dbname=COOLTEST'
diff --git a/RelationalCool/tests/PerformanceAV/TestRalOnly/execTestRalOnly.rh73.501MB.oracle.out b/RelationalCool/tests/PerformanceAV/TestRalOnly/execTestRalOnly.rh73.501MB.oracle.out
new file mode 100644
index 000000000..ab54f9e04
--- /dev/null
+++ b/RelationalCool/tests/PerformanceAV/TestRalOnly/execTestRalOnly.rh73.501MB.oracle.out
@@ -0,0 +1,4 @@
+7.810u 0.230s 0:13.16 61.0%     0+0k 0+0io 2277pf+0w
+0.670u 0.060s 0:05.44 13.4%     0+0k 0+0io 2271pf+0w
+25.140u 7.490s 0:37.00 88.1%    0+0k 0+0io 2277pf+0w
+0.620u 0.050s 0:05.50 12.1%     0+0k 0+0io 2271pf+0w
diff --git a/RelationalCool/tests/PerformanceAV/TestRalOnly/execTestRalOnly.rh73.501MB.oracle.out.ANALYZED b/RelationalCool/tests/PerformanceAV/TestRalOnly/execTestRalOnly.rh73.501MB.oracle.out.ANALYZED
new file mode 100644
index 000000000..8e9207e94
--- /dev/null
+++ b/RelationalCool/tests/PerformanceAV/TestRalOnly/execTestRalOnly.rh73.501MB.oracle.out.ANALYZED
@@ -0,0 +1,3 @@
+7.690u 0.330s 0:12.86 62.3%     0+0k 0+0io 2277pf+0w
+0.630u 0.120s 0:05.27 14.2%     0+0k 0+0io 2271pf+0w
+
diff --git a/RelationalCool/tests/PerformanceAV/TestRalOnly/ralOnly-memory.rh73.501MB.oracle.out b/RelationalCool/tests/PerformanceAV/TestRalOnly/ralOnly-memory.rh73.501MB.oracle.out
new file mode 100644
index 000000000..85f63b64e
--- /dev/null
+++ b/RelationalCool/tests/PerformanceAV/TestRalOnly/ralOnly-memory.rh73.501MB.oracle.out
@@ -0,0 +1,103 @@
+Property Catalogue: level[Info] Adding property: OutputLevel = 2 in scope "SEAL/Services/MessageService"
+Property Catalogue: level[Info] Adding property: Format =  "%-36s %-8s %s" in scope "SEAL/Services/MessageService"
+MessageService callback    Debug MessageService output level changed to Debug
+ConfigurationService    Debug Setting property: "Format" to value " "%-36s %-8s %s"" in scope "SEAL/Services/MessageService"
+POOL/Services/RelationalService      Info     Found plugin for RDBMS technology "mysql" with implementation "odbc"
+POOL/Services/RelationalService      Info     Found plugin for RDBMS technology "oracle" with native implementation
+POOL/Services/RelationalService      Info     Default implementation for RDBMS technology "mysql" is "odbc"
+POOL/Services/RelationalService      Info     Default implementation for RDBMS technology "oracle" is native
+RelationalDatabase                   Debug    Instantiate a RelationalDatabase for 'oracle://cooldb2;schema=AVALASSI;user=avalassi;password=andrea;dbname=COOLTEST'
+RelationalDatabase                   Info     Instantiate a RalDatabase for 'oracle://cooldb2;schema=AVALASSI;user=avalassi;password=andrea;dbname=COOLTEST'
+POOL/RelationalPlugins/oracle        Info     Connected to a server running Oracle version 9.2.0.6.0
+POOL/RelationalPlugins/oracle        Warning  Environment variable RAL_SQLTRACE is set: enable SQL_TRACE
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "alter session set events '10046 trace name context forever, level 12'"
+POOL/RelationalPlugins/oracle        Warning  SQL_TRACE enabled
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT TABLE_NAME FROM ALL_TABLES WHERE OWNER = 'AVALASSI'"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT "DB_ATTRIBUTE_NAME", "DB_ATTRIBUTE_VALUE" FROM "AVALASSI"."COOLTEST_DB_ATTRIBUTES""
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_ISLEAF", "NODE_INSTIME", "FOLDER_PAYLOADSPEC", "FOLDER_VERSIONING", "FOLDER_IOVTABLENAME" FROM "AVALASSI"."COOLTEST_FOLDERS" WHERE "NODE_FULLPATH"=:"fullName""
+RelationalFolder                     Debug    Instantiate a RelationalFolder for '/myfolder'
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT "OBJECT_ID", "CHANNEL_ID", "IOV_SINCE", "IOV_UNTIL", "SYS_INSTIME", "I", "S", "X0", "X1", "X2", "X3", "X4", "X5", "X6", "X7", "X8", "X9", "P" FROM "AVALASSI"."COOLTEST_F0001_IOVS" WHERE "CHANNEL_ID"=:"channel" AND "IOV_SINCE">=:"since" AND "IOV_UNTIL"<=:"till" ORDER BY "CHANNEL_ID" ASC,"IOV_SINCE" ASC"
+>>>>>>    Timing Results  <<<<<<<<<< 
+----- 1.PrepareQuery----------- :                              ( n=1 )
+Total Real Time  :      0.010 +/-      0.010 s
+Total User Time  :      0.000 +/-      0.000 s
+Total System Time:      0.000 +/-      0.000 s
+Total Idle Time  :      0.010 +/-      0.010 s
+Total VmSize incr:      0.000 +/-      0.000 MB
+Total VmRSS incr :      0.012 +/-      0.012 MB
+----- 2.ProcessQuery----------- :                              ( n=1 )
+Total Real Time  :      0.250 +/-      0.250 s
+Total User Time  :      0.000 +/-      0.000 s
+Total System Time:      0.000 +/-      0.000 s
+Total Idle Time  :      0.250 +/-      0.250 s
+Total VmSize incr:      0.412 +/-      0.412 MB
+Total VmRSS incr :      0.404 +/-      0.404 MB
+----- 3.FetchRows-------------- :                              ( n=1 )
+Total Real Time  :      3.730 +/-      3.730 s
+Total User Time  :      0.430 +/-      0.430 s
+Total System Time:      0.020 +/-      0.020 s
+Total Idle Time  :      3.280 +/-      3.280 s
+Total VmSize incr:      0.012 +/-      0.012 MB
+Total VmRSS incr :      0.028 +/-      0.028 MB
+----- 4.CopyAttributeList------ :                              ( n=0 )
+Total Real Time  :      0.000 +/-      0.000 s
+Total User Time  :      0.000 +/-      0.000 s
+Total System Time:      0.000 +/-      0.000 s
+Total Idle Time  :      0.000 +/-      0.000 s
+Total VmSize incr:      0.000 +/-      0.000 MB
+Total VmRSS incr :      0.000 +/-      0.000 MB
+----- 5.CloseQuery------------- :                              ( n=1 )
+Total Real Time  :      0.000 +/-      0.000 s
+Total User Time  :      0.000 +/-      0.000 s
+Total System Time:      0.000 +/-      0.000 s
+Total Idle Time  :      0.000 +/-      0.000 s
+Total VmSize incr:      0.000 +/-      0.000 MB
+Total VmRSS incr :      0.000 +/-      0.000 MB
+----- TOTAL FetchObjRowsByVal-- :                              ( n=1 )
+Total Real Time  :      3.990 +/-      3.990 s
+Total User Time  :      0.430 +/-      0.430 s
+Total System Time:      0.020 +/-      0.020 s
+Total Idle Time  :      3.540 +/-      3.540 s
+Total VmSize incr:      0.424 +/-      0.424 MB
+Total VmRSS incr :      0.444 +/-      0.444 MB
+>>>>>>    Timing Results  <<<<<<<<<< 
+----- 1.FetchObjRowsByVal----- :                              ( n=1 )
+Total Real Time  :      4.000 +/-      4.000 s
+Total User Time  :      0.440 +/-      0.440 s
+Total System Time:      0.020 +/-      0.020 s
+Total Idle Time  :      3.540 +/-      3.540 s
+Total VmSize incr:      0.436 +/-      0.436 MB
+Total VmRSS incr :      0.468 +/-      0.468 MB
+----- 2.DecodeRow------------- :                              ( n=1 )
+Total Real Time  :      0.010 +/-      0.010 s
+Total User Time  :      0.000 +/-      0.000 s
+Total System Time:      0.000 +/-      0.000 s
+Total Idle Time  :      0.010 +/-      0.010 s
+Total VmSize incr:      0.000 +/-      0.000 MB
+Total VmRSS incr :      0.000 +/-      0.000 MB
+----- 3.DeleteOld------------- :                              ( n=1 )
+Total Real Time  :      0.000 +/-      0.000 s
+Total User Time  :      0.000 +/-      0.000 s
+Total System Time:      0.000 +/-      0.000 s
+Total Idle Time  :      0.000 +/-      0.000 s
+Total VmSize incr:      0.000 +/-      0.000 MB
+Total VmRSS incr :      0.000 +/-      0.000 MB
+----- TOTAL BrowseObjInTag---- :                              ( n=1 )
+Total Real Time  :      4.010 +/-      4.010 s
+Total User Time  :      0.440 +/-      0.440 s
+Total System Time:      0.020 +/-      0.020 s
+Total Idle Time  :      3.550 +/-      3.550 s
+Total VmSize incr:      0.436 +/-      0.436 MB
+Total VmRSS incr :      0.468 +/-      0.468 MB
+** reading 100000 objects (150 bytes mixed) **
+read back 0 objects
+sec total: 4.01592
+obj/s:     0
+RelationalFolder                     Debug    Delete the RelationalFolder for '/myfolder'
+sec total (INCLUDING DELETE): 4.03061
+
+OK (1)
+[OVAL] Cppunit-result =0
+RelationalDatabase                   Info     Delete the RalDatabase for 'oracle://cooldb2;schema=AVALASSI;user=avalassi;password=andrea;dbname=COOLTEST'
+POOL/RelationalPlugins/oracle        Warning  No active transaction to roll back
+RelationalDatabase                   Debug    Delete the RelationalDatabase for 'oracle://cooldb2;schema=AVALASSI;user=avalassi;password=andrea;dbname=COOLTEST'
diff --git a/RelationalCool/tests/PerformanceAV/TestRalOnly/ralOnly-time.rh73.501MB.oracle.out b/RelationalCool/tests/PerformanceAV/TestRalOnly/ralOnly-time.rh73.501MB.oracle.out
new file mode 100644
index 000000000..b74733f8a
--- /dev/null
+++ b/RelationalCool/tests/PerformanceAV/TestRalOnly/ralOnly-time.rh73.501MB.oracle.out
@@ -0,0 +1,83 @@
+Property Catalogue: level[Info] Adding property: OutputLevel = 2 in scope "SEAL/Services/MessageService"
+Property Catalogue: level[Info] Adding property: Format =  "%-36s %-8s %s" in scope "SEAL/Services/MessageService"
+MessageService callback    Debug MessageService output level changed to Debug
+ConfigurationService    Debug Setting property: "Format" to value " "%-36s %-8s %s"" in scope "SEAL/Services/MessageService"
+POOL/Services/RelationalService      Info     Found plugin for RDBMS technology "mysql" with implementation "odbc"
+POOL/Services/RelationalService      Info     Found plugin for RDBMS technology "oracle" with native implementation
+POOL/Services/RelationalService      Info     Default implementation for RDBMS technology "mysql" is "odbc"
+POOL/Services/RelationalService      Info     Default implementation for RDBMS technology "oracle" is native
+RelationalDatabase                   Debug    Instantiate a RelationalDatabase for 'oracle://cooldb2;schema=AVALASSI;user=avalassi;password=andrea;dbname=COOLTEST'
+RelationalDatabase                   Info     Instantiate a RalDatabase for 'oracle://cooldb2;schema=AVALASSI;user=avalassi;password=andrea;dbname=COOLTEST'
+POOL/RelationalPlugins/oracle        Info     Connected to a server running Oracle version 9.2.0.6.0
+POOL/RelationalPlugins/oracle        Warning  Environment variable RAL_SQLTRACE is set: enable SQL_TRACE
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "alter session set events '10046 trace name context forever, level 12'"
+POOL/RelationalPlugins/oracle        Warning  SQL_TRACE enabled
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT TABLE_NAME FROM ALL_TABLES WHERE OWNER = 'AVALASSI'"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT "DB_ATTRIBUTE_NAME", "DB_ATTRIBUTE_VALUE" FROM "AVALASSI"."COOLTEST_DB_ATTRIBUTES""
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_ISLEAF", "NODE_INSTIME", "FOLDER_PAYLOADSPEC", "FOLDER_VERSIONING", "FOLDER_IOVTABLENAME" FROM "AVALASSI"."COOLTEST_FOLDERS" WHERE "NODE_FULLPATH"=:"fullName""
+RelationalFolder                     Debug    Instantiate a RelationalFolder for '/myfolder'
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT "OBJECT_ID", "CHANNEL_ID", "IOV_SINCE", "IOV_UNTIL", "SYS_INSTIME", "I", "S", "X0", "X1", "X2", "X3", "X4", "X5", "X6", "X7", "X8", "X9", "P" FROM "AVALASSI"."COOLTEST_F0001_IOVS" WHERE "CHANNEL_ID"=:"channel" AND "IOV_SINCE">=:"since" AND "IOV_UNTIL"<=:"till" ORDER BY "CHANNEL_ID" ASC,"IOV_SINCE" ASC"
+>>>>>>    Timing Results  <<<<<<<<<< 
+----- 1.PrepareQuery----------- :                              ( n=1 )
+Total Real Time  :      0.010 +/-      0.010 s
+Total User Time  :      0.000 +/-      0.000 s
+Total System Time:      0.000 +/-      0.000 s
+Total Idle Time  :      0.010 +/-      0.010 s
+----- 2.ProcessQuery----------- :                              ( n=1 )
+Total Real Time  :      0.240 +/-      0.240 s
+Total User Time  :      0.000 +/-      0.000 s
+Total System Time:      0.000 +/-      0.000 s
+Total Idle Time  :      0.240 +/-      0.240 s
+----- 3.FetchRows-------------- :                              ( n=1 )
+Total Real Time  :      3.850 +/-      3.850 s
+Total User Time  :      0.490 +/-      0.490 s
+Total System Time:      0.030 +/-      0.030 s
+Total Idle Time  :      3.330 +/-      3.330 s
+----- 4.CopyAttributeList------ :                              ( n=0 )
+Total Real Time  :      0.000 +/-      0.000 s
+Total User Time  :      0.000 +/-      0.000 s
+Total System Time:      0.000 +/-      0.000 s
+Total Idle Time  :      0.000 +/-      0.000 s
+----- 5.CloseQuery------------- :                              ( n=1 )
+Total Real Time  :      0.000 +/-      0.000 s
+Total User Time  :      0.000 +/-      0.000 s
+Total System Time:      0.000 +/-      0.000 s
+Total Idle Time  :      0.000 +/-      0.000 s
+----- TOTAL FetchObjRowsByVal-- :                              ( n=1 )
+Total Real Time  :      4.100 +/-      4.100 s
+Total User Time  :      0.490 +/-      0.490 s
+Total System Time:      0.030 +/-      0.030 s
+Total Idle Time  :      3.580 +/-      3.580 s
+>>>>>>    Timing Results  <<<<<<<<<< 
+----- 1.FetchObjRowsByVal----- :                              ( n=1 )
+Total Real Time  :      4.110 +/-      4.110 s
+Total User Time  :      0.490 +/-      0.490 s
+Total System Time:      0.030 +/-      0.030 s
+Total Idle Time  :      3.590 +/-      3.590 s
+----- 2.DecodeRow------------- :                              ( n=1 )
+Total Real Time  :      0.010 +/-      0.010 s
+Total User Time  :      0.000 +/-      0.000 s
+Total System Time:      0.000 +/-      0.000 s
+Total Idle Time  :      0.010 +/-      0.010 s
+----- 3.DeleteOld------------- :                              ( n=1 )
+Total Real Time  :      0.000 +/-      0.000 s
+Total User Time  :      0.000 +/-      0.000 s
+Total System Time:      0.000 +/-      0.000 s
+Total Idle Time  :      0.000 +/-      0.000 s
+----- TOTAL BrowseObjInTag---- :                              ( n=1 )
+Total Real Time  :      4.120 +/-      4.120 s
+Total User Time  :      0.490 +/-      0.490 s
+Total System Time:      0.030 +/-      0.030 s
+Total Idle Time  :      3.600 +/-      3.600 s
+** reading 100000 objects (150 bytes mixed) **
+read back 0 objects
+sec total: 4.1212
+obj/s:     0
+RelationalFolder                     Debug    Delete the RelationalFolder for '/myfolder'
+sec total (INCLUDING DELETE): 4.13695
+
+OK (1)
+[OVAL] Cppunit-result =0
+RelationalDatabase                   Info     Delete the RalDatabase for 'oracle://cooldb2;schema=AVALASSI;user=avalassi;password=andrea;dbname=COOLTEST'
+POOL/RelationalPlugins/oracle        Warning  No active transaction to roll back
+RelationalDatabase                   Debug    Delete the RelationalDatabase for 'oracle://cooldb2;schema=AVALASSI;user=avalassi;password=andrea;dbname=COOLTEST'
diff --git a/RelationalCool/tests/PerformanceAV/TestRalOnly/ralOnly-time.rh73.501MB.oracle.out.ANALYZED b/RelationalCool/tests/PerformanceAV/TestRalOnly/ralOnly-time.rh73.501MB.oracle.out.ANALYZED
new file mode 100644
index 000000000..b76b5bbc8
--- /dev/null
+++ b/RelationalCool/tests/PerformanceAV/TestRalOnly/ralOnly-time.rh73.501MB.oracle.out.ANALYZED
@@ -0,0 +1,83 @@
+Property Catalogue: level[Info] Adding property: OutputLevel = 2 in scope "SEAL/Services/MessageService"
+Property Catalogue: level[Info] Adding property: Format =  "%-36s %-8s %s" in scope "SEAL/Services/MessageService"
+MessageService callback    Debug MessageService output level changed to Debug
+ConfigurationService    Debug Setting property: "Format" to value " "%-36s %-8s %s"" in scope "SEAL/Services/MessageService"
+POOL/Services/RelationalService      Info     Found plugin for RDBMS technology "mysql" with implementation "odbc"
+POOL/Services/RelationalService      Info     Found plugin for RDBMS technology "oracle" with native implementation
+POOL/Services/RelationalService      Info     Default implementation for RDBMS technology "mysql" is "odbc"
+POOL/Services/RelationalService      Info     Default implementation for RDBMS technology "oracle" is native
+RelationalDatabase                   Debug    Instantiate a RelationalDatabase for 'oracle://cooldb2;schema=AVALASSI;user=avalassi;password=andrea;dbname=COOLTEST'
+RelationalDatabase                   Info     Instantiate a RalDatabase for 'oracle://cooldb2;schema=AVALASSI;user=avalassi;password=andrea;dbname=COOLTEST'
+POOL/RelationalPlugins/oracle        Info     Connected to a server running Oracle version 9.2.0.6.0
+POOL/RelationalPlugins/oracle        Warning  Environment variable RAL_SQLTRACE is set: enable SQL_TRACE
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "alter session set events '10046 trace name context forever, level 12'"
+POOL/RelationalPlugins/oracle        Warning  SQL_TRACE enabled
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT TABLE_NAME FROM ALL_TABLES WHERE OWNER = 'AVALASSI'"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT "DB_ATTRIBUTE_NAME", "DB_ATTRIBUTE_VALUE" FROM "AVALASSI"."COOLTEST_DB_ATTRIBUTES""
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_ISLEAF", "NODE_INSTIME", "FOLDER_PAYLOADSPEC", "FOLDER_VERSIONING", "FOLDER_IOVTABLENAME" FROM "AVALASSI"."COOLTEST_FOLDERS" WHERE "NODE_FULLPATH"=:"fullName""
+RelationalFolder                     Debug    Instantiate a RelationalFolder for '/myfolder'
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT "OBJECT_ID", "CHANNEL_ID", "IOV_SINCE", "IOV_UNTIL", "SYS_INSTIME", "I", "S", "X0", "X1", "X2", "X3", "X4", "X5", "X6", "X7", "X8", "X9", "P" FROM "AVALASSI"."COOLTEST_F0001_IOVS" WHERE "CHANNEL_ID"=:"channel" AND "IOV_SINCE">=:"since" AND "IOV_UNTIL"<=:"till" ORDER BY "CHANNEL_ID" ASC,"IOV_SINCE" ASC"
+>>>>>>    Timing Results  <<<<<<<<<< 
+----- 1.PrepareQuery----------- :                              ( n=1 )
+Total Real Time  :      0.010 +/-      0.010 s
+Total User Time  :      0.000 +/-      0.000 s
+Total System Time:      0.000 +/-      0.000 s
+Total Idle Time  :      0.010 +/-      0.010 s
+----- 2.ProcessQuery----------- :                              ( n=1 )
+Total Real Time  :      0.010 +/-      0.010 s
+Total User Time  :      0.000 +/-      0.000 s
+Total System Time:      0.000 +/-      0.000 s
+Total Idle Time  :      0.010 +/-      0.010 s
+----- 3.FetchRows-------------- :                              ( n=1 )
+Total Real Time  :      3.790 +/-      3.790 s
+Total User Time  :      0.470 +/-      0.470 s
+Total System Time:      0.060 +/-      0.060 s
+Total Idle Time  :      3.260 +/-      3.260 s
+----- 4.CopyAttributeList------ :                              ( n=0 )
+Total Real Time  :      0.000 +/-      0.000 s
+Total User Time  :      0.000 +/-      0.000 s
+Total System Time:      0.000 +/-      0.000 s
+Total Idle Time  :      0.000 +/-      0.000 s
+----- 5.CloseQuery------------- :                              ( n=1 )
+Total Real Time  :      0.000 +/-      0.000 s
+Total User Time  :      0.000 +/-      0.000 s
+Total System Time:      0.000 +/-      0.000 s
+Total Idle Time  :      0.000 +/-      0.000 s
+----- TOTAL FetchObjRowsByVal-- :                              ( n=1 )
+Total Real Time  :      3.810 +/-      3.810 s
+Total User Time  :      0.470 +/-      0.470 s
+Total System Time:      0.060 +/-      0.060 s
+Total Idle Time  :      3.280 +/-      3.280 s
+>>>>>>    Timing Results  <<<<<<<<<< 
+----- 1.FetchObjRowsByVal----- :                              ( n=1 )
+Total Real Time  :      3.810 +/-      3.810 s
+Total User Time  :      0.470 +/-      0.470 s
+Total System Time:      0.060 +/-      0.060 s
+Total Idle Time  :      3.280 +/-      3.280 s
+----- 2.DecodeRow------------- :                              ( n=1 )
+Total Real Time  :      0.020 +/-      0.020 s
+Total User Time  :      0.000 +/-      0.000 s
+Total System Time:      0.000 +/-      0.000 s
+Total Idle Time  :      0.020 +/-      0.020 s
+----- 3.DeleteOld------------- :                              ( n=1 )
+Total Real Time  :      0.000 +/-      0.000 s
+Total User Time  :      0.000 +/-      0.000 s
+Total System Time:      0.000 +/-      0.000 s
+Total Idle Time  :      0.000 +/-      0.000 s
+----- TOTAL BrowseObjInTag---- :                              ( n=1 )
+Total Real Time  :      3.830 +/-      3.830 s
+Total User Time  :      0.470 +/-      0.470 s
+Total System Time:      0.060 +/-      0.060 s
+Total Idle Time  :      3.300 +/-      3.300 s
+** reading 100000 objects (150 bytes mixed) **
+read back 0 objects
+sec total: 3.8278
+obj/s:     0
+RelationalFolder                     Debug    Delete the RelationalFolder for '/myfolder'
+sec total (INCLUDING DELETE): 3.84342
+
+OK (1)
+[OVAL] Cppunit-result =0
+RelationalDatabase                   Info     Delete the RalDatabase for 'oracle://cooldb2;schema=AVALASSI;user=avalassi;password=andrea;dbname=COOLTEST'
+POOL/RelationalPlugins/oracle        Warning  No active transaction to roll back
+RelationalDatabase                   Debug    Delete the RelationalDatabase for 'oracle://cooldb2;schema=AVALASSI;user=avalassi;password=andrea;dbname=COOLTEST'
diff --git a/RelationalCool/tests/PerformanceAV/TestRalOnly/ralOnly-time.rh73.501MB.oracle.prf b/RelationalCool/tests/PerformanceAV/TestRalOnly/ralOnly-time.rh73.501MB.oracle.prf
new file mode 100644
index 000000000..7fcafc1cb
--- /dev/null
+++ b/RelationalCool/tests/PerformanceAV/TestRalOnly/ralOnly-time.rh73.501MB.oracle.prf
@@ -0,0 +1,239 @@
+
+TKPROF: Release 9.2.0.6.0 - Production on Tue Feb 1 14:51:57 2005
+
+Copyright (c) 1982, 2002, Oracle Corporation.  All rights reserved.
+
+Trace file: cooldb2_ora_5020.trc
+Sort options: exeela  fchcnt  
+********************************************************************************
+count    = number of times OCI procedure was executed
+cpu      = cpu time in seconds executing 
+elapsed  = elapsed time in seconds executing
+disk     = number of physical reads of buffers from disk
+query    = number of buffers gotten for consistent read
+current  = number of buffers gotten in current mode (usually for update)
+rows     = number of rows processed by the fetch or execute call
+********************************************************************************
+
+SELECT "OBJECT_ID", "CHANNEL_ID", "IOV_SINCE", "IOV_UNTIL", "SYS_INSTIME", 
+  "I", "S", "X0", "X1", "X2", "X3", "X4", "X5", "X6", "X7", "X8", "X9", "P" 
+FROM
+ "AVALASSI"."COOLTEST_F0001_IOVS" WHERE "CHANNEL_ID"=:"channel" AND 
+  "IOV_SINCE">=:"since" AND "IOV_UNTIL"<=:"till" ORDER BY "CHANNEL_ID" ASC,
+  "IOV_SINCE" ASC
+
+
+call     count       cpu    elapsed       disk      query    current        rows
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+Parse        1      0.00       0.00          0          0          0           0
+Execute      1      0.00       0.00          0          0          0           0
+Fetch      197      3.48       3.39          0      34442     140451       19604
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+total      199      3.48       3.39          0      34442     140451       19604
+
+Misses in library cache during parse: 0
+Optimizer goal: CHOOSE
+Parsing user id: 25  
+
+Rows     Row Source Operation
+-------  ---------------------------------------------------
+  10000  SORT ORDER BY 
+  10000   TABLE ACCESS FULL COOLTEST_F0001_IOVS 
+
+
+Elapsed times include waiting on following events:
+  Event waited on                             Times   Max. Wait  Total Waited
+  ----------------------------------------   Waited  ----------  ------------
+  SQL*Net message to client                     197        0.00          0.00
+  SQL*Net more data to client                  1177        0.00          0.05
+  SQL*Net message from client                   197        0.00          0.56
+********************************************************************************
+
+SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", 
+  "NODE_ISLEAF", "NODE_INSTIME", "FOLDER_PAYLOADSPEC", "FOLDER_VERSIONING", 
+  "FOLDER_IOVTABLENAME" 
+FROM
+ "AVALASSI"."COOLTEST_FOLDERS" WHERE "NODE_FULLPATH"=:"fullName"
+
+
+call     count       cpu    elapsed       disk      query    current        rows
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+Parse        1      0.00       0.00          0          0          0           0
+Execute      1      0.00       0.00          0          0          0           0
+Fetch        2      0.00       0.00          0          2          7           1
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+total        4      0.00       0.00          0          2          7           1
+
+Misses in library cache during parse: 0
+Optimizer goal: CHOOSE
+Parsing user id: 25  
+
+Rows     Row Source Operation
+-------  ---------------------------------------------------
+      1  TABLE ACCESS BY INDEX ROWID COOLTEST_FOLDERS 
+      1   INDEX RANGE SCAN COOLTEST_FOLDERS_FULN_1INDX (object id 8136)
+
+
+Elapsed times include waiting on following events:
+  Event waited on                             Times   Max. Wait  Total Waited
+  ----------------------------------------   Waited  ----------  ------------
+  SQL*Net message to client                       2        0.00          0.00
+  SQL*Net message from client                     2        0.00          0.00
+********************************************************************************
+
+SELECT TABLE_NAME 
+FROM
+ ALL_TABLES WHERE OWNER = 'AVALASSI'
+
+
+call     count       cpu    elapsed       disk      query    current        rows
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+Parse        1      0.00       0.00          0          0          0           0
+Execute      1      0.00       0.00          0          0          0           0
+Fetch        1      0.00       0.00          0        122          0           8
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+total        3      0.00       0.00          0        122          0           8
+
+Misses in library cache during parse: 0
+Optimizer goal: CHOOSE
+Parsing user id: 25  
+
+Rows     Row Source Operation
+-------  ---------------------------------------------------
+      8  FILTER  
+      8   NESTED LOOPS  
+      8    NESTED LOOPS OUTER 
+      8     NESTED LOOPS OUTER 
+      8      NESTED LOOPS OUTER 
+      8       NESTED LOOPS OUTER 
+      8        NESTED LOOPS  
+     16         NESTED LOOPS  
+      1          TABLE ACCESS BY INDEX ROWID USER$ 
+      1           INDEX UNIQUE SCAN I_USER1 (object id 44)
+     16          TABLE ACCESS BY INDEX ROWID OBJ$ 
+     16           INDEX RANGE SCAN I_OBJ2 (object id 37)
+      8         TABLE ACCESS CLUSTER TAB$ 
+      8          INDEX UNIQUE SCAN I_OBJ# (object id 3)
+      8        TABLE ACCESS BY INDEX ROWID OBJ$ 
+      8         INDEX UNIQUE SCAN I_OBJ1 (object id 36)
+      0       INDEX UNIQUE SCAN I_OBJ1 (object id 36)
+      8      TABLE ACCESS CLUSTER USER$ 
+      8       INDEX UNIQUE SCAN I_USER# (object id 11)
+      8     TABLE ACCESS CLUSTER SEG$ 
+      8      INDEX UNIQUE SCAN I_FILE#_BLOCK# (object id 9)
+      8    TABLE ACCESS CLUSTER TS$ 
+      8     INDEX UNIQUE SCAN I_TS# (object id 7)
+      0   NESTED LOOPS  
+      0    FIXED TABLE FULL X$KZSRO 
+      0    INDEX RANGE SCAN I_OBJAUTH2 (object id 109)
+      0   FIXED TABLE FULL X$KZSPR 
+
+
+Elapsed times include waiting on following events:
+  Event waited on                             Times   Max. Wait  Total Waited
+  ----------------------------------------   Waited  ----------  ------------
+  SQL*Net message to client                       1        0.00          0.00
+  SQL*Net message from client                     1        0.00          0.00
+********************************************************************************
+
+alter session set events '10046 trace name context forever, level 12'
+
+
+call     count       cpu    elapsed       disk      query    current        rows
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+Parse        0      0.00       0.00          0          0          0           0
+Execute      1      0.00       0.00          0          0          0           0
+Fetch        0      0.00       0.00          0          0          0           0
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+total        1      0.00       0.00          0          0          0           0
+
+Misses in library cache during parse: 0
+Optimizer goal: CHOOSE
+Parsing user id: 25  
+
+Elapsed times include waiting on following events:
+  Event waited on                             Times   Max. Wait  Total Waited
+  ----------------------------------------   Waited  ----------  ------------
+  SQL*Net message to client                       1        0.00          0.00
+  SQL*Net message from client                     1        0.00          0.00
+********************************************************************************
+
+SELECT "DB_ATTRIBUTE_NAME", "DB_ATTRIBUTE_VALUE" 
+FROM
+ "AVALASSI"."COOLTEST_DB_ATTRIBUTES"
+
+
+call     count       cpu    elapsed       disk      query    current        rows
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+Parse        1      0.00       0.00          0          0          0           0
+Execute      1      0.00       0.00          0          0          0           0
+Fetch        3      0.00       0.00          0         10         19           2
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+total        5      0.00       0.00          0         10         19           2
+
+Misses in library cache during parse: 0
+Optimizer goal: CHOOSE
+Parsing user id: 25  
+
+Rows     Row Source Operation
+-------  ---------------------------------------------------
+      2  TABLE ACCESS FULL COOLTEST_DB_ATTRIBUTES 
+
+
+Elapsed times include waiting on following events:
+  Event waited on                             Times   Max. Wait  Total Waited
+  ----------------------------------------   Waited  ----------  ------------
+  SQL*Net message to client                       3        0.00          0.00
+  SQL*Net message from client                     3        0.00          0.00
+
+
+
+********************************************************************************
+
+OVERALL TOTALS FOR ALL NON-RECURSIVE STATEMENTS
+
+call     count       cpu    elapsed       disk      query    current        rows
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+Parse        4      0.00       0.00          0          0          0           0
+Execute      5      0.00       0.00          0          0          0           0
+Fetch      203      3.48       3.40          0      34576     140477       19615
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+total      212      3.48       3.40          0      34576     140477       19615
+
+Misses in library cache during parse: 0
+
+Elapsed times include waiting on following events:
+  Event waited on                             Times   Max. Wait  Total Waited
+  ----------------------------------------   Waited  ----------  ------------
+  SQL*Net message to client                     216        0.00          0.00
+  SQL*Net message from client                   216        0.98          1.58
+  SQL*Net more data to client                  1178        0.00          0.05
+
+
+OVERALL TOTALS FOR ALL RECURSIVE STATEMENTS
+
+call     count       cpu    elapsed       disk      query    current        rows
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+Parse        0      0.00       0.00          0          0          0           0
+Execute      0      0.00       0.00          0          0          0           0
+Fetch        0      0.00       0.00          0          0          0           0
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+total        0      0.00       0.00          0          0          0           0
+
+Misses in library cache during parse: 0
+
+    5  user  SQL statements in session.
+    0  internal SQL statements in session.
+    5  SQL statements in session.
+********************************************************************************
+Trace file: cooldb2_ora_5020.trc
+Trace file compatibility: 9.02.00
+Sort options: exeela  fchcnt  
+       1  session in tracefile.
+       5  user  SQL statements in trace file.
+       0  internal SQL statements in trace file.
+       5  SQL statements in trace file.
+       5  unique SQL statements in trace file.
+    1911  lines in trace file.
+
+
diff --git a/RelationalCool/tests/PerformanceAV/TestRalOnly/ralOnly-time.rh73.501MB.oracle.prf.ANALYZED b/RelationalCool/tests/PerformanceAV/TestRalOnly/ralOnly-time.rh73.501MB.oracle.prf.ANALYZED
new file mode 100644
index 000000000..e1763e135
--- /dev/null
+++ b/RelationalCool/tests/PerformanceAV/TestRalOnly/ralOnly-time.rh73.501MB.oracle.prf.ANALYZED
@@ -0,0 +1,239 @@
+
+TKPROF: Release 9.2.0.6.0 - Production on Tue Feb 1 15:12:08 2005
+
+Copyright (c) 1982, 2002, Oracle Corporation.  All rights reserved.
+
+Trace file: cooldb2_ora_5101.trc
+Sort options: exeela  fchcnt  
+********************************************************************************
+count    = number of times OCI procedure was executed
+cpu      = cpu time in seconds executing 
+elapsed  = elapsed time in seconds executing
+disk     = number of physical reads of buffers from disk
+query    = number of buffers gotten for consistent read
+current  = number of buffers gotten in current mode (usually for update)
+rows     = number of rows processed by the fetch or execute call
+********************************************************************************
+
+SELECT "OBJECT_ID", "CHANNEL_ID", "IOV_SINCE", "IOV_UNTIL", "SYS_INSTIME", 
+  "I", "S", "X0", "X1", "X2", "X3", "X4", "X5", "X6", "X7", "X8", "X9", "P" 
+FROM
+ "AVALASSI"."COOLTEST_F0001_IOVS" WHERE "CHANNEL_ID"=:"channel" AND 
+  "IOV_SINCE">=:"since" AND "IOV_UNTIL"<=:"till" ORDER BY "CHANNEL_ID" ASC,
+  "IOV_SINCE" ASC
+
+
+call     count       cpu    elapsed       disk      query    current        rows
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+Parse        1      0.00       0.00          0          0          0           0
+Execute      1      0.00       0.00          0          0          0           0
+Fetch      197      3.15       3.10          0      31647     140451       19604
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+total      199      3.15       3.10          0      31647     140451       19604
+
+Misses in library cache during parse: 0
+Optimizer goal: CHOOSE
+Parsing user id: 25  
+
+Rows     Row Source Operation
+-------  ---------------------------------------------------
+  10000  TABLE ACCESS BY INDEX ROWID COOLTEST_F0001_IOVS 
+  10000   INDEX RANGE SCAN COOLTEST_F0001_IOVS_CSU_3INDX (object id 8142)
+
+
+Elapsed times include waiting on following events:
+  Event waited on                             Times   Max. Wait  Total Waited
+  ----------------------------------------   Waited  ----------  ------------
+  SQL*Net message to client                     197        0.00          0.00
+  SQL*Net more data to client                  1177        0.00          0.04
+  SQL*Net message from client                   197        0.00          0.57
+********************************************************************************
+
+SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", 
+  "NODE_ISLEAF", "NODE_INSTIME", "FOLDER_PAYLOADSPEC", "FOLDER_VERSIONING", 
+  "FOLDER_IOVTABLENAME" 
+FROM
+ "AVALASSI"."COOLTEST_FOLDERS" WHERE "NODE_FULLPATH"=:"fullName"
+
+
+call     count       cpu    elapsed       disk      query    current        rows
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+Parse        1      0.00       0.00          0          0          0           0
+Execute      1      0.00       0.00          0          0          0           0
+Fetch        2      0.00       0.00          0          2          7           1
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+total        4      0.00       0.00          0          2          7           1
+
+Misses in library cache during parse: 0
+Optimizer goal: CHOOSE
+Parsing user id: 25  
+
+Rows     Row Source Operation
+-------  ---------------------------------------------------
+      1  TABLE ACCESS BY INDEX ROWID COOLTEST_FOLDERS 
+      1   INDEX RANGE SCAN COOLTEST_FOLDERS_FULN_1INDX (object id 8136)
+
+
+Elapsed times include waiting on following events:
+  Event waited on                             Times   Max. Wait  Total Waited
+  ----------------------------------------   Waited  ----------  ------------
+  SQL*Net message to client                       2        0.00          0.00
+  SQL*Net message from client                     2        0.00          0.00
+********************************************************************************
+
+SELECT TABLE_NAME 
+FROM
+ ALL_TABLES WHERE OWNER = 'AVALASSI'
+
+
+call     count       cpu    elapsed       disk      query    current        rows
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+Parse        1      0.00       0.00          0          0          0           0
+Execute      1      0.00       0.00          0          0          0           0
+Fetch        1      0.00       0.00          0        122          0           8
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+total        3      0.00       0.00          0        122          0           8
+
+Misses in library cache during parse: 0
+Optimizer goal: CHOOSE
+Parsing user id: 25  
+
+Rows     Row Source Operation
+-------  ---------------------------------------------------
+      8  FILTER  
+      8   NESTED LOOPS  
+      8    NESTED LOOPS OUTER 
+      8     NESTED LOOPS OUTER 
+      8      NESTED LOOPS OUTER 
+      8       NESTED LOOPS OUTER 
+      8        NESTED LOOPS  
+     16         NESTED LOOPS  
+      1          TABLE ACCESS BY INDEX ROWID USER$ 
+      1           INDEX UNIQUE SCAN I_USER1 (object id 44)
+     16          TABLE ACCESS BY INDEX ROWID OBJ$ 
+     16           INDEX RANGE SCAN I_OBJ2 (object id 37)
+      8         TABLE ACCESS CLUSTER TAB$ 
+      8          INDEX UNIQUE SCAN I_OBJ# (object id 3)
+      8        TABLE ACCESS BY INDEX ROWID OBJ$ 
+      8         INDEX UNIQUE SCAN I_OBJ1 (object id 36)
+      0       INDEX UNIQUE SCAN I_OBJ1 (object id 36)
+      8      TABLE ACCESS CLUSTER USER$ 
+      8       INDEX UNIQUE SCAN I_USER# (object id 11)
+      8     TABLE ACCESS CLUSTER SEG$ 
+      8      INDEX UNIQUE SCAN I_FILE#_BLOCK# (object id 9)
+      8    TABLE ACCESS CLUSTER TS$ 
+      8     INDEX UNIQUE SCAN I_TS# (object id 7)
+      0   NESTED LOOPS  
+      0    FIXED TABLE FULL X$KZSRO 
+      0    INDEX RANGE SCAN I_OBJAUTH2 (object id 109)
+      0   FIXED TABLE FULL X$KZSPR 
+
+
+Elapsed times include waiting on following events:
+  Event waited on                             Times   Max. Wait  Total Waited
+  ----------------------------------------   Waited  ----------  ------------
+  SQL*Net message to client                       1        0.00          0.00
+  SQL*Net message from client                     1        0.00          0.00
+********************************************************************************
+
+alter session set events '10046 trace name context forever, level 12'
+
+
+call     count       cpu    elapsed       disk      query    current        rows
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+Parse        0      0.00       0.00          0          0          0           0
+Execute      1      0.00       0.00          0          0          0           0
+Fetch        0      0.00       0.00          0          0          0           0
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+total        1      0.00       0.00          0          0          0           0
+
+Misses in library cache during parse: 0
+Optimizer goal: CHOOSE
+Parsing user id: 25  
+
+Elapsed times include waiting on following events:
+  Event waited on                             Times   Max. Wait  Total Waited
+  ----------------------------------------   Waited  ----------  ------------
+  SQL*Net message to client                       1        0.00          0.00
+  SQL*Net message from client                     1        0.00          0.00
+********************************************************************************
+
+SELECT "DB_ATTRIBUTE_NAME", "DB_ATTRIBUTE_VALUE" 
+FROM
+ "AVALASSI"."COOLTEST_DB_ATTRIBUTES"
+
+
+call     count       cpu    elapsed       disk      query    current        rows
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+Parse        1      0.00       0.00          0          0          0           0
+Execute      1      0.00       0.00          0          0          0           0
+Fetch        3      0.00       0.00          0         10         19           2
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+total        5      0.00       0.00          0         10         19           2
+
+Misses in library cache during parse: 0
+Optimizer goal: CHOOSE
+Parsing user id: 25  
+
+Rows     Row Source Operation
+-------  ---------------------------------------------------
+      2  TABLE ACCESS FULL COOLTEST_DB_ATTRIBUTES 
+
+
+Elapsed times include waiting on following events:
+  Event waited on                             Times   Max. Wait  Total Waited
+  ----------------------------------------   Waited  ----------  ------------
+  SQL*Net message to client                       3        0.00          0.00
+  SQL*Net message from client                     3        0.00          0.00
+
+
+
+********************************************************************************
+
+OVERALL TOTALS FOR ALL NON-RECURSIVE STATEMENTS
+
+call     count       cpu    elapsed       disk      query    current        rows
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+Parse        4      0.00       0.00          0          0          0           0
+Execute      5      0.00       0.00          0          0          0           0
+Fetch      203      3.15       3.11          0      31781     140477       19615
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+total      212      3.15       3.11          0      31781     140477       19615
+
+Misses in library cache during parse: 0
+
+Elapsed times include waiting on following events:
+  Event waited on                             Times   Max. Wait  Total Waited
+  ----------------------------------------   Waited  ----------  ------------
+  SQL*Net message to client                     216        0.00          0.00
+  SQL*Net message from client                   216        0.98          1.59
+  SQL*Net more data to client                  1178        0.00          0.04
+
+
+OVERALL TOTALS FOR ALL RECURSIVE STATEMENTS
+
+call     count       cpu    elapsed       disk      query    current        rows
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+Parse        0      0.00       0.00          0          0          0           0
+Execute      0      0.00       0.00          0          0          0           0
+Fetch        0      0.00       0.00          0          0          0           0
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+total        0      0.00       0.00          0          0          0           0
+
+Misses in library cache during parse: 0
+
+    5  user  SQL statements in session.
+    0  internal SQL statements in session.
+    5  SQL statements in session.
+********************************************************************************
+Trace file: cooldb2_ora_5101.trc
+Trace file compatibility: 9.02.00
+Sort options: exeela  fchcnt  
+       1  session in tracefile.
+       5  user  SQL statements in trace file.
+       0  internal SQL statements in trace file.
+       5  SQL statements in trace file.
+       5  unique SQL statements in trace file.
+    1911  lines in trace file.
+
+
diff --git a/RelationalCool/tests/PerformanceAV/TestRalOnly/withCool-memory.rh73.501MB.oracle.out b/RelationalCool/tests/PerformanceAV/TestRalOnly/withCool-memory.rh73.501MB.oracle.out
new file mode 100644
index 000000000..fcebcd2cf
--- /dev/null
+++ b/RelationalCool/tests/PerformanceAV/TestRalOnly/withCool-memory.rh73.501MB.oracle.out
@@ -0,0 +1,103 @@
+Property Catalogue: level[Info] Adding property: OutputLevel = 2 in scope "SEAL/Services/MessageService"
+Property Catalogue: level[Info] Adding property: Format =  "%-36s %-8s %s" in scope "SEAL/Services/MessageService"
+MessageService callback    Debug MessageService output level changed to Debug
+ConfigurationService    Debug Setting property: "Format" to value " "%-36s %-8s %s"" in scope "SEAL/Services/MessageService"
+POOL/Services/RelationalService      Info     Found plugin for RDBMS technology "mysql" with implementation "odbc"
+POOL/Services/RelationalService      Info     Found plugin for RDBMS technology "oracle" with native implementation
+POOL/Services/RelationalService      Info     Default implementation for RDBMS technology "mysql" is "odbc"
+POOL/Services/RelationalService      Info     Default implementation for RDBMS technology "oracle" is native
+RelationalDatabase                   Debug    Instantiate a RelationalDatabase for 'oracle://cooldb2;schema=AVALASSI;user=avalassi;password=andrea;dbname=COOLTEST'
+RelationalDatabase                   Info     Instantiate a RalDatabase for 'oracle://cooldb2;schema=AVALASSI;user=avalassi;password=andrea;dbname=COOLTEST'
+POOL/RelationalPlugins/oracle        Info     Connected to a server running Oracle version 9.2.0.6.0
+POOL/RelationalPlugins/oracle        Warning  Environment variable RAL_SQLTRACE is set: enable SQL_TRACE
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "alter session set events '10046 trace name context forever, level 12'"
+POOL/RelationalPlugins/oracle        Warning  SQL_TRACE enabled
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT TABLE_NAME FROM ALL_TABLES WHERE OWNER = 'AVALASSI'"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT "DB_ATTRIBUTE_NAME", "DB_ATTRIBUTE_VALUE" FROM "AVALASSI"."COOLTEST_DB_ATTRIBUTES""
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_ISLEAF", "NODE_INSTIME", "FOLDER_PAYLOADSPEC", "FOLDER_VERSIONING", "FOLDER_IOVTABLENAME" FROM "AVALASSI"."COOLTEST_FOLDERS" WHERE "NODE_FULLPATH"=:"fullName""
+RelationalFolder                     Debug    Instantiate a RelationalFolder for '/myfolder'
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT "OBJECT_ID", "CHANNEL_ID", "IOV_SINCE", "IOV_UNTIL", "SYS_INSTIME", "I", "S", "X0", "X1", "X2", "X3", "X4", "X5", "X6", "X7", "X8", "X9", "P" FROM "AVALASSI"."COOLTEST_F0001_IOVS" WHERE "CHANNEL_ID"=:"channel" AND "IOV_SINCE">=:"since" AND "IOV_UNTIL"<=:"till" ORDER BY "CHANNEL_ID" ASC,"IOV_SINCE" ASC"
+>>>>>>    Timing Results  <<<<<<<<<< 
+----- 1.PrepareQuery----------- :                              ( n=1 )
+Total Real Time  :      0.010 +/-      0.010 s
+Total User Time  :      0.000 +/-      0.000 s
+Total System Time:      0.000 +/-      0.000 s
+Total Idle Time  :      0.010 +/-      0.010 s
+Total VmSize incr:      0.000 +/-      0.000 MB
+Total VmRSS incr :      0.012 +/-      0.012 MB
+----- 2.ProcessQuery----------- :                              ( n=1 )
+Total Real Time  :      0.250 +/-      0.250 s
+Total User Time  :      0.020 +/-      0.020 s
+Total System Time:      0.000 +/-      0.000 s
+Total Idle Time  :      0.230 +/-      0.230 s
+Total VmSize incr:      0.412 +/-      0.412 MB
+Total VmRSS incr :      0.404 +/-      0.404 MB
+----- 3.FetchRows-------------- :                              ( n=10001 )
+Total Real Time  :     10.360 +/-      0.104 s
+Total User Time  :      4.880 +/-      0.049 s
+Total System Time:      1.910 +/-      0.019 s
+Total Idle Time  :      3.590 +/-      0.036 s
+Total VmSize incr:      0.448 +/-      0.004 MB
+Total VmRSS incr :      1.528 +/-      0.015 MB
+----- 4.CopyAttributeList------ :                              ( n=10000 )
+Total Real Time  :     11.370 +/-      0.114 s
+Total User Time  :     10.000 +/-      0.100 s
+Total System Time:      1.770 +/-      0.018 s
+Total Idle Time  :     -0.400 +/-     -0.004 s
+Total VmSize incr:     25.092 +/-      0.251 MB
+Total VmRSS incr :     23.796 +/-      0.238 MB
+----- 5.CloseQuery------------- :                              ( n=1 )
+Total Real Time  :      0.000 +/-      0.000 s
+Total User Time  :      0.000 +/-      0.000 s
+Total System Time:      0.000 +/-      0.000 s
+Total Idle Time  :      0.000 +/-      0.000 s
+Total VmSize incr:      0.000 +/-      0.000 MB
+Total VmRSS incr :      0.000 +/-      0.000 MB
+----- TOTAL FetchObjRowsByVal-- :                              ( n=1 )
+Total Real Time  :     34.380 +/-     34.380 s
+Total User Time  :     23.690 +/-     23.690 s
+Total System Time:      7.390 +/-      7.390 s
+Total Idle Time  :      3.300 +/-      3.300 s
+Total VmSize incr:     26.016 +/-     26.016 MB
+Total VmRSS incr :     25.740 +/-     25.740 MB
+>>>>>>    Timing Results  <<<<<<<<<< 
+----- 1.FetchObjRowsByVal----- :                              ( n=1 )
+Total Real Time  :     34.380 +/-     34.380 s
+Total User Time  :     23.700 +/-     23.700 s
+Total System Time:      7.390 +/-      7.390 s
+Total Idle Time  :      3.290 +/-      3.290 s
+Total VmSize incr:     26.028 +/-     26.028 MB
+Total VmRSS incr :     25.752 +/-     25.752 MB
+----- 2.DecodeRow------------- :                              ( n=1 )
+Total Real Time  :      0.990 +/-      0.990 s
+Total User Time  :      0.960 +/-      0.960 s
+Total System Time:      0.010 +/-      0.010 s
+Total Idle Time  :      0.020 +/-      0.020 s
+Total VmSize incr:      3.016 +/-      3.016 MB
+Total VmRSS incr :      2.956 +/-      2.956 MB
+----- 3.DeleteOld------------- :                              ( n=1 )
+Total Real Time  :      0.160 +/-      0.160 s
+Total User Time  :      0.160 +/-      0.160 s
+Total System Time:      0.000 +/-      0.000 s
+Total Idle Time  :      0.000 +/-      0.000 s
+Total VmSize incr:     -0.132 +/-     -0.132 MB
+Total VmRSS incr :     -0.080 +/-     -0.080 MB
+----- TOTAL BrowseObjInTag---- :                              ( n=1 )
+Total Real Time  :     35.530 +/-     35.530 s
+Total User Time  :     24.820 +/-     24.820 s
+Total System Time:      7.400 +/-      7.400 s
+Total Idle Time  :      3.310 +/-      3.310 s
+Total VmSize incr:     28.912 +/-     28.912 MB
+Total VmRSS incr :     28.628 +/-     28.628 MB
+** reading 100000 objects (150 bytes mixed) **
+read back 10000 objects
+sec total: 35.5368
+obj/s:     281.398
+RelationalFolder                     Debug    Delete the RelationalFolder for '/myfolder'
+sec total (INCLUDING DELETE): 35.6753
+
+OK (1)
+[OVAL] Cppunit-result =0
+RelationalDatabase                   Info     Delete the RalDatabase for 'oracle://cooldb2;schema=AVALASSI;user=avalassi;password=andrea;dbname=COOLTEST'
+POOL/RelationalPlugins/oracle        Warning  No active transaction to roll back
+RelationalDatabase                   Debug    Delete the RelationalDatabase for 'oracle://cooldb2;schema=AVALASSI;user=avalassi;password=andrea;dbname=COOLTEST'
diff --git a/RelationalCool/tests/PerformanceAV/TestRalOnly/withCool-time.rh73.501MB.oracle.out b/RelationalCool/tests/PerformanceAV/TestRalOnly/withCool-time.rh73.501MB.oracle.out
new file mode 100644
index 000000000..50c33f562
--- /dev/null
+++ b/RelationalCool/tests/PerformanceAV/TestRalOnly/withCool-time.rh73.501MB.oracle.out
@@ -0,0 +1,83 @@
+Property Catalogue: level[Info] Adding property: OutputLevel = 2 in scope "SEAL/Services/MessageService"
+Property Catalogue: level[Info] Adding property: Format =  "%-36s %-8s %s" in scope "SEAL/Services/MessageService"
+MessageService callback    Debug MessageService output level changed to Debug
+ConfigurationService    Debug Setting property: "Format" to value " "%-36s %-8s %s"" in scope "SEAL/Services/MessageService"
+POOL/Services/RelationalService      Info     Found plugin for RDBMS technology "mysql" with implementation "odbc"
+POOL/Services/RelationalService      Info     Found plugin for RDBMS technology "oracle" with native implementation
+POOL/Services/RelationalService      Info     Default implementation for RDBMS technology "mysql" is "odbc"
+POOL/Services/RelationalService      Info     Default implementation for RDBMS technology "oracle" is native
+RelationalDatabase                   Debug    Instantiate a RelationalDatabase for 'oracle://cooldb2;schema=AVALASSI;user=avalassi;password=andrea;dbname=COOLTEST'
+RelationalDatabase                   Info     Instantiate a RalDatabase for 'oracle://cooldb2;schema=AVALASSI;user=avalassi;password=andrea;dbname=COOLTEST'
+POOL/RelationalPlugins/oracle        Info     Connected to a server running Oracle version 9.2.0.6.0
+POOL/RelationalPlugins/oracle        Warning  Environment variable RAL_SQLTRACE is set: enable SQL_TRACE
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "alter session set events '10046 trace name context forever, level 12'"
+POOL/RelationalPlugins/oracle        Warning  SQL_TRACE enabled
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT TABLE_NAME FROM ALL_TABLES WHERE OWNER = 'AVALASSI'"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT "DB_ATTRIBUTE_NAME", "DB_ATTRIBUTE_VALUE" FROM "AVALASSI"."COOLTEST_DB_ATTRIBUTES""
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_ISLEAF", "NODE_INSTIME", "FOLDER_PAYLOADSPEC", "FOLDER_VERSIONING", "FOLDER_IOVTABLENAME" FROM "AVALASSI"."COOLTEST_FOLDERS" WHERE "NODE_FULLPATH"=:"fullName""
+RelationalFolder                     Debug    Instantiate a RelationalFolder for '/myfolder'
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT "OBJECT_ID", "CHANNEL_ID", "IOV_SINCE", "IOV_UNTIL", "SYS_INSTIME", "I", "S", "X0", "X1", "X2", "X3", "X4", "X5", "X6", "X7", "X8", "X9", "P" FROM "AVALASSI"."COOLTEST_F0001_IOVS" WHERE "CHANNEL_ID"=:"channel" AND "IOV_SINCE">=:"since" AND "IOV_UNTIL"<=:"till" ORDER BY "CHANNEL_ID" ASC,"IOV_SINCE" ASC"
+>>>>>>    Timing Results  <<<<<<<<<< 
+----- 1.PrepareQuery----------- :                              ( n=1 )
+Total Real Time  :      0.010 +/-      0.010 s
+Total User Time  :      0.000 +/-      0.000 s
+Total System Time:      0.000 +/-      0.000 s
+Total Idle Time  :      0.010 +/-      0.010 s
+----- 2.ProcessQuery----------- :                              ( n=1 )
+Total Real Time  :      0.250 +/-      0.250 s
+Total User Time  :      0.000 +/-      0.000 s
+Total System Time:      0.000 +/-      0.000 s
+Total Idle Time  :      0.250 +/-      0.250 s
+----- 3.FetchRows-------------- :                              ( n=10001 )
+Total Real Time  :      4.180 +/-      0.042 s
+Total User Time  :      0.630 +/-      0.006 s
+Total System Time:      0.040 +/-      0.000 s
+Total Idle Time  :      3.530 +/-      0.035 s
+----- 4.CopyAttributeList------ :                              ( n=10000 )
+Total Real Time  :      5.550 +/-      0.056 s
+Total User Time  :      5.640 +/-      0.056 s
+Total System Time:      0.060 +/-      0.001 s
+Total Idle Time  :     -0.130 +/-     -0.001 s
+----- 5.CloseQuery------------- :                              ( n=1 )
+Total Real Time  :      0.000 +/-      0.000 s
+Total User Time  :      0.000 +/-      0.000 s
+Total System Time:      0.000 +/-      0.000 s
+Total Idle Time  :      0.000 +/-      0.000 s
+----- TOTAL FetchObjRowsByVal-- :                              ( n=1 )
+Total Real Time  :     10.120 +/-     10.120 s
+Total User Time  :      6.400 +/-      6.400 s
+Total System Time:      0.110 +/-      0.110 s
+Total Idle Time  :      3.610 +/-      3.610 s
+>>>>>>    Timing Results  <<<<<<<<<< 
+----- 1.FetchObjRowsByVal----- :                              ( n=1 )
+Total Real Time  :     10.120 +/-     10.120 s
+Total User Time  :      6.400 +/-      6.400 s
+Total System Time:      0.110 +/-      0.110 s
+Total Idle Time  :      3.610 +/-      3.610 s
+----- 2.DecodeRow------------- :                              ( n=1 )
+Total Real Time  :      1.010 +/-      1.010 s
+Total User Time  :      0.960 +/-      0.960 s
+Total System Time:      0.030 +/-      0.030 s
+Total Idle Time  :      0.020 +/-      0.020 s
+----- 3.DeleteOld------------- :                              ( n=1 )
+Total Real Time  :      0.160 +/-      0.160 s
+Total User Time  :      0.150 +/-      0.150 s
+Total System Time:      0.000 +/-      0.000 s
+Total Idle Time  :      0.010 +/-      0.010 s
+----- TOTAL BrowseObjInTag---- :                              ( n=1 )
+Total Real Time  :     11.290 +/-     11.290 s
+Total User Time  :      7.510 +/-      7.510 s
+Total System Time:      0.140 +/-      0.140 s
+Total Idle Time  :      3.640 +/-      3.640 s
+** reading 100000 objects (150 bytes mixed) **
+read back 10000 objects
+sec total: 11.2898
+obj/s:     885.756
+RelationalFolder                     Debug    Delete the RelationalFolder for '/myfolder'
+sec total (INCLUDING DELETE): 11.4288
+
+OK (1)
+[OVAL] Cppunit-result =0
+RelationalDatabase                   Info     Delete the RalDatabase for 'oracle://cooldb2;schema=AVALASSI;user=avalassi;password=andrea;dbname=COOLTEST'
+POOL/RelationalPlugins/oracle        Warning  No active transaction to roll back
+RelationalDatabase                   Debug    Delete the RelationalDatabase for 'oracle://cooldb2;schema=AVALASSI;user=avalassi;password=andrea;dbname=COOLTEST'
diff --git a/RelationalCool/tests/PerformanceAV/TestRalOnly/withCool-time.rh73.501MB.oracle.out.ANALYZED b/RelationalCool/tests/PerformanceAV/TestRalOnly/withCool-time.rh73.501MB.oracle.out.ANALYZED
new file mode 100644
index 000000000..0d0e57422
--- /dev/null
+++ b/RelationalCool/tests/PerformanceAV/TestRalOnly/withCool-time.rh73.501MB.oracle.out.ANALYZED
@@ -0,0 +1,83 @@
+Property Catalogue: level[Info] Adding property: OutputLevel = 2 in scope "SEAL/Services/MessageService"
+Property Catalogue: level[Info] Adding property: Format =  "%-36s %-8s %s" in scope "SEAL/Services/MessageService"
+MessageService callback    Debug MessageService output level changed to Debug
+ConfigurationService    Debug Setting property: "Format" to value " "%-36s %-8s %s"" in scope "SEAL/Services/MessageService"
+POOL/Services/RelationalService      Info     Found plugin for RDBMS technology "mysql" with implementation "odbc"
+POOL/Services/RelationalService      Info     Found plugin for RDBMS technology "oracle" with native implementation
+POOL/Services/RelationalService      Info     Default implementation for RDBMS technology "mysql" is "odbc"
+POOL/Services/RelationalService      Info     Default implementation for RDBMS technology "oracle" is native
+RelationalDatabase                   Debug    Instantiate a RelationalDatabase for 'oracle://cooldb2;schema=AVALASSI;user=avalassi;password=andrea;dbname=COOLTEST'
+RelationalDatabase                   Info     Instantiate a RalDatabase for 'oracle://cooldb2;schema=AVALASSI;user=avalassi;password=andrea;dbname=COOLTEST'
+POOL/RelationalPlugins/oracle        Info     Connected to a server running Oracle version 9.2.0.6.0
+POOL/RelationalPlugins/oracle        Warning  Environment variable RAL_SQLTRACE is set: enable SQL_TRACE
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "alter session set events '10046 trace name context forever, level 12'"
+POOL/RelationalPlugins/oracle        Warning  SQL_TRACE enabled
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT TABLE_NAME FROM ALL_TABLES WHERE OWNER = 'AVALASSI'"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT "DB_ATTRIBUTE_NAME", "DB_ATTRIBUTE_VALUE" FROM "AVALASSI"."COOLTEST_DB_ATTRIBUTES""
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_ISLEAF", "NODE_INSTIME", "FOLDER_PAYLOADSPEC", "FOLDER_VERSIONING", "FOLDER_IOVTABLENAME" FROM "AVALASSI"."COOLTEST_FOLDERS" WHERE "NODE_FULLPATH"=:"fullName""
+RelationalFolder                     Debug    Instantiate a RelationalFolder for '/myfolder'
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT "OBJECT_ID", "CHANNEL_ID", "IOV_SINCE", "IOV_UNTIL", "SYS_INSTIME", "I", "S", "X0", "X1", "X2", "X3", "X4", "X5", "X6", "X7", "X8", "X9", "P" FROM "AVALASSI"."COOLTEST_F0001_IOVS" WHERE "CHANNEL_ID"=:"channel" AND "IOV_SINCE">=:"since" AND "IOV_UNTIL"<=:"till" ORDER BY "CHANNEL_ID" ASC,"IOV_SINCE" ASC"
+>>>>>>    Timing Results  <<<<<<<<<< 
+----- 1.PrepareQuery----------- :                              ( n=1 )
+Total Real Time  :      0.010 +/-      0.010 s
+Total User Time  :      0.000 +/-      0.000 s
+Total System Time:      0.000 +/-      0.000 s
+Total Idle Time  :      0.010 +/-      0.010 s
+----- 2.ProcessQuery----------- :                              ( n=1 )
+Total Real Time  :      0.220 +/-      0.220 s
+Total User Time  :      0.000 +/-      0.000 s
+Total System Time:      0.010 +/-      0.010 s
+Total Idle Time  :      0.210 +/-      0.210 s
+----- 3.FetchRows-------------- :                              ( n=10001 )
+Total Real Time  :      4.090 +/-      0.041 s
+Total User Time  :      0.730 +/-      0.007 s
+Total System Time:      0.100 +/-      0.001 s
+Total Idle Time  :      3.250 +/-      0.032 s
+----- 4.CopyAttributeList------ :                              ( n=10000 )
+Total Real Time  :      5.550 +/-      0.056 s
+Total User Time  :      5.410 +/-      0.054 s
+Total System Time:      0.110 +/-      0.001 s
+Total Idle Time  :      0.070 +/-      0.001 s
+----- 5.CloseQuery------------- :                              ( n=1 )
+Total Real Time  :      0.000 +/-      0.000 s
+Total User Time  :      0.000 +/-      0.000 s
+Total System Time:      0.000 +/-      0.000 s
+Total Idle Time  :      0.000 +/-      0.000 s
+----- TOTAL FetchObjRowsByVal-- :                              ( n=1 )
+Total Real Time  :     10.020 +/-     10.020 s
+Total User Time  :      6.240 +/-      6.240 s
+Total System Time:      0.250 +/-      0.250 s
+Total Idle Time  :      3.530 +/-      3.530 s
+>>>>>>    Timing Results  <<<<<<<<<< 
+----- 1.FetchObjRowsByVal----- :                              ( n=1 )
+Total Real Time  :     10.030 +/-     10.030 s
+Total User Time  :      6.240 +/-      6.240 s
+Total System Time:      0.250 +/-      0.250 s
+Total Idle Time  :      3.540 +/-      3.540 s
+----- 2.DecodeRow------------- :                              ( n=1 )
+Total Real Time  :      0.970 +/-      0.970 s
+Total User Time  :      0.970 +/-      0.970 s
+Total System Time:      0.000 +/-      0.000 s
+Total Idle Time  :      0.000 +/-      0.000 s
+----- 3.DeleteOld------------- :                              ( n=1 )
+Total Real Time  :      0.160 +/-      0.160 s
+Total User Time  :      0.160 +/-      0.160 s
+Total System Time:      0.000 +/-      0.000 s
+Total Idle Time  :      0.000 +/-      0.000 s
+----- TOTAL BrowseObjInTag---- :                              ( n=1 )
+Total Real Time  :     11.160 +/-     11.160 s
+Total User Time  :      7.370 +/-      7.370 s
+Total System Time:      0.250 +/-      0.250 s
+Total Idle Time  :      3.540 +/-      3.540 s
+** reading 100000 objects (150 bytes mixed) **
+read back 10000 objects
+sec total: 11.1632
+obj/s:     895.803
+RelationalFolder                     Debug    Delete the RelationalFolder for '/myfolder'
+sec total (INCLUDING DELETE): 11.3014
+
+OK (1)
+[OVAL] Cppunit-result =0
+RelationalDatabase                   Info     Delete the RalDatabase for 'oracle://cooldb2;schema=AVALASSI;user=avalassi;password=andrea;dbname=COOLTEST'
+POOL/RelationalPlugins/oracle        Warning  No active transaction to roll back
+RelationalDatabase                   Debug    Delete the RelationalDatabase for 'oracle://cooldb2;schema=AVALASSI;user=avalassi;password=andrea;dbname=COOLTEST'
diff --git a/RelationalCool/tests/PerformanceAV/TestRalOnly/withCool-time.rh73.501MB.oracle.prf b/RelationalCool/tests/PerformanceAV/TestRalOnly/withCool-time.rh73.501MB.oracle.prf
new file mode 100644
index 000000000..8b3af0e32
--- /dev/null
+++ b/RelationalCool/tests/PerformanceAV/TestRalOnly/withCool-time.rh73.501MB.oracle.prf
@@ -0,0 +1,241 @@
+
+TKPROF: Release 9.2.0.6.0 - Production on Tue Feb 1 14:51:49 2005
+
+Copyright (c) 1982, 2002, Oracle Corporation.  All rights reserved.
+
+Trace file: cooldb2_ora_5014.trc
+Sort options: exeela  fchcnt  
+********************************************************************************
+count    = number of times OCI procedure was executed
+cpu      = cpu time in seconds executing 
+elapsed  = elapsed time in seconds executing
+disk     = number of physical reads of buffers from disk
+query    = number of buffers gotten for consistent read
+current  = number of buffers gotten in current mode (usually for update)
+rows     = number of rows processed by the fetch or execute call
+********************************************************************************
+
+SELECT "OBJECT_ID", "CHANNEL_ID", "IOV_SINCE", "IOV_UNTIL", "SYS_INSTIME", 
+  "I", "S", "X0", "X1", "X2", "X3", "X4", "X5", "X6", "X7", "X8", "X9", "P" 
+FROM
+ "AVALASSI"."COOLTEST_F0001_IOVS" WHERE "CHANNEL_ID"=:"channel" AND 
+  "IOV_SINCE">=:"since" AND "IOV_UNTIL"<=:"till" ORDER BY "CHANNEL_ID" ASC,
+  "IOV_SINCE" ASC
+
+
+call     count       cpu    elapsed       disk      query    current        rows
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+Parse        1      0.00       0.00          0          0          0           0
+Execute      1      0.00       0.00          0          0          0           0
+Fetch      197      3.61       3.42         32      34442     140447       19604
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+total      199      3.61       3.42         32      34442     140447       19604
+
+Misses in library cache during parse: 0
+Optimizer goal: CHOOSE
+Parsing user id: 25  
+
+Rows     Row Source Operation
+-------  ---------------------------------------------------
+  10000  SORT ORDER BY 
+  10000   TABLE ACCESS FULL COOLTEST_F0001_IOVS 
+
+
+Elapsed times include waiting on following events:
+  Event waited on                             Times   Max. Wait  Total Waited
+  ----------------------------------------   Waited  ----------  ------------
+  SQL*Net message to client                     197        0.00          0.00
+  db file scattered read                         16        0.00          0.00
+  SQL*Net more data to client                  1177        0.00          0.04
+  SQL*Net message from client                   197        0.06          6.41
+********************************************************************************
+
+SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", 
+  "NODE_ISLEAF", "NODE_INSTIME", "FOLDER_PAYLOADSPEC", "FOLDER_VERSIONING", 
+  "FOLDER_IOVTABLENAME" 
+FROM
+ "AVALASSI"."COOLTEST_FOLDERS" WHERE "NODE_FULLPATH"=:"fullName"
+
+
+call     count       cpu    elapsed       disk      query    current        rows
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+Parse        1      0.00       0.00          0          0          0           0
+Execute      1      0.00       0.00          0          0          0           0
+Fetch        2      0.00       0.00          0          2          7           1
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+total        4      0.00       0.00          0          2          7           1
+
+Misses in library cache during parse: 0
+Optimizer goal: CHOOSE
+Parsing user id: 25  
+
+Rows     Row Source Operation
+-------  ---------------------------------------------------
+      1  TABLE ACCESS BY INDEX ROWID COOLTEST_FOLDERS 
+      1   INDEX RANGE SCAN COOLTEST_FOLDERS_FULN_1INDX (object id 8136)
+
+
+Elapsed times include waiting on following events:
+  Event waited on                             Times   Max. Wait  Total Waited
+  ----------------------------------------   Waited  ----------  ------------
+  SQL*Net message to client                       2        0.00          0.00
+  SQL*Net message from client                     2        0.00          0.00
+********************************************************************************
+
+SELECT TABLE_NAME 
+FROM
+ ALL_TABLES WHERE OWNER = 'AVALASSI'
+
+
+call     count       cpu    elapsed       disk      query    current        rows
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+Parse        1      0.00       0.00          0          0          0           0
+Execute      1      0.00       0.00          0          0          0           0
+Fetch        1      0.01       0.00          0        122          0           8
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+total        3      0.01       0.00          0        122          0           8
+
+Misses in library cache during parse: 0
+Optimizer goal: CHOOSE
+Parsing user id: 25  
+
+Rows     Row Source Operation
+-------  ---------------------------------------------------
+      8  FILTER  
+      8   NESTED LOOPS  
+      8    NESTED LOOPS OUTER 
+      8     NESTED LOOPS OUTER 
+      8      NESTED LOOPS OUTER 
+      8       NESTED LOOPS OUTER 
+      8        NESTED LOOPS  
+     16         NESTED LOOPS  
+      1          TABLE ACCESS BY INDEX ROWID USER$ 
+      1           INDEX UNIQUE SCAN I_USER1 (object id 44)
+     16          TABLE ACCESS BY INDEX ROWID OBJ$ 
+     16           INDEX RANGE SCAN I_OBJ2 (object id 37)
+      8         TABLE ACCESS CLUSTER TAB$ 
+      8          INDEX UNIQUE SCAN I_OBJ# (object id 3)
+      8        TABLE ACCESS BY INDEX ROWID OBJ$ 
+      8         INDEX UNIQUE SCAN I_OBJ1 (object id 36)
+      0       INDEX UNIQUE SCAN I_OBJ1 (object id 36)
+      8      TABLE ACCESS CLUSTER USER$ 
+      8       INDEX UNIQUE SCAN I_USER# (object id 11)
+      8     TABLE ACCESS CLUSTER SEG$ 
+      8      INDEX UNIQUE SCAN I_FILE#_BLOCK# (object id 9)
+      8    TABLE ACCESS CLUSTER TS$ 
+      8     INDEX UNIQUE SCAN I_TS# (object id 7)
+      0   NESTED LOOPS  
+      0    FIXED TABLE FULL X$KZSRO 
+      0    INDEX RANGE SCAN I_OBJAUTH2 (object id 109)
+      0   FIXED TABLE FULL X$KZSPR 
+
+
+Elapsed times include waiting on following events:
+  Event waited on                             Times   Max. Wait  Total Waited
+  ----------------------------------------   Waited  ----------  ------------
+  SQL*Net message to client                       1        0.00          0.00
+  SQL*Net message from client                     1        0.00          0.00
+********************************************************************************
+
+alter session set events '10046 trace name context forever, level 12'
+
+
+call     count       cpu    elapsed       disk      query    current        rows
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+Parse        0      0.00       0.00          0          0          0           0
+Execute      1      0.00       0.00          0          0          0           0
+Fetch        0      0.00       0.00          0          0          0           0
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+total        1      0.00       0.00          0          0          0           0
+
+Misses in library cache during parse: 0
+Optimizer goal: CHOOSE
+Parsing user id: 25  
+
+Elapsed times include waiting on following events:
+  Event waited on                             Times   Max. Wait  Total Waited
+  ----------------------------------------   Waited  ----------  ------------
+  SQL*Net message to client                       1        0.00          0.00
+  SQL*Net message from client                     1        0.00          0.00
+********************************************************************************
+
+SELECT "DB_ATTRIBUTE_NAME", "DB_ATTRIBUTE_VALUE" 
+FROM
+ "AVALASSI"."COOLTEST_DB_ATTRIBUTES"
+
+
+call     count       cpu    elapsed       disk      query    current        rows
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+Parse        1      0.00       0.00          0          0          0           0
+Execute      1      0.00       0.00          0          0          0           0
+Fetch        3      0.01       0.00          0         10         19           2
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+total        5      0.01       0.00          0         10         19           2
+
+Misses in library cache during parse: 0
+Optimizer goal: CHOOSE
+Parsing user id: 25  
+
+Rows     Row Source Operation
+-------  ---------------------------------------------------
+      2  TABLE ACCESS FULL COOLTEST_DB_ATTRIBUTES 
+
+
+Elapsed times include waiting on following events:
+  Event waited on                             Times   Max. Wait  Total Waited
+  ----------------------------------------   Waited  ----------  ------------
+  SQL*Net message to client                       3        0.00          0.00
+  SQL*Net message from client                     3        0.00          0.00
+
+
+
+********************************************************************************
+
+OVERALL TOTALS FOR ALL NON-RECURSIVE STATEMENTS
+
+call     count       cpu    elapsed       disk      query    current        rows
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+Parse        4      0.00       0.00          0          0          0           0
+Execute      5      0.00       0.00          0          0          0           0
+Fetch      203      3.63       3.43         32      34576     140473       19615
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+total      212      3.63       3.43         32      34576     140473       19615
+
+Misses in library cache during parse: 0
+
+Elapsed times include waiting on following events:
+  Event waited on                             Times   Max. Wait  Total Waited
+  ----------------------------------------   Waited  ----------  ------------
+  SQL*Net message to client                     216        0.00          0.00
+  SQL*Net message from client                   216        1.24          8.67
+  SQL*Net more data to client                  1178        0.00          0.04
+  db file scattered read                         16        0.00          0.00
+
+
+OVERALL TOTALS FOR ALL RECURSIVE STATEMENTS
+
+call     count       cpu    elapsed       disk      query    current        rows
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+Parse        0      0.00       0.00          0          0          0           0
+Execute      0      0.00       0.00          0          0          0           0
+Fetch        0      0.00       0.00          0          0          0           0
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+total        0      0.00       0.00          0          0          0           0
+
+Misses in library cache during parse: 0
+
+    5  user  SQL statements in session.
+    0  internal SQL statements in session.
+    5  SQL statements in session.
+********************************************************************************
+Trace file: cooldb2_ora_5014.trc
+Trace file compatibility: 9.02.00
+Sort options: exeela  fchcnt  
+       1  session in tracefile.
+       5  user  SQL statements in trace file.
+       0  internal SQL statements in trace file.
+       5  SQL statements in trace file.
+       5  unique SQL statements in trace file.
+    1927  lines in trace file.
+
+
diff --git a/RelationalCool/tests/PerformanceAV/TestRalOnly/withCool-time.rh73.501MB.oracle.prf.ANALYZED b/RelationalCool/tests/PerformanceAV/TestRalOnly/withCool-time.rh73.501MB.oracle.prf.ANALYZED
new file mode 100644
index 000000000..06691fa26
--- /dev/null
+++ b/RelationalCool/tests/PerformanceAV/TestRalOnly/withCool-time.rh73.501MB.oracle.prf.ANALYZED
@@ -0,0 +1,239 @@
+
+TKPROF: Release 9.2.0.6.0 - Production on Tue Feb 1 15:11:57 2005
+
+Copyright (c) 1982, 2002, Oracle Corporation.  All rights reserved.
+
+Trace file: cooldb2_ora_5099.trc
+Sort options: exeela  fchcnt  
+********************************************************************************
+count    = number of times OCI procedure was executed
+cpu      = cpu time in seconds executing 
+elapsed  = elapsed time in seconds executing
+disk     = number of physical reads of buffers from disk
+query    = number of buffers gotten for consistent read
+current  = number of buffers gotten in current mode (usually for update)
+rows     = number of rows processed by the fetch or execute call
+********************************************************************************
+
+SELECT "OBJECT_ID", "CHANNEL_ID", "IOV_SINCE", "IOV_UNTIL", "SYS_INSTIME", 
+  "I", "S", "X0", "X1", "X2", "X3", "X4", "X5", "X6", "X7", "X8", "X9", "P" 
+FROM
+ "AVALASSI"."COOLTEST_F0001_IOVS" WHERE "CHANNEL_ID"=:"channel" AND 
+  "IOV_SINCE">=:"since" AND "IOV_UNTIL"<=:"till" ORDER BY "CHANNEL_ID" ASC,
+  "IOV_SINCE" ASC
+
+
+call     count       cpu    elapsed       disk      query    current        rows
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+Parse        1      0.00       0.00          0          0          0           0
+Execute      1      0.00       0.00          0          0          0           0
+Fetch      197      3.33       3.13          0      31647     140451       19604
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+total      199      3.33       3.13          0      31647     140451       19604
+
+Misses in library cache during parse: 1
+Optimizer goal: CHOOSE
+Parsing user id: 25  
+
+Rows     Row Source Operation
+-------  ---------------------------------------------------
+  10000  TABLE ACCESS BY INDEX ROWID COOLTEST_F0001_IOVS 
+  10000   INDEX RANGE SCAN COOLTEST_F0001_IOVS_CSU_3INDX (object id 8142)
+
+
+Elapsed times include waiting on following events:
+  Event waited on                             Times   Max. Wait  Total Waited
+  ----------------------------------------   Waited  ----------  ------------
+  SQL*Net message to client                     197        0.00          0.00
+  SQL*Net more data to client                  1177        0.00          0.04
+  SQL*Net message from client                   197        0.26          6.60
+********************************************************************************
+
+SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", 
+  "NODE_ISLEAF", "NODE_INSTIME", "FOLDER_PAYLOADSPEC", "FOLDER_VERSIONING", 
+  "FOLDER_IOVTABLENAME" 
+FROM
+ "AVALASSI"."COOLTEST_FOLDERS" WHERE "NODE_FULLPATH"=:"fullName"
+
+
+call     count       cpu    elapsed       disk      query    current        rows
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+Parse        1      0.00       0.00          0          0          0           0
+Execute      1      0.00       0.00          0          0          0           0
+Fetch        2      0.00       0.00          0          2          7           1
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+total        4      0.00       0.00          0          2          7           1
+
+Misses in library cache during parse: 0
+Optimizer goal: CHOOSE
+Parsing user id: 25  
+
+Rows     Row Source Operation
+-------  ---------------------------------------------------
+      1  TABLE ACCESS BY INDEX ROWID COOLTEST_FOLDERS 
+      1   INDEX RANGE SCAN COOLTEST_FOLDERS_FULN_1INDX (object id 8136)
+
+
+Elapsed times include waiting on following events:
+  Event waited on                             Times   Max. Wait  Total Waited
+  ----------------------------------------   Waited  ----------  ------------
+  SQL*Net message to client                       2        0.00          0.00
+  SQL*Net message from client                     2        0.00          0.00
+********************************************************************************
+
+SELECT TABLE_NAME 
+FROM
+ ALL_TABLES WHERE OWNER = 'AVALASSI'
+
+
+call     count       cpu    elapsed       disk      query    current        rows
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+Parse        1      0.01       0.00          0          0          0           0
+Execute      1      0.00       0.00          0          0          0           0
+Fetch        1      0.00       0.00          0        122          0           8
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+total        3      0.01       0.00          0        122          0           8
+
+Misses in library cache during parse: 0
+Optimizer goal: CHOOSE
+Parsing user id: 25  
+
+Rows     Row Source Operation
+-------  ---------------------------------------------------
+      8  FILTER  
+      8   NESTED LOOPS  
+      8    NESTED LOOPS OUTER 
+      8     NESTED LOOPS OUTER 
+      8      NESTED LOOPS OUTER 
+      8       NESTED LOOPS OUTER 
+      8        NESTED LOOPS  
+     16         NESTED LOOPS  
+      1          TABLE ACCESS BY INDEX ROWID USER$ 
+      1           INDEX UNIQUE SCAN I_USER1 (object id 44)
+     16          TABLE ACCESS BY INDEX ROWID OBJ$ 
+     16           INDEX RANGE SCAN I_OBJ2 (object id 37)
+      8         TABLE ACCESS CLUSTER TAB$ 
+      8          INDEX UNIQUE SCAN I_OBJ# (object id 3)
+      8        TABLE ACCESS BY INDEX ROWID OBJ$ 
+      8         INDEX UNIQUE SCAN I_OBJ1 (object id 36)
+      0       INDEX UNIQUE SCAN I_OBJ1 (object id 36)
+      8      TABLE ACCESS CLUSTER USER$ 
+      8       INDEX UNIQUE SCAN I_USER# (object id 11)
+      8     TABLE ACCESS CLUSTER SEG$ 
+      8      INDEX UNIQUE SCAN I_FILE#_BLOCK# (object id 9)
+      8    TABLE ACCESS CLUSTER TS$ 
+      8     INDEX UNIQUE SCAN I_TS# (object id 7)
+      0   NESTED LOOPS  
+      0    FIXED TABLE FULL X$KZSRO 
+      0    INDEX RANGE SCAN I_OBJAUTH2 (object id 109)
+      0   FIXED TABLE FULL X$KZSPR 
+
+
+Elapsed times include waiting on following events:
+  Event waited on                             Times   Max. Wait  Total Waited
+  ----------------------------------------   Waited  ----------  ------------
+  SQL*Net message to client                       1        0.00          0.00
+  SQL*Net message from client                     1        0.00          0.00
+********************************************************************************
+
+alter session set events '10046 trace name context forever, level 12'
+
+
+call     count       cpu    elapsed       disk      query    current        rows
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+Parse        0      0.00       0.00          0          0          0           0
+Execute      1      0.00       0.00          0          0          0           0
+Fetch        0      0.00       0.00          0          0          0           0
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+total        1      0.00       0.00          0          0          0           0
+
+Misses in library cache during parse: 0
+Optimizer goal: CHOOSE
+Parsing user id: 25  
+
+Elapsed times include waiting on following events:
+  Event waited on                             Times   Max. Wait  Total Waited
+  ----------------------------------------   Waited  ----------  ------------
+  SQL*Net message to client                       1        0.00          0.00
+  SQL*Net message from client                     1        0.00          0.00
+********************************************************************************
+
+SELECT "DB_ATTRIBUTE_NAME", "DB_ATTRIBUTE_VALUE" 
+FROM
+ "AVALASSI"."COOLTEST_DB_ATTRIBUTES"
+
+
+call     count       cpu    elapsed       disk      query    current        rows
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+Parse        1      0.00       0.00          0          0          0           0
+Execute      1      0.00       0.00          0          0          0           0
+Fetch        3      0.01       0.00          0         10         19           2
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+total        5      0.01       0.00          0         10         19           2
+
+Misses in library cache during parse: 0
+Optimizer goal: CHOOSE
+Parsing user id: 25  
+
+Rows     Row Source Operation
+-------  ---------------------------------------------------
+      2  TABLE ACCESS FULL COOLTEST_DB_ATTRIBUTES 
+
+
+Elapsed times include waiting on following events:
+  Event waited on                             Times   Max. Wait  Total Waited
+  ----------------------------------------   Waited  ----------  ------------
+  SQL*Net message to client                       3        0.00          0.00
+  SQL*Net message from client                     3        0.00          0.00
+
+
+
+********************************************************************************
+
+OVERALL TOTALS FOR ALL NON-RECURSIVE STATEMENTS
+
+call     count       cpu    elapsed       disk      query    current        rows
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+Parse        4      0.01       0.00          0          0          0           0
+Execute      5      0.00       0.00          0          0          0           0
+Fetch      203      3.34       3.13          0      31781     140477       19615
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+total      212      3.35       3.14          0      31781     140477       19615
+
+Misses in library cache during parse: 1
+
+Elapsed times include waiting on following events:
+  Event waited on                             Times   Max. Wait  Total Waited
+  ----------------------------------------   Waited  ----------  ------------
+  SQL*Net message to client                     216        0.00          0.00
+  SQL*Net message from client                   216        1.21          8.84
+  SQL*Net more data to client                  1178        0.00          0.04
+
+
+OVERALL TOTALS FOR ALL RECURSIVE STATEMENTS
+
+call     count       cpu    elapsed       disk      query    current        rows
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+Parse        0      0.00       0.00          0          0          0           0
+Execute      0      0.00       0.00          0          0          0           0
+Fetch        0      0.00       0.00          0          0          0           0
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+total        0      0.00       0.00          0          0          0           0
+
+Misses in library cache during parse: 0
+
+    5  user  SQL statements in session.
+    0  internal SQL statements in session.
+    5  SQL statements in session.
+********************************************************************************
+Trace file: cooldb2_ora_5099.trc
+Trace file compatibility: 9.02.00
+Sort options: exeela  fchcnt  
+       1  session in tracefile.
+       5  user  SQL statements in trace file.
+       0  internal SQL statements in trace file.
+       5  SQL statements in trace file.
+       5  unique SQL statements in trace file.
+    1911  lines in trace file.
+
+
diff --git a/RelationalCool/tests/PerformanceAV/TestScrollableCursor/execTestScrollableCursor.rh73.1006MB.oracle.out.ANALYZED b/RelationalCool/tests/PerformanceAV/TestScrollableCursor/execTestScrollableCursor.rh73.1006MB.oracle.out.ANALYZED
new file mode 100644
index 000000000..e992a6cb7
--- /dev/null
+++ b/RelationalCool/tests/PerformanceAV/TestScrollableCursor/execTestScrollableCursor.rh73.1006MB.oracle.out.ANALYZED
@@ -0,0 +1,5 @@
+3.600u 0.220s 0:08.22 46.4%     0+0k 0+0io 2274pf+0w
+3.590u 0.210s 0:04.99 76.1%     0+0k 0+0io 2273pf+0w
+21.360u 7.090s 0:33.04 86.1%    0+0k 0+0io 2274pf+0w
+20.990u 7.250s 0:29.71 95.0%    0+0k 0+0io 2273pf+0w
+
diff --git a/RelationalCool/tests/PerformanceAV/TestScrollableCursor/notScrollable-memory.rh73.1006MB.oracle.out.ANALYZED b/RelationalCool/tests/PerformanceAV/TestScrollableCursor/notScrollable-memory.rh73.1006MB.oracle.out.ANALYZED
new file mode 100644
index 000000000..e0ed13c11
--- /dev/null
+++ b/RelationalCool/tests/PerformanceAV/TestScrollableCursor/notScrollable-memory.rh73.1006MB.oracle.out.ANALYZED
@@ -0,0 +1,110 @@
+Property Catalogue: level[Info] Adding property: OutputLevel = 2 in scope "SEAL/Services/MessageService"
+Property Catalogue: level[Info] Adding property: Format =  "%-36s %-8s %s" in scope "SEAL/Services/MessageService"
+MessageService callback    Debug MessageService output level changed to Debug
+ConfigurationService    Debug Setting property: "Format" to value " "%-36s %-8s %s"" in scope "SEAL/Services/MessageService"
+POOL/Services/RelationalService      Info     Found plugin for RDBMS technology "mysql" with implementation "odbc"
+POOL/Services/RelationalService      Info     Found plugin for RDBMS technology "oracle" with native implementation
+POOL/Services/RelationalService      Info     Default implementation for RDBMS technology "mysql" is "odbc"
+POOL/Services/RelationalService      Info     Default implementation for RDBMS technology "oracle" is native
+RelationalDatabase                   Debug    Instantiate a RelationalDatabase for 'oracle://cooldb2;schema=AVALASSI;user=avalassi;password=andrea;dbname=COOLTEST'
+RelationalDatabase                   Info     Instantiate a RalDatabase for 'oracle://cooldb2;schema=AVALASSI;user=avalassi;password=andrea;dbname=COOLTEST'
+POOL/RelationalPlugins/oracle        Info     Connected to a server running Oracle version 9.2.0.6.0
+POOL/RelationalPlugins/oracle        Warning  Environment variable RAL_SQLTRACE is set: enable SQL_TRACE
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "alter session set events '10046 trace name context forever, level 12'"
+POOL/RelationalPlugins/oracle        Warning  SQL_TRACE enabled
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT TABLE_NAME FROM ALL_TABLES WHERE OWNER = 'AVALASSI'"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT "DB_ATTRIBUTE_NAME", "DB_ATTRIBUTE_VALUE" FROM "AVALASSI"."COOLTEST_DB_ATTRIBUTES""
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_ISLEAF", "NODE_INSTIME", "FOLDER_PAYLOADSPEC", "FOLDER_VERSIONING", "FOLDER_IOVTABLENAME" FROM "AVALASSI"."COOLTEST_FOLDERS" WHERE "NODE_FULLPATH"=:"fullName""
+RelationalFolder                     Debug    Instantiate a RelationalFolder for '/myfolder'
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT "OBJECT_ID", "CHANNEL_ID", "IOV_SINCE", "IOV_UNTIL", "SYS_INSTIME", "I", "S", "X0", "X1", "X2", "X3", "X4", "X5", "X6", "X7", "X8", "X9", "P" FROM "AVALASSI"."COOLTEST_F0001_IOVS" WHERE "CHANNEL_ID"=:"channel" AND "IOV_SINCE">=:"since" AND "IOV_UNTIL"<=:"till" ORDER BY "CHANNEL_ID" ASC,"IOV_SINCE" ASC"
+>>>>>>    Timing Results  <<<<<<<<<< 
+----- 1.PrepareQuery----------- :                              ( n=1 )
+Total Real Time  :      0.000 +/-      0.000 s
+Total User Time  :      0.010 +/-      0.010 s
+Total System Time:      0.000 +/-      0.000 s
+Total Idle Time  :     -0.010 +/-     -0.010 s
+Total VmSize incr:      0.000 +/-      0.000 MB
+Total VmRSS incr :      0.012 +/-      0.012 MB
+----- 2.ProcessQuery----------- :                              ( n=1 )
+Total Real Time  :      0.010 +/-      0.010 s
+Total User Time  :      0.010 +/-      0.010 s
+Total System Time:      0.000 +/-      0.000 s
+Total Idle Time  :      0.000 +/-      0.000 s
+Total VmSize incr:      0.412 +/-      0.412 MB
+Total VmRSS incr :      0.404 +/-      0.404 MB
+----- 3.FetchRows-------------- :                              ( n=10001 )
+Total Real Time  :      6.700 +/-      0.067 s
+Total User Time  :      4.900 +/-      0.049 s
+Total System Time:      1.780 +/-      0.018 s
+Total Idle Time  :      0.020 +/-      0.000 s
+Total VmSize incr:      0.012 +/-      0.000 MB
+Total VmRSS incr :      0.024 +/-      0.000 MB
+----- 4.CopyAttributeList------ :                              ( n=10000 )
+Total Real Time  :      7.970 +/-      0.080 s
+Total User Time  :      6.210 +/-      0.062 s
+Total System Time:      1.550 +/-      0.015 s
+Total Idle Time  :      0.250 +/-      0.003 s
+Total VmSize incr:     12.216 +/-      0.122 MB
+Total VmRSS incr :     12.172 +/-      0.122 MB
+----- 5.CloseQuery------------- :                              ( n=1 )
+Total Real Time  :      0.010 +/-      0.010 s
+Total User Time  :      0.000 +/-      0.000 s
+Total System Time:      0.000 +/-      0.000 s
+Total Idle Time  :      0.010 +/-      0.010 s
+Total VmSize incr:      0.000 +/-      0.000 MB
+Total VmRSS incr :      0.000 +/-      0.000 MB
+----- TOTAL FetchObjRowsByVal-- :                              ( n=1 )
+Total Real Time  :     27.240 +/-     27.240 s
+Total User Time  :     19.690 +/-     19.690 s
+Total System Time:      7.180 +/-      7.180 s
+Total Idle Time  :      0.370 +/-      0.370 s
+Total VmSize incr:     12.680 +/-     12.680 MB
+Total VmRSS incr :     12.612 +/-     12.612 MB
+>>>>>>    Timing Results  <<<<<<<<<< 
+----- 1.FetchObjRowsByVal----- :                              ( n=1 )
+Total Real Time  :     27.240 +/-     27.240 s
+Total User Time  :     19.690 +/-     19.690 s
+Total System Time:      7.180 +/-      7.180 s
+Total Idle Time  :      0.370 +/-      0.370 s
+Total VmSize incr:     12.692 +/-     12.692 MB
+Total VmRSS incr :     12.636 +/-     12.636 MB
+----- 2.DecodeRow------------- :                              ( n=1 )
+Total Real Time  :      0.980 +/-      0.980 s
+Total User Time  :      0.980 +/-      0.980 s
+Total System Time:      0.000 +/-      0.000 s
+Total Idle Time  :      0.000 +/-      0.000 s
+Total VmSize incr:      3.032 +/-      3.032 MB
+Total VmRSS incr :      2.980 +/-      2.980 MB
+----- 3.DeleteOld------------- :                              ( n=1 )
+Total Real Time  :      0.110 +/-      0.110 s
+Total User Time  :      0.100 +/-      0.100 s
+Total System Time:      0.000 +/-      0.000 s
+Total Idle Time  :      0.010 +/-      0.010 s
+Total VmSize incr:     -0.132 +/-     -0.132 MB
+Total VmRSS incr :     -0.080 +/-     -0.080 MB
+----- 4.FillIterator---------- :                              ( n=1 )
+Total Real Time  :      0.010 +/-      0.010 s
+Total User Time  :      0.000 +/-      0.000 s
+Total System Time:      0.000 +/-      0.000 s
+Total Idle Time  :      0.010 +/-      0.010 s
+Total VmSize incr:     -0.132 +/-     -0.132 MB
+Total VmRSS incr :     -0.076 +/-     -0.076 MB
+----- TOTAL BrowseObjInTag---- :                              ( n=1 )
+Total Real Time  :     28.340 +/-     28.340 s
+Total User Time  :     20.770 +/-     20.770 s
+Total System Time:      7.190 +/-      7.190 s
+Total Idle Time  :      0.380 +/-      0.380 s
+Total VmSize incr:     15.460 +/-     15.460 MB
+Total VmRSS incr :     15.460 +/-     15.460 MB
+** reading 100000 objects (150 bytes mixed) **
+read back 10000 objects
+sec total: 28.3538
+obj/s:     352.687
+RelationalFolder                     Debug    Delete the RelationalFolder for '/myfolder'
+sec total (INCLUDING DELETE): 28.3953
+
+OK (1)
+[OVAL] Cppunit-result =0
+RelationalDatabase                   Info     Delete the RalDatabase for 'oracle://cooldb2;schema=AVALASSI;user=avalassi;password=andrea;dbname=COOLTEST'
+POOL/RelationalPlugins/oracle        Warning  No active transaction to roll back
+RelationalDatabase                   Debug    Delete the RelationalDatabase for 'oracle://cooldb2;schema=AVALASSI;user=avalassi;password=andrea;dbname=COOLTEST'
diff --git a/RelationalCool/tests/PerformanceAV/TestScrollableCursor/notScrollable-time.rh73.1006MB.oracle.out.ANALYZED b/RelationalCool/tests/PerformanceAV/TestScrollableCursor/notScrollable-time.rh73.1006MB.oracle.out.ANALYZED
new file mode 100644
index 000000000..7b155b4e3
--- /dev/null
+++ b/RelationalCool/tests/PerformanceAV/TestScrollableCursor/notScrollable-time.rh73.1006MB.oracle.out.ANALYZED
@@ -0,0 +1,88 @@
+Property Catalogue: level[Info] Adding property: OutputLevel = 2 in scope "SEAL/Services/MessageService"
+Property Catalogue: level[Info] Adding property: Format =  "%-36s %-8s %s" in scope "SEAL/Services/MessageService"
+MessageService callback    Debug MessageService output level changed to Debug
+ConfigurationService    Debug Setting property: "Format" to value " "%-36s %-8s %s"" in scope "SEAL/Services/MessageService"
+POOL/Services/RelationalService      Info     Found plugin for RDBMS technology "mysql" with implementation "odbc"
+POOL/Services/RelationalService      Info     Found plugin for RDBMS technology "oracle" with native implementation
+POOL/Services/RelationalService      Info     Default implementation for RDBMS technology "mysql" is "odbc"
+POOL/Services/RelationalService      Info     Default implementation for RDBMS technology "oracle" is native
+RelationalDatabase                   Debug    Instantiate a RelationalDatabase for 'oracle://cooldb2;schema=AVALASSI;user=avalassi;password=andrea;dbname=COOLTEST'
+RelationalDatabase                   Info     Instantiate a RalDatabase for 'oracle://cooldb2;schema=AVALASSI;user=avalassi;password=andrea;dbname=COOLTEST'
+POOL/RelationalPlugins/oracle        Info     Connected to a server running Oracle version 9.2.0.6.0
+POOL/RelationalPlugins/oracle        Warning  Environment variable RAL_SQLTRACE is set: enable SQL_TRACE
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "alter session set events '10046 trace name context forever, level 12'"
+POOL/RelationalPlugins/oracle        Warning  SQL_TRACE enabled
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT TABLE_NAME FROM ALL_TABLES WHERE OWNER = 'AVALASSI'"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT "DB_ATTRIBUTE_NAME", "DB_ATTRIBUTE_VALUE" FROM "AVALASSI"."COOLTEST_DB_ATTRIBUTES""
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_ISLEAF", "NODE_INSTIME", "FOLDER_PAYLOADSPEC", "FOLDER_VERSIONING", "FOLDER_IOVTABLENAME" FROM "AVALASSI"."COOLTEST_FOLDERS" WHERE "NODE_FULLPATH"=:"fullName""
+RelationalFolder                     Debug    Instantiate a RelationalFolder for '/myfolder'
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT "OBJECT_ID", "CHANNEL_ID", "IOV_SINCE", "IOV_UNTIL", "SYS_INSTIME", "I", "S", "X0", "X1", "X2", "X3", "X4", "X5", "X6", "X7", "X8", "X9", "P" FROM "AVALASSI"."COOLTEST_F0001_IOVS" WHERE "CHANNEL_ID"=:"channel" AND "IOV_SINCE">=:"since" AND "IOV_UNTIL"<=:"till" ORDER BY "CHANNEL_ID" ASC,"IOV_SINCE" ASC"
+>>>>>>    Timing Results  <<<<<<<<<< 
+----- 1.PrepareQuery----------- :                              ( n=1 )
+Total Real Time  :      0.000 +/-      0.000 s
+Total User Time  :      0.000 +/-      0.000 s
+Total System Time:      0.000 +/-      0.000 s
+Total Idle Time  :      0.000 +/-      0.000 s
+----- 2.ProcessQuery----------- :                              ( n=1 )
+Total Real Time  :      0.010 +/-      0.010 s
+Total User Time  :      0.000 +/-      0.000 s
+Total System Time:      0.000 +/-      0.000 s
+Total Idle Time  :      0.010 +/-      0.010 s
+----- 3.FetchRows-------------- :                              ( n=10001 )
+Total Real Time  :      0.680 +/-      0.007 s
+Total User Time  :      0.400 +/-      0.004 s
+Total System Time:      0.040 +/-      0.000 s
+Total Idle Time  :      0.260 +/-      0.003 s
+----- 4.CopyAttributeList------ :                              ( n=10000 )
+Total Real Time  :      1.800 +/-      0.018 s
+Total User Time  :      1.810 +/-      0.018 s
+Total System Time:      0.080 +/-      0.001 s
+Total Idle Time  :     -0.070 +/-     -0.001 s
+----- 5.CloseQuery------------- :                              ( n=1 )
+Total Real Time  :      0.000 +/-      0.000 s
+Total User Time  :      0.000 +/-      0.000 s
+Total System Time:      0.000 +/-      0.000 s
+Total Idle Time  :      0.000 +/-      0.000 s
+----- TOTAL FetchObjRowsByVal-- :                              ( n=1 )
+Total Real Time  :      2.550 +/-      2.550 s
+Total User Time  :      2.290 +/-      2.290 s
+Total System Time:      0.140 +/-      0.140 s
+Total Idle Time  :      0.120 +/-      0.120 s
+>>>>>>    Timing Results  <<<<<<<<<< 
+----- 1.FetchObjRowsByVal----- :                              ( n=1 )
+Total Real Time  :      2.560 +/-      2.560 s
+Total User Time  :      2.290 +/-      2.290 s
+Total System Time:      0.140 +/-      0.140 s
+Total Idle Time  :      0.130 +/-      0.130 s
+----- 2.DecodeRow------------- :                              ( n=1 )
+Total Real Time  :      0.980 +/-      0.980 s
+Total User Time  :      0.980 +/-      0.980 s
+Total System Time:      0.000 +/-      0.000 s
+Total Idle Time  :      0.000 +/-      0.000 s
+----- 3.DeleteOld------------- :                              ( n=1 )
+Total Real Time  :      0.100 +/-      0.100 s
+Total User Time  :      0.110 +/-      0.110 s
+Total System Time:      0.000 +/-      0.000 s
+Total Idle Time  :     -0.010 +/-     -0.010 s
+----- 4.FillIterator---------- :                              ( n=1 )
+Total Real Time  :      0.010 +/-      0.010 s
+Total User Time  :      0.000 +/-      0.000 s
+Total System Time:      0.000 +/-      0.000 s
+Total Idle Time  :      0.010 +/-      0.010 s
+----- TOTAL BrowseObjInTag---- :                              ( n=1 )
+Total Real Time  :      3.650 +/-      3.650 s
+Total User Time  :      3.380 +/-      3.380 s
+Total System Time:      0.140 +/-      0.140 s
+Total Idle Time  :      0.130 +/-      0.130 s
+** reading 100000 objects (150 bytes mixed) **
+read back 10000 objects
+sec total: 3.66011
+obj/s:     2732.16
+RelationalFolder                     Debug    Delete the RelationalFolder for '/myfolder'
+sec total (INCLUDING DELETE): 3.69912
+
+OK (1)
+[OVAL] Cppunit-result =0
+RelationalDatabase                   Info     Delete the RalDatabase for 'oracle://cooldb2;schema=AVALASSI;user=avalassi;password=andrea;dbname=COOLTEST'
+POOL/RelationalPlugins/oracle        Warning  No active transaction to roll back
+RelationalDatabase                   Debug    Delete the RelationalDatabase for 'oracle://cooldb2;schema=AVALASSI;user=avalassi;password=andrea;dbname=COOLTEST'
diff --git a/RelationalCool/tests/PerformanceAV/TestScrollableCursor/notScrollable-time.rh73.1006MB.oracle.prf.ANALYZED b/RelationalCool/tests/PerformanceAV/TestScrollableCursor/notScrollable-time.rh73.1006MB.oracle.prf.ANALYZED
new file mode 100644
index 000000000..0d82221fd
--- /dev/null
+++ b/RelationalCool/tests/PerformanceAV/TestScrollableCursor/notScrollable-time.rh73.1006MB.oracle.prf.ANALYZED
@@ -0,0 +1,239 @@
+
+TKPROF: Release 9.2.0.6.0 - Production on Wed Feb 2 10:33:23 2005
+
+Copyright (c) 1982, 2002, Oracle Corporation.  All rights reserved.
+
+Trace file: notScrollable.trc
+Sort options: exeela  fchcnt  
+********************************************************************************
+count    = number of times OCI procedure was executed
+cpu      = cpu time in seconds executing 
+elapsed  = elapsed time in seconds executing
+disk     = number of physical reads of buffers from disk
+query    = number of buffers gotten for consistent read
+current  = number of buffers gotten in current mode (usually for update)
+rows     = number of rows processed by the fetch or execute call
+********************************************************************************
+
+SELECT "OBJECT_ID", "CHANNEL_ID", "IOV_SINCE", "IOV_UNTIL", "SYS_INSTIME", 
+  "I", "S", "X0", "X1", "X2", "X3", "X4", "X5", "X6", "X7", "X8", "X9", "P" 
+FROM
+ "AVALASSI"."COOLTEST_F0001_IOVS" WHERE "CHANNEL_ID"=:"channel" AND 
+  "IOV_SINCE">=:"since" AND "IOV_UNTIL"<=:"till" ORDER BY "CHANNEL_ID" ASC,
+  "IOV_SINCE" ASC
+
+
+call     count       cpu    elapsed       disk      query    current        rows
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+Parse        1      0.00       0.00          0          0          0           0
+Execute      1      0.00       0.00          0          0          0           0
+Fetch      100      0.15       0.17          0        852          0       10000
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+total      102      0.15       0.17          0        852          0       10000
+
+Misses in library cache during parse: 0
+Optimizer goal: CHOOSE
+Parsing user id: 25  
+
+Rows     Row Source Operation
+-------  ---------------------------------------------------
+  10000  TABLE ACCESS BY INDEX ROWID COOLTEST_F0001_IOVS 
+  10000   INDEX RANGE SCAN COOLTEST_F0001_IOVS_CSU_3INDX (object id 8142)
+
+
+Elapsed times include waiting on following events:
+  Event waited on                             Times   Max. Wait  Total Waited
+  ----------------------------------------   Waited  ----------  ------------
+  SQL*Net message to client                     100        0.00          0.00
+  SQL*Net more data to client                   595        0.00          0.01
+  SQL*Net message from client                   100        0.02          2.30
+********************************************************************************
+
+SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", 
+  "NODE_ISLEAF", "NODE_INSTIME", "FOLDER_PAYLOADSPEC", "FOLDER_VERSIONING", 
+  "FOLDER_IOVTABLENAME" 
+FROM
+ "AVALASSI"."COOLTEST_FOLDERS" WHERE "NODE_FULLPATH"=:"fullName"
+
+
+call     count       cpu    elapsed       disk      query    current        rows
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+Parse        1      0.00       0.00          0          0          0           0
+Execute      1      0.00       0.00          0          0          0           0
+Fetch        2      0.00       0.00          0          2          0           1
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+total        4      0.00       0.00          0          2          0           1
+
+Misses in library cache during parse: 0
+Optimizer goal: CHOOSE
+Parsing user id: 25  
+
+Rows     Row Source Operation
+-------  ---------------------------------------------------
+      1  TABLE ACCESS BY INDEX ROWID COOLTEST_FOLDERS 
+      1   INDEX RANGE SCAN COOLTEST_FOLDERS_FULN_1INDX (object id 8136)
+
+
+Elapsed times include waiting on following events:
+  Event waited on                             Times   Max. Wait  Total Waited
+  ----------------------------------------   Waited  ----------  ------------
+  SQL*Net message to client                       2        0.00          0.00
+  SQL*Net message from client                     2        0.00          0.00
+********************************************************************************
+
+SELECT TABLE_NAME 
+FROM
+ ALL_TABLES WHERE OWNER = 'AVALASSI'
+
+
+call     count       cpu    elapsed       disk      query    current        rows
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+Parse        1      0.00       0.00          0          0          0           0
+Execute      1      0.00       0.00          0          0          0           0
+Fetch        1      0.00       0.00          0        122          0           8
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+total        3      0.00       0.00          0        122          0           8
+
+Misses in library cache during parse: 0
+Optimizer goal: CHOOSE
+Parsing user id: 25  
+
+Rows     Row Source Operation
+-------  ---------------------------------------------------
+      8  FILTER  
+      8   NESTED LOOPS  
+      8    NESTED LOOPS OUTER 
+      8     NESTED LOOPS OUTER 
+      8      NESTED LOOPS OUTER 
+      8       NESTED LOOPS OUTER 
+      8        NESTED LOOPS  
+     16         NESTED LOOPS  
+      1          TABLE ACCESS BY INDEX ROWID USER$ 
+      1           INDEX UNIQUE SCAN I_USER1 (object id 44)
+     16          TABLE ACCESS BY INDEX ROWID OBJ$ 
+     16           INDEX RANGE SCAN I_OBJ2 (object id 37)
+      8         TABLE ACCESS CLUSTER TAB$ 
+      8          INDEX UNIQUE SCAN I_OBJ# (object id 3)
+      8        TABLE ACCESS BY INDEX ROWID OBJ$ 
+      8         INDEX UNIQUE SCAN I_OBJ1 (object id 36)
+      0       INDEX UNIQUE SCAN I_OBJ1 (object id 36)
+      8      TABLE ACCESS CLUSTER USER$ 
+      8       INDEX UNIQUE SCAN I_USER# (object id 11)
+      8     TABLE ACCESS CLUSTER SEG$ 
+      8      INDEX UNIQUE SCAN I_FILE#_BLOCK# (object id 9)
+      8    TABLE ACCESS CLUSTER TS$ 
+      8     INDEX UNIQUE SCAN I_TS# (object id 7)
+      0   NESTED LOOPS  
+      0    FIXED TABLE FULL X$KZSRO 
+      0    INDEX RANGE SCAN I_OBJAUTH2 (object id 109)
+      0   FIXED TABLE FULL X$KZSPR 
+
+
+Elapsed times include waiting on following events:
+  Event waited on                             Times   Max. Wait  Total Waited
+  ----------------------------------------   Waited  ----------  ------------
+  SQL*Net message to client                       1        0.00          0.00
+  SQL*Net message from client                     1        0.00          0.00
+********************************************************************************
+
+alter session set events '10046 trace name context forever, level 12'
+
+
+call     count       cpu    elapsed       disk      query    current        rows
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+Parse        0      0.00       0.00          0          0          0           0
+Execute      1      0.00       0.00          0          0          0           0
+Fetch        0      0.00       0.00          0          0          0           0
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+total        1      0.00       0.00          0          0          0           0
+
+Misses in library cache during parse: 0
+Optimizer goal: CHOOSE
+Parsing user id: 25  
+
+Elapsed times include waiting on following events:
+  Event waited on                             Times   Max. Wait  Total Waited
+  ----------------------------------------   Waited  ----------  ------------
+  SQL*Net message to client                       1        0.00          0.00
+  SQL*Net message from client                     1        0.00          0.00
+********************************************************************************
+
+SELECT "DB_ATTRIBUTE_NAME", "DB_ATTRIBUTE_VALUE" 
+FROM
+ "AVALASSI"."COOLTEST_DB_ATTRIBUTES"
+
+
+call     count       cpu    elapsed       disk      query    current        rows
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+Parse        1      0.00       0.00          0          0          0           0
+Execute      1      0.00       0.00          0          0          0           0
+Fetch        2      0.00       0.00          0          8          0           2
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+total        4      0.00       0.00          0          8          0           2
+
+Misses in library cache during parse: 0
+Optimizer goal: CHOOSE
+Parsing user id: 25  
+
+Rows     Row Source Operation
+-------  ---------------------------------------------------
+      2  TABLE ACCESS FULL COOLTEST_DB_ATTRIBUTES 
+
+
+Elapsed times include waiting on following events:
+  Event waited on                             Times   Max. Wait  Total Waited
+  ----------------------------------------   Waited  ----------  ------------
+  SQL*Net message to client                       2        0.00          0.00
+  SQL*Net message from client                     2        0.00          0.00
+
+
+
+********************************************************************************
+
+OVERALL TOTALS FOR ALL NON-RECURSIVE STATEMENTS
+
+call     count       cpu    elapsed       disk      query    current        rows
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+Parse        4      0.00       0.00          0          0          0           0
+Execute      5      0.00       0.00          0          0          0           0
+Fetch      105      0.15       0.17          0        984          0       10011
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+total      114      0.15       0.18          0        984          0       10011
+
+Misses in library cache during parse: 0
+
+Elapsed times include waiting on following events:
+  Event waited on                             Times   Max. Wait  Total Waited
+  ----------------------------------------   Waited  ----------  ------------
+  SQL*Net message to client                     118        0.00          0.00
+  SQL*Net message from client                   118        1.10          4.41
+  SQL*Net more data to client                   596        0.00          0.01
+
+
+OVERALL TOTALS FOR ALL RECURSIVE STATEMENTS
+
+call     count       cpu    elapsed       disk      query    current        rows
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+Parse        0      0.00       0.00          0          0          0           0
+Execute      0      0.00       0.00          0          0          0           0
+Fetch        0      0.00       0.00          0          0          0           0
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+total        0      0.00       0.00          0          0          0           0
+
+Misses in library cache during parse: 0
+
+    5  user  SQL statements in session.
+    0  internal SQL statements in session.
+    5  SQL statements in session.
+********************************************************************************
+Trace file: notScrollable.trc
+Trace file compatibility: 9.02.00
+Sort options: exeela  fchcnt  
+       1  session in tracefile.
+       5  user  SQL statements in trace file.
+       0  internal SQL statements in trace file.
+       5  SQL statements in trace file.
+       5  unique SQL statements in trace file.
+    1035  lines in trace file.
+
+
diff --git a/RelationalCool/tests/PerformanceAV/TestScrollableCursor/scrollable-memory.rh73.1006MB.oracle.out.ANALYZED b/RelationalCool/tests/PerformanceAV/TestScrollableCursor/scrollable-memory.rh73.1006MB.oracle.out.ANALYZED
new file mode 100644
index 000000000..85df71f55
--- /dev/null
+++ b/RelationalCool/tests/PerformanceAV/TestScrollableCursor/scrollable-memory.rh73.1006MB.oracle.out.ANALYZED
@@ -0,0 +1,110 @@
+Property Catalogue: level[Info] Adding property: OutputLevel = 2 in scope "SEAL/Services/MessageService"
+Property Catalogue: level[Info] Adding property: Format =  "%-36s %-8s %s" in scope "SEAL/Services/MessageService"
+MessageService callback    Debug MessageService output level changed to Debug
+ConfigurationService    Debug Setting property: "Format" to value " "%-36s %-8s %s"" in scope "SEAL/Services/MessageService"
+POOL/Services/RelationalService      Info     Found plugin for RDBMS technology "mysql" with implementation "odbc"
+POOL/Services/RelationalService      Info     Found plugin for RDBMS technology "oracle" with native implementation
+POOL/Services/RelationalService      Info     Default implementation for RDBMS technology "mysql" is "odbc"
+POOL/Services/RelationalService      Info     Default implementation for RDBMS technology "oracle" is native
+RelationalDatabase                   Debug    Instantiate a RelationalDatabase for 'oracle://cooldb2;schema=AVALASSI;user=avalassi;password=andrea;dbname=COOLTEST'
+RelationalDatabase                   Info     Instantiate a RalDatabase for 'oracle://cooldb2;schema=AVALASSI;user=avalassi;password=andrea;dbname=COOLTEST'
+POOL/RelationalPlugins/oracle        Info     Connected to a server running Oracle version 9.2.0.6.0
+POOL/RelationalPlugins/oracle        Warning  Environment variable RAL_SQLTRACE is set: enable SQL_TRACE
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "alter session set events '10046 trace name context forever, level 12'"
+POOL/RelationalPlugins/oracle        Warning  SQL_TRACE enabled
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT TABLE_NAME FROM ALL_TABLES WHERE OWNER = 'AVALASSI'"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT "DB_ATTRIBUTE_NAME", "DB_ATTRIBUTE_VALUE" FROM "AVALASSI"."COOLTEST_DB_ATTRIBUTES""
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_ISLEAF", "NODE_INSTIME", "FOLDER_PAYLOADSPEC", "FOLDER_VERSIONING", "FOLDER_IOVTABLENAME" FROM "AVALASSI"."COOLTEST_FOLDERS" WHERE "NODE_FULLPATH"=:"fullName""
+RelationalFolder                     Debug    Instantiate a RelationalFolder for '/myfolder'
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT "OBJECT_ID", "CHANNEL_ID", "IOV_SINCE", "IOV_UNTIL", "SYS_INSTIME", "I", "S", "X0", "X1", "X2", "X3", "X4", "X5", "X6", "X7", "X8", "X9", "P" FROM "AVALASSI"."COOLTEST_F0001_IOVS" WHERE "CHANNEL_ID"=:"channel" AND "IOV_SINCE">=:"since" AND "IOV_UNTIL"<=:"till" ORDER BY "CHANNEL_ID" ASC,"IOV_SINCE" ASC"
+>>>>>>    Timing Results  <<<<<<<<<< 
+----- 1.PrepareQuery----------- :                              ( n=1 )
+Total Real Time  :      0.000 +/-      0.000 s
+Total User Time  :      0.010 +/-      0.010 s
+Total System Time:      0.000 +/-      0.000 s
+Total Idle Time  :     -0.010 +/-     -0.010 s
+Total VmSize incr:      0.000 +/-      0.000 MB
+Total VmRSS incr :      0.012 +/-      0.012 MB
+----- 2.ProcessQuery----------- :                              ( n=1 )
+Total Real Time  :      0.020 +/-      0.020 s
+Total User Time  :      0.000 +/-      0.000 s
+Total System Time:      0.000 +/-      0.000 s
+Total Idle Time  :      0.020 +/-      0.020 s
+Total VmSize incr:      0.412 +/-      0.412 MB
+Total VmRSS incr :      0.404 +/-      0.404 MB
+----- 3.FetchRows-------------- :                              ( n=10001 )
+Total Real Time  :     10.280 +/-      0.103 s
+Total User Time  :      4.970 +/-      0.050 s
+Total System Time:      1.750 +/-      0.017 s
+Total Idle Time  :      3.580 +/-      0.036 s
+Total VmSize incr:      0.024 +/-      0.000 MB
+Total VmRSS incr :      0.024 +/-      0.000 MB
+----- 4.CopyAttributeList------ :                              ( n=10000 )
+Total Real Time  :      7.930 +/-      0.079 s
+Total User Time  :      6.310 +/-      0.063 s
+Total System Time:      1.710 +/-      0.017 s
+Total Idle Time  :     -0.110 +/-     -0.001 s
+Total VmSize incr:     12.196 +/-      0.122 MB
+Total VmRSS incr :     12.172 +/-      0.122 MB
+----- 5.CloseQuery------------- :                              ( n=1 )
+Total Real Time  :      0.000 +/-      0.000 s
+Total User Time  :      0.000 +/-      0.000 s
+Total System Time:      0.000 +/-      0.000 s
+Total Idle Time  :      0.000 +/-      0.000 s
+Total VmSize incr:      0.000 +/-      0.000 MB
+Total VmRSS incr :      0.000 +/-      0.000 MB
+----- TOTAL FetchObjRowsByVal-- :                              ( n=1 )
+Total Real Time  :     30.560 +/-     30.560 s
+Total User Time  :     20.020 +/-     20.020 s
+Total System Time:      7.020 +/-      7.020 s
+Total Idle Time  :      3.520 +/-      3.520 s
+Total VmSize incr:     12.672 +/-     12.672 MB
+Total VmRSS incr :     12.612 +/-     12.612 MB
+>>>>>>    Timing Results  <<<<<<<<<< 
+----- 1.FetchObjRowsByVal----- :                              ( n=1 )
+Total Real Time  :     30.570 +/-     30.570 s
+Total User Time  :     20.030 +/-     20.030 s
+Total System Time:      7.020 +/-      7.020 s
+Total Idle Time  :      3.520 +/-      3.520 s
+Total VmSize incr:     12.684 +/-     12.684 MB
+Total VmRSS incr :     12.636 +/-     12.636 MB
+----- 2.DecodeRow------------- :                              ( n=1 )
+Total Real Time  :      0.990 +/-      0.990 s
+Total User Time  :      0.990 +/-      0.990 s
+Total System Time:      0.000 +/-      0.000 s
+Total Idle Time  :      0.000 +/-      0.000 s
+Total VmSize incr:      3.040 +/-      3.040 MB
+Total VmRSS incr :      2.980 +/-      2.980 MB
+----- 3.DeleteOld------------- :                              ( n=1 )
+Total Real Time  :      0.110 +/-      0.110 s
+Total User Time  :      0.100 +/-      0.100 s
+Total System Time:      0.000 +/-      0.000 s
+Total Idle Time  :      0.010 +/-      0.010 s
+Total VmSize incr:     -0.132 +/-     -0.132 MB
+Total VmRSS incr :     -0.080 +/-     -0.080 MB
+----- 4.FillIterator---------- :                              ( n=1 )
+Total Real Time  :      0.010 +/-      0.010 s
+Total User Time  :      0.000 +/-      0.000 s
+Total System Time:      0.000 +/-      0.000 s
+Total Idle Time  :      0.010 +/-      0.010 s
+Total VmSize incr:     -0.132 +/-     -0.132 MB
+Total VmRSS incr :     -0.076 +/-     -0.076 MB
+----- TOTAL BrowseObjInTag---- :                              ( n=1 )
+Total Real Time  :     31.680 +/-     31.680 s
+Total User Time  :     21.120 +/-     21.120 s
+Total System Time:      7.020 +/-      7.020 s
+Total Idle Time  :      3.540 +/-      3.540 s
+Total VmSize incr:     15.460 +/-     15.460 MB
+Total VmRSS incr :     15.460 +/-     15.460 MB
+** reading 100000 objects (150 bytes mixed) **
+read back 10000 objects
+sec total: 31.6942
+obj/s:     315.516
+RelationalFolder                     Debug    Delete the RelationalFolder for '/myfolder'
+sec total (INCLUDING DELETE): 31.7334
+
+OK (1)
+[OVAL] Cppunit-result =0
+RelationalDatabase                   Info     Delete the RalDatabase for 'oracle://cooldb2;schema=AVALASSI;user=avalassi;password=andrea;dbname=COOLTEST'
+POOL/RelationalPlugins/oracle        Warning  No active transaction to roll back
+RelationalDatabase                   Debug    Delete the RelationalDatabase for 'oracle://cooldb2;schema=AVALASSI;user=avalassi;password=andrea;dbname=COOLTEST'
diff --git a/RelationalCool/tests/PerformanceAV/TestScrollableCursor/scrollable-time.rh73.1006MB.oracle.out.ANALYZED b/RelationalCool/tests/PerformanceAV/TestScrollableCursor/scrollable-time.rh73.1006MB.oracle.out.ANALYZED
new file mode 100644
index 000000000..3a4968c38
--- /dev/null
+++ b/RelationalCool/tests/PerformanceAV/TestScrollableCursor/scrollable-time.rh73.1006MB.oracle.out.ANALYZED
@@ -0,0 +1,88 @@
+Property Catalogue: level[Info] Adding property: OutputLevel = 2 in scope "SEAL/Services/MessageService"
+Property Catalogue: level[Info] Adding property: Format =  "%-36s %-8s %s" in scope "SEAL/Services/MessageService"
+MessageService callback    Debug MessageService output level changed to Debug
+ConfigurationService    Debug Setting property: "Format" to value " "%-36s %-8s %s"" in scope "SEAL/Services/MessageService"
+POOL/Services/RelationalService      Info     Found plugin for RDBMS technology "mysql" with implementation "odbc"
+POOL/Services/RelationalService      Info     Found plugin for RDBMS technology "oracle" with native implementation
+POOL/Services/RelationalService      Info     Default implementation for RDBMS technology "mysql" is "odbc"
+POOL/Services/RelationalService      Info     Default implementation for RDBMS technology "oracle" is native
+RelationalDatabase                   Debug    Instantiate a RelationalDatabase for 'oracle://cooldb2;schema=AVALASSI;user=avalassi;password=andrea;dbname=COOLTEST'
+RelationalDatabase                   Info     Instantiate a RalDatabase for 'oracle://cooldb2;schema=AVALASSI;user=avalassi;password=andrea;dbname=COOLTEST'
+POOL/RelationalPlugins/oracle        Info     Connected to a server running Oracle version 9.2.0.6.0
+POOL/RelationalPlugins/oracle        Warning  Environment variable RAL_SQLTRACE is set: enable SQL_TRACE
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "alter session set events '10046 trace name context forever, level 12'"
+POOL/RelationalPlugins/oracle        Warning  SQL_TRACE enabled
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT TABLE_NAME FROM ALL_TABLES WHERE OWNER = 'AVALASSI'"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT "DB_ATTRIBUTE_NAME", "DB_ATTRIBUTE_VALUE" FROM "AVALASSI"."COOLTEST_DB_ATTRIBUTES""
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_ISLEAF", "NODE_INSTIME", "FOLDER_PAYLOADSPEC", "FOLDER_VERSIONING", "FOLDER_IOVTABLENAME" FROM "AVALASSI"."COOLTEST_FOLDERS" WHERE "NODE_FULLPATH"=:"fullName""
+RelationalFolder                     Debug    Instantiate a RelationalFolder for '/myfolder'
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT "OBJECT_ID", "CHANNEL_ID", "IOV_SINCE", "IOV_UNTIL", "SYS_INSTIME", "I", "S", "X0", "X1", "X2", "X3", "X4", "X5", "X6", "X7", "X8", "X9", "P" FROM "AVALASSI"."COOLTEST_F0001_IOVS" WHERE "CHANNEL_ID"=:"channel" AND "IOV_SINCE">=:"since" AND "IOV_UNTIL"<=:"till" ORDER BY "CHANNEL_ID" ASC,"IOV_SINCE" ASC"
+>>>>>>    Timing Results  <<<<<<<<<< 
+----- 1.PrepareQuery----------- :                              ( n=1 )
+Total Real Time  :      0.000 +/-      0.000 s
+Total User Time  :      0.000 +/-      0.000 s
+Total System Time:      0.000 +/-      0.000 s
+Total Idle Time  :      0.000 +/-      0.000 s
+----- 2.ProcessQuery----------- :                              ( n=1 )
+Total Real Time  :      0.010 +/-      0.010 s
+Total User Time  :      0.010 +/-      0.010 s
+Total System Time:      0.000 +/-      0.000 s
+Total Idle Time  :      0.000 +/-      0.000 s
+----- 3.FetchRows-------------- :                              ( n=10001 )
+Total Real Time  :      3.760 +/-      0.038 s
+Total User Time  :      0.590 +/-      0.006 s
+Total System Time:      0.110 +/-      0.001 s
+Total Idle Time  :      3.020 +/-      0.030 s
+----- 4.CopyAttributeList------ :                              ( n=10000 )
+Total Real Time  :      1.860 +/-      0.019 s
+Total User Time  :      1.600 +/-      0.016 s
+Total System Time:      0.050 +/-      0.001 s
+Total Idle Time  :      0.220 +/-      0.002 s
+----- 5.CloseQuery------------- :                              ( n=1 )
+Total Real Time  :      0.000 +/-      0.000 s
+Total User Time  :      0.000 +/-      0.000 s
+Total System Time:      0.000 +/-      0.000 s
+Total Idle Time  :      0.000 +/-      0.000 s
+----- TOTAL FetchObjRowsByVal-- :                              ( n=1 )
+Total Real Time  :      5.740 +/-      5.740 s
+Total User Time  :      2.270 +/-      2.270 s
+Total System Time:      0.170 +/-      0.170 s
+Total Idle Time  :      3.300 +/-      3.300 s
+>>>>>>    Timing Results  <<<<<<<<<< 
+----- 1.FetchObjRowsByVal----- :                              ( n=1 )
+Total Real Time  :      5.740 +/-      5.740 s
+Total User Time  :      2.280 +/-      2.280 s
+Total System Time:      0.170 +/-      0.170 s
+Total Idle Time  :      3.290 +/-      3.290 s
+----- 2.DecodeRow------------- :                              ( n=1 )
+Total Real Time  :      1.000 +/-      1.000 s
+Total User Time  :      0.990 +/-      0.990 s
+Total System Time:      0.000 +/-      0.000 s
+Total Idle Time  :      0.010 +/-      0.010 s
+----- 3.DeleteOld------------- :                              ( n=1 )
+Total Real Time  :      0.110 +/-      0.110 s
+Total User Time  :      0.100 +/-      0.100 s
+Total System Time:      0.000 +/-      0.000 s
+Total Idle Time  :      0.010 +/-      0.010 s
+----- 4.FillIterator---------- :                              ( n=1 )
+Total Real Time  :      0.000 +/-      0.000 s
+Total User Time  :      0.010 +/-      0.010 s
+Total System Time:      0.000 +/-      0.000 s
+Total Idle Time  :     -0.010 +/-     -0.010 s
+----- TOTAL BrowseObjInTag---- :                              ( n=1 )
+Total Real Time  :      6.850 +/-      6.850 s
+Total User Time  :      3.380 +/-      3.380 s
+Total System Time:      0.170 +/-      0.170 s
+Total Idle Time  :      3.300 +/-      3.300 s
+** reading 100000 objects (150 bytes mixed) **
+read back 10000 objects
+sec total: 6.86195
+obj/s:     1457.31
+RelationalFolder                     Debug    Delete the RelationalFolder for '/myfolder'
+sec total (INCLUDING DELETE): 6.90321
+
+OK (1)
+[OVAL] Cppunit-result =0
+RelationalDatabase                   Info     Delete the RalDatabase for 'oracle://cooldb2;schema=AVALASSI;user=avalassi;password=andrea;dbname=COOLTEST'
+POOL/RelationalPlugins/oracle        Warning  No active transaction to roll back
+RelationalDatabase                   Debug    Delete the RelationalDatabase for 'oracle://cooldb2;schema=AVALASSI;user=avalassi;password=andrea;dbname=COOLTEST'
diff --git a/RelationalCool/tests/PerformanceAV/TestScrollableCursor/scrollable-time.rh73.1006MB.oracle.prf.ANALYZED b/RelationalCool/tests/PerformanceAV/TestScrollableCursor/scrollable-time.rh73.1006MB.oracle.prf.ANALYZED
new file mode 100644
index 000000000..550117029
--- /dev/null
+++ b/RelationalCool/tests/PerformanceAV/TestScrollableCursor/scrollable-time.rh73.1006MB.oracle.prf.ANALYZED
@@ -0,0 +1,239 @@
+
+TKPROF: Release 9.2.0.6.0 - Production on Wed Feb 2 10:33:29 2005
+
+Copyright (c) 1982, 2002, Oracle Corporation.  All rights reserved.
+
+Trace file: scrollable.trc
+Sort options: exeela  fchcnt  
+********************************************************************************
+count    = number of times OCI procedure was executed
+cpu      = cpu time in seconds executing 
+elapsed  = elapsed time in seconds executing
+disk     = number of physical reads of buffers from disk
+query    = number of buffers gotten for consistent read
+current  = number of buffers gotten in current mode (usually for update)
+rows     = number of rows processed by the fetch or execute call
+********************************************************************************
+
+SELECT "OBJECT_ID", "CHANNEL_ID", "IOV_SINCE", "IOV_UNTIL", "SYS_INSTIME", 
+  "I", "S", "X0", "X1", "X2", "X3", "X4", "X5", "X6", "X7", "X8", "X9", "P" 
+FROM
+ "AVALASSI"."COOLTEST_F0001_IOVS" WHERE "CHANNEL_ID"=:"channel" AND 
+  "IOV_SINCE">=:"since" AND "IOV_UNTIL"<=:"till" ORDER BY "CHANNEL_ID" ASC,
+  "IOV_SINCE" ASC
+
+
+call     count       cpu    elapsed       disk      query    current        rows
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+Parse        1      0.00       0.00          0          0          0           0
+Execute      1      0.00       0.00          0          0          0           0
+Fetch      197      2.99       3.10          0      31647     140447       19604
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+total      199      2.99       3.10          0      31647     140447       19604
+
+Misses in library cache during parse: 0
+Optimizer goal: CHOOSE
+Parsing user id: 25  
+
+Rows     Row Source Operation
+-------  ---------------------------------------------------
+  10000  TABLE ACCESS BY INDEX ROWID COOLTEST_F0001_IOVS 
+  10000   INDEX RANGE SCAN COOLTEST_F0001_IOVS_CSU_3INDX (object id 8142)
+
+
+Elapsed times include waiting on following events:
+  Event waited on                             Times   Max. Wait  Total Waited
+  ----------------------------------------   Waited  ----------  ------------
+  SQL*Net message to client                     197        0.00          0.00
+  SQL*Net more data to client                  1177        0.00          0.04
+  SQL*Net message from client                   197        0.02          2.46
+********************************************************************************
+
+SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", 
+  "NODE_ISLEAF", "NODE_INSTIME", "FOLDER_PAYLOADSPEC", "FOLDER_VERSIONING", 
+  "FOLDER_IOVTABLENAME" 
+FROM
+ "AVALASSI"."COOLTEST_FOLDERS" WHERE "NODE_FULLPATH"=:"fullName"
+
+
+call     count       cpu    elapsed       disk      query    current        rows
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+Parse        1      0.00       0.00          0          0          0           0
+Execute      1      0.00       0.00          0          0          0           0
+Fetch        2      0.00       0.00          0          2          7           1
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+total        4      0.00       0.00          0          2          7           1
+
+Misses in library cache during parse: 0
+Optimizer goal: CHOOSE
+Parsing user id: 25  
+
+Rows     Row Source Operation
+-------  ---------------------------------------------------
+      1  TABLE ACCESS BY INDEX ROWID COOLTEST_FOLDERS 
+      1   INDEX RANGE SCAN COOLTEST_FOLDERS_FULN_1INDX (object id 8136)
+
+
+Elapsed times include waiting on following events:
+  Event waited on                             Times   Max. Wait  Total Waited
+  ----------------------------------------   Waited  ----------  ------------
+  SQL*Net message to client                       2        0.00          0.00
+  SQL*Net message from client                     2        0.00          0.00
+********************************************************************************
+
+SELECT TABLE_NAME 
+FROM
+ ALL_TABLES WHERE OWNER = 'AVALASSI'
+
+
+call     count       cpu    elapsed       disk      query    current        rows
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+Parse        1      0.00       0.00          0          0          0           0
+Execute      1      0.00       0.00          0          0          0           0
+Fetch        1      0.00       0.00          0        122          0           8
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+total        3      0.00       0.00          0        122          0           8
+
+Misses in library cache during parse: 0
+Optimizer goal: CHOOSE
+Parsing user id: 25  
+
+Rows     Row Source Operation
+-------  ---------------------------------------------------
+      8  FILTER  
+      8   NESTED LOOPS  
+      8    NESTED LOOPS OUTER 
+      8     NESTED LOOPS OUTER 
+      8      NESTED LOOPS OUTER 
+      8       NESTED LOOPS OUTER 
+      8        NESTED LOOPS  
+     16         NESTED LOOPS  
+      1          TABLE ACCESS BY INDEX ROWID USER$ 
+      1           INDEX UNIQUE SCAN I_USER1 (object id 44)
+     16          TABLE ACCESS BY INDEX ROWID OBJ$ 
+     16           INDEX RANGE SCAN I_OBJ2 (object id 37)
+      8         TABLE ACCESS CLUSTER TAB$ 
+      8          INDEX UNIQUE SCAN I_OBJ# (object id 3)
+      8        TABLE ACCESS BY INDEX ROWID OBJ$ 
+      8         INDEX UNIQUE SCAN I_OBJ1 (object id 36)
+      0       INDEX UNIQUE SCAN I_OBJ1 (object id 36)
+      8      TABLE ACCESS CLUSTER USER$ 
+      8       INDEX UNIQUE SCAN I_USER# (object id 11)
+      8     TABLE ACCESS CLUSTER SEG$ 
+      8      INDEX UNIQUE SCAN I_FILE#_BLOCK# (object id 9)
+      8    TABLE ACCESS CLUSTER TS$ 
+      8     INDEX UNIQUE SCAN I_TS# (object id 7)
+      0   NESTED LOOPS  
+      0    FIXED TABLE FULL X$KZSRO 
+      0    INDEX RANGE SCAN I_OBJAUTH2 (object id 109)
+      0   FIXED TABLE FULL X$KZSPR 
+
+
+Elapsed times include waiting on following events:
+  Event waited on                             Times   Max. Wait  Total Waited
+  ----------------------------------------   Waited  ----------  ------------
+  SQL*Net message to client                       1        0.00          0.00
+  SQL*Net message from client                     1        0.00          0.00
+********************************************************************************
+
+alter session set events '10046 trace name context forever, level 12'
+
+
+call     count       cpu    elapsed       disk      query    current        rows
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+Parse        0      0.00       0.00          0          0          0           0
+Execute      1      0.00       0.00          0          0          0           0
+Fetch        0      0.00       0.00          0          0          0           0
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+total        1      0.00       0.00          0          0          0           0
+
+Misses in library cache during parse: 0
+Optimizer goal: CHOOSE
+Parsing user id: 25  
+
+Elapsed times include waiting on following events:
+  Event waited on                             Times   Max. Wait  Total Waited
+  ----------------------------------------   Waited  ----------  ------------
+  SQL*Net message to client                       1        0.00          0.00
+  SQL*Net message from client                     1        0.00          0.00
+********************************************************************************
+
+SELECT "DB_ATTRIBUTE_NAME", "DB_ATTRIBUTE_VALUE" 
+FROM
+ "AVALASSI"."COOLTEST_DB_ATTRIBUTES"
+
+
+call     count       cpu    elapsed       disk      query    current        rows
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+Parse        1      0.00       0.00          0          0          0           0
+Execute      1      0.00       0.00          0          0          0           0
+Fetch        3      0.00       0.00          0         10         19           2
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+total        5      0.00       0.00          0         10         19           2
+
+Misses in library cache during parse: 0
+Optimizer goal: CHOOSE
+Parsing user id: 25  
+
+Rows     Row Source Operation
+-------  ---------------------------------------------------
+      2  TABLE ACCESS FULL COOLTEST_DB_ATTRIBUTES 
+
+
+Elapsed times include waiting on following events:
+  Event waited on                             Times   Max. Wait  Total Waited
+  ----------------------------------------   Waited  ----------  ------------
+  SQL*Net message to client                       3        0.00          0.00
+  SQL*Net message from client                     3        0.00          0.00
+
+
+
+********************************************************************************
+
+OVERALL TOTALS FOR ALL NON-RECURSIVE STATEMENTS
+
+call     count       cpu    elapsed       disk      query    current        rows
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+Parse        4      0.00       0.00          0          0          0           0
+Execute      5      0.00       0.00          0          0          0           0
+Fetch      203      2.99       3.10          0      31781     140473       19615
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+total      212      2.99       3.10          0      31781     140473       19615
+
+Misses in library cache during parse: 0
+
+Elapsed times include waiting on following events:
+  Event waited on                             Times   Max. Wait  Total Waited
+  ----------------------------------------   Waited  ----------  ------------
+  SQL*Net message to client                     216        0.00          0.00
+  SQL*Net message from client                   216        1.10          4.57
+  SQL*Net more data to client                  1178        0.00          0.04
+
+
+OVERALL TOTALS FOR ALL RECURSIVE STATEMENTS
+
+call     count       cpu    elapsed       disk      query    current        rows
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+Parse        0      0.00       0.00          0          0          0           0
+Execute      0      0.00       0.00          0          0          0           0
+Fetch        0      0.00       0.00          0          0          0           0
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+total        0      0.00       0.00          0          0          0           0
+
+Misses in library cache during parse: 0
+
+    5  user  SQL statements in session.
+    0  internal SQL statements in session.
+    5  SQL statements in session.
+********************************************************************************
+Trace file: scrollable.trc
+Trace file compatibility: 9.02.00
+Sort options: exeela  fchcnt  
+       1  session in tracefile.
+       5  user  SQL statements in trace file.
+       0  internal SQL statements in trace file.
+       5  SQL statements in trace file.
+       5  unique SQL statements in trace file.
+    1911  lines in trace file.
+
+
diff --git a/RelationalCool/tests/PerformanceAV/TestShareData/doNotShareData-memory.rh73.501MB.oracle.out.ANALYZED b/RelationalCool/tests/PerformanceAV/TestShareData/doNotShareData-memory.rh73.501MB.oracle.out.ANALYZED
new file mode 100644
index 000000000..01ca28da3
--- /dev/null
+++ b/RelationalCool/tests/PerformanceAV/TestShareData/doNotShareData-memory.rh73.501MB.oracle.out.ANALYZED
@@ -0,0 +1,112 @@
+Property Catalogue: level[Info] Adding property: OutputLevel = 2 in scope "SEAL/Services/MessageService"
+Property Catalogue: level[Info] Adding property: Format =  "%-36s %-8s %s" in scope "SEAL/Services/MessageService"
+MessageService callback    Debug MessageService output level changed to Debug
+ConfigurationService    Debug Setting property: "Format" to value " "%-36s %-8s %s"" in scope "SEAL/Services/MessageService"
+POOL/Services/RelationalService      Info     Found plugin for RDBMS technology "mysql" with implementation "odbc"
+POOL/Services/RelationalService      Info     Found plugin for RDBMS technology "oracle" with native implementation
+POOL/Services/RelationalService      Info     Default implementation for RDBMS technology "mysql" is "odbc"
+POOL/Services/RelationalService      Info     Default implementation for RDBMS technology "oracle" is native
+RelationalDatabase                   Debug    Instantiate a RelationalDatabase for 'oracle://cooldb2;schema=AVALASSI;user=avalassi;password=andrea;dbname=COOLTEST'
+RelationalDatabase                   Info     Instantiate a RalDatabase for 'oracle://cooldb2;schema=AVALASSI;user=avalassi;password=andrea;dbname=COOLTEST'
+POOL/RelationalPlugins/oracle        Info     Connected to a server running Oracle version 9.2.0.6.0
+POOL/RelationalPlugins/oracle        Warning  Environment variable RAL_SQLTRACE is set: enable SQL_TRACE
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "alter session set events '10046 trace name context forever, level 12'"
+POOL/RelationalPlugins/oracle        Warning  SQL_TRACE enabled
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT TABLE_NAME FROM ALL_TABLES WHERE OWNER = 'AVALASSI'"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT "DB_ATTRIBUTE_NAME", "DB_ATTRIBUTE_VALUE" FROM "AVALASSI"."COOLTEST_DB_ATTRIBUTES""
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_INSTIME", "FOLDER_PAYLOADSPEC", "FOLDER_VERSIONING", "FOLDER_IOVTABLENAME" FROM "AVALASSI"."COOLTEST_FOLDERS" WHERE "NODE_FULLPATH"=:"fullName""
+RelationalFolder                     Debug    Instantiate a RelationalFolder for '/myfolder'
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT "OBJECT_ID", "CHANNEL_ID", "IOV_SINCE", "IOV_UNTIL", "SYS_INSTIME", "I", "S", "X0", "X1", "X2", "X3", "X4", "X5", "X6", "X7", "X8", "X9", "P" FROM "AVALASSI"."COOLTEST_F0001_IOVS" WHERE "CHANNEL_ID"=:"channel" AND "IOV_SINCE">=:"since" AND "IOV_UNTIL"<=:"till" ORDER BY "CHANNEL_ID" ASC,"IOV_SINCE" ASC"
+>>>>>>    Timing Results  <<<<<<<<<< 
+----- 1.PrepareQuery----------- :                              ( n=1 )
+Total Real Time  :      0.010 +/-      0.010 s
+Total User Time  :      0.010 +/-      0.010 s
+Total System Time:      0.000 +/-      0.000 s
+Total Idle Time  :      0.000 +/-      0.000 s
+Total VmSize incr:      0.000 +/-      0.000 MB
+Total VmRSS incr :      0.004 +/-      0.004 MB
+----- 2.ProcessQuery----------- :                              ( n=1 )
+Total Real Time  :      0.010 +/-      0.010 s
+Total User Time  :      0.000 +/-      0.000 s
+Total System Time:      0.000 +/-      0.000 s
+Total Idle Time  :      0.010 +/-      0.010 s
+Total VmSize incr:      0.404 +/-      0.404 MB
+Total VmRSS incr :      0.408 +/-      0.408 MB
+----- 3.FetchRows-------------- :                              ( n=10001 )
+Total Real Time  :      7.250 +/-      0.072 s
+Total User Time  :      5.120 +/-      0.051 s
+Total System Time:      1.760 +/-      0.018 s
+Total Idle Time  :      0.360 +/-      0.004 s
+Total VmSize incr:      0.172 +/-      0.002 MB
+Total VmRSS incr :      1.540 +/-      0.015 MB
+----- 4.CopyAttributeList------ :                              ( n=10000 )
+Total Real Time  :     11.680 +/-      0.117 s
+Total User Time  :      9.880 +/-      0.099 s
+Total System Time:      1.830 +/-      0.018 s
+Total Idle Time  :     -0.010 +/-     -0.000 s
+Total VmSize incr:     24.504 +/-      0.245 MB
+Total VmRSS incr :     23.788 +/-      0.238 MB
+----- 5.CloseQuery------------- :                              ( n=1 )
+Total Real Time  :      0.000 +/-      0.000 s
+Total User Time  :      0.000 +/-      0.000 s
+Total System Time:      0.000 +/-      0.000 s
+Total Idle Time  :      0.000 +/-      0.000 s
+Total VmSize incr:      0.000 +/-      0.000 MB
+Total VmRSS incr :      0.000 +/-      0.000 MB
+----- TOTAL FetchObjRowsByVal-- :                              ( n=1 )
+Total Real Time  :     31.650 +/-     31.650 s
+Total User Time  :     23.890 +/-     23.890 s
+Total System Time:      7.430 +/-      7.430 s
+Total Idle Time  :      0.330 +/-      0.330 s
+Total VmSize incr:     25.772 +/-     25.772 MB
+Total VmRSS incr :     25.740 +/-     25.740 MB
+>>>>>>    Timing Results  <<<<<<<<<< 
+----- 1.FetchObjRowsByVal----- :                              ( n=1 )
+Total Real Time  :     31.650 +/-     31.650 s
+Total User Time  :     23.900 +/-     23.900 s
+Total System Time:      7.430 +/-      7.430 s
+Total Idle Time  :      0.320 +/-      0.320 s
+Total VmSize incr:     25.784 +/-     25.784 MB
+Total VmRSS incr :     25.756 +/-     25.756 MB
+----- 2.DecodeRow------------- :                              ( n=1 )
+Total Real Time  :      0.950 +/-      0.950 s
+Total User Time  :      0.950 +/-      0.950 s
+Total System Time:      0.000 +/-      0.000 s
+Total Idle Time  :      0.000 +/-      0.000 s
+Total VmSize incr:      3.008 +/-      3.008 MB
+Total VmRSS incr :      2.952 +/-      2.952 MB
+----- 3.DeleteOld------------- :                              ( n=1 )
+Total Real Time  :      0.160 +/-      0.160 s
+Total User Time  :      0.160 +/-      0.160 s
+Total System Time:      0.000 +/-      0.000 s
+Total Idle Time  :      0.000 +/-      0.000 s
+Total VmSize incr:     -0.132 +/-     -0.132 MB
+Total VmRSS incr :     -0.080 +/-     -0.080 MB
+----- 4.FillIterator---------- :                              ( n=1 )
+Total Real Time  :      0.010 +/-      0.010 s
+Total User Time  :      0.010 +/-      0.010 s
+Total System Time:      0.000 +/-      0.000 s
+Total Idle Time  :      0.000 +/-      0.000 s
+Total VmSize incr:      0.028 +/-      0.028 MB
+Total VmRSS incr :      0.076 +/-      0.076 MB
+----- TOTAL BrowseObjInTag---- :                              ( n=1 )
+Total Real Time  :     32.780 +/-     32.780 s
+Total User Time  :     25.020 +/-     25.020 s
+Total System Time:      7.430 +/-      7.430 s
+Total Idle Time  :      0.330 +/-      0.330 s
+Total VmSize incr:     28.688 +/-     28.688 MB
+Total VmRSS incr :     28.704 +/-     28.704 MB
+==> First object: since=0
+==> Last  object: since=9999
+** reading 100000 objects (150 bytes mixed) **
+read back 10000 objects
+sec total: 32.7868
+obj/s:     305.001
+RelationalFolder                     Debug    Delete the RelationalFolder for '/myfolder'
+sec total (INCLUDING DELETE): 32.9312
+
+OK (1)
+[OVAL] Cppunit-result =0
+RelationalDatabase                   Info     Delete the RalDatabase for 'oracle://cooldb2;schema=AVALASSI;user=avalassi;password=andrea;dbname=COOLTEST'
+POOL/RelationalPlugins/oracle        Warning  No active transaction to roll back
+RelationalDatabase                   Debug    Delete the RelationalDatabase for 'oracle://cooldb2;schema=AVALASSI;user=avalassi;password=andrea;dbname=COOLTEST'
diff --git a/RelationalCool/tests/PerformanceAV/TestShareData/doNotShareData-time.rh73.501MB.oracle.out.ANALYZED b/RelationalCool/tests/PerformanceAV/TestShareData/doNotShareData-time.rh73.501MB.oracle.out.ANALYZED
new file mode 100644
index 000000000..bbe0dde5a
--- /dev/null
+++ b/RelationalCool/tests/PerformanceAV/TestShareData/doNotShareData-time.rh73.501MB.oracle.out.ANALYZED
@@ -0,0 +1,90 @@
+Property Catalogue: level[Info] Adding property: OutputLevel = 2 in scope "SEAL/Services/MessageService"
+Property Catalogue: level[Info] Adding property: Format =  "%-36s %-8s %s" in scope "SEAL/Services/MessageService"
+MessageService callback    Debug MessageService output level changed to Debug
+ConfigurationService    Debug Setting property: "Format" to value " "%-36s %-8s %s"" in scope "SEAL/Services/MessageService"
+POOL/Services/RelationalService      Info     Found plugin for RDBMS technology "mysql" with implementation "odbc"
+POOL/Services/RelationalService      Info     Found plugin for RDBMS technology "oracle" with native implementation
+POOL/Services/RelationalService      Info     Default implementation for RDBMS technology "mysql" is "odbc"
+POOL/Services/RelationalService      Info     Default implementation for RDBMS technology "oracle" is native
+RelationalDatabase                   Debug    Instantiate a RelationalDatabase for 'oracle://cooldb2;schema=AVALASSI;user=avalassi;password=andrea;dbname=COOLTEST'
+RelationalDatabase                   Info     Instantiate a RalDatabase for 'oracle://cooldb2;schema=AVALASSI;user=avalassi;password=andrea;dbname=COOLTEST'
+POOL/RelationalPlugins/oracle        Info     Connected to a server running Oracle version 9.2.0.6.0
+POOL/RelationalPlugins/oracle        Warning  Environment variable RAL_SQLTRACE is set: enable SQL_TRACE
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "alter session set events '10046 trace name context forever, level 12'"
+POOL/RelationalPlugins/oracle        Warning  SQL_TRACE enabled
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT TABLE_NAME FROM ALL_TABLES WHERE OWNER = 'AVALASSI'"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT "DB_ATTRIBUTE_NAME", "DB_ATTRIBUTE_VALUE" FROM "AVALASSI"."COOLTEST_DB_ATTRIBUTES""
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_INSTIME", "FOLDER_PAYLOADSPEC", "FOLDER_VERSIONING", "FOLDER_IOVTABLENAME" FROM "AVALASSI"."COOLTEST_FOLDERS" WHERE "NODE_FULLPATH"=:"fullName""
+RelationalFolder                     Debug    Instantiate a RelationalFolder for '/myfolder'
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT "OBJECT_ID", "CHANNEL_ID", "IOV_SINCE", "IOV_UNTIL", "SYS_INSTIME", "I", "S", "X0", "X1", "X2", "X3", "X4", "X5", "X6", "X7", "X8", "X9", "P" FROM "AVALASSI"."COOLTEST_F0001_IOVS" WHERE "CHANNEL_ID"=:"channel" AND "IOV_SINCE">=:"since" AND "IOV_UNTIL"<=:"till" ORDER BY "CHANNEL_ID" ASC,"IOV_SINCE" ASC"
+>>>>>>    Timing Results  <<<<<<<<<< 
+----- 1.PrepareQuery----------- :                              ( n=1 )
+Total Real Time  :      0.010 +/-      0.010 s
+Total User Time  :      0.010 +/-      0.010 s
+Total System Time:      0.000 +/-      0.000 s
+Total Idle Time  :      0.000 +/-      0.000 s
+----- 2.ProcessQuery----------- :                              ( n=1 )
+Total Real Time  :      0.000 +/-      0.000 s
+Total User Time  :      0.000 +/-      0.000 s
+Total System Time:      0.000 +/-      0.000 s
+Total Idle Time  :      0.000 +/-      0.000 s
+----- 3.FetchRows-------------- :                              ( n=10001 )
+Total Real Time  :      0.980 +/-      0.010 s
+Total User Time  :      0.620 +/-      0.006 s
+Total System Time:      0.050 +/-      0.000 s
+Total Idle Time  :      0.300 +/-      0.003 s
+----- 4.CopyAttributeList------ :                              ( n=10000 )
+Total Real Time  :      5.560 +/-      0.056 s
+Total User Time  :      5.490 +/-      0.055 s
+Total System Time:      0.130 +/-      0.001 s
+Total Idle Time  :     -0.070 +/-     -0.001 s
+----- 5.CloseQuery------------- :                              ( n=1 )
+Total Real Time  :      0.000 +/-      0.000 s
+Total User Time  :      0.000 +/-      0.000 s
+Total System Time:      0.000 +/-      0.000 s
+Total Idle Time  :      0.000 +/-      0.000 s
+----- TOTAL FetchObjRowsByVal-- :                              ( n=1 )
+Total Real Time  :      6.650 +/-      6.650 s
+Total User Time  :      6.230 +/-      6.230 s
+Total System Time:      0.190 +/-      0.190 s
+Total Idle Time  :      0.230 +/-      0.230 s
+>>>>>>    Timing Results  <<<<<<<<<< 
+----- 1.FetchObjRowsByVal----- :                              ( n=1 )
+Total Real Time  :      6.650 +/-      6.650 s
+Total User Time  :      6.230 +/-      6.230 s
+Total System Time:      0.190 +/-      0.190 s
+Total Idle Time  :      0.230 +/-      0.230 s
+----- 2.DecodeRow------------- :                              ( n=1 )
+Total Real Time  :      0.950 +/-      0.950 s
+Total User Time  :      0.930 +/-      0.930 s
+Total System Time:      0.020 +/-      0.020 s
+Total Idle Time  :      0.000 +/-      0.000 s
+----- 3.DeleteOld------------- :                              ( n=1 )
+Total Real Time  :      0.160 +/-      0.160 s
+Total User Time  :      0.160 +/-      0.160 s
+Total System Time:      0.000 +/-      0.000 s
+Total Idle Time  :      0.000 +/-      0.000 s
+----- 4.FillIterator---------- :                              ( n=1 )
+Total Real Time  :      0.010 +/-      0.010 s
+Total User Time  :      0.010 +/-      0.010 s
+Total System Time:      0.000 +/-      0.000 s
+Total Idle Time  :      0.000 +/-      0.000 s
+----- TOTAL BrowseObjInTag---- :                              ( n=1 )
+Total Real Time  :      7.770 +/-      7.770 s
+Total User Time  :      7.330 +/-      7.330 s
+Total System Time:      0.210 +/-      0.210 s
+Total Idle Time  :      0.230 +/-      0.230 s
+==> First object: since=0
+==> Last  object: since=9999
+** reading 100000 objects (150 bytes mixed) **
+read back 10000 objects
+sec total: 7.77131
+obj/s:     1286.78
+RelationalFolder                     Debug    Delete the RelationalFolder for '/myfolder'
+sec total (INCLUDING DELETE): 7.90669
+
+OK (1)
+[OVAL] Cppunit-result =0
+RelationalDatabase                   Info     Delete the RalDatabase for 'oracle://cooldb2;schema=AVALASSI;user=avalassi;password=andrea;dbname=COOLTEST'
+POOL/RelationalPlugins/oracle        Warning  No active transaction to roll back
+RelationalDatabase                   Debug    Delete the RelationalDatabase for 'oracle://cooldb2;schema=AVALASSI;user=avalassi;password=andrea;dbname=COOLTEST'
diff --git a/RelationalCool/tests/PerformanceAV/TestShareData/doNotShareData-time.rh73.501MB.oracle.prf.ANALYZED b/RelationalCool/tests/PerformanceAV/TestShareData/doNotShareData-time.rh73.501MB.oracle.prf.ANALYZED
new file mode 100644
index 000000000..4c009ece1
--- /dev/null
+++ b/RelationalCool/tests/PerformanceAV/TestShareData/doNotShareData-time.rh73.501MB.oracle.prf.ANALYZED
@@ -0,0 +1,239 @@
+
+TKPROF: Release 9.2.0.6.0 - Production on Tue Feb 1 19:54:46 2005
+
+Copyright (c) 1982, 2002, Oracle Corporation.  All rights reserved.
+
+Trace file: doNotShareData.trc
+Sort options: exeela  fchcnt  
+********************************************************************************
+count    = number of times OCI procedure was executed
+cpu      = cpu time in seconds executing 
+elapsed  = elapsed time in seconds executing
+disk     = number of physical reads of buffers from disk
+query    = number of buffers gotten for consistent read
+current  = number of buffers gotten in current mode (usually for update)
+rows     = number of rows processed by the fetch or execute call
+********************************************************************************
+
+SELECT "OBJECT_ID", "CHANNEL_ID", "IOV_SINCE", "IOV_UNTIL", "SYS_INSTIME", 
+  "I", "S", "X0", "X1", "X2", "X3", "X4", "X5", "X6", "X7", "X8", "X9", "P" 
+FROM
+ "AVALASSI"."COOLTEST_F0001_IOVS" WHERE "CHANNEL_ID"=:"channel" AND 
+  "IOV_SINCE">=:"since" AND "IOV_UNTIL"<=:"till" ORDER BY "CHANNEL_ID" ASC,
+  "IOV_SINCE" ASC
+
+
+call     count       cpu    elapsed       disk      query    current        rows
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+Parse        1      0.00       0.00          0          0          0           0
+Execute      1      0.00       0.00          0          0          0           0
+Fetch      197      3.06       3.02          0      31647     140451       19604
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+total      199      3.06       3.02          0      31647     140451       19604
+
+Misses in library cache during parse: 0
+Optimizer goal: CHOOSE
+Parsing user id: 25  
+
+Rows     Row Source Operation
+-------  ---------------------------------------------------
+  10000  TABLE ACCESS BY INDEX ROWID COOLTEST_F0001_IOVS 
+  10000   INDEX RANGE SCAN COOLTEST_F0001_IOVS_CSU_3INDX (object id 8142)
+
+
+Elapsed times include waiting on following events:
+  Event waited on                             Times   Max. Wait  Total Waited
+  ----------------------------------------   Waited  ----------  ------------
+  SQL*Net message to client                     197        0.00          0.00
+  SQL*Net more data to client                  1177        0.00          0.04
+  SQL*Net message from client                   197        0.06          6.57
+********************************************************************************
+
+SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", 
+  "NODE_ISLEAF", "NODE_INSTIME", "FOLDER_PAYLOADSPEC", "FOLDER_VERSIONING", 
+  "FOLDER_IOVTABLENAME" 
+FROM
+ "AVALASSI"."COOLTEST_FOLDERS" WHERE "NODE_FULLPATH"=:"fullName"
+
+
+call     count       cpu    elapsed       disk      query    current        rows
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+Parse        1      0.00       0.00          0          0          0           0
+Execute      1      0.00       0.00          0          0          0           0
+Fetch        2      0.00       0.00          0          2          7           1
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+total        4      0.00       0.00          0          2          7           1
+
+Misses in library cache during parse: 0
+Optimizer goal: CHOOSE
+Parsing user id: 25  
+
+Rows     Row Source Operation
+-------  ---------------------------------------------------
+      1  TABLE ACCESS BY INDEX ROWID COOLTEST_FOLDERS 
+      1   INDEX RANGE SCAN COOLTEST_FOLDERS_FULN_1INDX (object id 8136)
+
+
+Elapsed times include waiting on following events:
+  Event waited on                             Times   Max. Wait  Total Waited
+  ----------------------------------------   Waited  ----------  ------------
+  SQL*Net message to client                       2        0.00          0.00
+  SQL*Net message from client                     2        0.00          0.00
+********************************************************************************
+
+SELECT TABLE_NAME 
+FROM
+ ALL_TABLES WHERE OWNER = 'AVALASSI'
+
+
+call     count       cpu    elapsed       disk      query    current        rows
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+Parse        1      0.00       0.00          0          0          0           0
+Execute      1      0.00       0.00          0          0          0           0
+Fetch        1      0.00       0.00          0        122          0           8
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+total        3      0.00       0.00          0        122          0           8
+
+Misses in library cache during parse: 0
+Optimizer goal: CHOOSE
+Parsing user id: 25  
+
+Rows     Row Source Operation
+-------  ---------------------------------------------------
+      8  FILTER  
+      8   NESTED LOOPS  
+      8    NESTED LOOPS OUTER 
+      8     NESTED LOOPS OUTER 
+      8      NESTED LOOPS OUTER 
+      8       NESTED LOOPS OUTER 
+      8        NESTED LOOPS  
+     16         NESTED LOOPS  
+      1          TABLE ACCESS BY INDEX ROWID USER$ 
+      1           INDEX UNIQUE SCAN I_USER1 (object id 44)
+     16          TABLE ACCESS BY INDEX ROWID OBJ$ 
+     16           INDEX RANGE SCAN I_OBJ2 (object id 37)
+      8         TABLE ACCESS CLUSTER TAB$ 
+      8          INDEX UNIQUE SCAN I_OBJ# (object id 3)
+      8        TABLE ACCESS BY INDEX ROWID OBJ$ 
+      8         INDEX UNIQUE SCAN I_OBJ1 (object id 36)
+      0       INDEX UNIQUE SCAN I_OBJ1 (object id 36)
+      8      TABLE ACCESS CLUSTER USER$ 
+      8       INDEX UNIQUE SCAN I_USER# (object id 11)
+      8     TABLE ACCESS CLUSTER SEG$ 
+      8      INDEX UNIQUE SCAN I_FILE#_BLOCK# (object id 9)
+      8    TABLE ACCESS CLUSTER TS$ 
+      8     INDEX UNIQUE SCAN I_TS# (object id 7)
+      0   NESTED LOOPS  
+      0    FIXED TABLE FULL X$KZSRO 
+      0    INDEX RANGE SCAN I_OBJAUTH2 (object id 109)
+      0   FIXED TABLE FULL X$KZSPR 
+
+
+Elapsed times include waiting on following events:
+  Event waited on                             Times   Max. Wait  Total Waited
+  ----------------------------------------   Waited  ----------  ------------
+  SQL*Net message to client                       1        0.00          0.00
+  SQL*Net message from client                     1        0.00          0.00
+********************************************************************************
+
+alter session set events '10046 trace name context forever, level 12'
+
+
+call     count       cpu    elapsed       disk      query    current        rows
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+Parse        0      0.00       0.00          0          0          0           0
+Execute      1      0.00       0.00          0          0          0           0
+Fetch        0      0.00       0.00          0          0          0           0
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+total        1      0.00       0.00          0          0          0           0
+
+Misses in library cache during parse: 0
+Optimizer goal: CHOOSE
+Parsing user id: 25  
+
+Elapsed times include waiting on following events:
+  Event waited on                             Times   Max. Wait  Total Waited
+  ----------------------------------------   Waited  ----------  ------------
+  SQL*Net message to client                       1        0.00          0.00
+  SQL*Net message from client                     1        0.00          0.00
+********************************************************************************
+
+SELECT "DB_ATTRIBUTE_NAME", "DB_ATTRIBUTE_VALUE" 
+FROM
+ "AVALASSI"."COOLTEST_DB_ATTRIBUTES"
+
+
+call     count       cpu    elapsed       disk      query    current        rows
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+Parse        1      0.00       0.00          0          0          0           0
+Execute      1      0.00       0.00          0          0          0           0
+Fetch        3      0.00       0.00          0         10         19           2
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+total        5      0.00       0.00          0         10         19           2
+
+Misses in library cache during parse: 0
+Optimizer goal: CHOOSE
+Parsing user id: 25  
+
+Rows     Row Source Operation
+-------  ---------------------------------------------------
+      2  TABLE ACCESS FULL COOLTEST_DB_ATTRIBUTES 
+
+
+Elapsed times include waiting on following events:
+  Event waited on                             Times   Max. Wait  Total Waited
+  ----------------------------------------   Waited  ----------  ------------
+  SQL*Net message to client                       3        0.00          0.00
+  SQL*Net message from client                     3        0.00          0.00
+
+
+
+********************************************************************************
+
+OVERALL TOTALS FOR ALL NON-RECURSIVE STATEMENTS
+
+call     count       cpu    elapsed       disk      query    current        rows
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+Parse        4      0.00       0.00          0          0          0           0
+Execute      5      0.00       0.00          0          0          0           0
+Fetch      203      3.06       3.03          0      31781     140477       19615
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+total      212      3.06       3.03          0      31781     140477       19615
+
+Misses in library cache during parse: 0
+
+Elapsed times include waiting on following events:
+  Event waited on                             Times   Max. Wait  Total Waited
+  ----------------------------------------   Waited  ----------  ------------
+  SQL*Net message to client                     216        0.00          0.00
+  SQL*Net message from client                   216        1.26          8.85
+  SQL*Net more data to client                  1178        0.00          0.04
+
+
+OVERALL TOTALS FOR ALL RECURSIVE STATEMENTS
+
+call     count       cpu    elapsed       disk      query    current        rows
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+Parse        0      0.00       0.00          0          0          0           0
+Execute      0      0.00       0.00          0          0          0           0
+Fetch        0      0.00       0.00          0          0          0           0
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+total        0      0.00       0.00          0          0          0           0
+
+Misses in library cache during parse: 0
+
+    5  user  SQL statements in session.
+    0  internal SQL statements in session.
+    5  SQL statements in session.
+********************************************************************************
+Trace file: doNotShareData.trc
+Trace file compatibility: 9.02.00
+Sort options: exeela  fchcnt  
+       1  session in tracefile.
+       5  user  SQL statements in trace file.
+       0  internal SQL statements in trace file.
+       5  SQL statements in trace file.
+       5  unique SQL statements in trace file.
+    1911  lines in trace file.
+
+
diff --git a/RelationalCool/tests/PerformanceAV/TestShareData/execTestShareData.out.rh73.501MB.oracle.out.ANALYZED b/RelationalCool/tests/PerformanceAV/TestShareData/execTestShareData.out.rh73.501MB.oracle.out.ANALYZED
new file mode 100644
index 000000000..df0b7f12c
--- /dev/null
+++ b/RelationalCool/tests/PerformanceAV/TestShareData/execTestShareData.out.rh73.501MB.oracle.out.ANALYZED
@@ -0,0 +1,5 @@
+3.580u 0.140s 0:05.05 73.6%     0+0k 0+0io 2281pf+0w
+7.660u 0.250s 0:09.21 85.8%     0+0k 0+0io 2286pf+0w
+20.480u 7.570s 0:29.45 95.2%    0+0k 0+0io 2281pf+0w
+25.350u 7.480s 0:34.42 95.3%    0+0k 0+0io 2286pf+0w
+
diff --git a/RelationalCool/tests/PerformanceAV/TestShareData/shareData-memory.rh73.501MB.oracle.out.ANALYZED b/RelationalCool/tests/PerformanceAV/TestShareData/shareData-memory.rh73.501MB.oracle.out.ANALYZED
new file mode 100644
index 000000000..f4038f479
--- /dev/null
+++ b/RelationalCool/tests/PerformanceAV/TestShareData/shareData-memory.rh73.501MB.oracle.out.ANALYZED
@@ -0,0 +1,112 @@
+Property Catalogue: level[Info] Adding property: OutputLevel = 2 in scope "SEAL/Services/MessageService"
+Property Catalogue: level[Info] Adding property: Format =  "%-36s %-8s %s" in scope "SEAL/Services/MessageService"
+MessageService callback    Debug MessageService output level changed to Debug
+ConfigurationService    Debug Setting property: "Format" to value " "%-36s %-8s %s"" in scope "SEAL/Services/MessageService"
+POOL/Services/RelationalService      Info     Found plugin for RDBMS technology "mysql" with implementation "odbc"
+POOL/Services/RelationalService      Info     Found plugin for RDBMS technology "oracle" with native implementation
+POOL/Services/RelationalService      Info     Default implementation for RDBMS technology "mysql" is "odbc"
+POOL/Services/RelationalService      Info     Default implementation for RDBMS technology "oracle" is native
+RelationalDatabase                   Debug    Instantiate a RelationalDatabase for 'oracle://cooldb2;schema=AVALASSI;user=avalassi;password=andrea;dbname=COOLTEST'
+RelationalDatabase                   Info     Instantiate a RalDatabase for 'oracle://cooldb2;schema=AVALASSI;user=avalassi;password=andrea;dbname=COOLTEST'
+POOL/RelationalPlugins/oracle        Info     Connected to a server running Oracle version 9.2.0.6.0
+POOL/RelationalPlugins/oracle        Warning  Environment variable RAL_SQLTRACE is set: enable SQL_TRACE
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "alter session set events '10046 trace name context forever, level 12'"
+POOL/RelationalPlugins/oracle        Warning  SQL_TRACE enabled
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT TABLE_NAME FROM ALL_TABLES WHERE OWNER = 'AVALASSI'"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT "DB_ATTRIBUTE_NAME", "DB_ATTRIBUTE_VALUE" FROM "AVALASSI"."COOLTEST_DB_ATTRIBUTES""
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_INSTIME", "FOLDER_PAYLOADSPEC", "FOLDER_VERSIONING", "FOLDER_IOVTABLENAME" FROM "AVALASSI"."COOLTEST_FOLDERS" WHERE "NODE_FULLPATH"=:"fullName""
+RelationalFolder                     Debug    Instantiate a RelationalFolder for '/myfolder'
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT "OBJECT_ID", "CHANNEL_ID", "IOV_SINCE", "IOV_UNTIL", "SYS_INSTIME", "I", "S", "X0", "X1", "X2", "X3", "X4", "X5", "X6", "X7", "X8", "X9", "P" FROM "AVALASSI"."COOLTEST_F0001_IOVS" WHERE "CHANNEL_ID"=:"channel" AND "IOV_SINCE">=:"since" AND "IOV_UNTIL"<=:"till" ORDER BY "CHANNEL_ID" ASC,"IOV_SINCE" ASC"
+>>>>>>    Timing Results  <<<<<<<<<< 
+----- 1.PrepareQuery----------- :                              ( n=1 )
+Total Real Time  :      0.010 +/-      0.010 s
+Total User Time  :      0.000 +/-      0.000 s
+Total System Time:      0.000 +/-      0.000 s
+Total Idle Time  :      0.010 +/-      0.010 s
+Total VmSize incr:      0.000 +/-      0.000 MB
+Total VmRSS incr :      0.004 +/-      0.004 MB
+----- 2.ProcessQuery----------- :                              ( n=1 )
+Total Real Time  :      0.010 +/-      0.010 s
+Total User Time  :      0.000 +/-      0.000 s
+Total System Time:      0.010 +/-      0.010 s
+Total Idle Time  :      0.000 +/-      0.000 s
+Total VmSize incr:      0.404 +/-      0.404 MB
+Total VmRSS incr :      0.408 +/-      0.408 MB
+----- 3.FetchRows-------------- :                              ( n=10001 )
+Total Real Time  :      7.140 +/-      0.071 s
+Total User Time  :      4.920 +/-      0.049 s
+Total System Time:      1.830 +/-      0.018 s
+Total Idle Time  :      0.370 +/-      0.004 s
+Total VmSize incr:      0.012 +/-      0.000 MB
+Total VmRSS incr :      0.020 +/-      0.000 MB
+----- 4.CopyAttributeList------ :                              ( n=10000 )
+Total Real Time  :      7.730 +/-      0.077 s
+Total User Time  :      5.820 +/-      0.058 s
+Total System Time:      1.900 +/-      0.019 s
+Total Idle Time  :      0.020 +/-      0.000 s
+Total VmSize incr:     12.212 +/-      0.122 MB
+Total VmRSS incr :     12.160 +/-      0.122 MB
+----- 5.CloseQuery------------- :                              ( n=1 )
+Total Real Time  :      0.000 +/-      0.000 s
+Total User Time  :      0.000 +/-      0.000 s
+Total System Time:      0.000 +/-      0.000 s
+Total Idle Time  :      0.000 +/-      0.000 s
+Total VmSize incr:      0.000 +/-      0.000 MB
+Total VmRSS incr :      0.000 +/-      0.000 MB
+----- TOTAL FetchObjRowsByVal-- :                              ( n=1 )
+Total Real Time  :     27.010 +/-     27.010 s
+Total User Time  :     19.220 +/-     19.220 s
+Total System Time:      7.480 +/-      7.480 s
+Total Idle Time  :      0.310 +/-      0.310 s
+Total VmSize incr:     12.824 +/-     12.824 MB
+Total VmRSS incr :     12.596 +/-     12.596 MB
+>>>>>>    Timing Results  <<<<<<<<<< 
+----- 1.FetchObjRowsByVal----- :                              ( n=1 )
+Total Real Time  :     27.010 +/-     27.010 s
+Total User Time  :     19.230 +/-     19.230 s
+Total System Time:      7.480 +/-      7.480 s
+Total Idle Time  :      0.300 +/-      0.300 s
+Total VmSize incr:     12.836 +/-     12.836 MB
+Total VmRSS incr :     12.628 +/-     12.628 MB
+----- 2.DecodeRow------------- :                              ( n=1 )
+Total Real Time  :      0.950 +/-      0.950 s
+Total User Time  :      0.940 +/-      0.940 s
+Total System Time:      0.010 +/-      0.010 s
+Total Idle Time  :      0.000 +/-      0.000 s
+Total VmSize incr:      3.016 +/-      3.016 MB
+Total VmRSS incr :      2.956 +/-      2.956 MB
+----- 3.DeleteOld------------- :                              ( n=1 )
+Total Real Time  :      0.100 +/-      0.100 s
+Total User Time  :      0.100 +/-      0.100 s
+Total System Time:      0.000 +/-      0.000 s
+Total Idle Time  :      0.000 +/-      0.000 s
+Total VmSize incr:     -0.132 +/-     -0.132 MB
+Total VmRSS incr :     -0.080 +/-     -0.080 MB
+----- 4.FillIterator---------- :                              ( n=1 )
+Total Real Time  :      0.000 +/-      0.000 s
+Total User Time  :      0.000 +/-      0.000 s
+Total System Time:      0.000 +/-      0.000 s
+Total Idle Time  :      0.000 +/-      0.000 s
+Total VmSize incr:     -0.132 +/-     -0.132 MB
+Total VmRSS incr :     -0.076 +/-     -0.076 MB
+----- TOTAL BrowseObjInTag---- :                              ( n=1 )
+Total Real Time  :     28.080 +/-     28.080 s
+Total User Time  :     20.280 +/-     20.280 s
+Total System Time:      7.500 +/-      7.500 s
+Total Idle Time  :      0.300 +/-      0.300 s
+Total VmSize incr:     15.588 +/-     15.588 MB
+Total VmRSS incr :     15.428 +/-     15.428 MB
+==> First object: since=9999
+==> Last  object: since=9999
+** reading 100000 objects (150 bytes mixed) **
+read back 10000 objects
+sec total: 28.0914
+obj/s:     355.981
+RelationalFolder                     Debug    Delete the RelationalFolder for '/myfolder'
+sec total (INCLUDING DELETE): 28.1286
+
+OK (1)
+[OVAL] Cppunit-result =0
+RelationalDatabase                   Info     Delete the RalDatabase for 'oracle://cooldb2;schema=AVALASSI;user=avalassi;password=andrea;dbname=COOLTEST'
+POOL/RelationalPlugins/oracle        Warning  No active transaction to roll back
+RelationalDatabase                   Debug    Delete the RelationalDatabase for 'oracle://cooldb2;schema=AVALASSI;user=avalassi;password=andrea;dbname=COOLTEST'
diff --git a/RelationalCool/tests/PerformanceAV/TestShareData/shareData-time.rh73.501MB.oracle.out.ANALYZED b/RelationalCool/tests/PerformanceAV/TestShareData/shareData-time.rh73.501MB.oracle.out.ANALYZED
new file mode 100644
index 000000000..43c2ea5cd
--- /dev/null
+++ b/RelationalCool/tests/PerformanceAV/TestShareData/shareData-time.rh73.501MB.oracle.out.ANALYZED
@@ -0,0 +1,90 @@
+Property Catalogue: level[Info] Adding property: OutputLevel = 2 in scope "SEAL/Services/MessageService"
+Property Catalogue: level[Info] Adding property: Format =  "%-36s %-8s %s" in scope "SEAL/Services/MessageService"
+MessageService callback    Debug MessageService output level changed to Debug
+ConfigurationService    Debug Setting property: "Format" to value " "%-36s %-8s %s"" in scope "SEAL/Services/MessageService"
+POOL/Services/RelationalService      Info     Found plugin for RDBMS technology "mysql" with implementation "odbc"
+POOL/Services/RelationalService      Info     Found plugin for RDBMS technology "oracle" with native implementation
+POOL/Services/RelationalService      Info     Default implementation for RDBMS technology "mysql" is "odbc"
+POOL/Services/RelationalService      Info     Default implementation for RDBMS technology "oracle" is native
+RelationalDatabase                   Debug    Instantiate a RelationalDatabase for 'oracle://cooldb2;schema=AVALASSI;user=avalassi;password=andrea;dbname=COOLTEST'
+RelationalDatabase                   Info     Instantiate a RalDatabase for 'oracle://cooldb2;schema=AVALASSI;user=avalassi;password=andrea;dbname=COOLTEST'
+POOL/RelationalPlugins/oracle        Info     Connected to a server running Oracle version 9.2.0.6.0
+POOL/RelationalPlugins/oracle        Warning  Environment variable RAL_SQLTRACE is set: enable SQL_TRACE
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "alter session set events '10046 trace name context forever, level 12'"
+POOL/RelationalPlugins/oracle        Warning  SQL_TRACE enabled
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT TABLE_NAME FROM ALL_TABLES WHERE OWNER = 'AVALASSI'"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT "DB_ATTRIBUTE_NAME", "DB_ATTRIBUTE_VALUE" FROM "AVALASSI"."COOLTEST_DB_ATTRIBUTES""
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_INSTIME", "FOLDER_PAYLOADSPEC", "FOLDER_VERSIONING", "FOLDER_IOVTABLENAME" FROM "AVALASSI"."COOLTEST_FOLDERS" WHERE "NODE_FULLPATH"=:"fullName""
+RelationalFolder                     Debug    Instantiate a RelationalFolder for '/myfolder'
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT "OBJECT_ID", "CHANNEL_ID", "IOV_SINCE", "IOV_UNTIL", "SYS_INSTIME", "I", "S", "X0", "X1", "X2", "X3", "X4", "X5", "X6", "X7", "X8", "X9", "P" FROM "AVALASSI"."COOLTEST_F0001_IOVS" WHERE "CHANNEL_ID"=:"channel" AND "IOV_SINCE">=:"since" AND "IOV_UNTIL"<=:"till" ORDER BY "CHANNEL_ID" ASC,"IOV_SINCE" ASC"
+>>>>>>    Timing Results  <<<<<<<<<< 
+----- 1.PrepareQuery----------- :                              ( n=1 )
+Total Real Time  :      0.000 +/-      0.000 s
+Total User Time  :      0.010 +/-      0.010 s
+Total System Time:      0.000 +/-      0.000 s
+Total Idle Time  :     -0.010 +/-     -0.010 s
+----- 2.ProcessQuery----------- :                              ( n=1 )
+Total Real Time  :      0.010 +/-      0.010 s
+Total User Time  :      0.000 +/-      0.000 s
+Total System Time:      0.010 +/-      0.010 s
+Total Idle Time  :      0.000 +/-      0.000 s
+----- 3.FetchRows-------------- :                              ( n=10001 )
+Total Real Time  :      0.840 +/-      0.008 s
+Total User Time  :      0.460 +/-      0.005 s
+Total System Time:      0.020 +/-      0.000 s
+Total Idle Time  :      0.390 +/-      0.004 s
+----- 4.CopyAttributeList------ :                              ( n=10000 )
+Total Real Time  :      1.640 +/-      0.016 s
+Total User Time  :      1.780 +/-      0.018 s
+Total System Time:      0.040 +/-      0.000 s
+Total Idle Time  :     -0.180 +/-     -0.002 s
+----- 5.CloseQuery------------- :                              ( n=1 )
+Total Real Time  :      0.000 +/-      0.000 s
+Total User Time  :      0.000 +/-      0.000 s
+Total System Time:      0.000 +/-      0.000 s
+Total Idle Time  :      0.000 +/-      0.000 s
+----- TOTAL FetchObjRowsByVal-- :                              ( n=1 )
+Total Real Time  :      2.620 +/-      2.620 s
+Total User Time  :      2.290 +/-      2.290 s
+Total System Time:      0.070 +/-      0.070 s
+Total Idle Time  :      0.260 +/-      0.260 s
+>>>>>>    Timing Results  <<<<<<<<<< 
+----- 1.FetchObjRowsByVal----- :                              ( n=1 )
+Total Real Time  :      2.620 +/-      2.620 s
+Total User Time  :      2.290 +/-      2.290 s
+Total System Time:      0.080 +/-      0.080 s
+Total Idle Time  :      0.250 +/-      0.250 s
+----- 2.DecodeRow------------- :                              ( n=1 )
+Total Real Time  :      0.960 +/-      0.960 s
+Total User Time  :      0.950 +/-      0.950 s
+Total System Time:      0.010 +/-      0.010 s
+Total Idle Time  :      0.000 +/-      0.000 s
+----- 3.DeleteOld------------- :                              ( n=1 )
+Total Real Time  :      0.110 +/-      0.110 s
+Total User Time  :      0.100 +/-      0.100 s
+Total System Time:      0.000 +/-      0.000 s
+Total Idle Time  :      0.010 +/-      0.010 s
+----- 4.FillIterator---------- :                              ( n=1 )
+Total Real Time  :      0.000 +/-      0.000 s
+Total User Time  :      0.010 +/-      0.010 s
+Total System Time:      0.000 +/-      0.000 s
+Total Idle Time  :     -0.010 +/-     -0.010 s
+----- TOTAL BrowseObjInTag---- :                              ( n=1 )
+Total Real Time  :      3.690 +/-      3.690 s
+Total User Time  :      3.350 +/-      3.350 s
+Total System Time:      0.090 +/-      0.090 s
+Total Idle Time  :      0.250 +/-      0.250 s
+==> First object: since=9999
+==> Last  object: since=9999
+** reading 100000 objects (150 bytes mixed) **
+read back 10000 objects
+sec total: 3.69822
+obj/s:     2704.01
+RelationalFolder                     Debug    Delete the RelationalFolder for '/myfolder'
+sec total (INCLUDING DELETE): 3.73535
+
+OK (1)
+[OVAL] Cppunit-result =0
+RelationalDatabase                   Info     Delete the RalDatabase for 'oracle://cooldb2;schema=AVALASSI;user=avalassi;password=andrea;dbname=COOLTEST'
+POOL/RelationalPlugins/oracle        Warning  No active transaction to roll back
+RelationalDatabase                   Debug    Delete the RelationalDatabase for 'oracle://cooldb2;schema=AVALASSI;user=avalassi;password=andrea;dbname=COOLTEST'
diff --git a/RelationalCool/tests/PerformanceAV/TestShareData/shareData-time.rh73.501MB.oracle.prf.ANALYZED b/RelationalCool/tests/PerformanceAV/TestShareData/shareData-time.rh73.501MB.oracle.prf.ANALYZED
new file mode 100644
index 000000000..db4dad511
--- /dev/null
+++ b/RelationalCool/tests/PerformanceAV/TestShareData/shareData-time.rh73.501MB.oracle.prf.ANALYZED
@@ -0,0 +1,239 @@
+
+TKPROF: Release 9.2.0.6.0 - Production on Tue Feb 1 19:54:36 2005
+
+Copyright (c) 1982, 2002, Oracle Corporation.  All rights reserved.
+
+Trace file: shareData.trc
+Sort options: exeela  fchcnt  
+********************************************************************************
+count    = number of times OCI procedure was executed
+cpu      = cpu time in seconds executing 
+elapsed  = elapsed time in seconds executing
+disk     = number of physical reads of buffers from disk
+query    = number of buffers gotten for consistent read
+current  = number of buffers gotten in current mode (usually for update)
+rows     = number of rows processed by the fetch or execute call
+********************************************************************************
+
+SELECT "OBJECT_ID", "CHANNEL_ID", "IOV_SINCE", "IOV_UNTIL", "SYS_INSTIME", 
+  "I", "S", "X0", "X1", "X2", "X3", "X4", "X5", "X6", "X7", "X8", "X9", "P" 
+FROM
+ "AVALASSI"."COOLTEST_F0001_IOVS" WHERE "CHANNEL_ID"=:"channel" AND 
+  "IOV_SINCE">=:"since" AND "IOV_UNTIL"<=:"till" ORDER BY "CHANNEL_ID" ASC,
+  "IOV_SINCE" ASC
+
+
+call     count       cpu    elapsed       disk      query    current        rows
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+Parse        1      0.00       0.00          0          0          0           0
+Execute      1      0.00       0.00          0          0          0           0
+Fetch      197      3.16       3.02          0      31647     140447       19604
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+total      199      3.16       3.02          0      31647     140447       19604
+
+Misses in library cache during parse: 0
+Optimizer goal: CHOOSE
+Parsing user id: 25  
+
+Rows     Row Source Operation
+-------  ---------------------------------------------------
+  10000  TABLE ACCESS BY INDEX ROWID COOLTEST_F0001_IOVS 
+  10000   INDEX RANGE SCAN COOLTEST_F0001_IOVS_CSU_3INDX (object id 8142)
+
+
+Elapsed times include waiting on following events:
+  Event waited on                             Times   Max. Wait  Total Waited
+  ----------------------------------------   Waited  ----------  ------------
+  SQL*Net message to client                     197        0.00          0.00
+  SQL*Net more data to client                  1177        0.00          0.05
+  SQL*Net message from client                   197        0.02          2.49
+********************************************************************************
+
+SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", 
+  "NODE_ISLEAF", "NODE_INSTIME", "FOLDER_PAYLOADSPEC", "FOLDER_VERSIONING", 
+  "FOLDER_IOVTABLENAME" 
+FROM
+ "AVALASSI"."COOLTEST_FOLDERS" WHERE "NODE_FULLPATH"=:"fullName"
+
+
+call     count       cpu    elapsed       disk      query    current        rows
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+Parse        1      0.00       0.00          0          0          0           0
+Execute      1      0.00       0.00          0          0          0           0
+Fetch        2      0.00       0.00          0          2          7           1
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+total        4      0.00       0.00          0          2          7           1
+
+Misses in library cache during parse: 0
+Optimizer goal: CHOOSE
+Parsing user id: 25  
+
+Rows     Row Source Operation
+-------  ---------------------------------------------------
+      1  TABLE ACCESS BY INDEX ROWID COOLTEST_FOLDERS 
+      1   INDEX RANGE SCAN COOLTEST_FOLDERS_FULN_1INDX (object id 8136)
+
+
+Elapsed times include waiting on following events:
+  Event waited on                             Times   Max. Wait  Total Waited
+  ----------------------------------------   Waited  ----------  ------------
+  SQL*Net message to client                       2        0.00          0.00
+  SQL*Net message from client                     2        0.00          0.00
+********************************************************************************
+
+SELECT TABLE_NAME 
+FROM
+ ALL_TABLES WHERE OWNER = 'AVALASSI'
+
+
+call     count       cpu    elapsed       disk      query    current        rows
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+Parse        1      0.00       0.00          0          0          0           0
+Execute      1      0.00       0.00          0          0          0           0
+Fetch        1      0.01       0.00          0        122          0           8
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+total        3      0.01       0.00          0        122          0           8
+
+Misses in library cache during parse: 0
+Optimizer goal: CHOOSE
+Parsing user id: 25  
+
+Rows     Row Source Operation
+-------  ---------------------------------------------------
+      8  FILTER  
+      8   NESTED LOOPS  
+      8    NESTED LOOPS OUTER 
+      8     NESTED LOOPS OUTER 
+      8      NESTED LOOPS OUTER 
+      8       NESTED LOOPS OUTER 
+      8        NESTED LOOPS  
+     16         NESTED LOOPS  
+      1          TABLE ACCESS BY INDEX ROWID USER$ 
+      1           INDEX UNIQUE SCAN I_USER1 (object id 44)
+     16          TABLE ACCESS BY INDEX ROWID OBJ$ 
+     16           INDEX RANGE SCAN I_OBJ2 (object id 37)
+      8         TABLE ACCESS CLUSTER TAB$ 
+      8          INDEX UNIQUE SCAN I_OBJ# (object id 3)
+      8        TABLE ACCESS BY INDEX ROWID OBJ$ 
+      8         INDEX UNIQUE SCAN I_OBJ1 (object id 36)
+      0       INDEX UNIQUE SCAN I_OBJ1 (object id 36)
+      8      TABLE ACCESS CLUSTER USER$ 
+      8       INDEX UNIQUE SCAN I_USER# (object id 11)
+      8     TABLE ACCESS CLUSTER SEG$ 
+      8      INDEX UNIQUE SCAN I_FILE#_BLOCK# (object id 9)
+      8    TABLE ACCESS CLUSTER TS$ 
+      8     INDEX UNIQUE SCAN I_TS# (object id 7)
+      0   NESTED LOOPS  
+      0    FIXED TABLE FULL X$KZSRO 
+      0    INDEX RANGE SCAN I_OBJAUTH2 (object id 109)
+      0   FIXED TABLE FULL X$KZSPR 
+
+
+Elapsed times include waiting on following events:
+  Event waited on                             Times   Max. Wait  Total Waited
+  ----------------------------------------   Waited  ----------  ------------
+  SQL*Net message to client                       1        0.00          0.00
+  SQL*Net message from client                     1        0.00          0.00
+********************************************************************************
+
+alter session set events '10046 trace name context forever, level 12'
+
+
+call     count       cpu    elapsed       disk      query    current        rows
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+Parse        0      0.00       0.00          0          0          0           0
+Execute      1      0.00       0.00          0          0          0           0
+Fetch        0      0.00       0.00          0          0          0           0
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+total        1      0.00       0.00          0          0          0           0
+
+Misses in library cache during parse: 0
+Optimizer goal: CHOOSE
+Parsing user id: 25  
+
+Elapsed times include waiting on following events:
+  Event waited on                             Times   Max. Wait  Total Waited
+  ----------------------------------------   Waited  ----------  ------------
+  SQL*Net message to client                       1        0.00          0.00
+  SQL*Net message from client                     1        0.00          0.00
+********************************************************************************
+
+SELECT "DB_ATTRIBUTE_NAME", "DB_ATTRIBUTE_VALUE" 
+FROM
+ "AVALASSI"."COOLTEST_DB_ATTRIBUTES"
+
+
+call     count       cpu    elapsed       disk      query    current        rows
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+Parse        1      0.00       0.00          0          0          0           0
+Execute      1      0.00       0.00          0          0          0           0
+Fetch        3      0.00       0.00          0         10         19           2
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+total        5      0.00       0.00          0         10         19           2
+
+Misses in library cache during parse: 0
+Optimizer goal: CHOOSE
+Parsing user id: 25  
+
+Rows     Row Source Operation
+-------  ---------------------------------------------------
+      2  TABLE ACCESS FULL COOLTEST_DB_ATTRIBUTES 
+
+
+Elapsed times include waiting on following events:
+  Event waited on                             Times   Max. Wait  Total Waited
+  ----------------------------------------   Waited  ----------  ------------
+  SQL*Net message to client                       3        0.00          0.00
+  SQL*Net message from client                     3        0.00          0.00
+
+
+
+********************************************************************************
+
+OVERALL TOTALS FOR ALL NON-RECURSIVE STATEMENTS
+
+call     count       cpu    elapsed       disk      query    current        rows
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+Parse        4      0.00       0.00          0          0          0           0
+Execute      5      0.00       0.00          0          0          0           0
+Fetch      203      3.17       3.03          0      31781     140473       19615
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+total      212      3.17       3.03          0      31781     140473       19615
+
+Misses in library cache during parse: 0
+
+Elapsed times include waiting on following events:
+  Event waited on                             Times   Max. Wait  Total Waited
+  ----------------------------------------   Waited  ----------  ------------
+  SQL*Net message to client                     216        0.00          0.00
+  SQL*Net message from client                   216        1.10          4.61
+  SQL*Net more data to client                  1178        0.00          0.05
+
+
+OVERALL TOTALS FOR ALL RECURSIVE STATEMENTS
+
+call     count       cpu    elapsed       disk      query    current        rows
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+Parse        0      0.00       0.00          0          0          0           0
+Execute      0      0.00       0.00          0          0          0           0
+Fetch        0      0.00       0.00          0          0          0           0
+------- ------  -------- ---------- ---------- ---------- ----------  ----------
+total        0      0.00       0.00          0          0          0           0
+
+Misses in library cache during parse: 0
+
+    5  user  SQL statements in session.
+    0  internal SQL statements in session.
+    5  SQL statements in session.
+********************************************************************************
+Trace file: shareData.trc
+Trace file compatibility: 9.02.00
+Sort options: exeela  fchcnt  
+       1  session in tracefile.
+       5  user  SQL statements in trace file.
+       0  internal SQL statements in trace file.
+       5  SQL statements in trace file.
+       5  unique SQL statements in trace file.
+    1911  lines in trace file.
+
+
diff --git a/RelationalCool/tests/PerformanceAV/execTestAttributeValueAccessor.csh b/RelationalCool/tests/PerformanceAV/execTestAttributeValueAccessor.csh
new file mode 100755
index 000000000..a351d939d
--- /dev/null
+++ b/RelationalCool/tests/PerformanceAV/execTestAttributeValueAccessor.csh
@@ -0,0 +1,53 @@
+#! /bin/csh -f
+
+set theOS = `more /etc/redhat-release`
+if ( "$theOS" == "Red Hat Linux release 7.3 (Valhalla)" ) then
+  set theOS = rh73
+else if ( "$theOS" == "Scientific Linux CERN release 3.0.3 (SL)" ) then
+  set theOS = slc3
+else
+  echo "Unknown OS"; exit 1
+endif
+
+set theMem = `more /proc/meminfo|grep MemTotal|awk '{print int($2/1024) "MB"}'`
+
+set theDB = `echo $COOLTESTDB | awk '{print substr($1,0,index($1,"://")-1)}'`
+
+###set out = $theOS.$theMem.$theDB.out
+set out = $theOS.$theMem.$theDB.out.ANALYZED
+
+unsetenv POOL_ORA_SQL_TRACE
+###setenv POOL_ORA_SQL_TRACE ON
+
+\rm TestAttributeValueAccessor/*$out
+setenv COOL_RALDATABASE_USETIMER ON
+unsetenv COOL_RALDATABASE_TESTNEWCOPY
+unsetenv COOL_RALDATABASE_RALONLY
+
+unsetenv COOL_RALDATABASE_DONOTUSEAVACCESSOR
+unsetenv COOL_COOLCHRONO_PROCMEMORY
+time unitTest_RelationalCool_PerformanceAV \
+    >& TestAttributeValueAccessor/useAccessor-time.$out
+
+setenv COOL_RALDATABASE_DONOTUSEAVACCESSOR ON
+unsetenv COOL_COOLCHRONO_PROCMEMORY
+time unitTest_RelationalCool_PerformanceAV \
+    >& TestAttributeValueAccessor/doNotUseAccessor-time.$out
+
+tkdiff TestAttributeValueAccessor/useAccessor-time.$out \
+    TestAttributeValueAccessor/doNotUseAccessor-time.$out &
+
+###exit 1
+
+unsetenv COOL_RALDATABASE_DONOTUSEAVACCESSOR
+setenv COOL_COOLCHRONO_PROCMEMORY ON
+time unitTest_RelationalCool_PerformanceAV \
+    >& TestAttributeValueAccessor/useAccessor-memory.$out
+
+setenv COOL_RALDATABASE_DONOTUSEAVACCESSOR ON
+setenv COOL_COOLCHRONO_PROCMEMORY ON
+time unitTest_RelationalCool_PerformanceAV \
+    >& TestAttributeValueAccessor/doNotUseAccessor-memory.$out
+
+tkdiff TestAttributeValueAccessor/useAccessor-memory.$out \
+    TestAttributeValueAccessor/doNotUseAccessor-memory.$out &
diff --git a/RelationalCool/tests/PerformanceAV/execTestNewCopy.csh b/RelationalCool/tests/PerformanceAV/execTestNewCopy.csh
new file mode 100755
index 000000000..e19887aca
--- /dev/null
+++ b/RelationalCool/tests/PerformanceAV/execTestNewCopy.csh
@@ -0,0 +1,38 @@
+#! /bin/csh -f
+
+set theOS = `more /etc/redhat-release`
+if ( "$theOS" == "Red Hat Linux release 7.3 (Valhalla)" ) then
+  set theOS = rh73
+else if ( "$theOS" == "Scientific Linux CERN release 3.0.3 (SL)" ) then
+  set theOS = slc3
+else
+  echo "Unknown OS"; exit 1
+endif
+
+set theMem = `more /proc/meminfo|grep MemTotal|awk '{print int($2/1024) "MB"}'`
+
+set out = $theOS.$theMem.out
+
+\rm TestNewCopy/*$out
+unsetenv COOL_RALDATABASE_TESTRALONLY
+
+unsetenv COOL_RALDATABASE_TESTNEWCOPY
+unsetenv COOL_COOLCHRONO_PROCMEMORY
+time unitTest_RelationalCool_PerformanceAV >& TestNewCopy/oldCopy-time.$out
+
+setenv COOL_RALDATABASE_TESTNEWCOPY ON
+unsetenv COOL_COOLCHRONO_PROCMEMORY
+time unitTest_RelationalCool_PerformanceAV >& TestNewCopy/newCopy-time.$out
+
+tkdiff TestNewCopy/oldCopy-time.$out TestNewCopy/newCopy-time.$out &
+
+unsetenv COOL_RALDATABASE_TESTNEWCOPY
+setenv COOL_COOLCHRONO_PROCMEMORY ON
+time unitTest_RelationalCool_PerformanceAV >& TestNewCopy/oldCopy-memory.$out
+
+setenv COOL_RALDATABASE_TESTNEWCOPY ON
+setenv COOL_COOLCHRONO_PROCMEMORY ON
+time unitTest_RelationalCool_PerformanceAV >& TestNewCopy/newCopy-memory.$out
+
+tkdiff TestNewCopy/oldCopy-memory.$out TestNewCopy/newCopy-memory.$out &
+
diff --git a/RelationalCool/tests/PerformanceAV/execTestRalOnly.csh b/RelationalCool/tests/PerformanceAV/execTestRalOnly.csh
new file mode 100755
index 000000000..a5836206e
--- /dev/null
+++ b/RelationalCool/tests/PerformanceAV/execTestRalOnly.csh
@@ -0,0 +1,46 @@
+#! /bin/csh -f
+
+set theOS = `more /etc/redhat-release`
+if ( "$theOS" == "Red Hat Linux release 7.3 (Valhalla)" ) then
+  set theOS = rh73
+else if ( "$theOS" == "Scientific Linux CERN release 3.0.3 (SL)" ) then
+  set theOS = slc3
+else
+  echo "Unknown OS"; exit 1
+endif
+
+set theMem = `more /proc/meminfo|grep MemTotal|awk '{print int($2/1024) "MB"}'`
+
+set theDB = `echo $COOLTESTDB | awk '{print substr($1,0,index($1,"://")-1)}'`
+
+set out = $theOS.$theMem.$theDB.out
+###set out = $theOS.$theMem.$theDB.out.ANALYZED
+
+unsetenv POOL_ORA_SQL_TRACE
+###setenv POOL_ORA_SQL_TRACE ON
+
+\rm TestRalOnly/*$out
+unsetenv COOL_RALDATABASE_TESTNEWCOPY
+
+unsetenv COOL_COOLCHRONO_PROCMEMORY
+unsetenv COOL_RALDATABASE_RALONLY
+time unitTest_RelationalCool_PerformanceAV >& TestRalOnly/withCool-time.$out
+
+unsetenv COOL_COOLCHRONO_PROCMEMORY
+setenv COOL_RALDATABASE_RALONLY ON
+time unitTest_RelationalCool_PerformanceAV >& TestRalOnly/ralOnly-time.$out
+
+tkdiff TestRalOnly/withCool-time.$out TestRalOnly/ralOnly-time.$out &
+
+###exit 1
+
+setenv COOL_COOLCHRONO_PROCMEMORY ON
+unsetenv COOL_RALDATABASE_RALONLY
+time unitTest_RelationalCool_PerformanceAV >& TestRalOnly/withCool-memory.$out
+
+setenv COOL_COOLCHRONO_PROCMEMORY ON
+setenv COOL_RALDATABASE_RALONLY ON
+time unitTest_RelationalCool_PerformanceAV >& TestRalOnly/ralOnly-memory.$out
+
+tkdiff TestRalOnly/withCool-memory.$out TestRalOnly/ralOnly-memory.$out &
+
diff --git a/RelationalCool/tests/PerformanceAV/execTestScrollableCursor.csh b/RelationalCool/tests/PerformanceAV/execTestScrollableCursor.csh
new file mode 100755
index 000000000..4c92f3f7d
--- /dev/null
+++ b/RelationalCool/tests/PerformanceAV/execTestScrollableCursor.csh
@@ -0,0 +1,59 @@
+#! /bin/csh -f
+
+set theOS = `more /etc/redhat-release`
+if ( "$theOS" == "Red Hat Linux release 7.3 (Valhalla)" ) then
+  set theOS = rh73
+else if ( "$theOS" == "Scientific Linux CERN release 3.0.3 (SL)" ) then
+  set theOS = slc3
+else
+  echo "Unknown OS"; exit 1
+endif
+
+set theMem = `more /proc/meminfo|grep MemTotal|awk '{print int($2/1024) "MB"}'`
+
+set theDB = `echo $COOLTESTDB | awk '{print substr($1,0,index($1,"://")-1)}'`
+
+#setenv COOL_TESTAV_RECREATEDB ON
+#unitTest_RelationalCool_PerformanceAV
+unsetenv COOL_TESTAV_RECREATEDB
+
+setenv COOL_RALDATABASE_USETIMER ON
+
+###set out = $theOS.$theMem.$theDB.out
+set out = $theOS.$theMem.$theDB.out.ANALYZED
+
+unsetenv POOL_ORA_SQL_TRACE
+###setenv POOL_ORA_SQL_TRACE ON
+
+\rm TestScrollableCursor/*$out
+unsetenv COOL_RALDATABASE_TESTNEWCOPY
+unsetenv COOL_RALDATABASE_RALONLY
+
+setenv POOL_ORA_SCROLLABLE_CURSOR ON
+unsetenv COOL_COOLCHRONO_PROCMEMORY
+time unitTest_RelationalCool_PerformanceAV \
+    >& TestScrollableCursor/scrollable-time.$out
+
+unsetenv POOL_ORA_SCROLLABLE_CURSOR
+unsetenv COOL_COOLCHRONO_PROCMEMORY
+time unitTest_RelationalCool_PerformanceAV \
+    >& TestScrollableCursor/notScrollable-time.$out
+
+tkdiff TestScrollableCursor/scrollable-time.$out \
+    TestScrollableCursor/notScrollable-time.$out &
+
+###exit 1
+
+setenv POOL_ORA_SCROLLABLE_CURSOR ON
+setenv COOL_COOLCHRONO_PROCMEMORY ON
+time unitTest_RelationalCool_PerformanceAV \
+    >& TestScrollableCursor/scrollable-memory.$out
+
+unsetenv POOL_ORA_SCROLLABLE_CURSOR
+setenv COOL_COOLCHRONO_PROCMEMORY ON
+time unitTest_RelationalCool_PerformanceAV \
+    >& TestScrollableCursor/notScrollable-memory.$out
+
+tkdiff TestScrollableCursor/scrollable-memory.$out \
+    TestScrollableCursor/notScrollable-memory.$out &
+
diff --git a/RelationalCool/tests/PerformanceAV/execTestShareData.csh b/RelationalCool/tests/PerformanceAV/execTestShareData.csh
new file mode 100755
index 000000000..ad61d946f
--- /dev/null
+++ b/RelationalCool/tests/PerformanceAV/execTestShareData.csh
@@ -0,0 +1,55 @@
+#! /bin/csh -f
+
+echo "This test is not supported anymore as of COOL_0_0_3-pre1-zeta!"; exit 1
+
+set theOS = `more /etc/redhat-release`
+if ( "$theOS" == "Red Hat Linux release 7.3 (Valhalla)" ) then
+  set theOS = rh73
+else if ( "$theOS" == "Scientific Linux CERN release 3.0.3 (SL)" ) then
+  set theOS = slc3
+else
+  echo "Unknown OS"; exit 1
+endif
+
+set theMem = `more /proc/meminfo|grep MemTotal|awk '{print int($2/1024) "MB"}'`
+
+set theDB = `echo $COOLTESTDB | awk '{print substr($1,0,index($1,"://")-1)}'`
+
+###set out = $theOS.$theMem.$theDB.out
+set out = $theOS.$theMem.$theDB.out.ANALYZED
+
+###unsetenv POOL_ORA_SQL_TRACE
+setenv POOL_ORA_SQL_TRACE ON
+
+\rm TestShareData/*$out
+setenv COOL_RALDATABASE_USETIMER ON
+unsetenv COOL_RALDATABASE_TESTNEWCOPY
+unsetenv COOL_RALDATABASE_RALONLY
+
+unsetenv COOL_RALDATABASE_DONOTSHAREDATA
+unsetenv COOL_COOLCHRONO_PROCMEMORY
+time unitTest_RelationalCool_PerformanceAV \
+    >& TestShareData/shareData-time.$out
+
+setenv COOL_RALDATABASE_DONOTSHAREDATA ON
+unsetenv COOL_COOLCHRONO_PROCMEMORY
+time unitTest_RelationalCool_PerformanceAV \
+    >& TestShareData/doNotShareData-time.$out
+
+tkdiff TestShareData/shareData-time.$out \
+    TestShareData/doNotShareData-time.$out &
+
+###exit 1
+
+unsetenv COOL_RALDATABASE_DONOTSHAREDATA
+setenv COOL_COOLCHRONO_PROCMEMORY ON
+time unitTest_RelationalCool_PerformanceAV \
+    >& TestShareData/shareData-memory.$out
+
+setenv COOL_RALDATABASE_DONOTSHAREDATA ON
+setenv COOL_COOLCHRONO_PROCMEMORY ON
+time unitTest_RelationalCool_PerformanceAV \
+    >& TestShareData/doNotShareData-memory.$out
+
+tkdiff TestShareData/shareData-memory.$out \
+    TestShareData/doNotShareData-memory.$out &
diff --git a/RelationalCool/tests/PerformanceAV/mySetupMySQL.csh b/RelationalCool/tests/PerformanceAV/mySetupMySQL.csh
new file mode 100644
index 000000000..221675cef
--- /dev/null
+++ b/RelationalCool/tests/PerformanceAV/mySetupMySQL.csh
@@ -0,0 +1,2 @@
+setenv COOLTESTDB "mysql://lxb0771;schema=AVALASSI;user=avalassi;password=PASSWORD;dbname=COOLTSTA"
+
diff --git a/RelationalCool/tests/PerformanceAV/mySetupOracle.csh b/RelationalCool/tests/PerformanceAV/mySetupOracle.csh
new file mode 100644
index 000000000..1e80b4f24
--- /dev/null
+++ b/RelationalCool/tests/PerformanceAV/mySetupOracle.csh
@@ -0,0 +1,2 @@
+setenv COOLTESTDB "oracle://cooldb2;schema=AVALASSI;user=avalassi;password=PASSWORD;dbname=COOLTSTA"
+setenv TNS_ADMIN ~/myLCG/COOL_HEAD/src/RelationalCool/tests
diff --git a/RelationalCool/tests/PerformanceAV/scaling_mixed.txt b/RelationalCool/tests/PerformanceAV/scaling_mixed.txt
new file mode 100644
index 000000000..3754e74f7
--- /dev/null
+++ b/RelationalCool/tests/PerformanceAV/scaling_mixed.txt
@@ -0,0 +1,82 @@
+MIXED test
+-----------
+
+#objects        Write           Read            Data
+
+COOL-MySQL      
+10k             11 sec          11 sec          3.6 MB
+20k             29 sec          23 sec          6.8 MB
+50k             114 sec         60 sec          15.2 MB
+100k            380 sec         121 sec         31.0 MB
+
+COOL-Oracle
+10k             15 sec          33 sec          4.0 MB
+20k             30 sec          74 sec          7.3 MB
+50k             82 sec          295 sec         16.7 MB
+100k            ERROR           
+
+Lisbon-MySQL      
+10k             27 sec          0 sec!          1.4 MB
+20k             55 sec          1 sec!          2.8 MB
+50k             109 sec         2 sec!          7.2 MB
+100k            259 sec         4 sec!          14.4 MB
+
+Comments:
+
+- Both COOL-MySQL and COOL-Oracle occupy more than twice bytes as 
+  Lisbon-MySQL: this may indicate a difference in data type storage
+  that may contribute a factor 2 to the comparison (COOL appears
+  slower by a factor 2 because it occupies twice as much space?)
+
+- COOL-MySQL scales well in reading: good.
+
+- COOL-MySQL does NOT scale in writing: BAD! 
+  This needs to be understood/fixed.
+
+- Lisbon-MySQL read may not have hit yet the threshold for cache usage: the 
+  tests should be repeated with higher load until the threshold is found.
+
+- COOL-Oracle is a factor 3 slower than COOL-MySQL at low data.
+
+- COOL-Oracle does NOT scale in reading: VERY BAD!
+  This needs to be understood/fixed.
+
+- COOL-Oracle is almost a factor 2 faster than Lisbon-MySQL in writing.
+
+- COOL-Oracle crashes in writing 100k: VERY BAD! 
+  Error ORA-24381: error(s) in array DML (executing the bulk insert statement)
+  This needs to be understood/fixed.
+
+Summary:
+* COOL-MySQL
+  - BAD writing does not scale! 
+  - OK reading scales, but slow
+* Lisbon-MySQL
+  - OK writing scales, but slow
+  - VERY GOOD reading, very fast 
+    (factor 30 better than COOL-MySQL: or maybe 15, if same data volume used?)
+* COOL-Oracle [NOT USING A DEDICATED SERVER]
+  - BAD writing crashes at 100k! 
+  - BAD reading does not scale! 
+
+Comment on the cache:
+* I repeated some tests on the MySQL server after disabling the query cache:
+  #query_cache_type=1
+  #query_cache_size=16M
+  query_cache_limit=0
+  query_cache_type=0
+  query_cache_size=0M
+I find that Lisbon-MySQL gets slower in writing, but not in reading!
+This is unlikely to be a statistical fluctuation (I got 180, 152, 150 with 
+no cache, versus 109, 127, 132 with cache, before and after the no cache test)
+  Lisbon-MySQL      
+  50k             150 sec         2 sec!          7.2 MB
+                  (was 109)       (was 2)
+Instead COOL-MySQL stays exactly the same
+  COOL-MySQL      
+  50k             114 sec         59 sec          15.2 MB
+                  (was 114)       (was 2)
+* Direct SQL query from TOra: it gets stuck, too much data.
+* All in all, it seems that Lisbon-MySQL is intrinsecally faster because 
+a MyISAM table is used. I do not see any threshold effect from caching 
+(not yet?). I am not sure I can see any effect from the C++ driver.
\ No newline at end of file
diff --git a/RelationalCool/tests/PerformanceAV/scaling_mixed_2.txt b/RelationalCool/tests/PerformanceAV/scaling_mixed_2.txt
new file mode 100644
index 000000000..a3a7bd6e1
--- /dev/null
+++ b/RelationalCool/tests/PerformanceAV/scaling_mixed_2.txt
@@ -0,0 +1,98 @@
+MIXED test
+-----------
+
+#objects        Write             Read            Data
+
+COOL-MySQL [write using 10k object bursts: in parentheses, single burst]
+10k             11 sec (11)       11 sec          3.6 MB
+20k             29 sec (29)       23 sec          6.8 MB
+50k             70 sec (114)      60 sec          15.2 MB
+100k            156 sec (380)     121 sec         31.0 MB
+200k            418 sec (---)     603 sec (??)    61.4 MB
+[Clear non-linearity in writing 200k: first 10k burst in 10 sec, last in 25]
+[Reading 200k may be the first sign of end-of-caching]
+[Client memory seems too limited to handle such large in-memory data]
+
+COOL-Oracle  [write using 50k object bursts: in parentheses, single burst]
+10k             9 sec (9)         24 sec          4.0 MB
+20k             18 sec (18)       48 sec          7.3 MB
+50k             55 sec (51)       122 sec         16.7 MB
+100k            108 sec (ERROR)   248 sec         32.5 MB
+200k            234 sec (ERROR)   697 sec         63.9 MB
+
+Lisbon-MySQL      
+10k             27 sec            0 sec!          1.4 MB
+20k             55 sec            1 sec!          2.8 MB
+50k             109 sec           2 sec!          7.2 MB
+100k            259 sec           4 sec!          14.4 MB
+200k            553 sec           8 sec!          28.8 MB
+
+Comments:
+
+- Both COOL-MySQL and COOL-Oracle occupy more than twice bytes as 
+  Lisbon-MySQL: this may indicate a difference in data type storage
+  that may contribute a factor 2 to the comparison (COOL appears
+  slower by a factor 2 because it occupies twice as much space?)
+
+- COOL-MySQL scales well in reading: good.
+  BUT it suddenly become non-linear at 200k objects: BAD!
+  This needs to be understood/fixed: this might be the end-of-caching.
+
+- COOL-MySQL writing needs splitting the job in 10k bursts.
+  Using 10k bursts is already much better when storing 50k objects.
+
+- COOL-Oracle writing needs splitting the job in 50k bursts.
+  There is no performance enhancement (if anything, a slight degradation),
+  but otherwise it crashes with ORA-24381.
+
+- COOL-MySQL almost scales in writing: so so.
+  The more data in the database, the slower it goes?
+  This needs to be understood/fixed.  
+
+- Lisbon-MySQL read may not have hit yet the threshold for cache usage: the 
+  tests should be repeated with higher load until the threshold is found.
+  Or is there something else? MyISAM? Driver? Not loading all CondDBTable???
+
+- COOL-Oracle is faster in writing than both COOL-MySQL (factor 1.5 to 2) 
+  and Lisbon-MySQL (factor 2.5): VERY GOOD! 
+
+- The tests may need to be changed: the effect of the limited memory of the
+  client seems to become apparent. After writing the buffer, it takes a
+  long time to destroy the in-memory vector and start reading?
+
+- COOL-Oracle does not scale too well in reading: so so.
+  This needs to be understood/fixed. Related to client memory?
+
+Summary:
+* COOL-MySQL
+  - SOSO writing, does not scale very well 
+  - OK reading, scales but slow
+* Lisbon-MySQL
+  - OK writing, scales but slow
+  - VERY GOOD reading, very fast 
+    (factor 30 better than COOL-MySQL: or maybe 15, if same data volume used?)
+* COOL-Oracle
+  - GOOD writing, faster than the other two!
+  - SOSO reading, does not scale very well 
+
+Comment on the cache:
+* I repeated some tests on the MySQL server after disabling the query cache:
+  #query_cache_type=1
+  #query_cache_size=16M
+  query_cache_limit=0
+  query_cache_type=0
+  query_cache_size=0M
+I find that Lisbon-MySQL gets slower in writing, but not in reading!
+This is unlikely to be a statistical fluctuation (I got 180, 152, 150 with 
+no cache, versus 109, 127, 132 with cache, before and after the no cache test)
+  Lisbon-MySQL      
+  50k             150 sec         2 sec!          7.2 MB
+                  (was 109)       (was 2)
+Instead COOL-MySQL stays exactly the same
+  COOL-MySQL [no 10k bursts]
+  50k             114 sec         59 sec          15.2 MB
+                  (was 114)       (was 59)
+* Direct SQL query from TOra: it gets stuck, too much data.
+* All in all, it seems that Lisbon-MySQL is intrinsecally faster because 
+a MyISAM table is used. I do not see any threshold effect from caching 
+(not yet?). I am not sure I can see any effect from the C++ driver.
\ No newline at end of file
diff --git a/RelationalCool/tests/PerformanceAV/test_PerformanceAV.cpp b/RelationalCool/tests/PerformanceAV/test_PerformanceAV.cpp
new file mode 100644
index 000000000..d3f69257a
--- /dev/null
+++ b/RelationalCool/tests/PerformanceAV/test_PerformanceAV.cpp
@@ -0,0 +1,477 @@
+// PORT -- temporarily disabled: not part of our official test suite
+int main() { return 0; }
+#ifdef NOPORT
+/**
+
+@file test_PerformanceAV.cpp
+
+@author Sven A. Schmidt
+
+@date 2005-01-03
+
+*/
+
+
+#include<cppunit/extensions/HelperMacros.h>
+
+#include "CoolKernel/IFolder.h"
+#include "CoolKernel/IObject.h"
+#include "CoolKernel/IObjectIterator.h"
+#include "CoolKernel/IDatabaseSvc.h"
+#include "CoolKernel/Exception.h"
+
+#include "../Performance/Benchmark.h"
+
+#include "src/CoralApplication.h"
+#include "src/ProcMemory.h"
+
+using coral::AttributeList;
+using coral::AttributeListSpecification;
+typedef boost::shared_ptr<AttributeListSpecification> SpecPtr;
+
+// include for 'sleep' (ORA-01466 workaround)
+//#include <unistd.h>
+#include "src/sleep.h"
+
+#include <string>
+using std::cout;
+using std::endl;
+using std::string;
+using std::stringstream;
+
+#include <vector>
+using std::vector;
+
+namespace cool {
+
+const char* COOLTESTDB = "COOLTESTDB";
+
+// set this to true to have a quick run through all tests
+// tests should initialize their iteration count like this:
+//    long iterations = quick ? 1 : 10000;
+const bool quick = true;
+//const bool quick = false;
+
+
+/// Performace test class
+class PerformanceTestAV : public CppUnit::TestFixture {
+		
+  CPPUNIT_TEST_SUITE( PerformanceTestAV );
+  
+  CPPUNIT_TEST( test_bulk_rw_mixed );
+   
+  //CPPUNIT_TEST( test_bulk_rw_float_1 );
+  //CPPUNIT_TEST( test_bulk_rw_float_20 );
+  //CPPUNIT_TEST( test_bulk_rw_float_100 );
+  //CPPUNIT_TEST( test_bulk_rw_float_200 );
+
+  //CPPUNIT_TEST( test_bulk_rw_string4kb_1 );
+  //CPPUNIT_TEST( test_bulk_rw_string4kb_100 );
+  //CPPUNIT_TEST( test_bulk_rw_string4kb_200 );
+  
+  CPPUNIT_TEST_SUITE_END();
+		
+public:
+    
+  AttributeListSpecification mixedPayloadSpec;
+  string connectString;
+  IDatabasePtr db;
+  
+  
+  /*
+  void test_bulk_rw_string4kb_1() {
+    int nFields = 1;
+    long nObjs = quick ? 1 : 25000;
+    rw_string4kb( nFields, nObjs );
+  }
+  
+  void test_bulk_rw_string4kb_100() {
+    int nFields = 100;
+    long nObjs = quick ? 1 : 200; // reduced row count, each obj is 400kB
+                                  // 25k objects would allocate 10GB of memory
+                                  // could run several batches instead
+    rw_string4kb( nFields, nObjs );
+  }
+  
+  void test_bulk_rw_string4kb_200() {
+    int nFields = 200;
+    long nObjs = quick ? 1 : 100; // reduced row count, each obj is 400kB
+                                  // 25k objects would allocate 20GB of memory
+                                  // could run several batches instead
+    rw_string4kb( nFields, nObjs );
+  }
+  
+  
+  void rw_string4kb( int nFields, long nObjs ) {
+    
+    SpecPtr spec = uniformSpec( nFields, "string" );
+    AttributeList payload = string4kbPayload( spec );		
+    
+    IFolderPtr folder = db->createFolder( "/myfolder", *spec );
+    
+    mysleep();
+        
+    {
+      Benchmark b;
+      b.start();
+      
+      folder->setupStorageBuffer();
+      
+      for ( long i = 0; i < nObjs; ++i ) {
+        folder->storeObject( i, ValidityKeyMax, payload );
+      }
+      
+      folder->flushStorageBuffer();
+      
+      double secElapsed = b.stop();
+      
+      cout << "\n----------------------------------------------------" << endl;
+      cout << "** writing " << nObjs << " objects ("
+        << nFields << " 4kb strings) **" << endl;
+      cout << "wrote " << nObjs << " objects" << endl;
+      cout << "sec total: " << secElapsed << endl;
+      cout << "obj/s:     " << nObjs/secElapsed << endl << endl;
+    }
+    
+    
+    {
+      Benchmark b;
+      b.start();
+      
+      IObjectIteratorPtr objs = 
+        folder->browseObjectsInTag( "", 0, 0, ValidityKeyMax );
+
+      long nReadObjects = 0;
+      while( objs->hasNext() ) {
+        objs->next();
+        nReadObjects++;
+      }      
+
+      double secElapsed = b.stop();
+      
+      cout << "** reading " << nObjs << " objects ("
+        << nFields << " 4kb strings) **" << endl;
+      cout << "read back " << nReadObjects << " objects" << endl;
+      cout << "sec total: " << secElapsed << endl;
+      cout << "obj/s:     " << nReadObjects/secElapsed << endl;
+    }
+    
+  }
+  
+  
+  
+  
+  void test_bulk_rw_float_1() {
+    int nFields = 1;
+    long nObjs = quick ? 1 : 25000;
+    rw_floats( nFields, nObjs );
+  }
+  
+  void test_bulk_rw_float_100() {
+    int nFields = 100;
+    long nObjs = quick ? 1 : 25000;
+    rw_floats( nFields, nObjs );
+  }
+  
+  void test_bulk_rw_float_200() {
+    int nFields = 200;
+    long nObjs = quick ? 1 : 25000;
+    rw_floats( nFields, nObjs );
+  }
+  
+  
+  void test_bulk_rw_float_20() {
+    int nFields = 20;
+    long nObjs = quick ? 1 : 25000;
+    rw_floats( nFields, nObjs );
+  }
+  
+  
+  void rw_floats( int nFields, long nObjs ) {
+    
+    SpecPtr spec = uniformSpec( nFields, "float" );
+    IFolderPtr folder = db->createFolder( "/myfolder", *spec );
+    
+    mysleep();
+    
+    {
+      Benchmark b;
+      b.start();
+      
+      folder->setupStorageBuffer();
+      
+      for ( long i = 0; i < nObjs; ++i ) {
+        folder->storeObject( i, ValidityKeyMax, floatPayload( i, spec ) );
+      }
+      
+      folder->flushStorageBuffer();
+      
+      double secElapsed = b.stop();
+      
+      cout << "\n----------------------------------------------------" << endl;
+      cout << "** writing " << nObjs << " objects ("
+        << nFields << " floats) **" << endl;
+      cout << "wrote " << nObjs << " objects" << endl;
+      cout << "sec total: " << secElapsed << endl;
+      cout << "obj/s:     " << nObjs/secElapsed << endl << endl;
+    }
+    
+    
+    {
+      Benchmark b;
+      b.start();
+      
+      IObjectIteratorPtr objs = 
+        folder->browseObjectsInTag( "", 0, 0, ValidityKeyMax );
+
+      long nReadObjects = 0;
+      while( objs->hasNext() ) {
+        objs->next();
+        nReadObjects++;
+      }      
+      
+      double secElapsed = b.stop();
+      
+      cout << "** reading " << nObjs << " objects ("
+        << nFields << " floats) **" << endl;
+      cout << "read back " << nReadObjects << " objects" << endl;
+      cout << "sec total: " << secElapsed << endl;
+      cout << "obj/s:     " << nReadObjects/secElapsed << endl;
+    }
+    
+  }
+
+  */
+  
+  void test_bulk_rw_mixed() {
+
+    //ProcMemory* mem = new ProcMemory();
+    //std::cout << "START of TEST" << std::endl; mem->printVm();
+
+    //long nObjs = quick ? 1 : 10000;
+    //long nObjs = 1;
+    //long nObjs = 10;
+    //long nObjs = 1000;
+    //long nObjs = 10000;
+    //long nObjs = 20000;
+    //long nObjs = 50000;
+    long nObjs = 100000;
+    //long nObjs = 200000;
+
+    if ( getenv ( "COOL_TESTAV_RECREATEDB" ) ) {
+
+      IFolderPtr folder = db->createFolder( "/myfolder", mixedPayloadSpec );
+
+      Benchmark b;
+      b.start();
+      
+      folder->setupStorageBuffer();
+      for ( long i = 0; i < nObjs; ++i ) {
+        folder->storeObject( i, ValidityKeyMax, mixedPayload( i ) );
+      }
+      
+      //std::cout << "Before flushing" << std::endl; mem->printVm();
+
+      folder->flushStorageBuffer();
+      
+      double secElapsed = b.stop();
+
+      cout << "\n----------------------------------------------------" << endl;
+      cout << "** writing " << nObjs << " objects (150 bytes mixed) **" << endl;
+      cout << "sec total: " << secElapsed << endl;
+      cout << "obj/s:     " << nObjs/secElapsed << endl << endl;
+
+      // ORA-01466
+      cool::sleep(1);
+      
+    }
+    
+    //std::cout << "After flushing" << std::endl; mem->printVm();
+
+    Benchmark bFull;
+    bFull.start();
+
+    {
+
+      IFolderPtr folder = db->getFolder( "/myfolder" );
+
+      Benchmark b;
+      b.start();
+      
+      // Read ALL objects in tag
+      //IObjectIteratorPtr objs =
+      //  folder->browseObjects( 0, ValidityKeyMax, 0, "" );
+      //  folder->browseObjectsInTag( "", 0, 0, ValidityKeyMax ); // OLD!
+
+      // Read only 10k objects in tag
+      IObjectIteratorPtr objs =
+        folder->browseObjects( 0, 10000, 0, "" );
+      //folder->browseObjectsInTag( "", 0, 0, 10000 ); // OLD!
+      
+      //std::cout << "After reading" << std::endl; mem->printVm();
+
+      long nReadObjects = 0;
+      while( objs->hasNext() ) {
+        objs->next();
+        nReadObjects++;
+        if( nReadObjects == 1 )
+          cout << "==> First object: since=" << objs->current()->since() << endl;
+      }      
+      cout << "==> Last  object: since=" << objs->current()->since() << endl;
+      
+      double secElapsed = b.stop();
+      
+      cout << "** reading " << nObjs << " objects (150 bytes mixed) **" << endl;
+      cout << "read back " << nReadObjects << " objects" << endl;
+      cout << "sec total: " << secElapsed << endl;
+      cout << "obj/s:     " << nReadObjects/secElapsed << endl;
+    }      
+
+    cout << "sec total (INCLUDING DELETE): " << bFull.stop() << endl;
+    
+    //std::cout << "END OF TEST" << std::endl; mem->printVm();
+
+  }
+  
+  
+		
+  
+  /// Creates a dummy payload AttributeList for a given index
+  AttributeList mixedPayload( int index ) {
+    AttributeList payload( mixedPayloadSpec );
+    payload["I"].setValue<int>( index );
+    stringstream s;
+    s << "Object " << index;
+    payload["S"].setValue<string>( s.str() );
+    payload["X0"].setValue<float>( (float)(index/1000.) );
+    payload["X1"].setValue<float>( (float)(index/1000.) );
+    payload["X2"].setValue<float>( (float)(index/1000.) );
+    payload["X3"].setValue<float>( (float)(index/1000.) );
+    payload["X4"].setValue<float>( (float)(index/1000.) );
+    payload["X5"].setValue<float>( (float)(index/1000.) );
+    payload["X6"].setValue<float>( (float)(index/1000.) );
+    payload["X7"].setValue<float>( (float)(index/1000.) );
+    payload["X8"].setValue<float>( (float)(index/1000.) );
+    payload["X9"].setValue<float>( (float)(index/1000.) );
+    payload["P"].setValue<string>( "0123456789"
+                                   "0123456789"
+                                   "0123456789"
+                                   "0123456789"
+                                   "0123456789"
+                                   "0123456789"
+                                   "0123456789"
+                                   "0123456789"
+                                   "0123456789"
+                                   "0123456789"
+                                   );
+    return payload;
+  }
+		
+  
+  /// Creates a uniform payload specification for nFields fields
+  SpecPtr uniformSpec( int nFields, const string & type ) {
+    SpecPtr spec( new AttributeListSpecification() );
+    for ( int i = 0; i < nFields; ++i ) {
+      stringstream s;
+      s << "X" << i;
+      spec->push_back( s.str(), type );
+    }
+    return spec;
+  }
+  
+  
+  /// Creates a dummy 4kB string AttributeList
+  AttributeList string4kbPayload( SpecPtr & spec ) {
+    stringstream payloadString;
+    int bytes = 4000;
+    for ( int i = 0; i < bytes; ++i ) payloadString << "a";
+    
+    int nFields = spec->size();
+    AttributeList payload( spec );
+    for ( int i = 0; i < nFields; ++i ) {
+      stringstream s;
+      s << "X" << i;
+      payload[ s.str() ].setValue<string>( payloadString.str() );
+    }
+    return payload;
+  }
+		
+  
+  /// Creates a dummy float AttributeList for a given index
+  AttributeList floatPayload( int index, SpecPtr & spec ) {
+    int nFields = spec->size();
+    AttributeList payload( spec );
+    for ( int i = 0; i < nFields; ++i ) {
+      stringstream s;
+      s << "X" << i;
+      payload[ s.str() ].setValue<float>( (float)(index/1000.) );
+    }
+    return payload;
+  }
+		
+  
+  void mysleep() {
+    const int sleep_timeout = 1;
+    if ( sleep_timeout > 0 ) {
+      //cout << "temporary 'sleep()' to work aound ORA-01466 problem" << endl;
+      cool::sleep(sleep_timeout);
+    }
+  }
+  
+  
+  void setUp() {
+    if ( mixedPayloadSpec.size() == 0 ) {
+      mixedPayloadSpec.push_back("I","int");
+      mixedPayloadSpec.push_back("S","string");
+      mixedPayloadSpec.push_back("X0","float");
+      mixedPayloadSpec.push_back("X1","float");
+      mixedPayloadSpec.push_back("X2","float");
+      mixedPayloadSpec.push_back("X3","float");
+      mixedPayloadSpec.push_back("X4","float");
+      mixedPayloadSpec.push_back("X5","float");
+      mixedPayloadSpec.push_back("X6","float");
+      mixedPayloadSpec.push_back("X7","float");
+      mixedPayloadSpec.push_back("X8","float");
+      mixedPayloadSpec.push_back("X9","float");
+      mixedPayloadSpec.push_back("P","string");
+    }
+    
+    if ( getenv( COOLTESTDB ) ) {
+      connectString = getenv( COOLTESTDB );
+    } else {
+      cout << "Please provide a connect string by "
+      << "specifying one in the environment variable COOLTESTDB, e.g." 
+      << endl;
+      cout << "setenv COOLTESTDB "
+        << "\"oracle://devdb10;schema=lcg_cool;dbname=COOLTEST\"" << endl;
+      cout << "Aborting test" << endl;
+      exit(-1);
+    }
+    
+    static CoralApplication app;
+    IDatabaseSvc& dbSvc = app.databaseService();
+    if ( getenv ( "COOL_TESTAV_RECREATEDB" ) ) {
+      dbSvc.dropDatabase( connectString );
+      db = dbSvc.createDatabase( connectString );
+    } else
+      db = dbSvc.openDatabase( connectString, false );
+    
+    mysleep();
+  }
+		
+		void tearDown() {
+      db.reset();
+		}
+  
+};
+
+CPPUNIT_TEST_SUITE_REGISTRATION( PerformanceTestAV );
+
+} // namespace
+
+// sas: This file is from the OPAL package I believe. It allows for
+// shorter test classes and prepares the test class for OPAL
+#include<CppUnit_testdriver.icpp>
+
+
+#endif // NOPORT
diff --git a/RelationalCool/tests/Privileges/out.oracle.slc3_ia32_gcc323 b/RelationalCool/tests/Privileges/out.oracle.slc3_ia32_gcc323
new file mode 100644
index 000000000..433eb6b88
--- /dev/null
+++ b/RelationalCool/tests/Privileges/out.oracle.slc3_ia32_gcc323
@@ -0,0 +1,186 @@
+============================================
+Executing test as user 'lcg_cooltest'
+Connection string: 'oracle://coolprod;schema=lcg_cooltest;dbname=COOLTEST;user=lcg_cooltest'
+Property Catalogue: level[Info] Adding property: OutputLevel = 5 in scope "SEAL/Services/MessageService"
+Property Catalogue: level[Info] Adding property: Format =  "%-36s %-8s %s" in scope "SEAL/Services/MessageService"
+Property Catalogue: level[Info] Adding property: AuthenticationFile =  "/afs/cern.ch/user/a/avalassi/private/authentication.xml" in scope "POOL/Services/XMLAuthenticationService"
+==> Start TEST: create database
+++++> End TEST: create database
+==> Start TEST: open database
+++++> End TEST: open database
+==> Start TEST: create new MV folder
+++++> End TEST: create new MV folder
+==> Start TEST: create new folder set
+++++> End TEST: create new folder set
+==> Start TEST: read SV IOVs
+++++> End TEST: read SV IOVs
+==> Start TEST: read MV IOVs head
+++++> End TEST: read MV IOVs head
+==> Start TEST: read MV IOVs mytag
+++++> End TEST: read MV IOVs mytag
+==> Start TEST: tag MV IOVs
+++++> End TEST: tag MV IOVs
+==> Start TEST: retag MV IOVs
+++++> End TEST: retag MV IOVs
+==> Start TEST: insert SV IOVs
+++++> End TEST: insert SV IOVs
+==> Start TEST: insert MV IOVs
+++++> End TEST: insert MV IOVs
+==> Start TEST: drop SV folder
+++++> End TEST: drop SV folder
+==> Start TEST: drop MV folder
+++++> End TEST: drop MV folder
+==> Start TEST: drop folderset
+++++> End TEST: drop folderset
+==> Start TEST: drop database
+++++> End TEST: drop database
+++++++++++++++++++++++++++++++++++++++++++++
+============================================
+Executing test as user 'lcg_cooltest_reader'
+Connection string: 'oracle://coolprod;schema=lcg_cooltest;dbname=COOLTEST;user=lcg_cooltest_reader'
+==> Start TEST: create database
+POOL/RelationalPlugins/oracle        Error    ORA-01031: insufficient privileges (executing the statement "CREATE TABLE "LCG_COOLTEST"."COOLTEST_DB_ATTRIBUTES" ( "DB_ATTRIBUTE_NAME" VARCHAR2(255) )")
+++++> End TEST: create database
+==> Start TEST: open database
+++++> End TEST: open database
+==> Start TEST: create new MV folder
+POOL/RelationalPlugins/oracle        Error    ORA-01031: insufficient privileges (executing the statement "UPDATE "LCG_COOLTEST"."COOLTEST_NODES_SEQ" SET "CURRENT_VALUE"=:"newvalue", "LASTMOD_DATE"=TO_CHAR(SYSTIMESTAMP AT TIME ZONE 'GMT','yyyy-mm-dd_hh24:mi:ss.ff6')||'000 GMT'")
+++++> End TEST: create new MV folder
+==> Start TEST: create new folder set
+POOL/RelationalPlugins/oracle        Error    ORA-01031: insufficient privileges (executing the statement "UPDATE "LCG_COOLTEST"."COOLTEST_NODES_SEQ" SET "CURRENT_VALUE"=:"newvalue", "LASTMOD_DATE"=TO_CHAR(SYSTIMESTAMP AT TIME ZONE 'GMT','yyyy-mm-dd_hh24:mi:ss.ff6')||'000 GMT'")
+++++> End TEST: create new folder set
+==> Start TEST: read SV IOVs
+++++> End TEST: read SV IOVs
+==> Start TEST: read MV IOVs head
+++++> End TEST: read MV IOVs head
+==> Start TEST: read MV IOVs mytag
+++++> End TEST: read MV IOVs mytag
+==> Start TEST: tag MV IOVs
+POOL/RelationalPlugins/oracle        Error    ORA-01031: insufficient privileges (executing the statement "UPDATE "LCG_COOLTEST"."COOLTEST_F0003_TAGS_SEQ" SET "CURRENT_VALUE"=:"newvalue", "LASTMOD_DATE"=TO_CHAR(SYSTIMESTAMP AT TIME ZONE 'GMT','yyyy-mm-dd_hh24:mi:ss.ff6')||'000 GMT'")
+++++> End TEST: tag MV IOVs
+==> Start TEST: retag MV IOVs
+POOL/RelationalPlugins/oracle        Error    ORA-01031: insufficient privileges (executing the statement "DELETE FROM "LCG_COOLTEST"."COOLTEST_F0003_IOV2TAG" WHERE "TAG_ID"= :"tagId"")
+++++> End TEST: retag MV IOVs
+==> Start TEST: insert SV IOVs
+POOL/RelationalPlugins/oracle        Error    ORA-01031: insufficient privileges (executing the statement "UPDATE "LCG_COOLTEST"."COOLTEST_F0002_IOVS_SEQ" SET "CURRENT_VALUE"=:"newvalue", "LASTMOD_DATE"=TO_CHAR(SYSTIMESTAMP AT TIME ZONE 'GMT','yyyy-mm-dd_hh24:mi:ss.ff6')||'000 GMT'")
+++++> End TEST: insert SV IOVs
+==> Start TEST: insert MV IOVs
+POOL/RelationalPlugins/oracle        Error    ORA-01031: insufficient privileges (executing the statement "UPDATE "LCG_COOLTEST"."COOLTEST_F0003_IOVS_SEQ" SET "CURRENT_VALUE"=:"newvalue", "LASTMOD_DATE"=TO_CHAR(SYSTIMESTAMP AT TIME ZONE 'GMT','yyyy-mm-dd_hh24:mi:ss.ff6')||'000 GMT'")
+++++> End TEST: insert MV IOVs
+==> Start TEST: drop SV folder
+POOL/RelationalPlugins/oracle        Error    ORA-01031: insufficient privileges (executing the statement "DROP TABLE "LCG_COOLTEST"."COOLTEST_F0002_IOVS"")
+++++> End TEST: drop SV folder
+==> Start TEST: drop MV folder
+POOL/RelationalPlugins/oracle        Error    ORA-01031: insufficient privileges (executing the statement "DROP TABLE "LCG_COOLTEST"."COOLTEST_F0003_IOV2TAG"")
+++++> End TEST: drop MV folder
+==> Start TEST: drop folderset
+POOL/RelationalPlugins/oracle        Error    ORA-01031: insufficient privileges (executing the statement "DELETE FROM "LCG_COOLTEST"."COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName"")
+++++> End TEST: drop folderset
+==> Start TEST: drop database
+POOL/RelationalPlugins/oracle        Error    ORA-01031: insufficient privileges (executing the statement "DELETE FROM "LCG_COOLTEST"."COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName"")
+++++> End TEST: drop database
+++++++++++++++++++++++++++++++++++++++++++++
+============================================
+Executing test as user 'lcg_cooltest_writer'
+Connection string: 'oracle://coolprod;schema=lcg_cooltest;dbname=COOLTEST;user=lcg_cooltest_writer'
+==> Start TEST: create database
+POOL/RelationalPlugins/oracle        Error    ORA-01031: insufficient privileges (executing the statement "CREATE TABLE "LCG_COOLTEST"."COOLTEST_DB_ATTRIBUTES" ( "DB_ATTRIBUTE_NAME" VARCHAR2(255) )")
+++++> End TEST: create database
+==> Start TEST: open database
+++++> End TEST: open database
+==> Start TEST: create new MV folder
+POOL/RelationalPlugins/oracle        Error    ORA-01031: insufficient privileges (executing the statement "UPDATE "LCG_COOLTEST"."COOLTEST_NODES_SEQ" SET "CURRENT_VALUE"=:"newvalue", "LASTMOD_DATE"=TO_CHAR(SYSTIMESTAMP AT TIME ZONE 'GMT','yyyy-mm-dd_hh24:mi:ss.ff6')||'000 GMT'")
+++++> End TEST: create new MV folder
+==> Start TEST: create new folder set
+POOL/RelationalPlugins/oracle        Error    ORA-01031: insufficient privileges (executing the statement "UPDATE "LCG_COOLTEST"."COOLTEST_NODES_SEQ" SET "CURRENT_VALUE"=:"newvalue", "LASTMOD_DATE"=TO_CHAR(SYSTIMESTAMP AT TIME ZONE 'GMT','yyyy-mm-dd_hh24:mi:ss.ff6')||'000 GMT'")
+++++> End TEST: create new folder set
+==> Start TEST: read SV IOVs
+++++> End TEST: read SV IOVs
+==> Start TEST: read MV IOVs head
+++++> End TEST: read MV IOVs head
+==> Start TEST: read MV IOVs mytag
+++++> End TEST: read MV IOVs mytag
+==> Start TEST: tag MV IOVs
+POOL/RelationalPlugins/oracle        Error    ORA-01031: insufficient privileges (executing the statement "UPDATE "LCG_COOLTEST"."COOLTEST_F0003_TAGS_SEQ" SET "CURRENT_VALUE"=:"newvalue", "LASTMOD_DATE"=TO_CHAR(SYSTIMESTAMP AT TIME ZONE 'GMT','yyyy-mm-dd_hh24:mi:ss.ff6')||'000 GMT'")
+++++> End TEST: tag MV IOVs
+==> Start TEST: retag MV IOVs
+POOL/RelationalPlugins/oracle        Error    ORA-01031: insufficient privileges (executing the statement "DELETE FROM "LCG_COOLTEST"."COOLTEST_F0003_IOV2TAG" WHERE "TAG_ID"= :"tagId"")
+++++> End TEST: retag MV IOVs
+==> Start TEST: insert SV IOVs
+++++> End TEST: insert SV IOVs
+==> Start TEST: insert MV IOVs
+++++> End TEST: insert MV IOVs
+==> Start TEST: drop SV folder
+POOL/RelationalPlugins/oracle        Error    ORA-01031: insufficient privileges (executing the statement "DROP TABLE "LCG_COOLTEST"."COOLTEST_F0002_IOVS"")
+++++> End TEST: drop SV folder
+==> Start TEST: drop MV folder
+POOL/RelationalPlugins/oracle        Error    ORA-01031: insufficient privileges (executing the statement "DROP TABLE "LCG_COOLTEST"."COOLTEST_F0003_IOV2TAG"")
+++++> End TEST: drop MV folder
+==> Start TEST: drop folderset
+POOL/RelationalPlugins/oracle        Error    ORA-01031: insufficient privileges (executing the statement "DELETE FROM "LCG_COOLTEST"."COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName"")
+++++> End TEST: drop folderset
+==> Start TEST: drop database
+POOL/RelationalPlugins/oracle        Error    ORA-01031: insufficient privileges (executing the statement "DELETE FROM "LCG_COOLTEST"."COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName"")
+++++> End TEST: drop database
+++++++++++++++++++++++++++++++++++++++++++++
+============================================
+Executing test as user 'lcg_cooltest_tagger'
+Connection string: 'oracle://coolprod;schema=lcg_cooltest;dbname=COOLTEST;user=lcg_cooltest_tagger'
+==> Start TEST: create database
+POOL/RelationalPlugins/oracle        Error    ORA-01031: insufficient privileges (executing the statement "CREATE TABLE "LCG_COOLTEST"."COOLTEST_DB_ATTRIBUTES" ( "DB_ATTRIBUTE_NAME" VARCHAR2(255) )")
+++++> End TEST: create database
+==> Start TEST: open database
+++++> End TEST: open database
+==> Start TEST: create new MV folder
+POOL/RelationalPlugins/oracle        Error    ORA-01031: insufficient privileges (executing the statement "UPDATE "LCG_COOLTEST"."COOLTEST_NODES_SEQ" SET "CURRENT_VALUE"=:"newvalue", "LASTMOD_DATE"=TO_CHAR(SYSTIMESTAMP AT TIME ZONE 'GMT','yyyy-mm-dd_hh24:mi:ss.ff6')||'000 GMT'")
+++++> End TEST: create new MV folder
+==> Start TEST: create new folder set
+POOL/RelationalPlugins/oracle        Error    ORA-01031: insufficient privileges (executing the statement "UPDATE "LCG_COOLTEST"."COOLTEST_NODES_SEQ" SET "CURRENT_VALUE"=:"newvalue", "LASTMOD_DATE"=TO_CHAR(SYSTIMESTAMP AT TIME ZONE 'GMT','yyyy-mm-dd_hh24:mi:ss.ff6')||'000 GMT'")
+++++> End TEST: create new folder set
+==> Start TEST: read SV IOVs
+++++> End TEST: read SV IOVs
+==> Start TEST: read MV IOVs head
+++++> End TEST: read MV IOVs head
+==> Start TEST: read MV IOVs mytag
+++++> End TEST: read MV IOVs mytag
+==> Start TEST: tag MV IOVs
+++++> End TEST: tag MV IOVs
+==> Start TEST: retag MV IOVs
+++++> End TEST: retag MV IOVs
+==> Start TEST: insert SV IOVs
+POOL/RelationalPlugins/oracle        Error    ORA-01031: insufficient privileges (executing the statement "UPDATE "LCG_COOLTEST"."COOLTEST_F0002_IOVS_SEQ" SET "CURRENT_VALUE"=:"newvalue", "LASTMOD_DATE"=TO_CHAR(SYSTIMESTAMP AT TIME ZONE 'GMT','yyyy-mm-dd_hh24:mi:ss.ff6')||'000 GMT'")
+++++> End TEST: insert SV IOVs
+==> Start TEST: insert MV IOVs
+POOL/RelationalPlugins/oracle        Error    ORA-01031: insufficient privileges (executing the statement "UPDATE "LCG_COOLTEST"."COOLTEST_F0003_IOVS_SEQ" SET "CURRENT_VALUE"=:"newvalue", "LASTMOD_DATE"=TO_CHAR(SYSTIMESTAMP AT TIME ZONE 'GMT','yyyy-mm-dd_hh24:mi:ss.ff6')||'000 GMT'")
+++++> End TEST: insert MV IOVs
+==> Start TEST: drop SV folder
+POOL/RelationalPlugins/oracle        Error    ORA-01031: insufficient privileges (executing the statement "DROP TABLE "LCG_COOLTEST"."COOLTEST_F0002_IOVS"")
+++++> End TEST: drop SV folder
+==> Start TEST: drop MV folder
+POOL/RelationalPlugins/oracle        Error    ORA-01031: insufficient privileges (executing the statement "DROP TABLE "LCG_COOLTEST"."COOLTEST_F0003_IOV2TAG"")
+++++> End TEST: drop MV folder
+==> Start TEST: drop folderset
+POOL/RelationalPlugins/oracle        Error    ORA-01031: insufficient privileges (executing the statement "DELETE FROM "LCG_COOLTEST"."COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName"")
+++++> End TEST: drop folderset
+==> Start TEST: drop database
+POOL/RelationalPlugins/oracle        Error    ORA-01031: insufficient privileges (executing the statement "DELETE FROM "LCG_COOLTEST"."COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName"")
+++++> End TEST: drop database
+++++++++++++++++++++++++++++++++++++++++++++
+============================================
+Executing test as user 'lcg_cooltest_nopriv'
+Connection string: 'oracle://coolprod;schema=lcg_cooltest;dbname=COOLTEST;user=lcg_cooltest_nopriv'
+==> Start TEST: create database
+POOL/RelationalPlugins/oracle        Error    ORA-01031: insufficient privileges (executing the statement "CREATE TABLE "LCG_COOLTEST"."COOLTEST_DB_ATTRIBUTES" ( "DB_ATTRIBUTE_NAME" VARCHAR2(255) )")
+++++> End TEST: create database
+==> Start TEST: open database
+++++> End TEST: open database
+**** SKIP TEST: create new MV folder
+**** SKIP TEST: create new folderset
+**** SKIP TEST: drop SV folder
+**** SKIP TEST: drop MV folder
+**** SKIP TEST: drop folderset
+**** SKIP TEST: drop database
+++++++++++++++++++++++++++++++++++++++++++++
+
+OK (5)
+[OVAL] Cppunit-result =0
diff --git a/RelationalCool/tests/Privileges/test_Privileges.cpp b/RelationalCool/tests/Privileges/test_Privileges.cpp
new file mode 100644
index 000000000..115f310a1
--- /dev/null
+++ b/RelationalCool/tests/Privileges/test_Privileges.cpp
@@ -0,0 +1,954 @@
+int main() { return 0; }
+#ifdef NOPORT
+// $Id: test_Privileges.cpp,v 1.15 2008-08-27 09:34:29 avalassi Exp $
+
+// Include files
+#include <cppunit/extensions/HelperMacros.h>
+#include <sstream>
+#include "AttributeList/AttributeList.h"
+#include "CoolKernel/Exception.h"
+#include "CoolKernel/IDatabase.h"
+#include "CoolKernel/IDatabaseSvc.h"
+#include "CoolKernel/IFolder.h"
+#include "CoolKernel/IObjectIterator.h"
+#include "RelationalAccess/RelationalException.h"
+
+// Local include files
+#include "src/CoralApplication.h"
+#include "src/RalPrivilegeManager.h"
+#include "src/RelationalDatabaseId.h"
+
+// Forward declaration
+namespace cool {
+  class PrivilegesTest;
+}
+
+// Environment variable name
+namespace cool {
+  const char* COOLTESTDB = "COOLTESTDB";
+}
+
+//-----------------------------------------------------------------------------
+
+class cool::PrivilegesTest : public CppUnit::TestFixture {
+  
+  CPPUNIT_TEST_SUITE( PrivilegesTest );
+  
+  CPPUNIT_TEST( testAll_Owner );
+  CPPUNIT_TEST( testAll_Reader );
+  CPPUNIT_TEST( testAll_Writer );
+  CPPUNIT_TEST( testAll_Tagger );
+  CPPUNIT_TEST( testAll_NoPriv );
+
+  CPPUNIT_TEST_SUITE_END();
+  
+public:
+  
+  enum Role { NONE=-1, OWNER=0, READER=1, WRITER=2, TAGGER=3, NOPRIV=4 };
+
+  Role m_role;
+  std::string m_connectOwner;
+  std::string m_userOwner;
+  std::string m_connect;
+  std::string m_user;
+  IDatabasePtr m_db; 
+  pool::AttributeListSpecification m_payloadSpec;
+  std::string m_fNameSV;
+  std::string m_fNameMV;
+  std::string m_fsName;
+  ChannelId m_chId;
+  unsigned long m_expSV;
+  std::string m_tagMV;
+  unsigned long m_expMVtag;
+  unsigned long m_expMVhead;  
+  
+  //---------------------------------------------------------------------------
+
+  IDatabaseSvc& databaseService()
+  {
+    static CoralApplication app;
+    IDatabaseSvc& dbSvc = app.databaseService();
+    return dbSvc;
+  }
+  
+  //---------------------------------------------------------------------------
+
+  const std::string userForRole( const Role& role ) 
+  {
+    // Default suffixes are used for the user names for the various roles
+    std::string user;
+    if ( role == OWNER ) {
+      user = m_userOwner;
+    } else if ( role == READER ) {
+      user = m_userOwner + "_reader";
+    } else if ( role == WRITER ) {
+      user = m_userOwner + "_writer";
+    } else if ( role == TAGGER ) {
+      user = m_userOwner + "_tagger";
+    } else if ( role == NOPRIV ) { 
+      user = m_userOwner + "_nopriv";
+    } else {
+      std::cout << "PANIC! Unknown role " << role << std::endl;
+      exit( -1 );
+    }
+    return user;
+  }
+
+  //---------------------------------------------------------------------------
+
+  void getConnectString() 
+  {
+
+    // Get the connection string for the owner user
+    if ( getenv( COOLTESTDB ) ) {
+      m_connectOwner = getenv( COOLTESTDB );
+    } else {
+      std::cout << "ERROR! You must provide a connection string "
+                << "in the environment variable " << COOLTESTDB << ", e.g." 
+                << std::endl;
+      std::cout << "setenv " << COOLTESTDB
+                << " 'oracle://coolprod;schema=lcg_cooltest;dbname=COOLTEST"
+                << ";user=lcg_cooltest'" << std::endl;
+      exit(-1);
+    }
+    RelationalDatabaseId idOwner( m_connectOwner );
+    if ( idOwner.user() == "" ) {
+      std::cout << "ERROR! You must specify the (owner) user" << std::endl;
+      exit(-1);
+    }
+    if ( idOwner.password() != "" ) {
+      std::cout << "ERROR! You must NOT specify the password" << std::endl;
+      exit(-1);
+    }
+    m_userOwner = idOwner.user();
+    
+    // Get the appropriate user name and connection string for the current role
+    m_user = userForRole( m_role );
+    std::cout << "============================================" << std::endl;
+    std::cout << "Executing test as user '" << m_user << "'" << std::endl;
+    RelationalDatabaseId id( idOwner.technology(), 
+                             idOwner.server(), 
+                             idOwner.schema(), 
+                             idOwner.dbName(), 
+                             m_user );
+    m_connect = id.url();
+    std::cout << "Connection string: '" << m_connect << "'" << std::endl;
+
+  }
+      
+  //---------------------------------------------------------------------------
+
+  void dropDatabaseAsOwner() 
+  {
+    IDatabaseSvc& dbSvc = databaseService();
+    dbSvc.dropDatabase( m_connectOwner );
+  }
+  
+  //---------------------------------------------------------------------------
+
+  void createDatabaseAsOwner() 
+  {
+
+    // Drop the database and recreate it
+    dropDatabaseAsOwner();
+    IDatabaseSvc& dbSvc = databaseService();
+    IDatabasePtr db = dbSvc.createDatabase( m_connectOwner );
+    //cool::Sleep(1); // TEMPORARY? Patch for ORA-01466
+
+    // Create two new folders (one SV, one MV) with the same payload spec
+    IFolderPtr fSV = db->createFolder
+      ( m_fNameSV, m_payloadSpec, "", FolderVersioning::SINGLE_VERSION, true );
+    IFolderPtr fMV = db->createFolder
+      ( m_fNameMV, m_payloadSpec, "", FolderVersioning::MULTI_VERSION, true );
+
+    // Create an empty folder set
+    db->createFolderSet( m_fsName, "", true );
+
+    // Store some IOVs in the two folders
+    fSV->storeObject(  0, ValidityKeyMax, dummyPayload( 1 ), m_chId );
+    fSV->storeObject( 10, ValidityKeyMax, dummyPayload( 2 ), m_chId );
+    fSV->storeObject( 20, ValidityKeyMax, dummyPayload( 3 ), m_chId );
+    m_expSV = 3; // #IOVs in HEAD [0,10] [10,20] [20,+inf]
+    fMV->storeObject(  0, 100, dummyPayload( 1 ), m_chId );
+    fMV->storeObject( 10,  20, dummyPayload( 2 ), m_chId );
+    fMV->storeObject( 20,  30, dummyPayload( 3 ), m_chId );
+    m_tagMV = "MYTAG";
+    fMV->tagCurrentHead( m_tagMV, "Description of " + m_tagMV );
+    m_expMVtag = 4; // #IOVs in MYTAG [0,10] [10,20] [20,30] [30,100]
+    fMV->storeObject( 30,  40, dummyPayload( 4 ), m_chId );
+    m_expMVhead = 5; // #IOVs in HEAD [0,10] [10,20] [20,30] [30,40] [40,100]
+
+    // Grant the appropriate rights to the appropriate users
+    // Nothing to do for the owner (already owner) and the no-privilege role
+    RalDatabase* ralDb = dynamic_cast<RalDatabase*>( db.get() );
+    RalPrivilegeManager prMgr( ralDb );
+    std::string user;
+    // --- Reader
+    user = userForRole( READER );
+    prMgr.grantReaderPrivileges( user );
+    //prMgr.revokeWriterPrivileges( user );
+    //prMgr.revokeTaggerPrivileges( user );
+    // --- Writer
+    user = userForRole( WRITER );
+    prMgr.grantReaderPrivileges( user );
+    prMgr.grantWriterPrivileges( user );
+    //prMgr.revokeTaggerPrivileges( user );
+    // --- Tagger
+    user = userForRole( TAGGER );
+    bool retag = true; // grant retag privileges
+    prMgr.grantReaderPrivileges( user ); 
+    //prMgr.revokeWriterPrivileges( user );
+    prMgr.grantTaggerPrivileges( user, retag );
+
+  }
+  
+  //---------------------------------------------------------------------------
+
+  void test_CreateDatabase() 
+  {
+    std::string status;
+    const std::string statusOk = "OK - Database created";
+    const std::string statusTableNotCreated = "Not OK - Table not created";
+    const std::string statusCoolExc = "Not OK - Unknown COOL exception";
+    const std::string statusSealExc = "Not OK - Unknown SEAL exception";
+    const std::string statusStdExc = "Not OK - Unknown std::exception";
+    const std::string statusUnknown = "Not OK - Unknown exception";
+    try {
+      IDatabaseSvc& dbSvc = databaseService();
+      dbSvc.createDatabase( m_connect );
+      status = statusOk;
+    } catch ( pool::RelationalTableNotCreated& /* dummy */ ) {
+      status = statusTableNotCreated; 
+    } catch ( cool::Exception& e ) {
+      std::cout << "cool::Exception caught: '" << e.message() <<"'"<<std::endl;
+      status = statusCoolExc; 
+    } catch ( seal::Exception& e ) {
+      std::cout << "seal::Exception caught: '" << e.message() <<"'"<<std::endl;
+      status = statusSealExc; 
+    } catch( std::exception& se ) {
+      std::cout << "std::exception caught: '" << se.what() << "'" << std::endl;
+      status = statusStdExc; 
+    } catch ( ... ) {
+      std::cout << "Unknown exception caught" << std::endl;
+      status = statusUnknown; 
+    }    
+    
+    // Different results are expected for different roles
+    std::string msg = std::string( "Create database as user " ) +  m_user;
+    if ( m_role == OWNER ) {
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( msg, statusOk, status );
+    } 
+    else if ( m_role == READER ) {
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( msg, statusTableNotCreated, status );
+    } 
+    else if ( m_role == WRITER ) {
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( msg, statusTableNotCreated, status );
+    } 
+    else if ( m_role == TAGGER ) {
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( msg, statusTableNotCreated, status );
+    } 
+    else if ( m_role == NOPRIV ) {
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( msg, statusTableNotCreated, status );
+    } 
+    else {
+      std::cout << "PANIC! Unknown role type" << std::endl;
+      exit( -1 );
+    }    
+  }  
+  
+  //---------------------------------------------------------------------------
+
+  const bool test_OpenDatabase() 
+  {
+    std::string status;
+    const std::string statusOk = "OK - Database opened";
+    const std::string statusNotFound = "Not OK - Database not found";
+    const std::string statusCoolExc = "Not OK - Unknown COOL exception";
+    const std::string statusSealExc = "Not OK - Unknown SEAL exception";
+    const std::string statusStdExc = "Not OK - Unknown std::exception";
+    const std::string statusUnknown = "Not OK - Unknown exception";
+    try {
+      IDatabaseSvc& dbSvc = databaseService();
+      m_db = dbSvc.openDatabase( m_connect, false );
+      status = statusOk;
+    } catch ( DatabaseDoesNotExist& /* dummy */ ) {
+      status = statusNotFound; 
+    } catch ( cool::Exception& e ) {
+      std::cout << "cool::Exception caught: '" << e.message() <<"'"<<std::endl;
+      status = statusCoolExc; 
+    } catch ( seal::Exception& e ) {
+      std::cout << "seal::Exception caught: '" << e.message() <<"'"<<std::endl;
+      status = statusSealExc; 
+    } catch( std::exception& se ) {
+      std::cout << "std::exception caught: '" << se.what() << "'" << std::endl;
+      status = statusStdExc; 
+    } catch ( ... ) {
+      std::cout << "Unknown exception caught" << std::endl;
+      status = statusUnknown; 
+    }    
+    
+    // Different results are expected for different roles
+    std::string msg = std::string( "Open database as user " ) +  m_user;
+    if ( m_role == OWNER ) {
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( msg, statusOk, status );
+    } 
+    else if ( m_role == READER ) {
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( msg, statusOk, status );
+    } 
+    else if ( m_role == WRITER ) {
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( msg, statusOk, status );
+    } 
+    else if ( m_role == TAGGER ) {
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( msg, statusOk, status );
+    } 
+    else if ( m_role == NOPRIV ) {
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( msg, statusNotFound, status );
+    } 
+    else {
+      std::cout << "PANIC! Unknown role type" << std::endl;
+      exit( -1 );
+    }    
+
+    // Status code is needed to know if further tests can be performed
+    if ( status == statusOk ) return true;
+    else return false;
+    
+  }  
+  
+  //---------------------------------------------------------------------------
+  
+  void test_CreateNode( const std::string& fullPath, const bool isFolder ) 
+  {
+    std::string status;
+    const std::string statusOk = "OK - Node created";
+    const std::string statusTableNotCreated = "Not OK - Table not created";
+    const std::string statusRowNotUpdated = "Not OK - Row not updated";
+    const std::string statusCoolExc = "Not OK - Unknown COOL exception";
+    const std::string statusSealExc = "Not OK - Unknown SEAL exception";
+    const std::string statusStdExc = "Not OK - Unknown std::exception";
+    const std::string statusUnknown = "Not OK - Unknown exception";
+    try {
+      if ( isFolder ) 
+        m_db->createFolder
+          ( fullPath, 
+            m_payloadSpec, "", FolderVersioning::MULTI_VERSION, true );
+      else
+        m_db->createFolderSet
+          ( fullPath, "", true );
+      status = statusOk;
+    } catch ( pool::RelationalTableNotCreated& /* dummy */ ) {
+      status = statusTableNotCreated; 
+    } catch ( RowNotUpdated& /* dummy */ ) {
+      status = statusRowNotUpdated; 
+    } catch ( cool::Exception& e ) {
+      std::cout << "cool::Exception caught: '" << e.message() <<"'"<<std::endl;
+      status = statusCoolExc; 
+    } catch ( seal::Exception& e ) {
+      std::cout << "seal::Exception caught: '" << e.message() <<"'"<<std::endl;
+      status = statusSealExc; 
+    } catch( std::exception& se ) {
+      std::cout << "std::exception caught: '" << se.what() << "'" << std::endl;
+      status = statusStdExc; 
+    } catch ( ... ) {
+      std::cout << "Unknown exception caught" << std::endl;
+      status = statusUnknown; 
+    }    
+    
+    // Different results are expected for different roles
+    std::string msg = 
+      std::string( "Create node " ) + fullPath + " as user " +  m_user;
+    if ( m_role == OWNER ) {
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( msg, statusOk, status );
+    } 
+    else if ( m_role == READER ) {
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( msg, statusRowNotUpdated, status );
+    } 
+    else if ( m_role == WRITER ) {
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( msg, statusRowNotUpdated, status );
+    } 
+    else if ( m_role == TAGGER ) {
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( msg, statusRowNotUpdated, status );
+    } 
+    /*
+    else if ( m_role == NOPRIV ) {
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( msg, ???, status );
+    } 
+    */
+    else {
+      std::cout << "PANIC! Unknown role type" << std::endl;
+      exit( -1 );
+    }    
+  }  
+  
+  //---------------------------------------------------------------------------
+
+  void test_ReadIOVs( const std::string& fullPath, 
+                      const std::string& tagName, 
+                      const unsigned long nExpected ) 
+  {
+    std::string status;
+    const std::string statusOk = "OK - IOVs retrieved";
+    const std::string statusCoolExc = "Not OK - Unknown COOL exception";
+    const std::string statusSealExc = "Not OK - Unknown SEAL exception";
+    const std::string statusStdExc = "Not OK - Unknown std::exception";
+    const std::string statusUnknown = "Not OK - Unknown exception";
+    unsigned long nActual = 0;
+    try {
+      IFolderPtr folder = m_db->getFolder( fullPath );
+      IObjectIteratorPtr objs = 
+        folder->browseObjects
+        ( ValidityKeyMin, ValidityKeyMax, m_chId, tagName );
+      nActual = objs->size();
+      status = statusOk;
+    } catch ( cool::Exception& e ) {
+      std::cout << "cool::Exception caught: '" << e.message() <<"'"<<std::endl;
+      status = statusCoolExc; 
+    } catch ( seal::Exception& e ) {
+      std::cout << "seal::Exception caught: '" << e.message() <<"'"<<std::endl;
+      status = statusSealExc; 
+    } catch( std::exception& se ) {
+      std::cout << "std::exception caught: '" << se.what() << "'" << std::endl;
+      status = statusStdExc; 
+    } catch ( ... ) {
+      std::cout << "Unknown exception caught" << std::endl;
+      status = statusUnknown; 
+    }    
+    
+    // Different results are expected for different roles
+    std::string msg = 
+      std::string( "Read IOVs of folder " ) + fullPath + " in tag " + tagName 
+      + " as user " +  m_user;
+    if ( m_role == OWNER ) {
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( msg, statusOk, status );
+    } 
+    else if ( m_role == READER ) {
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( msg, statusOk, status );
+    } 
+    else if ( m_role == WRITER ) {
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( msg, statusOk, status );
+    } 
+    else if ( m_role == TAGGER ) {
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( msg, statusOk, status );
+    } 
+    /*
+    else if ( m_role == NOPRIV ) {
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( msg, ???, status );
+    } 
+    */
+    else {
+      std::cout << "PANIC! Unknown role type" << std::endl;
+      exit( -1 );
+    }    
+
+    // Also test that the expected number of IOVS was actually retrieved 
+    if ( status == statusOk ) 
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( msg + ": IOV count", nExpected, nActual );
+  }  
+  
+  //---------------------------------------------------------------------------
+
+  void test_TagIOVs( const std::string& fullPath,
+                     const std::string& tagName,
+                     const bool retag,
+                     const unsigned long nExpected )
+  {
+    std::string status;
+    const std::string statusOk = "OK - IOVs tagged";
+    const std::string statusFolderSV = "Not OK - Single version folder";
+    const std::string statusRowNotInserted = "Not OK - Row not inserted";
+    const std::string statusRowNotUpdated = "Not OK - Row not updated";
+    const std::string statusRowNotDeleted = "Not OK - Row not deleted";
+    const std::string statusCoolExc = "Not OK - Unknown COOL exception";
+    const std::string statusSealExc = "Not OK - Unknown SEAL exception";
+    const std::string statusStdExc = "Not OK - Unknown std::exception";
+    const std::string statusUnknown = "Not OK - Unknown exception";
+    unsigned long nActual = 0;
+    try {
+      IFolderPtr folder = m_db->getFolder( fullPath );
+      bool existsTag = m_db->existsTag( tagName );
+      if ( retag ) {
+        if ( ! existsTag ) 
+          throw Exception
+            ( "PANIC! Tag for retagging does not exist", "test_TagIOVs" );
+        folder->deleteTag( tagName );
+      } else {
+        if ( existsTag ) 
+          throw Exception
+            ( "PANIC! Tag for new tagging already exists", "test_TagIOVs" );
+      }
+      folder->tag( tagName, "Description of " + tagName );
+      IObjectIteratorPtr objs =
+        folder->browseObjects
+        ( ValidityKeyMin, ValidityKeyMax, m_chId, tagName );
+      nActual = objs->size();
+      status = statusOk;
+    } catch ( FolderIsSingleVersion& /* dummy */ ) {
+      status = statusFolderSV; 
+    } catch ( RowNotInserted& /* dummy */ ) {
+      status = statusRowNotInserted; 
+    } catch ( RowNotUpdated& /* dummy */ ) {
+      status = statusRowNotUpdated; 
+    } catch ( RowNotDeleted& /* dummy */ ) {
+      status = statusRowNotDeleted; 
+    } catch ( cool::Exception& e ) {
+      std::cout << "cool::Exception caught: '" << e.message() <<"'"<<std::endl;
+      status = statusCoolExc; 
+    } catch ( seal::Exception& e ) {
+      std::cout << "seal::Exception caught: '" << e.message() <<"'"<<std::endl;
+      status = statusSealExc; 
+    } catch( std::exception& se ) {
+      std::cout << "std::exception caught: '" << se.what() << "'" << std::endl;
+      status = statusStdExc; 
+    } catch ( ... ) {
+      std::cout << "Unknown exception caught" << std::endl;
+      status = statusUnknown; 
+    }    
+    
+    // Different results are expected for different roles
+    std::string msg;
+    if ( retag ) 
+      msg = std::string( "Retag IOVs in folder " ) + fullPath
+        + " with tag " + tagName + " as user " +  m_user;
+    else
+      msg = std::string( "Tag IOVs in folder " ) + fullPath
+        + " with tag " + tagName + " as user " +  m_user;
+    if ( m_role == OWNER ) {
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( msg, statusOk, status );
+    } 
+    else if ( m_role == READER ) {
+      if ( !retag ) 
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( msg, statusRowNotUpdated, status );
+      else 
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( msg, statusRowNotDeleted, status );
+    } 
+    else if ( m_role == WRITER ) {
+      if ( !retag ) 
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( msg, statusRowNotUpdated, status );
+      else 
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( msg, statusRowNotDeleted, status );
+    } 
+    else if ( m_role == TAGGER ) {
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( msg, statusOk, status );
+    } 
+    /*
+    else if ( m_role == NOPRIV ) {
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( msg, ???, status );
+    } 
+    */
+    else {
+      std::cout << "PANIC! Unknown role type" << std::endl;
+      exit( -1 );
+    }    
+
+    // Also test that the expected number of IOVs was retrieved 
+    if ( status == statusOk ) 
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( msg + ": IOV count", nExpected, nActual );
+  }  
+  
+  //---------------------------------------------------------------------------
+
+  void test_InsertIOVs( const std::string& fullPath,
+                        const bool singleVersion )
+  {
+    std::string status;
+    const std::string statusOk = "OK - IOVs inserted";
+    const std::string statusRowNotInserted = "Not OK - Row not inserted";
+    const std::string statusRowNotUpdated = "Not OK - Row not updated";
+    const std::string statusCoolExc = "Not OK - Unknown COOL exception";
+    const std::string statusSealExc = "Not OK - Unknown SEAL exception";
+    const std::string statusStdExc = "Not OK - Unknown std::exception";
+    const std::string statusUnknown = "Not OK - Unknown exception";
+    unsigned long nExpected;
+    unsigned long nActual = 0;
+    try {
+      IFolderPtr folder = m_db->getFolder( fullPath );
+      if ( singleVersion ) {
+        folder->storeObject(  50, ValidityKeyMax, dummyPayload( 11 ), m_chId );
+        folder->storeObject( 100, ValidityKeyMax, dummyPayload( 12 ), m_chId );
+        // New HEAD: [0,10] [10,20] [20,50] [50,100] [100,+inf]
+        nExpected = 5;
+      } 
+      else {
+        folder->storeObject(  50,  100, dummyPayload( 11 ), m_chId );
+        folder->storeObject(  60,   80, dummyPayload( 12 ), m_chId );
+        // New HEAD: [0,10][10,20][20,30][30,40][40,50][50,60][60,80][80,100]
+        nExpected = 8;
+      }
+      IObjectIteratorPtr objs = 
+        folder->browseObjects
+        ( ValidityKeyMin, ValidityKeyMax, m_chId, "" );
+      nActual = objs->size();
+      status = statusOk;
+    } catch ( RowNotInserted& /* dummy */ ) {
+      status = statusRowNotInserted; 
+    } catch ( RowNotUpdated& /* dummy */ ) {
+      status = statusRowNotUpdated; 
+    } catch ( cool::Exception& e ) {
+      std::cout << "cool::Exception caught: '" << e.message() <<"'"<<std::endl;
+      status = statusCoolExc; 
+    } catch ( seal::Exception& e ) {
+      std::cout << "seal::Exception caught: '" << e.message() <<"'"<<std::endl;
+      status = statusSealExc; 
+    } catch( std::exception& se ) {
+      std::cout << "std::exception caught: '" << se.what() << "'" << std::endl;
+      status = statusStdExc; 
+    } catch ( ... ) {
+      std::cout << "Unknown exception caught" << std::endl;
+      status = statusUnknown; 
+    }    
+    
+    // Different results are expected for different roles
+    std::string msg = 
+      std::string( "Insert IOVs into folder " ) + fullPath
+      + " as user " +  m_user;
+    if ( m_role == OWNER ) {
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( msg, statusOk, status );
+    } 
+    else if ( m_role == READER ) {
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( msg, statusRowNotUpdated, status );
+    } 
+    else if ( m_role == WRITER ) {
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( msg, statusOk, status );
+    } 
+    else if ( m_role == TAGGER ) {
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( msg, statusRowNotUpdated, status );
+    } 
+    /*
+    else if ( m_role == NOPRIV ) {
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( msg, ???, status );
+    } 
+    */
+    else {
+      std::cout << "PANIC! Unknown role type" << std::endl;
+      exit( -1 );
+    }    
+
+    // Also test that the expected number of IOVs was retrieved 
+    if ( status == statusOk ) 
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( msg + ": IOV count", nExpected, nActual );
+  }  
+  
+  //---------------------------------------------------------------------------
+
+  void test_DropNode( const std::string& fullPath, const bool isFolder ) 
+  {
+    std::string status;
+    const std::string statusOk = "OK - Node dropped";
+    const std::string statusNotFound = "Not OK - Node not found";
+    const std::string statusTableNotDropped = "Not OK - Table not dropped";
+    const std::string statusRowNotDeleted = "Not OK - Row not deleted";
+    const std::string statusCoolExc = "Not OK - Unknown COOL exception";
+    const std::string statusSealExc = "Not OK - Unknown SEAL exception";
+    const std::string statusStdExc = "Not OK - Unknown std::exception";
+    const std::string statusUnknown = "Not OK - Unknown exception";
+    try {
+      m_db->dropNode( fullPath );
+      status = statusOk;
+    } catch ( FolderNotFound& /* dummy */ ) {
+      status = statusNotFound; 
+    } catch ( FolderSetNotFound& /* dummy */ ) {
+      status = statusNotFound; 
+    } catch ( TableNotDropped& /* dummy */ ) {
+      status = statusTableNotDropped; 
+    } catch ( RowNotDeleted& /* dummy */ ) {
+      status = statusRowNotDeleted; 
+    } catch ( cool::Exception& e ) {
+      std::cout << "cool::Exception caught: '" << e.message() <<"'"<<std::endl;
+      status = statusCoolExc; 
+    } catch ( seal::Exception& e ) {
+      std::cout << "seal::Exception caught: '" << e.message() <<"'"<<std::endl;
+      status = statusSealExc; 
+    } catch( std::exception& se ) {
+      std::cout << "std::exception caught: '" << se.what() << "'" << std::endl;
+      status = statusStdExc; 
+    } catch ( ... ) {
+      std::cout << "Unknown exception caught" << std::endl;
+      status = statusUnknown; 
+    }    
+    
+    // Different results are expected for different roles
+    std::string msg = 
+      std::string( "Drop node " ) + fullPath + " as user " +  m_user;
+    if ( m_role == OWNER ) {
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( msg, statusOk, status );
+    } 
+    else if ( m_role == READER ) {
+      if ( isFolder ) 
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( msg, statusTableNotDropped, status );
+      else 
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( msg, statusRowNotDeleted, status );
+    } 
+    else if ( m_role == WRITER ) {
+      if ( isFolder ) 
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( msg, statusTableNotDropped, status );
+      else 
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( msg, statusRowNotDeleted, status );
+    } 
+    else if ( m_role == TAGGER ) {
+      if ( isFolder ) 
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( msg, statusTableNotDropped, status );
+      else 
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( msg, statusRowNotDeleted, status );  
+    } 
+    /*
+    else if ( m_role == NOPRIV ) {
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( msg, ???, status );
+    } 
+    */
+    else {
+      std::cout << "PANIC! Unknown role type" << std::endl;
+      exit( -1 );
+    }    
+  }  
+  
+  //---------------------------------------------------------------------------
+
+  void test_DropDatabase() 
+  {
+    std::string status;
+    const std::string statusOk = "OK - Database dropped";
+    const std::string statusNotFound = "Not OK - Database not found";
+    const std::string statusTableNotDropped = "Not OK - Table not dropped";
+    const std::string statusRowNotDeleted = "Not OK - Row not deleted";
+    const std::string statusCoolExc = "Not OK - Unknown COOL exception";
+    const std::string statusSealExc = "Not OK - Unknown SEAL exception";
+    const std::string statusStdExc = "Not OK - Unknown std::exception";
+    const std::string statusUnknown = "Not OK - Unknown exception";
+    try {
+      IDatabaseSvc& dbSvc = databaseService();
+      dbSvc.dropDatabase( m_connect );
+      status = statusOk;
+    } catch ( DatabaseDoesNotExist& /* dummy */ ) {
+      status = statusNotFound; 
+    } catch ( TableNotDropped& /* dummy */ ) {
+      status = statusTableNotDropped; 
+    } catch ( RowNotDeleted& /* dummy */ ) {
+      status = statusRowNotDeleted; 
+    } catch ( cool::Exception& e ) {
+      std::cout << "cool::Exception caught: '" << e.message() <<"'"<<std::endl;
+      status = statusCoolExc; 
+    } catch ( seal::Exception& e ) {
+      std::cout << "seal::Exception caught: '" << e.message() <<"'"<<std::endl;
+      status = statusSealExc; 
+    } catch( std::exception& se ) {
+      std::cout << "std::exception caught: '" << se.what() << "'" << std::endl;
+      status = statusStdExc; 
+    } catch ( ... ) {
+      std::cout << "Unknown exception caught" << std::endl;
+      status = statusUnknown; 
+    }    
+    
+    // Different results are expected for different roles
+    std::string msg = std::string( "Drop database as user " ) +  m_user;
+    if ( m_role == OWNER ) {
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( msg, statusOk, status );
+    } 
+    else if ( m_role == READER ) {
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( msg, statusRowNotDeleted, status );
+    } 
+    else if ( m_role == WRITER ) {
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( msg, statusRowNotDeleted, status );
+    } 
+    else if ( m_role == TAGGER ) {
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( msg, statusRowNotDeleted, status );
+    } 
+    /*
+    else if ( m_role == NOPRIV ) {
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( msg, ???, status );
+    } 
+    */
+    else {
+      std::cout << "PANIC! Unknown role type" << std::endl;
+      exit( -1 );
+    }    
+  }  
+  
+  //---------------------------------------------------------------------------
+
+  void testAll_Role( const Role role ) 
+  {
+    m_role = role;
+    try {
+
+      getConnectString();
+
+      dropDatabaseAsOwner();
+      std::cout << "==> Start TEST: create database" << std::endl;
+      test_CreateDatabase();
+      std::cout << "++++> End TEST: create database" << std::endl;
+
+      createDatabaseAsOwner();
+      std::cout << "==> Start TEST: open database" << std::endl;
+      bool openOK = test_OpenDatabase();
+      std::cout << "++++> End TEST: open database" << std::endl;
+
+      // Execute these tests only if the database can be opened
+      if ( openOK ) {
+
+        std::cout << "==> Start TEST: create new MV folder" << std::endl;
+        test_CreateNode( m_fNameMV + "_new", true );
+        std::cout << "++++> End TEST: create new MV folder" << std::endl;
+
+        std::cout << "==> Start TEST: create new folder set" << std::endl;
+        test_CreateNode( m_fsName + "_new", false );
+        std::cout << "++++> End TEST: create new folder set" << std::endl;
+
+        std::cout << "==> Start TEST: read SV IOVs" << std::endl;
+        test_ReadIOVs( m_fNameSV, "", m_expSV );
+        std::cout << "++++> End TEST: read SV IOVs" << std::endl;
+
+        std::cout << "==> Start TEST: read MV IOVs head" << std::endl;
+        test_ReadIOVs( m_fNameMV, "", m_expMVhead );
+        std::cout << "++++> End TEST: read MV IOVs head" << std::endl;
+
+        std::cout << "==> Start TEST: read MV IOVs mytag" << std::endl;
+        test_ReadIOVs( m_fNameMV, m_tagMV, m_expMVtag );
+        std::cout << "++++> End TEST: read MV IOVs mytag" << std::endl;
+
+        std::cout << "==> Start TEST: tag MV IOVs" << std::endl;
+        test_TagIOVs( m_fNameMV, m_tagMV + "_new", false, m_expMVhead );
+        std::cout << "++++> End TEST: tag MV IOVs" << std::endl;
+
+        std::cout << "==> Start TEST: retag MV IOVs" << std::endl;
+        test_TagIOVs( m_fNameMV, m_tagMV, true, m_expMVhead );
+        std::cout << "++++> End TEST: retag MV IOVs" << std::endl;
+
+        std::cout << "==> Start TEST: insert SV IOVs" << std::endl;
+        test_InsertIOVs( m_fNameSV, true );
+        std::cout << "++++> End TEST: insert SV IOVs" << std::endl;
+
+        std::cout << "==> Start TEST: insert MV IOVs" << std::endl;
+        test_InsertIOVs( m_fNameMV, false );
+        std::cout << "++++> End TEST: insert MV IOVs" << std::endl;
+
+        std::cout << "==> Start TEST: drop SV folder" << std::endl;
+        test_DropNode( m_fNameSV, true );
+        std::cout << "++++> End TEST: drop SV folder" << std::endl;
+
+        std::cout << "==> Start TEST: drop MV folder" << std::endl;
+        test_DropNode( m_fNameMV, true );
+        std::cout << "++++> End TEST: drop MV folder" << std::endl;
+
+        std::cout << "==> Start TEST: drop folderset" << std::endl;
+        test_DropNode( m_fsName, false );
+        std::cout << "++++> End TEST: drop folderset" << std::endl;
+
+        std::cout << "==> Start TEST: drop database" << std::endl;
+        test_DropDatabase();
+        std::cout << "++++> End TEST: drop database" << std::endl;
+
+      }
+
+      // Skip these tests if the database cannot even be opened
+      else {
+        std::cout << "**** SKIP TEST: create new MV folder" << std::endl;
+        std::cout << "**** SKIP TEST: create new folderset" << std::endl;
+        std::cout << "**** SKIP TEST: drop SV folder" << std::endl;
+        std::cout << "**** SKIP TEST: drop MV folder" << std::endl;
+        std::cout << "**** SKIP TEST: drop folderset" << std::endl;
+        std::cout << "**** SKIP TEST: drop database" << std::endl;
+      }
+      
+    } 
+
+    catch ( cool::Exception& e ) {
+      std::cout << "cool::Exception caught: '" << e.message()<<"'"<< std::endl;
+      std::cout << "++++++++++++++++++++++++++++++++++++++++++++" << std::endl;
+      throw;
+    } 
+
+    catch ( seal::Exception& e ) {
+      std::cout << "seal::Exception caught: '" << e.message()<<"'"<< std::endl;
+      std::cout << "++++++++++++++++++++++++++++++++++++++++++++" << std::endl;
+      throw;
+    } 
+
+    /*
+    // Comment this out: each CPPUNIT failure is itself an std::exception!
+    catch ( std::exception& se ) {
+      std::cout << "std::exception caught: '" << se.what() << "'" << std::endl;
+      std::cout << "++++++++++++++++++++++++++++++++++++++++++++" << std::endl;
+      throw;
+    } 
+    */
+
+    catch ( ... ) {
+      std::cout << "UNKNOWN exception caught!" << std::endl;
+      std::cout << "++++++++++++++++++++++++++++++++++++++++++++" << std::endl;
+      throw;
+    }
+
+    std::cout << "++++++++++++++++++++++++++++++++++++++++++++" << std::endl;
+  }  
+  
+  //---------------------------------------------------------------------------
+
+  void testAll_Owner() {
+    testAll_Role( OWNER );
+  }  
+  
+  void testAll_Reader() {
+    testAll_Role( READER );
+  }  
+  
+  void testAll_Writer() {
+    testAll_Role( WRITER );
+  }  
+  
+  void testAll_Tagger() {
+    testAll_Role( TAGGER );
+  }  
+  
+  void testAll_NoPriv() {
+    testAll_Role( NOPRIV );
+  }  
+  
+  //---------------------------------------------------------------------------
+
+  pool::AttributeList dummyPayload( int index ) {
+    pool::AttributeList payload( m_payloadSpec );
+    payload["A_INT"].setValue<int>( index );
+    payload["A_FLOAT"].setValue<float>( (float)(index/1000.) );
+    std::stringstream s;
+    s << "Object " << index;
+    payload["A_STRING"].setValue<std::string>( s.str() );
+    return payload;
+  }
+
+  void setUp() {
+    m_role = NONE;
+    m_connectOwner = "";
+    m_userOwner = "";
+    m_connect = "";
+    m_user = "";
+    IDatabasePtr dbNull;
+    m_db = dbNull;
+    if ( m_payloadSpec.size() == 0 ) {
+      m_payloadSpec.push_back( "A_INT", "int" );
+      m_payloadSpec.push_back( "A_FLOAT", "float" );
+      m_payloadSpec.push_back( "A_STRING", "string" );
+    }
+    m_fNameSV = "/my/folderSV";
+    m_fNameMV = "/my/folderMV";
+    m_fsName = "/my/folderset";
+    m_chId = 0;
+  }
+  
+  void tearDown() {
+    m_db.reset();
+  }  
+  
+  //---------------------------------------------------------------------------
+
+};
+
+CPPUNIT_TEST_SUITE_REGISTRATION( cool::PrivilegesTest );
+#include<CppUnit_testdriver.icpp>
+
+//-----------------------------------------------------------------------------
+
+
+#endif // NOPORT
diff --git a/RelationalCool/tests/ProcMemory/test_ProcMemory.cpp b/RelationalCool/tests/ProcMemory/test_ProcMemory.cpp
new file mode 100644
index 000000000..654dab1b8
--- /dev/null
+++ b/RelationalCool/tests/ProcMemory/test_ProcMemory.cpp
@@ -0,0 +1,51 @@
+// $Id: test_ProcMemory.cpp,v 1.4 2008-08-06 09:33:07 avalassi Exp $
+
+// Include files
+#include <iostream>
+#include <sstream>
+#include <string>
+
+// Local include files
+#include "../../src/ProcMemory.h"
+#include "src/sleep.h"
+
+// Message output
+#define LOG std::cout << "__main "
+
+//-----------------------------------------------------------------------------
+
+int main ( int /* argc */, char* /* argv[] */ )
+{
+  long sleepSec = 0;
+  ProcMemory* mem = new ProcMemory();
+  LOG << "-----------------------------------------------------" << std::endl;
+  LOG << "START of JOB" << std::endl;
+  mem->printVm();
+  LOG << "-----------------------------------------------------" << std::endl;
+  cool::sleep(sleepSec);
+  LOG << "malloc 1MB " << std::endl;
+  void* p1m = malloc( 1048576 );
+  mem->printVm();
+  LOG << "-----------------------------------------------------" << std::endl;
+  cool::sleep(sleepSec);
+  LOG << "malloc 100MB " << std::endl;
+  void* p100m = malloc( 104857600 );
+  mem->printVm();
+  LOG << "-----------------------------------------------------" << std::endl;
+  cool::sleep(sleepSec);
+  LOG << "free 1MB " << std::endl;
+  free ( p1m );
+  mem->printVm();
+  LOG << "-----------------------------------------------------" << std::endl;
+  cool::sleep(sleepSec);
+  LOG << "free 100MB " << std::endl;
+  LOG << "END of JOB" << std::endl;
+  free ( p100m );
+  mem->printVm();
+  LOG << "-----------------------------------------------------" << std::endl;
+  cool::sleep(sleepSec);
+  delete mem;
+}
+
+//----------------------------------------------------------------------------
+
diff --git a/RelationalCool/tests/RalDatabase/README.threads b/RelationalCool/tests/RalDatabase/README.threads
new file mode 100644
index 000000000..3b5c8ece6
--- /dev/null
+++ b/RelationalCool/tests/RalDatabase/README.threads
@@ -0,0 +1,51 @@
+2005.07.14
+
+Problem with pthread_mutex_lock is solved!
+
+It was indeed enough to remove OCI_THREADED in OracleSession.cpp.
+
+This was tested using a private version of POOL.
+With respect to POOL_2_1_1-beta, the following changes were made:
+
+  // AV 2005.07.13 - start
+  // Test if OCI_THREADED __alone__ is responsible for COOL pthread_mutex_lock
+  //sword status = OCIEnvCreate( &m_environmentHandle,
+  //                             OCI_OBJECT,
+  //                             0,0,0,0,0,0 );
+  sword status;
+  if ( getenv ( "COOL_OCI_THREADED" ) )
+    status = OCIEnvCreate( &m_environmentHandle,
+                           OCI_THREADED | OCI_OBJECT,
+                           0,0,0,0,0,0 );
+  else
+    status = OCIEnvCreate( &m_environmentHandle,
+                           OCI_OBJECT,
+                           0,0,0,0,0,0 );
+  // AV 2005.07.13 - end
+
+The test RalDatabaseTest::dropDatabase was executed alone
+(all tests but dropDatabase were disabled in RalDatabaseTest),
+with and without COOL_OCI_THREADED set:
+
+coolDropDatabase.csh $COOLTESTDB
+unsetenv COOL_OCI_THREADED
+date ; unitTest_RelationalCool_RalDatabase > & dropDatabaseTest.out.OCI_DEFAULT ; date
+setenv COOL_OCI_THREADED on
+date ; unitTest_RelationalCool_RalDatabase > & dropDatabaseTest.out.OCI_THREADED ; date
+[Interrupted by Ctrl-C]
+date
+unsetenv COOL_OCI_THREADED
+date ; unitTest_RelationalCool_RalDatabase > & dropDatabaseTest.out.OCI_DEFAULT.2 ; date
+
+The first and third job, with OCI_THREADED disabled, completed successfully
+in around 30 seconds. The second job, with OCI_THREADED enabled, got stuck
+and was killed with Ctrl-C after 2 minutes. The stack dump shows indeed
+the problem with pthread_mutex_lock.
+
+The outputs from the first and second jobs are included in CVS
+(not the output from the third job, which is similar to that 
+of the first one and was only meant as an additional cross-check).
+
+Problem solved!! :-)
+
+
diff --git a/RelationalCool/tests/RalDatabase/dropDatabaseTest.out.OCI_DEFAULT b/RelationalCool/tests/RalDatabase/dropDatabaseTest.out.OCI_DEFAULT
new file mode 100644
index 000000000..3c79ac646
--- /dev/null
+++ b/RelationalCool/tests/RalDatabase/dropDatabaseTest.out.OCI_DEFAULT
@@ -0,0 +1,229 @@
+(Start: Thu Jul 14 10:32:06 CEST 2005)
+Property Catalogue: level[Info] Adding property: OutputLevel = 2 in scope "SEAL/Services/MessageService"
+Property Catalogue: level[Info] Adding property: Format =  "%-36s %-8s %s" in scope "SEAL/Services/MessageService"
+Property Catalogue: level[Info] Adding property: AuthenticationFile =  "/afs/cern.ch/user/a/avalassi/private/authentication.xml" in scope "POOL/Services/XMLAuthenticationService"
+MessageService callback    Debug MessageService output level changed to Debug
+ConfigurationService    Debug Setting property: "Format" to value " "%-36s %-8s %s"" in scope "SEAL/Services/MessageService"
+Application                          Info     Instantiate a COOL Application
+Application                          Info     Load the COOL database service
+RalDatabaseSvc                       Info     Instantiate the RalDatabaseSvc
+RalDatabaseSvc                       Info     Load the POOL relational service
+POOL/Services/RelationalService      Info     Found plugin for RDBMS technology "mysql" with implementation "odbc"
+POOL/Services/RelationalService      Info     Found plugin for RDBMS technology "oracle" with native implementation
+POOL/Services/RelationalService      Info     Found plugin for RDBMS technology "sqlite" with native implementation
+POOL/Services/RelationalService      Info     Default implementation for RDBMS technology "mysql" is "odbc"
+POOL/Services/RelationalService      Info     Default implementation for RDBMS technology "oracle" is native
+POOL/Services/RelationalService      Info     Default implementation for RDBMS technology "sqlite" is native
+RalDatabaseSvc                       Info     Load the POOL XML authentication service
+ConfigurationService                 Debug    Setting property: "AuthenticationFile" to value " "/afs/cern.ch/user/a/avalassi/private/authentication.xml"" in scope "POOL/Services/XMLAuthenticationService"
+RelationalDatabase                   Debug    Instantiate a RelationalDatabase for 'oracle://devdb10;schema=lcg_cool;dbname=COOLTEST'
+RelationalDatabase                   Info     Instantiate a RalDatabase for 'oracle://devdb10;schema=lcg_cool;dbname=COOLTEST'
+RalAuthenticationManager             Debug    Retrieve COOL authentication credentials for 'oracle://devdb10;schema=lcg_cool;dbname=COOLTEST'
+RalAuthenticationManager             Debug    Retrieve COOL authentication credentials using an authentication service 
+RalAuthenticationManager             Debug    Credentials found for 'oracle://devdb10;schema=lcg_cool'
+RalAuthenticationManager             Debug    COOL authentication credentials successfully retrieved
+POOL/RelationalPlugins/oracle        Info     Connected to a server running Oracle version 10.1.0.4.0
+RelationalDatabase                   Info     Delete the RalDatabase for 'oracle://devdb10;schema=lcg_cool;dbname=COOLTEST'
+POOL/RelationalPlugins/oracle        Warning  No active transaction to roll back
+RelationalDatabase                   Debug    Delete the RelationalDatabase for 'oracle://devdb10;schema=lcg_cool;dbname=COOLTEST'
+RelationalDatabase                   Debug    Instantiate a RelationalDatabase for 'oracle://devdb10;schema=lcg_cool;dbname=COOLTEST'
+RelationalDatabase                   Info     Instantiate a RalDatabase for 'oracle://devdb10;schema=lcg_cool;dbname=COOLTEST'
+RalAuthenticationManager             Debug    Retrieve COOL authentication credentials for 'oracle://devdb10;schema=lcg_cool;dbname=COOLTEST'
+RalAuthenticationManager             Debug    Retrieve COOL authentication credentials using an authentication service 
+RalAuthenticationManager             Debug    Credentials found for 'oracle://devdb10;schema=lcg_cool'
+RalAuthenticationManager             Debug    COOL authentication credentials successfully retrieved
+POOL/RelationalPlugins/oracle        Info     Connected to a server running Oracle version 10.1.0.4.0
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "CREATE TABLE "LCG_COOL"."COOLTEST_DB_ATTRIBUTES" ( "DB_ATTRIBUTE_NAME" VARCHAR2(255) )"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "ALTER TABLE "LCG_COOL"."COOLTEST_DB_ATTRIBUTES" ADD (CONSTRAINT "COOLTEST_DB_ATTRIBUTES_PK" PRIMARY KEY ("DB_ATTRIBUTE_NAME") )"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT ALL_CONS_COLUMNS.COLUMN_NAME FROM ALL_CONSTRAINTS, ALL_CONS_COLUMNS WHERE ALL_CONSTRAINTS.OWNER = 'LCG_COOL' AND ALL_CONSTRAINTS.TABLE_NAME = 'COOLTEST_DB_ATTRIBUTES' AND ALL_CONSTRAINTS.CONSTRAINT_TYPE = 'U' AND ALL_CONS_COLUMNS.CONSTRAINT_NAME = ALL_CONSTRAINTS.CONSTRAINT_NAME AND ALL_CONS_COLUMNS.OWNER = ALL_CONSTRAINTS.OWNER AND ALL_CONS_COLUMNS.TABLE_NAME = ALL_CONSTRAINTS.TABLE_NAME"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT A.CONSTRAINT_NAME, B.COLUMN_NAME FROM ALL_CONSTRAINTS A, ALL_CONS_COLUMNS B WHERE A.OWNER = 'LCG_COOL' AND A.TABLE_NAME = 'COOLTEST_DB_ATTRIBUTES' AND A.CONSTRAINT_TYPE = 'P' AND B.OWNER = A.OWNER AND B.TABLE_NAME = A.TABLE_NAME AND B.CONSTRAINT_NAME = A.CONSTRAINT_NAME ORDER BY B.POSITION"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT A.CONSTRAINT_NAME AS FK_NAME, B.TABLE_NAME AS REF_TABLE, C.COLUMN_NAME AS FK_COL, D.COLUMN_NAME AS REF_COL FROM (SELECT CONSTRAINT_NAME, R_CONSTRAINT_NAME FROM ALL_CONSTRAINTS WHERE OWNER='LCG_COOL' AND TABLE_NAME = 'COOLTEST_DB_ATTRIBUTES' AND CONSTRAINT_TYPE='R') A, (SELECT TABLE_NAME, CONSTRAINT_NAME FROM ALL_CONSTRAINTS WHERE OWNER='LCG_COOL') B, (SELECT COLUMN_NAME, CONSTRAINT_NAME, POSITION FROM ALL_CONS_COLUMNS WHERE OWNER='LCG_COOL' AND TABLE_NAME='COOLTEST_DB_ATTRIBUTES' ORDER BY POSITION) C, (SELECT COLUMN_NAME, CONSTRAINT_NAME, TABLE_NAME, POSITION FROM ALL_CONS_COLUMNS WHERE OWNER='LCG_COOL') D WHERE A.R_CONSTRAINT_NAME = B.CONSTRAINT_NAME AND A.CONSTRAINT_NAME = C.CONSTRAINT_NAME AND B.CONSTRAINT_NAME = D.CONSTRAINT_NAME AND C.POSITION = D.POSITION ORDER BY FK_NAME, D.POSITION"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT A.INDEX_NAME, A.UNIQUENESS, B.COLUMN_NAME FROM ALL_INDEXES A, ALL_IND_COLUMNS B WHERE A.OWNER = 'LCG_COOL' AND A.TABLE_NAME = 'COOLTEST_DB_ATTRIBUTES' AND A.GENERATED = 'N' AND A.INDEX_NAME = B.INDEX_NAME AND B.INDEX_OWNER = A.OWNER AND B.TABLE_NAME = A.TABLE_NAME AND A.INDEX_NAME NOT IN (SELECT CONSTRAINT_NAME FROM ALL_CONSTRAINTS WHERE OWNER = A.OWNER AND TABLE_NAME = A.TABLE_NAME AND CONSTRAINT_TYPE = 'P') ORDER BY A.INDEX_NAME, B.COLUMN_POSITION"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "ALTER TABLE "LCG_COOL"."COOLTEST_DB_ATTRIBUTES" ADD ( "DB_ATTRIBUTE_VALUE" VARCHAR2(4000) )"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "INSERT INTO "LCG_COOL"."COOLTEST_DB_ATTRIBUTES" ("DB_ATTRIBUTE_NAME","DB_ATTRIBUTE_VALUE") VALUES (:"DB_ATTRIBUTE_NAME",:"DB_ATTRIBUTE_VALUE")"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "INSERT INTO "LCG_COOL"."COOLTEST_DB_ATTRIBUTES" ("DB_ATTRIBUTE_NAME","DB_ATTRIBUTE_VALUE") VALUES (:"DB_ATTRIBUTE_NAME",:"DB_ATTRIBUTE_VALUE")"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "INSERT INTO "LCG_COOL"."COOLTEST_DB_ATTRIBUTES" ("DB_ATTRIBUTE_NAME","DB_ATTRIBUTE_VALUE") VALUES (:"DB_ATTRIBUTE_NAME",:"DB_ATTRIBUTE_VALUE")"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "INSERT INTO "LCG_COOL"."COOLTEST_DB_ATTRIBUTES" ("DB_ATTRIBUTE_NAME","DB_ATTRIBUTE_VALUE") VALUES (:"DB_ATTRIBUTE_NAME",:"DB_ATTRIBUTE_VALUE")"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "INSERT INTO "LCG_COOL"."COOLTEST_DB_ATTRIBUTES" ("DB_ATTRIBUTE_NAME","DB_ATTRIBUTE_VALUE") VALUES (:"DB_ATTRIBUTE_NAME",:"DB_ATTRIBUTE_VALUE")"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "INSERT INTO "LCG_COOL"."COOLTEST_DB_ATTRIBUTES" ("DB_ATTRIBUTE_NAME","DB_ATTRIBUTE_VALUE") VALUES (:"DB_ATTRIBUTE_NAME",:"DB_ATTRIBUTE_VALUE")"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "INSERT INTO "LCG_COOL"."COOLTEST_DB_ATTRIBUTES" ("DB_ATTRIBUTE_NAME","DB_ATTRIBUTE_VALUE") VALUES (:"DB_ATTRIBUTE_NAME",:"DB_ATTRIBUTE_VALUE")"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "CREATE TABLE "LCG_COOL"."COOLTEST_NODES" ( "NODE_ID" NUMBER(10), "NODE_PARENTID" NUMBER(10), "NODE_NAME" VARCHAR2(255), "NODE_FULLPATH" VARCHAR2(255), "NODE_DESCRIPTION" VARCHAR2(255), "NODE_ISLEAF" NUMBER(1), "NODE_INSTIME" VARCHAR2(255), "FOLDER_PAYLOADSPEC" VARCHAR2(255), "FOLDER_VERSIONING" NUMBER(10), "FOLDER_IOVTABLENAME" VARCHAR2(255), "FOLDER_TAGTABLENAME" VARCHAR2(255), "FOLDER_IOV2TAGTABLENAME" VARCHAR2(255) )"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "ALTER TABLE "LCG_COOL"."COOLTEST_NODES" ADD (CONSTRAINT "COOLTEST_NODES_PK" PRIMARY KEY ("NODE_ID") )"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "ALTER TABLE "LCG_COOL"."COOLTEST_NODES" ADD (CONSTRAINT "COOLTEST_NODES_PARENT_FK" FOREIGN KEY ("NODE_PARENTID") REFERENCES "COOLTEST_NODES" ("NODE_ID"))"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "CREATE UNIQUE INDEX "LCG_COOL"."COOLTEST_NODES_PATH_UK" ON "LCG_COOL"."COOLTEST_NODES"("NODE_FULLPATH")"
+RelationalDatabase                   Debug    Altering table COOLTEST_NODES: modify the SQL type of column FOLDER_PAYLOADSPEC to VARCHAR2(4000)
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT ALL_CONS_COLUMNS.COLUMN_NAME FROM ALL_CONSTRAINTS, ALL_CONS_COLUMNS WHERE ALL_CONSTRAINTS.OWNER = 'LCG_COOL' AND ALL_CONSTRAINTS.TABLE_NAME = 'COOLTEST_NODES' AND ALL_CONSTRAINTS.CONSTRAINT_TYPE = 'U' AND ALL_CONS_COLUMNS.CONSTRAINT_NAME = ALL_CONSTRAINTS.CONSTRAINT_NAME AND ALL_CONS_COLUMNS.OWNER = ALL_CONSTRAINTS.OWNER AND ALL_CONS_COLUMNS.TABLE_NAME = ALL_CONSTRAINTS.TABLE_NAME"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT A.CONSTRAINT_NAME, B.COLUMN_NAME FROM ALL_CONSTRAINTS A, ALL_CONS_COLUMNS B WHERE A.OWNER = 'LCG_COOL' AND A.TABLE_NAME = 'COOLTEST_NODES' AND A.CONSTRAINT_TYPE = 'P' AND B.OWNER = A.OWNER AND B.TABLE_NAME = A.TABLE_NAME AND B.CONSTRAINT_NAME = A.CONSTRAINT_NAME ORDER BY B.POSITION"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT A.CONSTRAINT_NAME AS FK_NAME, B.TABLE_NAME AS REF_TABLE, C.COLUMN_NAME AS FK_COL, D.COLUMN_NAME AS REF_COL FROM (SELECT CONSTRAINT_NAME, R_CONSTRAINT_NAME FROM ALL_CONSTRAINTS WHERE OWNER='LCG_COOL' AND TABLE_NAME = 'COOLTEST_NODES' AND CONSTRAINT_TYPE='R') A, (SELECT TABLE_NAME, CONSTRAINT_NAME FROM ALL_CONSTRAINTS WHERE OWNER='LCG_COOL') B, (SELECT COLUMN_NAME, CONSTRAINT_NAME, POSITION FROM ALL_CONS_COLUMNS WHERE OWNER='LCG_COOL' AND TABLE_NAME='COOLTEST_NODES' ORDER BY POSITION) C, (SELECT COLUMN_NAME, CONSTRAINT_NAME, TABLE_NAME, POSITION FROM ALL_CONS_COLUMNS WHERE OWNER='LCG_COOL') D WHERE A.R_CONSTRAINT_NAME = B.CONSTRAINT_NAME AND A.CONSTRAINT_NAME = C.CONSTRAINT_NAME AND B.CONSTRAINT_NAME = D.CONSTRAINT_NAME AND C.POSITION = D.POSITION ORDER BY FK_NAME, D.POSITION"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT A.INDEX_NAME, A.UNIQUENESS, B.COLUMN_NAME FROM ALL_INDEXES A, ALL_IND_COLUMNS B WHERE A.OWNER = 'LCG_COOL' AND A.TABLE_NAME = 'COOLTEST_NODES' AND A.GENERATED = 'N' AND A.INDEX_NAME = B.INDEX_NAME AND B.INDEX_OWNER = A.OWNER AND B.TABLE_NAME = A.TABLE_NAME AND A.INDEX_NAME NOT IN (SELECT CONSTRAINT_NAME FROM ALL_CONSTRAINTS WHERE OWNER = A.OWNER AND TABLE_NAME = A.TABLE_NAME AND CONSTRAINT_TYPE = 'P') ORDER BY A.INDEX_NAME, B.COLUMN_POSITION"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "ALTER TABLE "LCG_COOL"."COOLTEST_NODES" DROP COLUMN "FOLDER_PAYLOADSPEC""
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "ALTER TABLE "LCG_COOL"."COOLTEST_NODES" ADD ( "FOLDER_PAYLOADSPEC" VARCHAR2(4000) )"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "ALTER TABLE "LCG_COOL"."COOLTEST_NODES" DROP COLUMN "FOLDER_VERSIONING""
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "ALTER TABLE "LCG_COOL"."COOLTEST_NODES" ADD ( "FOLDER_VERSIONING" NUMBER(10) )"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "ALTER TABLE "LCG_COOL"."COOLTEST_NODES" DROP COLUMN "FOLDER_IOVTABLENAME""
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "ALTER TABLE "LCG_COOL"."COOLTEST_NODES" ADD ( "FOLDER_IOVTABLENAME" VARCHAR2(255) )"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "ALTER TABLE "LCG_COOL"."COOLTEST_NODES" DROP COLUMN "FOLDER_TAGTABLENAME""
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "ALTER TABLE "LCG_COOL"."COOLTEST_NODES" ADD ( "FOLDER_TAGTABLENAME" VARCHAR2(255) )"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "ALTER TABLE "LCG_COOL"."COOLTEST_NODES" DROP COLUMN "FOLDER_IOV2TAGTABLENAME""
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "ALTER TABLE "LCG_COOL"."COOLTEST_NODES" ADD ( "FOLDER_IOV2TAGTABLENAME" VARCHAR2(255) )"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "CREATE TABLE "LCG_COOL"."COOLTEST_NODES_SEQ" ( "SEQUENCE_NAME" VARCHAR2(255), "CURRENT_VALUE" NUMBER(10), "LASTMOD_DATE" VARCHAR2(255) )"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "ALTER TABLE "LCG_COOL"."COOLTEST_NODES_SEQ" ADD (CONSTRAINT "COOLTEST_NODES_SEQ_PK" PRIMARY KEY ("SEQUENCE_NAME") )"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "INSERT INTO "LCG_COOL"."COOLTEST_NODES_SEQ" ("SEQUENCE_NAME") VALUES (:"SEQUENCE_NAME")"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT "CURRENT_VALUE", "LASTMOD_DATE" FROM "LCG_COOL"."COOLTEST_NODES_SEQ" FOR UPDATE"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "UPDATE "LCG_COOL"."COOLTEST_NODES_SEQ" SET "CURRENT_VALUE"=:"newvalue", "LASTMOD_DATE"=TO_CHAR(SYSTIMESTAMP AT TIME ZONE 'GMT','yyyy-mm-dd_hh24:mi:ss.ff6')||'000 GMT'"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT "CURRENT_VALUE", "LASTMOD_DATE" FROM "LCG_COOL"."COOLTEST_NODES_SEQ" FOR UPDATE"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "INSERT INTO "LCG_COOL"."COOLTEST_NODES" ("NODE_ID","NODE_NAME","NODE_FULLPATH","NODE_DESCRIPTION","NODE_ISLEAF","NODE_INSTIME") VALUES (:"NODE_ID",:"NODE_NAME",:"NODE_FULLPATH",:"NODE_DESCRIPTION",:"NODE_ISLEAF",:"NODE_INSTIME")"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "CREATE TABLE "LCG_COOL"."COOLTEST_TAGS" ( "TAG_ID" NUMBER(10), "NODE_ID" NUMBER(10), "TAG_NAME" VARCHAR2(255), "TAG_DESCRIPTION" VARCHAR2(255), "SYS_INSTIME" VARCHAR2(255) )"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "ALTER TABLE "LCG_COOL"."COOLTEST_TAGS" ADD (CONSTRAINT "COOLTEST_TAGS_PK" PRIMARY KEY ("TAG_ID","NODE_ID") )"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_INSTIME", "FOLDER_PAYLOADSPEC", "FOLDER_VERSIONING", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME" FROM "LCG_COOL"."COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalFolder                     Debug    Instantiate a RelationalFolder for '/'
+RelationalFolder                     Debug    Delete the RelationalFolder for '/'
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT "CURRENT_VALUE", "LASTMOD_DATE" FROM "LCG_COOL"."COOLTEST_NODES_SEQ" FOR UPDATE"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "UPDATE "LCG_COOL"."COOLTEST_NODES_SEQ" SET "CURRENT_VALUE"=:"newvalue", "LASTMOD_DATE"=TO_CHAR(SYSTIMESTAMP AT TIME ZONE 'GMT','yyyy-mm-dd_hh24:mi:ss.ff6')||'000 GMT'"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT "CURRENT_VALUE", "LASTMOD_DATE" FROM "LCG_COOL"."COOLTEST_NODES_SEQ" FOR UPDATE"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_INSTIME", "FOLDER_PAYLOADSPEC", "FOLDER_VERSIONING", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME" FROM "LCG_COOL"."COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "INSERT INTO "LCG_COOL"."COOLTEST_NODES" ("NODE_ID","NODE_PARENTID","NODE_NAME","NODE_FULLPATH","NODE_DESCRIPTION","NODE_ISLEAF","NODE_INSTIME","FOLDER_PAYLOADSPEC","FOLDER_VERSIONING","FOLDER_IOVTABLENAME","FOLDER_TAGTABLENAME","FOLDER_IOV2TAGTABLENAME") VALUES (:"NODE_ID",:"NODE_PARENTID",:"NODE_NAME",:"NODE_FULLPATH",:"NODE_DESCRIPTION",:"NODE_ISLEAF",:"NODE_INSTIME",:"FOLDER_PAYLOADSPEC",:"FOLDER_VERSIONING",:"FOLDER_IOVTABLENAME",:"FOLDER_TAGTABLENAME",:"FOLDER_IOV2TAGTABLENAME")"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "CREATE TABLE "LCG_COOL"."COOLTEST_F0001_IOVS" ( "OBJECT_ID" NUMBER(10), "CHANNEL_ID" NUMBER(10), "IOV_SINCE" NUMBER(20), "IOV_UNTIL" NUMBER(20), "SYS_INSTIME" VARCHAR2(255), "ORIGINAL_ID" NUMBER(10), "NEW_HEAD_ID" NUMBER(10), "I" NUMBER(10), "S" VARCHAR2(255), "X" BINARY_FLOAT )"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "ALTER TABLE "LCG_COOL"."COOLTEST_F0001_IOVS" ADD (CONSTRAINT "COOLTEST_F0001_IOVS_PK" PRIMARY KEY ("OBJECT_ID") )"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "CREATE INDEX "LCG_COOL"."COOLTEST_F0001_IOVS_CO_2INDX" ON "LCG_COOL"."COOLTEST_F0001_IOVS"("CHANNEL_ID","OBJECT_ID")"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "CREATE INDEX "LCG_COOL"."COOLTEST_F0001_IOVS_CSU_3INDX" ON "LCG_COOL"."COOLTEST_F0001_IOVS"("CHANNEL_ID","IOV_SINCE","IOV_UNTIL")"
+RelationalDatabase                   Debug    Altering table COOLTEST_F0001_IOVS: modify the SQL type of column S to VARCHAR2(4000)
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT ALL_CONS_COLUMNS.COLUMN_NAME FROM ALL_CONSTRAINTS, ALL_CONS_COLUMNS WHERE ALL_CONSTRAINTS.OWNER = 'LCG_COOL' AND ALL_CONSTRAINTS.TABLE_NAME = 'COOLTEST_F0001_IOVS' AND ALL_CONSTRAINTS.CONSTRAINT_TYPE = 'U' AND ALL_CONS_COLUMNS.CONSTRAINT_NAME = ALL_CONSTRAINTS.CONSTRAINT_NAME AND ALL_CONS_COLUMNS.OWNER = ALL_CONSTRAINTS.OWNER AND ALL_CONS_COLUMNS.TABLE_NAME = ALL_CONSTRAINTS.TABLE_NAME"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT A.CONSTRAINT_NAME, B.COLUMN_NAME FROM ALL_CONSTRAINTS A, ALL_CONS_COLUMNS B WHERE A.OWNER = 'LCG_COOL' AND A.TABLE_NAME = 'COOLTEST_F0001_IOVS' AND A.CONSTRAINT_TYPE = 'P' AND B.OWNER = A.OWNER AND B.TABLE_NAME = A.TABLE_NAME AND B.CONSTRAINT_NAME = A.CONSTRAINT_NAME ORDER BY B.POSITION"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT A.CONSTRAINT_NAME AS FK_NAME, B.TABLE_NAME AS REF_TABLE, C.COLUMN_NAME AS FK_COL, D.COLUMN_NAME AS REF_COL FROM (SELECT CONSTRAINT_NAME, R_CONSTRAINT_NAME FROM ALL_CONSTRAINTS WHERE OWNER='LCG_COOL' AND TABLE_NAME = 'COOLTEST_F0001_IOVS' AND CONSTRAINT_TYPE='R') A, (SELECT TABLE_NAME, CONSTRAINT_NAME FROM ALL_CONSTRAINTS WHERE OWNER='LCG_COOL') B, (SELECT COLUMN_NAME, CONSTRAINT_NAME, POSITION FROM ALL_CONS_COLUMNS WHERE OWNER='LCG_COOL' AND TABLE_NAME='COOLTEST_F0001_IOVS' ORDER BY POSITION) C, (SELECT COLUMN_NAME, CONSTRAINT_NAME, TABLE_NAME, POSITION FROM ALL_CONS_COLUMNS WHERE OWNER='LCG_COOL') D WHERE A.R_CONSTRAINT_NAME = B.CONSTRAINT_NAME AND A.CONSTRAINT_NAME = C.CONSTRAINT_NAME AND B.CONSTRAINT_NAME = D.CONSTRAINT_NAME AND C.POSITION = D.POSITION ORDER BY FK_NAME, D.POSITION"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT A.INDEX_NAME, A.UNIQUENESS, B.COLUMN_NAME FROM ALL_INDEXES A, ALL_IND_COLUMNS B WHERE A.OWNER = 'LCG_COOL' AND A.TABLE_NAME = 'COOLTEST_F0001_IOVS' AND A.GENERATED = 'N' AND A.INDEX_NAME = B.INDEX_NAME AND B.INDEX_OWNER = A.OWNER AND B.TABLE_NAME = A.TABLE_NAME AND A.INDEX_NAME NOT IN (SELECT CONSTRAINT_NAME FROM ALL_CONSTRAINTS WHERE OWNER = A.OWNER AND TABLE_NAME = A.TABLE_NAME AND CONSTRAINT_TYPE = 'P') ORDER BY A.INDEX_NAME, B.COLUMN_POSITION"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "ALTER TABLE "LCG_COOL"."COOLTEST_F0001_IOVS" DROP COLUMN "S""
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "ALTER TABLE "LCG_COOL"."COOLTEST_F0001_IOVS" ADD ( "S" VARCHAR2(4000) )"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "ALTER TABLE "LCG_COOL"."COOLTEST_F0001_IOVS" DROP COLUMN "X""
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "ALTER TABLE "LCG_COOL"."COOLTEST_F0001_IOVS" ADD ( "X" BINARY_FLOAT )"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "CREATE TABLE "LCG_COOL"."COOLTEST_F0001_IOVS_SEQ" ( "SEQUENCE_NAME" VARCHAR2(255), "CURRENT_VALUE" NUMBER(10), "LASTMOD_DATE" VARCHAR2(255) )"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "ALTER TABLE "LCG_COOL"."COOLTEST_F0001_IOVS_SEQ" ADD (CONSTRAINT "COOLTEST_F0001_IOVS_SEQ_PK" PRIMARY KEY ("SEQUENCE_NAME") )"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "INSERT INTO "LCG_COOL"."COOLTEST_F0001_IOVS_SEQ" ("SEQUENCE_NAME") VALUES (:"SEQUENCE_NAME")"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT "CURRENT_VALUE", "LASTMOD_DATE" FROM "LCG_COOL"."COOLTEST_F0001_IOVS_SEQ" FOR UPDATE"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "UPDATE "LCG_COOL"."COOLTEST_F0001_IOVS_SEQ" SET "CURRENT_VALUE"=:"newvalue", "LASTMOD_DATE"=TO_CHAR(SYSTIMESTAMP AT TIME ZONE 'GMT','yyyy-mm-dd_hh24:mi:ss.ff6')||'000 GMT'"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_INSTIME", "FOLDER_PAYLOADSPEC", "FOLDER_VERSIONING", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME" FROM "LCG_COOL"."COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalFolder                     Debug    Instantiate a RelationalFolder for '/f1'
+RelationalFolder                     Debug    Delete the RelationalFolder for '/f1'
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_INSTIME", "FOLDER_PAYLOADSPEC", "FOLDER_VERSIONING", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME" FROM "LCG_COOL"."COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalFolder                     Debug    Instantiate a RelationalFolder for '/'
+RelationalFolder                     Debug    Delete the RelationalFolder for '/'
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT "CURRENT_VALUE", "LASTMOD_DATE" FROM "LCG_COOL"."COOLTEST_NODES_SEQ" FOR UPDATE"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "UPDATE "LCG_COOL"."COOLTEST_NODES_SEQ" SET "CURRENT_VALUE"=:"newvalue", "LASTMOD_DATE"=TO_CHAR(SYSTIMESTAMP AT TIME ZONE 'GMT','yyyy-mm-dd_hh24:mi:ss.ff6')||'000 GMT'"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT "CURRENT_VALUE", "LASTMOD_DATE" FROM "LCG_COOL"."COOLTEST_NODES_SEQ" FOR UPDATE"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_INSTIME", "FOLDER_PAYLOADSPEC", "FOLDER_VERSIONING", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME" FROM "LCG_COOL"."COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "INSERT INTO "LCG_COOL"."COOLTEST_NODES" ("NODE_ID","NODE_PARENTID","NODE_NAME","NODE_FULLPATH","NODE_DESCRIPTION","NODE_ISLEAF","NODE_INSTIME","FOLDER_PAYLOADSPEC","FOLDER_VERSIONING","FOLDER_IOVTABLENAME","FOLDER_TAGTABLENAME","FOLDER_IOV2TAGTABLENAME") VALUES (:"NODE_ID",:"NODE_PARENTID",:"NODE_NAME",:"NODE_FULLPATH",:"NODE_DESCRIPTION",:"NODE_ISLEAF",:"NODE_INSTIME",:"FOLDER_PAYLOADSPEC",:"FOLDER_VERSIONING",:"FOLDER_IOVTABLENAME",:"FOLDER_TAGTABLENAME",:"FOLDER_IOV2TAGTABLENAME")"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "CREATE TABLE "LCG_COOL"."COOLTEST_F0002_IOVS" ( "OBJECT_ID" NUMBER(10), "CHANNEL_ID" NUMBER(10), "IOV_SINCE" NUMBER(20), "IOV_UNTIL" NUMBER(20), "SYS_INSTIME" VARCHAR2(255), "ORIGINAL_ID" NUMBER(10), "NEW_HEAD_ID" NUMBER(10), "I" NUMBER(10), "S" VARCHAR2(255), "X" BINARY_FLOAT )"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "ALTER TABLE "LCG_COOL"."COOLTEST_F0002_IOVS" ADD (CONSTRAINT "COOLTEST_F0002_IOVS_PK" PRIMARY KEY ("OBJECT_ID") )"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "CREATE INDEX "LCG_COOL"."COOLTEST_F0002_IOVS_CO_2INDX" ON "LCG_COOL"."COOLTEST_F0002_IOVS"("CHANNEL_ID","OBJECT_ID")"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "CREATE INDEX "LCG_COOL"."COOLTEST_F0002_IOVS_CSU_3INDX" ON "LCG_COOL"."COOLTEST_F0002_IOVS"("CHANNEL_ID","IOV_SINCE","IOV_UNTIL")"
+RelationalDatabase                   Debug    Altering table COOLTEST_F0002_IOVS: modify the SQL type of column S to VARCHAR2(4000)
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT ALL_CONS_COLUMNS.COLUMN_NAME FROM ALL_CONSTRAINTS, ALL_CONS_COLUMNS WHERE ALL_CONSTRAINTS.OWNER = 'LCG_COOL' AND ALL_CONSTRAINTS.TABLE_NAME = 'COOLTEST_F0002_IOVS' AND ALL_CONSTRAINTS.CONSTRAINT_TYPE = 'U' AND ALL_CONS_COLUMNS.CONSTRAINT_NAME = ALL_CONSTRAINTS.CONSTRAINT_NAME AND ALL_CONS_COLUMNS.OWNER = ALL_CONSTRAINTS.OWNER AND ALL_CONS_COLUMNS.TABLE_NAME = ALL_CONSTRAINTS.TABLE_NAME"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT A.CONSTRAINT_NAME, B.COLUMN_NAME FROM ALL_CONSTRAINTS A, ALL_CONS_COLUMNS B WHERE A.OWNER = 'LCG_COOL' AND A.TABLE_NAME = 'COOLTEST_F0002_IOVS' AND A.CONSTRAINT_TYPE = 'P' AND B.OWNER = A.OWNER AND B.TABLE_NAME = A.TABLE_NAME AND B.CONSTRAINT_NAME = A.CONSTRAINT_NAME ORDER BY B.POSITION"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT A.CONSTRAINT_NAME AS FK_NAME, B.TABLE_NAME AS REF_TABLE, C.COLUMN_NAME AS FK_COL, D.COLUMN_NAME AS REF_COL FROM (SELECT CONSTRAINT_NAME, R_CONSTRAINT_NAME FROM ALL_CONSTRAINTS WHERE OWNER='LCG_COOL' AND TABLE_NAME = 'COOLTEST_F0002_IOVS' AND CONSTRAINT_TYPE='R') A, (SELECT TABLE_NAME, CONSTRAINT_NAME FROM ALL_CONSTRAINTS WHERE OWNER='LCG_COOL') B, (SELECT COLUMN_NAME, CONSTRAINT_NAME, POSITION FROM ALL_CONS_COLUMNS WHERE OWNER='LCG_COOL' AND TABLE_NAME='COOLTEST_F0002_IOVS' ORDER BY POSITION) C, (SELECT COLUMN_NAME, CONSTRAINT_NAME, TABLE_NAME, POSITION FROM ALL_CONS_COLUMNS WHERE OWNER='LCG_COOL') D WHERE A.R_CONSTRAINT_NAME = B.CONSTRAINT_NAME AND A.CONSTRAINT_NAME = C.CONSTRAINT_NAME AND B.CONSTRAINT_NAME = D.CONSTRAINT_NAME AND C.POSITION = D.POSITION ORDER BY FK_NAME, D.POSITION"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT A.INDEX_NAME, A.UNIQUENESS, B.COLUMN_NAME FROM ALL_INDEXES A, ALL_IND_COLUMNS B WHERE A.OWNER = 'LCG_COOL' AND A.TABLE_NAME = 'COOLTEST_F0002_IOVS' AND A.GENERATED = 'N' AND A.INDEX_NAME = B.INDEX_NAME AND B.INDEX_OWNER = A.OWNER AND B.TABLE_NAME = A.TABLE_NAME AND A.INDEX_NAME NOT IN (SELECT CONSTRAINT_NAME FROM ALL_CONSTRAINTS WHERE OWNER = A.OWNER AND TABLE_NAME = A.TABLE_NAME AND CONSTRAINT_TYPE = 'P') ORDER BY A.INDEX_NAME, B.COLUMN_POSITION"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "ALTER TABLE "LCG_COOL"."COOLTEST_F0002_IOVS" DROP COLUMN "S""
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "ALTER TABLE "LCG_COOL"."COOLTEST_F0002_IOVS" ADD ( "S" VARCHAR2(4000) )"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "ALTER TABLE "LCG_COOL"."COOLTEST_F0002_IOVS" DROP COLUMN "X""
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "ALTER TABLE "LCG_COOL"."COOLTEST_F0002_IOVS" ADD ( "X" BINARY_FLOAT )"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "CREATE TABLE "LCG_COOL"."COOLTEST_F0002_IOVS_SEQ" ( "SEQUENCE_NAME" VARCHAR2(255), "CURRENT_VALUE" NUMBER(10), "LASTMOD_DATE" VARCHAR2(255) )"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "ALTER TABLE "LCG_COOL"."COOLTEST_F0002_IOVS_SEQ" ADD (CONSTRAINT "COOLTEST_F0002_IOVS_SEQ_PK" PRIMARY KEY ("SEQUENCE_NAME") )"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "INSERT INTO "LCG_COOL"."COOLTEST_F0002_IOVS_SEQ" ("SEQUENCE_NAME") VALUES (:"SEQUENCE_NAME")"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT "CURRENT_VALUE", "LASTMOD_DATE" FROM "LCG_COOL"."COOLTEST_F0002_IOVS_SEQ" FOR UPDATE"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "UPDATE "LCG_COOL"."COOLTEST_F0002_IOVS_SEQ" SET "CURRENT_VALUE"=:"newvalue", "LASTMOD_DATE"=TO_CHAR(SYSTIMESTAMP AT TIME ZONE 'GMT','yyyy-mm-dd_hh24:mi:ss.ff6')||'000 GMT'"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_INSTIME", "FOLDER_PAYLOADSPEC", "FOLDER_VERSIONING", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME" FROM "LCG_COOL"."COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalFolder                     Debug    Instantiate a RelationalFolder for '/f2'
+RelationalFolder                     Debug    Delete the RelationalFolder for '/f2'
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_INSTIME", "FOLDER_PAYLOADSPEC", "FOLDER_VERSIONING", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME" FROM "LCG_COOL"."COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalFolder                     Debug    Instantiate a RelationalFolder for '/'
+RelationalFolder                     Debug    Delete the RelationalFolder for '/'
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT "CURRENT_VALUE", "LASTMOD_DATE" FROM "LCG_COOL"."COOLTEST_NODES_SEQ" FOR UPDATE"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "UPDATE "LCG_COOL"."COOLTEST_NODES_SEQ" SET "CURRENT_VALUE"=:"newvalue", "LASTMOD_DATE"=TO_CHAR(SYSTIMESTAMP AT TIME ZONE 'GMT','yyyy-mm-dd_hh24:mi:ss.ff6')||'000 GMT'"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT "CURRENT_VALUE", "LASTMOD_DATE" FROM "LCG_COOL"."COOLTEST_NODES_SEQ" FOR UPDATE"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_INSTIME", "FOLDER_PAYLOADSPEC", "FOLDER_VERSIONING", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME" FROM "LCG_COOL"."COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "INSERT INTO "LCG_COOL"."COOLTEST_NODES" ("NODE_ID","NODE_PARENTID","NODE_NAME","NODE_FULLPATH","NODE_DESCRIPTION","NODE_ISLEAF","NODE_INSTIME","FOLDER_PAYLOADSPEC","FOLDER_VERSIONING","FOLDER_IOVTABLENAME","FOLDER_TAGTABLENAME","FOLDER_IOV2TAGTABLENAME") VALUES (:"NODE_ID",:"NODE_PARENTID",:"NODE_NAME",:"NODE_FULLPATH",:"NODE_DESCRIPTION",:"NODE_ISLEAF",:"NODE_INSTIME",:"FOLDER_PAYLOADSPEC",:"FOLDER_VERSIONING",:"FOLDER_IOVTABLENAME",:"FOLDER_TAGTABLENAME",:"FOLDER_IOV2TAGTABLENAME")"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "CREATE TABLE "LCG_COOL"."COOLTEST_F0003_IOVS" ( "OBJECT_ID" NUMBER(10), "CHANNEL_ID" NUMBER(10), "IOV_SINCE" NUMBER(20), "IOV_UNTIL" NUMBER(20), "SYS_INSTIME" VARCHAR2(255), "ORIGINAL_ID" NUMBER(10), "NEW_HEAD_ID" NUMBER(10), "I" NUMBER(10), "S" VARCHAR2(255), "X" BINARY_FLOAT )"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "ALTER TABLE "LCG_COOL"."COOLTEST_F0003_IOVS" ADD (CONSTRAINT "COOLTEST_F0003_IOVS_PK" PRIMARY KEY ("OBJECT_ID") )"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "CREATE INDEX "LCG_COOL"."COOLTEST_F0003_IOVS_CO_2INDX" ON "LCG_COOL"."COOLTEST_F0003_IOVS"("CHANNEL_ID","OBJECT_ID")"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "CREATE INDEX "LCG_COOL"."COOLTEST_F0003_IOVS_CSU_3INDX" ON "LCG_COOL"."COOLTEST_F0003_IOVS"("CHANNEL_ID","IOV_SINCE","IOV_UNTIL")"
+RelationalDatabase                   Debug    Altering table COOLTEST_F0003_IOVS: modify the SQL type of column S to VARCHAR2(4000)
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT ALL_CONS_COLUMNS.COLUMN_NAME FROM ALL_CONSTRAINTS, ALL_CONS_COLUMNS WHERE ALL_CONSTRAINTS.OWNER = 'LCG_COOL' AND ALL_CONSTRAINTS.TABLE_NAME = 'COOLTEST_F0003_IOVS' AND ALL_CONSTRAINTS.CONSTRAINT_TYPE = 'U' AND ALL_CONS_COLUMNS.CONSTRAINT_NAME = ALL_CONSTRAINTS.CONSTRAINT_NAME AND ALL_CONS_COLUMNS.OWNER = ALL_CONSTRAINTS.OWNER AND ALL_CONS_COLUMNS.TABLE_NAME = ALL_CONSTRAINTS.TABLE_NAME"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT A.CONSTRAINT_NAME, B.COLUMN_NAME FROM ALL_CONSTRAINTS A, ALL_CONS_COLUMNS B WHERE A.OWNER = 'LCG_COOL' AND A.TABLE_NAME = 'COOLTEST_F0003_IOVS' AND A.CONSTRAINT_TYPE = 'P' AND B.OWNER = A.OWNER AND B.TABLE_NAME = A.TABLE_NAME AND B.CONSTRAINT_NAME = A.CONSTRAINT_NAME ORDER BY B.POSITION"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT A.CONSTRAINT_NAME AS FK_NAME, B.TABLE_NAME AS REF_TABLE, C.COLUMN_NAME AS FK_COL, D.COLUMN_NAME AS REF_COL FROM (SELECT CONSTRAINT_NAME, R_CONSTRAINT_NAME FROM ALL_CONSTRAINTS WHERE OWNER='LCG_COOL' AND TABLE_NAME = 'COOLTEST_F0003_IOVS' AND CONSTRAINT_TYPE='R') A, (SELECT TABLE_NAME, CONSTRAINT_NAME FROM ALL_CONSTRAINTS WHERE OWNER='LCG_COOL') B, (SELECT COLUMN_NAME, CONSTRAINT_NAME, POSITION FROM ALL_CONS_COLUMNS WHERE OWNER='LCG_COOL' AND TABLE_NAME='COOLTEST_F0003_IOVS' ORDER BY POSITION) C, (SELECT COLUMN_NAME, CONSTRAINT_NAME, TABLE_NAME, POSITION FROM ALL_CONS_COLUMNS WHERE OWNER='LCG_COOL') D WHERE A.R_CONSTRAINT_NAME = B.CONSTRAINT_NAME AND A.CONSTRAINT_NAME = C.CONSTRAINT_NAME AND B.CONSTRAINT_NAME = D.CONSTRAINT_NAME AND C.POSITION = D.POSITION ORDER BY FK_NAME, D.POSITION"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT A.INDEX_NAME, A.UNIQUENESS, B.COLUMN_NAME FROM ALL_INDEXES A, ALL_IND_COLUMNS B WHERE A.OWNER = 'LCG_COOL' AND A.TABLE_NAME = 'COOLTEST_F0003_IOVS' AND A.GENERATED = 'N' AND A.INDEX_NAME = B.INDEX_NAME AND B.INDEX_OWNER = A.OWNER AND B.TABLE_NAME = A.TABLE_NAME AND A.INDEX_NAME NOT IN (SELECT CONSTRAINT_NAME FROM ALL_CONSTRAINTS WHERE OWNER = A.OWNER AND TABLE_NAME = A.TABLE_NAME AND CONSTRAINT_TYPE = 'P') ORDER BY A.INDEX_NAME, B.COLUMN_POSITION"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "ALTER TABLE "LCG_COOL"."COOLTEST_F0003_IOVS" DROP COLUMN "S""
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "ALTER TABLE "LCG_COOL"."COOLTEST_F0003_IOVS" ADD ( "S" VARCHAR2(4000) )"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "ALTER TABLE "LCG_COOL"."COOLTEST_F0003_IOVS" DROP COLUMN "X""
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "ALTER TABLE "LCG_COOL"."COOLTEST_F0003_IOVS" ADD ( "X" BINARY_FLOAT )"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "CREATE TABLE "LCG_COOL"."COOLTEST_F0003_IOVS_SEQ" ( "SEQUENCE_NAME" VARCHAR2(255), "CURRENT_VALUE" NUMBER(10), "LASTMOD_DATE" VARCHAR2(255) )"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "ALTER TABLE "LCG_COOL"."COOLTEST_F0003_IOVS_SEQ" ADD (CONSTRAINT "COOLTEST_F0003_IOVS_SEQ_PK" PRIMARY KEY ("SEQUENCE_NAME") )"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "INSERT INTO "LCG_COOL"."COOLTEST_F0003_IOVS_SEQ" ("SEQUENCE_NAME") VALUES (:"SEQUENCE_NAME")"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT "CURRENT_VALUE", "LASTMOD_DATE" FROM "LCG_COOL"."COOLTEST_F0003_IOVS_SEQ" FOR UPDATE"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "UPDATE "LCG_COOL"."COOLTEST_F0003_IOVS_SEQ" SET "CURRENT_VALUE"=:"newvalue", "LASTMOD_DATE"=TO_CHAR(SYSTIMESTAMP AT TIME ZONE 'GMT','yyyy-mm-dd_hh24:mi:ss.ff6')||'000 GMT'"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_INSTIME", "FOLDER_PAYLOADSPEC", "FOLDER_VERSIONING", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME" FROM "LCG_COOL"."COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalFolder                     Debug    Instantiate a RelationalFolder for '/f3'
+RelationalFolder                     Debug    Delete the RelationalFolder for '/f3'
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_INSTIME", "FOLDER_PAYLOADSPEC", "FOLDER_VERSIONING", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME" FROM "LCG_COOL"."COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalFolder                     Debug    Instantiate a RelationalFolder for '/'
+RelationalFolder                     Debug    Delete the RelationalFolder for '/'
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT "CURRENT_VALUE", "LASTMOD_DATE" FROM "LCG_COOL"."COOLTEST_NODES_SEQ" FOR UPDATE"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "UPDATE "LCG_COOL"."COOLTEST_NODES_SEQ" SET "CURRENT_VALUE"=:"newvalue", "LASTMOD_DATE"=TO_CHAR(SYSTIMESTAMP AT TIME ZONE 'GMT','yyyy-mm-dd_hh24:mi:ss.ff6')||'000 GMT'"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT "CURRENT_VALUE", "LASTMOD_DATE" FROM "LCG_COOL"."COOLTEST_NODES_SEQ" FOR UPDATE"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_INSTIME", "FOLDER_PAYLOADSPEC", "FOLDER_VERSIONING", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME" FROM "LCG_COOL"."COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "INSERT INTO "LCG_COOL"."COOLTEST_NODES" ("NODE_ID","NODE_PARENTID","NODE_NAME","NODE_FULLPATH","NODE_DESCRIPTION","NODE_ISLEAF","NODE_INSTIME","FOLDER_PAYLOADSPEC","FOLDER_VERSIONING","FOLDER_IOVTABLENAME","FOLDER_TAGTABLENAME","FOLDER_IOV2TAGTABLENAME") VALUES (:"NODE_ID",:"NODE_PARENTID",:"NODE_NAME",:"NODE_FULLPATH",:"NODE_DESCRIPTION",:"NODE_ISLEAF",:"NODE_INSTIME",:"FOLDER_PAYLOADSPEC",:"FOLDER_VERSIONING",:"FOLDER_IOVTABLENAME",:"FOLDER_TAGTABLENAME",:"FOLDER_IOV2TAGTABLENAME")"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "CREATE TABLE "LCG_COOL"."COOLTEST_F0004_IOVS" ( "OBJECT_ID" NUMBER(10), "CHANNEL_ID" NUMBER(10), "IOV_SINCE" NUMBER(20), "IOV_UNTIL" NUMBER(20), "SYS_INSTIME" VARCHAR2(255), "ORIGINAL_ID" NUMBER(10), "NEW_HEAD_ID" NUMBER(10), "I" NUMBER(10), "S" VARCHAR2(255), "X" BINARY_FLOAT )"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "ALTER TABLE "LCG_COOL"."COOLTEST_F0004_IOVS" ADD (CONSTRAINT "COOLTEST_F0004_IOVS_PK" PRIMARY KEY ("OBJECT_ID") )"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "CREATE INDEX "LCG_COOL"."COOLTEST_F0004_IOVS_CO_2INDX" ON "LCG_COOL"."COOLTEST_F0004_IOVS"("CHANNEL_ID","OBJECT_ID")"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "CREATE INDEX "LCG_COOL"."COOLTEST_F0004_IOVS_CSU_3INDX" ON "LCG_COOL"."COOLTEST_F0004_IOVS"("CHANNEL_ID","IOV_SINCE","IOV_UNTIL")"
+RelationalDatabase                   Debug    Altering table COOLTEST_F0004_IOVS: modify the SQL type of column S to VARCHAR2(4000)
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT ALL_CONS_COLUMNS.COLUMN_NAME FROM ALL_CONSTRAINTS, ALL_CONS_COLUMNS WHERE ALL_CONSTRAINTS.OWNER = 'LCG_COOL' AND ALL_CONSTRAINTS.TABLE_NAME = 'COOLTEST_F0004_IOVS' AND ALL_CONSTRAINTS.CONSTRAINT_TYPE = 'U' AND ALL_CONS_COLUMNS.CONSTRAINT_NAME = ALL_CONSTRAINTS.CONSTRAINT_NAME AND ALL_CONS_COLUMNS.OWNER = ALL_CONSTRAINTS.OWNER AND ALL_CONS_COLUMNS.TABLE_NAME = ALL_CONSTRAINTS.TABLE_NAME"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT A.CONSTRAINT_NAME, B.COLUMN_NAME FROM ALL_CONSTRAINTS A, ALL_CONS_COLUMNS B WHERE A.OWNER = 'LCG_COOL' AND A.TABLE_NAME = 'COOLTEST_F0004_IOVS' AND A.CONSTRAINT_TYPE = 'P' AND B.OWNER = A.OWNER AND B.TABLE_NAME = A.TABLE_NAME AND B.CONSTRAINT_NAME = A.CONSTRAINT_NAME ORDER BY B.POSITION"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT A.CONSTRAINT_NAME AS FK_NAME, B.TABLE_NAME AS REF_TABLE, C.COLUMN_NAME AS FK_COL, D.COLUMN_NAME AS REF_COL FROM (SELECT CONSTRAINT_NAME, R_CONSTRAINT_NAME FROM ALL_CONSTRAINTS WHERE OWNER='LCG_COOL' AND TABLE_NAME = 'COOLTEST_F0004_IOVS' AND CONSTRAINT_TYPE='R') A, (SELECT TABLE_NAME, CONSTRAINT_NAME FROM ALL_CONSTRAINTS WHERE OWNER='LCG_COOL') B, (SELECT COLUMN_NAME, CONSTRAINT_NAME, POSITION FROM ALL_CONS_COLUMNS WHERE OWNER='LCG_COOL' AND TABLE_NAME='COOLTEST_F0004_IOVS' ORDER BY POSITION) C, (SELECT COLUMN_NAME, CONSTRAINT_NAME, TABLE_NAME, POSITION FROM ALL_CONS_COLUMNS WHERE OWNER='LCG_COOL') D WHERE A.R_CONSTRAINT_NAME = B.CONSTRAINT_NAME AND A.CONSTRAINT_NAME = C.CONSTRAINT_NAME AND B.CONSTRAINT_NAME = D.CONSTRAINT_NAME AND C.POSITION = D.POSITION ORDER BY FK_NAME, D.POSITION"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT A.INDEX_NAME, A.UNIQUENESS, B.COLUMN_NAME FROM ALL_INDEXES A, ALL_IND_COLUMNS B WHERE A.OWNER = 'LCG_COOL' AND A.TABLE_NAME = 'COOLTEST_F0004_IOVS' AND A.GENERATED = 'N' AND A.INDEX_NAME = B.INDEX_NAME AND B.INDEX_OWNER = A.OWNER AND B.TABLE_NAME = A.TABLE_NAME AND A.INDEX_NAME NOT IN (SELECT CONSTRAINT_NAME FROM ALL_CONSTRAINTS WHERE OWNER = A.OWNER AND TABLE_NAME = A.TABLE_NAME AND CONSTRAINT_TYPE = 'P') ORDER BY A.INDEX_NAME, B.COLUMN_POSITION"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "ALTER TABLE "LCG_COOL"."COOLTEST_F0004_IOVS" DROP COLUMN "S""
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "ALTER TABLE "LCG_COOL"."COOLTEST_F0004_IOVS" ADD ( "S" VARCHAR2(4000) )"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "ALTER TABLE "LCG_COOL"."COOLTEST_F0004_IOVS" DROP COLUMN "X""
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "ALTER TABLE "LCG_COOL"."COOLTEST_F0004_IOVS" ADD ( "X" BINARY_FLOAT )"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "CREATE TABLE "LCG_COOL"."COOLTEST_F0004_IOVS_SEQ" ( "SEQUENCE_NAME" VARCHAR2(255), "CURRENT_VALUE" NUMBER(10), "LASTMOD_DATE" VARCHAR2(255) )"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "ALTER TABLE "LCG_COOL"."COOLTEST_F0004_IOVS_SEQ" ADD (CONSTRAINT "COOLTEST_F0004_IOVS_SEQ_PK" PRIMARY KEY ("SEQUENCE_NAME") )"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "INSERT INTO "LCG_COOL"."COOLTEST_F0004_IOVS_SEQ" ("SEQUENCE_NAME") VALUES (:"SEQUENCE_NAME")"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT "CURRENT_VALUE", "LASTMOD_DATE" FROM "LCG_COOL"."COOLTEST_F0004_IOVS_SEQ" FOR UPDATE"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "UPDATE "LCG_COOL"."COOLTEST_F0004_IOVS_SEQ" SET "CURRENT_VALUE"=:"newvalue", "LASTMOD_DATE"=TO_CHAR(SYSTIMESTAMP AT TIME ZONE 'GMT','yyyy-mm-dd_hh24:mi:ss.ff6')||'000 GMT'"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_INSTIME", "FOLDER_PAYLOADSPEC", "FOLDER_VERSIONING", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME" FROM "LCG_COOL"."COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalFolder                     Debug    Instantiate a RelationalFolder for '/f4'
+RelationalFolder                     Debug    Delete the RelationalFolder for '/f4'
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "DROP TABLE "LCG_COOL"."COOLTEST_TAGS""
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_INSTIME", "FOLDER_PAYLOADSPEC", "FOLDER_VERSIONING", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME" FROM "LCG_COOL"."COOLTEST_NODES" ORDER BY "NODE_FULLPATH" DESC"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_INSTIME", "FOLDER_PAYLOADSPEC", "FOLDER_VERSIONING", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME" FROM "LCG_COOL"."COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "DROP TABLE "LCG_COOL"."COOLTEST_F0004_IOVS""
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "DROP TABLE "LCG_COOL"."COOLTEST_F0004_IOVS_SEQ""
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "DELETE FROM "LCG_COOL"."COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_INSTIME", "FOLDER_PAYLOADSPEC", "FOLDER_VERSIONING", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME" FROM "LCG_COOL"."COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "DROP TABLE "LCG_COOL"."COOLTEST_F0003_IOVS""
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "DROP TABLE "LCG_COOL"."COOLTEST_F0003_IOVS_SEQ""
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "DELETE FROM "LCG_COOL"."COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_INSTIME", "FOLDER_PAYLOADSPEC", "FOLDER_VERSIONING", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME" FROM "LCG_COOL"."COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "DROP TABLE "LCG_COOL"."COOLTEST_F0002_IOVS""
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "DROP TABLE "LCG_COOL"."COOLTEST_F0002_IOVS_SEQ""
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "DELETE FROM "LCG_COOL"."COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_INSTIME", "FOLDER_PAYLOADSPEC", "FOLDER_VERSIONING", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME" FROM "LCG_COOL"."COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "DROP TABLE "LCG_COOL"."COOLTEST_F0001_IOVS""
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "DROP TABLE "LCG_COOL"."COOLTEST_F0001_IOVS_SEQ""
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "DELETE FROM "LCG_COOL"."COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_INSTIME", "FOLDER_PAYLOADSPEC", "FOLDER_VERSIONING", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME" FROM "LCG_COOL"."COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_INSTIME", "FOLDER_PAYLOADSPEC", "FOLDER_VERSIONING", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME" FROM "LCG_COOL"."COOLTEST_NODES" WHERE "NODE_PARENTID"= :"parentId" and "NODE_ISLEAF"= :"isLeaf" ORDER BY "NODE_FULLPATH" ASC"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_INSTIME", "FOLDER_PAYLOADSPEC", "FOLDER_VERSIONING", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME" FROM "LCG_COOL"."COOLTEST_NODES" WHERE "NODE_PARENTID"= :"parentId" and "NODE_ISLEAF"= :"isLeaf" ORDER BY "NODE_FULLPATH" ASC"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "DELETE FROM "LCG_COOL"."COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "DROP TABLE "LCG_COOL"."COOLTEST_NODES_SEQ""
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "DROP TABLE "LCG_COOL"."COOLTEST_NODES""
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "DROP TABLE "LCG_COOL"."COOLTEST_DB_ATTRIBUTES""
+
+OK (1)
+[OVAL] Cppunit-result =0
+RelationalDatabase                   Info     Delete the RalDatabase for 'oracle://devdb10;schema=lcg_cool;dbname=COOLTEST'
+POOL/RelationalPlugins/oracle        Warning  No active transaction to roll back
+RelationalDatabase                   Debug    Delete the RelationalDatabase for 'oracle://devdb10;schema=lcg_cool;dbname=COOLTEST'
+Application                          Info     Delete the COOL Application
+RalDatabaseSvc                       Info     Delete the RalDatabaseSvc
+(Start: Thu Jul 14 10:32:06 CEST 2005)
+(End:   Thu Jul 14 10:32:34 CEST 2005)
+
diff --git a/RelationalCool/tests/RalDatabase/dropDatabaseTest.out.OCI_THREADED b/RelationalCool/tests/RalDatabase/dropDatabaseTest.out.OCI_THREADED
new file mode 100644
index 000000000..8a48f0002
--- /dev/null
+++ b/RelationalCool/tests/RalDatabase/dropDatabaseTest.out.OCI_THREADED
@@ -0,0 +1,306 @@
+(Start: Thu Jul 14 10:32:53 CEST 2005)
+Property Catalogue: level[Info] Adding property: OutputLevel = 2 in scope "SEAL/Services/MessageService"
+Property Catalogue: level[Info] Adding property: Format =  "%-36s %-8s %s" in scope "SEAL/Services/MessageService"
+Property Catalogue: level[Info] Adding property: AuthenticationFile =  "/afs/cern.ch/user/a/avalassi/private/authentication.xml" in scope "POOL/Services/XMLAuthenticationService"
+MessageService callback    Debug MessageService output level changed to Debug
+ConfigurationService    Debug Setting property: "Format" to value " "%-36s %-8s %s"" in scope "SEAL/Services/MessageService"
+Application                          Info     Instantiate a COOL Application
+Application                          Info     Load the COOL database service
+RalDatabaseSvc                       Info     Instantiate the RalDatabaseSvc
+RalDatabaseSvc                       Info     Load the POOL relational service
+POOL/Services/RelationalService      Info     Found plugin for RDBMS technology "mysql" with implementation "odbc"
+POOL/Services/RelationalService      Info     Found plugin for RDBMS technology "oracle" with native implementation
+POOL/Services/RelationalService      Info     Found plugin for RDBMS technology "sqlite" with native implementation
+POOL/Services/RelationalService      Info     Default implementation for RDBMS technology "mysql" is "odbc"
+POOL/Services/RelationalService      Info     Default implementation for RDBMS technology "oracle" is native
+POOL/Services/RelationalService      Info     Default implementation for RDBMS technology "sqlite" is native
+RalDatabaseSvc                       Info     Load the POOL XML authentication service
+ConfigurationService                 Debug    Setting property: "AuthenticationFile" to value " "/afs/cern.ch/user/a/avalassi/private/authentication.xml"" in scope "POOL/Services/XMLAuthenticationService"
+RelationalDatabase                   Debug    Instantiate a RelationalDatabase for 'oracle://devdb10;schema=lcg_cool;dbname=COOLTEST'
+RelationalDatabase                   Info     Instantiate a RalDatabase for 'oracle://devdb10;schema=lcg_cool;dbname=COOLTEST'
+RalAuthenticationManager             Debug    Retrieve COOL authentication credentials for 'oracle://devdb10;schema=lcg_cool;dbname=COOLTEST'
+RalAuthenticationManager             Debug    Retrieve COOL authentication credentials using an authentication service 
+RalAuthenticationManager             Debug    Credentials found for 'oracle://devdb10;schema=lcg_cool'
+RalAuthenticationManager             Debug    COOL authentication credentials successfully retrieved
+POOL/RelationalPlugins/oracle        Info     Connected to a server running Oracle version 10.1.0.4.0
+RelationalDatabase                   Info     Delete the RalDatabase for 'oracle://devdb10;schema=lcg_cool;dbname=COOLTEST'
+POOL/RelationalPlugins/oracle        Warning  No active transaction to roll back
+RelationalDatabase                   Debug    Delete the RelationalDatabase for 'oracle://devdb10;schema=lcg_cool;dbname=COOLTEST'
+RelationalDatabase                   Debug    Instantiate a RelationalDatabase for 'oracle://devdb10;schema=lcg_cool;dbname=COOLTEST'
+RelationalDatabase                   Info     Instantiate a RalDatabase for 'oracle://devdb10;schema=lcg_cool;dbname=COOLTEST'
+RalAuthenticationManager             Debug    Retrieve COOL authentication credentials for 'oracle://devdb10;schema=lcg_cool;dbname=COOLTEST'
+RalAuthenticationManager             Debug    Retrieve COOL authentication credentials using an authentication service 
+RalAuthenticationManager             Debug    Credentials found for 'oracle://devdb10;schema=lcg_cool'
+RalAuthenticationManager             Debug    COOL authentication credentials successfully retrieved
+POOL/RelationalPlugins/oracle        Info     Connected to a server running Oracle version 10.1.0.4.0
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "CREATE TABLE "LCG_COOL"."COOLTEST_DB_ATTRIBUTES" ( "DB_ATTRIBUTE_NAME" VARCHAR2(255) )"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "ALTER TABLE "LCG_COOL"."COOLTEST_DB_ATTRIBUTES" ADD (CONSTRAINT "COOLTEST_DB_ATTRIBUTES_PK" PRIMARY KEY ("DB_ATTRIBUTE_NAME") )"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT ALL_CONS_COLUMNS.COLUMN_NAME FROM ALL_CONSTRAINTS, ALL_CONS_COLUMNS WHERE ALL_CONSTRAINTS.OWNER = 'LCG_COOL' AND ALL_CONSTRAINTS.TABLE_NAME = 'COOLTEST_DB_ATTRIBUTES' AND ALL_CONSTRAINTS.CONSTRAINT_TYPE = 'U' AND ALL_CONS_COLUMNS.CONSTRAINT_NAME = ALL_CONSTRAINTS.CONSTRAINT_NAME AND ALL_CONS_COLUMNS.OWNER = ALL_CONSTRAINTS.OWNER AND ALL_CONS_COLUMNS.TABLE_NAME = ALL_CONSTRAINTS.TABLE_NAME"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT A.CONSTRAINT_NAME, B.COLUMN_NAME FROM ALL_CONSTRAINTS A, ALL_CONS_COLUMNS B WHERE A.OWNER = 'LCG_COOL' AND A.TABLE_NAME = 'COOLTEST_DB_ATTRIBUTES' AND A.CONSTRAINT_TYPE = 'P' AND B.OWNER = A.OWNER AND B.TABLE_NAME = A.TABLE_NAME AND B.CONSTRAINT_NAME = A.CONSTRAINT_NAME ORDER BY B.POSITION"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT A.CONSTRAINT_NAME AS FK_NAME, B.TABLE_NAME AS REF_TABLE, C.COLUMN_NAME AS FK_COL, D.COLUMN_NAME AS REF_COL FROM (SELECT CONSTRAINT_NAME, R_CONSTRAINT_NAME FROM ALL_CONSTRAINTS WHERE OWNER='LCG_COOL' AND TABLE_NAME = 'COOLTEST_DB_ATTRIBUTES' AND CONSTRAINT_TYPE='R') A, (SELECT TABLE_NAME, CONSTRAINT_NAME FROM ALL_CONSTRAINTS WHERE OWNER='LCG_COOL') B, (SELECT COLUMN_NAME, CONSTRAINT_NAME, POSITION FROM ALL_CONS_COLUMNS WHERE OWNER='LCG_COOL' AND TABLE_NAME='COOLTEST_DB_ATTRIBUTES' ORDER BY POSITION) C, (SELECT COLUMN_NAME, CONSTRAINT_NAME, TABLE_NAME, POSITION FROM ALL_CONS_COLUMNS WHERE OWNER='LCG_COOL') D WHERE A.R_CONSTRAINT_NAME = B.CONSTRAINT_NAME AND A.CONSTRAINT_NAME = C.CONSTRAINT_NAME AND B.CONSTRAINT_NAME = D.CONSTRAINT_NAME AND C.POSITION = D.POSITION ORDER BY FK_NAME, D.POSITION"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT A.INDEX_NAME, A.UNIQUENESS, B.COLUMN_NAME FROM ALL_INDEXES A, ALL_IND_COLUMNS B WHERE A.OWNER = 'LCG_COOL' AND A.TABLE_NAME = 'COOLTEST_DB_ATTRIBUTES' AND A.GENERATED = 'N' AND A.INDEX_NAME = B.INDEX_NAME AND B.INDEX_OWNER = A.OWNER AND B.TABLE_NAME = A.TABLE_NAME AND A.INDEX_NAME NOT IN (SELECT CONSTRAINT_NAME FROM ALL_CONSTRAINTS WHERE OWNER = A.OWNER AND TABLE_NAME = A.TABLE_NAME AND CONSTRAINT_TYPE = 'P') ORDER BY A.INDEX_NAME, B.COLUMN_POSITION"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "ALTER TABLE "LCG_COOL"."COOLTEST_DB_ATTRIBUTES" ADD ( "DB_ATTRIBUTE_VALUE" VARCHAR2(4000) )"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "INSERT INTO "LCG_COOL"."COOLTEST_DB_ATTRIBUTES" ("DB_ATTRIBUTE_NAME","DB_ATTRIBUTE_VALUE") VALUES (:"DB_ATTRIBUTE_NAME",:"DB_ATTRIBUTE_VALUE")"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "INSERT INTO "LCG_COOL"."COOLTEST_DB_ATTRIBUTES" ("DB_ATTRIBUTE_NAME","DB_ATTRIBUTE_VALUE") VALUES (:"DB_ATTRIBUTE_NAME",:"DB_ATTRIBUTE_VALUE")"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "INSERT INTO "LCG_COOL"."COOLTEST_DB_ATTRIBUTES" ("DB_ATTRIBUTE_NAME","DB_ATTRIBUTE_VALUE") VALUES (:"DB_ATTRIBUTE_NAME",:"DB_ATTRIBUTE_VALUE")"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "INSERT INTO "LCG_COOL"."COOLTEST_DB_ATTRIBUTES" ("DB_ATTRIBUTE_NAME","DB_ATTRIBUTE_VALUE") VALUES (:"DB_ATTRIBUTE_NAME",:"DB_ATTRIBUTE_VALUE")"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "INSERT INTO "LCG_COOL"."COOLTEST_DB_ATTRIBUTES" ("DB_ATTRIBUTE_NAME","DB_ATTRIBUTE_VALUE") VALUES (:"DB_ATTRIBUTE_NAME",:"DB_ATTRIBUTE_VALUE")"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "INSERT INTO "LCG_COOL"."COOLTEST_DB_ATTRIBUTES" ("DB_ATTRIBUTE_NAME","DB_ATTRIBUTE_VALUE") VALUES (:"DB_ATTRIBUTE_NAME",:"DB_ATTRIBUTE_VALUE")"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "INSERT INTO "LCG_COOL"."COOLTEST_DB_ATTRIBUTES" ("DB_ATTRIBUTE_NAME","DB_ATTRIBUTE_VALUE") VALUES (:"DB_ATTRIBUTE_NAME",:"DB_ATTRIBUTE_VALUE")"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "CREATE TABLE "LCG_COOL"."COOLTEST_NODES" ( "NODE_ID" NUMBER(10), "NODE_PARENTID" NUMBER(10), "NODE_NAME" VARCHAR2(255), "NODE_FULLPATH" VARCHAR2(255), "NODE_DESCRIPTION" VARCHAR2(255), "NODE_ISLEAF" NUMBER(1), "NODE_INSTIME" VARCHAR2(255), "FOLDER_PAYLOADSPEC" VARCHAR2(255), "FOLDER_VERSIONING" NUMBER(10), "FOLDER_IOVTABLENAME" VARCHAR2(255), "FOLDER_TAGTABLENAME" VARCHAR2(255), "FOLDER_IOV2TAGTABLENAME" VARCHAR2(255) )"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "ALTER TABLE "LCG_COOL"."COOLTEST_NODES" ADD (CONSTRAINT "COOLTEST_NODES_PK" PRIMARY KEY ("NODE_ID") )"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "ALTER TABLE "LCG_COOL"."COOLTEST_NODES" ADD (CONSTRAINT "COOLTEST_NODES_PARENT_FK" FOREIGN KEY ("NODE_PARENTID") REFERENCES "COOLTEST_NODES" ("NODE_ID"))"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "CREATE UNIQUE INDEX "LCG_COOL"."COOLTEST_NODES_PATH_UK" ON "LCG_COOL"."COOLTEST_NODES"("NODE_FULLPATH")"
+RelationalDatabase                   Debug    Altering table COOLTEST_NODES: modify the SQL type of column FOLDER_PAYLOADSPEC to VARCHAR2(4000)
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT ALL_CONS_COLUMNS.COLUMN_NAME FROM ALL_CONSTRAINTS, ALL_CONS_COLUMNS WHERE ALL_CONSTRAINTS.OWNER = 'LCG_COOL' AND ALL_CONSTRAINTS.TABLE_NAME = 'COOLTEST_NODES' AND ALL_CONSTRAINTS.CONSTRAINT_TYPE = 'U' AND ALL_CONS_COLUMNS.CONSTRAINT_NAME = ALL_CONSTRAINTS.CONSTRAINT_NAME AND ALL_CONS_COLUMNS.OWNER = ALL_CONSTRAINTS.OWNER AND ALL_CONS_COLUMNS.TABLE_NAME = ALL_CONSTRAINTS.TABLE_NAME"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT A.CONSTRAINT_NAME, B.COLUMN_NAME FROM ALL_CONSTRAINTS A, ALL_CONS_COLUMNS B WHERE A.OWNER = 'LCG_COOL' AND A.TABLE_NAME = 'COOLTEST_NODES' AND A.CONSTRAINT_TYPE = 'P' AND B.OWNER = A.OWNER AND B.TABLE_NAME = A.TABLE_NAME AND B.CONSTRAINT_NAME = A.CONSTRAINT_NAME ORDER BY B.POSITION"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT A.CONSTRAINT_NAME AS FK_NAME, B.TABLE_NAME AS REF_TABLE, C.COLUMN_NAME AS FK_COL, D.COLUMN_NAME AS REF_COL FROM (SELECT CONSTRAINT_NAME, R_CONSTRAINT_NAME FROM ALL_CONSTRAINTS WHERE OWNER='LCG_COOL' AND TABLE_NAME = 'COOLTEST_NODES' AND CONSTRAINT_TYPE='R') A, (SELECT TABLE_NAME, CONSTRAINT_NAME FROM ALL_CONSTRAINTS WHERE OWNER='LCG_COOL') B, (SELECT COLUMN_NAME, CONSTRAINT_NAME, POSITION FROM ALL_CONS_COLUMNS WHERE OWNER='LCG_COOL' AND TABLE_NAME='COOLTEST_NODES' ORDER BY POSITION) C, (SELECT COLUMN_NAME, CONSTRAINT_NAME, TABLE_NAME, POSITION FROM ALL_CONS_COLUMNS WHERE OWNER='LCG_COOL') D WHERE A.R_CONSTRAINT_NAME = B.CONSTRAINT_NAME AND A.CONSTRAINT_NAME = C.CONSTRAINT_NAME AND B.CONSTRAINT_NAME = D.CONSTRAINT_NAME AND C.POSITION = D.POSITION ORDER BY FK_NAME, D.POSITION"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT A.INDEX_NAME, A.UNIQUENESS, B.COLUMN_NAME FROM ALL_INDEXES A, ALL_IND_COLUMNS B WHERE A.OWNER = 'LCG_COOL' AND A.TABLE_NAME = 'COOLTEST_NODES' AND A.GENERATED = 'N' AND A.INDEX_NAME = B.INDEX_NAME AND B.INDEX_OWNER = A.OWNER AND B.TABLE_NAME = A.TABLE_NAME AND A.INDEX_NAME NOT IN (SELECT CONSTRAINT_NAME FROM ALL_CONSTRAINTS WHERE OWNER = A.OWNER AND TABLE_NAME = A.TABLE_NAME AND CONSTRAINT_TYPE = 'P') ORDER BY A.INDEX_NAME, B.COLUMN_POSITION"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "ALTER TABLE "LCG_COOL"."COOLTEST_NODES" DROP COLUMN "FOLDER_PAYLOADSPEC""
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "ALTER TABLE "LCG_COOL"."COOLTEST_NODES" ADD ( "FOLDER_PAYLOADSPEC" VARCHAR2(4000) )"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "ALTER TABLE "LCG_COOL"."COOLTEST_NODES" DROP COLUMN "FOLDER_VERSIONING""
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "ALTER TABLE "LCG_COOL"."COOLTEST_NODES" ADD ( "FOLDER_VERSIONING" NUMBER(10) )"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "ALTER TABLE "LCG_COOL"."COOLTEST_NODES" DROP COLUMN "FOLDER_IOVTABLENAME""
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "ALTER TABLE "LCG_COOL"."COOLTEST_NODES" ADD ( "FOLDER_IOVTABLENAME" VARCHAR2(255) )"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "ALTER TABLE "LCG_COOL"."COOLTEST_NODES" DROP COLUMN "FOLDER_TAGTABLENAME""
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "ALTER TABLE "LCG_COOL"."COOLTEST_NODES" ADD ( "FOLDER_TAGTABLENAME" VARCHAR2(255) )"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "ALTER TABLE "LCG_COOL"."COOLTEST_NODES" DROP COLUMN "FOLDER_IOV2TAGTABLENAME""
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "ALTER TABLE "LCG_COOL"."COOLTEST_NODES" ADD ( "FOLDER_IOV2TAGTABLENAME" VARCHAR2(255) )"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "CREATE TABLE "LCG_COOL"."COOLTEST_NODES_SEQ" ( "SEQUENCE_NAME" VARCHAR2(255), "CURRENT_VALUE" NUMBER(10), "LASTMOD_DATE" VARCHAR2(255) )"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "ALTER TABLE "LCG_COOL"."COOLTEST_NODES_SEQ" ADD (CONSTRAINT "COOLTEST_NODES_SEQ_PK" PRIMARY KEY ("SEQUENCE_NAME") )"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "INSERT INTO "LCG_COOL"."COOLTEST_NODES_SEQ" ("SEQUENCE_NAME") VALUES (:"SEQUENCE_NAME")"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT "CURRENT_VALUE", "LASTMOD_DATE" FROM "LCG_COOL"."COOLTEST_NODES_SEQ" FOR UPDATE"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "UPDATE "LCG_COOL"."COOLTEST_NODES_SEQ" SET "CURRENT_VALUE"=:"newvalue", "LASTMOD_DATE"=TO_CHAR(SYSTIMESTAMP AT TIME ZONE 'GMT','yyyy-mm-dd_hh24:mi:ss.ff6')||'000 GMT'"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT "CURRENT_VALUE", "LASTMOD_DATE" FROM "LCG_COOL"."COOLTEST_NODES_SEQ" FOR UPDATE"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "INSERT INTO "LCG_COOL"."COOLTEST_NODES" ("NODE_ID","NODE_NAME","NODE_FULLPATH","NODE_DESCRIPTION","NODE_ISLEAF","NODE_INSTIME") VALUES (:"NODE_ID",:"NODE_NAME",:"NODE_FULLPATH",:"NODE_DESCRIPTION",:"NODE_ISLEAF",:"NODE_INSTIME")"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "CREATE TABLE "LCG_COOL"."COOLTEST_TAGS" ( "TAG_ID" NUMBER(10), "NODE_ID" NUMBER(10), "TAG_NAME" VARCHAR2(255), "TAG_DESCRIPTION" VARCHAR2(255), "SYS_INSTIME" VARCHAR2(255) )"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "ALTER TABLE "LCG_COOL"."COOLTEST_TAGS" ADD (CONSTRAINT "COOLTEST_TAGS_PK" PRIMARY KEY ("TAG_ID","NODE_ID") )"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_INSTIME", "FOLDER_PAYLOADSPEC", "FOLDER_VERSIONING", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME" FROM "LCG_COOL"."COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalFolder                     Debug    Instantiate a RelationalFolder for '/'
+RelationalFolder                     Debug    Delete the RelationalFolder for '/'
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT "CURRENT_VALUE", "LASTMOD_DATE" FROM "LCG_COOL"."COOLTEST_NODES_SEQ" FOR UPDATE"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "UPDATE "LCG_COOL"."COOLTEST_NODES_SEQ" SET "CURRENT_VALUE"=:"newvalue", "LASTMOD_DATE"=TO_CHAR(SYSTIMESTAMP AT TIME ZONE 'GMT','yyyy-mm-dd_hh24:mi:ss.ff6')||'000 GMT'"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT "CURRENT_VALUE", "LASTMOD_DATE" FROM "LCG_COOL"."COOLTEST_NODES_SEQ" FOR UPDATE"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_INSTIME", "FOLDER_PAYLOADSPEC", "FOLDER_VERSIONING", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME" FROM "LCG_COOL"."COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "INSERT INTO "LCG_COOL"."COOLTEST_NODES" ("NODE_ID","NODE_PARENTID","NODE_NAME","NODE_FULLPATH","NODE_DESCRIPTION","NODE_ISLEAF","NODE_INSTIME","FOLDER_PAYLOADSPEC","FOLDER_VERSIONING","FOLDER_IOVTABLENAME","FOLDER_TAGTABLENAME","FOLDER_IOV2TAGTABLENAME") VALUES (:"NODE_ID",:"NODE_PARENTID",:"NODE_NAME",:"NODE_FULLPATH",:"NODE_DESCRIPTION",:"NODE_ISLEAF",:"NODE_INSTIME",:"FOLDER_PAYLOADSPEC",:"FOLDER_VERSIONING",:"FOLDER_IOVTABLENAME",:"FOLDER_TAGTABLENAME",:"FOLDER_IOV2TAGTABLENAME")"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "CREATE TABLE "LCG_COOL"."COOLTEST_F0001_IOVS" ( "OBJECT_ID" NUMBER(10), "CHANNEL_ID" NUMBER(10), "IOV_SINCE" NUMBER(20), "IOV_UNTIL" NUMBER(20), "SYS_INSTIME" VARCHAR2(255), "ORIGINAL_ID" NUMBER(10), "NEW_HEAD_ID" NUMBER(10), "I" NUMBER(10), "S" VARCHAR2(255), "X" BINARY_FLOAT )"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "ALTER TABLE "LCG_COOL"."COOLTEST_F0001_IOVS" ADD (CONSTRAINT "COOLTEST_F0001_IOVS_PK" PRIMARY KEY ("OBJECT_ID") )"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "CREATE INDEX "LCG_COOL"."COOLTEST_F0001_IOVS_CO_2INDX" ON "LCG_COOL"."COOLTEST_F0001_IOVS"("CHANNEL_ID","OBJECT_ID")"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "CREATE INDEX "LCG_COOL"."COOLTEST_F0001_IOVS_CSU_3INDX" ON "LCG_COOL"."COOLTEST_F0001_IOVS"("CHANNEL_ID","IOV_SINCE","IOV_UNTIL")"
+RelationalDatabase                   Debug    Altering table COOLTEST_F0001_IOVS: modify the SQL type of column S to VARCHAR2(4000)
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT ALL_CONS_COLUMNS.COLUMN_NAME FROM ALL_CONSTRAINTS, ALL_CONS_COLUMNS WHERE ALL_CONSTRAINTS.OWNER = 'LCG_COOL' AND ALL_CONSTRAINTS.TABLE_NAME = 'COOLTEST_F0001_IOVS' AND ALL_CONSTRAINTS.CONSTRAINT_TYPE = 'U' AND ALL_CONS_COLUMNS.CONSTRAINT_NAME = ALL_CONSTRAINTS.CONSTRAINT_NAME AND ALL_CONS_COLUMNS.OWNER = ALL_CONSTRAINTS.OWNER AND ALL_CONS_COLUMNS.TABLE_NAME = ALL_CONSTRAINTS.TABLE_NAME"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT A.CONSTRAINT_NAME, B.COLUMN_NAME FROM ALL_CONSTRAINTS A, ALL_CONS_COLUMNS B WHERE A.OWNER = 'LCG_COOL' AND A.TABLE_NAME = 'COOLTEST_F0001_IOVS' AND A.CONSTRAINT_TYPE = 'P' AND B.OWNER = A.OWNER AND B.TABLE_NAME = A.TABLE_NAME AND B.CONSTRAINT_NAME = A.CONSTRAINT_NAME ORDER BY B.POSITION"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT A.CONSTRAINT_NAME AS FK_NAME, B.TABLE_NAME AS REF_TABLE, C.COLUMN_NAME AS FK_COL, D.COLUMN_NAME AS REF_COL FROM (SELECT CONSTRAINT_NAME, R_CONSTRAINT_NAME FROM ALL_CONSTRAINTS WHERE OWNER='LCG_COOL' AND TABLE_NAME = 'COOLTEST_F0001_IOVS' AND CONSTRAINT_TYPE='R') A, (SELECT TABLE_NAME, CONSTRAINT_NAME FROM ALL_CONSTRAINTS WHERE OWNER='LCG_COOL') B, (SELECT COLUMN_NAME, CONSTRAINT_NAME, POSITION FROM ALL_CONS_COLUMNS WHERE OWNER='LCG_COOL' AND TABLE_NAME='COOLTEST_F0001_IOVS' ORDER BY POSITION) C, (SELECT COLUMN_NAME, CONSTRAINT_NAME, TABLE_NAME, POSITION FROM ALL_CONS_COLUMNS WHERE OWNER='LCG_COOL') D WHERE A.R_CONSTRAINT_NAME = B.CONSTRAINT_NAME AND A.CONSTRAINT_NAME = C.CONSTRAINT_NAME AND B.CONSTRAINT_NAME = D.CONSTRAINT_NAME AND C.POSITION = D.POSITION ORDER BY FK_NAME, D.POSITION"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT A.INDEX_NAME, A.UNIQUENESS, B.COLUMN_NAME FROM ALL_INDEXES A, ALL_IND_COLUMNS B WHERE A.OWNER = 'LCG_COOL' AND A.TABLE_NAME = 'COOLTEST_F0001_IOVS' AND A.GENERATED = 'N' AND A.INDEX_NAME = B.INDEX_NAME AND B.INDEX_OWNER = A.OWNER AND B.TABLE_NAME = A.TABLE_NAME AND A.INDEX_NAME NOT IN (SELECT CONSTRAINT_NAME FROM ALL_CONSTRAINTS WHERE OWNER = A.OWNER AND TABLE_NAME = A.TABLE_NAME AND CONSTRAINT_TYPE = 'P') ORDER BY A.INDEX_NAME, B.COLUMN_POSITION"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "ALTER TABLE "LCG_COOL"."COOLTEST_F0001_IOVS" DROP COLUMN "S""
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "ALTER TABLE "LCG_COOL"."COOLTEST_F0001_IOVS" ADD ( "S" VARCHAR2(4000) )"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "ALTER TABLE "LCG_COOL"."COOLTEST_F0001_IOVS" DROP COLUMN "X""
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "ALTER TABLE "LCG_COOL"."COOLTEST_F0001_IOVS" ADD ( "X" BINARY_FLOAT )"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "CREATE TABLE "LCG_COOL"."COOLTEST_F0001_IOVS_SEQ" ( "SEQUENCE_NAME" VARCHAR2(255), "CURRENT_VALUE" NUMBER(10), "LASTMOD_DATE" VARCHAR2(255) )"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "ALTER TABLE "LCG_COOL"."COOLTEST_F0001_IOVS_SEQ" ADD (CONSTRAINT "COOLTEST_F0001_IOVS_SEQ_PK" PRIMARY KEY ("SEQUENCE_NAME") )"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "INSERT INTO "LCG_COOL"."COOLTEST_F0001_IOVS_SEQ" ("SEQUENCE_NAME") VALUES (:"SEQUENCE_NAME")"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT "CURRENT_VALUE", "LASTMOD_DATE" FROM "LCG_COOL"."COOLTEST_F0001_IOVS_SEQ" FOR UPDATE"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "UPDATE "LCG_COOL"."COOLTEST_F0001_IOVS_SEQ" SET "CURRENT_VALUE"=:"newvalue", "LASTMOD_DATE"=TO_CHAR(SYSTIMESTAMP AT TIME ZONE 'GMT','yyyy-mm-dd_hh24:mi:ss.ff6')||'000 GMT'"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_INSTIME", "FOLDER_PAYLOADSPEC", "FOLDER_VERSIONING", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME" FROM "LCG_COOL"."COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalFolder                     Debug    Instantiate a RelationalFolder for '/f1'
+RelationalFolder                     Debug    Delete the RelationalFolder for '/f1'
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_INSTIME", "FOLDER_PAYLOADSPEC", "FOLDER_VERSIONING", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME" FROM "LCG_COOL"."COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalFolder                     Debug    Instantiate a RelationalFolder for '/'
+RelationalFolder                     Debug    Delete the RelationalFolder for '/'
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT "CURRENT_VALUE", "LASTMOD_DATE" FROM "LCG_COOL"."COOLTEST_NODES_SEQ" FOR UPDATE"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "UPDATE "LCG_COOL"."COOLTEST_NODES_SEQ" SET "CURRENT_VALUE"=:"newvalue", "LASTMOD_DATE"=TO_CHAR(SYSTIMESTAMP AT TIME ZONE 'GMT','yyyy-mm-dd_hh24:mi:ss.ff6')||'000 GMT'"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT "CURRENT_VALUE", "LASTMOD_DATE" FROM "LCG_COOL"."COOLTEST_NODES_SEQ" FOR UPDATE"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_INSTIME", "FOLDER_PAYLOADSPEC", "FOLDER_VERSIONING", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME" FROM "LCG_COOL"."COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "INSERT INTO "LCG_COOL"."COOLTEST_NODES" ("NODE_ID","NODE_PARENTID","NODE_NAME","NODE_FULLPATH","NODE_DESCRIPTION","NODE_ISLEAF","NODE_INSTIME","FOLDER_PAYLOADSPEC","FOLDER_VERSIONING","FOLDER_IOVTABLENAME","FOLDER_TAGTABLENAME","FOLDER_IOV2TAGTABLENAME") VALUES (:"NODE_ID",:"NODE_PARENTID",:"NODE_NAME",:"NODE_FULLPATH",:"NODE_DESCRIPTION",:"NODE_ISLEAF",:"NODE_INSTIME",:"FOLDER_PAYLOADSPEC",:"FOLDER_VERSIONING",:"FOLDER_IOVTABLENAME",:"FOLDER_TAGTABLENAME",:"FOLDER_IOV2TAGTABLENAME")"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "CREATE TABLE "LCG_COOL"."COOLTEST_F0002_IOVS" ( "OBJECT_ID" NUMBER(10), "CHANNEL_ID" NUMBER(10), "IOV_SINCE" NUMBER(20), "IOV_UNTIL" NUMBER(20), "SYS_INSTIME" VARCHAR2(255), "ORIGINAL_ID" NUMBER(10), "NEW_HEAD_ID" NUMBER(10), "I" NUMBER(10), "S" VARCHAR2(255), "X" BINARY_FLOAT )"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "ALTER TABLE "LCG_COOL"."COOLTEST_F0002_IOVS" ADD (CONSTRAINT "COOLTEST_F0002_IOVS_PK" PRIMARY KEY ("OBJECT_ID") )"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "CREATE INDEX "LCG_COOL"."COOLTEST_F0002_IOVS_CO_2INDX" ON "LCG_COOL"."COOLTEST_F0002_IOVS"("CHANNEL_ID","OBJECT_ID")"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "CREATE INDEX "LCG_COOL"."COOLTEST_F0002_IOVS_CSU_3INDX" ON "LCG_COOL"."COOLTEST_F0002_IOVS"("CHANNEL_ID","IOV_SINCE","IOV_UNTIL")"
+RelationalDatabase                   Debug    Altering table COOLTEST_F0002_IOVS: modify the SQL type of column S to VARCHAR2(4000)
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT ALL_CONS_COLUMNS.COLUMN_NAME FROM ALL_CONSTRAINTS, ALL_CONS_COLUMNS WHERE ALL_CONSTRAINTS.OWNER = 'LCG_COOL' AND ALL_CONSTRAINTS.TABLE_NAME = 'COOLTEST_F0002_IOVS' AND ALL_CONSTRAINTS.CONSTRAINT_TYPE = 'U' AND ALL_CONS_COLUMNS.CONSTRAINT_NAME = ALL_CONSTRAINTS.CONSTRAINT_NAME AND ALL_CONS_COLUMNS.OWNER = ALL_CONSTRAINTS.OWNER AND ALL_CONS_COLUMNS.TABLE_NAME = ALL_CONSTRAINTS.TABLE_NAME"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT A.CONSTRAINT_NAME, B.COLUMN_NAME FROM ALL_CONSTRAINTS A, ALL_CONS_COLUMNS B WHERE A.OWNER = 'LCG_COOL' AND A.TABLE_NAME = 'COOLTEST_F0002_IOVS' AND A.CONSTRAINT_TYPE = 'P' AND B.OWNER = A.OWNER AND B.TABLE_NAME = A.TABLE_NAME AND B.CONSTRAINT_NAME = A.CONSTRAINT_NAME ORDER BY B.POSITION"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT A.CONSTRAINT_NAME AS FK_NAME, B.TABLE_NAME AS REF_TABLE, C.COLUMN_NAME AS FK_COL, D.COLUMN_NAME AS REF_COL FROM (SELECT CONSTRAINT_NAME, R_CONSTRAINT_NAME FROM ALL_CONSTRAINTS WHERE OWNER='LCG_COOL' AND TABLE_NAME = 'COOLTEST_F0002_IOVS' AND CONSTRAINT_TYPE='R') A, (SELECT TABLE_NAME, CONSTRAINT_NAME FROM ALL_CONSTRAINTS WHERE OWNER='LCG_COOL') B, (SELECT COLUMN_NAME, CONSTRAINT_NAME, POSITION FROM ALL_CONS_COLUMNS WHERE OWNER='LCG_COOL' AND TABLE_NAME='COOLTEST_F0002_IOVS' ORDER BY POSITION) C, (SELECT COLUMN_NAME, CONSTRAINT_NAME, TABLE_NAME, POSITION FROM ALL_CONS_COLUMNS WHERE OWNER='LCG_COOL') D WHERE A.R_CONSTRAINT_NAME = B.CONSTRAINT_NAME AND A.CONSTRAINT_NAME = C.CONSTRAINT_NAME AND B.CONSTRAINT_NAME = D.CONSTRAINT_NAME AND C.POSITION = D.POSITION ORDER BY FK_NAME, D.POSITION"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT A.INDEX_NAME, A.UNIQUENESS, B.COLUMN_NAME FROM ALL_INDEXES A, ALL_IND_COLUMNS B WHERE A.OWNER = 'LCG_COOL' AND A.TABLE_NAME = 'COOLTEST_F0002_IOVS' AND A.GENERATED = 'N' AND A.INDEX_NAME = B.INDEX_NAME AND B.INDEX_OWNER = A.OWNER AND B.TABLE_NAME = A.TABLE_NAME AND A.INDEX_NAME NOT IN (SELECT CONSTRAINT_NAME FROM ALL_CONSTRAINTS WHERE OWNER = A.OWNER AND TABLE_NAME = A.TABLE_NAME AND CONSTRAINT_TYPE = 'P') ORDER BY A.INDEX_NAME, B.COLUMN_POSITION"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "ALTER TABLE "LCG_COOL"."COOLTEST_F0002_IOVS" DROP COLUMN "S""
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "ALTER TABLE "LCG_COOL"."COOLTEST_F0002_IOVS" ADD ( "S" VARCHAR2(4000) )"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "ALTER TABLE "LCG_COOL"."COOLTEST_F0002_IOVS" DROP COLUMN "X""
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "ALTER TABLE "LCG_COOL"."COOLTEST_F0002_IOVS" ADD ( "X" BINARY_FLOAT )"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "CREATE TABLE "LCG_COOL"."COOLTEST_F0002_IOVS_SEQ" ( "SEQUENCE_NAME" VARCHAR2(255), "CURRENT_VALUE" NUMBER(10), "LASTMOD_DATE" VARCHAR2(255) )"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "ALTER TABLE "LCG_COOL"."COOLTEST_F0002_IOVS_SEQ" ADD (CONSTRAINT "COOLTEST_F0002_IOVS_SEQ_PK" PRIMARY KEY ("SEQUENCE_NAME") )"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "INSERT INTO "LCG_COOL"."COOLTEST_F0002_IOVS_SEQ" ("SEQUENCE_NAME") VALUES (:"SEQUENCE_NAME")"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT "CURRENT_VALUE", "LASTMOD_DATE" FROM "LCG_COOL"."COOLTEST_F0002_IOVS_SEQ" FOR UPDATE"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "UPDATE "LCG_COOL"."COOLTEST_F0002_IOVS_SEQ" SET "CURRENT_VALUE"=:"newvalue", "LASTMOD_DATE"=TO_CHAR(SYSTIMESTAMP AT TIME ZONE 'GMT','yyyy-mm-dd_hh24:mi:ss.ff6')||'000 GMT'"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_INSTIME", "FOLDER_PAYLOADSPEC", "FOLDER_VERSIONING", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME" FROM "LCG_COOL"."COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalFolder                     Debug    Instantiate a RelationalFolder for '/f2'
+RelationalFolder                     Debug    Delete the RelationalFolder for '/f2'
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_INSTIME", "FOLDER_PAYLOADSPEC", "FOLDER_VERSIONING", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME" FROM "LCG_COOL"."COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalFolder                     Debug    Instantiate a RelationalFolder for '/'
+RelationalFolder                     Debug    Delete the RelationalFolder for '/'
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT "CURRENT_VALUE", "LASTMOD_DATE" FROM "LCG_COOL"."COOLTEST_NODES_SEQ" FOR UPDATE"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "UPDATE "LCG_COOL"."COOLTEST_NODES_SEQ" SET "CURRENT_VALUE"=:"newvalue", "LASTMOD_DATE"=TO_CHAR(SYSTIMESTAMP AT TIME ZONE 'GMT','yyyy-mm-dd_hh24:mi:ss.ff6')||'000 GMT'"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT "CURRENT_VALUE", "LASTMOD_DATE" FROM "LCG_COOL"."COOLTEST_NODES_SEQ" FOR UPDATE"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_INSTIME", "FOLDER_PAYLOADSPEC", "FOLDER_VERSIONING", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME" FROM "LCG_COOL"."COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "INSERT INTO "LCG_COOL"."COOLTEST_NODES" ("NODE_ID","NODE_PARENTID","NODE_NAME","NODE_FULLPATH","NODE_DESCRIPTION","NODE_ISLEAF","NODE_INSTIME","FOLDER_PAYLOADSPEC","FOLDER_VERSIONING","FOLDER_IOVTABLENAME","FOLDER_TAGTABLENAME","FOLDER_IOV2TAGTABLENAME") VALUES (:"NODE_ID",:"NODE_PARENTID",:"NODE_NAME",:"NODE_FULLPATH",:"NODE_DESCRIPTION",:"NODE_ISLEAF",:"NODE_INSTIME",:"FOLDER_PAYLOADSPEC",:"FOLDER_VERSIONING",:"FOLDER_IOVTABLENAME",:"FOLDER_TAGTABLENAME",:"FOLDER_IOV2TAGTABLENAME")"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "CREATE TABLE "LCG_COOL"."COOLTEST_F0003_IOVS" ( "OBJECT_ID" NUMBER(10), "CHANNEL_ID" NUMBER(10), "IOV_SINCE" NUMBER(20), "IOV_UNTIL" NUMBER(20), "SYS_INSTIME" VARCHAR2(255), "ORIGINAL_ID" NUMBER(10), "NEW_HEAD_ID" NUMBER(10), "I" NUMBER(10), "S" VARCHAR2(255), "X" BINARY_FLOAT )"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "ALTER TABLE "LCG_COOL"."COOLTEST_F0003_IOVS" ADD (CONSTRAINT "COOLTEST_F0003_IOVS_PK" PRIMARY KEY ("OBJECT_ID") )"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "CREATE INDEX "LCG_COOL"."COOLTEST_F0003_IOVS_CO_2INDX" ON "LCG_COOL"."COOLTEST_F0003_IOVS"("CHANNEL_ID","OBJECT_ID")"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "CREATE INDEX "LCG_COOL"."COOLTEST_F0003_IOVS_CSU_3INDX" ON "LCG_COOL"."COOLTEST_F0003_IOVS"("CHANNEL_ID","IOV_SINCE","IOV_UNTIL")"
+RelationalDatabase                   Debug    Altering table COOLTEST_F0003_IOVS: modify the SQL type of column S to VARCHAR2(4000)
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT ALL_CONS_COLUMNS.COLUMN_NAME FROM ALL_CONSTRAINTS, ALL_CONS_COLUMNS WHERE ALL_CONSTRAINTS.OWNER = 'LCG_COOL' AND ALL_CONSTRAINTS.TABLE_NAME = 'COOLTEST_F0003_IOVS' AND ALL_CONSTRAINTS.CONSTRAINT_TYPE = 'U' AND ALL_CONS_COLUMNS.CONSTRAINT_NAME = ALL_CONSTRAINTS.CONSTRAINT_NAME AND ALL_CONS_COLUMNS.OWNER = ALL_CONSTRAINTS.OWNER AND ALL_CONS_COLUMNS.TABLE_NAME = ALL_CONSTRAINTS.TABLE_NAME"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT A.CONSTRAINT_NAME, B.COLUMN_NAME FROM ALL_CONSTRAINTS A, ALL_CONS_COLUMNS B WHERE A.OWNER = 'LCG_COOL' AND A.TABLE_NAME = 'COOLTEST_F0003_IOVS' AND A.CONSTRAINT_TYPE = 'P' AND B.OWNER = A.OWNER AND B.TABLE_NAME = A.TABLE_NAME AND B.CONSTRAINT_NAME = A.CONSTRAINT_NAME ORDER BY B.POSITION"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT A.CONSTRAINT_NAME AS FK_NAME, B.TABLE_NAME AS REF_TABLE, C.COLUMN_NAME AS FK_COL, D.COLUMN_NAME AS REF_COL FROM (SELECT CONSTRAINT_NAME, R_CONSTRAINT_NAME FROM ALL_CONSTRAINTS WHERE OWNER='LCG_COOL' AND TABLE_NAME = 'COOLTEST_F0003_IOVS' AND CONSTRAINT_TYPE='R') A, (SELECT TABLE_NAME, CONSTRAINT_NAME FROM ALL_CONSTRAINTS WHERE OWNER='LCG_COOL') B, (SELECT COLUMN_NAME, CONSTRAINT_NAME, POSITION FROM ALL_CONS_COLUMNS WHERE OWNER='LCG_COOL' AND TABLE_NAME='COOLTEST_F0003_IOVS' ORDER BY POSITION) C, (SELECT COLUMN_NAME, CONSTRAINT_NAME, TABLE_NAME, POSITION FROM ALL_CONS_COLUMNS WHERE OWNER='LCG_COOL') D WHERE A.R_CONSTRAINT_NAME = B.CONSTRAINT_NAME AND A.CONSTRAINT_NAME = C.CONSTRAINT_NAME AND B.CONSTRAINT_NAME = D.CONSTRAINT_NAME AND C.POSITION = D.POSITION ORDER BY FK_NAME, D.POSITION"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT A.INDEX_NAME, A.UNIQUENESS, B.COLUMN_NAME FROM ALL_INDEXES A, ALL_IND_COLUMNS B WHERE A.OWNER = 'LCG_COOL' AND A.TABLE_NAME = 'COOLTEST_F0003_IOVS' AND A.GENERATED = 'N' AND A.INDEX_NAME = B.INDEX_NAME AND B.INDEX_OWNER = A.OWNER AND B.TABLE_NAME = A.TABLE_NAME AND A.INDEX_NAME NOT IN (SELECT CONSTRAINT_NAME FROM ALL_CONSTRAINTS WHERE OWNER = A.OWNER AND TABLE_NAME = A.TABLE_NAME AND CONSTRAINT_TYPE = 'P') ORDER BY A.INDEX_NAME, B.COLUMN_POSITION"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "ALTER TABLE "LCG_COOL"."COOLTEST_F0003_IOVS" DROP COLUMN "S""
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "ALTER TABLE "LCG_COOL"."COOLTEST_F0003_IOVS" ADD ( "S" VARCHAR2(4000) )"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "ALTER TABLE "LCG_COOL"."COOLTEST_F0003_IOVS" DROP COLUMN "X""
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "ALTER TABLE "LCG_COOL"."COOLTEST_F0003_IOVS" ADD ( "X" BINARY_FLOAT )"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "CREATE TABLE "LCG_COOL"."COOLTEST_F0003_IOVS_SEQ" ( "SEQUENCE_NAME" VARCHAR2(255), "CURRENT_VALUE" NUMBER(10), "LASTMOD_DATE" VARCHAR2(255) )"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "ALTER TABLE "LCG_COOL"."COOLTEST_F0003_IOVS_SEQ" ADD (CONSTRAINT "COOLTEST_F0003_IOVS_SEQ_PK" PRIMARY KEY ("SEQUENCE_NAME") )"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "INSERT INTO "LCG_COOL"."COOLTEST_F0003_IOVS_SEQ" ("SEQUENCE_NAME") VALUES (:"SEQUENCE_NAME")"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT "CURRENT_VALUE", "LASTMOD_DATE" FROM "LCG_COOL"."COOLTEST_F0003_IOVS_SEQ" FOR UPDATE"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "UPDATE "LCG_COOL"."COOLTEST_F0003_IOVS_SEQ" SET "CURRENT_VALUE"=:"newvalue", "LASTMOD_DATE"=TO_CHAR(SYSTIMESTAMP AT TIME ZONE 'GMT','yyyy-mm-dd_hh24:mi:ss.ff6')||'000 GMT'"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_INSTIME", "FOLDER_PAYLOADSPEC", "FOLDER_VERSIONING", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME" FROM "LCG_COOL"."COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalFolder                     Debug    Instantiate a RelationalFolder for '/f3'
+RelationalFolder                     Debug    Delete the RelationalFolder for '/f3'
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_INSTIME", "FOLDER_PAYLOADSPEC", "FOLDER_VERSIONING", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME" FROM "LCG_COOL"."COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalFolder                     Debug    Instantiate a RelationalFolder for '/'
+RelationalFolder                     Debug    Delete the RelationalFolder for '/'
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT "CURRENT_VALUE", "LASTMOD_DATE" FROM "LCG_COOL"."COOLTEST_NODES_SEQ" FOR UPDATE"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "UPDATE "LCG_COOL"."COOLTEST_NODES_SEQ" SET "CURRENT_VALUE"=:"newvalue", "LASTMOD_DATE"=TO_CHAR(SYSTIMESTAMP AT TIME ZONE 'GMT','yyyy-mm-dd_hh24:mi:ss.ff6')||'000 GMT'"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT "CURRENT_VALUE", "LASTMOD_DATE" FROM "LCG_COOL"."COOLTEST_NODES_SEQ" FOR UPDATE"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_INSTIME", "FOLDER_PAYLOADSPEC", "FOLDER_VERSIONING", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME" FROM "LCG_COOL"."COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "INSERT INTO "LCG_COOL"."COOLTEST_NODES" ("NODE_ID","NODE_PARENTID","NODE_NAME","NODE_FULLPATH","NODE_DESCRIPTION","NODE_ISLEAF","NODE_INSTIME","FOLDER_PAYLOADSPEC","FOLDER_VERSIONING","FOLDER_IOVTABLENAME","FOLDER_TAGTABLENAME","FOLDER_IOV2TAGTABLENAME") VALUES (:"NODE_ID",:"NODE_PARENTID",:"NODE_NAME",:"NODE_FULLPATH",:"NODE_DESCRIPTION",:"NODE_ISLEAF",:"NODE_INSTIME",:"FOLDER_PAYLOADSPEC",:"FOLDER_VERSIONING",:"FOLDER_IOVTABLENAME",:"FOLDER_TAGTABLENAME",:"FOLDER_IOV2TAGTABLENAME")"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "CREATE TABLE "LCG_COOL"."COOLTEST_F0004_IOVS" ( "OBJECT_ID" NUMBER(10), "CHANNEL_ID" NUMBER(10), "IOV_SINCE" NUMBER(20), "IOV_UNTIL" NUMBER(20), "SYS_INSTIME" VARCHAR2(255), "ORIGINAL_ID" NUMBER(10), "NEW_HEAD_ID" NUMBER(10), "I" NUMBER(10), "S" VARCHAR2(255), "X" BINARY_FLOAT )"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "ALTER TABLE "LCG_COOL"."COOLTEST_F0004_IOVS" ADD (CONSTRAINT "COOLTEST_F0004_IOVS_PK" PRIMARY KEY ("OBJECT_ID") )"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "CREATE INDEX "LCG_COOL"."COOLTEST_F0004_IOVS_CO_2INDX" ON "LCG_COOL"."COOLTEST_F0004_IOVS"("CHANNEL_ID","OBJECT_ID")"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "CREATE INDEX "LCG_COOL"."COOLTEST_F0004_IOVS_CSU_3INDX" ON "LCG_COOL"."COOLTEST_F0004_IOVS"("CHANNEL_ID","IOV_SINCE","IOV_UNTIL")"
+RelationalDatabase                   Debug    Altering table COOLTEST_F0004_IOVS: modify the SQL type of column S to VARCHAR2(4000)
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT ALL_CONS_COLUMNS.COLUMN_NAME FROM ALL_CONSTRAINTS, ALL_CONS_COLUMNS WHERE ALL_CONSTRAINTS.OWNER = 'LCG_COOL' AND ALL_CONSTRAINTS.TABLE_NAME = 'COOLTEST_F0004_IOVS' AND ALL_CONSTRAINTS.CONSTRAINT_TYPE = 'U' AND ALL_CONS_COLUMNS.CONSTRAINT_NAME = ALL_CONSTRAINTS.CONSTRAINT_NAME AND ALL_CONS_COLUMNS.OWNER = ALL_CONSTRAINTS.OWNER AND ALL_CONS_COLUMNS.TABLE_NAME = ALL_CONSTRAINTS.TABLE_NAME"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT A.CONSTRAINT_NAME, B.COLUMN_NAME FROM ALL_CONSTRAINTS A, ALL_CONS_COLUMNS B WHERE A.OWNER = 'LCG_COOL' AND A.TABLE_NAME = 'COOLTEST_F0004_IOVS' AND A.CONSTRAINT_TYPE = 'P' AND B.OWNER = A.OWNER AND B.TABLE_NAME = A.TABLE_NAME AND B.CONSTRAINT_NAME = A.CONSTRAINT_NAME ORDER BY B.POSITION"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT A.CONSTRAINT_NAME AS FK_NAME, B.TABLE_NAME AS REF_TABLE, C.COLUMN_NAME AS FK_COL, D.COLUMN_NAME AS REF_COL FROM (SELECT CONSTRAINT_NAME, R_CONSTRAINT_NAME FROM ALL_CONSTRAINTS WHERE OWNER='LCG_COOL' AND TABLE_NAME = 'COOLTEST_F0004_IOVS' AND CONSTRAINT_TYPE='R') A, (SELECT TABLE_NAME, CONSTRAINT_NAME FROM ALL_CONSTRAINTS WHERE OWNER='LCG_COOL') B, (SELECT COLUMN_NAME, CONSTRAINT_NAME, POSITION FROM ALL_CONS_COLUMNS WHERE OWNER='LCG_COOL' AND TABLE_NAME='COOLTEST_F0004_IOVS' ORDER BY POSITION) C, (SELECT COLUMN_NAME, CONSTRAINT_NAME, TABLE_NAME, POSITION FROM ALL_CONS_COLUMNS WHERE OWNER='LCG_COOL') D WHERE A.R_CONSTRAINT_NAME = B.CONSTRAINT_NAME AND A.CONSTRAINT_NAME = C.CONSTRAINT_NAME AND B.CONSTRAINT_NAME = D.CONSTRAINT_NAME AND C.POSITION = D.POSITION ORDER BY FK_NAME, D.POSITION"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT A.INDEX_NAME, A.UNIQUENESS, B.COLUMN_NAME FROM ALL_INDEXES A, ALL_IND_COLUMNS B WHERE A.OWNER = 'LCG_COOL' AND A.TABLE_NAME = 'COOLTEST_F0004_IOVS' AND A.GENERATED = 'N' AND A.INDEX_NAME = B.INDEX_NAME AND B.INDEX_OWNER = A.OWNER AND B.TABLE_NAME = A.TABLE_NAME AND A.INDEX_NAME NOT IN (SELECT CONSTRAINT_NAME FROM ALL_CONSTRAINTS WHERE OWNER = A.OWNER AND TABLE_NAME = A.TABLE_NAME AND CONSTRAINT_TYPE = 'P') ORDER BY A.INDEX_NAME, B.COLUMN_POSITION"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "ALTER TABLE "LCG_COOL"."COOLTEST_F0004_IOVS" DROP COLUMN "S""
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "ALTER TABLE "LCG_COOL"."COOLTEST_F0004_IOVS" ADD ( "S" VARCHAR2(4000) )"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "ALTER TABLE "LCG_COOL"."COOLTEST_F0004_IOVS" DROP COLUMN "X""
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "ALTER TABLE "LCG_COOL"."COOLTEST_F0004_IOVS" ADD ( "X" BINARY_FLOAT )"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "CREATE TABLE "LCG_COOL"."COOLTEST_F0004_IOVS_SEQ" ( "SEQUENCE_NAME" VARCHAR2(255), "CURRENT_VALUE" NUMBER(10), "LASTMOD_DATE" VARCHAR2(255) )"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "ALTER TABLE "LCG_COOL"."COOLTEST_F0004_IOVS_SEQ" ADD (CONSTRAINT "COOLTEST_F0004_IOVS_SEQ_PK" PRIMARY KEY ("SEQUENCE_NAME") )"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "INSERT INTO "LCG_COOL"."COOLTEST_F0004_IOVS_SEQ" ("SEQUENCE_NAME") VALUES (:"SEQUENCE_NAME")"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT "CURRENT_VALUE", "LASTMOD_DATE" FROM "LCG_COOL"."COOLTEST_F0004_IOVS_SEQ" FOR UPDATE"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "UPDATE "LCG_COOL"."COOLTEST_F0004_IOVS_SEQ" SET "CURRENT_VALUE"=:"newvalue", "LASTMOD_DATE"=TO_CHAR(SYSTIMESTAMP AT TIME ZONE 'GMT','yyyy-mm-dd_hh24:mi:ss.ff6')||'000 GMT'"
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_INSTIME", "FOLDER_PAYLOADSPEC", "FOLDER_VERSIONING", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME" FROM "LCG_COOL"."COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalFolder                     Debug    Instantiate a RelationalFolder for '/f4'
+RelationalFolder                     Debug    Delete the RelationalFolder for '/f4'
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "DROP TABLE "LCG_COOL"."COOLTEST_TAGS""
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_INSTIME", "FOLDER_PAYLOADSPEC", "FOLDER_VERSIONING", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME" FROM "LCG_COOL"."COOLTEST_NODES" ORDER BY "NODE_FULLPATH" DESC"
+
+unitTest_RelationalCool_RalDatabase (pid=5443 ppid=9055) received fatal signal 2 (Interrupt)
+signal context:
+  signo  = 2, errno = 0, code = 128 (kernel)
+  pid    = 0, uid = 0
+  value  = (6114303, 0x5d4bff)
+  stack  = (2, 0, (nil))
+
+  eip: 0023:00e167f9           eflags: 00200202
+  eax: fffffffc   ebx: 0988d020   ecx: 00000000   edx: 00000002
+  esi: 00000000   edi: 09889a20   ebp: bfff730c   esp: bfff72f4
+   ds: 002b        es: 002b        fs: 0000        ss: 002b
+
+  signal esp: bfff72f4  trap: 0/0  oldmask: 00000000   cr2: 00000000
+
+  FPU:  control = ffff027f
+        status  = ffff0100
+        tag     = ffffffff
+        ip      = 0023:01995604
+        data    = 002b:01db72a4
+        state   = 00000100
+    %fp0 = [0000:0000000000000000]
+    %fp1 = [0000:0000000000000000]
+    %fp2 = [0000:0000000000000000]
+    %fp3 = [0000:0000000000000000]
+    %fp4 = [0000:0000000000000000]
+    %fp5 = [400d:000000000000a182]
+    %fp6 = [4009:0000000000008000]
+    %fp7 = [400b:0000000000008000]
+
+stack trace:
+ 0x003d75ac _ZN4seal9DebugAids10stacktraceEi + 0x60 [/afs/cern.ch/sw/lcg/external/../app/releases/SEAL/SEAL_1_7_0/slc3_ia32_gcc323/lib/liblcg_SealBase.so]
+ 0x00401ede _ZN4seal6Signal9fatalDumpEiP7siginfoPv + 0xde [/afs/cern.ch/sw/lcg/external/../app/releases/SEAL/SEAL_1_7_0/slc3_ia32_gcc323/lib/liblcg_SealBase.so]
+ 0x00401909 _ZN4seal6Signal5fatalEiP7siginfoPv + 0xd5 [/afs/cern.ch/sw/lcg/external/../app/releases/SEAL/SEAL_1_7_0/slc3_ia32_gcc323/lib/liblcg_SealBase.so]
+ 0x00512eb0 ? + 0x512eb0 [/lib/tls/libc.so.6]
+ 0x005d4bbf pthread_mutex_lock + 0x2f [/lib/tls/libc.so.6]
+ 0x01b9c4a6 sltsmna + 0x1e [/afs/cern.ch/sw/lcg/external/oracle/10.1.0.3-1/slc3_ia32_gcc323/lib/libclntsh.so.10.1]
+ 0x013f5cee kpustmtrelease + 0x8ba [/afs/cern.ch/sw/lcg/external/oracle/10.1.0.3-1/slc3_ia32_gcc323/lib/libclntsh.so.10.1]
+ 0x01470a55 OCIStmtRelease + 0xa9 [/afs/cern.ch/sw/lcg/external/oracle/10.1.0.3-1/slc3_ia32_gcc323/lib/libclntsh.so.10.1]
+ 0x0098deff _ZN4pool12OracleAccess15OracleStatement5resetEv + 0x31b [/afs/cern.ch/user/a/avalassi/myLCG/POOL_2_1_1/slc3_ia32_gcc323/lib/liblcg_OracleAccess.so]
+ 0x00983589 _ZN4pool12OracleAccess15OracleStatementD1Ev + 0x1d [/afs/cern.ch/user/a/avalassi/myLCG/POOL_2_1_1/slc3_ia32_gcc323/lib/liblcg_OracleAccess.so]
+ 0x0096ab23 _ZN4pool12OracleAccess18OracleQueryInTable5resetEv + 0x317 [/afs/cern.ch/user/a/avalassi/myLCG/POOL_2_1_1/slc3_ia32_gcc323/lib/liblcg_OracleAccess.so]
+ 0x00966fb5 _ZN4pool12OracleAccess18OracleQueryInTableD0Ev + 0x29 [/afs/cern.ch/user/a/avalassi/myLCG/POOL_2_1_1/slc3_ia32_gcc323/lib/liblcg_OracleAccess.so]
+ 0x00ad9ba0 _ZN4cool11RalDatabase12listAllNodesEb + 0x4b0 [/afs/cern.ch/user/a/avalassi/myLCG/COOL_HEAD/slc3_ia32_gcc323/lib/liblcg_RelationalCool.so]
+ 0x00ad5983 _ZN4cool11RalDatabase12dropAllNodesEv + 0x37 [/afs/cern.ch/user/a/avalassi/myLCG/COOL_HEAD/slc3_ia32_gcc323/lib/liblcg_RelationalCool.so]
+ 0x00aa9548 _ZN4cool11RalDatabase12dropDatabaseEv + 0xf4 [/afs/cern.ch/user/a/avalassi/myLCG/COOL_HEAD/slc3_ia32_gcc323/lib/liblcg_RelationalCool.so]
+ 0x0804ea1a _ZN4cool15RalDatabaseTest17test_dropDatabaseEv + 0x39e [unitTest_RelationalCool_RalDatabase]
+ 0x080506f8 _ZN7CppUnit10TestCallerIN4cool15RalDatabaseTestENS_19NoExceptionExpectedEE7runTestEv + 0x38 [unitTest_RelationalCool_RalDatabase]
+ 0x0091411c _ZN7CppUnit8TestCase3runEPNS_10TestResultE + 0x40 [/afs/cern.ch/sw/lcg/external/CppUnit/1.8.0/slc3_ia32_gcc323/lib/libcppunit-1.8.so.0]
+ 0x0091cf10 _ZN7CppUnit9TestSuite3runEPNS_10TestResultE + 0x38 [/afs/cern.ch/sw/lcg/external/CppUnit/1.8.0/slc3_ia32_gcc323/lib/libcppunit-1.8.so.0]
+ 0x0091cf10 _ZN7CppUnit9TestSuite3runEPNS_10TestResultE + 0x38 [/afs/cern.ch/sw/lcg/external/CppUnit/1.8.0/slc3_ia32_gcc323/lib/libcppunit-1.8.so.0]
+ 0x0091cf10 _ZN7CppUnit9TestSuite3runEPNS_10TestResultE + 0x38 [/afs/cern.ch/sw/lcg/external/CppUnit/1.8.0/slc3_ia32_gcc323/lib/libcppunit-1.8.so.0]
+ 0x0091c643 _ZN7CppUnit6TextUi10TestRunner7runTestEPNS_4TestEb + 0x3f [/afs/cern.ch/sw/lcg/external/CppUnit/1.8.0/slc3_ia32_gcc323/lib/libcppunit-1.8.so.0]
+ 0x0091c33d _ZN7CppUnit6TextUi10TestRunner13runTestByNameESsb + 0x39 [/afs/cern.ch/sw/lcg/external/CppUnit/1.8.0/slc3_ia32_gcc323/lib/libcppunit-1.8.so.0]
+ 0x0091c255 _ZN7CppUnit6TextUi10TestRunner3runESsbbb + 0x49 [/afs/cern.ch/sw/lcg/external/CppUnit/1.8.0/slc3_ia32_gcc323/lib/libcppunit-1.8.so.0]
+ 0x0804b830 main + 0xb0 [unitTest_RelationalCool_RalDatabase]
+ 0x0050078a __libc_start_main + 0xda [/lib/tls/libc.so.6]
+ 0x0804b6f5 _ZN7CppUnit14TypeInfoHelper12getClassNameERKSt9type_info + 0x31 [unitTest_RelationalCool_RalDatabase]
+
+shared libraries present:
+ 0x00000000 /afs/cern.ch/user/a/avalassi/myLCG/COOL_HEAD/slc3_ia32_gcc323/tests/bin/unitTest_RelationalCool_RalDatabase
+ 0x003ae000 /afs/cern.ch/sw/lcg/external/../app/releases/SEAL/SEAL_1_7_0/slc3_ia32_gcc323/lib/liblcg_SealBase.so
+ 0x00c86000 /afs/cern.ch/user/a/avalassi/myLCG/POOL_2_1_1/slc3_ia32_gcc323/lib/liblcg_AttributeList.so
+ 0x0072e000 /afs/cern.ch/user/a/avalassi/myLCG/POOL_2_1_1/slc3_ia32_gcc323/lib/liblcg_POOLCore.so
+ 0x00111000 /afs/cern.ch/sw/lcg/external/../app/releases/SEAL/SEAL_1_7_0/slc3_ia32_gcc323/lib/liblcg_PluginManager.so
+ 0x00172000 /afs/cern.ch/sw/lcg/external/../app/releases/SEAL/SEAL_1_7_0/slc3_ia32_gcc323/lib/liblcg_SealKernel.so
+ 0x00de7000 /afs/cern.ch/user/a/avalassi/myLCG/POOL_2_1_1/slc3_ia32_gcc323/lib/liblcg_RelationalAccess.so
+ 0x00131000 /afs/cern.ch/sw/lcg/external/../app/releases/SEAL/SEAL_1_7_0/slc3_ia32_gcc323/lib/liblcg_SealUtil.so
+ 0x00a6d000 /afs/cern.ch/user/a/avalassi/myLCG/COOL_HEAD/slc3_ia32_gcc323/lib/liblcg_RelationalCool.so
+ 0x0076c000 /afs/cern.ch/user/a/avalassi/myLCG/COOL_HEAD/slc3_ia32_gcc323/lib/liblcg_CoolApplication.so
+ 0x0026d000 /afs/cern.ch/sw/lcg/external/../app/releases/SEAL/SEAL_1_7_0/slc3_ia32_gcc323/lib/liblcg_Reflection.so
+ 0x004b0000 /afs/cern.ch/sw/lcg/external/../app/releases/SEAL/SEAL_1_7_0/slc3_ia32_gcc323/lib/liblcg_SealServices.so
+ 0x00898000 /afs/cern.ch/sw/lcg/external/uuid/1.32/slc3_ia32_gcc323/lib/libuuid.so.1
+ 0x00902000 /afs/cern.ch/sw/lcg/external/CppUnit/1.8.0/slc3_ia32_gcc323/lib/libcppunit-1.8.so.0
+ 0x0069a000 /afs/cern.ch/sw/lcg/external/pcre/4.4/slc3_ia32_gcc323/lib/libpcre.so.0
+ 0x00446000 /lib/libnsl.so.1
+ 0x00e4f000 /lib/libcrypt.so.1
+ 0x0013e000 /lib/libdl.so.2
+ 0x0018c000 /usr/lib/libstdc++.so.5
+ 0x00832000 /lib/tls/libm.so.6
+ 0x00b5a000 /lib/libgcc_s.so.1
+ 0x004eb000 /lib/tls/libc.so.6
+ 0x00e0d000 /lib/tls/libpthread.so.0
+ 0x00bc1000 /lib/ld-linux.so.2
+ 0x00141000 /afs/cern.ch/sw/lcg/external/../app/releases/SEAL/SEAL_1_7_0/slc3_ia32_gcc323/lib/liblcg_MyComponent.so
+ 0x0065a000 /afs/cern.ch/sw/lcg/external/../app/releases/SEAL/SEAL_1_7_0/slc3_ia32_gcc323/lib/liblcg_MyBaseComponent.so
+ 0x00147000 /afs/cern.ch/sw/lcg/external/../app/releases/SEAL/SEAL_1_7_0/slc3_ia32_gcc323/lib/liblcg_MyComponent1.so
+ 0x0014d000 /afs/cern.ch/sw/lcg/external/../app/releases/SEAL/SEAL_1_7_0/slc3_ia32_gcc323/lib/liblcg_ExampleComponents.so
+ 0x00c41000 /afs/cern.ch/sw/lcg/external/../app/releases/SEAL/SEAL_1_7_0/slc3_ia32_gcc323/lib/liblcg_SealStorage.so
+ 0x0023f000 /afs/cern.ch/sw/lcg/external/Boost/1.32.0/slc3_ia32_gcc323/lib/libboost_thread-gcc-mt.so
+ 0x00bf7000 /afs/cern.ch/sw/lcg/external/../app/releases/SEAL/SEAL_1_7_0/slc3_ia32_gcc323/lib/liblcg_SealZip.so
+ 0x00299000 /afs/cern.ch/sw/lcg/external/../app/releases/SEAL/SEAL_1_7_0/slc3_ia32_gcc323/lib/liblcg_SealIOTools.so
+ 0x0015d000 /usr/lib/libz.so.1
+ 0x00f86000 /lib/tls/librt.so.1
+ 0x00b7e000 /afs/cern.ch/sw/lcg/external/../app/releases/SEAL/SEAL_1_7_0/slc3_ia32_gcc323/lib/libCMSExamplesDict.so
+ 0x002bf000 /afs/cern.ch/sw/lcg/external/../app/releases/SEAL/SEAL_1_7_0/slc3_ia32_gcc323/lib/liblcg_ReflectionBuilder.so
+ 0x008cf000 /afs/cern.ch/sw/lcg/external/../app/releases/SEAL/SEAL_1_7_0/slc3_ia32_gcc323/lib/libCMSExamplesRflx.so
+ 0x002cf000 /afs/cern.ch/sw/lcg/external/../app/releases/SEAL/SEAL_1_7_0/slc3_ia32_gcc323/lib/liblcg_Reflex.so
+ 0x0032c000 /afs/cern.ch/sw/lcg/external/../app/releases/SEAL/SEAL_1_7_0/slc3_ia32_gcc323/lib/libSealDictDict.so
+ 0x00772000 /afs/cern.ch/sw/lcg/external/../app/releases/SEAL/SEAL_1_7_0/slc3_ia32_gcc323/lib/libSealDictRflx.so
+ 0x00430000 /afs/cern.ch/user/a/avalassi/myLCG/POOL_2_1_1/slc3_ia32_gcc323/lib/liblcg_AuthenticationService.so
+ 0x00f9a000 /afs/cern.ch/sw/lcg/external/XercesC/2.3.0/slc3_ia32_gcc323/lib/libxerces-c.so.23
+ 0x0092b000 /afs/cern.ch/user/a/avalassi/myLCG/POOL_2_1_1/slc3_ia32_gcc323/lib/liblcg_OracleAccess.so
+ 0x0127f000 /afs/cern.ch/sw/lcg/external/oracle/10.1.0.3-1/slc3_ia32_gcc323/lib/libclntsh.so.10.1
+ 0x079e5000 /afs/cern.ch/sw/lcg/external/oracle/10.1.0.3-1/slc3_ia32_gcc323/lib/libnnz10.so
+ 0x028fa000 /afs/cern.ch/sw/lcg/external/oracle/10.1.0.3-1/slc3_ia32_gcc323/lib/libociei.so
+ 0x003a1000 /lib/libnss_files.so.2
+ 0x0016b000 /lib/libnss_dns.so.2
+ 0x0045b000 /lib/libresolv.so.2
+(Start: Thu Jul 14 10:32:53 CEST 2005)
+(End:   Thu Jul 14 10:35:13 CEST 2005)
diff --git a/RelationalCool/tests/RalDatabase/test_RalDatabase.cpp b/RelationalCool/tests/RalDatabase/test_RalDatabase.cpp
new file mode 100644
index 000000000..f4f2688d6
--- /dev/null
+++ b/RelationalCool/tests/RalDatabase/test_RalDatabase.cpp
@@ -0,0 +1,3496 @@
+/**
+
+ @file test_RalDatabase.cpp
+ 
+ @author Sven A. Schmidt and Andrea Valassi and Marco Clemencic
+ 
+ @date 2004-11-27
+ 
+ */
+
+#include "src/CoralApplication.h"
+#include "src/HvsPathHandlerException.h"
+#include "src/RalDatabase.h"
+#include "src/RalDatabaseSvc.h"
+#include "src/RelationalDatabaseId.h"
+#include "src/RelationalException.h"
+#include "src/RelationalFolder.h"
+#include "src/RelationalFolderUnsupported.h"
+#include "src/RelationalFolderSet.h"
+#include "src/RelationalFolderSetUnsupported.h"
+#include "src/RelationalObject.h"
+#include "src/RelationalObjectTable.h"
+#include "src/RelationalObjectTableRow.h"
+#include "src/RelationalNodeTable.h"
+#include "src/RelationalSequence.h"
+#include "src/RelationalSequenceMgr.h"
+#include "src/RelationalTagMgr.h"
+#include "src/RelationalTransaction.h"
+#include "src/RelationalDatabaseTable.h"
+#include "src/VersionInfo.h"
+#include "src/timeToString.h"
+
+#include "CoolKernel/IField.h"
+#include "CoolKernel/IFolder.h"
+#include "CoolKernel/IObject.h"
+#include "CoolKernel/IObjectIterator.h"
+#include "CoolKernel/IDatabaseSvc.h"
+#include "CoolKernel/ChannelSelection.h"
+#include "CoolKernel/RecordException.h"
+#include "CoolKernel/RecordSpecification.h"
+
+#include "RelationalAccess/IRelationalService.h"
+#include "RelationalAccess/ISchema.h"
+#include "RelationalAccess/ITable.h"
+#include "RelationalAccess/ITableDataEditor.h"
+#include "RelationalAccess/ITransaction.h"
+//#include "RelationalAccess/SessionException.h"
+
+// ---- this things are needed to force a drop of the connection
+//#include "src/RalDatabaseSvc.h"
+#include "RelationalAccess/IConnectionService.h"
+#include "RelationalAccess/IConnectionServiceConfiguration.h"
+
+#include <string>
+using std::cout;
+using std::endl;
+using std::string;
+#include <sstream>
+using std::stringstream;
+#include <vector>
+using std::vector;
+
+#include "CoolDBUnitTest.h"
+
+using coral::AttributeList;
+
+namespace cool {
+
+/// RalDatabase test class.
+
+class RalDatabaseTest : public CoolDBUnitTest {
+		
+  CPPUNIT_TEST_SUITE( RalDatabaseTest );
+
+  // Whenever possible the tests are ordered by increasing complexity,
+  // i.e. dropDatabase depends on dropAllNodes, therefore dropAllNodes
+  // is tested before dropDatabase. In case of failures one can then start
+  // to investigate from top down.
+  // Test execution order is determined by the order in the following
+  // declarations.
+
+  CPPUNIT_TEST( test_createDatabase );
+  CPPUNIT_TEST( test_openDatabase_rw );
+  CPPUNIT_TEST( test_openDatabase_ro );
+
+  CPPUNIT_TEST( test_dbNameLength );
+  CPPUNIT_TEST( test_dbNameUppercase );
+  CPPUNIT_TEST( test_dbNameLettersAndNumbers );
+  CPPUNIT_TEST( test_dbNameStartsWithLetter );
+  // AV 04.04.05 Test no longer relevant: input dbname MUST be uppercase
+  //CPPUNIT_TEST( test_dbName_caseInsensitivity );
+
+  CPPUNIT_TEST( test_listAllNodes );
+  CPPUNIT_TEST( test_listAllTables );
+
+  CPPUNIT_TEST( test_fetchRootNodeTableRow );
+  CPPUNIT_TEST( test_insertNodeTableRow );
+  CPPUNIT_TEST( test_fetchNodeTableRow );
+  CPPUNIT_TEST( test_fetchNodeTableRow_nestedScope );
+
+  CPPUNIT_TEST( test_insertNodeTableRow_nonleaf );
+  CPPUNIT_TEST( test_insertNodeTableRow_leaf );
+  CPPUNIT_TEST( test_dropNode );
+  CPPUNIT_TEST( test_dropAllNodes );
+  CPPUNIT_TEST( test_dropDatabase );
+
+  CPPUNIT_TEST( test_existsFolder );
+  CPPUNIT_TEST( test_existsFolderSet );
+  CPPUNIT_TEST( test_existsNode );
+
+  CPPUNIT_TEST( test_createFolderSet );
+  CPPUNIT_TEST( test_createFolderSet_alreadyExists );
+
+  CPPUNIT_TEST( test_createFolder_SV );
+  CPPUNIT_TEST( test_createFolder_MV );
+
+  CPPUNIT_TEST( test_createFolder_invalidVersioningMode );
+  
+  CPPUNIT_TEST( test_createFolder_withParents );
+  CPPUNIT_TEST( test_createFolder_alreadyExists );
+
+  CPPUNIT_TEST( test_createFolder_invalidName );
+  CPPUNIT_TEST( test_createFolderSet_invalidName );
+  //CPPUNIT_TEST( test_createFolder_invalidName_old );    // no longer relevant
+  //CPPUNIT_TEST( test_createFolderSet_invalidName_old ); // no longer relevant
+  //CPPUNIT_TEST( test_createFolder_twoSimilarNames );    // no longer relevant
+  //CPPUNIT_TEST( test_createFolderSet_twoSimilarNames ); // no longer relevant
+
+  CPPUNIT_TEST( test_getFolder );
+  CPPUNIT_TEST( test_getFolderSet );
+
+  CPPUNIT_TEST( test_folderAttributes_MV );
+  CPPUNIT_TEST( test_folderAttributes_SV );
+
+  CPPUNIT_TEST( test_createFolder_description );
+  CPPUNIT_TEST( test_createFolderSet_description );  
+
+  CPPUNIT_TEST( test_updateRows );
+  CPPUNIT_TEST( test_release_0_1_0 );
+  CPPUNIT_TEST( test_release_3_0_0 );
+  CPPUNIT_TEST( test_allProdReleases );
+
+  CPPUNIT_TEST( test_useFolder_2_0_0 );
+  CPPUNIT_TEST( test_dropFolder_2_0_0 );
+  CPPUNIT_TEST( test_dropDatabaseWithFolder_2_0_0 );
+  CPPUNIT_TEST( test_listAllTablesWithFolder_2_0_0 );
+
+  CPPUNIT_TEST( test_listAllTablesWithNode_1_9_9 );
+
+  CPPUNIT_TEST( test_useNode_2_0_9 );
+  CPPUNIT_TEST( test_dropNode_2_0_9 );
+  CPPUNIT_TEST( test_dropDatabaseWithNode_2_0_9 );
+  CPPUNIT_TEST( test_listAllTablesWithNode_2_0_9 );
+
+  CPPUNIT_TEST( test_useNode_2_9_0 );
+  CPPUNIT_TEST( test_dropNode_2_9_0 );
+  CPPUNIT_TEST( test_dropDatabaseWithNode_2_9_0 );
+  CPPUNIT_TEST( test_listAllTablesWithNode_2_9_0 );
+
+  CPPUNIT_TEST( test_listChannels_SV );
+  CPPUNIT_TEST( test_listChannels_MV );
+
+  //CPPUNIT_TEST( test_listTags_SV ); // moved to RelationalFolder
+  //CPPUNIT_TEST( test_listTags_MV ); // moved to RelationalFolder
+
+  CPPUNIT_TEST( test_tagInsertionTime_SV );
+
+  CPPUNIT_TEST( test_tagInsertionTime_MV );
+
+  CPPUNIT_TEST( test_tagInsertionTime_MV_nonexist );
+  CPPUNIT_TEST( test_tagDescription_SV );
+  CPPUNIT_TEST( test_tagDescription_MV );
+  CPPUNIT_TEST( test_tagDescription_MV_nonexist );
+
+  CPPUNIT_TEST( test_updateNodeTableDescription );
+
+  // Takes long to run -- activate if needed
+  //CPPUNIT_TEST( test_openCursorIssue );
+
+  CPPUNIT_TEST( test_closeDatabase );
+
+  CPPUNIT_TEST( test_closeDatabase_exceptional_folder_behavior );
+  CPPUNIT_TEST( test_closeDatabase_exceptional_folderset_behavior );
+
+  CPPUNIT_TEST( test_closeDatabase_exceptional_database_behavior );
+
+  CPPUNIT_TEST( test_nodeTable_lastModDate );
+
+  CPPUNIT_TEST( test_openDatabase_ro_updateExceptionBug30500 );
+
+#ifdef COOL280
+  CPPUNIT_TEST( test_manualTransaction_commit );
+  CPPUNIT_TEST( test_manualTransaction_rollback );
+  CPPUNIT_TEST( test_manualTransaction_tag_rollback );
+  CPPUNIT_TEST( test_manualTransaction_userTag_rollback );
+  CPPUNIT_TEST( test_manualTransaction_createFolder );
+  CPPUNIT_TEST( test_manualTransaction_createFolderSet );
+#endif
+  
+  CPPUNIT_TEST_SUITE_END();
+		
+public:
+    
+  RalDatabase* ralDb; // safely cast pointer to db
+
+  RecordSpecification payloadSpec;  
+
+  RalDatabaseTest()
+  : payloadSpec() {
+    
+    payloadSpec.extend("I",StorageType::Int32);
+    payloadSpec.extend("S",StorageType::String255);
+    payloadSpec.extend("X",StorageType::Float);
+  }
+  
+  ~RalDatabaseTest() {}
+
+  
+#ifdef COOL280
+  // Tests manual transaction commit
+  void test_manualTransaction_commit() 
+  {
+    setupDb();
+    
+    { // create initial folder
+      IFolderPtr folder = ralDb->createFolder( "/A1", payloadSpec );
+      
+      folder->storeObject(  0, 10, dummyPayload( 010), 0 );
+      folder->storeObject( 10, 25, dummyPayload(1025), 0 );
+      
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "Count 1", 2u,
+                                   folder->countObjects( 0, 100, 0));
+      
+      forceDisconnect();
+    }
+    
+    { // re-open db
+      bool readOnlyFlag = false;
+      openDB(readOnlyFlag);
+      
+      ITransactionPtr t = m_db->startTransaction();
+      
+      IFolderPtr folder = m_db->getFolder("/A1");
+      folder->storeObject( 25, 30, dummyPayload( 010), 0 );
+      folder->storeObject( 30, 40, dummyPayload(1025), 0 );
+      
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "Count 2", 4u,
+                                   folder->countObjects( 0, 100, 0) );
+      
+      t->commit();
+      
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "Count 3", 4u,
+                                   folder->countObjects( 0, 100, 0) );
+      
+      t->rollback();
+      
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "Count 4", 4u,
+                                   folder->countObjects( 0, 100, 0) );
+    }
+  }
+  
+  
+  // Tests manual transaction rollback
+  void test_manualTransaction_rollback() 
+  {
+    setupDb();
+    
+    { // create initial folder
+      IFolderPtr folder = ralDb->createFolder( "/A1", payloadSpec );
+      
+      folder->storeObject(  0, 10, dummyPayload( 010), 0 );
+      folder->storeObject( 10, 25, dummyPayload(1025), 0 );
+      
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "Count 1", 2u,
+                                   folder->countObjects( 0, 100, 0));
+      
+      forceDisconnect();
+    }
+    
+    { // re-open db
+      bool readOnlyFlag = false;
+      openDB(readOnlyFlag);
+      
+      ITransactionPtr t = m_db->startTransaction();
+      
+      IFolderPtr folder = m_db->getFolder("/A1");
+      folder->storeObject( 25, 30, dummyPayload( 010), 0 );
+      folder->storeObject( 30, 40, dummyPayload(1025), 0 );
+      
+      t->rollback();
+      
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "Count 2", 2u,
+                                   folder->countObjects( 0, 100, 0) );
+    }
+  }
+  
+  
+  // Test createFolder behavior in manual transaction mode
+  void test_manualTransaction_createFolder() {
+    setupDb();
+    
+    ITransactionPtr t = ralDb->startTransaction();
+    
+    try {
+      ralDb->createFolder( "/A1", payloadSpec );
+      CPPUNIT_FAIL("createFolder in manual transaction mode must fail");
+    } catch ( RelationalException& e ) {
+      std::string expected = "Cannot create folder in manual transaction mode";
+      CPPUNIT_ASSERT_EQUAL_MESSAGE("exception caught",
+                                   expected, std::string(e.what()));
+    }
+  }
+  
+  
+  // Tests createFolderSet behavior in manual transaction mode
+  void test_manualTransaction_createFolderSet() {
+    setupDb();
+    
+    ITransactionPtr t = ralDb->startTransaction();
+    
+    try {
+      ralDb->createFolderSet( "/A1" );
+      CPPUNIT_FAIL("createFolderSet in manual transaction mode must fail");
+    } catch ( RelationalException& e ) {
+      std::string expected = "Cannot create folder set in manual "
+                             "transaction mode";
+      CPPUNIT_ASSERT_EQUAL_MESSAGE("exception caught",
+                                   expected, std::string(e.what()));
+    }
+  }
+  
+  
+  // Tests tag rollback in manual transaction mode
+  void test_manualTransaction_tag_rollback() 
+  {
+    setupDb();
+    
+    { // create initial folder
+      IFolderPtr folder = ralDb->createFolder("/A1", 
+                                              payloadSpec,
+                                              "",
+                                              FolderVersioning::MULTI_VERSION);
+      folder->storeObject(  0, 10, dummyPayload( 010), 0 );
+      forceDisconnect();
+    }
+    
+    { // re-open db with auto-transactions disabled
+      bool readOnlyFlag = false;
+      openDB(readOnlyFlag);
+      
+      ITransactionPtr t = m_db->startTransaction();
+      
+      IFolderPtr folder = m_db->getFolder("/A1");
+      
+      folder->tagCurrentHead("testTag");
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "tag exists ", 
+                                   true, m_db->existsTag("testTag"));
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "Count", 1u,
+                                   folder->countObjects(0, 100,
+                                                        0, "testTag"));
+      
+      
+      t->rollback();
+      
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "tag rolled back", 
+                                   false, m_db->existsTag("testTag") );
+    }
+  }
+  
+  
+  // Tests user tag rollback in manual transaction mode
+  void test_manualTransaction_userTag_rollback() 
+  {
+    setupDb();
+    
+    { // create initial folder
+      IFolderPtr folder = ralDb->createFolder("/A1", 
+                                              payloadSpec,
+                                              "",
+                                              FolderVersioning::MULTI_VERSION);
+      folder->storeObject(  0, 10, dummyPayload( 010), 0 );
+      forceDisconnect();
+    }
+    
+    { // re-open db with auto-transactions disabled
+      bool readOnlyFlag = false;
+      openDB(readOnlyFlag);
+      
+      ITransactionPtr t = m_db->startTransaction();
+      
+      IFolderPtr folder = m_db->getFolder("/A1");
+      
+      folder->storeObject( 35, 40, dummyPayload(2030), 0, "testTag" );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE("tag exists ", 
+                                   true, m_db->existsTag("testTag"));
+      CPPUNIT_ASSERT_EQUAL_MESSAGE("Count", 1u,
+                                   folder->countObjects(0, 100,
+                                                        0, "testTag"));
+      
+      t->rollback();
+      
+      CPPUNIT_ASSERT_EQUAL_MESSAGE("tag rolled back", 
+                                   false, m_db->existsTag("testTag"));
+    }
+  }
+#endif  
+  
+  /// Tests the exception thrown when updating a readonly database (bug #30500)
+  void test_openDatabase_ro_updateExceptionBug30500() 
+  {
+    CoralApplication app;
+    IDatabaseSvc& dbSvc = app.databaseService();
+    dbSvc.dropDatabase( m_connectionString );
+    IDatabasePtr db = dbSvc.createDatabase( m_connectionString );
+    db->createFolder( "/a", payloadSpec );
+    m_db =  dbSvc.openDatabase( m_connectionString );
+    CPPUNIT_ASSERT( m_db.get() != 0 );
+    CPPUNIT_ASSERT( m_db->isOpen() );
+    try 
+    {
+      m_db->createFolder( "/b", payloadSpec );
+      CPPUNIT_FAIL( "createFolder must fail" );
+    } 
+    catch ( DatabaseOpenInReadOnlyMode& ) {} 
+    //catch ( coral::InvalidOperationInReadOnlyModeException& ) {} 
+    catch ( std::exception& e )
+    {
+      std::cout << "Exception caught: " << e.what() << std::endl;
+      throw;     
+    }
+    try 
+    {
+      Record dummyRec( payloadSpec );
+      IFolderPtr folder = m_db->getFolder( "/a" );
+      folder->storeObject( 0, 10, dummyRec, 0 );
+      CPPUNIT_FAIL( "storeObject must fail" );
+    } 
+    catch ( DatabaseOpenInReadOnlyMode& ) {} 
+    //catch ( coral::InvalidOperationInReadOnlyModeException& ) {} 
+    catch ( std::exception& e ) 
+    {
+      std::cout << "Exception caught: " << e.what() << std::endl;
+      throw;     
+    }
+  }
+  
+
+  /// Tests LASTMOD_DATE updating for description changes
+  void test_nodeTable_lastModDate() {
+    setupDb();
+    ralDb->createFolderSet( "/myfolder", "my desc" );
+
+    {
+      RelationalTransaction transaction( ralDb->transactionMgr() );
+      RelationalTableRow row = ralDb->fetchNodeTableRow( "/myfolder" );
+      CPPUNIT_ASSERT_EQUAL( row["NODE_INSTIME"].data<std::string>(),
+                            row["LASTMOD_DATE"].data<std::string>() );
+      transaction.commit();
+    }
+    
+    // sleep for one second to make sure the update time change is properly
+    // picked up (MySQL has a 1s granularity for example)
+    sleep(1);
+    ralDb->updateNodeTableDescription( "/myfolder", "new desc" );
+    
+    {
+      RelationalTransaction transaction( ralDb->transactionMgr() );
+      RelationalTableRow row = ralDb->fetchNodeTableRow( "/myfolder" );
+      CPPUNIT_ASSERT( row["NODE_INSTIME"].data<std::string>()
+                      != row["LASTMOD_DATE"].data<std::string>() );
+      transaction.commit();
+    }
+  }
+
+  
+  
+  /// Tests exceptional behavior of a closed database.
+  void test_closeDatabase_exceptional_database_behavior() {
+    setupDb();
+    ralDb->closeDatabase();
+    
+    try {
+      ralDb->createFolder( "/b", payloadSpec );
+      CPPUNIT_FAIL( "createFolder must fail" );
+    } catch ( DatabaseNotOpen& ) { }
+    
+    try {
+      ralDb->createFolderSet( "/fs" );
+      CPPUNIT_FAIL( "createFolderSet must fail" );
+    } catch ( DatabaseNotOpen& ) { }
+    
+    try {
+      ralDb->existsFolderSet( "/" );
+      CPPUNIT_FAIL( "existsFolderSet must fail" );
+    } catch ( DatabaseNotOpen& ) { }
+    
+    try {
+      ralDb->getFolderSet( "/" );
+      CPPUNIT_FAIL( "getFolderSet must fail" );
+    } catch ( DatabaseNotOpen& ) { }
+    
+    try {
+      ralDb->createFolder( "/f", payloadSpec );
+      CPPUNIT_FAIL( "createFolder must fail" );
+    } catch ( DatabaseNotOpen& ) { }
+    
+    try {
+      ralDb->existsFolder( "/f" );
+      CPPUNIT_FAIL( "existsFolder must fail" );
+    } catch ( DatabaseNotOpen& ) { }
+    
+    try {
+      ralDb->existsTag( "A" );
+      CPPUNIT_FAIL( "existsTag must fail" );
+    } catch ( DatabaseNotOpen& ) { }
+    
+    try {
+      ralDb->tagNameScope( "A" );
+      CPPUNIT_FAIL( "tagScope must fail" );
+    } catch ( DatabaseNotOpen& ) { }
+    
+    try {
+      ralDb->taggedNodes( "A" );
+      CPPUNIT_FAIL( "taggedNodes must fail" );
+    } catch ( DatabaseNotOpen& ) { }
+
+    try {
+      ralDb->getFolder( "/f" );
+      CPPUNIT_FAIL( "getFolder must fail" );
+    } catch ( DatabaseNotOpen& ) { }
+    
+    try {
+      ralDb->dropNode( "/" );
+      CPPUNIT_FAIL( "dropNode must fail" );
+    } catch ( DatabaseNotOpen& ) { }
+    
+    try {
+      ralDb->listAllNodes();
+      CPPUNIT_FAIL( "listAllNodes must fail" );
+    } catch ( DatabaseNotOpen& ) { }
+
+    try {
+      ralDb->listAllTables();
+      CPPUNIT_FAIL( "listAllTables must fail" );
+    } catch ( DatabaseNotOpen& ) { }
+
+  }
+
+
+  /// Tests exceptional behavior of folderset with a closed database.
+  void test_closeDatabase_exceptional_folderset_behavior() {
+    setupDb();
+    IFolderSetPtr root = ralDb->getFolderSet( "/" );
+    ralDb->closeDatabase();
+    
+    try {
+      root->listFolders();
+      CPPUNIT_FAIL( "listFolders must fail" );
+    } catch ( DatabaseNotOpen& ) { }
+    
+    try {
+      root->listFolderSets();
+      CPPUNIT_FAIL( "listFolderSets must fail" );
+    } catch ( DatabaseNotOpen& ) { }
+  }
+
+
+  /// Tests exceptional behavior of folder methods with a closed database.
+  void test_closeDatabase_exceptional_folder_behavior() {
+    try {
+      setupDb();
+      IFolderPtr folder = ralDb->createFolder
+        ( "/b", payloadSpec, "desc", FolderVersioning::MULTI_VERSION );
+      folder->storeObject( 0, 10, dummyPayload(0), 0 );
+      ralDb->closeDatabase();
+      
+      try {
+        folder->storeObject( 10, 20, dummyPayload(0), 0 );
+        CPPUNIT_FAIL( "storeObject must fail" );
+      } catch ( DatabaseNotOpen& ) { }
+      
+      try {
+        folder->setupStorageBuffer();
+        folder->storeObject( 10, 20, dummyPayload(0), 0 );
+        folder->flushStorageBuffer();
+        CPPUNIT_FAIL( "bulk insertion must fail" );
+      } catch ( DatabaseNotOpen& ) { }      
+
+      try {
+        folder->findObject( 5, 0 );
+        CPPUNIT_FAIL( "findObject must fail" );
+      } catch ( DatabaseNotOpen& ) { }      
+
+      try {
+        folder->browseObjects( ValidityKeyMin, ValidityKeyMax, 0 );
+        CPPUNIT_FAIL( "browseObjects 1 must fail" );
+      } catch ( DatabaseNotOpen& ) { }      
+
+      try {
+        folder->findObjects( 0, ChannelSelection::all() );
+        CPPUNIT_FAIL( "findObjects 2 must fail" );
+      } catch ( DatabaseNotOpen& ) { }      
+
+      try {
+        folder->browseObjects( ValidityKeyMin, 
+                               ValidityKeyMax, 
+                               ChannelSelection::all() );
+        CPPUNIT_FAIL( "browseObjects 3 must fail" );
+      } catch ( DatabaseNotOpen& ) { }
+      
+      /*
+      try {
+        folder->fetchObjects( ValidityKeyMin, ValidityKeyMax );
+        CPPUNIT_FAIL( "fetchObjects 1 must fail" );
+      } catch ( DatabaseNotOpen& ) { }
+      
+      try {
+        folder->fetchObjects( 0, ChannelSelection::all() );
+        CPPUNIT_FAIL( "fetchObjects 2 must fail" );
+      } catch ( DatabaseNotOpen& ) { }
+      
+      try {
+        folder->fetchObjects( ValidityKeyMin, 
+                              ValidityKeyMax, 
+                              ChannelSelection::all() );
+        CPPUNIT_FAIL( "fetchObjects 3 must fail" );
+      } catch ( DatabaseNotOpen& ) { }
+      */
+
+      try {
+        folder->countObjects( ValidityKeyMin, 
+                              ValidityKeyMax, 
+                              ChannelSelection::all() );
+        CPPUNIT_FAIL( "objectCount must fail" );
+      } catch ( DatabaseNotOpen& ) { }
+      
+      try {
+        folder->listChannels();
+        CPPUNIT_FAIL( "listChannels must fail" );
+      } catch ( DatabaseNotOpen& ) { }
+      
+      try {
+        folder->listChannelsWithNames();
+        CPPUNIT_FAIL( "listChannelsWithNames must fail" );
+      } catch ( DatabaseNotOpen& ) { }
+      
+      try {
+        folder->tagCurrentHead( "A" );
+        CPPUNIT_FAIL( "tagCurrentHead must fail" );
+      } catch ( DatabaseNotOpen& ) { }
+      
+      try {
+        folder->tagHeadAsOfDate( Time(), "A" );
+        CPPUNIT_FAIL( "tagHeadAsOfDate must fail" );
+      } catch ( DatabaseNotOpen& ) { }
+      
+      try {
+        folder->insertionTimeOfLastObjectInTag( "A" );
+        CPPUNIT_FAIL( "insertionTimeOfLastObjectInTag must fail" );
+      } catch ( DatabaseNotOpen& ) { }
+      
+      try {
+        folder->deleteTag( "A" );
+        CPPUNIT_FAIL( "deleteTag must fail" );
+      } catch ( DatabaseNotOpen& ) { }
+      
+      try {
+        folder->setDescription( "" );
+        CPPUNIT_FAIL( "setDescription must fail" );
+      } catch ( DatabaseNotOpen& ) { }
+      
+      try {
+        folder->listTags();
+        CPPUNIT_FAIL( "listTags must fail" );
+      } catch ( DatabaseNotOpen& ) { }
+      
+      try {
+        folder->tagInsertionTime( "A" );
+        CPPUNIT_FAIL( "tagInsertionTime must fail" );
+      } catch ( DatabaseNotOpen& ) { }
+      
+      try {
+        folder->tagDescription( "A" );
+        CPPUNIT_FAIL( "tagDescription must fail" );
+      } catch ( DatabaseNotOpen& ) { }
+    } catch ( std::exception& e ) {
+      cout << "Exception caught: " << e.what() << endl;
+      throw;
+    }
+  }
+    
+    
+  /// Tests closeDatabase and reopening.
+  void test_closeDatabase() {
+    setupDb();
+    CPPUNIT_ASSERT_MESSAGE( "before disconnect", ralDb->isOpen() );
+    ralDb->closeDatabase();
+    CPPUNIT_ASSERT_MESSAGE( "after disconnect", ! ralDb->isOpen() );
+    ralDb->openDatabase();
+    CPPUNIT_ASSERT_MESSAGE( "after reconnect", ralDb->isOpen() );
+    // make sure writing works
+    ralDb->createFolder( "/a", payloadSpec );
+  }
+  
+  
+  /// Tests the bug report from David Front about cursors not being closed
+  void test_openCursorIssue() {
+    try {      
+      setupDb();
+      ralDb->setUseTimeout( false );
+      int nFolders = 300;
+      for ( int i = 0; i < nFolders; ++i ) {
+        stringstream s; s << "/f_" << i;
+        cout << "Creating folder '" << s.str() << "'" << endl;
+        ralDb->createFolder( s.str(), payloadSpec );
+      }
+      vector<string> nodes = ralDb->listAllNodes();
+      CPPUNIT_ASSERT_EQUAL( nFolders +1, (int)nodes.size() );      
+      for ( int i = 0; i < nFolders; ++i ) {
+        stringstream s; s << "/f_" << i;
+        cout << "Writing into '" << s.str() << "'" << endl;
+        IFolderPtr f = ralDb->getFolder( s.str() );
+        f->setupStorageBuffer();
+        for ( int j = 0; j < 10; ++j )
+          f->storeObject( j, ValidityKeyMax, dummyPayload( j ), 0 );
+        f->flushStorageBuffer();
+        //sleep(1);
+      }
+    } catch ( std::exception& e ) {
+      std::cout << "Exception caught: " << e.what() << std::endl;
+      throw;     
+    }
+  }
+  
+  
+  /// Tests updateNodeTableDescription
+  void test_updateNodeTableDescription() {
+    setupDb();
+    ralDb->createFolderSet( "/myfolder", "my desc" );
+    ralDb->updateNodeTableDescription( "/myfolder", "new desc" );
+    
+    RelationalTransaction transaction( ralDb->transactionMgr() );
+    RelationalTableRow row = ralDb->fetchNodeTableRow( "/myfolder" );
+    transaction.commit();    
+    CPPUNIT_ASSERT_EQUAL
+      ( string("new desc"), row["NODE_DESCRIPTION"].data<std::string>() );
+  }
+  
+  
+  /// Tests that tagDescription for MV folders for a nonexisting tag
+  /// throws a TagNotFound exception
+  void test_tagDescription_MV_nonexist() {
+    setupDb();
+    IFolderPtr folder = 
+      ralDb->createFolder( "/myfolder", 
+                           payloadSpec,
+                           "my description",
+                           FolderVersioning::MULTI_VERSION );
+    folder->storeObject( 0, ValidityKeyMax, dummyPayload( 0 ), 0 );
+    RelationalFolder* relfolder = 
+      dynamic_cast<RelationalFolder*>( folder.get() );
+    CPPUNIT_ASSERT_THROW( ralDb->tagMgr().tagDescription( relfolder, "A" ),
+                          TagNotFound );
+  }    
+  
+  
+  /// Tests tagDescription for MV folders
+  void test_tagDescription_MV() {
+    setupDb();
+    IFolderPtr folder = 
+      ralDb->createFolder( "/myfolder", 
+                           payloadSpec,
+                           "my description",
+                           FolderVersioning::MULTI_VERSION );
+    folder->storeObject( 0, ValidityKeyMax, dummyPayload( 0 ), 0 );
+    folder->tagCurrentHead( "A", "desc A" );
+    RelationalFolder* relfolder = 
+      dynamic_cast<RelationalFolder*>( folder.get() );
+    std::string desc = ralDb->tagMgr().tagDescription( relfolder, "A" );    
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "tag desc", std::string("desc A"), desc );
+  }    
+  
+  
+  /// Tests that tagDescription for SV folders throws an exception
+  void test_tagDescription_SV() {
+    setupDb();
+    IFolderPtr folder = 
+      ralDb->createFolder( "/myfolder", 
+                           payloadSpec,
+                           "my description",
+                           FolderVersioning::SINGLE_VERSION );
+    RelationalFolder* relfolder = 
+      dynamic_cast<RelationalFolder*>( folder.get() );
+    CPPUNIT_ASSERT_THROW( ralDb->tagMgr().tagDescription( relfolder, "any tag" ),
+                         TagNotFound );
+  }
+  
+  
+  /// Tests that tagInsertionTime for MV folders for a nonexisting tag
+  /// throws a TagNotFound exception
+  void test_tagInsertionTime_MV_nonexist() {
+    setupDb();
+    IFolderPtr folder = 
+      ralDb->createFolder( "/myfolder", 
+                           payloadSpec,
+                           "my description",
+                           FolderVersioning::MULTI_VERSION );
+    folder->storeObject( 0, ValidityKeyMax, dummyPayload( 0 ), 0 );
+    RelationalFolder* relfolder = 
+      dynamic_cast<RelationalFolder*>( folder.get() );
+    CPPUNIT_ASSERT_THROW( ralDb->tagMgr().tagInsertionTime( relfolder, "A" ),
+                         TagNotFound );
+  }    
+  
+  
+  /// Tests tagInsertionTime for MV folders
+  void test_tagInsertionTime_MV() {
+    try {
+      setupDb();
+      IFolderPtr folder = 
+        ralDb->createFolder( "/myfolder", 
+                             payloadSpec,
+                             "my description",
+                             FolderVersioning::MULTI_VERSION );
+      folder->storeObject( 0, ValidityKeyMax, dummyPayload( 0 ), 0 );
+      
+      // Create a temporary sequence to get the server SYSDATE before insertion
+      Time before;
+      std::string tmpSeqName = string( m_coolDBName + "_TMP_CLOCK" );
+      {
+        RelationalTransaction transaction( ralDb->transactionMgr() );    
+        if ( ralDb->queryMgr().sequenceMgr().existsSequence( tmpSeqName ) )
+          ralDb->queryMgr().sequenceMgr().dropSequence( tmpSeqName );
+        boost::shared_ptr<RelationalSequence> tmpSeq = 
+          ralDb->queryMgr().sequenceMgr().createSequence( tmpSeqName );
+        tmpSeq->nextVal();    
+        before = stringToTime( tmpSeq->currDate() );
+        transaction.commit();
+      }    
+      
+      // MySQL now() has 1 second granularity: need to sleep at least 1 second
+      // (if test checks for strict < or >; not needed if checks for <= or >=)
+      sleep(1);
+      
+      // Tag the folder
+      folder->tagCurrentHead( "A" );
+      
+      // MySQL now() has 1 second granularity: need to sleep at least 1 second
+      // (if test checks for strict < or >; not needed if checks for <= or >=)
+      sleep(1);
+      
+      // Get the server SYSDATE after insertion
+      Time after;
+      {
+        RelationalTransaction transaction( ralDb->transactionMgr() );    
+        boost::shared_ptr<RelationalSequence> tmpSeq = 
+          ralDb->queryMgr().sequenceMgr().getSequence( tmpSeqName );
+        tmpSeq->nextVal();    
+        after = stringToTime( tmpSeq->currDate() );
+        transaction.commit();
+      }
+      
+      // Cleanup - drop the temporary sequence
+      {
+        RelationalTransaction transaction( ralDb->transactionMgr() );
+        ralDb->queryMgr().sequenceMgr().dropSequence( tmpSeqName );
+        transaction.commit();
+      }
+      RelationalFolder* relfolder = 
+        dynamic_cast<RelationalFolder*>( folder.get() );
+      //std::cout << "*** Windows will throw UNKNOWN exception?" << std::endl;
+      Time tagTime = 
+        ralDb->tagMgr().tagInsertionTime( relfolder, "A" );    
+      //std::cout << "*** Windows has thrown UNKNOWN exception?" << std::endl;
+      CPPUNIT_ASSERT_MESSAGE( "before < tagTime", before < tagTime );
+      CPPUNIT_ASSERT_MESSAGE( "tagTime < after", tagTime < after );
+    } catch ( std::exception& e ) {
+      std::cout << "Exception caught: " << e.what() << std::endl;
+      throw;     
+    } catch ( ... ) {
+      std::cout << "UNKNOWN Exception caught!" << std::endl;
+      throw;     
+    }    
+  }
+
+  
+  /// Tests that tagInsertionTime for SV folders throws an exception
+  void test_tagInsertionTime_SV() {
+    setupDb();
+    IFolderPtr folder = 
+      ralDb->createFolder( "/myfolder", 
+                           payloadSpec,
+                           "my description",
+                           FolderVersioning::SINGLE_VERSION );
+    RelationalFolder* relfolder = 
+      dynamic_cast<RelationalFolder*>( folder.get() );
+    CPPUNIT_ASSERT_THROW(ralDb->tagMgr()
+                         .tagInsertionTime( relfolder, "any tag" ),
+                         TagNotFound);                     
+  }
+  
+  
+  /// Tests listChannels for MV folders
+  void test_listChannels_MV() {
+    setupDb();
+    IFolderPtr folder = 
+      ralDb->createFolder( "/myfolder", 
+                           payloadSpec,
+                           "my description",
+                           FolderVersioning::MULTI_VERSION );
+    ChannelId channel = 1;
+    folder->storeObject( 0, ValidityKeyMax, dummyPayload( 0 ), channel );
+    channel = 3;
+    folder->storeObject( 0, ValidityKeyMax, dummyPayload( 0 ), channel );
+    channel = 5;
+    folder->storeObject( 0, ValidityKeyMax, dummyPayload( 0 ), channel );
+    
+    std::vector<ChannelId> channels = folder->listChannels();
+    CPPUNIT_ASSERT_EQUAL_MESSAGE
+      ( "channel count", 3u, (unsigned int)channels.size() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "channel 1", (ChannelId)1, channels[0] );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "channel 2", (ChannelId)3, channels[1] );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "channel 3", (ChannelId)5, channels[2] );
+  }
+  
+  
+  /// Tests listChannels for SV folders
+  void test_listChannels_SV() {
+    setupDb();
+    IFolderPtr folder = 
+      ralDb->createFolder( "/myfolder", 
+                           payloadSpec,
+                           "my description",
+                           FolderVersioning::SINGLE_VERSION );
+    ChannelId channel = 1;
+    folder->storeObject( 0, ValidityKeyMax, dummyPayload( 0 ), channel );
+    channel = 3;
+    folder->storeObject( 0, ValidityKeyMax, dummyPayload( 0 ), channel );
+    channel = 5;
+    folder->storeObject( 0, ValidityKeyMax, dummyPayload( 0 ), channel );
+
+    std::vector<ChannelId> channels = folder->listChannels();
+    CPPUNIT_ASSERT_EQUAL_MESSAGE
+      ( "channel count", 3u, (unsigned int)channels.size() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "channel 1", (ChannelId)1, channels[0] );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "channel 2", (ChannelId)3, channels[1] );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "channel 3", (ChannelId)5, channels[2] );
+  }
+  
+  
+  /// Updates the release number in the RELEASE column of the main table
+  void updateRelease( const std::string& releaseNumber )
+  {
+    RalSessionMgr ralSessMgr( ppConnectionSvc(), m_connectionString, false );
+    ralSessMgr.session().transaction().start();
+    coral::ISchema& schema = ralSessMgr.session().nominalSchema();
+    std::string mainTable = RelationalDatabaseTable::tableName( m_coolDBName );
+    coral::ITable& table = schema.tableHandle( mainTable );
+    coral::AttributeList updateData;
+    updateData.extend( "newRelease", "string" );
+    updateData.extend( "releaseColumn", "string" );
+    updateData["newRelease"].setValue( releaseNumber );
+    updateData["releaseColumn"].setValue( string("RELEASE") );
+    std::string setClause = "DB_ATTRIBUTE_VALUE = :newRelease";
+    std::string whereClause = "DB_ATTRIBUTE_NAME = :releaseColumn";
+    int updatedRows = 
+      table.dataEditor().updateRows( setClause, whereClause, updateData );    
+    ralSessMgr.session().transaction().commit();
+    CPPUNIT_ASSERT_EQUAL_MESSAGE
+      ( std::string( "release update row count (new release: " )
+        + releaseNumber + ")", 1, updatedRows );
+    ralSessMgr.disconnect();
+    //forceDisconnect(); // NO! This will make ralDb unusable (segfault...)!
+  }
+  
+
+  /// Updates the schema version in the SCHEMA_VERSION column of the main table
+  void updateSchemaVersion( const std::string& schemaVersion )
+  {
+    RalSessionMgr ralSessMgr( ppConnectionSvc(), m_connectionString, false );  
+    ralSessMgr.session().transaction().start();
+    coral::ISchema& schema = ralSessMgr.session().nominalSchema();
+    std::string mainTable = RelationalDatabaseTable::tableName( m_coolDBName );
+    coral::ITable& table = schema.tableHandle( mainTable );
+    coral::AttributeList updateData;
+    updateData.extend( "newSchemaVersion", "string" );
+    updateData.extend( "schemaVersionColumn", "string" );
+    updateData["newSchemaVersion"].setValue( schemaVersion );
+    updateData["schemaVersionColumn"].setValue( string("SCHEMA_VERSION") );
+    std::string setClause = "DB_ATTRIBUTE_VALUE = :newSchemaVersion";
+    std::string whereClause = "DB_ATTRIBUTE_NAME = :schemaVersionColumn";
+    int updatedRows = 
+      table.dataEditor().updateRows
+      ( setClause, whereClause, updateData );
+    ralSessMgr.session().transaction().commit();
+    CPPUNIT_ASSERT_EQUAL_MESSAGE
+      ( std::string( "schema version update row count (new schema: " )
+        + schemaVersion + ")", 1, updatedRows );
+    ralSessMgr.disconnect();
+    //forceDisconnect(); // NO! This will make ralDb unusable (segfault...)!
+  }
+  
+
+  /// Updates the SCHEMA_VERSION column of the node table for the given node
+  void updateNodeSchemaVersion( const std::string& fullPath,
+                                const std::string& schemaVersion )
+  {
+    RalSessionMgr ralSessMgr( ppConnectionSvc(), m_connectionString, false );
+    ralSessMgr.session().transaction().start();
+    coral::ISchema& schema = ralSessMgr.session().nominalSchema();
+    coral::ITable& table = schema.tableHandle( ralDb->nodeTableName() );
+    coral::AttributeList updateData;
+    updateData.extend( "newSchemaVersion", "string" );
+    updateData.extend( "fullPath", "string" );
+    updateData["newSchemaVersion"].setValue( schemaVersion );
+    updateData["fullPath"].setValue( fullPath );
+    std::string setClause = RelationalNodeTable::columnNames::nodeSchemaVersion
+      + " = :newSchemaVersion";
+    std::string whereClause = RelationalNodeTable::columnNames::nodeFullPath
+      + " = :fullPath";
+    int updatedRows = table.dataEditor().updateRows
+      ( setClause, whereClause, updateData );
+    ralSessMgr.session().transaction().commit();
+    CPPUNIT_ASSERT_EQUAL_MESSAGE
+      ( std::string( "node schema version update row count (new schema: " )
+        + schemaVersion + ")", 1, updatedRows );
+    ralSessMgr.disconnect();
+    //forceDisconnect(); // NO! This will make ralDb unusable (segfault...)!
+  }
+  
+
+  /// Function to test a release version that should _NOT_ be opened.
+  void checkReleaseFAIL_NoSchemaEvolution(const std::string& rel) {
+
+    createDB();
+    updateRelease( rel );
+    try {
+
+      openDB();
+
+      forceDisconnect();
+      updateRelease( VersionInfo::release );
+
+      CPPUNIT_ASSERT_MESSAGE( "exception expected for "+rel, false );
+
+    } catch ( RelationalException& e ) {
+
+      forceDisconnect();
+      updateRelease( VersionInfo::release );
+
+      std::string expected = "IncompatibleReleaseNumber exception. "
+        "Release number mismatch - SCHEMA EVOLUTION NOT POSSIBLE: "
+        "database with OLDER release number " + rel +
+        " (older than 1.2.0)"
+        " cannot be opened using CURRENT client release number "
+        + std::string(VersionInfo::release);
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "exception caught",
+                                    expected, string( e.what() ) );
+
+    } catch ( ... ) {
+
+      forceDisconnect();
+      updateRelease( VersionInfo::release );
+
+      throw;
+    }
+  }
+
+  /// Function to test a release version that should _NOT_ be opened.
+  void checkReleaseFAIL_SchemaEvolution(const std::string& rel) {
+
+    createDB();
+    updateRelease( rel );
+    try {
+
+      openDB();
+
+      forceDisconnect();
+      updateRelease( VersionInfo::release );
+
+      CPPUNIT_ASSERT_MESSAGE( "exception expected for "+rel, false );
+
+    } catch ( RelationalException& e ) {
+
+      forceDisconnect();
+      updateRelease( VersionInfo::release );
+
+      std::string expected = "IncompatibleReleaseNumber exception. "
+        "Release number mismatch - SCHEMA EVOLUTION REQUIRED: "
+        "database with OLDER release number " + rel +
+        " cannot be opened using CURRENT client release number "
+        + std::string(VersionInfo::release);
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "exception caught",
+                                    expected, string( e.what() ) );
+
+    } catch ( ... ) {
+
+      forceDisconnect();
+      updateRelease( VersionInfo::release );
+
+      throw;
+    }
+  }
+
+  /// Function to test a release version that should be opened.
+  void checkReleaseOK(const std::string& rel) {
+    
+    createDB();
+    updateRelease( rel );
+    try {
+
+      openDB();
+      CPPUNIT_ASSERT( m_db.get() != 0 );
+      CPPUNIT_ASSERT( m_db->isOpen() );
+
+    } catch ( RelationalException& ) {
+
+      forceDisconnect();
+      updateRelease( VersionInfo::release );
+
+      CPPUNIT_ASSERT_MESSAGE( "could not open version "+rel, false );
+
+    } catch ( ... ) {
+
+      forceDisconnect();
+      updateRelease( VersionInfo::release );
+
+      throw;
+    }
+
+    forceDisconnect();
+    updateRelease( VersionInfo::release );
+  }
+  
+  /// Cross-check the present release against all production releases
+  /// REMEMBER TO UPDATE THIS AT EVERY RELEASE! This includes a check against
+  /// the current release (which will become a former release when the next
+  /// one is out, and will fail the test if you forget to update it!)
+  void test_allProdReleases() 
+  {
+
+    std::vector<std::string> not_openable_no_schema_evolution;
+    not_openable_no_schema_evolution.push_back( "1.0.0" );
+    not_openable_no_schema_evolution.push_back( "1.0.1" );
+    not_openable_no_schema_evolution.push_back( "1.0.2" );
+    not_openable_no_schema_evolution.push_back( "1.1.0" );    
+
+    std::vector<std::string> not_openable_schema_evolution;
+    not_openable_schema_evolution.push_back( "1.2.0" );
+    not_openable_schema_evolution.push_back( "1.2.1" );
+    not_openable_schema_evolution.push_back( "1.2.2" );
+    not_openable_schema_evolution.push_back( "1.2.3" );
+    not_openable_schema_evolution.push_back( "1.2.4" );
+    not_openable_schema_evolution.push_back( "1.2.5" );
+    not_openable_schema_evolution.push_back( "1.2.6" );
+    not_openable_schema_evolution.push_back( "1.2.7" );
+    not_openable_schema_evolution.push_back( "1.2.8" );
+    not_openable_schema_evolution.push_back( "1.2.9" );
+    not_openable_schema_evolution.push_back( "1.3.0" );
+    not_openable_schema_evolution.push_back( "1.3.1" );
+    not_openable_schema_evolution.push_back( "1.3.2" );
+    not_openable_schema_evolution.push_back( "1.3.3" );
+    not_openable_schema_evolution.push_back( "1.3.4" );
+
+    std::vector<std::string> openable; // current can (needs not) be included
+    openable.push_back( "2.0.0" );
+    openable.push_back( "2.1.0" );
+    openable.push_back( "2.1.1" );
+    openable.push_back( "2.2.0" );
+    openable.push_back( "2.2.1" );
+    openable.push_back( "2.2.2" );
+    openable.push_back( "2.3.0" );
+    openable.push_back( "2.3.1" );
+    openable.push_back( "2.4.0" );
+    openable.push_back( "2.5.0" );
+    openable.push_back( "2.6.0" );
+    openable.push_back( "2.7.0" );
+
+    // Check for failure - too old even for schema evolution
+    std::vector<std::string> ::iterator rel;
+    for ( rel = not_openable_no_schema_evolution.begin(); 
+          rel != not_openable_no_schema_evolution.end(); 
+          ++rel )
+    {
+      checkReleaseFAIL_NoSchemaEvolution( *rel );
+    }
+
+    // Check for failure - need schema evolution
+    for ( rel = not_openable_schema_evolution.begin(); 
+          rel != not_openable_schema_evolution.end(); 
+          ++rel )
+    {
+      checkReleaseFAIL_SchemaEvolution( *rel );
+    }
+
+    // Check for success - forward compatible
+    for( rel = openable.begin(); rel != openable.end(); ++rel ){
+      checkReleaseOK( *rel );
+    }
+    
+    // Current Version - can be opened
+    createDB();
+    try {
+      openDB();
+      CPPUNIT_ASSERT( m_db.get() != 0 );
+      CPPUNIT_ASSERT( m_db->isOpen() );
+    } catch ( ... ) {
+      forceDisconnect();
+      throw;
+    }
+    forceDisconnect();
+
+  }
+
+
+  /// This is actually a test of the CORAL updateRows method (sr #101074)
+  void test_updateRows() {
+    createDB();
+    // The following three calls update rows without changing any column 
+    // values: all three calls fail on MySQL if sr #101074 is not fixed,
+    // because the return value of updateRows is 0 instead of 1
+    updateRelease( VersionInfo::release );
+    updateSchemaVersion( VersionInfo::schemaVersion );
+    openDB(false);
+    ralDb = dynamic_cast<RalDatabase*>(m_db.get());
+    updateNodeSchemaVersion( "/", VersionInfo::schemaVersion );
+  }
+  
+
+  /// Tests that an exception is thrown when the current API is used to
+  /// access a release 0.1.0 database (the object_id ordering change was
+  /// data incompatible -- 1.0.0 and later cannot reliably read 0.1.0 data)
+  void test_release_0_1_0() {
+    checkReleaseFAIL_NoSchemaEvolution("0.1.0");
+  }
+
+
+  /// Tests what happens when the current API is used 
+  /// to access a newer release 3.0.0 database
+  void test_release_3_0_0() 
+  {
+    std::string newRel("3.0.0");
+    std::string newSch("3.0.0");
+    std::string oldSch("1.0.0");
+    createDB();
+    updateRelease( newRel );
+    try {
+      
+      // 1. Newer release, same schema - it can be opened
+      openDB();
+
+      // 2. Newer release, newer schema - it cannot be opened
+      try {
+        updateSchemaVersion( newSch );
+        openDB();
+        CPPUNIT_FAIL( "Exception expected for newer schema " + newSch );
+      }
+      catch ( IncompatibleReleaseNumber& e ) {
+        std::stringstream s;
+        s << "IncompatibleReleaseNumber exception. "
+          << "Release number and schema version mismatch"
+          << " - SCHEMA NOT BACKWARD COMPATIBLE: "
+          << "database with NEWER release number " << newRel
+          << " and NEWER schema version " << newSch
+          << " cannot be opened using CURRENT client release number "
+          << VersionInfo::release
+          << " (CURRENT schema version " << VersionInfo::schemaVersion << ")";
+        CPPUNIT_ASSERT_EQUAL_MESSAGE
+          ( "exception caught", s.str(), std::string( e.what() ) );
+      }
+                                   
+      // 3. Newer release, older schema - panic!
+      try {
+        updateSchemaVersion( oldSch );
+        openDB();
+        CPPUNIT_FAIL( "Exception expected for older schema " + newSch );
+      }
+      catch ( IncompatibleReleaseNumber& e ) {
+        std::stringstream s;
+        s << "IncompatibleReleaseNumber exception. "
+          << "PANIC! Release number and schema version mismatch: "
+          << "database with NEWER release number " << newRel
+          << " than CURRENT client release number " << VersionInfo::release
+          << " has OLDER schema version " << oldSch
+          << " (CURRENT schema version " << VersionInfo::schemaVersion << ")";
+        CPPUNIT_ASSERT_EQUAL_MESSAGE
+          ( "exception caught", s.str(), std::string( e.what() ) );
+      }
+
+      forceDisconnect();
+      updateRelease( VersionInfo::release );
+      updateSchemaVersion( VersionInfo::schemaVersion );
+                                   
+    } catch ( ... ) {
+      forceDisconnect();
+      updateRelease( VersionInfo::release );
+      updateSchemaVersion( VersionInfo::schemaVersion );
+      throw;
+    }
+
+  }
+  
+
+  /// Tests what happens when the current API is used 
+  /// to access a folder with obsolete schema version 2.0.0
+  void test_useFolder_2_0_0() 
+  {
+    setupDb();
+    ralDb->createFolderSet( "/my" );
+    ralDb->createFolder
+      ( "/my/folder", payloadSpec, "", FolderVersioning::MULTI_VERSION );
+    std::string newSch("2.0.0");
+    std::string oldFoldSch( RelationalFolder::folderSchemaVersion() );
+
+    /// 1. Test folder using its original schema version
+    IFolderPtr folder;
+    folder = ralDb->getFolder( "/my/folder" );
+    CPPUNIT_ASSERT( folder.get() != 0 );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE
+      ( "1. folder name", std::string( "/my/folder" ), folder->fullPath() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE
+      ( "1. folder schema", oldFoldSch, folder->folderAttributes()
+        ["NODE_SCHEMA_VERSION"].data<std::string>() );
+    folder->folderSpecification(); // Should not throw
+
+    /// 2. Test folder using an obsolete schema version
+    updateNodeSchemaVersion( "/my/folder", newSch );
+    folder = ralDb->getFolder( "/my/folder" );
+    CPPUNIT_ASSERT( folder.get() != 0 );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE
+      ( "2. folder name", std::string( "/my/folder" ), folder->fullPath() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE
+      ( "2. folder schema", newSch, folder->folderAttributes()
+        ["NODE_SCHEMA_VERSION"].data<std::string>() );
+    try {
+      CPPUNIT_ASSERT_THROW
+        ( folder->folderSpecification(), UnsupportedFolderSchema );
+      CPPUNIT_ASSERT_THROW
+        ( folder->payloadSpecification(), UnsupportedFolderSchema );
+      CPPUNIT_ASSERT_THROW
+        ( folder->versioningMode(), UnsupportedFolderSchema );
+      CPPUNIT_ASSERT_THROW
+        ( folder->setupStorageBuffer(), UnsupportedFolderSchema );
+      Record dummyRec( payloadSpec );
+      CPPUNIT_ASSERT_THROW
+        ( folder->storeObject( 0, 10, dummyRec, 0 ), UnsupportedFolderSchema );
+      CPPUNIT_ASSERT_THROW
+        ( folder->flushStorageBuffer(), UnsupportedFolderSchema );
+      CPPUNIT_ASSERT_THROW
+        ( folder->findObject( 0, 0 ), UnsupportedFolderSchema );
+      ChannelSelection dummyChSel( 0 );
+      CPPUNIT_ASSERT_THROW
+        ( folder->findObjects( 0, dummyChSel ), UnsupportedFolderSchema );
+      CPPUNIT_ASSERT_THROW
+        ( folder->setPrefetchAll( true ), UnsupportedFolderSchema );
+      CPPUNIT_ASSERT_THROW
+        ( folder->browseObjects( 0, 10, dummyChSel ), 
+          UnsupportedFolderSchema );
+      CPPUNIT_ASSERT_THROW
+        ( folder->countObjects( 0, 10, dummyChSel ), UnsupportedFolderSchema );
+      CPPUNIT_ASSERT_THROW
+        ( folder->renamePayload( "I", "J" ), UnsupportedFolderSchema );
+      RecordSpecification extSpec;
+      extSpec.extend("I",StorageType::Int32);
+      Record extRec( extSpec );
+      CPPUNIT_ASSERT_THROW
+        ( folder->extendPayloadSpecification( extRec ), UnsupportedFolderSchema );
+      CPPUNIT_ASSERT_THROW
+        ( folder->tagCurrentHead( "a" ), UnsupportedFolderSchema );
+      Time now;
+      CPPUNIT_ASSERT_THROW
+        ( folder->insertionTimeOfLastObjectInTag("a"), 
+          UnsupportedFolderSchema );
+      CPPUNIT_ASSERT_THROW
+        ( folder->deleteTag( "a" ), UnsupportedFolderSchema );
+      CPPUNIT_ASSERT_THROW
+        ( folder->tagHeadAsOfDate( now, "a" ), UnsupportedFolderSchema );
+      CPPUNIT_ASSERT_THROW
+        ( folder->existsUserTag( "a" ), UnsupportedFolderSchema );
+      CPPUNIT_ASSERT_THROW
+        ( folder->listChannels(), UnsupportedFolderSchema );
+      CPPUNIT_ASSERT_THROW
+        ( folder->listChannelsWithNames(), UnsupportedFolderSchema );
+      CPPUNIT_ASSERT_THROW
+        ( folder->createChannel( 1, "b" ), UnsupportedFolderSchema );
+      CPPUNIT_ASSERT_THROW
+        ( folder->setChannelName( 1, "a" ), UnsupportedFolderSchema );
+      CPPUNIT_ASSERT_THROW
+        ( folder->channelName( 1 ), UnsupportedFolderSchema );
+      CPPUNIT_ASSERT_THROW
+        ( folder->channelId( "a" ), UnsupportedFolderSchema );
+      CPPUNIT_ASSERT_THROW
+        ( folder->existsChannel( 0 ), UnsupportedFolderSchema );
+      CPPUNIT_ASSERT_THROW
+        ( folder->existsChannel( "a" ), UnsupportedFolderSchema );
+      CPPUNIT_ASSERT_THROW
+        ( folder->setChannelDescription( 1, "a" ), UnsupportedFolderSchema );
+      CPPUNIT_ASSERT_THROW
+        ( folder->channelDescription( 1 ), UnsupportedFolderSchema );
+    } catch (...) {
+      updateNodeSchemaVersion( "/my/folder", oldFoldSch );
+      throw;
+    }    
+
+    /// 3. Test folder using its original schema version again
+    updateNodeSchemaVersion( "/my/folder", oldFoldSch );
+    folder = ralDb->getFolder( "/my/folder" );
+    CPPUNIT_ASSERT( folder.get() != 0 );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE
+      ( "3. folder name", std::string( "/my/folder" ), folder->fullPath() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE
+      ( "3. folder schema", oldFoldSch, folder->folderAttributes()
+        ["NODE_SCHEMA_VERSION"].data<std::string>() );
+    folder->folderSpecification(); // Should not throw
+
+  }
+  
+
+  /// Tests what happens when the current API is used 
+  /// to drop a folder with obsolete schema version 2.0.0
+  void test_dropFolder_2_0_0() 
+  {
+    setupDb();
+    ralDb->createFolderSet( "/my" );
+    ralDb->createFolder( "/my/folder", payloadSpec );
+    std::string newSch("2.0.0");
+    std::string oldFoldSch( RelationalFolder::folderSchemaVersion() );
+    updateNodeSchemaVersion( "/my/folder", newSch );
+    try {
+      CPPUNIT_ASSERT_THROW
+        ( ralDb->dropNode( "/my/folder" ), Exception );
+    } catch (...) {
+      updateNodeSchemaVersion( "/my/folder", oldFoldSch );
+      throw;
+    }    
+    updateNodeSchemaVersion( "/my/folder", oldFoldSch );
+  }
+
+  
+  /// Tests listAllTables if there is an obsolete folder version 2.0.0
+  void test_listAllTablesWithFolder_2_0_0() 
+  {
+    // Create folders
+    setupDb();
+    ralDb->createFolderSet( "/f1" );
+    ralDb->createFolder( "/f1/folderA", payloadSpec );
+    ralDb->createFolder( "/f1/folderB", payloadSpec );
+    // Prepare list of expected tables
+    std::vector<std::string> suffixes;
+    suffixes.push_back( "_DB_ATTRIBUTES" );
+    suffixes.push_back( "_F0000_TAGS_SEQ" );
+    suffixes.push_back( "_F0001_TAGS_SEQ" );
+    suffixes.push_back( "_F0002_CHANNELS" );
+    suffixes.push_back( "_F0002_IOVS" );
+    suffixes.push_back( "_F0002_IOVS_SEQ" );
+    suffixes.push_back( "_F0003_CHANNELS" );
+    suffixes.push_back( "_F0003_IOVS" );
+    suffixes.push_back( "_F0003_IOVS_SEQ" );
+    suffixes.push_back( "_NODES" );
+    suffixes.push_back( "_NODES_SEQ" );
+    suffixes.push_back( "_TAG2TAG" );
+    suffixes.push_back( "_TAG2TAG_SEQ" );
+    suffixes.push_back( "_TAGS" );
+    // Change a folder schema to 2.0.0
+    std::string newSch("2.0.0");
+    std::string oldFoldSch( RelationalFolder::folderSchemaVersion() );
+    updateNodeSchemaVersion( "/f1/folderA", newSch );
+    try {
+      std::vector<string> tables = ralDb->listAllTables();
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "tables count", (size_t)14, tables.size() );
+      std::vector<std::string>::const_iterator suffix;
+      for ( suffix = suffixes.begin(); suffix != suffixes.end(); suffix++ ) 
+      {
+        std::string table;
+        table = m_coolDBName + *suffix;
+        CPPUNIT_ASSERT_MESSAGE
+          ( table, 
+            find( tables.begin(), tables.end(), table ) != tables.end() );
+      }
+    } catch (...) {      
+      updateNodeSchemaVersion( "/f1/folderA", oldFoldSch );
+      throw;
+    }    
+    updateNodeSchemaVersion( "/f1/folderA", oldFoldSch );
+  }
+  
+  
+  /// Tests listAllTables if there are obsolete node versions 1.9.9
+  void test_listAllTablesWithNode_1_9_9() 
+  {
+    // Create folders
+    setupDb();
+    ralDb->createFolderSet( "/f1" );
+    ralDb->createFolder( "/f1/folderA", payloadSpec );
+    ralDb->createFolder( "/f1/folderB", payloadSpec );
+    // Change a folder set schema to 1.9.9
+    {
+      std::string newSch("1.9.9");
+      std::string oldFsetSch( RelationalFolderSet::folderSetSchemaVersion() );
+      updateNodeSchemaVersion( "/f1", newSch );
+      try {
+        CPPUNIT_ASSERT_THROW
+          ( ralDb->listAllTables(), PanicException );
+      } catch (...) {      
+        updateNodeSchemaVersion( "/f1", oldFsetSch );
+        throw;
+      }    
+      updateNodeSchemaVersion( "/f1", oldFsetSch );
+    }    
+    // Change a folder schema to 1.9.9
+    {
+      std::string newSch("1.9.9");
+      std::string oldFoldSch( RelationalFolder::folderSchemaVersion() );
+      updateNodeSchemaVersion( "/f1/folderA", newSch );
+      try {
+        CPPUNIT_ASSERT_THROW
+          ( ralDb->listAllTables(), PanicException );
+      } catch (...) {      
+        updateNodeSchemaVersion( "/f1/folderA", oldFoldSch );
+        throw;
+      }    
+      updateNodeSchemaVersion( "/f1/folderA", oldFoldSch );
+    }
+  }
+  
+  
+  /// Tests listAllTables if there are new node versions 2.0.9
+  void test_listAllTablesWithNode_2_0_9() 
+  {
+    // Create folders
+    setupDb();
+    ralDb->createFolderSet( "/f1" );
+    ralDb->createFolder( "/f1/folderA", payloadSpec );
+    ralDb->createFolder( "/f1/folderB", payloadSpec );
+    // Prepare list of expected tables
+    std::vector<std::string> suffixes;
+    suffixes.push_back( "_DB_ATTRIBUTES" );
+    suffixes.push_back( "_F0000_TAGS_SEQ" );
+    suffixes.push_back( "_F0001_TAGS_SEQ" );
+    suffixes.push_back( "_F0002_CHANNELS" );
+    suffixes.push_back( "_F0002_IOVS" );
+    suffixes.push_back( "_F0002_IOVS_SEQ" );
+    suffixes.push_back( "_F0003_CHANNELS" );
+    suffixes.push_back( "_F0003_IOVS" );
+    suffixes.push_back( "_F0003_IOVS_SEQ" );
+    suffixes.push_back( "_NODES" );
+    suffixes.push_back( "_NODES_SEQ" );
+    suffixes.push_back( "_TAG2TAG" );
+    suffixes.push_back( "_TAG2TAG_SEQ" );
+    suffixes.push_back( "_TAGS" );
+    // Change a folder schema and a folder set to 2.0.9
+    std::string newSch("2.0.9");
+    std::string oldFsetSch( RelationalFolderSet::folderSetSchemaVersion() );
+    std::string oldFoldSch( RelationalFolder::folderSchemaVersion() );
+    updateNodeSchemaVersion( "/f1", newSch );
+    updateNodeSchemaVersion( "/f1/folderA", newSch );
+    try {
+      std::vector<string> tables = ralDb->listAllTables();
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "tables count", (size_t)14, tables.size() );
+      std::vector<std::string>::const_iterator suffix;
+      for ( suffix = suffixes.begin(); suffix != suffixes.end(); suffix++ ) 
+      {
+        std::string table;
+        table = m_coolDBName + *suffix;
+        CPPUNIT_ASSERT_MESSAGE
+          ( table, 
+            find( tables.begin(), tables.end(), table ) != tables.end() );
+      }
+    } catch (...) {      
+      updateNodeSchemaVersion( "/f1", oldFsetSch );
+      updateNodeSchemaVersion( "/f1/folderA", oldFoldSch );
+      throw;
+    }    
+    updateNodeSchemaVersion( "/f1", oldFsetSch );
+    updateNodeSchemaVersion( "/f1/folderA", oldFoldSch );
+  }
+  
+  
+  /// Tests listAllTables if there are new node versions 2.9.0
+  void test_listAllTablesWithNode_2_9_0() 
+  {
+    // Create folders
+    setupDb();
+    ralDb->createFolderSet( "/f1" );
+    ralDb->createFolder( "/f1/folderA", payloadSpec );
+    ralDb->createFolder( "/f1/folderB", payloadSpec );
+    // Change a folder set schema to 2.9.0
+    {
+      std::string newSch("2.9.0");
+      std::string oldFsetSch( RelationalFolderSet::folderSetSchemaVersion() );
+      updateNodeSchemaVersion( "/f1", newSch );
+      try {
+        //CPPUNIT_ASSERT_THROW
+        //  ( ralDb->listAllTables(), UnsupportedFolderSetSchema );
+      } catch (...) {      
+        updateNodeSchemaVersion( "/f1", oldFsetSch );
+        throw;
+      }    
+      updateNodeSchemaVersion( "/f1", oldFsetSch );
+    }    
+    // Change a folder schema to 2.9.0
+    {
+      std::string newSch("2.9.0");
+      std::string oldFoldSch( RelationalFolder::folderSchemaVersion() );
+      updateNodeSchemaVersion( "/f1/folderA", newSch );
+      try {
+        CPPUNIT_ASSERT_THROW
+          ( ralDb->listAllTables(), UnsupportedFolderSchema );
+      } catch (...) {      
+        updateNodeSchemaVersion( "/f1/folderA", oldFoldSch );
+        throw;
+      }    
+      updateNodeSchemaVersion( "/f1/folderA", oldFoldSch );
+    }
+  }
+  
+  
+  /// Tests what happens when the current API is used to drop a database 
+  /// containing a folder with obsolete schema version 2.0.0
+  void test_dropDatabaseWithFolder_2_0_0() 
+  {
+    setupDb();
+    ralDb->createFolderSet( "/my" );
+    ralDb->createFolder( "/my/folder1", payloadSpec );
+    ralDb->createFolder( "/my/folder2", payloadSpec );
+    ralDb->createFolder( "/my/folder3", payloadSpec );
+    std::string newSch("2.0.0");
+    std::string oldFoldSch( RelationalFolder::folderSchemaVersion() );
+    updateNodeSchemaVersion( "/my/folder2", newSch );
+    try {
+      CPPUNIT_ASSERT_THROW
+        ( ralDb->dropDatabase(), Exception );
+      IFolderSetPtr folderset = ralDb->getFolderSet( "/my" );
+      CPPUNIT_ASSERT( folderset.get() != 0 );
+      IFolderPtr folder;
+      folder = ralDb->getFolder( "/my/folder1" );
+      CPPUNIT_ASSERT( folder.get() != 0 );
+      folder = ralDb->getFolder( "/my/folder2" );
+      CPPUNIT_ASSERT( folder.get() != 0 );
+      folder = ralDb->getFolder( "/my/folder3" );
+      CPPUNIT_ASSERT( folder.get() != 0 );
+    } catch (...) {      
+      updateNodeSchemaVersion( "/my/folder2", oldFoldSch );
+      throw;
+    }    
+    updateNodeSchemaVersion( "/my/folder2", oldFoldSch );
+  }
+
+  
+  /// Tests what happens when the current API is used 
+  /// to access a node with newer schema version 2.0.9
+  void test_useNode_2_0_9() 
+  {
+    setupDb();
+    ralDb->createFolderSet( "/my" );
+    ralDb->createFolder
+      ( "/my/folder", payloadSpec, "", FolderVersioning::MULTI_VERSION );
+    std::string newSch("2.0.9");
+    //std::string newSch("2.9.0"); // test error recovery in catch(...) clause
+    std::string oldFoldSch( RelationalFolder::folderSchemaVersion() );
+    std::string oldFsetSch( RelationalFolderSet::folderSetSchemaVersion() );
+
+    /// 1. Test folderset and folder using their original schema version
+    IFolderSetPtr folderset;
+    IFolderPtr folder;
+    folderset = ralDb->getFolderSet( "/my" );
+    CPPUNIT_ASSERT( folderset.get() != 0 );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE
+      ( "1. folderset name", std::string( "/my" ), folderset->fullPath() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE
+      ( "1. folderset schema", oldFsetSch, folderset->folderSetAttributes()
+        ["NODE_SCHEMA_VERSION"].data<std::string>() );
+    folderset->listFolders(); // Should not throw
+    folder = ralDb->getFolder( "/my/folder" );
+    CPPUNIT_ASSERT( folder.get() != 0 );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE
+      ( "1. folder name", std::string( "/my/folder" ), folder->fullPath() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE
+      ( "1. folder schema", oldFoldSch, folder->folderAttributes()
+        ["NODE_SCHEMA_VERSION"].data<std::string>() );
+    folder->folderSpecification(); // Should not throw
+
+    /// 2. Test folderset and folder using a newer schema version
+    updateNodeSchemaVersion( "/my", newSch );
+    updateNodeSchemaVersion( "/my/folder", newSch );
+    folderset = ralDb->getFolderSet( "/my" );
+    CPPUNIT_ASSERT( folderset.get() != 0 );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE
+      ( "2. folderset name", std::string( "/my" ), folderset->fullPath() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE
+      ( "2. folderset schema", newSch, folderset->folderSetAttributes()
+        ["NODE_SCHEMA_VERSION"].data<std::string>() );
+    folder = ralDb->getFolder( "/my/folder" );
+    CPPUNIT_ASSERT( folder.get() != 0 );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE
+      ( "2. folder name", std::string( "/my/folder" ), folder->fullPath() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE
+      ( "2. folder schema", newSch, folder->folderAttributes()
+        ["NODE_SCHEMA_VERSION"].data<std::string>() );
+    // None of the following methods should throw
+    try {
+      folderset->listFolders();
+      folderset->listFolderSets();
+      folder->folderSpecification();
+      folder->payloadSpecification();
+      folder->versioningMode();
+      folder->setupStorageBuffer();
+      Record dummyRec( payloadSpec );
+      folder->storeObject( 0, 10, dummyRec, 0 );
+      folder->flushStorageBuffer();
+      
+      IObjectPtr obj = folder->findObject( 0, 0 );
+      // We cannot use the current time to tag if the client
+      // and server are not synchronized  (see bug #24481 for details)
+      Time insertion_time = obj->insertionTime();
+      obj.reset();
+      
+      ChannelSelection dummyChSel( 0 );
+      folder->findObjects( 0, dummyChSel );
+      folder->setPrefetchAll( true );
+      folder->browseObjects( 0, 10, dummyChSel );
+      folder->countObjects( 0, 10, dummyChSel );
+      folder->renamePayload( "I", "J" );
+      RecordSpecification extSpec;
+      extSpec.extend("I",StorageType::Int32);
+      Record extRec( extSpec );
+      folder->extendPayloadSpecification( extRec );
+      sleep(1); // Patch for the ORA-01466 problem: sleep one second
+      folder->tagCurrentHead( "a" );
+      
+      // We cannot use the current time if the client and server are not
+      // synchronized (see bug #24481 for details)
+      // Time now;
+      
+      folder->insertionTimeOfLastObjectInTag("a");
+      folder->deleteTag( "a" );
+      
+      // folder->tagHeadAsOfDate( now, "a" );
+      folder->tagHeadAsOfDate( insertion_time, "a" );
+      
+      folder->existsUserTag( "a" );
+      folder->listChannels();
+      folder->listChannelsWithNames();
+      folder->createChannel( 1, "b" );
+      folder->setChannelName( 1, "a" );
+      folder->channelName( 1 );
+      folder->channelId( "a" );
+      folder->existsChannel( 0 );
+      folder->existsChannel( "a" );
+      folder->setChannelDescription( 1, "a" );
+      folder->channelDescription( 1 );
+    } catch (...) {
+      updateNodeSchemaVersion( "/my/folder", oldFoldSch );
+      updateNodeSchemaVersion( "/my", oldFsetSch );
+      throw;
+    }    
+
+    /// 3. Test folderset and folder using their original schema version again
+    updateNodeSchemaVersion( "/my", oldFsetSch );    
+    updateNodeSchemaVersion( "/my/folder", oldFoldSch );
+    folderset = ralDb->getFolderSet( "/my" );
+    CPPUNIT_ASSERT( folderset.get() != 0 );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE
+      ( "3. folderset name", std::string( "/my" ), folderset->fullPath() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE
+      ( "3. folderset schema", oldFsetSch, folderset->folderSetAttributes()
+        ["NODE_SCHEMA_VERSION"].data<std::string>() );
+    folderset->listFolders(); // Should not throw
+    folder = ralDb->getFolder( "/my/folder" );
+    CPPUNIT_ASSERT( folder.get() != 0 );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE
+      ( "3. folder name", std::string( "/my/folder" ), folder->fullPath() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE
+      ( "3. folder schema", oldFoldSch, folder->folderAttributes()
+        ["NODE_SCHEMA_VERSION"].data<std::string>() );
+    folder->folderSpecification(); // Should not throw
+
+  }
+  
+
+  /// Tests what happens when the current API is used 
+  /// to drop a node with newer schema version 2.0.9
+  void test_dropNode_2_0_9() 
+  {
+    setupDb();
+    ralDb->createFolderSet( "/my" );
+    ralDb->createFolder( "/my/folder", payloadSpec );
+    std::string newSch("2.0.9");
+    //std::string newSch("2.9.0"); // test error recovery in catch(...) clause
+    std::string oldFoldSch( RelationalFolder::folderSchemaVersion() );
+    std::string oldFsetSch( RelationalFolderSet::folderSetSchemaVersion() );
+    updateNodeSchemaVersion( "/my", newSch );
+    updateNodeSchemaVersion( "/my/folder", newSch );
+    try {
+      ralDb->dropNode( "/my/folder" );
+      ralDb->dropNode( "/my" );
+    } catch (...) {
+      updateNodeSchemaVersion( "/my/folder", oldFoldSch );
+      updateNodeSchemaVersion( "/my", oldFsetSch );
+      throw;
+    }    
+  }
+
+  
+  /// Tests what happens when the current API is used 
+  /// to drop a database containing node with newer schema version 2.0.9
+  void test_dropDatabaseWithNode_2_0_9() 
+  {
+    setupDb();
+    ralDb->createFolderSet( "/my" );
+    ralDb->createFolder( "/my/folder1", payloadSpec );
+    ralDb->createFolder( "/my/folder2", payloadSpec );
+    ralDb->createFolder( "/my/folder3", payloadSpec );
+    std::string newSch("2.0.9");
+    //std::string newSch("2.9.0"); // test error recovery in catch(...) clause
+    std::string oldFoldSch( RelationalFolder::folderSchemaVersion() );
+    updateNodeSchemaVersion( "/my/folder2", newSch );
+    try {
+      ralDb->dropDatabase();
+    } catch (...) {      
+      updateNodeSchemaVersion( "/my/folder2", oldFoldSch );
+      throw;
+    }    
+  }
+
+  
+  /// Tests what happens when the current API is used 
+  /// to access a node with newer schema version 2.9.0
+  void test_useNode_2_9_0() 
+  {
+    setupDb();
+    ralDb->createFolderSet( "/my" );
+    ralDb->createFolder
+      ( "/my/folder", payloadSpec, "", FolderVersioning::MULTI_VERSION );
+    std::string newSch("2.9.0");
+    std::string oldFoldSch( RelationalFolder::folderSchemaVersion() );
+    std::string oldFsetSch( RelationalFolderSet::folderSetSchemaVersion() );
+
+    /// 1. Test folderset and folder using their original schema version
+    IFolderSetPtr folderset;
+    IFolderPtr folder;
+    folderset = ralDb->getFolderSet( "/my" );
+    CPPUNIT_ASSERT( folderset.get() != 0 );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE
+      ( "1. folderset name", std::string( "/my" ), folderset->fullPath() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE
+      ( "1. folderset schema", oldFsetSch, folderset->folderSetAttributes()
+        ["NODE_SCHEMA_VERSION"].data<std::string>() );
+    folderset->listFolders(); // Should not throw
+
+    folder = ralDb->getFolder( "/my/folder" );
+    CPPUNIT_ASSERT( folder.get() != 0 );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE
+      ( "1. folder name", std::string( "/my/folder" ), folder->fullPath() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE
+      ( "1. folder schema", oldFoldSch, folder->folderAttributes()
+        ["NODE_SCHEMA_VERSION"].data<std::string>() );
+    folder->folderSpecification(); // Should not throw
+
+    /// 2. Test folderset and folder using a newer schema version
+    updateNodeSchemaVersion( "/my", newSch );
+    updateNodeSchemaVersion( "/my/folder", newSch );
+    folderset = ralDb->getFolderSet( "/my" );
+    CPPUNIT_ASSERT( folderset.get() != 0 );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE
+      ( "2. folderset name", std::string( "/my" ), folderset->fullPath() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE
+      ( "2. folderset schema", newSch, folderset->folderSetAttributes()
+        ["NODE_SCHEMA_VERSION"].data<std::string>() );
+    folder = ralDb->getFolder( "/my/folder" );
+    CPPUNIT_ASSERT( folder.get() != 0 );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE
+      ( "2. folder name", std::string( "/my/folder" ), folder->fullPath() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE
+      ( "2. folder schema", newSch, folder->folderAttributes()
+        ["NODE_SCHEMA_VERSION"].data<std::string>() );
+    try {
+      CPPUNIT_ASSERT_THROW
+        ( folderset->listFolders(), UnsupportedFolderSetSchema );
+      CPPUNIT_ASSERT_THROW
+        ( folderset->listFolderSets(), UnsupportedFolderSetSchema );
+      CPPUNIT_ASSERT_THROW
+        ( folder->folderSpecification(), UnsupportedFolderSchema );
+      CPPUNIT_ASSERT_THROW
+        ( folder->payloadSpecification(), UnsupportedFolderSchema );
+      CPPUNIT_ASSERT_THROW
+        ( folder->versioningMode(), UnsupportedFolderSchema );
+      CPPUNIT_ASSERT_THROW
+        ( folder->setupStorageBuffer(), UnsupportedFolderSchema );
+      Record dummyRec( payloadSpec );
+      CPPUNIT_ASSERT_THROW
+        ( folder->storeObject( 0, 10, dummyRec, 0 ), UnsupportedFolderSchema );
+      CPPUNIT_ASSERT_THROW
+        ( folder->flushStorageBuffer(), UnsupportedFolderSchema );
+      CPPUNIT_ASSERT_THROW
+        ( folder->findObject( 0, 0 ), UnsupportedFolderSchema );
+      ChannelSelection dummyChSel( 0 );
+      CPPUNIT_ASSERT_THROW
+        ( folder->findObjects( 0, dummyChSel ), UnsupportedFolderSchema );
+      CPPUNIT_ASSERT_THROW
+        ( folder->setPrefetchAll( true ), UnsupportedFolderSchema );
+      CPPUNIT_ASSERT_THROW
+        ( folder->browseObjects( 0, 10, dummyChSel ), 
+          UnsupportedFolderSchema );
+      CPPUNIT_ASSERT_THROW
+        ( folder->countObjects( 0, 10, dummyChSel ), UnsupportedFolderSchema );
+      CPPUNIT_ASSERT_THROW
+        ( folder->renamePayload( "I", "J" ), UnsupportedFolderSchema );
+      RecordSpecification extSpec;
+      extSpec.extend("I",StorageType::Int32);
+      Record extRec( extSpec );
+      CPPUNIT_ASSERT_THROW
+        ( folder->extendPayloadSpecification( extRec ), UnsupportedFolderSchema );
+      CPPUNIT_ASSERT_THROW
+        ( folder->tagCurrentHead( "a" ), UnsupportedFolderSchema );
+      Time now;
+      CPPUNIT_ASSERT_THROW
+        ( folder->insertionTimeOfLastObjectInTag("a"), 
+          UnsupportedFolderSchema );
+      CPPUNIT_ASSERT_THROW
+        ( folder->deleteTag( "a" ), UnsupportedFolderSchema );
+      CPPUNIT_ASSERT_THROW
+        ( folder->tagHeadAsOfDate( now, "a" ), UnsupportedFolderSchema );
+      CPPUNIT_ASSERT_THROW
+        ( folder->existsUserTag( "a" ), UnsupportedFolderSchema );
+      CPPUNIT_ASSERT_THROW
+        ( folder->listChannels(), UnsupportedFolderSchema );
+      CPPUNIT_ASSERT_THROW
+        ( folder->listChannelsWithNames(), UnsupportedFolderSchema );
+      CPPUNIT_ASSERT_THROW
+        ( folder->createChannel( 1, "b" ), UnsupportedFolderSchema );
+      CPPUNIT_ASSERT_THROW
+        ( folder->setChannelName( 1, "a" ), UnsupportedFolderSchema );
+      CPPUNIT_ASSERT_THROW
+        ( folder->channelName( 1 ), UnsupportedFolderSchema );
+      CPPUNIT_ASSERT_THROW
+        ( folder->channelId( "a" ), UnsupportedFolderSchema );
+      CPPUNIT_ASSERT_THROW
+        ( folder->existsChannel( 0 ), UnsupportedFolderSchema );
+      CPPUNIT_ASSERT_THROW
+        ( folder->existsChannel( "a" ), UnsupportedFolderSchema );
+      CPPUNIT_ASSERT_THROW
+        ( folder->setChannelDescription( 1, "a" ), UnsupportedFolderSchema );
+      CPPUNIT_ASSERT_THROW
+        ( folder->channelDescription( 1 ), UnsupportedFolderSchema );
+    } catch (...) {
+      updateNodeSchemaVersion( "/my/folder", oldFoldSch );
+      updateNodeSchemaVersion( "/my", oldFsetSch );
+      throw;
+    }    
+
+    /// 3. Test folderset and folder using their original schema version again
+    updateNodeSchemaVersion( "/my", oldFsetSch );    
+    updateNodeSchemaVersion( "/my/folder", oldFoldSch );
+    folderset = ralDb->getFolderSet( "/my" );
+    CPPUNIT_ASSERT( folderset.get() != 0 );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE
+      ( "3. folderset name", std::string( "/my" ), folderset->fullPath() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE
+      ( "3. folderset schema", oldFsetSch, folderset->folderSetAttributes()
+        ["NODE_SCHEMA_VERSION"].data<std::string>() );
+    folderset->listFolders(); // Should not throw
+
+    folder = ralDb->getFolder( "/my/folder" );
+    CPPUNIT_ASSERT( folder.get() != 0 );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE
+      ( "3. folder name", std::string( "/my/folder" ), folder->fullPath() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE
+      ( "3. folder schema", oldFoldSch, folder->folderAttributes()
+        ["NODE_SCHEMA_VERSION"].data<std::string>() );
+    folder->folderSpecification(); // Should not throw
+
+  }
+  
+
+  /// Tests what happens when the current API is used 
+  /// to drop a node with newer schema version 2.9.0
+  void test_dropNode_2_9_0() 
+  {
+    setupDb();
+    ralDb->createFolderSet( "/my" );
+    ralDb->createFolder( "/my/folder", payloadSpec );
+    std::string newSch("2.9.0");
+    std::string oldFoldSch( RelationalFolder::folderSchemaVersion() );
+    std::string oldFsetSch( RelationalFolderSet::folderSetSchemaVersion() );
+    updateNodeSchemaVersion( "/my", newSch );
+    updateNodeSchemaVersion( "/my/folder", newSch );
+    try {
+      CPPUNIT_ASSERT_THROW
+        ( ralDb->dropNode( "/my/folder" ), Exception );
+      CPPUNIT_ASSERT_THROW
+        ( ralDb->dropNode( "/my" ), Exception );
+    } catch (...) {
+      updateNodeSchemaVersion( "/my", oldFsetSch );
+      updateNodeSchemaVersion( "/my/folder", oldFoldSch );
+      throw;
+    }    
+    updateNodeSchemaVersion( "/my", oldFsetSch );
+    updateNodeSchemaVersion( "/my/folder", oldFoldSch );
+  }
+
+  
+  /// Tests what happens when the current API is used 
+  /// to drop a database containing node with newer schema version 2.9.0
+  void test_dropDatabaseWithNode_2_9_0() 
+  {
+    setupDb();
+    ralDb->createFolderSet( "/my" );
+    ralDb->createFolder( "/my/folder1", payloadSpec );
+    ralDb->createFolder( "/my/folder2", payloadSpec );
+    ralDb->createFolder( "/my/folder3", payloadSpec );
+    std::string newSch("2.9.0");
+    std::string oldFoldSch( RelationalFolder::folderSchemaVersion() );
+    updateNodeSchemaVersion( "/my/folder2", newSch );
+    try {
+      CPPUNIT_ASSERT_THROW
+        ( ralDb->dropDatabase(), Exception );
+      IFolderSetPtr folderset = ralDb->getFolderSet( "/my" );
+      CPPUNIT_ASSERT( folderset.get() != 0 );
+      IFolderPtr folder;
+      folder = ralDb->getFolder( "/my/folder1" );
+      CPPUNIT_ASSERT( folder.get() != 0 );
+      folder = ralDb->getFolder( "/my/folder2" );
+      CPPUNIT_ASSERT( folder.get() != 0 );
+      folder = ralDb->getFolder( "/my/folder3" );
+      CPPUNIT_ASSERT( folder.get() != 0 );
+    } catch (...) {      
+      updateNodeSchemaVersion( "/my/folder2", oldFoldSch );
+      throw;
+    }    
+    updateNodeSchemaVersion( "/my/folder2", oldFoldSch );
+  }
+
+
+  /// Tests createFolderSet with an invalid name (task #4371 and bug #30751)
+  void test_createFolderSet_invalidName() 
+  {
+    setupDb();
+    const MSG::Level oldOutputLevel = application().outputLevel();
+    application().setOutputLevel( MSG::FATAL );
+    try {
+      CPPUNIT_ASSERT_THROW
+        ( ralDb->createFolderSet( "/myfolderset " ), 
+          HvsPathHandlerException );
+      CPPUNIT_ASSERT_THROW
+        ( ralDb->createFolderSet( "/my\folderset" ), 
+          HvsPathHandlerException );
+      CPPUNIT_ASSERT_THROW
+        ( ralDb->createFolderSet( "/my folderset" ), 
+          HvsPathHandlerException );
+      CPPUNIT_ASSERT_THROW
+        ( ralDb->createFolderSet( "/my$folderset" ), 
+          HvsPathHandlerException );
+      ralDb->createFolderSet( "/my.folderset" );
+      ralDb->createFolderSet( "/my-folderset" );
+    } catch ( std::exception& e ) {
+      std::cout << "Exception caught: " << e.what() << std::endl;
+      application().setOutputLevel( oldOutputLevel );
+      throw;     
+    }
+    application().setOutputLevel( oldOutputLevel );
+  }
+  
+
+  /// Tests createFolder with an invalid name (task #4371 and bug #30751)
+  void test_createFolder_invalidName() 
+  {
+    setupDb();
+    const MSG::Level oldOutputLevel = application().outputLevel();
+    application().setOutputLevel( MSG::FATAL );
+    try {
+      CPPUNIT_ASSERT_THROW
+        ( ralDb->createFolder( "/myfolder ", payloadSpec ), 
+          HvsPathHandlerException );
+      CPPUNIT_ASSERT_THROW
+        ( ralDb->createFolder( "/my\folder", payloadSpec ), 
+          HvsPathHandlerException );
+      CPPUNIT_ASSERT_THROW
+        ( ralDb->createFolder( "/my folder", payloadSpec ), 
+          HvsPathHandlerException );
+      CPPUNIT_ASSERT_THROW
+        ( ralDb->createFolder( "/my$folder", payloadSpec ), 
+          HvsPathHandlerException );
+      ralDb->createFolder( "/my.folder", payloadSpec );
+      ralDb->createFolder( "/my-folder", payloadSpec );
+    } catch ( std::exception& e ) {
+      std::cout << "Exception caught: " << e.what() << std::endl;
+      application().setOutputLevel( oldOutputLevel );
+      throw;     
+    }
+    application().setOutputLevel( oldOutputLevel );
+  }
+  
+
+  /*
+  // The following 4 tests are longer relevant after completing task #4371
+  // (it is now impossible to create a node with a trailing space).
+
+  /// Tests createFolderSet with an invalid name (task #4371 and bug #30751)
+  void test_createFolderSet_invalidName_old() 
+  {
+    setupDb();
+    try {
+      std::string fName;
+      IFolderSetPtr f;
+      // Trailing space
+      fName = "/myfolderset ";
+      f = ralDb->createFolderSet( fName );
+      CPPUNIT_ASSERT( f.get() != 0 );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "\"" + fName + "\"", fName, f->fullPath() );
+    } catch ( std::exception& e ) {
+      std::cout << "Exception caught: " << e.what() << std::endl;
+      throw;     
+    }
+  }
+  
+
+  /// Tests createFolder with an invalid name (task #4371 and bug #30751)
+  void test_createFolder_invalidName_old() 
+  {
+    setupDb();
+    try {
+      std::string fName;
+      IFolderPtr f;
+      // Trailing space
+      fName = "/myfolder ";
+      f = ralDb->createFolder( fName, payloadSpec );
+      CPPUNIT_ASSERT( f.get() != 0 );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "\"" + fName + "\"", fName, f->fullPath() );
+    } catch ( std::exception& e ) {
+      std::cout << "Exception caught: " << e.what() << std::endl;
+      throw;     
+    }
+  }
+
+  
+  /// Tests creating two folder sets with the same name,
+  /// except for a trailing space (task #4371 and bug #30751)
+  void test_createFolderSet_twoSimilarNames() 
+  {
+    setupDb();
+    try {
+      std::string fName;
+      IFolderSetPtr f;
+      // Trailing space (FIRST)
+      fName = "/myfolderset ";
+      f = ralDb->createFolderSet( fName );
+      CPPUNIT_ASSERT( f.get() != 0 );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "\"" + fName + "\"", fName, f->fullPath() );
+      // Normal name (LATER...)
+      fName = "/myfolderset";
+      f = ralDb->createFolderSet( fName );
+      CPPUNIT_ASSERT( f.get() != 0 );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "\"" + fName + "\"", fName, f->fullPath() );
+    } catch ( std::exception& e ) {
+      std::cout << "Exception caught: " << e.what() << std::endl;
+      throw;     
+    }
+  }
+  
+
+  /// Tests creating two folders with the same name,
+  /// except for a trailing space (task #4371 and bug #30751)
+  void test_createFolder_twoSimilarNames() 
+  {
+    setupDb();
+    try {
+      std::string fName;
+      IFolderPtr f;
+      // Trailing space (FIRST)
+      fName = "/myfolder ";
+      f = ralDb->createFolder( fName, payloadSpec );
+      CPPUNIT_ASSERT( f.get() != 0 );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "\"" + fName + "\"", fName, f->fullPath() );
+      // Normal name (LATER...)
+      fName = "/myfolder";
+      f = ralDb->createFolder( fName, payloadSpec );
+      CPPUNIT_ASSERT( f.get() != 0 );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "\"" + fName + "\"", fName, f->fullPath() );
+    } catch ( std::exception& e ) {
+      std::cout << "Exception caught: " << e.what() << std::endl;
+      throw;     
+    }
+  }
+  */
+
+
+  /// Tests writing of the folder description
+  void test_createFolderSet_description() {
+    setupDb();
+    ralDb->createFolderSet( "/myfolder", "my description" );
+    
+    RelationalTransaction transaction( ralDb->transactionMgr() );
+    RelationalTableRow row( ralDb->fetchNodeTableRow( "/myfolder" ) );
+    transaction.commit();
+
+    CPPUNIT_ASSERT_EQUAL_MESSAGE
+      ( "db content", 
+        string("my description"), 
+        row["NODE_DESCRIPTION"].data<std::string>() );
+  }
+  
+  
+  /// Tests writing of the folder description
+  void test_createFolder_description() {
+    setupDb();
+    IFolderPtr folder = ralDb->createFolder( "/myfolder", 
+                                             payloadSpec,
+                                             "my description" );
+
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "description from create",
+                                  std::string("my description"), 
+                                  folder->description() );
+    
+    RelationalTransaction transaction( ralDb->transactionMgr() );
+    RelationalTableRow row( ralDb->fetchNodeTableRow( "/myfolder" ) );
+    transaction.commit();
+    CPPUNIT_ASSERT_EQUAL_MESSAGE
+      ( "db content",
+        string("my description"), 
+        row["NODE_DESCRIPTION"].data<std::string>()
+                                  );
+  }
+  
+
+  /// Tests getFolderSet
+  /// This test only ensures that the returned pointer is not null. The more
+  /// detailed test of the folderset read back is in test_RelationalFolderSet.
+  void test_getFolderSet() {
+    setupDb();
+    ralDb->createFolderSet( "/folderset" );
+    
+    IFolderSetPtr folderset = ralDb->getFolderSet( "/folderset" );
+    CPPUNIT_ASSERT( folderset.get() != 0 );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "folderset name test",
+                                  std::string( "/folderset" ), 
+                                  folderset->fullPath() );  
+  }
+
+
+  /// Tests getFolder
+  /// This test only ensures that the returned pointer is not null. The more
+  /// detailed test of the folder read back is in test_RelationalFolder.
+  void test_getFolder() {
+    setupDb();
+    std::string folderName( "/myfolder" );
+    ralDb->createFolder( folderName, payloadSpec );
+    
+    IFolderPtr folder = ralDb->getFolder( folderName );
+    CPPUNIT_ASSERT( folder.get() != 0 );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "folder name test",
+                                  folderName, 
+                                  folder->fullPath() );  
+    RelationalFolder* relfolder 
+      = dynamic_cast<RelationalFolder*>(folder.get());
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "compare object table name",
+                                  string(m_coolDBName+"_F0001_IOVS"),
+                                  relfolder->objectTableName() );
+    CPPUNIT_ASSERT_MESSAGE( "compare payload spec",
+                            payloadSpec 
+                            == folder->payloadSpecification() );
+  }
+  
+  
+  /// Tests folderAttributes for MV folder
+  void test_folderAttributes_MV() {
+    try{
+      setupDb();
+      std::string folderName( "/myfolder" );
+      ralDb->createFolder( folderName, 
+                           payloadSpec,
+                           "my description",
+                           FolderVersioning::MULTI_VERSION );
+      IFolderPtr folder = ralDb->getFolder( folderName );
+      CPPUNIT_ASSERT( folder.get() != 0 );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "folder name test",
+          folderName, 
+          folder->fullPath() );  
+      RelationalFolder* relfolder 
+        = dynamic_cast<RelationalFolder*>(folder.get());
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "compare object table name",
+          string(m_coolDBName+"_F0001_IOVS"),
+          relfolder->objectTableName() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "compare tag table name",
+          string(m_coolDBName+"_F0001_TAGS"),
+          relfolder->tagTableName() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "compare object2tag table name",
+          string(m_coolDBName+"_F0001_IOV2TAG"),
+          relfolder->object2TagTableName() );
+      CPPUNIT_ASSERT_MESSAGE
+        ( "compare payload spec",
+          payloadSpec == folder->payloadSpecification() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "compare object table name from folder properties",
+          string(m_coolDBName+"_F0001_IOVS"),
+          relfolder->folderAttributes()[ "FOLDER_IOVTABLENAME" ]
+          .data<std::string>() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "compare tag table name from folder properties",
+          string(m_coolDBName+"_F0001_TAGS"),
+          relfolder->folderAttributes()[ "FOLDER_TAGTABLENAME" ]
+          .data<std::string>() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "compare object2tag table name from folder properties",
+          string(m_coolDBName+"_F0001_IOV2TAG"),
+          relfolder->folderAttributes()[ "FOLDER_IOV2TAGTABLENAME" ]
+          .data<std::string>() );
+    } catch ( std::exception& e ) {
+      std::cout << "Exception caught: " << e.what() << std::endl;
+      throw;     
+    }
+  }
+
+
+  /// Tests folderAttributes for SV folder
+  void test_folderAttributes_SV() {
+    try{
+      setupDb();
+      std::string folderName( "/myfolder" );
+      ralDb->createFolder( folderName, 
+                           payloadSpec,
+                           "my description",
+                           FolderVersioning::SINGLE_VERSION );
+      IFolderPtr folder = ralDb->getFolder( folderName );
+      CPPUNIT_ASSERT( folder.get() != 0 );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "folder name test",
+          folderName, 
+          folder->fullPath() );  
+      RelationalFolder* relfolder 
+        = dynamic_cast<RelationalFolder*>(folder.get());
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "compare object table name",
+          string(m_coolDBName+"_F0001_IOVS"),
+          relfolder->objectTableName() );
+      CPPUNIT_ASSERT_MESSAGE
+        ( "compare payload spec",
+          payloadSpec == folder->payloadSpecification() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "compare object table name from folder properties",
+          string(m_coolDBName+"_F0001_IOVS"),
+          relfolder->folderAttributes()[ "FOLDER_IOVTABLENAME" ]
+          .data<std::string>() );
+      try {
+        relfolder->folderAttributes()
+          [ "FOLDER_TAGTABLENAME" ].data<std::string>();
+        CPPUNIT_ASSERT_MESSAGE
+          ( "exception expected for FOLDER_TAGTABLENAME", false );
+      } catch ( RecordSpecificationUnknownField& e ) {
+        RecordSpecificationUnknownField exp( "FOLDER_TAGTABLENAME", "" );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE
+          ( "exception message for FOLDER_TAGTABLENAME", 
+            string( exp.what() ), string( e.what() ) );
+      }
+      try {
+        relfolder->folderAttributes()
+        [ "FOLDER_IOV2TAGTABLENAME" ].data<std::string>();
+        CPPUNIT_ASSERT_MESSAGE
+          ( "exception expected for FOLDER_IOV2TAGTABLENAME", false );
+      } catch ( RecordSpecificationUnknownField& e ) {
+        RecordSpecificationUnknownField exp( "FOLDER_IOV2TAGTABLENAME", "" );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE
+          ( "exception message for FOLDER_IOV2TAGTABLENAME", 
+            string( exp.what() ), string( e.what() ) );
+      }
+      CPPUNIT_ASSERT_EQUAL
+        ( string(m_coolDBName+"_F0001_CHANNELS"),
+          relfolder->folderAttributes
+          ()[ "FOLDER_CHANNELTABLENAME" ].data<std::string>() );
+    } catch ( std::exception& e ) {
+      std::cout << "Exception caught: " << e.what() << std::endl;
+      throw;     
+    }
+  }
+
+
+  /// Tests that an exception is thrown when an invalid versioning mode
+  /// is specified on folder creation
+  void test_createFolder_invalidVersioningMode() {
+    setupDb();
+    CPPUNIT_ASSERT_THROW(
+                         ralDb->createFolder( "/myfolder", 
+                                               payloadSpec,
+                                              "my description",
+                                              // invalid mode
+                                              (FolderVersioning::Mode)-10
+                                              ),
+                         RelationalException );
+  }
+  
+  
+  /// Tests creating a folder in MV mode
+  void test_createFolder_MV() {
+    setupDb();
+    IFolderPtr folder = ralDb->createFolder( "/myfolder", 
+                                             payloadSpec,
+                                             "my description",
+                                             FolderVersioning::MULTI_VERSION );
+    
+    CPPUNIT_ASSERT( folder.get() != 0 );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "versioning mode",
+                                  FolderVersioning::MULTI_VERSION, 
+                                  folder->versioningMode() );
+    
+    RelationalTransaction transaction( ralDb->transactionMgr() );
+    RelationalTableRow row( ralDb->fetchNodeTableRow( "/myfolder" ) );
+    transaction.commit();
+    
+    CPPUNIT_ASSERT_EQUAL_MESSAGE
+      ( "FOLDER_VERSIONING", (int)FolderVersioning::MULTI_VERSION,
+        row["FOLDER_VERSIONING"].data<int>() );
+    {
+      RelationalTransaction transaction( ralDb->transactionMgr() );    
+      CPPUNIT_ASSERT_MESSAGE
+        ( "object table existence",
+          ralDb->queryMgr().existsTable( m_coolDBName + "_F0001_IOVS" ) );
+      CPPUNIT_ASSERT_MESSAGE
+        ( "tag table existence",
+          ralDb->queryMgr().existsTable( m_coolDBName + "_F0001_TAGS" ) );
+      CPPUNIT_ASSERT_MESSAGE
+        ( "iov2tag table existence",
+          ralDb->queryMgr().existsTable( m_coolDBName + "_F0001_IOV2TAG" ) );
+      transaction.commit();
+    }    
+  }
+  
+  
+  /// Tests createFolder in SV mode
+  void test_createFolder_SV() {
+    setupDb();
+    std::string folderName( "/myfolder" );
+    IFolderPtr folder = ralDb->createFolder( folderName, payloadSpec );
+    CPPUNIT_ASSERT( folder.get() != 0 );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "folder name test",
+                                  std::string("/myfolder"), 
+                                  folder->fullPath() );
+
+    RelationalFolder* relfolder 
+      = dynamic_cast<RelationalFolder*>(folder.get());
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "object table name",
+                                  string(m_coolDBName+"_F0001_IOVS"),
+                                  relfolder->objectTableName() );
+    {
+      RelationalTransaction transaction( ralDb->transactionMgr() );    
+      CPPUNIT_ASSERT_MESSAGE
+        ( "object table existence",
+          ralDb->queryMgr().existsTable( m_coolDBName + "_F0001_IOVS" ) );
+      CPPUNIT_ASSERT
+        ( ralDb->queryMgr().existsTable( m_coolDBName + "_F0001_CHANNELS" ) );
+      transaction.commit();
+    }    
+  }
+  
+  
+  /// Tests createFolder when the given folder already exists
+  void test_createFolder_alreadyExists() {
+    setupDb();
+    ralDb->createFolder( "/myfolder", payloadSpec );
+    // expected to throw a RelationalNodeExists exception
+    CPPUNIT_ASSERT_THROW( ralDb->createFolder( "/myfolder", payloadSpec ),
+                          NodeExists );
+  }
+  
+  
+  /// Tests createFolder with createParents = true
+  void test_createFolder_withParents() {
+    setupDb();
+    std::string folderName( "/a/b/c" );
+    bool createParents = true;
+    std::string description = "";
+    IFolderPtr folder = ralDb->createFolder( folderName, 
+                                             payloadSpec,
+                                             description,
+                                             FolderVersioning::SINGLE_VERSION,
+                                             createParents );
+    CPPUNIT_ASSERT_MESSAGE( "/a/b/c not null", folder.get() != 0 );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "/a/b/c folder name test",
+                                  std::string("/a/b/c"), 
+                                  folder->fullPath() );
+    IFolderSetPtr folderset = ralDb->getFolderSet( "/a/b" );
+    CPPUNIT_ASSERT_MESSAGE( "/a/b not null", folderset.get() != 0 );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "/a/b folderset name test",
+                                  std::string("/a/b"), 
+                                  folderset->fullPath() );
+    folderset = ralDb->getFolderSet( "/a" );
+    CPPUNIT_ASSERT_MESSAGE( "/a not null", folderset.get() != 0 );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "/a folder name test",
+                                  std::string("/a"), 
+                                  folderset->fullPath() );
+  }
+  
+  
+  /// Tests existsNode
+  void test_existsNode() {
+    setupDb();
+    m_db->createFolder( "/myfolder", payloadSpec );
+    m_db->createFolderSet( "/myfolderset" );
+    
+    RelationalTransaction transaction( ralDb->transactionMgr(), true );
+    
+    CPPUNIT_ASSERT_MESSAGE( "myfolder", 
+                            ralDb->existsNode( "/myfolder" ) );
+    CPPUNIT_ASSERT_MESSAGE( "myfolderset", 
+                            ralDb->existsNode( "/myfolderset" ) );
+    CPPUNIT_ASSERT_MESSAGE( "negative test", 
+                            ! ralDb->existsNode( "/nofolder" ) );
+    
+    transaction.commit();
+  }
+  
+
+  /// Tests existsFolderSet
+  void test_existsFolderSet() {
+    setupDb();
+    CPPUNIT_ASSERT_MESSAGE( "folderset does not exist yet", 
+                            ! ralDb->existsFolderSet( "/myfolderset" ) );
+    ralDb->createFolderSet( "/myfolderset" );
+    CPPUNIT_ASSERT_MESSAGE( "folderset exists", 
+                            ralDb->existsFolderSet( "/myfolderset" ) );
+  }
+  
+  
+  /// Tests existsFolder
+  void test_existsFolder() {
+    setupDb();
+    CPPUNIT_ASSERT_MESSAGE( "folder does not exist yet", 
+                            ! ralDb->existsFolder( "/myfolder" ) );
+    ralDb->createFolder( "/myfolder", payloadSpec );
+    CPPUNIT_ASSERT_MESSAGE( "folder exists", 
+                            ralDb->existsFolder( "/myfolder" ) );
+  }
+  
+  
+  /// Tests createFolder
+  void test_createFolderSet_alreadyExists() {
+    setupDb();
+    ralDb->createFolderSet( "/myfolder" );
+    // expected to throw a RelationalNodeExists exception
+    CPPUNIT_ASSERT_THROW( ralDb->createFolderSet( "/myfolder" ),
+                          NodeExists );
+  }
+  
+  
+  /// Tests createFolderSet
+  void test_createFolderSet() {
+    setupDb();
+    
+    ralDb->createFolderSet( "/myfolderset", "my description" );
+    
+    RelationalTransaction transaction( ralDb->transactionMgr() );
+    RelationalTableRow row = ralDb->fetchNodeTableRow( "/myfolderset" );
+    transaction.commit();
+    
+    CPPUNIT_ASSERT_EQUAL_MESSAGE
+      ( "NODE_ID", 1u, 
+        row["NODE_ID"].data<unsigned int>() );
+
+    CPPUNIT_ASSERT_EQUAL_MESSAGE
+      ( "NODE_PARENTID", 0u, 
+        row["NODE_PARENTID"].data<unsigned int>() );
+    
+    CPPUNIT_ASSERT_EQUAL_MESSAGE
+      ( "NODE_NAME", string("myfolderset"),
+        row["NODE_NAME"].data<std::string>() );
+    
+    CPPUNIT_ASSERT_EQUAL_MESSAGE
+      ( "NODE_FULLPATH", string("/myfolderset"), 
+        row["NODE_FULLPATH"].data<std::string>() );
+
+    CPPUNIT_ASSERT_EQUAL_MESSAGE
+      ( "NODE_DESCRIPTION", string("my description"), 
+        row["NODE_DESCRIPTION"].data<std::string>() );
+    
+    CPPUNIT_ASSERT_EQUAL_MESSAGE
+      ( "NODE_ISLEAF", false, 
+        row["NODE_ISLEAF"].data<bool>() );
+
+    CPPUNIT_ASSERT_EQUAL_MESSAGE
+      ( "NODE_INSTIME length",
+        string("yyyy-mm-dd_hh:mm:ss.nnnnnnnnn GMT").size(),
+        row["NODE_INSTIME"].data<std::string>().size() );
+    
+    CPPUNIT_ASSERT_EQUAL_MESSAGE
+      ( "FOLDER_PAYLOADSPEC", string(""), 
+        row["FOLDER_PAYLOADSPEC"].data<std::string>() );
+    
+    CPPUNIT_ASSERT_EQUAL_MESSAGE
+      ( "FOLDER_VERSIONING", (int)FolderVersioning::NONE,
+        row["FOLDER_VERSIONING"].data<int>() );
+    
+    CPPUNIT_ASSERT_EQUAL_MESSAGE
+      ( "FOLDER_IOVTABLENAME", string(""), 
+        row["FOLDER_IOVTABLENAME"].data<std::string>() );
+  }
+  
+  
+  /// Tests dropAllNodes
+  void test_dropAllNodes() {
+    setupDb();
+    std::vector<string> folderNames;
+    folderNames.push_back( "/f1" );
+    folderNames.push_back( "/f2" );
+    folderNames.push_back( "/f3" );
+    for ( std::vector<string>::const_iterator f = folderNames.begin();
+          f != folderNames.end();
+          ++f ) {
+      ralDb->createFolder( *f, payloadSpec );
+    }
+
+    for ( std::vector<string>::const_iterator f = folderNames.begin();
+          f != folderNames.end();
+          ++f ) {
+      CPPUNIT_ASSERT_MESSAGE( string("folder exists: ") + *f, 
+                              ralDb->existsFolder( *f ) );
+    }
+    
+    ralDb->dropAllNodes();
+    
+    for ( std::vector<string>::const_iterator f = folderNames.begin();
+          f != folderNames.end();
+          ++f ) {
+      CPPUNIT_ASSERT_MESSAGE( string("folder is deleted: ") + *f, 
+                              ! ralDb->existsFolder( *f ) );
+    }
+  }
+
+
+  /// Tests dropNode
+  void test_dropNode() {
+    setupDb();
+    try {      
+      {
+        // Test dropping a SV folder
+        IFolderPtr 
+          folder = ralDb->createFolder( "/myfolder_sv", payloadSpec );
+        
+        CPPUNIT_ASSERT_MESSAGE( "/myfolder_sv exists", 
+                                ralDb->existsFolder( "/myfolder_sv" ) );
+        stringstream prefix;
+        prefix << m_coolDBName << "_F000" << folder->id();
+        {
+          RelationalTransaction transaction( ralDb->transactionMgr() );
+          CPPUNIT_ASSERT_MESSAGE
+            ( "SV object table exists",
+              ralDb->queryMgr().existsTable( prefix.str() + "_IOVS" ) );
+          CPPUNIT_ASSERT_MESSAGE
+            ( "SV object sequence exists",
+              ralDb->queryMgr().existsTable( prefix.str() + "_IOVS_SEQ" ) );
+          transaction.commit();
+        }
+        ralDb->dropNode( "/myfolder_sv" );
+        CPPUNIT_ASSERT_MESSAGE
+          ( "/folder_sv is deleted", 
+            ! ralDb->existsFolder( "/myfolder_sv" ) );
+        {
+          RelationalTransaction transaction( ralDb->transactionMgr() );
+          CPPUNIT_ASSERT_MESSAGE
+            ( "SV object table removed",
+              ! ralDb->queryMgr().existsTable( prefix.str() + "_IOVS" ) );
+          CPPUNIT_ASSERT_MESSAGE
+            ( "SV object sequence removed",
+              ! ralDb->queryMgr().existsTable( prefix.str() + "_IOVS_SEQ" ) );
+          CPPUNIT_ASSERT_MESSAGE
+            ( "SV tag table removed",
+              ! ralDb->queryMgr().existsTable( prefix.str() + "_TAGS" ) );
+          CPPUNIT_ASSERT_MESSAGE
+            ( "SV tag sequence removed",
+              ! ralDb->queryMgr().existsTable( prefix.str() + "_TAGS_SEQ" ) );
+          CPPUNIT_ASSERT_MESSAGE
+            ( "SV iov2tag table removed",
+              ! ralDb->queryMgr().existsTable( prefix.str() + "_IOV2TAG" ) );
+          transaction.commit();
+        }
+      }
+      
+      {
+        // Test dropping a MV folder
+        IFolderPtr 
+          folder = ralDb->createFolder( "/myfolder_mv", payloadSpec, 
+                                        "", FolderVersioning::MULTI_VERSION );
+        CPPUNIT_ASSERT_MESSAGE( "/myfolder_mv exists", 
+                                ralDb->existsFolder( "/myfolder_mv" ) );
+        stringstream prefix;
+        prefix << m_coolDBName << "_F000" << folder->id();        
+        {
+          RelationalTransaction transaction( ralDb->transactionMgr() );
+          CPPUNIT_ASSERT_MESSAGE
+            ( "MV object table exists",
+              ralDb->queryMgr().existsTable( prefix.str() + "_IOVS" ) );
+          CPPUNIT_ASSERT_MESSAGE
+            ( "MV object sequence exists",
+              ralDb->queryMgr().existsTable( prefix.str() + "_IOVS_SEQ" ) );
+          CPPUNIT_ASSERT_MESSAGE
+            ( "MV tag table exists",
+              ralDb->queryMgr().existsTable( prefix.str() + "_TAGS" ) );
+          CPPUNIT_ASSERT_MESSAGE
+            ( "MV tag sequence exists",
+              ralDb->queryMgr().existsTable( prefix.str() + "_TAGS_SEQ" ) );
+          CPPUNIT_ASSERT_MESSAGE
+            ( "MV iov2tag table exists",
+              ralDb->queryMgr().existsTable( prefix.str() + "_IOV2TAG" ) );
+          transaction.commit();
+        }        
+        ralDb->dropNode( "/myfolder_mv" );
+        CPPUNIT_ASSERT_MESSAGE
+          ( "/folder_mv is deleted", 
+            ! ralDb->existsFolder( "/myfolder_mv" ) );
+        {
+          RelationalTransaction transaction( ralDb->transactionMgr() );
+          CPPUNIT_ASSERT_MESSAGE
+            ( "MV object table removed",
+              ! ralDb->queryMgr().existsTable( prefix.str() + "_IOVS" ) );
+          CPPUNIT_ASSERT_MESSAGE
+            ( "MV object sequence removed",
+              ! ralDb->queryMgr().existsTable( prefix.str() + "_IOVS_SEQ" ) );
+          CPPUNIT_ASSERT_MESSAGE
+            ( "MV tag table removed",
+              ! ralDb->queryMgr().existsTable( prefix.str() + "_TAGS" ) );
+          CPPUNIT_ASSERT_MESSAGE
+            ( "MV tag sequence removed",
+              ! ralDb->queryMgr().existsTable( prefix.str() + "_TAGS_SEQ" ) );
+          CPPUNIT_ASSERT_MESSAGE
+            ( "MV iov2tag table removed",
+              ! ralDb->queryMgr().existsTable( prefix.str() + "_IOV2TAG" ) );
+          transaction.commit();          
+        }
+      }
+    } catch ( std::exception& e ) {
+      std::cout << "Exception caught: " << e.what() << std::endl;
+      throw;     
+    }
+  }
+  
+  
+  /// Tests listAllNodes
+  void test_listAllNodes() {
+    setupDb();
+    ralDb->createFolderSet( "/f1" );
+    ralDb->createFolderSet( "/f2" );
+    ralDb->createFolderSet( "/f3" );
+    ralDb->createFolderSet( "/f4" );
+    ralDb->createFolder( "/f1/folderA", payloadSpec );
+    ralDb->createFolder( "/f1/folderB", payloadSpec );
+    ralDb->createFolder( "/f3/folderA", payloadSpec );
+    ralDb->createFolder( "/f3/folderB", payloadSpec );
+
+    std::vector<string> readbackNames = ralDb->listAllNodes();
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "node count", 
+                                  (size_t)9, readbackNames.size() );
+    CPPUNIT_ASSERT_MESSAGE( "/f1", 
+                            find( readbackNames.begin(), readbackNames.end(),
+                                  "/f1" ) != readbackNames.end() );
+    CPPUNIT_ASSERT_MESSAGE( "/f2", 
+                            find( readbackNames.begin(), readbackNames.end(),
+                                  "/f2" ) != readbackNames.end() );
+    CPPUNIT_ASSERT_MESSAGE( "/f3", 
+                            find( readbackNames.begin(), readbackNames.end(),
+                                  "/f3" ) != readbackNames.end() );
+    CPPUNIT_ASSERT_MESSAGE( "/f4", 
+                            find( readbackNames.begin(), readbackNames.end(),
+                                  "/f4" ) != readbackNames.end() );
+    CPPUNIT_ASSERT_MESSAGE( "/f1/folderA", 
+                            find( readbackNames.begin(), readbackNames.end(),
+                                  "/f1/folderA" ) != readbackNames.end() );
+    CPPUNIT_ASSERT_MESSAGE( "/f1/folderB", 
+                            find( readbackNames.begin(), readbackNames.end(),
+                                  "/f3/folderB" ) != readbackNames.end() );
+    CPPUNIT_ASSERT_MESSAGE( "/f3/folderA", 
+                            find( readbackNames.begin(), readbackNames.end(),
+                                  "/f3/folderA" ) != readbackNames.end() );
+    CPPUNIT_ASSERT_MESSAGE( "/f3/folderB", 
+                            find( readbackNames.begin(), readbackNames.end(),
+                                  "/f3/folderB" ) != readbackNames.end() );
+    CPPUNIT_ASSERT_MESSAGE( "root", 
+                            find( readbackNames.begin(), readbackNames.end(),
+                                  "/" ) != readbackNames.end() );
+  }
+  
+  
+  /// Tests listAllTables
+  void test_listAllTables() {
+    setupDb();
+    ralDb->createFolderSet( "/f1" );
+    ralDb->createFolder( "/f1/folderA", payloadSpec );
+    ralDb->createFolder( "/f1/folderB", payloadSpec );
+    std::vector<string> tables = ralDb->listAllTables();
+    CPPUNIT_ASSERT_EQUAL_MESSAGE
+      ( "tables count", (size_t)14, tables.size() );
+    std::vector<std::string> suffixes;
+    suffixes.push_back( "_DB_ATTRIBUTES" );
+    suffixes.push_back( "_F0000_TAGS_SEQ" );
+    suffixes.push_back( "_F0001_TAGS_SEQ" );
+    suffixes.push_back( "_F0002_CHANNELS" );
+    suffixes.push_back( "_F0002_IOVS" );
+    suffixes.push_back( "_F0002_IOVS_SEQ" );
+    suffixes.push_back( "_F0003_CHANNELS" );
+    suffixes.push_back( "_F0003_IOVS" );
+    suffixes.push_back( "_F0003_IOVS_SEQ" );
+    suffixes.push_back( "_NODES" );
+    suffixes.push_back( "_NODES_SEQ" );
+    suffixes.push_back( "_TAG2TAG" );
+    suffixes.push_back( "_TAG2TAG_SEQ" );
+    suffixes.push_back( "_TAGS" );
+    std::vector<std::string>::const_iterator suffix;
+    for ( suffix = suffixes.begin(); suffix != suffixes.end(); suffix++ ) 
+    {
+      std::string table;
+      table = m_coolDBName + *suffix;
+      CPPUNIT_ASSERT_MESSAGE
+        ( table, find( tables.begin(), tables.end(), table ) != tables.end() );
+    }
+  }
+  
+  
+  /// Tests insertNodeTableRow for a leaf node
+  /// [NB - This test bypasses the public API and causes data corruption!]
+  /// [Cleanup fails unless exception throwing in dropDatabase() is disabled]
+  void test_insertNodeTableRow_leaf() {
+    setupDb();
+    bool createParents = true;
+    bool isLeaf = true;
+    string payloadSpecDesc = "I:int";
+    try {
+      RelationalTransaction transaction( ralDb->transactionMgr() );
+      unsigned int nodeId =
+        ralDb->insertNodeTableRow( "/a/b/c",
+                                   "my description",
+                                   createParents,
+                                   isLeaf,
+                                   payloadSpecDesc,
+                                   FolderVersioning::SINGLE_VERSION );
+      RelationalTableRow row( ralDb->fetchNodeTableRow( "/a/b/c" ) );
+      transaction.commit();
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "return value", 3u, nodeId );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "NODE_ID", 3u, 
+          row["NODE_ID"].data<unsigned int>() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "NODE_PARENTID", 2u, 
+          row["NODE_PARENTID"].data<unsigned int>() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "NODE_NAME", string("c"), 
+          row["NODE_NAME"].data<std::string>() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "NODE_FULLPATH", string("/a/b/c"), 
+          row["NODE_FULLPATH"].data<std::string>() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "NODE_DESCRIPTION", string("my description"), 
+          row["NODE_DESCRIPTION"].data<std::string>() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "NODE_ISLEAF", true, 
+          row["NODE_ISLEAF"].data<bool>() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "NODE_INSTIME length",
+          string("yyyy-mm-dd_hh:mm:ss.nnnnnnnnn GMT").size(),
+          row["NODE_INSTIME"].data<std::string>().size() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "FOLDER_PAYLOADSPEC", string("I:int"), 
+          row["FOLDER_PAYLOADSPEC"].data<std::string>() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "FOLDER_VERSIONING", 
+          (int)FolderVersioning::SINGLE_VERSION,
+          row["FOLDER_VERSIONING"].data<int>() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "FOLDER_IOVTABLENAME", 
+          string(m_coolDBName+"_F0003_IOVS"), 
+          row["FOLDER_IOVTABLENAME"].data<std::string>() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "FOLDER_TAGTABLENAME", 
+          string(m_coolDBName+"_F0003_TAGS"), 
+          row["FOLDER_TAGTABLENAME"].data<std::string>() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "FOLDER_IOV2TAGTABLENAME", 
+          string(m_coolDBName+"_F0003_IOV2TAG"), 
+          row["FOLDER_IOV2TAGTABLENAME"].data<std::string>() );
+    } catch ( std::exception& e ) {
+      std::cout << "Exception caught: " << e.what() << std::endl;
+      throw;     
+    }
+  }
+  
+  
+  /// Tests insertNodeTableRow for a nonleaf node
+  void test_insertNodeTableRow_nonleaf() {
+    setupDb();
+    bool createParents = true;
+    bool isLeaf = false;
+    string payloadSpecDesc = "";
+
+    RelationalTransaction transaction( ralDb->transactionMgr() );
+
+    unsigned int nodeId 
+      = ralDb->insertNodeTableRow( "/a/b/c",
+                                     "my description",
+                                     createParents,
+                                     isLeaf,
+                                     payloadSpecDesc,
+                                     FolderVersioning::NONE );
+    RelationalTableRow row( ralDb->fetchNodeTableRow( "/a/b/c" ) );
+    transaction.commit();
+    
+    CPPUNIT_ASSERT_EQUAL_MESSAGE
+      ( "return value", 3u, nodeId );
+
+    CPPUNIT_ASSERT_EQUAL_MESSAGE
+      ( "NODE_ID", 3u, 
+        row["NODE_ID"].data<unsigned int>() );
+    
+    CPPUNIT_ASSERT_EQUAL_MESSAGE
+      ( "NODE_PARENTID", 2u, 
+        row["NODE_PARENTID"].data<unsigned int>() );
+    
+    CPPUNIT_ASSERT_EQUAL_MESSAGE
+      ( "NODE_NAME", string("c"), 
+        row["NODE_NAME"].data<std::string>() );
+    
+    CPPUNIT_ASSERT_EQUAL_MESSAGE
+      ( "NODE_FULLPATH", string("/a/b/c"), 
+        row["NODE_FULLPATH"].data<std::string>() );
+    
+    CPPUNIT_ASSERT_EQUAL_MESSAGE
+      ( "NODE_DESCRIPTION", string("my description"), 
+        row["NODE_DESCRIPTION"].data<std::string>() );
+    
+    CPPUNIT_ASSERT_EQUAL_MESSAGE
+      ( "NODE_ISLEAF", false, 
+        row["NODE_ISLEAF"].data<bool>() );
+    
+    CPPUNIT_ASSERT_EQUAL_MESSAGE
+      ( "NODE_INSTIME length", 
+        string("yyyy-mm-dd_hh:mm:ss.nnnnnnnnn GMT").size(),
+        row["NODE_INSTIME"].data<std::string>().size() );
+    
+    CPPUNIT_ASSERT_EQUAL_MESSAGE
+      ( "FOLDER_PAYLOADSPEC", string(""), 
+        row["FOLDER_PAYLOADSPEC"].data<std::string>() );
+    
+    CPPUNIT_ASSERT_EQUAL_MESSAGE
+      ( "FOLDER_VERSIONING", (int)FolderVersioning::NONE,
+        row["FOLDER_VERSIONING"].data<int>() );
+    
+    CPPUNIT_ASSERT_EQUAL_MESSAGE
+      ( "FOLDER_IOVTABLENAME", string(""), 
+        row["FOLDER_IOVTABLENAME"].data<std::string>() );
+  }
+  
+  
+  /// utility method to test AttributeList handling
+  RelationalTableRow
+  nestedScope( RalDatabase* aDb, const std::string& foldername ) {
+    static int callDepth = 0;
+    if ( callDepth < 10 ) {
+      ++callDepth;
+      return nestedScope( aDb, foldername );
+    } else {
+      callDepth = 0;
+      return aDb->fetchNodeTableRow( foldername );
+    }
+  }
+  
+  
+  /// Tests copying of AttributeList from the fetch methods
+  void test_fetchNodeTableRow_nestedScope() {
+    setupDb();
+    bool createParents = true;
+    bool isLeaf = false;
+    string payloadSpecDesc = "";
+
+    RelationalTransaction transaction( ralDb->transactionMgr() );
+
+    ralDb->insertNodeTableRow( "/myfolder",
+                                 "my description",
+                                 createParents,
+                                 isLeaf,
+                                 payloadSpecDesc,
+                                 FolderVersioning::NONE );
+    
+    RelationalTableRow row( nestedScope( ralDb, "/myfolder" ) );
+    transaction.commit();
+    
+    CPPUNIT_ASSERT_EQUAL( string("/myfolder"), 
+                          row["NODE_FULLPATH"].data<std::string>() );
+  }
+  
+  
+  /// Tests fetchNodeTableRow
+  void test_fetchNodeTableRow() {
+    try {
+      setupDb();
+      bool createParents = true;
+      bool isLeaf = false;
+      string payloadSpecDesc = "";
+      RelationalTransaction transaction( ralDb->transactionMgr() );
+      ralDb->insertNodeTableRow( "/myfolder",
+                                 "my description",
+                                 createParents,
+                                 isLeaf,
+                                 payloadSpecDesc,
+                                 FolderVersioning::NONE );
+      RelationalTableRow row( ralDb->fetchNodeTableRow( "/myfolder" ) );
+      transaction.commit();
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "NODE_ID", 1u,
+          row["NODE_ID"].data<unsigned int>() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "NODE_PARENTID", 0u, 
+          row["NODE_PARENTID"].data<unsigned int>() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "NODE_NAME", string("myfolder"), 
+          row["NODE_NAME"].data<std::string>() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "NODE_FULLPATH", string("/myfolder"), 
+          row["NODE_FULLPATH"].data<std::string>() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "NODE_DESCRIPTION", string("my description"), 
+          row["NODE_DESCRIPTION"].data<std::string>() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "NODE_ISLEAF", false, 
+          row["NODE_ISLEAF"].data<bool>() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "NODE_INSTIME length", 
+          string("yyyy-mm-dd_hh:mm:ss.nnnnnnnnn GMT").size(),
+          row["NODE_INSTIME"].data<std::string>().size() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "FOLDER_PAYLOADSPEC", string(""), 
+          row["FOLDER_PAYLOADSPEC"].data<std::string>() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "FOLDER_VERSIONING", 
+          (int)FolderVersioning::NONE,
+          row["FOLDER_VERSIONING"].data<int>() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "FOLDER_IOVTABLENAME", string(""), 
+          row["FOLDER_IOVTABLENAME"].data<std::string>() );
+    } catch ( std::exception& e ) {
+      std::cout << "Exception caught: " << e.what() << std::endl;
+      throw;     
+    }
+  }
+  
+  
+  /// Tests insertNodeTableRow
+  /// (if this fails, test_fetchNodeTableRow will also fail)
+  void test_insertNodeTableRow() {
+    try {
+      setupDb();
+      bool createParents = true;
+      bool isLeaf = false;
+      string payloadSpecDesc = "";
+      RelationalTransaction transaction( ralDb->transactionMgr() );
+      ralDb->insertNodeTableRow( "/myfolder",
+                                 "my description",
+                                 createParents,
+                                 isLeaf,
+                                 payloadSpecDesc,
+                                 FolderVersioning::NONE );
+      transaction.commit();
+    } catch ( std::exception& e ) {
+      std::cout << "Exception caught: " << e.what() << std::endl;
+      throw;     
+    }
+  }
+  
+  
+  /// Tests fetchRootNodeTableRow
+  /// (if this fails, test_insertNodeTableRow will also fail)
+  void test_fetchRootNodeTableRow() {
+    try {
+      setupDb();
+      RelationalTransaction transaction( ralDb->transactionMgr(), true );
+      RelationalTableRow row( ralDb->fetchNodeTableRow( "/" ) );
+      transaction.commit();
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "NODE_ID", 0u,
+          row["NODE_ID"].data<unsigned int>() );
+      //CPPUNIT_ASSERT_EQUAL_MESSAGE
+      //  ( "NODE_PARENTID", ??, // NULL 
+      //    row["NODE_PARENTID"].data<unsigned int>() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "NODE_NAME", string(""), 
+          row["NODE_NAME"].data<std::string>() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "NODE_FULLPATH", string("/"), 
+          row["NODE_FULLPATH"].data<std::string>() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "NODE_DESCRIPTION", string(""), 
+          row["NODE_DESCRIPTION"].data<std::string>() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "NODE_ISLEAF", false, 
+          row["NODE_ISLEAF"].data<bool>() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "NODE_INSTIME length", 
+          string("yyyy-mm-dd_hh:mm:ss.nnnnnnnnn GMT").size(),
+          row["NODE_INSTIME"].data<std::string>().size() );
+      //CPPUNIT_ASSERT_EQUAL_MESSAGE
+      //  ( "FOLDER_PAYLOADSPEC", string(""), 
+      //    row["FOLDER_PAYLOADSPEC"].data<std::string>() );
+      CPPUNIT_ASSERT_MESSAGE
+        ( "FOLDER_PAYLOADSPEC", row["FOLDER_PAYLOADSPEC"].isNull() );
+      ////CPPUNIT_ASSERT_EQUAL_MESSAGE
+      ////  ( "FOLDER_VERSIONING", 
+      ////    (int)FolderVersioning::NONE, // BUG: null - should be -1!
+      ////    row["FOLDER_VERSIONING"].data<int>() );
+      //CPPUNIT_ASSERT_EQUAL_MESSAGE
+      //  ( "FOLDER_IOVTABLENAME", string(""), 
+      //    row["FOLDER_IOVTABLENAME"].data<std::string>() );
+      CPPUNIT_ASSERT_MESSAGE
+        ( "FOLDER_IOVTABLENAME", row["FOLDER_IOVTABLENAME"].isNull() );
+    } catch ( std::exception& e ) {
+      std::cout << "Exception caught: " << e.what() << std::endl;
+      throw;     
+    }
+  }
+
+
+  /// Tests dropDatabase
+  void test_dropDatabase() {
+    std::vector<string> folderNames;
+    folderNames.push_back( "/f1" );
+    folderNames.push_back( "/f2" );
+    folderNames.push_back( "/f3" );
+    folderNames.push_back( "/f4" );
+    std::vector<string> objectTables;
+
+    CoralApplication app;
+    IDatabaseSvc& dbSvc = app.databaseService();
+    dbSvc.dropDatabase( m_connectionString );
+    m_db = dbSvc.createDatabase( m_connectionString );
+    ralDb = dynamic_cast<RalDatabase*>(m_db.get());
+    
+    for ( std::vector<string>::const_iterator f = folderNames.begin();
+          f != folderNames.end();
+          ++f ) {
+      IFolderPtr folder = ralDb->createFolder( *f, payloadSpec );
+      RelationalFolder* rf = dynamic_cast<RelationalFolder*>(folder.get());
+      objectTables.push_back( rf->objectTableName() );
+    }
+    
+    ralDb->dropDatabase();
+    
+    bool readOnly = true;
+    RelationalTransaction transaction( ralDb->transactionMgr(), readOnly );
+    coral::ISessionProxy& session = ralDb->session();
+    coral::ISchema& schema = session.nominalSchema();
+    //coral::ISchema& schema = ralDb->session().nominalSchema();
+    
+    CPPUNIT_ASSERT_MESSAGE( "main table deleted",
+                            ! schema.existsTable( ralDb->mainTableName() ) );
+    
+    string folderSeqName = 
+      RelationalNodeTable::sequenceName( ralDb->nodeTableName() );
+    CPPUNIT_ASSERT_MESSAGE( "sequence table deleted",
+                            ! schema.existsTable( folderSeqName ) );
+    
+    CPPUNIT_ASSERT_MESSAGE( "folder table deleted",
+                        ! schema.existsTable( ralDb->nodeTableName() ) );
+    
+    for ( std::vector<string>::const_iterator objTable = objectTables.begin();
+          objTable != objectTables.end();
+          ++objTable ) {
+      CPPUNIT_ASSERT_MESSAGE( *objTable + " table deleted",
+                              ! schema.existsTable( *objTable ) );
+    }
+
+    CPPUNIT_ASSERT_MESSAGE
+      ( "tag table deleted",
+        ! schema.existsTable( ralDb->globalTagTableName() ) );
+    
+    CPPUNIT_ASSERT_MESSAGE
+      ( "tag2tag table deleted",
+        ! schema.existsTable( ralDb->tag2TagTableName() ) );
+    
+  }
+  
+  /// Tests uppercasing of user provided connect strings
+  /// TEMPORARY! AV 04.04.05
+  /// This test is no longer relevant: input dbname must be uppercase!
+  /*
+  const std::string lowercaseString( const std::string& aString ) {
+    std::string aStringLow = aString;
+    std::transform 
+      ( aStringLow.begin(), aStringLow.end(), aStringLow.begin(), tolower );
+    return aStringLow;
+  }
+  void test_dbName_caseInsensitivity() {
+    RelationalDatabaseId id( m_connectionString );
+    string newId = id.technology() + "://";
+    newId += id.server() + ";";
+    newId += "schema=" + id.schema() + ";";
+    if ( id.user() != "" ) {
+      newId += "user=" + id.user() + ";";
+      newId += "password=" + id.password() + ";";
+    }    
+    newId += "dbname=" + lowercaseString( id.dbName() );
+    
+    CoralApplication app;
+    IDatabaseSvc& dbSvc = app.databaseService();
+    dbSvc.dropDatabase( newId );
+    m_db = dbSvc.createDatabase( newId );
+    ralDb = dynamic_cast<RalDatabase*>(m_db.get());
+
+    m_db->createFolder( "/sv", payloadSpec );
+    
+    CPPUNIT_ASSERT_MESSAGE
+      ( "object table existence",
+        ralDb->queryMgr().existsTable( uppercaseString( id.dbName() ) 
+        + "_F0001_IOVS" ) );
+    
+    m_db->createFolder( "/mv", payloadSpec, "desc", 
+                      FolderVersioning::MULTI_VERSION );
+
+    CPPUNIT_ASSERT_MESSAGE
+      ( "object table existence",
+        ralDb->queryMgr().existsTable( uppercaseString( id.dbName() ) 
+        + "_F0002_IOVS" ) );
+
+    CPPUNIT_ASSERT_MESSAGE
+      ( "tag table existence",
+        ralDb->queryMgr().existsTable( uppercaseString( id.dbName() ) 
+        + "_F0002_TAGS" ) );
+
+    CPPUNIT_ASSERT_MESSAGE
+      ( "iov2tag table existence",
+        ralDb->queryMgr().existsTable( uppercaseString( id.dbName() ) 
+        + "_F0002_IOV2TAG" ) );
+  }
+  */  
+
+  /// Tests the length of database names
+  void test_dbNameLength() {
+    RelationalDatabaseId id( m_connectionString );
+    string newId;
+    if ( id.alias().empty() ) {
+      newId = id.technology() + "://";
+      newId += id.server() + ";";
+      newId += "schema=" + id.schema() + ";";
+      if ( id.user() != "" ) {
+        newId += "user=" + id.user() + ";";
+        newId += "password=" + id.password() + ";";
+      }    
+      newId += "dbname=123456789;";
+    } else {
+      newId = id.alias() + "/123456789";
+    }
+    try {
+      CoralApplication app;
+      IDatabaseSvc& dbSvc = app.databaseService();
+      dbSvc.dropDatabase( newId );
+      m_db = dbSvc.createDatabase( newId );
+      CPPUNIT_ASSERT_MESSAGE( "exception expected", false );
+    } catch ( RelationalException& e ) {
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "exception caught",
+          string( "Invalid COOL database name '123456789': "
+                  "the database name length must not exceed 8 characters" ),
+          string( e.what() ) );    
+    }
+  }
+  
+  /// Tests that database names are uppercase
+  void test_dbNameUppercase() {
+    RelationalDatabaseId id( m_connectionString );
+    string newId;
+    if ( id.alias().empty() ) {
+      newId = id.technology() + "://";
+      newId += id.server() + ";";
+      newId += "schema=" + id.schema() + ";";
+      if ( id.user() != "" ) {
+        newId += "user=" + id.user() + ";";
+        newId += "password=" + id.password() + ";";
+      }    
+      newId += "dbname=aBcDeFgH;";
+    } else {
+      newId = id.alias() + "/aBcDeFgH";
+    }
+    try {
+      CoralApplication app;
+      IDatabaseSvc& dbSvc = app.databaseService();
+      dbSvc.dropDatabase( newId );
+      m_db = dbSvc.createDatabase( newId );
+      CPPUNIT_ASSERT_MESSAGE( "exception expected", false );
+    } catch ( RelationalException& e ) {
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "exception caught",
+          string( "Invalid COOL database name 'aBcDeFgH': "
+                  "the database name must be UPPERCASE" ),
+          string( e.what() ) );
+    }
+  }
+  
+  /// Tests that database names only contain letters and numbers
+  void test_dbNameLettersAndNumbers() {
+    RelationalDatabaseId id( m_connectionString );
+    string newId;
+    if ( id.alias().empty() ) {
+      newId = id.technology() + "://";
+      newId += id.server() + ";";
+      newId += "schema=" + id.schema() + ";";
+      if ( id.user() != "" ) {
+        newId += "user=" + id.user() + ";";
+        newId += "password=" + id.password() + ";";
+      }    
+      newId += "dbname=ABCD#FGH;";
+    } else {
+      newId = id.alias() + "/ABCD#FGH";
+    }
+    try {
+      CoralApplication app;
+      IDatabaseSvc& dbSvc = app.databaseService();
+      dbSvc.dropDatabase( newId );
+      m_db = dbSvc.createDatabase( newId );
+      CPPUNIT_ASSERT_MESSAGE( "exception expected", false );
+    } catch ( RelationalException& e ) {
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "exception caught",
+          string( "Invalid COOL database name 'ABCD#FGH': "
+                  "the database name must contain only letters, numbers" 
+                  " or the '_' character" ),
+          string( e.what() ) );
+    }
+  }
+
+
+  /// Tests that database names start with a letter
+  void test_dbNameStartsWithLetter() {
+    RelationalDatabaseId id( m_connectionString );
+    string newId;
+    if ( id.alias().empty() ) {
+      newId = id.technology() + "://";
+      newId += id.server() + ";";
+      newId += "schema=" + id.schema() + ";";
+      if ( id.user() != "" ) {
+        newId += "user=" + id.user() + ";";
+        newId += "password=" + id.password() + ";";
+      }    
+      newId += "dbname=1BCDEFGH;";
+    } else {
+      newId = id.alias() + "/1BCDEFGH";
+    }
+    try {
+      CoralApplication app;
+      IDatabaseSvc& dbSvc = app.databaseService();
+      dbSvc.dropDatabase( newId );
+      m_db = dbSvc.createDatabase( newId );
+      CPPUNIT_ASSERT_MESSAGE( "exception expected", false );
+    } catch ( RelationalException& e ) {
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "exception caught",
+          string( "Invalid COOL database name '1BCDEFGH': "
+                  "the database name must start with a letter" ),
+          string( e.what() ) );
+    }
+  }
+  
+
+  /// Tests openDatabase
+  void test_openDatabase_rw() {
+    try {
+      CoralApplication app;
+      IDatabaseSvc& dbSvc = app.databaseService();
+      dbSvc.dropDatabase( m_connectionString );
+      dbSvc.createDatabase( m_connectionString );
+      m_db =  dbSvc.openDatabase( m_connectionString, false );
+      CPPUNIT_ASSERT( m_db.get() != 0 );
+      CPPUNIT_ASSERT( m_db->isOpen() );
+    } catch ( std::exception& e ) {
+      std::cout << "Exception caught: " << e.what() << std::endl;
+      throw;     
+    }
+  }
+  
+  /// Tests openDatabase
+  void test_openDatabase_ro() {
+    try {
+      CoralApplication app;
+      IDatabaseSvc& dbSvc = app.databaseService();
+      dbSvc.dropDatabase( m_connectionString );
+      dbSvc.createDatabase( m_connectionString );
+      m_db =  dbSvc.openDatabase( m_connectionString );
+      CPPUNIT_ASSERT( m_db.get() != 0 );
+      CPPUNIT_ASSERT( m_db->isOpen() );
+    } catch ( std::exception& e ) {
+      std::cout << "Exception caught: " << e.what() << std::endl;
+      throw;     
+    }
+  }
+  
+  /// Tests createDatabase
+  void test_createDatabase() {
+    try {
+      CoralApplication app;
+      IDatabaseSvc& dbSvc = app.databaseService();
+      dbSvc.dropDatabase( m_connectionString );
+      m_db = dbSvc.createDatabase( m_connectionString );
+      CPPUNIT_ASSERT( m_db.get() != 0 );
+      CPPUNIT_ASSERT( m_db->isOpen() );
+      {
+        ralDb = dynamic_cast<RalDatabase*>(m_db.get());
+        RelationalDatabaseId id( m_connectionString );
+        std::string m_coolDBName = id.dbName();
+        RelationalTransaction transaction( ralDb->transactionMgr() );    
+        CPPUNIT_ASSERT
+          ( ralDb->queryMgr().existsTable( m_coolDBName + "_DB_ATTRIBUTES" ) );
+        CPPUNIT_ASSERT
+          ( ralDb->queryMgr().existsTable( m_coolDBName + "_F0000_TAGS_SEQ" ) );
+        CPPUNIT_ASSERT
+          ( ralDb->queryMgr().existsTable( m_coolDBName + "_NODES" ) );
+        CPPUNIT_ASSERT
+          ( ralDb->queryMgr().existsTable( m_coolDBName + "_NODES_SEQ" ) );
+        CPPUNIT_ASSERT
+          ( ralDb->queryMgr().existsTable( m_coolDBName + "_TAG2TAG" ) );
+        CPPUNIT_ASSERT
+          ( ralDb->queryMgr().existsTable( m_coolDBName + "_TAG2TAG_SEQ" ) );
+        CPPUNIT_ASSERT
+          ( ralDb->queryMgr().existsTable( m_coolDBName + "_TAGS" ) );
+        transaction.commit();
+      }    
+    } catch ( std::exception& e ) {
+      std::cout << "Exception caught: " << e.what() << std::endl;
+      throw;     
+    }
+  }
+  
+  
+  /// setup the database
+  /// This code is not in setup(), because some of its methods
+  /// need to be tested in this unit test class and therefore the
+  /// setup() method that is run before each test cannot rely on them
+  void setupDb() {
+    try {
+      createDB();
+      openDB(false);
+      ralDb = dynamic_cast<RalDatabase*>(m_db.get());
+    } catch ( std::exception& e ) {
+      std::cout << "Exception caught in setupDb(): " << e.what() << std::endl;
+      throw;     
+    }
+  }
+  
+  
+  /// Utility method to return a dummy object with a distinct payload
+  /// (determined by 'index') for a given set of since/until/channel
+  RelationalObjectPtr dummyObject( int index,
+                                   const ValidityKey& since,
+                                   const ValidityKey& until,
+                                   const ChannelId& channel = 0 ) {
+    RelationalObjectPtr 
+      obj( new RelationalObject( since, 
+                                 until,
+                                 dummyPayload( index ),
+                                 channel ) );
+    return obj;
+  }
+  
+  
+  /// Utility method to generate a distinct payload for a given index
+  Record dummyPayload( int index ) 
+  {
+    Record payload( payloadSpec );
+    payload["I"].setValue<Int32>( index );
+    std::stringstream s;
+    s << "Object " << index;
+    payload["S"].setValue<String255>( s.str() );
+    payload["X"].setValue<Float>( (float)(index/1000.) );
+    return payload;
+  }
+  
+
+  void setUp() {  
+  }
+  
+  
+  void tearDown() {
+    forceDisconnect();
+  }
+
+};
+
+
+CPPUNIT_TEST_SUITE_REGISTRATION( RalDatabaseTest );
+
+}
+
+COOLTEST_MAIN(RalDatabaseTest)
diff --git a/RelationalCool/tests/RalDatabaseSvc/test_RalDatabaseSvc.cpp b/RelationalCool/tests/RalDatabaseSvc/test_RalDatabaseSvc.cpp
new file mode 100644
index 000000000..3e4adb146
--- /dev/null
+++ b/RelationalCool/tests/RalDatabaseSvc/test_RalDatabaseSvc.cpp
@@ -0,0 +1,137 @@
+// $Id: test_RalDatabaseSvc.cpp,v 1.35 2008-04-11 10:02:51 marcocle Exp $
+
+// Include files
+#include "CoolDBUnitTest.h"
+#include "../Common/CppUnit_headers.h" // Disable CppUnit header warnings
+#include "CoolKernel/IDatabaseSvc.h"
+#include "CoolKernel/Exception.h"
+#include <iostream>
+
+// Local include files
+#include "src/CoralApplication.h"
+#include "src/VersionInfo.h"
+
+// Forward declaration
+namespace cool {
+  class RalDatabaseSvcTest;
+}
+
+//-----------------------------------------------------------------------------
+
+class cool::RalDatabaseSvcTest : public cool::CoolDBUnitTest {
+  
+  CPPUNIT_TEST_SUITE( RalDatabaseSvcTest );
+
+  CPPUNIT_TEST( test_getService );
+  CPPUNIT_TEST( test_serviceVersion );
+  CPPUNIT_TEST( test_createDatabase );
+  CPPUNIT_TEST( test_openDatabase );
+  CPPUNIT_TEST( test_openDatabase_rw );
+  CPPUNIT_TEST( test_openDatabase_nonexisting );
+
+  CPPUNIT_TEST_SUITE_END();
+		
+public:
+
+  /// Default constructor
+  RalDatabaseSvcTest():
+    // this test is testing the service, so I cannot get it in the constructor
+    cool::CoolDBUnitTest(false) 
+  {}
+  
+  void setUp() {
+  }
+		
+  void tearDown() {
+    dropDB();
+  }
+  
+  
+  /// Tests openDatabase on a nonexisting database
+  void test_openDatabase_nonexisting() 
+  {
+    CoralApplication app;
+    IDatabaseSvc& dbSvc = app.databaseService();
+    dbSvc.dropDatabase( m_connectionString );
+    CPPUNIT_ASSERT_THROW( dbSvc.openDatabase( m_connectionString ),
+                          DatabaseDoesNotExist );
+  }
+		
+  
+  /// Tests openDatabase
+  void test_openDatabase() {
+    try {
+      CoralApplication app;
+      IDatabaseSvc& dbSvc = app.databaseService();
+      //std::cout << "Drop database..." << std::endl;
+      dbSvc.dropDatabase( m_connectionString );
+      //std::cout << "Drop database... OK" << std::endl;
+      //std::cout << "Create database..." << std::endl;
+      dbSvc.createDatabase( m_connectionString );      
+      //std::cout << "Create database... OK" << std::endl;
+      //std::cout << "Open database..." << std::endl;
+      m_db = dbSvc.openDatabase( m_connectionString, true );
+      //std::cout << "Open database... OK" << std::endl;
+      CPPUNIT_ASSERT( m_db.get() != 0 );
+    } catch ( std::exception& e ) {
+      std::cout << e.what() << std::endl;
+      throw;
+    }
+  }
+		
+  /// Tests openDatabase
+  void test_openDatabase_rw() {
+    try {
+      CoralApplication app;
+      IDatabaseSvc& dbSvc = app.databaseService();
+      dbSvc.dropDatabase( m_connectionString );
+      dbSvc.createDatabase( m_connectionString );      
+      m_db = dbSvc.openDatabase( m_connectionString, false );
+      CPPUNIT_ASSERT( m_db.get() != 0 );
+    } catch ( std::exception& e ) {
+      std::cout << e.what() << std::endl;
+      throw;
+    }
+  }
+  
+  /// Tests createDatabase
+  void test_createDatabase() {
+    try {
+      CoralApplication app;
+      IDatabaseSvc& dbSvc = app.databaseService();
+      dbSvc.dropDatabase( m_connectionString );
+      m_db = dbSvc.createDatabase( m_connectionString );
+      CPPUNIT_ASSERT( m_db.get() != 0 );
+    } catch ( std::exception& e ) {
+      std::cout << e.what() << std::endl;
+      throw;
+    }
+  }
+		
+  
+  /// Tests IDatabaseSvc::serviceVersion()
+  void test_serviceVersion() {
+    CoralApplication app;
+    IDatabaseSvc& dbSvc = app.databaseService();
+    CPPUNIT_ASSERT_EQUAL_MESSAGE
+      ( "IDatabaseSvc version",
+        std::string(VersionInfo::release),
+        dbSvc.serviceVersion() );
+  }
+  
+  
+  /// Tests the getService method for the RalDatabaseSvc
+  /// (the seal plugin/context mechanism)
+  void test_getService() {
+    CoralApplication app;
+    app.databaseService();
+    //CPPUNIT_ASSERT_MESSAGE( "reach this point without exception", true );
+  }
+  
+};
+
+CPPUNIT_TEST_SUITE_REGISTRATION( cool::RalDatabaseSvcTest );
+
+//-----------------------------------------------------------------------------
+
+COOLTEST_MAIN(RalDatabaseSvcTest)
diff --git a/RelationalCool/tests/RalDatabase_extendedSpec/test_RalDatabase_extendedSpec.cpp b/RelationalCool/tests/RalDatabase_extendedSpec/test_RalDatabase_extendedSpec.cpp
new file mode 100644
index 000000000..dc9b39036
--- /dev/null
+++ b/RelationalCool/tests/RalDatabase_extendedSpec/test_RalDatabase_extendedSpec.cpp
@@ -0,0 +1,1181 @@
+// -*- coding: iso-8859-1 -*-
+// $Id: test_RalDatabase_extendedSpec.cpp,v 1.101 2008-05-15 16:32:33 avalassi Exp $
+
+// Include files
+#include "CoolKernel/IDatabaseSvc.h"
+#include "CoolKernel/IField.h"
+#include "CoolKernel/IObject.h"
+#include "CoolKernel/Record.h"
+#include "CoolKernel/RecordException.h"
+#include "CoolKernel/RecordSpecification.h"
+#include "CoralBase/Attribute.h" 
+#include "CoralBase/AttributeListException.h" 
+
+// Local include files
+#include "CppUnit_headers.h" // tests/Common - disable CppUnit header warnings
+#include "src/CoralApplication.h"
+#include "src/RelationalException.h"
+#include "src/RelationalFolder.h"
+#include "src/RelationalDatabase.h"
+#include "src/RelationalNodeTable.h"
+#include "src/RalDatabase.h"
+#include "src/SimpleObject.h"
+
+// ---- these things are needed to force a drop of the connection
+#include "src/RalDatabaseSvc.h"
+#include "RelationalAccess/IConnectionService.h"
+#include "RelationalAccess/IConnectionServiceConfiguration.h"
+
+namespace cool {
+  const char* COOLTESTDB = "COOLTESTDB";
+  // This line is to avoid error "qualified name does not name a class"
+  // on gcc 4.1 
+  class RalDatabaseTest_extendedSpec;
+}
+
+//-----------------------------------------------------------------------------
+
+class cool::RalDatabaseTest_extendedSpec : public CppUnit::TestFixture {
+		
+  CPPUNIT_TEST_SUITE( RalDatabaseTest_extendedSpec );  
+
+  CPPUNIT_TEST( test_payloadSpecDescription );
+  CPPUNIT_TEST( test_payloadSpecTooManyFields );
+  CPPUNIT_TEST( test_payloadSpecTooManyBlobFields );
+  CPPUNIT_TEST( test_payloadSpecTooManyString255Fields );
+  CPPUNIT_TEST( test_payloadSpecInvalidFieldName );
+
+  CPPUNIT_TEST( test_payloadSpecOver8000Bytes ); // fails on MySQL (bug #24646)
+
+  CPPUNIT_TEST( test_default_string4000 );
+  
+  CPPUNIT_TEST( test_extSpec_string255 );
+
+  CPPUNIT_TEST( test_default_UInt63 );
+
+  //CPPUNIT_TEST_EXCEPTION( test_unsupportedTypesToken, 
+  //                        coral::AttributeListException );
+
+  //CPPUNIT_TEST_EXCEPTION( test_unsupportedTypesChar,
+  //                        RelationalTypeConverterInvalidCppType );
+  
+  //CPPUNIT_TEST_EXCEPTION( test_unsupportedTypesLongDouble, 
+  //                        RelationalTypeConverterInvalidCppType );
+  
+  //CPPUNIT_TEST_EXCEPTION( test_unsupportedTypesLongLong,
+  //                        RelationalTypeConverterInvalidCppType );
+  
+  //CPPUNIT_TEST_EXCEPTION( test_unsupportedTypesVector, 
+  //                        coral::AttributeListException );
+  
+  CPPUNIT_TEST( test_supportedTypes );
+  
+  CPPUNIT_TEST( test_extSpec_allStrings );
+  
+  CPPUNIT_TEST( test_storagObject_special_characters );
+
+  CPPUNIT_TEST( test_emptyString );
+
+  CPPUNIT_TEST( test_nullCharInString );
+
+  CPPUNIT_TEST( test_blob64kOver64k );
+  CPPUNIT_TEST( test_blob16MOver64k );
+
+  CPPUNIT_TEST( test_emptyBlob );
+
+  CPPUNIT_TEST_SUITE_END();
+		
+public:
+  
+  std::string connectString;
+  IDatabasePtr db;    
+  RalDatabase* ralDb; // safely cast pointer to db
+  
+  RecordSpecification payloadSpec;
+  
+  RalDatabaseTest_extendedSpec() 
+  : payloadSpec() {
+    
+    payloadSpec.extend("I",StorageType::Int32);
+    payloadSpec.extend("S",StorageType::String255);
+    payloadSpec.extend("X",StorageType::Float);
+    
+    if ( getenv( COOLTESTDB ) ) {
+      connectString = getenv( COOLTESTDB );
+    } else {
+      std::cout << "Please provide a connect string by "
+      << "specifying one in the environment variable COOLTESTDB, e.g." 
+      << std::endl;
+      std::cout << "setenv COOLTESTDB "
+      << "\"oracle://devdb10;schema=lcg_cool;dbname=COOLTEST\"" << std::endl;
+      std::cout << "Aborting test" << std::endl;
+      exit(-1);
+    }
+  }
+  
+  ~RalDatabaseTest_extendedSpec() {}
+  
+  
+  /// Tests storage and retrieval of non-ascii and 'sql-tricky' characters
+  void test_storagObject_special_characters() {
+    RecordSpecification spec;
+    spec.extend( "quotes", StorageType::String255 );
+    spec.extend( "umlauts", StorageType::String255 );
+    spec.extend( "diacriticals", StorageType::String255 );
+    
+    coral::AttributeList payload = Record( spec ).attributeList();
+    IFolderPtr folder = ralDb->createFolder( "/myfolder", spec );
+
+    
+    std::string umlauts = "umlauts ";
+    // octal representation of umlauts in iso-8895-1
+    // "������������"
+    umlauts += "\304\313\317\326\334\337\344\353\357\366\374\377";
+    umlauts += " in string";
+    std::string diacriticals = "diacriticals ";
+    // octal representation of other accents in iso-8895-1
+    // "��������������������������������������������������"
+    diacriticals += "\300\301\302\303\305\306\307\310\311\312\314\315\316\320";
+    diacriticals += "\321\322\323\324\325\330\331\332\333\335\336\340\341\342";
+    diacriticals += "\343\345\346\347\350\351\352\354\355\356\360\361\362\363";
+    diacriticals += "\364\365\370\371\372\373\375\376";
+    diacriticals += " in string";
+
+    payload[ "quotes" ].setValue<String255>
+      ( "quotes '\" in string" );
+    payload[ "umlauts" ].setValue<String255>
+      ( umlauts );
+    payload[ "diacriticals" ].setValue<String255>
+      ( diacriticals );
+    folder->storeObject( 5, 15, payload, 0 );
+    
+    IObjectPtr obj = folder->findObject( 10, 0 );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE
+      ( "quotes string",
+        std::string( "quotes '\" in string" ),
+        obj->payload()["quotes"].data<String255>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE
+      ( "umlauts string",
+        umlauts,
+        obj->payload()["umlauts"].data<String255>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE
+      ( "diacriticals string",
+        diacriticals,
+        obj->payload()["diacriticals"].data<String255>() );
+    
+  }
+  
+  
+  /// Tests creation of a folder with as many columns as there are
+  /// C++ types supported in COOL (using default payload hints)
+  /// [Test all types in pool/AttributeList/src/AttributePredefinedTypes.cpp]
+  void test_supportedTypes() {
+
+    try {
+      
+      // Create a folder with 12 payload columns
+      typedef std::pair<std::string,StorageType::TypeId> pair_type;
+      std::vector<pair_type> all_types;
+      
+      all_types.push_back(pair_type("A_BOOL",
+                                    StorageType::Bool));
+      //all_types.push_back(pair_type("A_CHAR",StorageType::Char)); // RAL MySQL error on retrieval
+      all_types.push_back(pair_type("A_UCHAR",
+                                    StorageType::UChar));
+      all_types.push_back(pair_type("A_INT16",
+                                    StorageType::Int16));
+      all_types.push_back(pair_type("A_UINT16",
+                                    StorageType::UInt16));
+      all_types.push_back(pair_type("A_INT32",
+                                    StorageType::Int32));
+      all_types.push_back(pair_type("A_UINT32",
+                                    StorageType::UInt32));
+      all_types.push_back(pair_type("A_UINT63",
+                                    StorageType::UInt63));
+      all_types.push_back(pair_type("A_INT64",
+                                    StorageType::Int64));
+      //all_types.push_back(pair_type("A_UINT64",
+      //                              StorageType::UInt64)); // SQLite problems
+      all_types.push_back(pair_type("A_FLOAT",
+                                    StorageType::Float));
+      all_types.push_back(pair_type("A_DOUBLE",
+                                    StorageType::Double));
+      all_types.push_back(pair_type("A_STRING255",
+                                    StorageType::String255));
+      all_types.push_back(pair_type("A_STRING4K",
+                                    StorageType::String4k));
+      all_types.push_back(pair_type("A_STRING64K",
+                                    StorageType::String64k));
+      all_types.push_back(pair_type("A_STRING16M",
+                                    StorageType::String16M));  
+      all_types.push_back(pair_type("A_BLOB64K",
+                                    StorageType::Blob64k));  
+      all_types.push_back(pair_type("A_BLOB16M",
+                                    StorageType::Blob16M));  
+
+      RecordSpecification spec;
+      std::vector<pair_type>::iterator i;
+      for(i = all_types.begin(); i != all_types.end(); ++i ){
+        spec.extend(i->first,i->second);
+      }
+      IFolderPtr folder = ralDb->createFolder( "/myfolder", spec );
+      CPPUNIT_ASSERT( folder.get() != 0 );
+      
+      // Store some data into the IOV table
+      coral::AttributeList payload1 = Record( spec ).attributeList();
+      payload1[ "A_BOOL" ].data<Bool>() = false;
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "false=0", false, payload1["A_BOOL"].data<Bool>());
+      //payload1[ "A_CHAR" ]
+      //  .setValue<char>( 'a' );      // THIS MUST BE CHARACTER DATA
+      //  .setValue<char>( CHAR_MIN ); // -128 (if signed) 
+      payload1[ "A_UCHAR" ].data<UChar>() = 0;
+      payload1[ "A_INT16" ].data<Int16>() = Int16Min; // -32768
+      payload1[ "A_UINT16" ].data<UInt16>() = 0;
+      payload1[ "A_INT32" ].data<Int32>() = Int32Min; // -2147483648
+      payload1[ "A_UINT32" ].data<UInt32>() = 0;
+      payload1[ "A_UINT63" ].data<UInt63>() = 0;
+      payload1[ "A_INT64" ].data<Int64>() = Int64Min; // -9223372036854775808: OCI-22053!
+      //payload1[ "A_UINT64" ].data<UInt64>() = 0;
+      payload1[ "A_FLOAT" ].data<Float>() = (Float)0.123456789012345678901234567890;
+      payload1[ "A_DOUBLE" ].data<Double>() = 0.123456789012345678901234567890;
+      payload1[ "A_STRING255" ].data<String255>() = "low values";
+      payload1[ "A_STRING4K" ].data<String4k>() = "low values";
+      payload1[ "A_STRING64K" ].data<String64k>() = "low values";
+      payload1[ "A_STRING16M" ].data<String16M>() = "low values";
+      payload1[ "A_BLOB64K" ].data<Blob64k>().resize(100);
+      payload1[ "A_BLOB16M" ].data<Blob16M>().resize(100);
+      unsigned char * ptr64k = static_cast<unsigned char *>
+        (payload1[ "A_BLOB64K" ].data<Blob64k>().startingAddress());
+      for ( int i = 0 ; i < 100; ++i ) ptr64k[i] = 0;
+      unsigned char * ptr16M = static_cast<unsigned char *>
+        (payload1[ "A_BLOB16M" ].data<Blob16M>().startingAddress());
+      for ( int i = 0 ; i < 100; ++i ) ptr16M[i] = 0;
+      folder->storeObject( 5, 15, payload1, 0 ); 
+      
+      // Store some data into the IOV table
+      coral::AttributeList payload2 = Record( spec ).attributeList();
+      payload2[ "A_BOOL" ].data<Bool>() = true;
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "false=0", true, payload2["A_BOOL"].data<Bool>());
+      //payload2[ "A_CHAR" ]
+      //  .setValue<char>( 'Z' );      // THIS MUST BE CHARACTER DATA
+      //  .setValue<char>( CHAR_MAX ); // -128 (if signed) 
+      payload2[ "A_UCHAR" ].data<UChar>() = UCHAR_MAX; // 255
+      payload2[ "A_INT16" ].data<Int16>() = Int16Max; // 32767
+      payload2[ "A_UINT16" ].data<UInt16>() = UInt16Max; // 65535
+      payload2[ "A_INT32" ].data<Int32>() = Int32Max; // 2147483647
+      payload2[ "A_UINT32" ].data<UInt32>() = UInt32Max; // 4294967295
+      payload2[ "A_UINT63" ].data<UInt63>() = Int64Max; // 9223372036854775807
+      payload2[ "A_INT64" ].data<Int64>() = Int64Max; // 9223372036854775807
+      //payload2[ "A_UINT64" ].data<UInt64>() = UInt64Max; // 18446744073709551615
+      payload2[ "A_FLOAT" ].data<Float>() = (Float)0.987654321098765432109876543210;
+      payload2[ "A_DOUBLE" ].data<Double>() = 0.987654321098765432109876543210;
+      payload2[ "A_STRING255" ].data<String255>() = "HIGH VALUES";
+      payload2[ "A_STRING4K" ].data<String4k>() = "HIGH VALUES";
+      payload2[ "A_STRING64K" ].data<String64k>() = "HIGH VALUES";
+      payload2[ "A_STRING16M" ].data<String16M>() = "HIGH VALUES";
+      payload2[ "A_BLOB64K" ].data<Blob64k>().resize(100);
+      payload2[ "A_BLOB16M" ].data<Blob16M>().resize(100);
+      ptr64k = static_cast<unsigned char *>
+        (payload2[ "A_BLOB64K" ].data<Blob64k>().startingAddress());
+      for ( int i = 0 ; i < 100; ++i ) ptr64k[i] = 0xff;
+      ptr16M = static_cast<unsigned char *>
+        (payload2[ "A_BLOB16M" ].data<Blob16M>().startingAddress());
+      for ( int i = 0 ; i < 100; ++i ) ptr16M[i] = 0xff;
+      folder->storeObject( 15, 25, payload2, 0 );
+
+      // Retrieve back the two objects
+      IObjectPtr obj1 = folder->findObject( 10, 0 );
+      CPPUNIT_ASSERT_MESSAGE( "retrieved object 1", obj1.get() != 0 );
+      IObjectPtr obj2 = folder->findObject( 20, 0 );
+      CPPUNIT_ASSERT_MESSAGE( "retrieved object 2", obj2.get() != 0 );
+      
+      // Printout for bool
+      if ( false ) {
+        std::cout << "Payload1 IN  -> " 
+                  << payload1["A_BOOL"].data<Bool>() << std::endl;
+        std::cout << "Payload1 OUT -> " 
+                  << obj1->payload()["A_BOOL"].data<Bool>() << std::endl;
+        std::cout << "Payload2 IN  -> " 
+                  << payload2["A_BOOL"].data<Bool>() << std::endl;
+        std::cout << "Payload2 OUT -> " 
+                  << obj2->payload()["A_BOOL"].data<Bool>() << std::endl;
+      }
+      
+      // Printout for unsigned char
+      if ( false ) {
+        UChar u1in = payload1["A_UCHAR"].data<UChar>();
+        UChar u1out = obj1->payload()["A_UCHAR"].data<UChar>();
+        UChar u2in = payload2["A_UCHAR"].data<UChar>();
+        UChar u2out = obj2->payload()["A_UCHAR"].data<UChar>();
+        std::cout << "Payload1 IN  -> " << u1in << std::endl;
+        std::cout << "Payload1 OUT -> " << u1out << std::endl;
+        std::cout << "Payload2 IN  -> " << u2in << std::endl;
+        std::cout << "Payload2 OUT -> " << u2out << std::endl;
+        std::cout << "Payload1 IN  (int) -> " << (int)u1in << std::endl;
+        std::cout << "Payload1 OUT (int) -> " << (int)u1out << std::endl;
+        std::cout << "Payload2 IN  (int) -> " << (int)u2in << std::endl;
+        std::cout << "Payload2 OUT (int) -> " << (int)u2out << std::endl;
+      }
+      
+      // Printout for floats and doubles
+      if ( false ) {
+        Float f_in = payload1["A_FLOAT"].data<Float>();
+        Double d_in = payload1["A_DOUBLE"].data<Double>();
+        Float f_out = obj1->payload()["A_FLOAT"].data<Float>();
+        Double d_out = obj1->payload()["A_DOUBLE"].data<Double>();
+        int p = std::cout.precision();
+        std::cout.precision(30);
+        std::cout << "float1 IN   -> " << f_in << std::endl;
+        std::cout << "float1 OUT  -> " << f_out << std::endl;
+        std::cout << "double1 IN  -> " << d_in << std::endl;
+        std::cout << "double1 OUT -> " << d_out << std::endl;
+        std::cout.precision(p);
+      }
+      
+      // Compare the input payload to the retrieved payload for object 1 and 2
+      for ( unsigned int i=0; i<spec.size(); i++ ) 
+      {  
+        const IFieldSpecification& fldSpec = spec[i];
+        std::string val1_in,val2_in;
+        std::string val1_out,val2_out;
+        
+        // Special treatment for floats: compare with 6 digit precision
+        // TEMPORARY! You should be able to use higher precision!
+        if ( fldSpec.storageType() == StorageType::Float ) {
+          unsigned long fPrec = 6;
+          Float f_in = payload1[ fldSpec.name() ].data<Float>();
+          Float f_out = obj1->payload()[ fldSpec.name() ].data<Float>();
+          std::ostringstream s1_in, s1_out;
+          s1_in.precision(fPrec);
+          s1_out.precision(fPrec);
+          s1_in << f_in;
+          s1_out << f_out;
+          val1_in = s1_in.str();
+          val1_out = s1_out.str();
+          
+          f_in = payload2[ fldSpec.name() ].data<Float>();
+          f_out = obj2->payload()[ fldSpec.name() ].data<Float>();
+          std::ostringstream s2_in, s2_out;
+          s2_in.precision(fPrec);
+          s2_out.precision(fPrec);
+          s2_in << f_in;
+          s2_out << f_out;
+          val2_in = s2_in.str();
+          val2_out = s2_out.str();
+        }
+        
+        // Special treatment for doubles: compare with 15 digit precision
+        // TEMPORARY! You should be able to use higher precision!
+        else if ( fldSpec.storageType() == StorageType::Double ) {
+          unsigned long dPrec = 15;
+          Double d_in = payload1[ fldSpec.name() ].data<Double>();
+          Double d_out = obj1->payload()[ fldSpec.name() ].data<Double>();
+          std::ostringstream s1_in,s1_out;
+          s1_in.precision(dPrec);
+          s1_out.precision(dPrec);
+          s1_in << d_in;
+          s1_out << d_out;
+          val1_in = s1_in.str();
+          val1_out = s1_out.str();
+          
+          d_in = payload2[ fldSpec.name() ].data<Double>();
+          d_out = obj2->payload()[ fldSpec.name() ].data<Double>();
+          std::ostringstream s2_in,s2_out;
+          s2_in.precision(dPrec);
+          s2_out.precision(dPrec);
+          s2_in << d_in;
+          s2_out << d_out;
+          val2_in = s2_in.str();
+          val2_out = s2_out.str();
+        }
+        
+        else if ( fldSpec.storageType() == StorageType::Blob64k ) {
+          // use native comparison for blobs
+          payload1[ fldSpec.name() ].data<Blob64k>() == 
+            payload2[ fldSpec.name() ].data<Blob64k>();
+        }
+        
+        else if ( fldSpec.storageType() == StorageType::Blob16M ) {
+          // use native comparison for blobs
+          payload1[ fldSpec.name() ].data<Blob16M>() == 
+            payload2[ fldSpec.name() ].data<Blob16M>();
+        }
+        
+        // Default treatment for all but floats and doubles: compare as strings
+        else 
+        {
+          val1_in = toString( payload1[ fldSpec.name() ] );
+          val1_out = toString( obj1->payload()[ fldSpec.name() ].attribute() );
+          val2_in = toString( payload2[ fldSpec.name() ] );
+          val2_out = toString( obj2->payload()[ fldSpec.name() ].attribute() );
+        }
+        
+        // Compare expected and actual values
+        CPPUNIT_ASSERT_EQUAL_MESSAGE
+          ( std::string( "payload1 ['" )
+            + fldSpec.name() + "'] of type '" 
+            + fldSpec.storageType().name() + "'", 
+            val1_in, val1_out );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE
+          ( std::string( "payload2 ['" ) 
+            + fldSpec.name() + "'] of type '" 
+            + fldSpec.storageType().name() + "'", 
+            val2_in, val2_out );
+      }
+      
+    } catch ( std::exception& e ) {
+      std::cout << "Exception caught: '" << e.what() << "'" << std::endl;
+      throw;
+    } catch ( ... ) {
+      std::cout << "UNKNOWN exception caught!" << std::endl;
+      throw;
+    }
+    
+  }
+  
+  /// Tests creation of a folder with a vector column - should fail
+  /// PORT: This test used to throw a RelationalTypeConverterInvalidCppType
+  /// exception from 'createFolder'. However in CORAL, Token is not a 
+  /// supported type and spec->extend( "A_VECTOR", "vector<string>" ) already
+  /// throws an exception.
+  /// Marco: With the new RecordSpecification, it is impossible to us an unsupported type
+//  void test_unsupportedTypesVector() {
+//    boost::shared_ptr<coral::AttributeListSpecification>
+//    spec( new coral::AttributeListSpecification(), releaser() );
+//    spec->extend( "A_VECTOR", "vector<string>" );
+//    IFolderPtr folder = ralDb->createFolder( "/myfolder", *spec );
+//  }
+
+
+  /// Tests creation of a folder with a Token column - should fail
+  /// PORT: This test used to throw a RelationalTypeConverterInvalidCppType
+  /// exception from 'createFolder'. However in CORAL, Token is not a 
+  /// supported type and spec->extend( "A_TOKEN", "Token" ) already throws
+  /// an exception.
+  /// Marco: With the new RecordSpecification, it is impossible to us an unsupported type
+//  void test_unsupportedTypesToken() {
+//    boost::shared_ptr<coral::AttributeListSpecification>
+//    spec( new coral::AttributeListSpecification(), releaser() );
+//    spec->extend( "A_TOKEN", "Token" );
+//    IFolderPtr folder = ralDb->createFolder( "/myfolder", *spec );
+//  }
+
+  /// Tests creation of a folder with a long long column - should fail
+  /// Marco: With the new RecordSpecification, it is impossible to us an unsupported type
+//  void test_unsupportedTypesLongLong() {
+//    boost::shared_ptr<coral::AttributeListSpecification>
+//    spec( new coral::AttributeListSpecification(), releaser() );
+//    spec->extend( "A_LONGLONG", "long long" );
+//    try {
+//      IFolderPtr folder = ralDb->createFolder( "/myfolder", *spec );
+//    } catch ( std::exception& /*e*/ ) {
+//      //std::cout << "Exception caught: '" << e.what() << "'" << std::endl;
+//      throw;
+//    }    
+//  }
+
+  /// Tests creation of a folder with a char column - should fail
+  /// Marco: With the new RecordSpecification, it is impossible to us an unsupported type
+//  void test_unsupportedTypesChar() {
+//    boost::shared_ptr<coral::AttributeListSpecification>
+//    spec( new coral::AttributeListSpecification(), releaser() );
+//    spec->extend( "A_CHAR", "char" );
+//    try {
+//      IFolderPtr folder = ralDb->createFolder( "/myfolder", *spec );
+//    } catch ( std::exception& /*e*/ ) {
+//      //std::cout << "Exception caught: '" << e.what() << "'" << std::endl;
+//      throw;
+//    }    
+//  }
+
+
+  /// Tests creation of a folder with a Token column - should fail
+  /// Marco: With the new RecordSpecification, it is impossible to us an unsupported type
+//  void test_unsupportedTypesLongDouble() {
+//    boost::shared_ptr<coral::AttributeListSpecification>
+//    spec( new coral::AttributeListSpecification(), releaser() );
+//    spec->extend( "A_LONGDOUBLE", "long double" );
+//    try {
+//      IFolderPtr folder = ralDb->createFolder( "/myfolder", *spec );
+//    } catch ( std::exception& /*e*/ ) {
+//      //std::cout << "Exception caught: '" << e.what() << "'" << std::endl;
+//      throw;
+//    }    
+//  }
+
+
+  /// Tests that storing a UInt63 larger than 2^63-1 fails
+  /// (default for both IOV boundaries and user payload UInt63)
+  void test_default_UInt63() {
+    RecordSpecification spec;
+    std::string attrName = "UInt63";
+    StorageType::TypeId attrType = StorageType::UInt63;
+    spec.extend( attrName, attrType );
+    IFolderPtr folder = db->createFolder( "/myfolder", spec );
+    // Insert an object with uInt64=2^63-1: this should not throw
+    coral::AttributeList payload = Record( spec ).attributeList();
+    UInt63 attrValue = Int64Max;
+    payload[ attrName ].data<UInt63>() = attrValue;
+    folder->storeObject( 0, 1, payload, 0 );
+    // Insert an object with uInt64=2^63: this should throw
+    attrValue = (UInt63)Int64Max+1;
+    payload[ attrName ].setValue( attrValue );
+    CPPUNIT_ASSERT_THROW( folder->storeObject( 1, 2, payload, 0 ),
+                          StorageTypeInvalidValue );
+//    std::string msg;
+//    try {
+//      std::string attrHint = 
+//        RelationalTypeConverter::defaultUserPayloadHintForCppType( attrType );
+//      RelationalTypeConverterInvalidCppValue e0 
+//        ( payload[attrName], attrHint, "" );
+//      msg = e0.what();
+//      folder->storeObject( 1, 2, payload, 0 );
+//    } catch ( StorageTypeInvalidValue &e ) {
+//      std::cout << "Exception caught: '" << e.what() << "'" << std::endl;
+//      CPPUNIT_ASSERT_EQUAL_MESSAGE
+//        ( "exception error message", msg, std::string( e.what() ) );
+//      throw;
+//    }
+  }
+
+
+  /// Tests creation of a folder with non-default maximum string length of 255
+  /// (default has been changed to 4000 for user payload strings)
+  /// Tests that storing a string of 300 characters fails
+  void test_extSpec_string255() {
+    // Create payload specification
+    RecordSpecification spec;
+    std::string attrName = "S";
+    StorageType::TypeId attrType = StorageType::String255;
+    spec.extend( attrName, attrType );
+    // Create folder with extended payload specification
+    IFolderPtr folder = ralDb->createFolder( "/myfolder", spec );
+    CPPUNIT_ASSERT( folder.get() != 0 );
+    // Insert an object with 300 characters: this should throw
+    coral::AttributeList payload = Record( spec ).attributeList();
+    payload[ attrName ].data<String255>() = std::string(300,'x');
+    CPPUNIT_ASSERT_THROW( folder->storeObject( 0, 1, payload, 0 ),
+                          StorageTypeInvalidValue );
+//    std::string msg;
+//    try {
+//      RelationalTypeConverterInvalidCppValue e0 
+//        ( payload[attrName], attrHint, "" );
+//      msg = e0.what();
+//      folder->storeObject( 0, 1, payload, 0 );
+//    } catch ( RelationalTypeConverterInvalidCppValue& e ) {
+//      CPPUNIT_ASSERT_EQUAL_MESSAGE
+//        ( "exception error message", msg, std::string( e.what() ) );
+//      throw;
+//    }
+  }
+  
+  /// Tests creation of a folder with four string columns of all supported 
+  /// maximum lengths (255, 4K, 64K, 16M) using the private API
+  void test_extSpec_allStrings() {
+    // Create extended payload specification
+    typedef std::pair<std::string,StorageType::TypeId> pair_type;
+    std::vector<pair_type> all_types;
+    all_types.push_back
+      (pair_type ("A_STRING255", StorageType::String255 ) );
+    all_types.push_back
+      (pair_type ("A_STRING4K",  StorageType::String4k ) );
+    all_types.push_back
+      (pair_type ("A_STRING64K", StorageType::String64k ) );
+    all_types.push_back
+      (pair_type ("A_STRING16M", StorageType::String16M ) );
+    RecordSpecification spec;
+    std::vector<pair_type>::iterator i;
+    for(i = all_types.begin(); i != all_types.end(); ++i ){
+      spec.extend(i->first,i->second);
+    }
+    IFolderPtr folder = ralDb->createFolder( "/myfolder", spec );
+    CPPUNIT_ASSERT( folder.get() != 0 );
+
+    coral::AttributeList payload = Record( spec ).attributeList();
+    for(i = all_types.begin(); i != all_types.end(); ++i ){
+      payload[i->first].data<std::string>() =
+        std::string(StorageType::storageType(i->second).maxSize(),'x');
+    }
+    folder->storeObject( 0, 100, payload, 0 );
+    // Retrieve IOVS from the folder
+    //std::cout << "MARCO: get object" << std::endl;
+    IObjectPtr obj = folder->findObject( 10, 0 );    
+    for(i = all_types.begin(); i != all_types.end(); ++i ){
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "Wrong number of char retrieved",
+          StorageType::storageType(i->second).maxSize(),
+          obj->payload()[i->first].data<std::string>().size() );
+    }
+  }
+
+  /// Tests that storing a string longer than 4000 characters fails,
+  /// while storing a 300 character string succeeds
+  /// (default has been changed to 4000 for user payload strings)
+  void test_default_string4000() {
+    RecordSpecification spec;
+    std::string attrName = "S";
+    StorageType::TypeId attrType = StorageType::String4k;
+    spec.extend( attrName, attrType );
+    IFolderPtr folder = db->createFolder( "/myfolder", spec );
+    // Insert an object with 300 characters: this should not throw
+    coral::AttributeList payload = Record( spec ).attributeList();
+    payload[ attrName ].data<std::string>() = std::string(300,'x');
+    folder->storeObject( 0, 1, payload, 0 );
+    // Insert an object with 5000 characters: this should throw
+    payload[ attrName ].data<std::string>() = std::string(5000,'x');
+    CPPUNIT_ASSERT_THROW( folder->storeObject( 1, 2, payload, 0 ),
+                          StorageTypeInvalidValue );
+//    std::string msg;
+//    try {
+//      std::string attrHint = 
+//        RelationalTypeConverter::defaultUserPayloadHintForCppType( attrType );
+//      RelationalTypeConverterInvalidCppValue e0 
+//        ( payload[attrName], attrHint, "" );
+//      msg = e0.what();
+//      folder->storeObject( 1, 2, payload, 0 );
+//    } catch ( RelationalTypeConverterInvalidCppValue& e ) {
+//      CPPUNIT_ASSERT_EQUAL_MESSAGE
+//        ( "exception error message", msg, std::string( e.what() ) );
+//      throw;
+//    }
+  }
+
+  
+  /// Tests that storing a specification with a string representation
+  /// 65535 characters long always succeeds.
+  /// Note that the new constraints (<=900 fields with names <=30 characters)
+  /// imply that the longest description that can be built is only
+  /// 900*(30+1+9)+899*1=36899 characters ("name:String64k,name:String64k...). 
+  /// This test actually tests that this payload specification can be used.
+  void test_payloadSpecDescription() 
+  {
+    CPPUNIT_ASSERT_EQUAL_MESSAGE
+      ( "PANIC! Unexpected folder payload description maxSize (hint)",
+        StorageType::String64k,
+        RelationalNodeTable::columnTypeIds::folderPayloadSpecDesc );
+    RecordSpecification spec;
+    for ( int i = 0; i < 900; ++i ) {
+      std::stringstream s;
+      s << "S1234567890123456789012345" << i+1000;
+      spec.extend( s.str(), StorageType::String64k );
+    }      
+    CPPUNIT_ASSERT_EQUAL_MESSAGE
+      ( "Payload description size",
+        (size_t)36899,
+        RelationalDatabase::encodeRecordSpecification( spec ).size() );
+    IFolderPtr folder = db->createFolder( "/myfolder", spec );
+    CPPUNIT_ASSERT( folder.get() != 0 );
+  }
+  
+
+  /// Tests that storing a specification with over 900 columns fails
+  void test_payloadSpecTooManyFields() 
+  {
+    RecordSpecification spec;
+    for ( int i = 0; i < 900; ++i ) {
+      std::stringstream s;
+      s << "S" << i;
+      spec.extend( s.str(), StorageType::String4k );
+    }      
+    db->createFolder( "/myfolder900", spec );
+    {
+      int i = 900;
+      std::stringstream s;
+      s << "S" << i;
+      spec.extend( s.str(), StorageType::String4k );
+    }      
+    CPPUNIT_ASSERT_THROW( db->createFolder( "/myfolder901", spec ),
+                          PayloadSpecificationTooManyFields );
+  }
+  
+
+  /// Tests that storing a specification with over 10 blob columns fails
+  void test_payloadSpecTooManyBlobFields() 
+  {
+    RecordSpecification spec;
+    for ( int i = 0; i < 10; ++i ) {
+      std::stringstream s;
+      s << "B" << i;
+      spec.extend( s.str(), StorageType::Blob64k );
+    }      
+    db->createFolder( "/myfolder10blob", spec );
+    {
+      int i = 11;
+      std::stringstream s;
+      s << "B" << i;
+      //spec.extend( s.str(), StorageType::Blob64k );
+      spec.extend( s.str(), StorageType::Blob16M );
+    }      
+    CPPUNIT_ASSERT_THROW( db->createFolder( "/myfolder11blob", spec ),
+                          PayloadSpecificationTooManyBlobFields );
+  }
+
+
+  /// Test for bug #24646: storing a specification with over 8000 bytes fails
+  /// (where each long VARCHAR, TEXT or BLOB counts for 768 bytes)
+  void test_payloadSpecOver8000Bytes() 
+  {
+    {      
+      // This succeeds on all backends
+      RecordSpecification spec;
+      for ( int i = 0; i < 10; ++i ) 
+      {
+        std::stringstream s;
+        s << "CLOB" << i;
+        spec.extend( s.str(), StorageType::String64k );
+      }
+      IFolderPtr folder = db->createFolder( "/myfolder10clob", spec );
+      Record record( spec );
+      std::string value = std::string( 1000, 'x' );
+      for ( int i = 0; i < 10; ++i ) 
+      {
+        std::stringstream s;
+        s << "CLOB" << i;
+        record[s.str()].setValue( value ); 
+      }
+      folder->storeObject(  0, 10, record, 0 );
+    }
+    if ( ralDb->sessionMgr()->databaseTechnology() == "MySQL" )
+    {
+      std::cout << std::endl
+                << "WARNING: '8000 bytes' test disabled for MySQL (bug #24646)"
+                << std::endl;
+    }
+    else
+    {      
+      // This fails on MySQL (total size is 11*768>8000) with
+      // "MySQL errno:1030: Got error 139 from storage engine"
+      RecordSpecification spec;
+      for ( int i = 0; i < 11; ++i ) 
+      {
+        std::stringstream s;
+        s << "CLOB" << i;
+        spec.extend( s.str(), StorageType::String64k );
+      }
+      IFolderPtr folder = db->createFolder( "/myfolder11clob", spec );
+      Record record( spec );
+      std::string value = std::string( 1000, 'x' );
+      for ( int i = 0; i < 11; ++i ) 
+      {
+        std::stringstream s;
+        s << "CLOB" << i;
+        record[s.str()].setValue( value ); 
+      }
+      folder->storeObject(  0, 10, record, 0 );
+    }
+  }
+
+
+  /// Tests that storing a specification with over 200 string255 columns fails
+  void test_payloadSpecTooManyString255Fields() 
+  {
+    RecordSpecification spec;
+    // Total size on MySQL is 65535 = 257*255 -> at most 257 (user+sys) fields.
+    // IOV table has two String255 internal columns -> at most 255 user fields.
+    // But 65535 also includes all numeric fields -> COOL limit is 200.
+    for ( int i = 0; i < 200; ++i ) {
+      std::stringstream s;
+      s << "S" << i;
+      spec.extend( s.str(), StorageType::String255 );
+    }
+    // Assume long long (BIGINT) are the largest non-VARCHAR (8 bytes)
+    // See http://dev.mysql.com/doc/refman/5.1/en/storage-requirements.html
+    for ( int i = 0; i < 699; ++i ) {
+      std::stringstream s;
+      s << "I" << i;
+      spec.extend( s.str(), StorageType::Int64 );
+    }
+    db->createFolder( "/myfolder200String255", spec );
+    {
+      int i = 200;
+      std::stringstream s;
+      s << "S" << i;
+      spec.extend( s.str(), StorageType::String255 );
+    }      
+    CPPUNIT_ASSERT_THROW( db->createFolder( "/myfolder201String255", spec ),
+                          PayloadSpecificationTooManyString255Fields );
+  }
+
+  
+  /// Tests that storing a specification with invalid field names fails.
+  void test_payloadSpecInvalidFieldName()
+  {
+    // Test that a field name of size 30 succeeds, of size 31 fails
+    {
+      RecordSpecification spec;
+      spec.extend( "S12345678901234567890123456789", StorageType::String255 );
+      db->createFolder( "/myfolder", spec );
+      spec.extend( "S123456789012345678901234567890", StorageType::String255 );
+      CPPUNIT_ASSERT_THROW( db->createFolder( "/myfoldernew", spec ),
+                            PayloadSpecificationInvalidFieldName );
+    }
+    // Test that a field name of size 0 fails
+    {
+      RecordSpecification spec;
+      try {
+        spec.extend( "", StorageType::String255 );
+        CPPUNIT_FAIL( "Creating a field spec with name '' should fail" );
+      } catch ( FieldSpecificationInvalidName& ) {}
+    }
+    // Test that a field name containing the '-' sign fails
+    {
+      RecordSpecification spec;
+      spec.extend( "is-a", StorageType::String255 );
+      CPPUNIT_ASSERT_THROW( db->createFolder( "/myfoldernew", spec ),
+                            PayloadSpecificationInvalidFieldName );
+    }
+    // Test that a field name starting with the '_' sign fails
+    {
+      RecordSpecification spec;
+      spec.extend( "_payload", StorageType::String255 );
+      CPPUNIT_ASSERT_THROW( db->createFolder( "/myfoldernew", spec ),
+                            PayloadSpecificationInvalidFieldName );
+    }
+    // Test that a field name starting with a digit fails
+    {
+      RecordSpecification spec;
+      spec.extend( "1payload", StorageType::String255 );
+      CPPUNIT_ASSERT_THROW( db->createFolder( "/myfoldernew", spec ),
+                            PayloadSpecificationInvalidFieldName );
+    }
+    // Test that a field name starting with "COOL_" fails
+    {
+      RecordSpecification spec;
+      spec.extend( "COOL_payload", StorageType::String255 );
+      CPPUNIT_ASSERT_THROW( db->createFolder( "/myfoldernew", spec ),
+                            PayloadSpecificationInvalidFieldName );
+    }
+    // Test that a field name starting with "cool_" fails
+    {
+      RecordSpecification spec;
+      spec.extend( "cool_payload", StorageType::String255 );
+      CPPUNIT_ASSERT_THROW( db->createFolder( "/myfoldernew", spec ),
+                            PayloadSpecificationInvalidFieldName );
+    }
+    // Test that a field name starting with "Cool_" fails
+    {
+      RecordSpecification spec;
+      spec.extend( "Cool_Payload", StorageType::String255 );
+      CPPUNIT_ASSERT_THROW( db->createFolder( "/myfoldernew", spec ),
+                            PayloadSpecificationInvalidFieldName );
+    }
+  }
+  
+
+  /// Tests storing and retrieving empty strings
+  void test_emptyString() 
+  {
+    std::string name = "A_STRING255";
+    FolderSpecification spec;
+    spec.payloadSpecification().extend
+      ( name, StorageType::String255 );
+    IFolderPtr folder = ralDb->createFolder( "/myfolder", spec );
+    CPPUNIT_ASSERT( folder.get() != 0 );
+    Record record( spec.payloadSpecification() );
+    // Store value at 0 = ""
+    std::string value = "";
+    record[name].setValue( value ); 
+    folder->storeObject(  0, 10, record, 0 );
+    // Store value at 10 = NULL
+    record[name].setNull(); 
+    folder->storeObject( 10, 20, record, 0 );
+    // Retrieve value at 0 = ""
+    {
+      IObjectPtr obj = folder->findObject( 0, 0 );
+      const IField& fld = obj->payload()[name];
+      // This would succeed if setValue("") actually sets the value to NULL (2)
+      //CPPUNIT_ASSERT_EQUAL_MESSAGE
+      //  ( "Empty string - should be null (new IField!)", 
+      //    true, fld.isNull() );
+      // This used to fail on Oracle when "" and NULL were different (1)
+      // This now succeeds on all 3 dbs: setNull() sets the value to "" (3)
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "Empty string - should be not null", 
+          false, fld.isNull() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "Empty string - size should be 0", 
+          (size_t)0, fld.data<std::string>().size() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "Empty string - value should be \"\"", 
+          std::string(""), fld.data<std::string>() );
+    }    
+    // Retrieve value at 10 = NULL
+    {
+      IObjectPtr obj = folder->findObject( 10, 0 );
+      const IField& fld = obj->payload()[name];    
+      // This used to succeed on all 3 dbs when "" and NULL were different (1)
+      // This would succeed if setValue("") actually sets the value to NULL (2)
+      //CPPUNIT_ASSERT_EQUAL_MESSAGE
+      //  ( "Null string - should be null", 
+      //    true, fld.isNull() );
+      // This now succeeds on all 3 dbs: setNull() sets the value to "" (3)
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "Null string - on readback, should be not null", 
+          false, fld.isNull() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "Null string - on readback, size should be 0", 
+          (size_t)0, fld.data<std::string>().size() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "Null string - on readback, value should be \"\"", 
+          std::string(""), fld.data<std::string>() );
+    }
+  }
+  
+  /// Tests storing and retrieving std strings containing the \0 character
+  /// This fails on all three backends!
+  /// Note that it also fails on Benthic (but not on sqlplus).
+  void test_nullCharInString() 
+  {
+    std::string name = "A_STRING255";
+    FolderSpecification spec;
+    spec.payloadSpecification().extend
+      ( name, StorageType::String255 );
+    IFolderPtr folder = ralDb->createFolder( "/myfolder", spec );
+    CPPUNIT_ASSERT( folder.get() != 0 );
+    Record record( spec.payloadSpecification() );
+    std::string value = "";
+    for ( int i=0; i<10; i++ ){
+      value += 'A';
+      value += '\x00';
+      value += 'Z';
+    }
+    CPPUNIT_ASSERT_EQUAL_MESSAGE
+      ( "Input value size", 
+        (size_t)30, value.size() );
+    try {
+      record[name].setValue( value ); 
+      CPPUNIT_FAIL( "setValue should fail" );
+    } 
+    catch ( StorageTypeStringContainsNullChar& ) {} 
+    catch ( ... ) {
+      CPPUNIT_FAIL
+        ( "Wrong exception: expected StorageTypeStringContainsNullChar" );
+    } 
+    /*
+    record[name].setValue( value ); 
+    CPPUNIT_ASSERT_EQUAL_MESSAGE
+      ( "Input field size", 
+        (size_t)30, record[name].data<std::string>().size() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE
+      ( "Input field - compare to input value", 
+        value, record[name].data<std::string>() );
+    folder->storeObject( 0, 10, record, 0 );
+    IObjectPtr obj = folder->findObject( 0, 0 );
+    const IField& fld = obj->payload()[name];
+    CPPUNIT_ASSERT_EQUAL_MESSAGE
+      ( "Fetched string - should be not null", 
+        false, fld.isNull() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE
+      ( "Fetched string - size should be 30", 
+        (size_t)30, fld.data<std::string>().size() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE
+      ( "Fetched string - compare to input value", 
+        value, fld.data<std::string>() );
+    */
+  }    
+
+  
+  /// Tests storing and reading back a BLOB64K longer than 65535 characters.
+  /// This should fail on MySQL (the BLOB64K SQL type has that limit).
+  void test_blob64kOver64k() {
+    RecordSpecification spec;
+    std::string name = "B";
+    StorageType::TypeId attrType = StorageType::Blob64k;
+    spec.extend( name, attrType );
+    IFolderPtr folder = db->createFolder( "/myfolder", spec );
+    // Insert a BLOB64K with 65536 bytes or more
+    int numberOfElements = 65536 / sizeof(float);
+    if ( 65536 % sizeof(float) != 0 ) numberOfElements++;
+    Blob64k blob( numberOfElements * sizeof(float) );
+    float* addressToElement = static_cast< float* >( blob.startingAddress() );
+    for ( int i = 0; i < numberOfElements; ++i, ++addressToElement ) {
+      *addressToElement = static_cast<float>(i + 0.01);
+    }
+    Record record( spec );
+    /*
+    record[name].setValue( blob );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE
+      ( "Input field - should be not null", 
+        false, record[name].isNull() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE
+      ( "Input field size", 
+        blob.size(), record[name].data<Blob64k>().size() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE
+      ( "Input field - compare to input value", 
+        true, blob == record[name].data<Blob64k>() );
+    folder->storeObject( 0, 1, record, 0 );
+    IObjectPtr obj = folder->findObject( 0, 0 );
+    const IField& fld = obj->payload()[name];
+    CPPUNIT_ASSERT_EQUAL_MESSAGE
+      ( "Fetched field - should be not null", 
+        false, fld.isNull() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE
+      ( "Fetched field size", 
+        blob.size(), fld.data<Blob64k>().size() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE
+      ( "Fetched field - compare to input value", 
+        true, blob == fld.data<Blob64k>() );
+    */
+    try {
+      record[name].setValue( blob );
+      CPPUNIT_FAIL( "setValue should fail" );
+    } 
+    catch ( StorageTypeBlobTooLong& ) {} 
+    catch ( ... ) {
+      CPPUNIT_FAIL
+        ( "Wrong exception: expected StorageTypeBlobTooLong" );
+    } 
+  }
+
+  
+  /// Tests storing and reading back a BLOB16M longer than 65535 characters.
+  /// This should succeed on all platforms.
+  void test_blob16MOver64k() {
+    RecordSpecification spec;
+    std::string name = "B";
+    StorageType::TypeId attrType = StorageType::Blob16M;
+    spec.extend( name, attrType );
+    IFolderPtr folder = db->createFolder( "/myfolder", spec );
+    // Insert a BLOB16M with 65536 bytes or more
+    int numberOfElements = 65536 / sizeof(float);
+    if ( 65536 % sizeof(float) != 0 ) numberOfElements++;
+    Blob16M blob( numberOfElements * sizeof(float) );
+    float* addressToElement = static_cast< float* >( blob.startingAddress() );
+    for ( int i = 0; i < numberOfElements; ++i, ++addressToElement ) {
+      *addressToElement = static_cast< float >( i + 0.01 );
+    }
+    Record record( spec );
+    record[name].setValue( blob );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE
+      ( "Input field - should be not null", 
+        false, record[name].isNull() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE
+      ( "Input field size", 
+        blob.size(), record[name].data<Blob16M>().size() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE
+      ( "Input field - compare to input value", 
+        true, blob == record[name].data<Blob16M>() );
+    folder->storeObject( 0, 1, record, 0 );
+    IObjectPtr obj = folder->findObject( 0, 0 );
+    const IField& fld = obj->payload()[name];
+    CPPUNIT_ASSERT_EQUAL_MESSAGE
+      ( "Fetched field - should be not null", 
+        false, fld.isNull() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE
+      ( "Fetched field size", 
+        blob.size(), fld.data<Blob16M>().size() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE
+      ( "Fetched field - compare to input value", 
+        true, blob == fld.data<Blob16M>() );
+    /*
+    try {
+      record[name].setValue( blob );
+      CPPUNIT_FAIL( "setValue should fail" );
+    } 
+    catch ( StorageTypeBlobTooLong& ) {} 
+    catch ( ... ) {
+      CPPUNIT_FAIL
+        ( "Wrong exception: expected StorageTypeBlobTooLong" );
+    } 
+    */
+  }
+
+  
+  /// Tests storing and retrieving empty blobs
+  /// This used to fail for SQLite (bug #22485 aka bug #30036)
+  void test_emptyBlob() 
+  {
+    std::string name = "A_BLOB";
+    FolderSpecification spec;
+    spec.payloadSpecification().extend
+      ( name, StorageType::Blob64k );
+    IFolderPtr folder = ralDb->createFolder( "/myfolder", spec );
+    CPPUNIT_ASSERT( folder.get() != 0 );
+    Record record( spec.payloadSpecification() );
+    // Insert value at 0 = BLOB with 0 bytes
+    Blob64k value( 0 );
+    record[name].setValue( value ); 
+    folder->storeObject(  0, 10, record, 0 );
+    // Insert value at 10 = NULL BLOB
+    record[name].setNull(); 
+    folder->storeObject( 10, 20, record, 0 );
+    // Retrieve value at 0 = BLOB with 0 bytes
+    {
+      IObjectPtr obj = folder->findObject( 0, 0 );
+      const IField& fld = obj->payload()[name];
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "Empty blob - should be not null", 
+          false, fld.isNull() ); // Used to fail for sqlite (bug #22485)
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "Empty blob - size should be 0", 
+          (long int)0, (long int)fld.data<Blob64k>().size() );
+    }    
+    // Retrieve value at 10 = NULL BLOB
+    {
+      IObjectPtr obj = folder->findObject( 10, 0 );
+      const IField& fld = obj->payload()[name];
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "Null blob - should be null", 
+          true, fld.isNull() );
+    }
+  }
+
+
+  /// Creates a dummy payload AttributeList for a given index
+  Record dummyPayload( int index ) 
+  {
+    Record payload( payloadSpec );
+    payload["I"].setValue<Int32>( index );
+    std::stringstream s;
+    s << "Object " << index;
+    payload["S"].setValue<String255>( s.str() );
+    payload["X"].setValue<Float>( (float)(index/1000.) );
+    return payload;
+  }
+  
+  std::string toString( const coral::Attribute& a ) 
+  {
+    std::stringstream s;
+    const bool valueOnly = true;
+    a.toOutputStream( s, valueOnly );
+    return s.str();
+  }
+  
+  void setUp() {
+    try {
+      CoralApplication app;
+      IDatabaseSvc& dbSvc = app.databaseService();
+      dbSvc.dropDatabase( connectString );
+      db = dbSvc.createDatabase( connectString );
+      ralDb = dynamic_cast<RalDatabase*>(db.get());
+    } catch ( std::exception& e ) {
+      std::cout << "Exception caught: '" << e.what() << "'" << std::endl;
+      throw;
+    } catch ( ... ) {
+      std::cout << "UNKNOWN exception caught!" << std::endl;
+      throw;
+    }
+  }
+  
+  void tearDown() {
+    db.reset();
+    // Here I want to purge the connection pool
+    CoralApplication app;
+    IDatabaseSvc& dbSvc = app.databaseService();
+    RalDatabaseSvc* rdbSvc = dynamic_cast<RalDatabaseSvc*>(&dbSvc);
+    rdbSvc->connectionSvc().configuration().setConnectionTimeOut(-1);
+    rdbSvc->connectionSvc().purgeConnectionPool();
+  }
+  
+};
+  
+CPPUNIT_TEST_SUITE_REGISTRATION( cool::RalDatabaseTest_extendedSpec );
+
+//-----------------------------------------------------------------------------
+
+// Include CppUnit test driver
+#include <CppUnit_testdriver.icpp>
+
+
diff --git a/RelationalCool/tests/RalDatabase_versioning/README.segmentationFault b/RelationalCool/tests/RalDatabase_versioning/README.segmentationFault
new file mode 100644
index 000000000..4849953c8
--- /dev/null
+++ b/RelationalCool/tests/RalDatabase_versioning/README.segmentationFault
@@ -0,0 +1,653 @@
+20.03.2005 - COOL_0_1_1-pre2
+
+Tried to run the full RalDatabase_versioning test with the previously 
+chosen configuration (COOL debug, COOL with pthread, POOL nodebug).
+I continue to observe problems (mutex locks hanging).
+I also have the impression (again..) that the problems take place in 
+different points of the program depending on whether Debug is on or off.
+
+=> I take a more radical approach: use the POOL debug libraries also
+for rh73_gcc32 and rh73_gcc323 (while keeping COOL debug and pthread).
+This seems to solve the problem (all 51 tests pass on Oracle).
+I tag this configuration as COOL_0_1_1-pre2.
+
+All unit tests included in execUnitTests (i.e., RalDatabase_versioning
+and others) now pass for both Oracle and MySQL on all of rh73_gcc323,
+rh73_gcc323_dbg, rh73_gcc32, slc3_ia32_gcc323. I can now go on with 
+further developments (int64, CLOBs).
+
+I will keep rh73_gcc323 and slc3_ia32_gcc323 as main development platforms.
+
+19.03.2005 - COOL_0_1_1-pre1
+
+[The COOL_0_1_1-pre1 configuration is the default to start my studies. 
+COOL is in nopthread, nodebug mode, POOL in nodebug mode on rh73_gcc323.
+It is the one where I get segmentation faults.
+The COOL_0_1_1-pre2 configuration is the one where all tests are fixed.]
+
+The test_fetchObjectTableRows_5c test is the single 
+most annoying test I have seen recently.
+It has generated one full week of work or even more.
+
+It has given problems on MySQL, allowing us to fix the following bugs:
+- the ODBC bulk inserter was randomly adding '\0' at the end of stored strings
+- the order in which bind variables are declared to RAL must be the 
+  same as the order in which they are used in the AttributeList
+- %i and not %m is the correct format for minutes
+- now() has a second granularity, hence you must sleep at least one second
+  when testing the status of the database in between two insertions
+
+It has given problems on Oracle, for which we have workarounds but not 
+yet the real solution. On Oracle, the problem is heavily dependent
+on the operating system and the compiler options used for both POOL
+and COOL. The test may work correctly, crash with a segmentation fault
+or hang in a mutex lock depending on the compilation options.
+
+To execute the test:
+  eval `scram runtime -csh`
+  setenv COOLTESTDB "oracle://devdb;schema=conddb_test;user=conddb_test;password=PASSWORD;dbname=COOLSEGF"
+  unitTest_RelationalCool_RalDatabase_versioning
+
+Standard configuration
+POOL: slc3_ia32_gcc323
+COOL: slc3_ia32_gcc323 standard (with -pthread)
+==> test OK (the 1st time it is executed)
+==> test OK (from the 2nd time onwards)
+
+Standard configuration
+POOL: rh73_gcc323
+COOL: rh73_gcc323 standard (no -pthread - COOL default on RH73)
+==> segmentation fault (the 1st time it is executed) - trace #1
+==> hangs in mutex lock (from the 2nd time onwards) - trace #2
+
+Change the site/tools-CERN.conf, scram setup, eval `scram runtime -csh`
+[Also \rm ~/myLCG/COOL_HEAD/rh73_gcc323/lib/liblcg_RelationalCool.so 
+and scram b to see what happens with a new plugin]
+POOL: rh73_gcc323_dbg
+COOL: rh73_gcc323 standard (no -pthread - COOL default on RH73)
+==> test OK (the 1st time it is executed)
+==> test OK (from the 2nd time onwards)
+
+With pthread
+POOL: rh73_gcc323_dbg
+COOL: rh73_gcc323 with -pthread (modify BuildFile)
+==> hangs in mutex lock (the 1st time it is executed) - trace #3
+==> hangs in mutex lock (from the 2nd time) - similar (not identical) trace
+
+With pthread
+POOL: rh73_gcc323
+COOL: rh73_gcc323 with -pthread (modify BuildFile)
+==> hangs in mutex lock (the 1st time it is executed) - another trace
+==> hangs in mutex lock (from the 2nd time) - another trace
+
+With pthread and COOL debug
+POOL: rh73_gcc323
+COOL: rh73_gcc323 with -pthread and -g instead of -O2 (modify BuildFile)
+==> test OK (the 1st time it is executed)
+==> test OK (from the 2nd time onwards)
+
+With pthread and COOL debug
+POOL: rh73_gcc323_dbg
+COOL: rh73_gcc323 with -pthread and -g instead of -O2 (modify BuildFile)
+==> test OK (the 1st time it is executed)
+==> test OK (from the 2nd time onwards)
+
+With COOL debug without pthread
+POOL: rh73_gcc323_dbg
+COOL: rh73_gcc323 with -g instead of -O2 (modify BuildFile)
+==> test OK (the 1st time it is executed)
+==> test OK (from the 2nd time onwards)
+
+With COOL debug without pthread
+POOL: rh73_gcc323
+COOL: rh73_gcc323 with -g instead of -O2 (modify BuildFile)
+==> segmentation fault (the 1st time it is executed) - trace #4
+==> hangs in mutex lock (from the 2nd time onwards) - trace #5
+
+SUMMARY
+=======
+
+POOL    COOL        COOL    RESULT
+nodbg   nopthread   nodbg   x (segfault + hangs)
+nodbg   pthread     nodbg   x (hangs)
+nodbg   nopthread   dbg     x (segfault + hangs)
+nodbg   pthread     dbg     OK
+dbg     nopthread   nodbg   OK
+dbg     pthread     nodbg   x (hangs)
+dbg     nopthread   dbg     OK
+dbg     pthread     dbg     OK
+
+For COOL alone: pthread+debug is the only combination that works ok for both 
+POOL debug and nodebug => use pthread+debug for COOL also in non-debug mode.
+
+Using POOL debug also helps "save" the situation if pthread is not used.
+
+This recipe should be cross-checked against MySQL too.
+The reason why pthread had been removed in the first place was 
+a problem in a MyODBC test (can't remember under which circumstances).
+  setenv COOLTESTDB "mysql://pcitdb59;schema=COOLDB;user=cool;password=PASSWORD;dbname=COOLSEGF"
+
+Tried it for both POOL debug and nodebug, it works.
+
+POOL    COOL        COOL    RESULT
+nodbg   pthread     dbg     OK
+dbg     pthread     dbg     OK
+
+SOLUTIONS
+=========
+
+- No problem observed for SLC3
+  (but cross-checking the POOL code would be useful in any case...)
+
+- Hack until support for RH73 is discontinued:
+  use the COOL debug libraries (with pthread) even in non-debug mode
+
+DETAILS
+=======
+
+Trace #1
+--------
+
+The crash happens within the AttributeListSpecification destructor,
+called within the OracleQueryWithMultipleTables destructor.
+
+Note: the crash is avoided (docuble-check this...) if 
+OracleQueryWithMultipleTables::process() is not called.
+
+Note: both AttributeList and AttributeListSpecification have only 
+the default destructors. It may be better (for debug purposes) to 
+declare them in the .h and implement them empty in the .cpp files.
+
+Standard configuration
+POOL: rh73_gcc323
+COOL: rh73_gcc323 standard (no -pthread - COOL default on RH73)
+==> segmentation fault (the 1st time it is executed) - trace #1
+==> hangs in mutex lock (from the 2nd time onwards) - trace #2
+
+Here: I may soon crash (seg fault) or hang (mutex lock)
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT "i"."OBJECT_ID", "i"."CHANNEL_ID", "i"."IOV_SINCE", "i"."IOV_UNTIL", "i"."SYS_INSTIME", "i"."ORIGINAL_ID", "i"."NEW_HEAD_ID", "i"."I", "i"."S", "i"."X" FROM "CONDDB_TEST"."COOLSEGF_F0001_IOVS" "i", "CONDDB_TEST"."COOLSEGF_F0001_IOVS" "o" WHERE :"since" <= "i"."IOV_SINCE" and "i"."IOV_UNTIL" < :"until" and "i"."SYS_INSTIME" <= :"asOfDate1" and "i"."CHANNEL_ID" = :"channel" and ( ( "i"."NEW_HEAD_ID" = :"newHeadId" and "i"."OBJECT_ID" = "o"."OBJECT_ID" )  or ( "i"."NEW_HEAD_ID" = "o"."OBJECT_ID" and "o"."SYS_INSTIME" > :"asOfDate2" ) ) ORDER BY "IOV_SINCE" ASC"
+
+unitTest_RelationalCool_RalDatabase_versioning (pid=8272 ppid=4571) received fatal signal 11 (Segmentation fault)
+signal context:
+  signo  = 11, errno = 0, code = 1 (address not mapped to object)
+  pid    = 2103976551, uid = 135147756
+  value  = (135147992, 0x80e31d8)
+  addr   = 0x7d682267
+  stack  = (2, 0, (nil))
+
+  eip: 0023:40362300           eflags: 00210206
+  eax: 7d682267   ebx: 403905b8   ecx: 0805fdc0   edx: 7d682267
+  esi: 7d68226f   edi: bfffafc0   ebp: bfffafe8   esp: bfffafa0
+   ds: 002b        es: 002b        fs: 0000        ss: 002b
+
+  signal esp: bfffafa0  trap: 14/4  oldmask: 80000000   cr2: 7d682267
+
+  FPU:  control = ffff027f
+        status  = ffff0320
+        tag     = ffffffff
+        ip      = 0023:4099855e
+        data    = 002b:0810a7c4
+        state   = 00000320
+    %fp0 = [0000:0000000000000000]
+    %fp1 = [0000:0000000000000000]
+    %fp2 = [3fdd:7800371b5fe1d0e5]
+    %fp3 = [3ff6:d000ffff6eff8312]
+    %fp4 = [0000:0000000000000000]
+    %fp5 = [0000:0000000000000000]
+    %fp6 = [3ff6:d000ffff6eff8312]
+    %fp7 = [3ff6:d000ffff6eff8312]
+
+stack trace:
+ 0x4003ef46 _ZN4seal9DebugAids10stacktraceEi + 0x66 [/afs/cern.ch/sw/lcg/app/releases/SEAL/SEAL_1_6_1/rh73_gcc323/lib/liblcg_SealBase.so]
+ 0x4006f96a _ZN4seal6Signal9fatalDumpEiP7siginfoPv + 0xda [/afs/cern.ch/sw/lcg/app/releases/SEAL/SEAL_1_6_1/rh73_gcc323/lib/liblcg_SealBase.so]
+ 0x4006f210 _ZN4seal6Signal5fatalEiP7siginfoPv + 0xf0 [/afs/cern.ch/sw/lcg/app/releases/SEAL/SEAL_1_6_1/rh73_gcc323/lib/liblcg_SealBase.so]
+ 0x42029180 ? + 0x42029180 [unitTest_RelationalCool_RalDatabase_versioning]
+ 0x40216f9b _ZNSt6vectorIN4pool22AttributeSpecificationESaIS1_EED1Ev + 0x3b [/afs/cern.ch/user/a/avalassi/myLCG/COOL_HEAD/rh73_gcc323/lib/liblcg_RelationalCool.so]
+ 0x4021781c _ZN5boost6detail20sp_counted_base_implIPN4pool26AttributeListSpecificationENS_15checked_deleterIS3_EEE7disposeEv + 0x2c [/afs/cern.ch/user/a/avalassi/myLCG/COOL_HEAD/rh73_gcc323/lib/liblcg_RelationalCool.so]
+ 0x08054828 _ZN5boost6detail15sp_counted_base7releaseEv + 0x28 [unitTest_RelationalCool_RalDatabase_versioning]
+ 0x0805489c _ZN5boost6detail12shared_countD1Ev + 0x2c [unitTest_RelationalCool_RalDatabase_versioning]
+ 0x404062dd _ZN4pool12OracleAccess29OracleQueryWithMultipleTables5resetEv + 0x11d [/afs/cern.ch/sw/lcg/app/releases/POOL/POOL_2_0_2/rh73_gcc323/lib/liblcg_OracleAccess.so]
+ 0x40405fba _ZN4pool12OracleAccess29OracleQueryWithMultipleTablesD0Ev + 0x2a [/afs/cern.ch/sw/lcg/app/releases/POOL/POOL_2_0_2/rh73_gcc323/lib/liblcg_OracleAccess.so]
+ 0x401eb8ca _ZN4cool11RalDatabase20fetchObjectTableRowsERKSsRKN4pool26AttributeListSpecificationERKxS8_RKmRKN4seal4TimeE + 0x133a [/afs/cern.ch/user/a/avalassi/myLCG/COOL_HEAD/rh73_gcc323/lib/liblcg_RelationalCool.so]
+ 0x08051a2a _ZN4cool15RalDatabaseTest28test_fetchObjectTableRows_5cEv + 0x122a [unitTest_RelationalCool_RalDatabase_versioning]
+ 0x08057ead _ZN7CppUnit10TestCallerIN4cool15RalDatabaseTestENS_19NoExceptionExpectedEE7runTestEv + 0x3d [unitTest_RelationalCool_RalDatabase_versioning]
+ 0x40263cc5 _ZN7CppUnit8TestCase3runEPNS_10TestResultE + 0x45 [/afs/cern.ch/sw/lcg/external/CppUnit/1.8.0/rh73_gcc323/lib/libcppunit-1.8.so.0]
+ 0x4026d0cd _ZN7CppUnit9TestSuite3runEPNS_10TestResultE + 0x3d [/afs/cern.ch/sw/lcg/external/CppUnit/1.8.0/rh73_gcc323/lib/libcppunit-1.8.so.0]
+ 0x4026d0cd _ZN7CppUnit9TestSuite3runEPNS_10TestResultE + 0x3d [/afs/cern.ch/sw/lcg/external/CppUnit/1.8.0/rh73_gcc323/lib/libcppunit-1.8.so.0]
+ 0x4026d0cd _ZN7CppUnit9TestSuite3runEPNS_10TestResultE + 0x3d [/afs/cern.ch/sw/lcg/external/CppUnit/1.8.0/rh73_gcc323/lib/libcppunit-1.8.so.0]
+ 0x4026c67a _ZN7CppUnit6TextUi10TestRunner7runTestEPNS_4TestEb + 0x4a [/afs/cern.ch/sw/lcg/external/CppUnit/1.8.0/rh73_gcc323/lib/libcppunit-1.8.so.0]
+ 0x4026c387 _ZN7CppUnit6TextUi10TestRunner13runTestByNameESsb + 0x47 [/afs/cern.ch/sw/lcg/external/CppUnit/1.8.0/rh73_gcc323/lib/libcppunit-1.8.so.0]
+ 0x4026c2b2 _ZN7CppUnit6TextUi10TestRunner3runESsbbb + 0x52 [/afs/cern.ch/sw/lcg/external/CppUnit/1.8.0/rh73_gcc323/lib/libcppunit-1.8.so.0]
+ 0x0804e74f main + 0xdf [unitTest_RelationalCool_RalDatabase_versioning]
+ 0x42017589 __libc_start_main + 0x95 [unitTest_RelationalCool_RalDatabase_versioning]
+ 0x0804e581 _ZNK4seal4Time6minuteEb + 0x39 [unitTest_RelationalCool_RalDatabase_versioning]
+
+shared libraries present:
+ 0x00000000 /afs/cern.ch/user/a/avalassi/myLCG/COOL_HEAD/rh73_gcc323/tests/bin/unitTest_RelationalCool_RalDatabase_versioning
+ 0x40015000 /afs/cern.ch/sw/lcg/app/releases/SEAL/SEAL_1_6_1/rh73_gcc323/lib/liblcg_SealBase.so
+ 0x4009e000 /afs/cern.ch/sw/lcg/app/releases/POOL/POOL_2_0_2/rh73_gcc323/lib/liblcg_AttributeList.so
+ 0x400c6000 /afs/cern.ch/sw/lcg/app/releases/POOL/POOL_2_0_2/rh73_gcc323/lib/liblcg_POOLCore.so
+ 0x400d6000 /afs/cern.ch/sw/lcg/app/releases/SEAL/SEAL_1_6_1/rh73_gcc323/lib/liblcg_PluginManager.so
+ 0x400f8000 /afs/cern.ch/sw/lcg/app/releases/SEAL/SEAL_1_6_1/rh73_gcc323/lib/liblcg_SealKernel.so
+ 0x40114000 /afs/cern.ch/sw/lcg/app/releases/POOL/POOL_2_0_2/rh73_gcc323/lib/liblcg_RelationalAccess.so
+ 0x4013c000 /afs/cern.ch/sw/lcg/app/releases/SEAL/SEAL_1_6_1/rh73_gcc323/lib/liblcg_Reflection.so
+ 0x40169000 /afs/cern.ch/sw/lcg/app/releases/SEAL/SEAL_1_6_1/rh73_gcc323/lib/liblcg_SealServices.so
+ 0x401a3000 /afs/cern.ch/sw/lcg/app/releases/SEAL/SEAL_1_6_1/rh73_gcc323/lib/liblcg_SealUtil.so
+ 0x401b1000 /afs/cern.ch/user/a/avalassi/myLCG/COOL_HEAD/rh73_gcc323/lib/liblcg_RelationalCool.so
+ 0x40252000 /afs/cern.ch/sw/lcg/external/CppUnit/1.8.0/rh73_gcc323/lib/libcppunit-1.8.so.0
+ 0x40291000 /lib/libnsl.so.1
+ 0x402a6000 /lib/libcrypt.so.1
+ 0x402d3000 /lib/libdl.so.2
+ 0x402d6000 /afs/cern.ch/sw/lcg/external/pcre/4.4/rh73_gcc323/lib/libpcre.so.0
+ 0x402e3000 /afs/cern.ch/sw/lcg/external/uuid/1.32/rh73_gcc323/lib/libuuid.so.1
+ 0x402e6000 /usr/local/gcc-alt-3.2.3/lib/libstdc++.so.5
+ 0x40397000 /lib/i686/libm.so.6
+ 0x403b9000 /usr/local/gcc-alt-3.2.3/lib/libgcc_s.so.1
+ 0x00000000 /lib/i686/libc.so.6
+ 0x40000000 /lib/ld-linux.so.2
+ 0x403c2000 /afs/cern.ch/sw/lcg/app/releases/POOL/POOL_2_0_2/rh73_gcc323/lib/liblcg_OracleAccess.so
+ 0x40463000 /afs/cern.ch/sw/lcg/external/oracle/10.1.0.3-1/rh73_gcc323/lib/libclntsh.so.10.1
+ 0x40ff3000 /afs/cern.ch/sw/lcg/external/oracle/10.1.0.3-1/rh73_gcc323/lib/libnnz10.so
+ 0x4027d000 /lib/i686/libpthread.so.0
+ 0x42135000 /afs/cern.ch/sw/lcg/external/oracle/10.1.0.3-1/rh73_gcc323/lib/libociei.so
+ 0x41219000 /lib/libnss_files.so.2
+ 0x41223000 /lib/libnss_nisplus.so.2
+ 0x4122e000 /lib/libnss_dns.so.2
+ 0x41232000 /lib/libresolv.so.2
+Segmentation fault
+
+Trace #2 (after pressing CTRL-C)
+--------
+
+Standard configuration
+POOL: rh73_gcc323
+COOL: rh73_gcc323 standard (no -pthread - COOL default on RH73)
+==> segmentation fault (the 1st time it is executed) - trace #1
+==> hangs in mutex lock (from the 2nd time onwards) - trace #2
+
+Here: I may soon crash (seg fault) or hang (mutex lock)
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT "i"."OBJECT_ID", "i"."CHANNEL_ID", "i"."IOV_SINCE", "i"."IOV_UNTIL", "i"."SYS_INSTIME", "i"."ORIGINAL_ID", "i"."NEW_HEAD_ID", "i"."I", "i"."S", "i"."X" FROM "CONDDB_TEST"."COOLSEGF_F0001_IOVS" "i", "CONDDB_TEST"."COOLSEGF_F0001_IOVS" "o" WHERE :"since" <= "i"."IOV_SINCE" and "i"."IOV_UNTIL" < :"until" and "i"."SYS_INSTIME" <= :"asOfDate1" and "i"."CHANNEL_ID" = :"channel" and ( ( "i"."NEW_HEAD_ID" = :"newHeadId" and "i"."OBJECT_ID" = "o"."OBJECT_ID" )  or ( "i"."NEW_HEAD_ID" = "o"."OBJECT_ID" and "o"."SYS_INSTIME" > :"asOfDate2" ) ) ORDER BY "IOV_SINCE" ASC"
+
+Ctrl-C
+
+unitTest_RelationalCool_RalDatabase_versioning (pid=8282 ppid=4571) received fatal signal 2 (Interrupt)
+signal context:
+  signo  = 2, errno = 0, code = 128 (kernel)
+  pid    = 0, uid = 0
+  value  = (0, (nil))
+  stack  = (2, 0, (nil))
+
+  eip: 0023:420293d5           eflags: 00200216
+  eax: fffffffc   ebx: bfffa180   ecx: 00000008   edx: 4213030c
+  esi: bfffa180   edi: 4028e8e8   ebp: bfffa168   esp: bfffa160
+   ds: 002b        es: 002b        fs: 0000        ss: 002b
+
+  signal esp: bfffa160  trap: 0/0  oldmask: 80000000   cr2: 00000000
+
+  FPU:  control = ffff027f
+        status  = ffff0020
+        tag     = ffffffff
+        ip      = 0023:40de0a77
+        data    = 002b:bfff53c8
+        state   = 00000020
+    %fp0 = [0000:0000000000000000]
+    %fp1 = [0000:0000000000000000]
+    %fp2 = [0000:0000000000000000]
+    %fp3 = [3ff5:d000ffff6eff8312]
+    %fp4 = [0000:0000000000000000]
+    %fp5 = [4003:00000000c000f44f]
+    %fp6 = [4005:000000000000c800]
+    %fp7 = [4005:000000000000c800]
+
+stack trace:
+ 0x4003ef46 _ZN4seal9DebugAids10stacktraceEi + 0x66 [/afs/cern.ch/sw/lcg/app/releases/SEAL/SEAL_1_6_1/rh73_gcc323/lib/liblcg_SealBase.so]
+ 0x4006f96a _ZN4seal6Signal9fatalDumpEiP7siginfoPv + 0xda [/afs/cern.ch/sw/lcg/app/releases/SEAL/SEAL_1_6_1/rh73_gcc323/lib/liblcg_SealBase.so]
+ 0x4006f210 _ZN4seal6Signal5fatalEiP7siginfoPv + 0xf0 [/afs/cern.ch/sw/lcg/app/releases/SEAL/SEAL_1_6_1/rh73_gcc323/lib/liblcg_SealBase.so]
+ 0x42029180 ? + 0x42029180 [unitTest_RelationalCool_RalDatabase_versioning]
+ 0x40285609 ? + 0x40285609 [/lib/i686/libpthread.so.0]
+ 0x40287449 ? + 0x40287449 [/lib/i686/libpthread.so.0]
+ 0x402840d6 __pthread_mutex_lock + 0x66 [/lib/i686/libpthread.so.0]
+ 0x40409dfa _ZN4pool12OracleAccess29OracleQueryWithMultipleTables7processEv + 0x116a [/afs/cern.ch/sw/lcg/app/releases/POOL/POOL_2_0_2/rh73_gcc323/lib/liblcg_OracleAccess.so]
+ 0x401eb652 _ZN4cool11RalDatabase20fetchObjectTableRowsERKSsRKN4pool26AttributeListSpecificationERKxS8_RKmRKN4seal4TimeE + 0x10c2 [/afs/cern.ch/user/a/avalassi/myLCG/COOL_HEAD/rh73_gcc323/lib/liblcg_RelationalCool.so]
+ 0x08051a2a _ZN4cool15RalDatabaseTest28test_fetchObjectTableRows_5cEv + 0x122a [unitTest_RelationalCool_RalDatabase_versioning]
+ 0x08057ead _ZN7CppUnit10TestCallerIN4cool15RalDatabaseTestENS_19NoExceptionExpectedEE7runTestEv + 0x3d [unitTest_RelationalCool_RalDatabase_versioning]
+ 0x40263cc5 _ZN7CppUnit8TestCase3runEPNS_10TestResultE + 0x45 [/afs/cern.ch/sw/lcg/external/CppUnit/1.8.0/rh73_gcc323/lib/libcppunit-1.8.so.0]
+ 0x4026d0cd _ZN7CppUnit9TestSuite3runEPNS_10TestResultE + 0x3d [/afs/cern.ch/sw/lcg/external/CppUnit/1.8.0/rh73_gcc323/lib/libcppunit-1.8.so.0]
+ 0x4026d0cd _ZN7CppUnit9TestSuite3runEPNS_10TestResultE + 0x3d [/afs/cern.ch/sw/lcg/external/CppUnit/1.8.0/rh73_gcc323/lib/libcppunit-1.8.so.0]
+ 0x4026d0cd _ZN7CppUnit9TestSuite3runEPNS_10TestResultE + 0x3d [/afs/cern.ch/sw/lcg/external/CppUnit/1.8.0/rh73_gcc323/lib/libcppunit-1.8.so.0]
+ 0x4026c67a _ZN7CppUnit6TextUi10TestRunner7runTestEPNS_4TestEb + 0x4a [/afs/cern.ch/sw/lcg/external/CppUnit/1.8.0/rh73_gcc323/lib/libcppunit-1.8.so.0]
+ 0x4026c387 _ZN7CppUnit6TextUi10TestRunner13runTestByNameESsb + 0x47 [/afs/cern.ch/sw/lcg/external/CppUnit/1.8.0/rh73_gcc323/lib/libcppunit-1.8.so.0]
+ 0x4026c2b2 _ZN7CppUnit6TextUi10TestRunner3runESsbbb + 0x52 [/afs/cern.ch/sw/lcg/external/CppUnit/1.8.0/rh73_gcc323/lib/libcppunit-1.8.so.0]
+ 0x0804e74f main + 0xdf [unitTest_RelationalCool_RalDatabase_versioning]
+ 0x42017589 __libc_start_main + 0x95 [unitTest_RelationalCool_RalDatabase_versioning]
+ 0x0804e581 _ZNK4seal4Time6minuteEb + 0x39 [unitTest_RelationalCool_RalDatabase_versioning]
+
+shared libraries present:
+ 0x00000000 /afs/cern.ch/user/a/avalassi/myLCG/COOL_HEAD/rh73_gcc323/tests/bin/unitTest_RelationalCool_RalDatabase_versioning
+ 0x40015000 /afs/cern.ch/sw/lcg/app/releases/SEAL/SEAL_1_6_1/rh73_gcc323/lib/liblcg_SealBase.so
+ 0x4009e000 /afs/cern.ch/sw/lcg/app/releases/POOL/POOL_2_0_2/rh73_gcc323/lib/liblcg_AttributeList.so
+ 0x400c6000 /afs/cern.ch/sw/lcg/app/releases/POOL/POOL_2_0_2/rh73_gcc323/lib/liblcg_POOLCore.so
+ 0x400d6000 /afs/cern.ch/sw/lcg/app/releases/SEAL/SEAL_1_6_1/rh73_gcc323/lib/liblcg_PluginManager.so
+ 0x400f8000 /afs/cern.ch/sw/lcg/app/releases/SEAL/SEAL_1_6_1/rh73_gcc323/lib/liblcg_SealKernel.so
+ 0x40114000 /afs/cern.ch/sw/lcg/app/releases/POOL/POOL_2_0_2/rh73_gcc323/lib/liblcg_RelationalAccess.so
+ 0x4013c000 /afs/cern.ch/sw/lcg/app/releases/SEAL/SEAL_1_6_1/rh73_gcc323/lib/liblcg_Reflection.so
+ 0x40169000 /afs/cern.ch/sw/lcg/app/releases/SEAL/SEAL_1_6_1/rh73_gcc323/lib/liblcg_SealServices.so
+ 0x401a3000 /afs/cern.ch/sw/lcg/app/releases/SEAL/SEAL_1_6_1/rh73_gcc323/lib/liblcg_SealUtil.so
+ 0x401b1000 /afs/cern.ch/user/a/avalassi/myLCG/COOL_HEAD/rh73_gcc323/lib/liblcg_RelationalCool.so
+ 0x40252000 /afs/cern.ch/sw/lcg/external/CppUnit/1.8.0/rh73_gcc323/lib/libcppunit-1.8.so.0
+ 0x40291000 /lib/libnsl.so.1
+ 0x402a6000 /lib/libcrypt.so.1
+ 0x402d3000 /lib/libdl.so.2
+ 0x402d6000 /afs/cern.ch/sw/lcg/external/pcre/4.4/rh73_gcc323/lib/libpcre.so.0
+ 0x402e3000 /afs/cern.ch/sw/lcg/external/uuid/1.32/rh73_gcc323/lib/libuuid.so.1
+ 0x402e6000 /usr/local/gcc-alt-3.2.3/lib/libstdc++.so.5
+ 0x40397000 /lib/i686/libm.so.6
+ 0x403b9000 /usr/local/gcc-alt-3.2.3/lib/libgcc_s.so.1
+ 0x00000000 /lib/i686/libc.so.6
+ 0x40000000 /lib/ld-linux.so.2
+ 0x403c2000 /afs/cern.ch/sw/lcg/app/releases/POOL/POOL_2_0_2/rh73_gcc323/lib/liblcg_OracleAccess.so
+ 0x40463000 /afs/cern.ch/sw/lcg/external/oracle/10.1.0.3-1/rh73_gcc323/lib/libclntsh.so.10.1
+ 0x40ff3000 /afs/cern.ch/sw/lcg/external/oracle/10.1.0.3-1/rh73_gcc323/lib/libnnz10.so
+ 0x4027d000 /lib/i686/libpthread.so.0
+ 0x42135000 /afs/cern.ch/sw/lcg/external/oracle/10.1.0.3-1/rh73_gcc323/lib/libociei.so
+ 0x41219000 /lib/libnss_files.so.2
+ 0x41223000 /lib/libnss_nisplus.so.2
+ 0x4122e000 /lib/libnss_dns.so.2
+ 0x41232000 /lib/libresolv.so.2
+
+Trace #3  (after pressing CTRL-C)
+--------
+
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT "CURRENT_VALUE", "LASTMOD_DATE" FROM "CONDDB_TEST"."COOLSEGF_FOLDERS_SEQ" FOR UPDATE"
+
+Ctrl-C
+
+unitTest_RelationalCool_RalDatabase_versioning (pid=9127 ppid=4571) received fatal signal 2 (Interrupt)
+signal context:
+  signo  = 2, errno = 0, code = 128 (kernel)
+  pid    = 0, uid = 0
+  value  = (0, (nil))
+  stack  = (2, 0, (nil))
+
+  eip: 0023:420293d5           eflags: 00200216
+  eax: fffffffc   ebx: bfffb810   ecx: 00000008   edx: 4213030c
+  esi: bfffb810   edi: 402c18e8   ebp: bfffb7f8   esp: bfffb7f0
+   ds: 002b        es: 002b        fs: 0000        ss: 002b
+
+  signal esp: bfffb7f0  trap: 0/0  oldmask: 80000000   cr2: 00000000
+
+  FPU:  control = ffff027f
+        status  = ffff0100
+        tag     = ffffffff
+        ip      = 0023:40bec604
+        data    = 002b:4100e2a4
+        state   = 00000100
+    %fp0 = [0000:0000000000000000]
+    %fp1 = [0000:0000000000000000]
+    %fp2 = [0000:0000000000000000]
+    %fp3 = [0000:0000000000000000]
+    %fp4 = [0000:0000000000000000]
+    %fp5 = [0000:0000000000000000]
+    %fp6 = [4009:0000000000008000]
+    %fp7 = [400b:0000000000008000]
+
+stack trace:
+ 0x4003ef46 _ZN4seal9DebugAids10stacktraceEi + 0x66 [/afs/cern.ch/sw/lcg/app/releases/SEAL/SEAL_1_6_1/rh73_gcc323/lib/liblcg_SealBase.so]
+ 0x4006f96a _ZN4seal6Signal9fatalDumpEiP7siginfoPv + 0xda [/afs/cern.ch/sw/lcg/app/releases/SEAL/SEAL_1_6_1/rh73_gcc323/lib/liblcg_SealBase.so]
+ 0x4006f210 _ZN4seal6Signal5fatalEiP7siginfoPv + 0xf0 [/afs/cern.ch/sw/lcg/app/releases/SEAL/SEAL_1_6_1/rh73_gcc323/lib/liblcg_SealBase.so]
+ 0x42029180 ? + 0x42029180 [unitTest_RelationalCool_RalDatabase_versioning]
+ 0x402b8609 ? + 0x402b8609 [/lib/i686/libpthread.so.0]
+ 0x402b9f2c ? + 0x402b9f2c [/lib/i686/libpthread.so.0]
+ 0x402b70f6 __pthread_mutex_lock + 0x86 [/lib/i686/libpthread.so.0]
+ 0x40205705 _ZN4cool11RalDatabase23createGlobalFolderTableERKSs + 0xfc5 [/afs/cern.ch/user/a/avalassi/myLCG/COOL_HEAD/rh73_gcc323/lib/liblcg_RelationalCool.so]
+ 0x402027e7 _ZN4cool11RalDatabase14createDatabaseERKN4pool13AttributeListE + 0x227 [/afs/cern.ch/user/a/avalassi/myLCG/COOL_HEAD/rh73_gcc323/lib/liblcg_RelationalCool.so]
+ 0x40251301 _ZN4cool18RelationalDatabase14createDatabaseEv + 0x371 [/afs/cern.ch/user/a/avalassi/myLCG/COOL_HEAD/rh73_gcc323/lib/liblcg_RelationalCool.so]
+ 0x402479df _ZN4cool11RalDatabase14createDatabaseEv + 0x1f [/afs/cern.ch/user/a/avalassi/myLCG/COOL_HEAD/rh73_gcc323/lib/liblcg_RelationalCool.so]
+ 0x40249ec3 _ZN4cool14RalDatabaseSvc14createDatabaseERKSs + 0x43 [/afs/cern.ch/user/a/avalassi/myLCG/COOL_HEAD/rh73_gcc323/lib/liblcg_RelationalCool.so]
+ 0x4024a9a7 _ZTv0_n16_N4cool14RalDatabaseSvc14createDatabaseERKSs + 0x37 [/afs/cern.ch/user/a/avalassi/myLCG/COOL_HEAD/rh73_gcc323/lib/liblcg_RelationalCool.so]
+ 0x080509b7 _ZN4cool15RalDatabaseTest28test_fetchObjectTableRows_5cEv + 0x57 [unitTest_RelationalCool_RalDatabase_versioning]
+ 0x0805860d _ZN7CppUnit10TestCallerIN4cool15RalDatabaseTestENS_19NoExceptionExpectedEE7runTestEv + 0x3d [unitTest_RelationalCool_RalDatabase_versioning]
+ 0x40296cc5 _ZN7CppUnit8TestCase3runEPNS_10TestResultE + 0x45 [/afs/cern.ch/sw/lcg/external/CppUnit/1.8.0/rh73_gcc323/lib/libcppunit-1.8.so.0]
+ 0x402a00cd _ZN7CppUnit9TestSuite3runEPNS_10TestResultE + 0x3d [/afs/cern.ch/sw/lcg/external/CppUnit/1.8.0/rh73_gcc323/lib/libcppunit-1.8.so.0]
+ 0x402a00cd _ZN7CppUnit9TestSuite3runEPNS_10TestResultE + 0x3d [/afs/cern.ch/sw/lcg/external/CppUnit/1.8.0/rh73_gcc323/lib/libcppunit-1.8.so.0]
+ 0x402a00cd _ZN7CppUnit9TestSuite3runEPNS_10TestResultE + 0x3d [/afs/cern.ch/sw/lcg/external/CppUnit/1.8.0/rh73_gcc323/lib/libcppunit-1.8.so.0]
+ 0x4029f67a _ZN7CppUnit6TextUi10TestRunner7runTestEPNS_4TestEb + 0x4a [/afs/cern.ch/sw/lcg/external/CppUnit/1.8.0/rh73_gcc323/lib/libcppunit-1.8.so.0]
+ 0x4029f387 _ZN7CppUnit6TextUi10TestRunner13runTestByNameESsb + 0x47 [/afs/cern.ch/sw/lcg/external/CppUnit/1.8.0/rh73_gcc323/lib/libcppunit-1.8.so.0]
+ 0x4029f2b2 _ZN7CppUnit6TextUi10TestRunner3runESsbbb + 0x52 [/afs/cern.ch/sw/lcg/external/CppUnit/1.8.0/rh73_gcc323/lib/libcppunit-1.8.so.0]
+ 0x0804e8af main + 0xdf [unitTest_RelationalCool_RalDatabase_versioning]
+ 0x42017589 __libc_start_main + 0x95 [unitTest_RelationalCool_RalDatabase_versioning]
+ 0x0804e6e1 _ZNK4seal4Time6minuteEb + 0x35 [unitTest_RelationalCool_RalDatabase_versioning]
+
+shared libraries present:
+ 0x00000000 /afs/cern.ch/user/a/avalassi/myLCG/COOL_HEAD/rh73_gcc323/tests/bin/unitTest_RelationalCool_RalDatabase_versioning
+ 0x40015000 /afs/cern.ch/sw/lcg/app/releases/SEAL/SEAL_1_6_1/rh73_gcc323/lib/liblcg_SealBase.so
+ 0x4009e000 /afs/cern.ch/sw/lcg/app/releases/POOL/POOL_2_0_2/rh73_gcc323_dbg/lib/liblcg_AttributeList.so
+ 0x400d3000 /afs/cern.ch/sw/lcg/app/releases/POOL/POOL_2_0_2/rh73_gcc323_dbg/lib/liblcg_POOLCore.so
+ 0x400ed000 /afs/cern.ch/sw/lcg/app/releases/SEAL/SEAL_1_6_1/rh73_gcc323/lib/liblcg_PluginManager.so
+ 0x4010f000 /afs/cern.ch/sw/lcg/app/releases/SEAL/SEAL_1_6_1/rh73_gcc323/lib/liblcg_SealKernel.so
+ 0x4012b000 /afs/cern.ch/sw/lcg/app/releases/POOL/POOL_2_0_2/rh73_gcc323_dbg/lib/liblcg_RelationalAccess.so
+ 0x4016a000 /afs/cern.ch/sw/lcg/app/releases/SEAL/SEAL_1_6_1/rh73_gcc323/lib/liblcg_Reflection.so
+ 0x40197000 /afs/cern.ch/sw/lcg/app/releases/SEAL/SEAL_1_6_1/rh73_gcc323/lib/liblcg_SealServices.so
+ 0x401d1000 /afs/cern.ch/sw/lcg/app/releases/SEAL/SEAL_1_6_1/rh73_gcc323/lib/liblcg_SealUtil.so
+ 0x401df000 /afs/cern.ch/user/a/avalassi/myLCG/COOL_HEAD/rh73_gcc323/lib/liblcg_RelationalCool.so
+ 0x40285000 /afs/cern.ch/sw/lcg/external/CppUnit/1.8.0/rh73_gcc323/lib/libcppunit-1.8.so.0
+ 0x402c4000 /lib/libnsl.so.1
+ 0x402d9000 /lib/libcrypt.so.1
+ 0x40306000 /lib/libdl.so.2
+ 0x40309000 /afs/cern.ch/sw/lcg/external/pcre/4.4/rh73_gcc323/lib/libpcre.so.0
+ 0x40316000 /afs/cern.ch/sw/lcg/external/uuid/1.32/rh73_gcc323/lib/libuuid.so.1
+ 0x40319000 /usr/local/gcc-alt-3.2.3/lib/libstdc++.so.5
+ 0x403ca000 /lib/i686/libm.so.6
+ 0x403ec000 /usr/local/gcc-alt-3.2.3/lib/libgcc_s.so.1
+ 0x00000000 /lib/i686/libc.so.6
+ 0x40000000 /lib/ld-linux.so.2
+ 0x403f5000 /afs/cern.ch/sw/lcg/app/releases/POOL/POOL_2_0_2/rh73_gcc323_dbg/lib/liblcg_OracleAccess.so
+ 0x404d6000 /afs/cern.ch/sw/lcg/external/oracle/10.1.0.3-1/rh73_gcc323/lib/libclntsh.so.10.1
+ 0x41066000 /afs/cern.ch/sw/lcg/external/oracle/10.1.0.3-1/rh73_gcc323/lib/libnnz10.so
+ 0x402b0000 /lib/i686/libpthread.so.0
+ 0x42135000 /afs/cern.ch/sw/lcg/external/oracle/10.1.0.3-1/rh73_gcc323/lib/libociei.so
+ 0x4128c000 /lib/libnss_files.so.2
+ 0x41296000 /lib/libnss_nisplus.so.2
+ 0x412a1000 /lib/libnss_dns.so.2
+ 0x412a5000 /lib/libresolv.so.2
+
+Trace #4
+--------
+
+With COOL debug without pthread
+POOL: rh73_gcc323
+COOL: rh73_gcc323 with -g instead of -O2 (modify BuildFile)
+==> segmentation fault (the 1st time it is executed) - trace #4
+
+Here: I may soon crash (seg fault) or hang (mutex lock)
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT "i"."OBJECT_ID", "i"."CHANNEL_ID", "i"."IOV_SINCE", "i"."IOV_UNTIL", "i"."SYS_INSTIME", "i"."ORIGINAL_ID", "i"."NEW_HEAD_ID", "i"."I", "i"."S", "i"."X" FROM "CONDDB_TEST"."COOLSEGF_F0001_IOVS" "i", "CONDDB_TEST"."COOLSEGF_F0001_IOVS" "o" WHERE :"since" <= "i"."IOV_SINCE" and "i"."IOV_UNTIL" < :"until" and "i"."SYS_INSTIME" <= :"asOfDate1" and "i"."CHANNEL_ID" = :"channel" and ( ( "i"."NEW_HEAD_ID" = :"newHeadId" and "i"."OBJECT_ID" = "o"."OBJECT_ID" )  or ( "i"."NEW_HEAD_ID" = "o"."OBJECT_ID" and "o"."SYS_INSTIME" > :"asOfDate2" ) ) ORDER BY "IOV_SINCE" ASC"
+
+unitTest_RelationalCool_RalDatabase_versioning (pid=11582 ppid=4571) received fatal signal 11 (Segmentation fault)
+signal context:
+  signo  = 11, errno = 0, code = 1 (address not mapped to object)
+  pid    = 538976304, uid = 135041708
+  value  = (135041944, 0x80c9398)
+  addr   = 0x20202030
+  stack  = (2, 0, (nil))
+
+  eip: 0023:0805bb39           eflags: 00210202
+  eax: 2020202c   ebx: 08061f64   ecx: 080666d0   edx: 402493f0
+  esi: 08066718   edi: 08066718   ebp: bfffc088   esp: bfffc070
+   ds: 002b        es: 002b        fs: 0000        ss: 002b
+
+  signal esp: bfffc070  trap: 14/4  oldmask: 80000000   cr2: 20202030
+
+  FPU:  control = ffff027f
+        status  = ffff0320
+        tag     = ffffffff
+        ip      = 0023:409a555e
+        data    = 002b:08101144
+        state   = 00000320
+    %fp0 = [0000:0000000000000000]
+    %fp1 = [0000:0000000000000000]
+    %fp2 = [3fdd:7800371b5fe1d0e5]
+    %fp3 = [3ff6:d000ffff6eff8312]
+    %fp4 = [0000:0000000000000000]
+    %fp5 = [0000:0000000000000000]
+    %fp6 = [3ff6:d000ffff6eff8312]
+    %fp7 = [3ff6:d000ffff6eff8312]
+
+stack trace:
+ 0x4003ef46 _ZN4seal9DebugAids10stacktraceEi + 0x66 [/afs/cern.ch/sw/lcg/app/releases/SEAL/SEAL_1_6_1/rh73_gcc323/lib/liblcg_SealBase.so]
+ 0x4006f96a _ZN4seal6Signal9fatalDumpEiP7siginfoPv + 0xda [/afs/cern.ch/sw/lcg/app/releases/SEAL/SEAL_1_6_1/rh73_gcc323/lib/liblcg_SealBase.so]
+ 0x4006f210 _ZN4seal6Signal5fatalEiP7siginfoPv + 0xf0 [/afs/cern.ch/sw/lcg/app/releases/SEAL/SEAL_1_6_1/rh73_gcc323/lib/liblcg_SealBase.so]
+ 0x42029180 ? + 0x42029180 [unitTest_RelationalCool_RalDatabase_versioning]
+ 0x08059542 _ZN4pool26AttributeListSpecificationD1Ev + 0x20 [unitTest_RelationalCool_RalDatabase_versioning]
+ 0x4021f4d3 _ZN5boost14checked_deleteIN4pool26AttributeListSpecificationEEEvPT_ + 0x29 [/afs/cern.ch/user/a/avalassi/myLCG/COOL_HEAD/rh73_gcc323/lib/liblcg_RelationalCool.so]
+ 0x4021e4ab _ZNK5boost15checked_deleterIN4pool26AttributeListSpecificationEEclEPS2_ + 0x1d [/afs/cern.ch/user/a/avalassi/myLCG/COOL_HEAD/rh73_gcc323/lib/liblcg_RelationalCool.so]
+ 0x40224248 _ZN5boost6detail20sp_counted_base_implIPN4pool26AttributeListSpecificationENS_15checked_deleterIS3_EEE7disposeEv + 0x2a [/afs/cern.ch/user/a/avalassi/myLCG/COOL_HEAD/rh73_gcc323/lib/liblcg_RelationalCool.so]
+ 0x0805af9a _ZN5boost6detail15sp_counted_base7releaseEv + 0x38 [unitTest_RelationalCool_RalDatabase_versioning]
+ 0x0805935b _ZN5boost6detail12shared_countD1Ev + 0x27 [unitTest_RelationalCool_RalDatabase_versioning]
+ 0x404132dd _ZN4pool12OracleAccess29OracleQueryWithMultipleTables5resetEv + 0x11d [/afs/cern.ch/sw/lcg/app/releases/POOL/POOL_2_0_2/rh73_gcc323/lib/liblcg_OracleAccess.so]
+ 0x40412fba _ZN4pool12OracleAccess29OracleQueryWithMultipleTablesD0Ev + 0x2a [/afs/cern.ch/sw/lcg/app/releases/POOL/POOL_2_0_2/rh73_gcc323/lib/liblcg_OracleAccess.so]
+ 0x4021ad68 _ZNSt8auto_ptrIN4pool34IRelationalQueryWithMultipleTablesEED1Ev + 0x24 [/afs/cern.ch/user/a/avalassi/myLCG/COOL_HEAD/rh73_gcc323/lib/liblcg_RelationalCool.so]
+ 0x401ff5be _ZN4cool11RalDatabase20fetchObjectTableRowsERKSsRKN4pool26AttributeListSpecificationERKxS8_RKmRKN4seal4TimeE + 0x1aba [/afs/cern.ch/user/a/avalassi/myLCG/COOL_HEAD/rh73_gcc323/lib/liblcg_RelationalCool.so]
+ 0x0805571e _ZN4cool15RalDatabaseTest28test_fetchObjectTableRows_5cEv + 0x9b6 [unitTest_RelationalCool_RalDatabase_versioning]
+ 0x0805ac8c _ZN7CppUnit10TestCallerIN4cool15RalDatabaseTestENS_19NoExceptionExpectedEE7runTestEv + 0x62 [unitTest_RelationalCool_RalDatabase_versioning]
+ 0x40270cc5 _ZN7CppUnit8TestCase3runEPNS_10TestResultE + 0x45 [/afs/cern.ch/sw/lcg/external/CppUnit/1.8.0/rh73_gcc323/lib/libcppunit-1.8.so.0]
+ 0x4027a0cd _ZN7CppUnit9TestSuite3runEPNS_10TestResultE + 0x3d [/afs/cern.ch/sw/lcg/external/CppUnit/1.8.0/rh73_gcc323/lib/libcppunit-1.8.so.0]
+ 0x4027a0cd _ZN7CppUnit9TestSuite3runEPNS_10TestResultE + 0x3d [/afs/cern.ch/sw/lcg/external/CppUnit/1.8.0/rh73_gcc323/lib/libcppunit-1.8.so.0]
+ 0x4027a0cd _ZN7CppUnit9TestSuite3runEPNS_10TestResultE + 0x3d [/afs/cern.ch/sw/lcg/external/CppUnit/1.8.0/rh73_gcc323/lib/libcppunit-1.8.so.0]
+ 0x4027967a _ZN7CppUnit6TextUi10TestRunner7runTestEPNS_4TestEb + 0x4a [/afs/cern.ch/sw/lcg/external/CppUnit/1.8.0/rh73_gcc323/lib/libcppunit-1.8.so.0]
+ 0x40279387 _ZN7CppUnit6TextUi10TestRunner13runTestByNameESsb + 0x47 [/afs/cern.ch/sw/lcg/external/CppUnit/1.8.0/rh73_gcc323/lib/libcppunit-1.8.so.0]
+ 0x402792b2 _ZN7CppUnit6TextUi10TestRunner3runESsbbb + 0x52 [/afs/cern.ch/sw/lcg/external/CppUnit/1.8.0/rh73_gcc323/lib/libcppunit-1.8.so.0]
+ 0x08053107 main + 0x137 [unitTest_RelationalCool_RalDatabase_versioning]
+ 0x42017589 __libc_start_main + 0x95 [unitTest_RelationalCool_RalDatabase_versioning]
+ 0x08052ee1 _ZN7CppUnit14TypeInfoHelper12getClassNameERKSt9type_info + 0x8d [unitTest_RelationalCool_RalDatabase_versioning]
+
+shared libraries present:
+ 0x00000000 /afs/cern.ch/user/a/avalassi/myLCG/COOL_HEAD/rh73_gcc323/tests/bin/unitTest_RelationalCool_RalDatabase_versioning
+ 0x40015000 /afs/cern.ch/sw/lcg/app/releases/SEAL/SEAL_1_6_1/rh73_gcc323/lib/liblcg_SealBase.so
+ 0x4009e000 /afs/cern.ch/sw/lcg/app/releases/POOL/POOL_2_0_2/rh73_gcc323/lib/liblcg_AttributeList.so
+ 0x400c6000 /afs/cern.ch/sw/lcg/app/releases/POOL/POOL_2_0_2/rh73_gcc323/lib/liblcg_POOLCore.so
+ 0x400d6000 /afs/cern.ch/sw/lcg/app/releases/SEAL/SEAL_1_6_1/rh73_gcc323/lib/liblcg_PluginManager.so
+ 0x400f8000 /afs/cern.ch/sw/lcg/app/releases/SEAL/SEAL_1_6_1/rh73_gcc323/lib/liblcg_SealKernel.so
+ 0x40114000 /afs/cern.ch/sw/lcg/app/releases/POOL/POOL_2_0_2/rh73_gcc323/lib/liblcg_RelationalAccess.so
+ 0x4013c000 /afs/cern.ch/sw/lcg/app/releases/SEAL/SEAL_1_6_1/rh73_gcc323/lib/liblcg_Reflection.so
+ 0x40169000 /afs/cern.ch/sw/lcg/app/releases/SEAL/SEAL_1_6_1/rh73_gcc323/lib/liblcg_SealServices.so
+ 0x401a3000 /afs/cern.ch/sw/lcg/app/releases/SEAL/SEAL_1_6_1/rh73_gcc323/lib/liblcg_SealUtil.so
+ 0x401b1000 /afs/cern.ch/user/a/avalassi/myLCG/COOL_HEAD/rh73_gcc323/lib/liblcg_RelationalCool.so
+ 0x4025f000 /afs/cern.ch/sw/lcg/external/CppUnit/1.8.0/rh73_gcc323/lib/libcppunit-1.8.so.0
+ 0x4029e000 /lib/libnsl.so.1
+ 0x402b3000 /lib/libcrypt.so.1
+ 0x402e0000 /lib/libdl.so.2
+ 0x402e3000 /afs/cern.ch/sw/lcg/external/pcre/4.4/rh73_gcc323/lib/libpcre.so.0
+ 0x402f0000 /afs/cern.ch/sw/lcg/external/uuid/1.32/rh73_gcc323/lib/libuuid.so.1
+ 0x402f3000 /usr/local/gcc-alt-3.2.3/lib/libstdc++.so.5
+ 0x403a4000 /lib/i686/libm.so.6
+ 0x403c6000 /usr/local/gcc-alt-3.2.3/lib/libgcc_s.so.1
+ 0x00000000 /lib/i686/libc.so.6
+ 0x40000000 /lib/ld-linux.so.2
+ 0x403cf000 /afs/cern.ch/sw/lcg/app/releases/POOL/POOL_2_0_2/rh73_gcc323/lib/liblcg_OracleAccess.so
+ 0x40470000 /afs/cern.ch/sw/lcg/external/oracle/10.1.0.3-1/rh73_gcc323/lib/libclntsh.so.10.1
+ 0x41000000 /afs/cern.ch/sw/lcg/external/oracle/10.1.0.3-1/rh73_gcc323/lib/libnnz10.so
+ 0x4028a000 /lib/i686/libpthread.so.0
+ 0x42135000 /afs/cern.ch/sw/lcg/external/oracle/10.1.0.3-1/rh73_gcc323/lib/libociei.so
+ 0x41226000 /lib/libnss_files.so.2
+ 0x41230000 /lib/libnss_nisplus.so.2
+ 0x4123b000 /lib/libnss_dns.so.2
+ 0x4123f000 /lib/libresolv.so.2
+Segmentation fault
+
+Trace 5 (after CTRL-C)
+-------
+
+With COOL debug without pthread
+POOL: rh73_gcc323
+COOL: rh73_gcc323 with -g instead of -O2 (modify BuildFile)
+==> segmentation fault (the 1st time it is executed) - trace #4
+==> hangs in mutex lock (from the 2nd time onwards) - trace #5
+
+Here: I may soon crash (seg fault) or hang (mutex lock)
+POOL/RelationalPlugins/oracle        Debug    Prepared statement : "SELECT "i"."OBJECT_ID", "i"."CHANNEL_ID", "i"."IOV_SINCE", "i"."IOV_UNTIL", "i"."SYS_INSTIME", "i"."ORIGINAL_ID", "i"."NEW_HEAD_ID", "i"."I", "i"."S", "i"."X" FROM "CONDDB_TEST"."COOLSEGF_F0001_IOVS" "i", "CONDDB_TEST"."COOLSEGF_F0001_IOVS" "o" WHERE :"since" <= "i"."IOV_SINCE" and "i"."IOV_UNTIL" < :"until" and "i"."SYS_INSTIME" <= :"asOfDate1" and "i"."CHANNEL_ID" = :"channel" and ( ( "i"."NEW_HEAD_ID" = :"newHeadId" and "i"."OBJECT_ID" = "o"."OBJECT_ID" )  or ( "i"."NEW_HEAD_ID" = "o"."OBJECT_ID" and "o"."SYS_INSTIME" > :"asOfDate2" ) ) ORDER BY "IOV_SINCE" ASC"
+
+unitTest_RelationalCool_RalDatabase_versioning (pid=11599 ppid=4571) received fatal signal 2 (Interrupt)
+signal context:
+  signo  = 2, errno = 0, code = 128 (kernel)
+  pid    = 0, uid = 0
+  value  = (0, (nil))
+  stack  = (2, 0, (nil))
+
+  eip: 0023:420293d5           eflags: 00200216
+  eax: fffffffc   ebx: bfffa660   ecx: 00000008   edx: 4213030c
+  esi: bfffa660   edi: 4029b8e8   ebp: bfffa648   esp: bfffa640
+   ds: 002b        es: 002b        fs: 0000        ss: 002b
+
+  signal esp: bfffa640  trap: 0/0  oldmask: 80000000   cr2: 00000000
+
+  FPU:  control = ffff027f
+        status  = ffff0020
+        tag     = ffffffff
+        ip      = 0023:40deda77
+        data    = 002b:bfff59b8
+        state   = 00000020
+    %fp0 = [0000:0000000000000000]
+    %fp1 = [0000:0000000000000000]
+    %fp2 = [0000:0000000000000000]
+    %fp3 = [3ff5:d000ffff6eff8312]
+    %fp4 = [0000:0000000000000000]
+    %fp5 = [4003:00000000c000f44f]
+    %fp6 = [4005:000000000000c800]
+    %fp7 = [4005:000000000000c800]
+
+stack trace:
+ 0x4003ef46 _ZN4seal9DebugAids10stacktraceEi + 0x66 [/afs/cern.ch/sw/lcg/app/releases/SEAL/SEAL_1_6_1/rh73_gcc323/lib/liblcg_SealBase.so]
+ 0x4006f96a _ZN4seal6Signal9fatalDumpEiP7siginfoPv + 0xda [/afs/cern.ch/sw/lcg/app/releases/SEAL/SEAL_1_6_1/rh73_gcc323/lib/liblcg_SealBase.so]
+ 0x4006f210 _ZN4seal6Signal5fatalEiP7siginfoPv + 0xf0 [/afs/cern.ch/sw/lcg/app/releases/SEAL/SEAL_1_6_1/rh73_gcc323/lib/liblcg_SealBase.so]
+ 0x42029180 ? + 0x42029180 [unitTest_RelationalCool_RalDatabase_versioning]
+ 0x40292609 ? + 0x40292609 [/lib/i686/libpthread.so.0]
+ 0x40294449 ? + 0x40294449 [/lib/i686/libpthread.so.0]
+ 0x402910d6 __pthread_mutex_lock + 0x66 [/lib/i686/libpthread.so.0]
+ 0x40416dfa _ZN4pool12OracleAccess29OracleQueryWithMultipleTables7processEv + 0x116a [/afs/cern.ch/sw/lcg/app/releases/POOL/POOL_2_0_2/rh73_gcc323/lib/liblcg_OracleAccess.so]
+ 0x401ff255 _ZN4cool11RalDatabase20fetchObjectTableRowsERKSsRKN4pool26AttributeListSpecificationERKxS8_RKmRKN4seal4TimeE + 0x1751 [/afs/cern.ch/user/a/avalassi/myLCG/COOL_HEAD/rh73_gcc323/lib/liblcg_RelationalCool.so]
+ 0x0805571e _ZN4cool15RalDatabaseTest28test_fetchObjectTableRows_5cEv + 0x9b6 [unitTest_RelationalCool_RalDatabase_versioning]
+ 0x0805ac8c _ZN7CppUnit10TestCallerIN4cool15RalDatabaseTestENS_19NoExceptionExpectedEE7runTestEv + 0x62 [unitTest_RelationalCool_RalDatabase_versioning]
+ 0x40270cc5 _ZN7CppUnit8TestCase3runEPNS_10TestResultE + 0x45 [/afs/cern.ch/sw/lcg/external/CppUnit/1.8.0/rh73_gcc323/lib/libcppunit-1.8.so.0]
+ 0x4027a0cd _ZN7CppUnit9TestSuite3runEPNS_10TestResultE + 0x3d [/afs/cern.ch/sw/lcg/external/CppUnit/1.8.0/rh73_gcc323/lib/libcppunit-1.8.so.0]
+ 0x4027a0cd _ZN7CppUnit9TestSuite3runEPNS_10TestResultE + 0x3d [/afs/cern.ch/sw/lcg/external/CppUnit/1.8.0/rh73_gcc323/lib/libcppunit-1.8.so.0]
+ 0x4027a0cd _ZN7CppUnit9TestSuite3runEPNS_10TestResultE + 0x3d [/afs/cern.ch/sw/lcg/external/CppUnit/1.8.0/rh73_gcc323/lib/libcppunit-1.8.so.0]
+ 0x4027967a _ZN7CppUnit6TextUi10TestRunner7runTestEPNS_4TestEb + 0x4a [/afs/cern.ch/sw/lcg/external/CppUnit/1.8.0/rh73_gcc323/lib/libcppunit-1.8.so.0]
+ 0x40279387 _ZN7CppUnit6TextUi10TestRunner13runTestByNameESsb + 0x47 [/afs/cern.ch/sw/lcg/external/CppUnit/1.8.0/rh73_gcc323/lib/libcppunit-1.8.so.0]
+ 0x402792b2 _ZN7CppUnit6TextUi10TestRunner3runESsbbb + 0x52 [/afs/cern.ch/sw/lcg/external/CppUnit/1.8.0/rh73_gcc323/lib/libcppunit-1.8.so.0]
+ 0x08053107 main + 0x137 [unitTest_RelationalCool_RalDatabase_versioning]
+ 0x42017589 __libc_start_main + 0x95 [unitTest_RelationalCool_RalDatabase_versioning]
+ 0x08052ee1 _ZN7CppUnit14TypeInfoHelper12getClassNameERKSt9type_info + 0x8d [unitTest_RelationalCool_RalDatabase_versioning]
+
+shared libraries present:
+ 0x00000000 /afs/cern.ch/user/a/avalassi/myLCG/COOL_HEAD/rh73_gcc323/tests/bin/unitTest_RelationalCool_RalDatabase_versioning
+ 0x40015000 /afs/cern.ch/sw/lcg/app/releases/SEAL/SEAL_1_6_1/rh73_gcc323/lib/liblcg_SealBase.so
+ 0x4009e000 /afs/cern.ch/sw/lcg/app/releases/POOL/POOL_2_0_2/rh73_gcc323/lib/liblcg_AttributeList.so
+ 0x400c6000 /afs/cern.ch/sw/lcg/app/releases/POOL/POOL_2_0_2/rh73_gcc323/lib/liblcg_POOLCore.so
+ 0x400d6000 /afs/cern.ch/sw/lcg/app/releases/SEAL/SEAL_1_6_1/rh73_gcc323/lib/liblcg_PluginManager.so
+ 0x400f8000 /afs/cern.ch/sw/lcg/app/releases/SEAL/SEAL_1_6_1/rh73_gcc323/lib/liblcg_SealKernel.so
+ 0x40114000 /afs/cern.ch/sw/lcg/app/releases/POOL/POOL_2_0_2/rh73_gcc323/lib/liblcg_RelationalAccess.so
+ 0x4013c000 /afs/cern.ch/sw/lcg/app/releases/SEAL/SEAL_1_6_1/rh73_gcc323/lib/liblcg_Reflection.so
+ 0x40169000 /afs/cern.ch/sw/lcg/app/releases/SEAL/SEAL_1_6_1/rh73_gcc323/lib/liblcg_SealServices.so
+ 0x401a3000 /afs/cern.ch/sw/lcg/app/releases/SEAL/SEAL_1_6_1/rh73_gcc323/lib/liblcg_SealUtil.so
+ 0x401b1000 /afs/cern.ch/user/a/avalassi/myLCG/COOL_HEAD/rh73_gcc323/lib/liblcg_RelationalCool.so
+ 0x4025f000 /afs/cern.ch/sw/lcg/external/CppUnit/1.8.0/rh73_gcc323/lib/libcppunit-1.8.so.0
+ 0x4029e000 /lib/libnsl.so.1
+ 0x402b3000 /lib/libcrypt.so.1
+ 0x402e0000 /lib/libdl.so.2
+ 0x402e3000 /afs/cern.ch/sw/lcg/external/pcre/4.4/rh73_gcc323/lib/libpcre.so.0
+ 0x402f0000 /afs/cern.ch/sw/lcg/external/uuid/1.32/rh73_gcc323/lib/libuuid.so.1
+ 0x402f3000 /usr/local/gcc-alt-3.2.3/lib/libstdc++.so.5
+ 0x403a4000 /lib/i686/libm.so.6
+ 0x403c6000 /usr/local/gcc-alt-3.2.3/lib/libgcc_s.so.1
+ 0x00000000 /lib/i686/libc.so.6
+ 0x40000000 /lib/ld-linux.so.2
+ 0x403cf000 /afs/cern.ch/sw/lcg/app/releases/POOL/POOL_2_0_2/rh73_gcc323/lib/liblcg_OracleAccess.so
+ 0x40470000 /afs/cern.ch/sw/lcg/external/oracle/10.1.0.3-1/rh73_gcc323/lib/libclntsh.so.10.1
+ 0x41000000 /afs/cern.ch/sw/lcg/external/oracle/10.1.0.3-1/rh73_gcc323/lib/libnnz10.so
+ 0x4028a000 /lib/i686/libpthread.so.0
+ 0x42135000 /afs/cern.ch/sw/lcg/external/oracle/10.1.0.3-1/rh73_gcc323/lib/libociei.so
+ 0x41226000 /lib/libnss_files.so.2
+ 0x41230000 /lib/libnss_nisplus.so.2
+ 0x4123b000 /lib/libnss_dns.so.2
+ 0x4123f000 /lib/libresolv.so.2
+
diff --git a/RelationalCool/tests/RalSequence/test_RalSequence.cpp b/RelationalCool/tests/RalSequence/test_RalSequence.cpp
new file mode 100644
index 000000000..6da7d3ef5
--- /dev/null
+++ b/RelationalCool/tests/RalSequence/test_RalSequence.cpp
@@ -0,0 +1,136 @@
+// $Id: test_RalSequence.cpp,v 1.19 2008-04-10 13:57:42 avalassi Exp $
+/**
+
+ @file test_RalSequence.cpp
+ 
+ @author COOL Core Team
+ 
+ @date 2005-12-09
+
+ */
+
+// Include files
+#include "RelationalAccess/ISchema.h"
+
+// Local include files
+#include "CoolDBUnitTest.h"
+#include "src/RalDatabase.h"
+#include "src/RelationalQueryMgr.h"
+#include "src/RelationalSequence.h"
+#include "src/RelationalSequenceMgr.h"
+#include "src/RelationalTransaction.h"
+
+namespace cool {
+  
+
+/**
+ RalSequenceTest tests the behavior of RalSequence
+*/
+ 
+class RalSequenceTest : public cool::CoolDBUnitTest {
+		
+  CPPUNIT_TEST_SUITE( RalSequenceTest );
+		
+  CPPUNIT_TEST( test_createSequence );
+  CPPUNIT_TEST( test_nextVal );
+  CPPUNIT_TEST( test_currVal );
+		
+  CPPUNIT_TEST_SUITE_END();
+		
+public:
+
+  RalDatabase* ralDb;
+
+  void test_currVal() {
+    try {
+      RelationalTransaction transaction( ralDb->transactionMgr() );
+      boost::shared_ptr<RelationalSequence> 
+        seq( ralDb->queryMgr().sequenceMgr().createSequence
+             ( std::string( m_coolDBName + "_SEQ" ) ) );
+      unsigned long id = seq->nextVal();
+      CPPUNIT_ASSERT_EQUAL( 0ul, id );
+      id = seq->currVal();
+      CPPUNIT_ASSERT_EQUAL( 0ul, id );
+      transaction.commit();
+    } catch ( std::exception& e ) {
+      std::cout << e.what() << std::endl;
+      throw;
+    }
+  }
+	
+  
+  void test_nextVal() {
+    try {
+      RelationalTransaction transaction( ralDb->transactionMgr() );
+      boost::shared_ptr<RelationalSequence> 
+        seq( ralDb->queryMgr().sequenceMgr().createSequence
+             ( std::string( m_coolDBName + "_SEQ" ) ) );
+      unsigned long id = seq->nextVal();
+      CPPUNIT_ASSERT_EQUAL( 0ul, id );
+      id = seq->nextVal();
+      CPPUNIT_ASSERT_EQUAL( 1ul, id );
+      id = seq->nextVal();
+      CPPUNIT_ASSERT_EQUAL( 2ul, id );
+      transaction.commit();
+    } catch ( std::exception& e ) {
+      std::cout << e.what() << std::endl;
+      throw;
+    }
+  }
+	
+  
+  void test_createSequence() {
+    {
+      RelationalTransaction transaction( ralDb->transactionMgr() );
+      boost::shared_ptr<RelationalSequence> 
+        nodeSeq( ralDb->queryMgr().sequenceMgr().createSequence
+                 ( std::string( m_coolDBName + "_SEQ" ) ) );
+      transaction.commit();
+    }
+    {
+      RelationalTransaction transaction( ralDb->transactionMgr() );
+      CPPUNIT_ASSERT( ralDb->session().nominalSchema().existsTable
+                      ( std::string( m_coolDBName + "_SEQ" ) ) );
+      transaction.commit();
+    }
+  }
+  
+  
+  void setUp() 
+  {
+    try 
+    {
+      ralDb = new RalDatabase( ppConnectionSvc(), m_connectionString, false );
+    } 
+    catch ( std::exception& e ) 
+    {
+      ralDb = NULL;
+      std::cout << "Exception caught: " << e.what() << std::endl;
+      throw;     
+    }
+  }	
+  
+  void tearDown() 
+  {
+    if ( ralDb ) 
+    {
+      RelationalTransaction transaction( ralDb->transactionMgr() );
+      ralDb->session().nominalSchema().dropIfExistsTable
+        ( std::string( m_coolDBName + "_SEQ" ) );
+      transaction.commit();
+      delete ralDb;
+      ralDb = 0;
+    }
+  }
+
+  RalSequenceTest() : cool::CoolDBUnitTest( false ) // no dbSvc is needed
+  {
+  }
+  
+};
+
+CPPUNIT_TEST_SUITE_REGISTRATION( RalSequenceTest );
+
+} // namespace
+
+COOLTEST_MAIN(RalSequenceTest)
diff --git a/RelationalCool/tests/RelationalDatabaseId/test_RelationalDatabaseId.cpp b/RelationalCool/tests/RelationalDatabaseId/test_RelationalDatabaseId.cpp
new file mode 100644
index 000000000..37a2e520f
--- /dev/null
+++ b/RelationalCool/tests/RelationalDatabaseId/test_RelationalDatabaseId.cpp
@@ -0,0 +1,195 @@
+// $Id: test_RelationalDatabaseId.cpp,v 1.8 2009-02-04 10:57:58 avalassi Exp $
+/**
+
+ @file test_RelationalDatabaseId.cpp
+ 
+ @author Marco Clemencic
+ 
+ @date 2004-11-04
+
+ */
+
+#include "../Common/CppUnit_headers.h" // Disable CppUnit header warnings
+
+#include "src/RelationalDatabaseId.h"
+#include "src/RelationalException.h"
+
+namespace cool {
+  
+
+/**
+ RelationalDatabaseId test class.
+*/
+ 
+class RelationalDatabaseIdTest : public CppUnit::TestFixture {
+		
+  CPPUNIT_TEST_SUITE( RelationalDatabaseIdTest );
+		
+  CPPUNIT_TEST( test_technologies );
+  CPPUNIT_TEST( test_alias );
+  CPPUNIT_TEST( test_alias_role );
+  CPPUNIT_TEST( test_user );
+  CPPUNIT_TEST( test_password );
+  CPPUNIT_TEST( test_cached_urls );
+  CPPUNIT_TEST( test_cached_urls_alias );
+  CPPUNIT_TEST( test_cached_urls_alias_role );
+  CPPUNIT_TEST( test_order );
+		
+  CPPUNIT_TEST( test_missing );
+  CPPUNIT_TEST( test_bad_url );
+		
+  CPPUNIT_TEST( test_middleTier );
+
+  CPPUNIT_TEST_SUITE_END();
+		
+public:
+    
+  void setUp() {}
+		
+  void tearDown() {}
+
+  /// Test
+  void basic_test( const std::string connString,
+                   const std::string middleTier,
+                   const std::string tech, 
+                   const std::string server, 
+                   const std::string schema,
+                   const std::string dbname, 
+                   const std::string user="", 
+                   const std::string password="",
+                   const std::string alias="", 
+                   const std::string role="")
+  {
+    RelationalDatabaseId id(connString);
+
+    std::string msg = "Failed to parse '" + connString + "'";
+
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( msg, middleTier, id.middleTier() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( msg, tech,       id.technology() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( msg, server,     id.server()     );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( msg, schema,     id.schema()     );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( msg, dbname,     id.dbName()     );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( msg, user,       id.user()       );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( msg, password,   id.password()   );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( msg, alias,      id.alias()      );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( msg, role,       id.role()       );
+  }  
+
+  void test_technologies() 
+  {
+    basic_test("oracle://server;schema=theSchema;dbname=DBNAME",
+               "","oracle","server","theSchema","DBNAME");
+    basic_test("mysql://server;schema=theSchema;dbname=DBNAME",
+               "","mysql","server","theSchema","DBNAME");
+    basic_test("sqlite://server;schema=theSchema;dbname=DBNAME",
+               "","sqlite","server","theSchema","DBNAME");
+  }
+  
+  void test_middleTier() 
+  {
+    basic_test
+      ("coralxxx://host:port&oracle://server;schema=theSchema;dbname=DBNAME",
+       "coralxxx://host:port&","oracle","server","theSchema","DBNAME");
+    try 
+    {
+      RelationalDatabaseId
+        id("xxx://host:port&oracle://server;schema=theSchema;dbname=DBNAME");
+      CPPUNIT_FAIL( "middleTier prefix starting with xxx should fail" );
+    } 
+    catch ( RelationalException& ){}
+  }
+  
+  void test_alias() 
+  {
+    basic_test("alias/DBNAME",
+               "","","","","DBNAME","","","alias");
+  }  
+		
+  void test_alias_role() 
+  {
+    basic_test("alias(role)/DBNAME",
+               "","","","","DBNAME","","","alias","role");
+  }  
+		
+  void test_user() 
+  {
+    basic_test("oracle://server;schema=theSchema;dbname=DBNAME;user=theUser",
+               "","oracle","server","theSchema","DBNAME","theUser");
+  }  
+		
+  void test_password() 
+  {
+    basic_test
+      ("oracle://server;schema=theSchema;dbname=DBNAME;password=thePassword",
+       "","oracle","server","theSchema","DBNAME","","thePassword");
+  }
+		
+  void test_cached_urls() 
+  {
+    RelationalDatabaseId id("oracle://server;schema=theSchema;dbname=DBNAME;user=theUser;password=thePassword");
+    CPPUNIT_ASSERT_EQUAL(std::string("oracle://server;schema=theSchema;dbname=DBNAME;user=theUser;password=thePassword"),
+                         id.url());
+    CPPUNIT_ASSERT_EQUAL(std::string("oracle://server;schema=theSchema;dbname=DBNAME;user=theUser;password=********"),
+                         id.urlHidePswd());
+    CPPUNIT_ASSERT_EQUAL(std::string("oracle://server;schema=theSchema;user=theUser;password=thePassword"),
+                         id.urlNoDbname());
+  }
+  
+  void test_cached_urls_alias() 
+  {
+    RelationalDatabaseId id("alias/DBNAME");
+    CPPUNIT_ASSERT_EQUAL(std::string("alias/DBNAME"),
+                         id.url());
+    CPPUNIT_ASSERT_EQUAL(std::string("alias/DBNAME"),
+                         id.urlHidePswd());
+    CPPUNIT_ASSERT_EQUAL(std::string("alias"),
+                         id.urlNoDbname());
+  }
+
+  void test_cached_urls_alias_role() 
+  {
+    RelationalDatabaseId id("alias(role)/DBNAME");
+    CPPUNIT_ASSERT_EQUAL(std::string("alias(role)/DBNAME"),
+                         id.url());
+    CPPUNIT_ASSERT_EQUAL(std::string("alias(role)/DBNAME"),
+                         id.urlHidePswd());
+    CPPUNIT_ASSERT_EQUAL(std::string("alias(role)"),
+                         id.urlNoDbname());
+  }
+
+  void test_order() 
+  {
+    CPPUNIT_ASSERT_EQUAL(std::string("oracle://server;schema=theSchema;dbname=DBNAME;user=theUser;password=thePassword"),
+                         RelationalDatabaseId("oracle://server;user=theUser;dbname=DBNAME;schema=theSchema;password=thePassword")
+                         .url());
+  }
+		
+  void test_missing() 
+  {
+    CPPUNIT_ASSERT_THROW(RelationalDatabaseId("oracle://server;dbname=DBNAME;user=theUser;password=thePassword"),
+                         RelationalException);
+    CPPUNIT_ASSERT_THROW(RelationalDatabaseId("oracle://server;schema=theSchema;user=theUser;password=thePassword"),
+                         RelationalException);
+    CPPUNIT_ASSERT_THROW(RelationalDatabaseId("alias/"),
+                         RelationalException);
+  }
+		
+  void test_bad_url() 
+  {
+    CPPUNIT_ASSERT_THROW(RelationalDatabaseId("abcd://server;schema=theSchema;dbname=DBNAME;user=theUser;password=thePassword"),
+                         RelationalException);
+    CPPUNIT_ASSERT_THROW(RelationalDatabaseId("bad:url"),
+                         RelationalException);
+  }
+		
+};
+
+CPPUNIT_TEST_SUITE_REGISTRATION( RelationalDatabaseIdTest );
+
+} // namespace
+
+// sas: This file is from the OPAL package I believe. It allows for
+// shorter test classes and prepares the test class for OPAL
+#include<CppUnit_testdriver.icpp>
+
+
diff --git a/RelationalCool/tests/RelationalFolder/README.tests b/RelationalCool/tests/RelationalFolder/README.tests
new file mode 100755
index 000000000..011a1e0bb
--- /dev/null
+++ b/RelationalCool/tests/RelationalFolder/README.tests
@@ -0,0 +1,40 @@
+The four log files contain the results of the tests executed by building 
+a stripped down version of test_RelationalFolder.cpp, i.e. essentially 
+test_RelationalFolder.cpp.gmtime (only test_gmtime_timegm enabled, with 
+verbose output, empty setup, and tests enabled for isdst=0, -1 and +1).
+
+- out.Windows.p1.adjustTimeZone
+
+From test_RelationalFolder.cpp.gmtime (both +1 and -1 tests enabled).
+It fails on isdst=+1 in January.
+Executed with PC clock set to "automatically adjust summer time".
+
+- out.Windows.m1.adjustTimeZone
+
+From test_RelationalFolder.cpp.gmtime modified so that the isdst=+1
+test is disabled. It fails on isdst=-1 in April.
+Executed with PC clock set to "automatically adjust summer time".
+
+- out.Windows.noTest.adjustTimeZone
+
+From test_RelationalFolder.cpp.gmtime modified so that the isdst=+1
+and isdst=-1 tests are both disabled. It succeeds but prints out all.
+Executed with PC clock set to "automatically adjust summer time".
+
+- out.Windows.doNotAdjustTimeZone
+
+From test_RelationalFolder.cpp.gmtime (both +1 and -1 tests enabled),
+i.e. the same setup as for out.Windows.p1.adjustTimeZone. It succeeds.
+Executed with PC clock set to "DO NOT automatically adjust summer time".
+
+-------------------------------------------------------------------------------
+
+For reference, the executable is rebuilt using the following two commands:
+
+cl.exe /nologo /c /I\\afs\all\cern.ch\sw\lcg\app\releases\COOL\COOL_1_2_0\src\RelationalCool /I\\afs\all\cern.ch\sw\lcg\app\releases\COOL\COOL_1_2_0\src\CoolKernel /I\\afs\all\cern.ch\sw\lcg\app\releases\SEAL\SEAL_1_6_3\src\Foundation\SealBase /IL:\cygwin\win32_vc71_dbg\include /I\\afs\all\cern.ch\sw\lcg\app\releases\SEAL\SEAL_1_6_3\src\Foundation\SealPlatform /I\\afs\all\cern.ch\sw\lcg\app\releases\POOL\POOL_2_1_0\src\AttributeList /I\\afs\all\cern.ch\sw\lcg\app\releases\POOL\POOL_2_1_0\src\POOLCore /I\\afs\all\cern.ch\sw\lcg\app\releases\SEAL\SEAL_1_6_3\src\Framework\SealKernel /I\\afs\all\cern.ch\sw\lcg\app\releases\SEAL\SEAL_1_6_3\src\Foundation\PluginManager /I\\afs\all\cern.ch\sw\lcg\app\releases\POOL\POOL_2_1_0\src\RelationalAccess /I\\afs\all\cern.ch\sw\lcg\app\releases\SEAL\SEAL_1_6_3\src\Foundation\SealUtil /I\\afs\all\cern.ch\sw\lcg\app\releases\COOL\COOL_1_2_0\src\CoolApplication /I\\afs\all\cern.ch\sw\lcg\app\releases\SEAL\SEAL_1_6_3\src\Dictionary\Reflection /I\\afs\all\cern.ch\sw\lcg\app\releases\SEAL\SEAL_1_6_3\src\Framework\SealServices /I\\afs\all\cern.ch\sw\lcg\app\releases\COOL\COOL_1_2_0\src\RelationalCool\tests\Common /I\\afs\all\cern.ch\sw\lcg\external\uuid\1.32\win32_vc71\include /I\\afs\all\cern.ch\sw\lcg\external\Boost\1.31.0\win32_vc71\include\boost-1_31 /I\\afs\all\cern.ch\sw\lcg\external\CppUnit\1.8.0\win32_vc71\include /I\\afs\all\cern.ch\sw\lcg\external\pcre\4.4\win32_vc71\include /I\\afs\all\cern.ch\sw\lcg\app\releases\SEAL\SEAL_1_6_3\src /I\\afs\all\cern.ch\sw\lcg\app\releases\SEAL\SEAL_1_6_3\win32_vc71_dbg\include /I\\afs\all\cern.ch\sw\lcg\app\releases\POOL\POOL_2_1_0\src /Ic:\Program\ Files\Microsoft\ Visual\ Studio\ .NET\ 2003\VC7\include /Ic:\Program\ Files\Microsoft\ Visual\ Studio\ .NET\ 2003\VC7\PlatformSDK\Include /D_GNU_SOURCE /DGNU_SOURCE /DWIN32 /D_MBCS /D_WINDOWS /DSEAL_KERNEL_BUILD_ARCHIVE /D_DEBUG /W3 /WL /GR /GX /GF /GS /MD /Zm500 /Od /Z7 /Fo\\afs\all\cern.ch\sw\lcg\app\releases\COOL\COOL_1_2_0\tmp\win32_vc71_dbg\src\RelationalCool\tests\RelationalFolder\test_RelationalFolder.obj \\afs\all\cern.ch\sw\lcg\app\releases\COOL\COOL_1_2_0\src\RelationalCool\tests\RelationalFolder\test_RelationalFolder.cpp
+
+link.exe /NOLOGO /OUT:\\afs\all\cern.ch\sw\lcg\app\releases\COOL\COOL_1_2_0\win32_vc71_dbg\tests\bin\unitTest_RelationalCool_RelationalFolder.exe /EXETYPE:DYNAMIC /DEBUG /INCREMENTAL:NO /LIBPATH:\\afs\all\cern.ch\sw\lcg\app\releases\COOL\COOL_1_2_0\win32_vc71_dbg\lib /LIBPATH:\\afs\all\cern.ch\sw\lcg\external\uuid\1.32\win32_vc71\lib /LIBPATH:\\afs\all\cern.ch\sw\lcg\external\Boost\1.31.0\win32_vc71\lib /LIBPATH:\\afs\all\cern.ch\sw\lcg\external\CppUnit\1.8.0\win32_vc71\lib /LIBPATH:\\afs\all\cern.ch\sw\lcg\external\pcre\4.4\win32_vc71\lib /LIBPATH:\\afs\all\cern.ch\sw\lcg\app\releases\SEAL\SEAL_1_6_3\win32_vc71_dbg\lib /LIBPATH:\\afs\all\cern.ch\sw\lcg\app\releases\POOL\POOL_2_1_0\win32_vc71_dbg\lib /LIBPATH:c:\Program\ Files\Microsoft\ Visual\ Studio\ .NET\ 2003\VC7\lib /LIBPATH:c:\Program\ Files\Microsoft\ Visual\ Studio\ .NET\ 2003\VC7\PlatformSDK\Lib lcg_SealBase.lib lcg_AttributeList.lib lcg_POOLCore.lib lcg_PluginManager.lib lcg_SealKernel.lib lcg_RelationalAccess.lib lcg_SealUtil.lib lcg_RelationalCool.lib lcg_CoolApplication.lib lcg_Reflection.lib lcg_SealServices.lib uuid.lib cppunit_dll.lib libpcre.lib /nodefaultlib kernel32.lib user32.lib msvcprt.lib msvcrt.lib oldnames.lib \\afs\all\cern.ch\sw\lcg\app\releases\COOL\COOL_1_2_0\tmp\win32_vc71_dbg\src\RelationalCool\tests\RelationalFolder\test_RelationalFolder.obj
+
+
+
+
diff --git a/RelationalCool/tests/RelationalFolder/out.Windows.doNotAdjustTimeZone b/RelationalCool/tests/RelationalFolder/out.Windows.doNotAdjustTimeZone
new file mode 100755
index 000000000..3847dab88
--- /dev/null
+++ b/RelationalCool/tests/RelationalFolder/out.Windows.doNotAdjustTimeZone
@@ -0,0 +1,183 @@
+Test test_gmtime_timegm
+Before setting isdst:  aTm = 1970-1-3 12:1:2
+Before calling timegm: aTm = 1970-1-3 12:1:2 (DST=-1)
+After  calling timegm: aTm = 1970-1-3 12:1:2 (DST=0)
+Before calling timegm: aTm = 1970-1-3 12:1:2 (DST=0)
+After  calling timegm: aTm = 1970-1-3 12:1:2 (DST=0)
+Before calling timegm: aTm = 1970-1-3 12:1:2 (DST=1)
+After  calling timegm: aTm = 1970-1-3 12:1:2 (DST=0)
+aTm = 1970-1-3 12:1:2 (DST=-1,0,+1)
+aTimetM1 = 216062
+aTmM1 = 1970-1-3 12:1:2 (DST=0)
+aTimet0 = 216062
+aTm0 = 1970-1-3 12:1:2 (DST=0)
+aTimetP1 = 216062
+aTmP1 = 1970-1-3 12:1:2 (DST=0)
+Test test_gmtime_timegm
+Before setting isdst:  aTm = 1970-2-3 12:1:2
+Before calling timegm: aTm = 1970-2-3 12:1:2 (DST=-1)
+After  calling timegm: aTm = 1970-2-3 12:1:2 (DST=0)
+Before calling timegm: aTm = 1970-2-3 12:1:2 (DST=0)
+After  calling timegm: aTm = 1970-2-3 12:1:2 (DST=0)
+Before calling timegm: aTm = 1970-2-3 12:1:2 (DST=1)
+After  calling timegm: aTm = 1970-2-3 12:1:2 (DST=0)
+aTm = 1970-2-3 12:1:2 (DST=-1,0,+1)
+aTimetM1 = 2894462
+aTmM1 = 1970-2-3 12:1:2 (DST=0)
+aTimet0 = 2894462
+aTm0 = 1970-2-3 12:1:2 (DST=0)
+aTimetP1 = 2894462
+aTmP1 = 1970-2-3 12:1:2 (DST=0)
+Test test_gmtime_timegm
+Before setting isdst:  aTm = 1970-3-3 12:1:2
+Before calling timegm: aTm = 1970-3-3 12:1:2 (DST=-1)
+After  calling timegm: aTm = 1970-3-3 12:1:2 (DST=0)
+Before calling timegm: aTm = 1970-3-3 12:1:2 (DST=0)
+After  calling timegm: aTm = 1970-3-3 12:1:2 (DST=0)
+Before calling timegm: aTm = 1970-3-3 12:1:2 (DST=1)
+After  calling timegm: aTm = 1970-3-3 12:1:2 (DST=0)
+aTm = 1970-3-3 12:1:2 (DST=-1,0,+1)
+aTimetM1 = 5313662
+aTmM1 = 1970-3-3 12:1:2 (DST=0)
+aTimet0 = 5313662
+aTm0 = 1970-3-3 12:1:2 (DST=0)
+aTimetP1 = 5313662
+aTmP1 = 1970-3-3 12:1:2 (DST=0)
+Test test_gmtime_timegm
+Before setting isdst:  aTm = 1970-4-3 12:1:2
+Before calling timegm: aTm = 1970-4-3 12:1:2 (DST=-1)
+After  calling timegm: aTm = 1970-4-3 12:1:2 (DST=0)
+Before calling timegm: aTm = 1970-4-3 12:1:2 (DST=0)
+After  calling timegm: aTm = 1970-4-3 12:1:2 (DST=0)
+Before calling timegm: aTm = 1970-4-3 12:1:2 (DST=1)
+After  calling timegm: aTm = 1970-4-3 12:1:2 (DST=0)
+aTm = 1970-4-3 12:1:2 (DST=-1,0,+1)
+aTimetM1 = 7992062
+aTmM1 = 1970-4-3 12:1:2 (DST=0)
+aTimet0 = 7992062
+aTm0 = 1970-4-3 12:1:2 (DST=0)
+aTimetP1 = 7992062
+aTmP1 = 1970-4-3 12:1:2 (DST=0)
+Test test_gmtime_timegm
+Before setting isdst:  aTm = 1970-5-3 12:1:2
+Before calling timegm: aTm = 1970-5-3 12:1:2 (DST=-1)
+After  calling timegm: aTm = 1970-5-3 12:1:2 (DST=0)
+Before calling timegm: aTm = 1970-5-3 12:1:2 (DST=0)
+After  calling timegm: aTm = 1970-5-3 12:1:2 (DST=0)
+Before calling timegm: aTm = 1970-5-3 12:1:2 (DST=1)
+After  calling timegm: aTm = 1970-5-3 12:1:2 (DST=0)
+aTm = 1970-5-3 12:1:2 (DST=-1,0,+1)
+aTimetM1 = 10584062
+aTmM1 = 1970-5-3 12:1:2 (DST=0)
+aTimet0 = 10584062
+aTm0 = 1970-5-3 12:1:2 (DST=0)
+aTimetP1 = 10584062
+aTmP1 = 1970-5-3 12:1:2 (DST=0)
+Test test_gmtime_timegm
+Before setting isdst:  aTm = 1970-6-3 12:1:2
+Before calling timegm: aTm = 1970-6-3 12:1:2 (DST=-1)
+After  calling timegm: aTm = 1970-6-3 12:1:2 (DST=0)
+Before calling timegm: aTm = 1970-6-3 12:1:2 (DST=0)
+After  calling timegm: aTm = 1970-6-3 12:1:2 (DST=0)
+Before calling timegm: aTm = 1970-6-3 12:1:2 (DST=1)
+After  calling timegm: aTm = 1970-6-3 12:1:2 (DST=0)
+aTm = 1970-6-3 12:1:2 (DST=-1,0,+1)
+aTimetM1 = 13262462
+aTmM1 = 1970-6-3 12:1:2 (DST=0)
+aTimet0 = 13262462
+aTm0 = 1970-6-3 12:1:2 (DST=0)
+aTimetP1 = 13262462
+aTmP1 = 1970-6-3 12:1:2 (DST=0)
+Test test_gmtime_timegm
+Before setting isdst:  aTm = 1970-7-3 12:1:2
+Before calling timegm: aTm = 1970-7-3 12:1:2 (DST=-1)
+After  calling timegm: aTm = 1970-7-3 12:1:2 (DST=0)
+Before calling timegm: aTm = 1970-7-3 12:1:2 (DST=0)
+After  calling timegm: aTm = 1970-7-3 12:1:2 (DST=0)
+Before calling timegm: aTm = 1970-7-3 12:1:2 (DST=1)
+After  calling timegm: aTm = 1970-7-3 12:1:2 (DST=0)
+aTm = 1970-7-3 12:1:2 (DST=-1,0,+1)
+aTimetM1 = 15854462
+aTmM1 = 1970-7-3 12:1:2 (DST=0)
+aTimet0 = 15854462
+aTm0 = 1970-7-3 12:1:2 (DST=0)
+aTimetP1 = 15854462
+aTmP1 = 1970-7-3 12:1:2 (DST=0)
+Test test_gmtime_timegm
+Before setting isdst:  aTm = 1970-8-3 12:1:2
+Before calling timegm: aTm = 1970-8-3 12:1:2 (DST=-1)
+After  calling timegm: aTm = 1970-8-3 12:1:2 (DST=0)
+Before calling timegm: aTm = 1970-8-3 12:1:2 (DST=0)
+After  calling timegm: aTm = 1970-8-3 12:1:2 (DST=0)
+Before calling timegm: aTm = 1970-8-3 12:1:2 (DST=1)
+After  calling timegm: aTm = 1970-8-3 12:1:2 (DST=0)
+aTm = 1970-8-3 12:1:2 (DST=-1,0,+1)
+aTimetM1 = 18532862
+aTmM1 = 1970-8-3 12:1:2 (DST=0)
+aTimet0 = 18532862
+aTm0 = 1970-8-3 12:1:2 (DST=0)
+aTimetP1 = 18532862
+aTmP1 = 1970-8-3 12:1:2 (DST=0)
+Test test_gmtime_timegm
+Before setting isdst:  aTm = 1970-9-3 12:1:2
+Before calling timegm: aTm = 1970-9-3 12:1:2 (DST=-1)
+After  calling timegm: aTm = 1970-9-3 12:1:2 (DST=0)
+Before calling timegm: aTm = 1970-9-3 12:1:2 (DST=0)
+After  calling timegm: aTm = 1970-9-3 12:1:2 (DST=0)
+Before calling timegm: aTm = 1970-9-3 12:1:2 (DST=1)
+After  calling timegm: aTm = 1970-9-3 12:1:2 (DST=0)
+aTm = 1970-9-3 12:1:2 (DST=-1,0,+1)
+aTimetM1 = 21211262
+aTmM1 = 1970-9-3 12:1:2 (DST=0)
+aTimet0 = 21211262
+aTm0 = 1970-9-3 12:1:2 (DST=0)
+aTimetP1 = 21211262
+aTmP1 = 1970-9-3 12:1:2 (DST=0)
+Test test_gmtime_timegm
+Before setting isdst:  aTm = 1970-10-3 12:1:2
+Before calling timegm: aTm = 1970-10-3 12:1:2 (DST=-1)
+After  calling timegm: aTm = 1970-10-3 12:1:2 (DST=0)
+Before calling timegm: aTm = 1970-10-3 12:1:2 (DST=0)
+After  calling timegm: aTm = 1970-10-3 12:1:2 (DST=0)
+Before calling timegm: aTm = 1970-10-3 12:1:2 (DST=1)
+After  calling timegm: aTm = 1970-10-3 12:1:2 (DST=0)
+aTm = 1970-10-3 12:1:2 (DST=-1,0,+1)
+aTimetM1 = 23803262
+aTmM1 = 1970-10-3 12:1:2 (DST=0)
+aTimet0 = 23803262
+aTm0 = 1970-10-3 12:1:2 (DST=0)
+aTimetP1 = 23803262
+aTmP1 = 1970-10-3 12:1:2 (DST=0)
+Test test_gmtime_timegm
+Before setting isdst:  aTm = 1970-11-3 12:1:2
+Before calling timegm: aTm = 1970-11-3 12:1:2 (DST=-1)
+After  calling timegm: aTm = 1970-11-3 12:1:2 (DST=0)
+Before calling timegm: aTm = 1970-11-3 12:1:2 (DST=0)
+After  calling timegm: aTm = 1970-11-3 12:1:2 (DST=0)
+Before calling timegm: aTm = 1970-11-3 12:1:2 (DST=1)
+After  calling timegm: aTm = 1970-11-3 12:1:2 (DST=0)
+aTm = 1970-11-3 12:1:2 (DST=-1,0,+1)
+aTimetM1 = 26481662
+aTmM1 = 1970-11-3 12:1:2 (DST=0)
+aTimet0 = 26481662
+aTm0 = 1970-11-3 12:1:2 (DST=0)
+aTimetP1 = 26481662
+aTmP1 = 1970-11-3 12:1:2 (DST=0)
+Test test_gmtime_timegm
+Before setting isdst:  aTm = 1970-12-3 12:1:2
+Before calling timegm: aTm = 1970-12-3 12:1:2 (DST=-1)
+After  calling timegm: aTm = 1970-12-3 12:1:2 (DST=0)
+Before calling timegm: aTm = 1970-12-3 12:1:2 (DST=0)
+After  calling timegm: aTm = 1970-12-3 12:1:2 (DST=0)
+Before calling timegm: aTm = 1970-12-3 12:1:2 (DST=1)
+After  calling timegm: aTm = 1970-12-3 12:1:2 (DST=0)
+aTm = 1970-12-3 12:1:2 (DST=-1,0,+1)
+aTimetM1 = 29073662
+aTmM1 = 1970-12-3 12:1:2 (DST=0)
+aTimet0 = 29073662
+aTm0 = 1970-12-3 12:1:2 (DST=0)
+aTimetP1 = 29073662
+aTmP1 = 1970-12-3 12:1:2 (DST=0)
+
+OK (1)
+[OVAL] Cppunit-result =0
diff --git a/RelationalCool/tests/RelationalFolder/out.Windows.m1.adjustTimeZone b/RelationalCool/tests/RelationalFolder/out.Windows.m1.adjustTimeZone
new file mode 100755
index 000000000..33cc7477d
--- /dev/null
+++ b/RelationalCool/tests/RelationalFolder/out.Windows.m1.adjustTimeZone
@@ -0,0 +1,74 @@
+Test test_gmtime_timegm
+Before setting isdst:  aTm = 1970-1-3 12:1:2
+Before calling timegm: aTm = 1970-1-3 12:1:2 (DST=-1)
+After  calling timegm: aTm = 1970-1-3 12:1:2 (DST=0)
+Before calling timegm: aTm = 1970-1-3 12:1:2 (DST=0)
+After  calling timegm: aTm = 1970-1-3 12:1:2 (DST=0)
+Before calling timegm: aTm = 1970-1-3 12:1:2 (DST=1)
+After  calling timegm: aTm = 1970-1-3 11:1:2 (DST=0)
+aTm = 1970-1-3 12:1:2 (DST=-1,0,+1)
+aTimetM1 = 216062
+aTmM1 = 1970-1-3 12:1:2 (DST=0)
+aTimet0 = 216062
+aTm0 = 1970-1-3 12:1:2 (DST=0)
+aTimetP1 = 212462
+aTmP1 = 1970-1-3 11:1:2 (DST=0)
+Test test_gmtime_timegm
+Before setting isdst:  aTm = 1970-2-3 12:1:2
+Before calling timegm: aTm = 1970-2-3 12:1:2 (DST=-1)
+After  calling timegm: aTm = 1970-2-3 12:1:2 (DST=0)
+Before calling timegm: aTm = 1970-2-3 12:1:2 (DST=0)
+After  calling timegm: aTm = 1970-2-3 12:1:2 (DST=0)
+Before calling timegm: aTm = 1970-2-3 12:1:2 (DST=1)
+After  calling timegm: aTm = 1970-2-3 11:1:2 (DST=0)
+aTm = 1970-2-3 12:1:2 (DST=-1,0,+1)
+aTimetM1 = 2894462
+aTmM1 = 1970-2-3 12:1:2 (DST=0)
+aTimet0 = 2894462
+aTm0 = 1970-2-3 12:1:2 (DST=0)
+aTimetP1 = 2890862
+aTmP1 = 1970-2-3 11:1:2 (DST=0)
+Test test_gmtime_timegm
+Before setting isdst:  aTm = 1970-3-3 12:1:2
+Before calling timegm: aTm = 1970-3-3 12:1:2 (DST=-1)
+After  calling timegm: aTm = 1970-3-3 12:1:2 (DST=0)
+Before calling timegm: aTm = 1970-3-3 12:1:2 (DST=0)
+After  calling timegm: aTm = 1970-3-3 12:1:2 (DST=0)
+Before calling timegm: aTm = 1970-3-3 12:1:2 (DST=1)
+After  calling timegm: aTm = 1970-3-3 11:1:2 (DST=0)
+aTm = 1970-3-3 12:1:2 (DST=-1,0,+1)
+aTimetM1 = 5313662
+aTmM1 = 1970-3-3 12:1:2 (DST=0)
+aTimet0 = 5313662
+aTm0 = 1970-3-3 12:1:2 (DST=0)
+aTimetP1 = 5310062
+aTmP1 = 1970-3-3 11:1:2 (DST=0)
+Test test_gmtime_timegm
+Before setting isdst:  aTm = 1970-4-3 12:1:2
+Before calling timegm: aTm = 1970-4-3 12:1:2 (DST=-1)
+After  calling timegm: aTm = 1970-4-3 12:1:2 (DST=1)
+Before calling timegm: aTm = 1970-4-3 12:1:2 (DST=0)
+After  calling timegm: aTm = 1970-4-3 13:1:2 (DST=1)
+Before calling timegm: aTm = 1970-4-3 12:1:2 (DST=1)
+After  calling timegm: aTm = 1970-4-3 12:1:2 (DST=1)
+aTm = 1970-4-3 12:1:2 (DST=-1,0,+1)
+aTimetM1 = 7988462
+aTmM1 = 1970-4-3 11:1:2 (DST=0)
+aTimet0 = 7992062
+aTm0 = 1970-4-3 12:1:2 (DST=0)
+aTimetP1 = 7988462
+aTmP1 = 1970-4-3 11:1:2 (DST=0)
+
+\afs\all\cern.ch\sw\lcg\app\releases\COOL\COOL_1_2_0\src\RelationalCool\tests\RelationalFolder\test_RelationalFolder.cpp(284) : Assertion
+Test name: cool::RelationalFolderTest.test_gmtime_timegm
+- Expected : 12
+
+- Actual   : 11
+
+gmtime(timegm(tm,isDst=-1))==tm : hour (Month[0-11]=3)
+
+
+Failures !!!
+Run: 1   Failure total: 1   Failures: 1   Errors: 0
+Error: CppUnit Failures
+[OVAL] Cppunit-result =1
diff --git a/RelationalCool/tests/RelationalFolder/out.Windows.noTest.adjustTimeZone b/RelationalCool/tests/RelationalFolder/out.Windows.noTest.adjustTimeZone
new file mode 100755
index 000000000..59c485efb
--- /dev/null
+++ b/RelationalCool/tests/RelationalFolder/out.Windows.noTest.adjustTimeZone
@@ -0,0 +1,183 @@
+Test test_gmtime_timegm
+Before setting isdst:  aTm = 1970-1-3 12:1:2
+Before calling timegm: aTm = 1970-1-3 12:1:2 (DST=-1)
+After  calling timegm: aTm = 1970-1-3 12:1:2 (DST=0)
+Before calling timegm: aTm = 1970-1-3 12:1:2 (DST=0)
+After  calling timegm: aTm = 1970-1-3 12:1:2 (DST=0)
+Before calling timegm: aTm = 1970-1-3 12:1:2 (DST=1)
+After  calling timegm: aTm = 1970-1-3 11:1:2 (DST=0)
+aTm = 1970-1-3 12:1:2 (DST=-1,0,+1)
+aTimetM1 = 216062
+aTmM1 = 1970-1-3 12:1:2 (DST=0)
+aTimet0 = 216062
+aTm0 = 1970-1-3 12:1:2 (DST=0)
+aTimetP1 = 212462
+aTmP1 = 1970-1-3 11:1:2 (DST=0)
+Test test_gmtime_timegm
+Before setting isdst:  aTm = 1970-2-3 12:1:2
+Before calling timegm: aTm = 1970-2-3 12:1:2 (DST=-1)
+After  calling timegm: aTm = 1970-2-3 12:1:2 (DST=0)
+Before calling timegm: aTm = 1970-2-3 12:1:2 (DST=0)
+After  calling timegm: aTm = 1970-2-3 12:1:2 (DST=0)
+Before calling timegm: aTm = 1970-2-3 12:1:2 (DST=1)
+After  calling timegm: aTm = 1970-2-3 11:1:2 (DST=0)
+aTm = 1970-2-3 12:1:2 (DST=-1,0,+1)
+aTimetM1 = 2894462
+aTmM1 = 1970-2-3 12:1:2 (DST=0)
+aTimet0 = 2894462
+aTm0 = 1970-2-3 12:1:2 (DST=0)
+aTimetP1 = 2890862
+aTmP1 = 1970-2-3 11:1:2 (DST=0)
+Test test_gmtime_timegm
+Before setting isdst:  aTm = 1970-3-3 12:1:2
+Before calling timegm: aTm = 1970-3-3 12:1:2 (DST=-1)
+After  calling timegm: aTm = 1970-3-3 12:1:2 (DST=0)
+Before calling timegm: aTm = 1970-3-3 12:1:2 (DST=0)
+After  calling timegm: aTm = 1970-3-3 12:1:2 (DST=0)
+Before calling timegm: aTm = 1970-3-3 12:1:2 (DST=1)
+After  calling timegm: aTm = 1970-3-3 11:1:2 (DST=0)
+aTm = 1970-3-3 12:1:2 (DST=-1,0,+1)
+aTimetM1 = 5313662
+aTmM1 = 1970-3-3 12:1:2 (DST=0)
+aTimet0 = 5313662
+aTm0 = 1970-3-3 12:1:2 (DST=0)
+aTimetP1 = 5310062
+aTmP1 = 1970-3-3 11:1:2 (DST=0)
+Test test_gmtime_timegm
+Before setting isdst:  aTm = 1970-4-3 12:1:2
+Before calling timegm: aTm = 1970-4-3 12:1:2 (DST=-1)
+After  calling timegm: aTm = 1970-4-3 12:1:2 (DST=1)
+Before calling timegm: aTm = 1970-4-3 12:1:2 (DST=0)
+After  calling timegm: aTm = 1970-4-3 13:1:2 (DST=1)
+Before calling timegm: aTm = 1970-4-3 12:1:2 (DST=1)
+After  calling timegm: aTm = 1970-4-3 12:1:2 (DST=1)
+aTm = 1970-4-3 12:1:2 (DST=-1,0,+1)
+aTimetM1 = 7988462
+aTmM1 = 1970-4-3 11:1:2 (DST=0)
+aTimet0 = 7992062
+aTm0 = 1970-4-3 12:1:2 (DST=0)
+aTimetP1 = 7988462
+aTmP1 = 1970-4-3 11:1:2 (DST=0)
+Test test_gmtime_timegm
+Before setting isdst:  aTm = 1970-5-3 12:1:2
+Before calling timegm: aTm = 1970-5-3 12:1:2 (DST=-1)
+After  calling timegm: aTm = 1970-5-3 12:1:2 (DST=1)
+Before calling timegm: aTm = 1970-5-3 12:1:2 (DST=0)
+After  calling timegm: aTm = 1970-5-3 13:1:2 (DST=1)
+Before calling timegm: aTm = 1970-5-3 12:1:2 (DST=1)
+After  calling timegm: aTm = 1970-5-3 12:1:2 (DST=1)
+aTm = 1970-5-3 12:1:2 (DST=-1,0,+1)
+aTimetM1 = 10580462
+aTmM1 = 1970-5-3 11:1:2 (DST=0)
+aTimet0 = 10584062
+aTm0 = 1970-5-3 12:1:2 (DST=0)
+aTimetP1 = 10580462
+aTmP1 = 1970-5-3 11:1:2 (DST=0)
+Test test_gmtime_timegm
+Before setting isdst:  aTm = 1970-6-3 12:1:2
+Before calling timegm: aTm = 1970-6-3 12:1:2 (DST=-1)
+After  calling timegm: aTm = 1970-6-3 12:1:2 (DST=1)
+Before calling timegm: aTm = 1970-6-3 12:1:2 (DST=0)
+After  calling timegm: aTm = 1970-6-3 13:1:2 (DST=1)
+Before calling timegm: aTm = 1970-6-3 12:1:2 (DST=1)
+After  calling timegm: aTm = 1970-6-3 12:1:2 (DST=1)
+aTm = 1970-6-3 12:1:2 (DST=-1,0,+1)
+aTimetM1 = 13258862
+aTmM1 = 1970-6-3 11:1:2 (DST=0)
+aTimet0 = 13262462
+aTm0 = 1970-6-3 12:1:2 (DST=0)
+aTimetP1 = 13258862
+aTmP1 = 1970-6-3 11:1:2 (DST=0)
+Test test_gmtime_timegm
+Before setting isdst:  aTm = 1970-7-3 12:1:2
+Before calling timegm: aTm = 1970-7-3 12:1:2 (DST=-1)
+After  calling timegm: aTm = 1970-7-3 12:1:2 (DST=1)
+Before calling timegm: aTm = 1970-7-3 12:1:2 (DST=0)
+After  calling timegm: aTm = 1970-7-3 13:1:2 (DST=1)
+Before calling timegm: aTm = 1970-7-3 12:1:2 (DST=1)
+After  calling timegm: aTm = 1970-7-3 12:1:2 (DST=1)
+aTm = 1970-7-3 12:1:2 (DST=-1,0,+1)
+aTimetM1 = 15850862
+aTmM1 = 1970-7-3 11:1:2 (DST=0)
+aTimet0 = 15854462
+aTm0 = 1970-7-3 12:1:2 (DST=0)
+aTimetP1 = 15850862
+aTmP1 = 1970-7-3 11:1:2 (DST=0)
+Test test_gmtime_timegm
+Before setting isdst:  aTm = 1970-8-3 12:1:2
+Before calling timegm: aTm = 1970-8-3 12:1:2 (DST=-1)
+After  calling timegm: aTm = 1970-8-3 12:1:2 (DST=1)
+Before calling timegm: aTm = 1970-8-3 12:1:2 (DST=0)
+After  calling timegm: aTm = 1970-8-3 13:1:2 (DST=1)
+Before calling timegm: aTm = 1970-8-3 12:1:2 (DST=1)
+After  calling timegm: aTm = 1970-8-3 12:1:2 (DST=1)
+aTm = 1970-8-3 12:1:2 (DST=-1,0,+1)
+aTimetM1 = 18529262
+aTmM1 = 1970-8-3 11:1:2 (DST=0)
+aTimet0 = 18532862
+aTm0 = 1970-8-3 12:1:2 (DST=0)
+aTimetP1 = 18529262
+aTmP1 = 1970-8-3 11:1:2 (DST=0)
+Test test_gmtime_timegm
+Before setting isdst:  aTm = 1970-9-3 12:1:2
+Before calling timegm: aTm = 1970-9-3 12:1:2 (DST=-1)
+After  calling timegm: aTm = 1970-9-3 12:1:2 (DST=1)
+Before calling timegm: aTm = 1970-9-3 12:1:2 (DST=0)
+After  calling timegm: aTm = 1970-9-3 13:1:2 (DST=1)
+Before calling timegm: aTm = 1970-9-3 12:1:2 (DST=1)
+After  calling timegm: aTm = 1970-9-3 12:1:2 (DST=1)
+aTm = 1970-9-3 12:1:2 (DST=-1,0,+1)
+aTimetM1 = 21207662
+aTmM1 = 1970-9-3 11:1:2 (DST=0)
+aTimet0 = 21211262
+aTm0 = 1970-9-3 12:1:2 (DST=0)
+aTimetP1 = 21207662
+aTmP1 = 1970-9-3 11:1:2 (DST=0)
+Test test_gmtime_timegm
+Before setting isdst:  aTm = 1970-10-3 12:1:2
+Before calling timegm: aTm = 1970-10-3 12:1:2 (DST=-1)
+After  calling timegm: aTm = 1970-10-3 12:1:2 (DST=1)
+Before calling timegm: aTm = 1970-10-3 12:1:2 (DST=0)
+After  calling timegm: aTm = 1970-10-3 13:1:2 (DST=1)
+Before calling timegm: aTm = 1970-10-3 12:1:2 (DST=1)
+After  calling timegm: aTm = 1970-10-3 12:1:2 (DST=1)
+aTm = 1970-10-3 12:1:2 (DST=-1,0,+1)
+aTimetM1 = 23799662
+aTmM1 = 1970-10-3 11:1:2 (DST=0)
+aTimet0 = 23803262
+aTm0 = 1970-10-3 12:1:2 (DST=0)
+aTimetP1 = 23799662
+aTmP1 = 1970-10-3 11:1:2 (DST=0)
+Test test_gmtime_timegm
+Before setting isdst:  aTm = 1970-11-3 12:1:2
+Before calling timegm: aTm = 1970-11-3 12:1:2 (DST=-1)
+After  calling timegm: aTm = 1970-11-3 12:1:2 (DST=0)
+Before calling timegm: aTm = 1970-11-3 12:1:2 (DST=0)
+After  calling timegm: aTm = 1970-11-3 12:1:2 (DST=0)
+Before calling timegm: aTm = 1970-11-3 12:1:2 (DST=1)
+After  calling timegm: aTm = 1970-11-3 11:1:2 (DST=0)
+aTm = 1970-11-3 12:1:2 (DST=-1,0,+1)
+aTimetM1 = 26481662
+aTmM1 = 1970-11-3 12:1:2 (DST=0)
+aTimet0 = 26481662
+aTm0 = 1970-11-3 12:1:2 (DST=0)
+aTimetP1 = 26478062
+aTmP1 = 1970-11-3 11:1:2 (DST=0)
+Test test_gmtime_timegm
+Before setting isdst:  aTm = 1970-12-3 12:1:2
+Before calling timegm: aTm = 1970-12-3 12:1:2 (DST=-1)
+After  calling timegm: aTm = 1970-12-3 12:1:2 (DST=0)
+Before calling timegm: aTm = 1970-12-3 12:1:2 (DST=0)
+After  calling timegm: aTm = 1970-12-3 12:1:2 (DST=0)
+Before calling timegm: aTm = 1970-12-3 12:1:2 (DST=1)
+After  calling timegm: aTm = 1970-12-3 11:1:2 (DST=0)
+aTm = 1970-12-3 12:1:2 (DST=-1,0,+1)
+aTimetM1 = 29073662
+aTmM1 = 1970-12-3 12:1:2 (DST=0)
+aTimet0 = 29073662
+aTm0 = 1970-12-3 12:1:2 (DST=0)
+aTimetP1 = 29070062
+aTmP1 = 1970-12-3 11:1:2 (DST=0)
+
+OK (1)
+[OVAL] Cppunit-result =0
diff --git a/RelationalCool/tests/RelationalFolder/out.Windows.p1.adjustTimeZone b/RelationalCool/tests/RelationalFolder/out.Windows.p1.adjustTimeZone
new file mode 100755
index 000000000..afa8f0956
--- /dev/null
+++ b/RelationalCool/tests/RelationalFolder/out.Windows.p1.adjustTimeZone
@@ -0,0 +1,29 @@
+Test test_gmtime_timegm
+Before setting isdst:  aTm = 1970-1-3 12:1:2
+Before calling timegm: aTm = 1970-1-3 12:1:2 (DST=-1)
+After  calling timegm: aTm = 1970-1-3 12:1:2 (DST=0)
+Before calling timegm: aTm = 1970-1-3 12:1:2 (DST=0)
+After  calling timegm: aTm = 1970-1-3 12:1:2 (DST=0)
+Before calling timegm: aTm = 1970-1-3 12:1:2 (DST=1)
+After  calling timegm: aTm = 1970-1-3 11:1:2 (DST=0)
+aTm = 1970-1-3 12:1:2 (DST=-1,0,+1)
+aTimetM1 = 216062
+aTmM1 = 1970-1-3 12:1:2 (DST=0)
+aTimet0 = 216062
+aTm0 = 1970-1-3 12:1:2 (DST=0)
+aTimetP1 = 212462
+aTmP1 = 1970-1-3 11:1:2 (DST=0)
+
+\afs\all\cern.ch\sw\lcg\app\releases\COOL\COOL_1_2_0\src\RelationalCool\tests\RelationalFolder\test_RelationalFolder.cpp(287) : Assertion
+Test name: cool::RelationalFolderTest.test_gmtime_timegm
+- Expected : 12
+
+- Actual   : 11
+
+gmtime(timegm(tm,isDst=+1))==tm : hour (Month[0-11]=0)
+
+
+Failures !!!
+Run: 1   Failure total: 1   Failures: 1   Errors: 0
+Error: CppUnit Failures
+[OVAL] Cppunit-result =1
diff --git a/RelationalCool/tests/RelationalFolder/test_RelationalFolder.cpp b/RelationalCool/tests/RelationalFolder/test_RelationalFolder.cpp
new file mode 100644
index 000000000..b6bf8defe
--- /dev/null
+++ b/RelationalCool/tests/RelationalFolder/test_RelationalFolder.cpp
@@ -0,0 +1,5604 @@
+/**
+ 
+ @file test_RelationalFolder.cpp
+ 
+ @author Sven A. Schmidt
+ 
+ @date 2004-11-05
+ 
+ */
+
+
+// Mysterious warning: always line (?) 35 even if I add lines in between!
+// ../tests/RelationalFolder/test_RelationalFolder.cpp:35:   instantiated from here
+// cppunit/extensions/ExceptionTestCaseDecorator.h:96: warning: unused parameter 'e'
+
+#include "CoolDBUnitTest.h"
+
+#include "RelationalAccess/IRelationalService.h"
+#include "CoralBase/Attribute.h"
+#include "CoralBase/AttributeListException.h"
+
+#include "CoolKernel/ChannelSelection.h"
+#include "CoolKernel/CompositeSelection.h"
+#include "CoolKernel/FieldSelection.h"
+#include "CoolKernel/IDatabaseSvc.h"
+#include "CoolKernel/IField.h"
+#include "CoolKernel/IFolder.h"
+#include "CoolKernel/IObject.h"
+#include "CoolKernel/IObjectIterator.h"
+#include "CoolKernel/IRecordSelection.h"
+#include "CoolKernel/Record.h"
+#include "CoolKernel/RecordException.h"
+#include "CoolKernel/RecordSelectionException.h"
+#include "CoolKernel/RecordSpecification.h"
+
+#include "src/CoralApplication.h"
+#include "src/RalDatabase.h"
+#include "src/RelationalChannelTable.h"
+#include "src/RelationalException.h"
+#include "src/RelationalFolder.h"
+#include "src/RelationalTableRow.h"
+#include "src/RelationalTransaction.h"
+#include "src/RelationalPayloadQuery.h"
+
+
+#include "src/timeToString.h"
+
+// ---- this things are needed to force a drop of the connection
+#include "src/RalDatabaseSvc.h"
+#include "RelationalAccess/IConnectionService.h"
+#include "RelationalAccess/IConnectionServiceConfiguration.h"
+
+using coral::AttributeList;
+using coral::AttributeListSpecification;
+
+#include <string>
+using std::cout;
+using std::endl;
+using std::string;
+using std::stringstream;
+
+#include <vector>
+using std::vector;
+
+namespace cool {
+
+//! \brief RelationalFolder test class.
+class RelationalFolderTest : public CoolDBUnitTest {
+		
+  CPPUNIT_TEST_SUITE( RelationalFolderTest );
+
+  CPPUNIT_TEST( test_getFolder );
+  
+  CPPUNIT_TEST( test_folderSpecification );
+  
+  CPPUNIT_TEST( test_findObject );
+  CPPUNIT_TEST( test_findObject_MV );
+
+  CPPUNIT_TEST( test_findObject_wrongChannel );
+
+  CPPUNIT_TEST( test_findObject_after_dropNode_SV );
+  CPPUNIT_TEST( test_findObject_after_dropNode_MV );
+
+  CPPUNIT_TEST( test_access_outofscope_db );
+  CPPUNIT_TEST( test_flushStorageBuffer );
+
+  CPPUNIT_TEST( test_storeObject_bulk_SV );
+  CPPUNIT_TEST( test_storeObject_bulk_SV_listReused );
+
+  // This takes: ~30sec Oracle, ~120sec MySQL, ~30sec sqlite
+  CPPUNIT_TEST( test_storeObject_bulk_70k );
+  // This takes: ~60sec Oracle, ~240sec MySQL, ~60sec sqlite (after fixing bug #17903)
+  CPPUNIT_TEST( test_tagObject_bulk_70k ); // keep this disabled
+
+  CPPUNIT_TEST( test_storeObject_bulk_MV );
+
+  CPPUNIT_TEST( test_MV_tag_and_retrieve );
+  CPPUNIT_TEST( test_deleteTag_andRetag );
+
+  CPPUNIT_TEST( test_deleteTag_HEAD );
+
+  CPPUNIT_TEST( test_tagExistsElsewhere );
+  CPPUNIT_TEST( test_tagNameScope );
+  CPPUNIT_TEST( test_taggedNodes );
+  CPPUNIT_TEST( test_tagName_case_sensitivity );
+
+  CPPUNIT_TEST( test_multiple_folders );
+
+  CPPUNIT_TEST( test_ValidityKey_boundaries );
+  CPPUNIT_TEST( test_ValidityKeyException );
+  
+  CPPUNIT_TEST( test_flushStorageBuffer_exception );
+  CPPUNIT_TEST( test_flushStorageBuffer_exception_bug22474 );
+
+  CPPUNIT_TEST( test_browseObjects_SV );
+  CPPUNIT_TEST( test_browseObjects_SV_lowercasePayload );
+  CPPUNIT_TEST( test_browseObjects_SV_bug42101 );
+  CPPUNIT_TEST( test_browseObjects_MV );
+  CPPUNIT_TEST( test_browseObjects_MV_tag );
+
+  CPPUNIT_TEST( test_listTags_MV );
+  CPPUNIT_TEST( test_listTags_SV );
+  CPPUNIT_TEST( test_tagInsertionTime );
+  CPPUNIT_TEST( test_tagDescription );
+
+  CPPUNIT_TEST( test_storeObjects_bulk_multichannel );
+
+  CPPUNIT_TEST( test_setDescription );
+
+  CPPUNIT_TEST( test_storeObject_SV_overlap );
+  CPPUNIT_TEST( test_storeObject_SV_overlap_bulk );
+
+  CPPUNIT_TEST( test_storeObject_SV_unordered_closed );
+  CPPUNIT_TEST( test_storeObject_SV_unordered_open );
+  CPPUNIT_TEST( test_storeObject_SV_unordered_bulk_closed );
+  CPPUNIT_TEST( test_storeObject_SV_unordered_bulk_open );
+  CPPUNIT_TEST( test_storeObject_SV_unordered_bulk_open_2 );
+  CPPUNIT_TEST( test_storeObject_SV_unordered_bulk_open_3 );
+  CPPUNIT_TEST( test_storeObject_SV_unordered_MC_closed );
+  CPPUNIT_TEST( test_storeObject_SV_unordered_MC_bulk_closed );
+  CPPUNIT_TEST( test_storeObject_SV_unordered_MC_bulk_closed_oneperchannel );
+  CPPUNIT_TEST( test_storeObject_SV_unordered_MC_bulk_closed_oneperchannel_2 );
+  CPPUNIT_TEST( test_storeObject_SV_unordered_bulk_closed_oneback );
+  CPPUNIT_TEST( test_storeObject_SV_unordered_has_new_data_flag );
+
+  CPPUNIT_TEST( test_browseObjects_channel_range_SV );
+  CPPUNIT_TEST( test_browseObjects_all_channels_SV );
+  CPPUNIT_TEST( test_browseObjects_channel_range_MV );
+  CPPUNIT_TEST( test_browseObjects_all_channels_MV );
+
+  CPPUNIT_TEST( test_objectCount_SV );
+  CPPUNIT_TEST( test_objectCount_MV );
+
+  CPPUNIT_TEST( test_node_nameclash );
+
+  CPPUNIT_TEST( test_existsUserTag );
+  CPPUNIT_TEST( test_userTag_browseObjects_HEAD_insulation );
+  CPPUNIT_TEST( test_browseObjects_userTag );
+  CPPUNIT_TEST( test_userTag_example1 );
+  CPPUNIT_TEST( test_storeObject_userTag_SV );
+  CPPUNIT_TEST( test_tag_with_userTag );
+  CPPUNIT_TEST( test_userTag_with_tag );
+
+  CPPUNIT_TEST( test_storeObject_userTag_userTagOnly );
+  CPPUNIT_TEST( test_storeObject_userTag_userTagOnly_exceptions );
+
+  CPPUNIT_TEST( test_userTag_HEAD );
+  
+  CPPUNIT_TEST( test_attribute_names );
+  CPPUNIT_TEST( test_attribute_names_isa );
+  CPPUNIT_TEST( test_attribute_name_order_string );
+  
+  CPPUNIT_TEST( test_renamePayload );
+
+  CPPUNIT_TEST( test_extendPayloadSpecification );
+  CPPUNIT_TEST( test_extendPayloadSpecificationExceptions );
+
+  CPPUNIT_TEST( test_storeObject_emptyRecord );
+
+  CPPUNIT_TEST( test_browseObjects_channelName_SV_all );
+  CPPUNIT_TEST( test_browseObjects_channelName_SV_range );
+  CPPUNIT_TEST( test_browseObjects_channelName_MV_all );
+  CPPUNIT_TEST( test_browseObjects_channelName_MV_tag );
+  CPPUNIT_TEST( test_browseObjects_channelName_MV_userTag );
+  
+  CPPUNIT_TEST( test_findObjects_channelName_SV );
+  CPPUNIT_TEST( test_findObjects_channelName_MV );
+  CPPUNIT_TEST( test_findObjects_channelName_MV_tag );
+  CPPUNIT_TEST( test_findObjects_channelName_MV_userTag );
+
+  CPPUNIT_TEST( test_countObjects_channelName_SV_all );
+  CPPUNIT_TEST( test_countObjects_channelName_SV_range );
+  CPPUNIT_TEST( test_countObjects_channelName_MV_all );
+  CPPUNIT_TEST( test_countObjects_channelName_MV_tag );
+  CPPUNIT_TEST( test_countObjects_channelName_MV_userTag );
+
+  CPPUNIT_TEST( test_setTagDescription_currentHeadTag );
+  CPPUNIT_TEST( test_setTagDescription_headAsOfDateTag );
+  CPPUNIT_TEST( test_setTagDescription_userTag );
+  CPPUNIT_TEST( test_setTagDescription_TagNotFound );
+  CPPUNIT_TEST( test_setTagDescription_256 );
+  CPPUNIT_TEST( test_setTagDescription_headTag ); // bug #33989
+  
+  CPPUNIT_TEST( test_cloneHeadTag );
+  
+#ifdef COOL280
+  CPPUNIT_TEST( test_manualTransaction_renamePayload );
+  CPPUNIT_TEST( test_manualTransaction_extendPayloadSpecification );
+#endif
+  
+  CPPUNIT_TEST( test_RecordSelectionBrowseObjects );
+  
+  CPPUNIT_TEST( test_truncateIOV );
+
+	CPPUNIT_TEST( test_browseObjects_bug42708 );
+	CPPUNIT_TEST( test_browseObjects_bug42708_exception );
+	
+  CPPUNIT_TEST_SUITE_END();
+		
+public:
+
+  RecordSpecification payloadSpec;
+
+	void test_browseObjects_bug42708_exception() 
+  {
+		IFolderPtr folder = m_db->createFolder("/myfolder", 
+																					 payloadSpec,
+																					 "my description",
+																					 FolderVersioning::SINGLE_VERSION);
+		
+		for ( int i = 0; i < 100; ++i ) 
+			folder->storeObject(  0, 10, dummyPayload( i ), (ChannelId)i );
+		
+		ChannelSelection channels( 0 );
+		for ( int i = 1; i < 51; ++i ) 
+      channels.addRange( 2*i, 2*i ); // [0,0], [2,2]... [100,100] (51 ranges)
+
+		try 
+    {
+			IObjectIteratorPtr objs = folder->browseObjects(0,
+																											ValidityKeyMax,
+																											channels );
+			CPPUNIT_FAIL("browsing with 51 non-contiguous channel selection ranges "
+									 "must fail");
+    } catch ( RelationalException& e ) {
+      std::string expected = "Non-contiguous channel selection only "
+        "supported for up to 50 ranges";
+      CPPUNIT_ASSERT_EQUAL_MESSAGE("exception caught",
+                                   expected, std::string(e.what()));
+    }
+		
+	}
+	
+	void test_browseObjects_bug42708() {
+		IFolderPtr folder = m_db->createFolder("/myfolder", 
+																					 payloadSpec,
+																					 "my description",
+																					 FolderVersioning::SINGLE_VERSION);
+		
+		for ( int i = 0; i < 100; ++i )
+			folder->storeObject(  0, 10, dummyPayload( i ), (ChannelId)i );
+		
+		ChannelSelection channels( 0 );
+		for ( int i = 1; i < 50; ++i ) 
+      channels.addRange( 2*i, 2*i ); // [0,0], [2,2]... [98,98] (50 ranges)
+
+		IObjectIteratorPtr objs = folder->browseObjects(0,
+																										ValidityKeyMax,
+																										channels );
+			
+		CPPUNIT_ASSERT_EQUAL_MESSAGE( "object count", 50u, 
+																 (unsigned int)objs->size() );
+			
+    // Only test the first 5 objects
+		IObjectPtr obj = getNext(objs);
+		CPPUNIT_ASSERT_MESSAGE( "obj 1 payload", 
+													 dummyPayload( 0 ) == obj->payload() );
+		CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 1 channel",
+																 (ChannelId)0, obj->channelId() );
+		obj = getNext(objs);
+		CPPUNIT_ASSERT_MESSAGE( "obj 2 payload", 
+													 dummyPayload( 2 ) == obj->payload() );
+		CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 2 channel",
+																 (ChannelId)2, obj->channelId() );
+		
+		obj = getNext(objs);
+		CPPUNIT_ASSERT_MESSAGE( "obj 3 payload", 
+													 dummyPayload( 4 ) == obj->payload() );
+		CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 3 channel",
+																 (ChannelId)4, obj->channelId() );
+		
+		obj = getNext(objs);
+		CPPUNIT_ASSERT_MESSAGE( "obj 4 payload", 
+													 dummyPayload( 6 ) == obj->payload() );
+		CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 4 channel",
+																 (ChannelId)6, obj->channelId() );
+		
+		obj = getNext(objs);
+		CPPUNIT_ASSERT_MESSAGE( "obj 5 payload", 
+													 dummyPayload( 8 ) == obj->payload() );
+		CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 5 channel",
+																 (ChannelId)8, obj->channelId() );
+	}
+
+#ifdef COOL280
+  /// Tests renamePayload behavior in manual transaction mode
+  void test_manualTransaction_renamePayload() {
+    IFolderPtr folder = m_db->createFolder( "/A1", payloadSpec );
+    
+    ITransactionPtr t = m_db->startTransaction();
+    
+    try {
+      folder->renamePayload("I", "J");      
+      CPPUNIT_FAIL("renamePayload in manual transaction mode must fail");
+    } catch ( RelationalException& e ) {
+      std::string expected = "Cannot rename payload fields in manual "
+      "transaction mode";
+      CPPUNIT_ASSERT_EQUAL_MESSAGE("exception caught",
+                                   expected, std::string(e.what()));
+    }
+  }
+  
+  
+  /// Tests extendPayloadSpecification behavior in manual transaction mode
+  void test_manualTransaction_extendPayloadSpecification() {
+    IFolderPtr folder = m_db->createFolder( "/A1", payloadSpec );
+    
+    ITransactionPtr t = m_db->startTransaction();
+    
+    try {
+      RecordSpecification newFields;
+      newFields.extend("Y", StorageType::Int32);
+      folder->extendPayloadSpecification(Record(newFields));      
+      CPPUNIT_FAIL("extendPayloadSpecification in manual transaction mode "
+                   "must fail");
+    } catch ( RelationalException& e ) {
+      std::string expected = ("Cannot extend payload specification in manual "
+                              "transaction mode");
+      CPPUNIT_ASSERT_EQUAL_MESSAGE("exception caught",
+                                   expected, std::string(e.what()));
+    }
+  }
+#endif  
+  
+  /// Tests setTagDescription for the HEAD tag (bug #33989)
+  void test_setTagDescription_headTag() {
+    IFolderPtr folder = 
+    m_db->createFolder("/myfolder", 
+                       payloadSpec,
+                       "my description",
+                       FolderVersioning::MULTI_VERSION);
+    
+    folder->storeObject(  0, 10, dummyPayload( 0 ), 0 );
+    
+    try {
+      folder->setTagDescription( "HEAD", "desc" );
+      CPPUNIT_FAIL( "setTagDescription for HEAD tag should fail!" );
+    } 
+    catch ( Exception& ) {}
+  }
+  
+  
+  /// Tests setTagDesction for a description exceeding the 255 character limit
+  /// (task #6394).
+  void test_setTagDescription_256() {
+    IFolderPtr folder = 
+    m_db->createFolder("/myfolder", 
+                       payloadSpec,
+                       "my description",
+                       FolderVersioning::MULTI_VERSION);
+    
+    folder->storeObject(  0, 10, dummyPayload( 0 ), 0, "user tag" );
+    
+    std::string s256(256, '*');
+    try {
+      folder->setTagDescription( "user tag", s256 );
+      CPPUNIT_FAIL( "setTagDescription with >255 chars should fail!" );
+    } 
+    catch ( Exception& ) {}
+  }
+  
+  
+  /// Tests setTagDesction for a non-existing tag (task #6394).
+  void test_setTagDescription_TagNotFound() {
+    IFolderPtr folder = 
+    m_db->createFolder("/myfolder", 
+                       payloadSpec,
+                       "my description",
+                       FolderVersioning::MULTI_VERSION);
+    
+    folder->storeObject(  0, 10, dummyPayload( 0 ), 0, "user tag" );
+
+    try
+    {      
+      folder->setTagDescription( "non-existing tag", "new description" );
+      CPPUNIT_FAIL( "setTagDescription with non-existing tag should fail!" );
+    } 
+    catch ( TagNotFound& ) {}
+  }
+  
+  
+  /// Tests setTagDesction for a user tag (task #6394).
+  void test_setTagDescription_userTag() {
+    IFolderPtr folder = 
+    m_db->createFolder("/myfolder", 
+                       payloadSpec,
+                       "my description",
+                       FolderVersioning::MULTI_VERSION);
+    
+    folder->storeObject(  0, 10, dummyPayload( 0 ), 0, "user tag" );
+    
+    folder->setTagDescription( "user tag", "new description" );
+    
+    CPPUNIT_ASSERT_EQUAL( std::string("new description"),
+                          folder->tagDescription("user tag") );
+  }
+  
+  
+  /// Tests setTagDesction for an 'asof' date tag (task #6394).
+  void test_setTagDescription_headAsOfDateTag() {
+    IFolderPtr folder = 
+    m_db->createFolder("/myfolder", 
+                       payloadSpec,
+                       "my description",
+                       FolderVersioning::MULTI_VERSION);
+    
+    folder->storeObject(  0, 10, dummyPayload( 0 ), 0 );
+    IObjectPtr obj = folder->findObject( 0, 0 );
+    folder->tagHeadAsOfDate( obj->insertionTime(),
+                            "head tag", "original description" );
+    
+    CPPUNIT_ASSERT_EQUAL( std::string("original description"),
+                          folder->tagDescription("head tag") );
+    
+    folder->setTagDescription( "head tag", "new description" );
+    
+    CPPUNIT_ASSERT_EQUAL( std::string("new description"),
+                          folder->tagDescription("head tag") );
+  }
+  
+  
+  /// Tests setTagDesction for a current head tag (task #6394).
+  void test_setTagDescription_currentHeadTag() {
+    IFolderPtr folder = 
+    m_db->createFolder("/myfolder", 
+                       payloadSpec,
+                       "my description",
+                       FolderVersioning::MULTI_VERSION);
+    
+    folder->storeObject(  0, 10, dummyPayload( 0 ), 0 );
+    folder->tagCurrentHead( "head tag", "original description" );
+
+    CPPUNIT_ASSERT_EQUAL( std::string("original description"),
+                          folder->tagDescription("head tag") );
+
+    folder->setTagDescription( "head tag", "new description" );
+    
+    CPPUNIT_ASSERT_EQUAL( std::string("new description"),
+                          folder->tagDescription("head tag") );
+  }
+  
+  
+  /// Tests countObjects (MV folder) via the channel name interface
+  /// selecting user tagged IOVs
+  void test_countObjects_channelName_MV_userTag() {
+    IFolderPtr folder = 
+    m_db->createFolder("/myfolder", 
+                       payloadSpec,
+                       "my description",
+                       FolderVersioning::MULTI_VERSION);
+    folder->createChannel( 1, "ch 1" );
+    
+    folder->storeObject(  0, 10, dummyPayload( 0 ), 0, "user tag" );
+    folder->storeObject( 10, 20, dummyPayload( 1 ), 0, "user tag" );
+    folder->storeObject( 20, ValidityKeyMax, dummyPayload( 2 ), 0, "user tag" );
+    folder->storeObject(  0, 10, dummyPayload( 0 ), 1, "user tag" );
+    folder->storeObject( 10, 20, dummyPayload( 1 ), 1, "user tag" );
+    folder->storeObject( 20, ValidityKeyMax, dummyPayload( 2 ), 1, "user tag" );
+    folder->storeObject(  0, 10, dummyPayload( 0 ), 2, "user tag" );
+    folder->storeObject( 10, 20, dummyPayload( 1 ), 2, "user tag" );
+    folder->storeObject( 20, ValidityKeyMax, dummyPayload( 2 ), 2, "user tag" );
+    
+    folder->storeObject(  0, 10, dummyPayload( 0 ), 1 );
+    
+    ChannelSelection chsel( "ch 1" );
+    unsigned int count = folder->countObjects( 0, 
+                                              ValidityKeyMax, 
+                                              chsel, 
+                                              "user tag" );
+    
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "object count", 3u, count );
+  }
+  
+  
+  /// Tests countObjects (MV folder) via the channel name interface
+  /// selecting tagged IOVs
+  void test_countObjects_channelName_MV_tag() {
+    IFolderPtr folder = 
+    m_db->createFolder("/myfolder", 
+                       payloadSpec,
+                       "my description",
+                       FolderVersioning::MULTI_VERSION);
+    folder->createChannel( 1, "ch 1" );
+    
+    folder->storeObject(  0, 10, dummyPayload( 0 ), 0 );
+    folder->storeObject( 10, 20, dummyPayload( 1 ), 0 );
+    folder->storeObject( 20, ValidityKeyMax, dummyPayload( 2 ), 0 );
+    folder->storeObject(  0, 10, dummyPayload( 0 ), 1 );
+    folder->storeObject( 10, 20, dummyPayload( 1 ), 1 );
+    folder->storeObject( 20, ValidityKeyMax, dummyPayload( 2 ), 1 );
+    folder->storeObject(  0, 10, dummyPayload( 0 ), 2 );
+    folder->storeObject( 10, 20, dummyPayload( 1 ), 2 );
+    folder->storeObject( 20, ValidityKeyMax, dummyPayload( 2 ), 2 );
+    
+    folder->tagCurrentHead( "tag" );
+    
+    folder->storeObject(  0, 10, dummyPayload( 0 ), 1 );
+    
+    ChannelSelection chsel( "ch 1" );
+    unsigned int count = folder->countObjects( 0, 
+                                               ValidityKeyMax, 
+                                               chsel, 
+                                               "tag" );
+    
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "object count", 3u, count );
+  }
+  
+  
+  /// Tests countObjects (MV folder) via the channel name interface
+  /// selecting all IOVs
+  void test_countObjects_channelName_MV_all() {
+    IFolderPtr folder = 
+    m_db->createFolder("/myfolder", 
+                       payloadSpec,
+                       "my description",
+                       FolderVersioning::MULTI_VERSION);
+    folder->createChannel( 1, "ch 1" );
+    
+    folder->storeObject(  0, 10, dummyPayload( 0 ), 0 );
+    folder->storeObject( 10, 20, dummyPayload( 1 ), 0 );
+    folder->storeObject( 20, ValidityKeyMax, dummyPayload( 2 ), 0 );
+    folder->storeObject(  0, 10, dummyPayload( 0 ), 1 );
+    folder->storeObject( 10, 20, dummyPayload( 1 ), 1 );
+    folder->storeObject( 20, ValidityKeyMax, dummyPayload( 2 ), 1 );
+    folder->storeObject(  0, 10, dummyPayload( 0 ), 2 );
+    folder->storeObject( 10, 20, dummyPayload( 1 ), 2 );
+    folder->storeObject( 20, ValidityKeyMax, dummyPayload( 2 ), 2 );
+    
+    ChannelSelection chsel( "ch 1" );
+    unsigned int count = folder->countObjects( 0, ValidityKeyMax, chsel );
+    
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "object count", 3u, count );
+  }
+  
+  
+  /// Tests countObjects (SV folder) via the channel name interface
+  /// selecting a range of IOVs
+  void test_countObjects_channelName_SV_range() {
+    IFolderPtr folder = 
+    m_db->createFolder("/myfolder", 
+                       payloadSpec,
+                       "my description",
+                       FolderVersioning::SINGLE_VERSION);
+    folder->createChannel( 1, "ch 1" );
+    
+    folder->storeObject(  0, 10, dummyPayload( 0 ), 0 );
+    folder->storeObject( 10, 20, dummyPayload( 1 ), 0 );
+    folder->storeObject( 20, ValidityKeyMax, dummyPayload( 2 ), 0 );
+    folder->storeObject(  0, 10, dummyPayload( 0 ), 1 );
+    folder->storeObject( 10, 20, dummyPayload( 1 ), 1 );
+    folder->storeObject( 20, ValidityKeyMax, dummyPayload( 2 ), 1 );
+    folder->storeObject(  0, 10, dummyPayload( 0 ), 2 );
+    folder->storeObject( 10, 20, dummyPayload( 1 ), 2 );
+    folder->storeObject( 20, ValidityKeyMax, dummyPayload( 2 ), 2 );
+    
+    ChannelSelection chsel( "ch 1" );
+    unsigned int count = folder->countObjects( 5, 15, chsel );
+    
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "object count", 2u, count );
+  }
+  
+  
+  /// Tests countObjects (SV folder) via the channel name interface
+  /// selecting all IOVs
+  void test_countObjects_channelName_SV_all() {
+    IFolderPtr folder = 
+    m_db->createFolder("/myfolder", 
+                       payloadSpec,
+                       "my description",
+                       FolderVersioning::SINGLE_VERSION);
+    folder->createChannel( 1, "ch 1" );
+    
+    folder->storeObject(  0, 10, dummyPayload( 0 ), 0 );
+    folder->storeObject( 10, 20, dummyPayload( 1 ), 0 );
+    folder->storeObject( 20, ValidityKeyMax, dummyPayload( 2 ), 0 );
+    folder->storeObject(  0, 10, dummyPayload( 0 ), 1 );
+    folder->storeObject( 10, 20, dummyPayload( 1 ), 1 );
+    folder->storeObject( 20, ValidityKeyMax, dummyPayload( 2 ), 1 );
+    folder->storeObject(  0, 10, dummyPayload( 0 ), 2 );
+    folder->storeObject( 10, 20, dummyPayload( 1 ), 2 );
+    folder->storeObject( 20, ValidityKeyMax, dummyPayload( 2 ), 2 );
+    
+    ChannelSelection chsel( "ch 1" );
+    unsigned int count = folder->countObjects( 0, ValidityKeyMax, chsel );
+    
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "object count", 3u, count );
+  }
+  
+  IObjectPtr getNext( IObjectIteratorPtr objs) {
+        if (!objs->goToNext()) 
+                CPPUNIT_FAIL("objs has no next row");
+        return IObjectPtr( objs->currentRef().clone() );
+  };
+ 
+  /// Tests findObjects for a MV folder with the channel name interface
+  /// selecting from a user tag.
+  void test_findObjects_channelName_MV_userTag() {
+    IFolderPtr folder = 
+    m_db->createFolder("/myfolder", 
+                       payloadSpec,
+                       "my description",
+                       FolderVersioning::MULTI_VERSION);
+    folder->createChannel( 1, "ch 1" );
+    
+    folder->storeObject(  0, 10, dummyPayload( 0 ), 0, "user tag" );
+    folder->storeObject( 10, 20, dummyPayload( 1 ), 0, "user tag" );
+    folder->storeObject( 20, ValidityKeyMax, dummyPayload( 2 ), 0, "user tag" );
+    folder->storeObject(  0, 10, dummyPayload( 0 ), 1, "user tag" );
+    folder->storeObject( 10, 20, dummyPayload( 1 ), 1, "user tag" );
+    folder->storeObject( 20, ValidityKeyMax, dummyPayload( 2 ), 1, "user tag" );
+    folder->storeObject(  0, 10, dummyPayload( 0 ), 2, "user tag" );
+    folder->storeObject( 10, 20, dummyPayload( 1 ), 2, "user tag" );
+    folder->storeObject( 20, ValidityKeyMax, dummyPayload( 2 ), 2, "user tag" );
+    
+    folder->storeObject(  0, 10, dummyPayload( 0 ), 1 );
+    
+    ChannelSelection chsel( "ch 1" );
+    IObjectIteratorPtr objs = folder->findObjects( 5, chsel, "user tag" );
+    
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "object count", 1u, 
+                                 (unsigned int)objs->size() );
+    
+    IObjectPtr obj = getNext(objs);
+    CPPUNIT_ASSERT( dummyPayload( 0 ) == obj->payload() );
+    CPPUNIT_ASSERT_EQUAL( (ValidityKey)0, obj->since() );
+    CPPUNIT_ASSERT_EQUAL( (ValidityKey)10, obj->until() );
+    CPPUNIT_ASSERT_EQUAL( (ChannelId)1, obj->channelId() );
+  }
+  
+  
+  /// Tests findObjects for a MV folder with the channel name interface
+  /// selecting from a tag.
+  void test_findObjects_channelName_MV_tag() {
+    IFolderPtr folder = 
+    m_db->createFolder("/myfolder", 
+                       payloadSpec,
+                       "my description",
+                       FolderVersioning::MULTI_VERSION);
+    folder->createChannel( 1, "ch 1" );
+    
+    folder->storeObject(  0, 10, dummyPayload( 0 ), 0 );
+    folder->storeObject( 10, 20, dummyPayload( 1 ), 0 );
+    folder->storeObject( 20, ValidityKeyMax, dummyPayload( 2 ), 0 );
+    folder->storeObject(  0, 10, dummyPayload( 0 ), 1 );
+    folder->storeObject( 10, 20, dummyPayload( 1 ), 1 );
+    folder->storeObject( 20, ValidityKeyMax, dummyPayload( 2 ), 1 );
+    folder->storeObject(  0, 10, dummyPayload( 0 ), 2 );
+    folder->storeObject( 10, 20, dummyPayload( 1 ), 2 );
+    folder->storeObject( 20, ValidityKeyMax, dummyPayload( 2 ), 2 );
+    
+    folder->tagCurrentHead( "tag" );
+
+    folder->storeObject(  0, 10, dummyPayload( 0 ), 1 );
+
+    ChannelSelection chsel( "ch 1" );
+    IObjectIteratorPtr objs = folder->findObjects( 5, chsel, "tag" );
+    
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "object count", 1u, 
+                                 (unsigned int)objs->size() );
+    
+    IObjectPtr obj = getNext(objs);
+    CPPUNIT_ASSERT( dummyPayload( 0 ) == obj->payload() );
+    CPPUNIT_ASSERT_EQUAL( (ValidityKey)0, obj->since() );
+    CPPUNIT_ASSERT_EQUAL( (ValidityKey)10, obj->until() );
+    CPPUNIT_ASSERT_EQUAL( (ChannelId)1, obj->channelId() );
+  }
+  
+  
+  /// Tests findObjects for a MV folder with the channel name interface
+  void test_findObjects_channelName_MV() {
+    IFolderPtr folder = 
+    m_db->createFolder("/myfolder", 
+                       payloadSpec,
+                       "my description",
+                       FolderVersioning::MULTI_VERSION);
+    folder->createChannel( 1, "ch 1" );
+    
+    folder->storeObject(  0, 10, dummyPayload( 0 ), 0 );
+    folder->storeObject( 10, 20, dummyPayload( 1 ), 0 );
+    folder->storeObject( 20, ValidityKeyMax, dummyPayload( 2 ), 0 );
+    folder->storeObject(  0, 10, dummyPayload( 0 ), 1 );
+    folder->storeObject( 10, 20, dummyPayload( 1 ), 1 );
+    folder->storeObject( 20, ValidityKeyMax, dummyPayload( 2 ), 1 );
+    folder->storeObject(  0, 10, dummyPayload( 0 ), 2 );
+    folder->storeObject( 10, 20, dummyPayload( 1 ), 2 );
+    folder->storeObject( 20, ValidityKeyMax, dummyPayload( 2 ), 2 );
+    
+    ChannelSelection chsel( "ch 1" );
+    IObjectIteratorPtr objs = folder->findObjects( 5, chsel );
+    
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "object count", 1u, 
+                                 (unsigned int)objs->size() );
+    
+    IObjectPtr obj = getNext(objs);
+    CPPUNIT_ASSERT( dummyPayload( 0 ) == obj->payload() );
+    CPPUNIT_ASSERT_EQUAL( (ValidityKey)0, obj->since() );
+    CPPUNIT_ASSERT_EQUAL( (ValidityKey)10, obj->until() );
+    CPPUNIT_ASSERT_EQUAL( (ChannelId)1, obj->channelId() );
+  }
+  
+  
+  /// Tests findObjects for a SV folder with the channel name interface
+  void test_findObjects_channelName_SV() {
+    IFolderPtr folder = 
+    m_db->createFolder("/myfolder", 
+                       payloadSpec,
+                       "my description",
+                       FolderVersioning::SINGLE_VERSION);
+    folder->createChannel( 1, "ch 1" );
+    
+    folder->storeObject(  0, 10, dummyPayload( 0 ), 0 );
+    folder->storeObject( 10, 20, dummyPayload( 1 ), 0 );
+    folder->storeObject( 20, ValidityKeyMax, dummyPayload( 2 ), 0 );
+    folder->storeObject(  0, 10, dummyPayload( 0 ), 1 );
+    folder->storeObject( 10, 20, dummyPayload( 1 ), 1 );
+    folder->storeObject( 20, ValidityKeyMax, dummyPayload( 2 ), 1 );
+    folder->storeObject(  0, 10, dummyPayload( 0 ), 2 );
+    folder->storeObject( 10, 20, dummyPayload( 1 ), 2 );
+    folder->storeObject( 20, ValidityKeyMax, dummyPayload( 2 ), 2 );
+    
+    ChannelSelection chsel( "ch 1" );
+    IObjectIteratorPtr objs = folder->findObjects( 5, chsel );
+    
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "object count", 1u, 
+                                  (unsigned int)objs->size() );
+    
+    IObjectPtr obj = getNext(objs);
+    CPPUNIT_ASSERT( dummyPayload( 0 ) == obj->payload() );
+    CPPUNIT_ASSERT_EQUAL( (ValidityKey)0, obj->since() );
+    CPPUNIT_ASSERT_EQUAL( (ValidityKey)10, obj->until() );
+    CPPUNIT_ASSERT_EQUAL( (ChannelId)1, obj->channelId() );
+  }
+  
+  
+  /// Tests object browsing (MV folder) via the channel name interface
+  /// selecting user tagged IOVs
+  void test_browseObjects_channelName_MV_userTag() {
+    IFolderPtr folder = 
+    m_db->createFolder("/myfolder", 
+                       payloadSpec,
+                       "my description",
+                       FolderVersioning::MULTI_VERSION);
+    folder->createChannel( 1, "ch 1" );
+    
+    folder->storeObject(  0, 10, dummyPayload( 0 ), 0, "user tag" );
+    folder->storeObject( 10, 20, dummyPayload( 1 ), 0, "user tag" );
+    folder->storeObject( 20, ValidityKeyMax, dummyPayload( 2 ), 0, "user tag" );
+    folder->storeObject(  0, 10, dummyPayload( 0 ), 1, "user tag" );
+    folder->storeObject( 10, 20, dummyPayload( 1 ), 1, "user tag" );
+    folder->storeObject( 20, ValidityKeyMax, dummyPayload( 2 ), 1, "user tag" );
+    folder->storeObject(  0, 10, dummyPayload( 0 ), 2, "user tag" );
+    folder->storeObject( 10, 20, dummyPayload( 1 ), 2, "user tag" );
+    folder->storeObject( 20, ValidityKeyMax, dummyPayload( 2 ), 2, "user tag" );
+    
+    folder->storeObject(  0, 10, dummyPayload( 0 ), 1 );
+
+    ChannelSelection chsel( "ch 1" );
+    IObjectIteratorPtr objs = folder->browseObjects( 0, 
+                                                     ValidityKeyMax,
+                                                     chsel,
+                                                     "user tag" );
+    
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "object count", 3u, 
+                                 (unsigned int)objs->size() );
+    
+    IObjectPtr obj = getNext(objs);
+    CPPUNIT_ASSERT( dummyPayload( 0 ) == obj->payload() );
+    CPPUNIT_ASSERT_EQUAL( (ValidityKey)0, obj->since() );
+    CPPUNIT_ASSERT_EQUAL( (ValidityKey)10, obj->until() );
+    CPPUNIT_ASSERT_EQUAL( (ChannelId)1, obj->channelId() );
+    
+    obj = getNext(objs);
+    CPPUNIT_ASSERT( dummyPayload( 1 ) == obj->payload() );
+    CPPUNIT_ASSERT_EQUAL( (ValidityKey)10, obj->since() );
+    CPPUNIT_ASSERT_EQUAL( (ValidityKey)20, obj->until() );
+    CPPUNIT_ASSERT_EQUAL( (ChannelId)1, obj->channelId() );
+    
+    obj = getNext(objs);
+    CPPUNIT_ASSERT( dummyPayload( 2 ) == obj->payload() );
+    CPPUNIT_ASSERT_EQUAL( (ValidityKey)20, obj->since() );
+    CPPUNIT_ASSERT_EQUAL( ValidityKeyMax, obj->until() );
+    CPPUNIT_ASSERT_EQUAL( (ChannelId)1, obj->channelId() );
+  }
+  
+  
+  /// Tests object browsing (MV folder) via the channel name interface
+  /// selecting tagged IOVs
+  void test_browseObjects_channelName_MV_tag() {
+    IFolderPtr folder = 
+    m_db->createFolder("/myfolder", 
+                       payloadSpec,
+                       "my description",
+                       FolderVersioning::MULTI_VERSION);
+    folder->createChannel( 1, "ch 1" );
+    
+    folder->storeObject(  0, 10, dummyPayload( 0 ), 0 );
+    folder->storeObject( 10, 20, dummyPayload( 1 ), 0 );
+    folder->storeObject( 20, ValidityKeyMax, dummyPayload( 2 ), 0 );
+    folder->storeObject(  0, 10, dummyPayload( 0 ), 1 );
+    folder->storeObject( 10, 20, dummyPayload( 1 ), 1 );
+    folder->storeObject( 20, ValidityKeyMax, dummyPayload( 2 ), 1 );
+    folder->storeObject(  0, 10, dummyPayload( 0 ), 2 );
+    folder->storeObject( 10, 20, dummyPayload( 1 ), 2 );
+    folder->storeObject( 20, ValidityKeyMax, dummyPayload( 2 ), 2 );
+
+    folder->tagCurrentHead( "tag" );
+    
+    folder->storeObject(  0, 10, dummyPayload( 0 ), 1 );
+
+    ChannelSelection chsel( "ch 1" );
+    IObjectIteratorPtr objs = folder->browseObjects( 0, 
+                                                    ValidityKeyMax,
+                                                    chsel,
+                                                    "tag" );
+    
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "object count", 3u, 
+                                 (unsigned int)objs->size() );
+    
+    IObjectPtr obj = getNext(objs);
+    CPPUNIT_ASSERT( dummyPayload( 0 ) == obj->payload() );
+    CPPUNIT_ASSERT_EQUAL( (ValidityKey)0, obj->since() );
+    CPPUNIT_ASSERT_EQUAL( (ValidityKey)10, obj->until() );
+    CPPUNIT_ASSERT_EQUAL( (ChannelId)1, obj->channelId() );
+    
+    obj = getNext(objs);
+    CPPUNIT_ASSERT( dummyPayload( 1 ) == obj->payload() );
+    CPPUNIT_ASSERT_EQUAL( (ValidityKey)10, obj->since() );
+    CPPUNIT_ASSERT_EQUAL( (ValidityKey)20, obj->until() );
+    CPPUNIT_ASSERT_EQUAL( (ChannelId)1, obj->channelId() );
+    
+    obj = getNext(objs);
+    CPPUNIT_ASSERT( dummyPayload( 2 ) == obj->payload() );
+    CPPUNIT_ASSERT_EQUAL( (ValidityKey)20, obj->since() );
+    CPPUNIT_ASSERT_EQUAL( ValidityKeyMax, obj->until() );
+    CPPUNIT_ASSERT_EQUAL( (ChannelId)1, obj->channelId() );
+  }
+  
+  
+  /// Tests object browsing (MV folder) via the channel name interface
+  /// selecting all IOVs
+  void test_browseObjects_channelName_MV_all() {
+    IFolderPtr folder = 
+    m_db->createFolder("/myfolder", 
+                       payloadSpec,
+                       "my description",
+                       FolderVersioning::MULTI_VERSION);
+    folder->createChannel( 1, "ch 1" );
+    
+    folder->storeObject(  0, 10, dummyPayload( 0 ), 0 );
+    folder->storeObject( 10, 20, dummyPayload( 1 ), 0 );
+    folder->storeObject( 20, ValidityKeyMax, dummyPayload( 2 ), 0 );
+    folder->storeObject(  0, 10, dummyPayload( 0 ), 1 );
+    folder->storeObject( 10, 20, dummyPayload( 1 ), 1 );
+    folder->storeObject( 20, ValidityKeyMax, dummyPayload( 2 ), 1 );
+    folder->storeObject(  0, 10, dummyPayload( 0 ), 2 );
+    folder->storeObject( 10, 20, dummyPayload( 1 ), 2 );
+    folder->storeObject( 20, ValidityKeyMax, dummyPayload( 2 ), 2 );
+    
+    ChannelSelection chsel( "ch 1" );
+    IObjectIteratorPtr objs = folder->browseObjects( 0, ValidityKeyMax, chsel );
+    
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "object count", 3u, 
+                                 (unsigned int)objs->size() );
+    
+    IObjectPtr obj = getNext(objs);
+    CPPUNIT_ASSERT( dummyPayload( 0 ) == obj->payload() );
+    CPPUNIT_ASSERT_EQUAL( (ValidityKey)0, obj->since() );
+    CPPUNIT_ASSERT_EQUAL( (ValidityKey)10, obj->until() );
+    CPPUNIT_ASSERT_EQUAL( (ChannelId)1, obj->channelId() );
+    
+    obj = getNext(objs);
+    CPPUNIT_ASSERT( dummyPayload( 1 ) == obj->payload() );
+    CPPUNIT_ASSERT_EQUAL( (ValidityKey)10, obj->since() );
+    CPPUNIT_ASSERT_EQUAL( (ValidityKey)20, obj->until() );
+    CPPUNIT_ASSERT_EQUAL( (ChannelId)1, obj->channelId() );
+    
+    obj = getNext(objs);
+    CPPUNIT_ASSERT( dummyPayload( 2 ) == obj->payload() );
+    CPPUNIT_ASSERT_EQUAL( (ValidityKey)20, obj->since() );
+    CPPUNIT_ASSERT_EQUAL( ValidityKeyMax, obj->until() );
+    CPPUNIT_ASSERT_EQUAL( (ChannelId)1, obj->channelId() );
+  }
+  
+  
+  /// Tests object browsing (SV folder) via the channel name interface
+  /// selecting a range of IOVs
+  void test_browseObjects_channelName_SV_range() {
+    IFolderPtr folder = 
+    m_db->createFolder("/myfolder", 
+                       payloadSpec,
+                       "my description",
+                       FolderVersioning::SINGLE_VERSION);
+    folder->createChannel( 1, "ch 1" );
+    
+    folder->storeObject(  0, 10, dummyPayload( 0 ), 0 );
+    folder->storeObject( 10, 20, dummyPayload( 1 ), 0 );
+    folder->storeObject( 20, ValidityKeyMax, dummyPayload( 2 ), 0 );
+    folder->storeObject(  0, 10, dummyPayload( 0 ), 1 );
+    folder->storeObject( 10, 20, dummyPayload( 1 ), 1 );
+    folder->storeObject( 20, ValidityKeyMax, dummyPayload( 2 ), 1 );
+    folder->storeObject(  0, 10, dummyPayload( 0 ), 2 );
+    folder->storeObject( 10, 20, dummyPayload( 1 ), 2 );
+    folder->storeObject( 20, ValidityKeyMax, dummyPayload( 2 ), 2 );
+    
+    ChannelSelection chsel( "ch 1" );
+    IObjectIteratorPtr objs = folder->browseObjects( 5, 15, chsel );
+    
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "object count", 2u, 
+                                 (unsigned int)objs->size() );
+    
+    IObjectPtr obj = getNext(objs);
+    CPPUNIT_ASSERT( dummyPayload( 0 ) == obj->payload() );
+    CPPUNIT_ASSERT_EQUAL( (ValidityKey)0, obj->since() );
+    CPPUNIT_ASSERT_EQUAL( (ValidityKey)10, obj->until() );
+    CPPUNIT_ASSERT_EQUAL( (ChannelId)1, obj->channelId() );
+    
+    obj = getNext(objs);
+    CPPUNIT_ASSERT( dummyPayload( 1 ) == obj->payload() );
+    CPPUNIT_ASSERT_EQUAL( (ValidityKey)10, obj->since() );
+    CPPUNIT_ASSERT_EQUAL( (ValidityKey)20, obj->until() );
+    CPPUNIT_ASSERT_EQUAL( (ChannelId)1, obj->channelId() );
+  }
+  
+  
+  /// Tests object browsing (SV folder) via the channel name interface
+  /// selecting all IOVs
+  void test_browseObjects_channelName_SV_all() {
+    IFolderPtr folder = 
+    m_db->createFolder("/myfolder", 
+                        payloadSpec,
+                        "my description",
+                        FolderVersioning::SINGLE_VERSION);
+    folder->createChannel( 1, "ch 1" );
+    
+    folder->storeObject(  0, 10, dummyPayload( 0 ), 0 );
+    folder->storeObject( 10, 20, dummyPayload( 1 ), 0 );
+    folder->storeObject( 20, ValidityKeyMax, dummyPayload( 2 ), 0 );
+    folder->storeObject(  0, 10, dummyPayload( 0 ), 1 );
+    folder->storeObject( 10, 20, dummyPayload( 1 ), 1 );
+    folder->storeObject( 20, ValidityKeyMax, dummyPayload( 2 ), 1 );
+    folder->storeObject(  0, 10, dummyPayload( 0 ), 2 );
+    folder->storeObject( 10, 20, dummyPayload( 1 ), 2 );
+    folder->storeObject( 20, ValidityKeyMax, dummyPayload( 2 ), 2 );
+    
+    ChannelSelection chsel( "ch 1" );
+    IObjectIteratorPtr objs = folder->browseObjects( 0, ValidityKeyMax, chsel );
+    
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "object count", 3u, 
+                                  (unsigned int)objs->size() );
+    
+    IObjectPtr obj = getNext(objs);
+    CPPUNIT_ASSERT( dummyPayload( 0 ) == obj->payload() );
+    CPPUNIT_ASSERT_EQUAL( (ValidityKey)0, obj->since() );
+    CPPUNIT_ASSERT_EQUAL( (ValidityKey)10, obj->until() );
+    CPPUNIT_ASSERT_EQUAL( (ChannelId)1, obj->channelId() );
+    
+    obj = getNext(objs);
+    CPPUNIT_ASSERT( dummyPayload( 1 ) == obj->payload() );
+    CPPUNIT_ASSERT_EQUAL( (ValidityKey)10, obj->since() );
+    CPPUNIT_ASSERT_EQUAL( (ValidityKey)20, obj->until() );
+    CPPUNIT_ASSERT_EQUAL( (ChannelId)1, obj->channelId() );
+    
+    obj = getNext(objs);
+    CPPUNIT_ASSERT( dummyPayload( 2 ) == obj->payload() );
+    CPPUNIT_ASSERT_EQUAL( (ValidityKey)20, obj->since() );
+    CPPUNIT_ASSERT_EQUAL( ValidityKeyMax, obj->until() );
+    CPPUNIT_ASSERT_EQUAL( (ChannelId)1, obj->channelId() );
+  }
+  
+    
+    /// Tests creating and retrieving a folder.
+    /// This test is implemented in more detail with respect to the folder
+    /// attributes in test_RalDatabase
+    void test_folderSpecification() {
+      try {
+        m_db->createFolder( "/f_sv", payloadSpec, "a description" );
+        m_db->createFolder( "/f_mv", payloadSpec, "a description",
+                          FolderVersioning::MULTI_VERSION );
+        
+        FolderSpecification fs_sv( FolderVersioning::SINGLE_VERSION,
+                                   payloadSpec );
+        FolderSpecification fs_mv( FolderVersioning::MULTI_VERSION,
+                                   payloadSpec );
+
+        m_db->createFolder( "/fs_sv", fs_sv, "a description" );
+        m_db->createFolder( "/fs_mv", fs_mv, "a description" );
+        
+        IFolderPtr folder = m_db->getFolder( "/f_sv" );
+        CPPUNIT_ASSERT( fs_sv == folder->folderSpecification() );
+        
+        folder = m_db->getFolder( "/f_mv" );
+        CPPUNIT_ASSERT( fs_mv == folder->folderSpecification() );
+        
+        folder = m_db->getFolder( "/fs_sv" );
+        CPPUNIT_ASSERT( fs_sv == folder->folderSpecification() );
+        
+        folder = m_db->getFolder( "/fs_mv" );
+        CPPUNIT_ASSERT( fs_mv == folder->folderSpecification() );
+      } catch ( Exception& e ) {
+        cout << e.what() << endl;
+        throw;
+      }
+    }
+
+
+    /// Tests storeObject using an empty Record (bug #24464)
+    /// Also test the payloadValue templated method (task #2859)
+    void test_storeObject_emptyRecord() {
+      IFolderPtr folder = m_db->createFolder
+        ( "/f1", payloadSpec, "", FolderVersioning::SINGLE_VERSION );
+      Record payload10;
+      Record payload20( dummyPayload( 20 ) );
+      Record payload30;
+      RecordSpecification payload40Spec; // reshuffle the order
+      {
+        payload40Spec.extend("X",StorageType::Float);
+        payload40Spec.extend("I",StorageType::Int32);
+        payload40Spec.extend("S",StorageType::String255);
+      }
+      Record payload40( payload40Spec );
+      {
+        int index = 40;
+        payload40["I"].setValue<Int32>( index );
+        std::stringstream s;
+        s << "Object " << index;
+        payload40["S"].setValue<String255>( s.str() );
+        payload40["X"].setValue<Float>( (float)(index/1000.) );
+      }
+      Record payload50;
+      ChannelId chId = 1;
+      folder->setupStorageBuffer();
+      folder->storeObject( 10, 20, payload10, chId );
+      folder->storeObject( 20, 30, payload20, chId );
+      folder->storeObject( 30, 40, payload30, chId );
+      folder->storeObject( 40, 50, payload40, chId );
+      folder->storeObject( 50, 60, payload50, chId );
+      folder->flushStorageBuffer();
+
+      IObjectPtr obj = folder->findObject( 10, chId );
+      CPPUNIT_ASSERT( obj.get() != 0 );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "p10 size", (UInt32)3, obj->payload().size() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "p10[I] null", true, obj->payload()["I"].isNull() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "p10[I] value", std::string("NULL"), obj->payloadValue("I") );
+      CPPUNIT_ASSERT_THROW
+        ( obj->payloadValue<Int32>("I"), FieldIsNull );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "p10[X] null", true, obj->payload()["X"].isNull() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "p10[X] value", std::string("NULL"), obj->payloadValue("X") );
+      CPPUNIT_ASSERT_THROW
+        ( obj->payloadValue<Float>("X"), FieldIsNull );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "p10[S]", std::string(""), obj->payload()["S"].data<std::string>() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "p10[S] null", false, obj->payload()["S"].isNull() ); // "", not null
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "p10[S] value", std::string(""), obj->payloadValue("S") );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "p10[S] val<>", std::string(""), obj->payloadValue<String255>("S") );
+
+      // Warning: hardcode string representations of dummyPayload
+      obj = folder->findObject( 20, chId );
+      CPPUNIT_ASSERT( obj.get() != 0 );
+      CPPUNIT_ASSERT_MESSAGE( "p20", obj->payload() == payload20 );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "p20[I] value", std::string("20"), obj->payloadValue("I") );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "p20[I] val<>", 20, obj->payloadValue<Int32>("I") );
+      CPPUNIT_ASSERT_THROW
+        ( obj->payloadValue<Float>("I"), FieldWrongCppType );
+      CPPUNIT_ASSERT_THROW
+        ( obj->payloadValue<String255>("I"), FieldWrongCppType );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "p20[X] value", std::string("0.02"), obj->payloadValue("X") );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "p20[X] val<>", (Float)0.02, obj->payloadValue<Float>("X") );
+      CPPUNIT_ASSERT_THROW
+        ( obj->payloadValue<Int32>("X"), FieldWrongCppType );
+      CPPUNIT_ASSERT_THROW
+        ( obj->payloadValue<String255>("X"), FieldWrongCppType );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "p20[S] value", std::string("Object 20"), obj->payloadValue("S") );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "p20[S] val<>", std::string("Object 20"), 
+          obj->payloadValue<String255>("S") );
+      CPPUNIT_ASSERT_THROW
+        ( obj->payloadValue<Int32>("S"), FieldWrongCppType );
+      CPPUNIT_ASSERT_THROW
+        ( obj->payloadValue<Float>("S"), FieldWrongCppType );
+
+      obj = folder->findObject( 30, chId );
+      CPPUNIT_ASSERT( obj.get() != 0 );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "p30 size", (UInt32)3, obj->payload().size() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "p30[I] null", true, obj->payload()["I"].isNull() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "p30[X] null", true, obj->payload()["X"].isNull() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "p30[S]", std::string(""), obj->payload()["S"].data<std::string>() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "p30[S] null", false, obj->payload()["S"].isNull() ); // "", not null
+
+      obj = folder->findObject( 40, chId );
+      CPPUNIT_ASSERT( obj.get() != 0 );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "p40 size", (UInt32)3, obj->payload().size() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "p40[I] null", false, obj->payload()["I"].isNull() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "p40[I]", payload40["I"].data<int>(), 
+          obj->payload()["I"].data<int>() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "p40[X] null", false, obj->payload()["X"].isNull() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "p40[X]", payload40["X"].data<float>(), 
+          obj->payload()["X"].data<float>() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "p40[S] null", false, obj->payload()["S"].isNull() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "p40[S]", payload40["S"].data<std::string>(), 
+          obj->payload()["S"].data<std::string>() );
+
+      obj = folder->findObject( 50, chId );
+      CPPUNIT_ASSERT( obj.get() != 0 );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "p50 size", (UInt32)3, obj->payload().size() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "p50[I] null", true, obj->payload()["I"].isNull() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "p50[X] null", true, obj->payload()["X"].isNull() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "p50[S]", std::string(""), obj->payload()["S"].data<std::string>() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "p50[S] null", false, obj->payload()["S"].isNull() ); // "", not null
+    }
+
+
+    /// Tests a special case (bug) related to an order column in conjunction
+    /// with a string type field. (Related to bug #16189.)
+    void test_attribute_name_order_string() {
+      RecordSpecification spec;
+      spec.extend( "order", StorageType::String255 );
+      IFolderPtr f = m_db->createFolder( "/f", spec );
+      CPPUNIT_ASSERT( m_db->existsFolder( "/f" ) );
+      coral::AttributeList payload = Record( spec ).attributeList();
+      f->storeObject( 0, 2, payload, 0 );
+      IObjectPtr obj = f->findObject( 1, 0 );
+      CPPUNIT_ASSERT( obj.get() != 0 );
+    }
+
+    
+    /// Related to bug #15871. 
+    /// As of COOL_2_0_0 it is impossible to create a payload name "is-a".
+    void test_attribute_names_isa() 
+    {
+      RecordSpecification spec;
+      spec.extend( "is-a", StorageType::Int32 );
+      CPPUNIT_ASSERT_THROW( m_db->createFolder( "/f", spec ),
+                            PayloadSpecificationInvalidFieldName );
+      CPPUNIT_ASSERT( ! m_db->existsFolder( "/f" ) );
+    }
+    
+    
+    /// Tests that attribute names are properly quoted by the backends,
+    /// i.e. that for example reserved words like 'order' can be used as
+    /// attribute names. (Related to bug #16189.)
+    void test_attribute_names() {
+      RecordSpecification spec;
+      
+      spec.extend( "select", StorageType::Int32 );
+      spec.extend( "from", StorageType::Int32 );
+      spec.extend( "where", StorageType::Int32 );
+      spec.extend( "order", StorageType::Int32 );
+      spec.extend( "by", StorageType::Int32 );
+      spec.extend( "in", StorageType::Int32 );
+      spec.extend( "group", StorageType::Int32 );
+      spec.extend( "delete", StorageType::Int32 );
+      spec.extend( "drop", StorageType::Int32 );
+      spec.extend( "int", StorageType::Int32 );
+      spec.extend( "float", StorageType::Int32 );
+      spec.extend( "double", StorageType::Int32 );
+      spec.extend( "varchar", StorageType::Int32 );
+      spec.extend( "varchar2", StorageType::Int32 );
+      spec.extend( "char", StorageType::Int32 );
+      spec.extend( "number", StorageType::Int32 );
+      spec.extend( "decimal", StorageType::Int32 );
+      spec.extend( "blob", StorageType::Int32 );
+      spec.extend( "clob", StorageType::Int32 );
+      spec.extend( "string", StorageType::Int32 );
+      IFolderPtr f = m_db->createFolder( "/f", spec );
+      CPPUNIT_ASSERT( m_db->existsFolder( "/f" ) );
+      coral::AttributeList payload = Record( spec ).attributeList();
+      f->storeObject( 0, 2, payload, 0 );
+      IObjectPtr obj = f->findObject( 1, 0 );
+      CPPUNIT_ASSERT( obj.get() != 0 );
+    }
+    
+    
+    /// Tests user tag behavior with the reserved name 'HEAD'
+    void test_userTag_HEAD() {
+      try {
+        IFolderPtr folder = m_db->createFolder( "/a", 
+                                              payloadSpec,
+                                              "desc", 
+                                              FolderVersioning::MULTI_VERSION);
+        ChannelId ch = 0;
+        folder->storeObject( 0, 10, dummyPayload( 1 ), ch, "HEAD" );      
+        // AV The above should not trow: "" and "HEAD" are equivalent,
+        // this is the default argument for storing IOVs with no user tag!
+        //CPPUNIT_FAIL( "Using HEAD as a user tag should fail" );
+      } 
+      //catch ( ReservedHeadTag& ) {}
+      catch ( std::exception& e ) {
+        std::cout << "Exception caught: '" << e.what() << "'" << std::endl;
+        throw;
+      } 
+    }
+  
+    void test_cloneHeadTag() 
+    {
+      try 
+      {
+        IFolderPtr folder = m_db->createFolder( "/a", 
+                                              payloadSpec,
+                                              "desc", 
+                                              FolderVersioning::MULTI_VERSION);
+
+        folder->storeObject(  0, 10, dummyPayload( 0010 ), 0);      
+        folder->storeObject(  5, 20, dummyPayload( 0520 ), 0);      
+        folder->storeObject(  3, 30, dummyPayload( 0330 ), 1);      
+        folder->storeObject( 20, 40, dummyPayload( 2040 ), 1);      
+        folder->storeObject(  3, 30, dummyPayload( 0330 ), 9);      
+        folder->storeObject( 20, 40, dummyPayload( 2040 ), 9);
+        folder->storeObject( 40, 60, dummyPayload( 2040 ), 9);
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 Count ", 
+                                      2u, folder->countObjects(0,100,0));
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 Count ", 
+                                      2u, folder->countObjects(0,100,1));
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 Count ", 
+                                      3u, folder->countObjects(0,100,9));
+        
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 Exist ", false,
+                                      m_db->existsTag("A1") );
+        
+        folder->tagCurrentHead("A1","tag1");
+        
+        folder->storeObject(  35, 50, dummyPayload( 3550 ), 1);
+        
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "4 Count ", 
+                                      3u, folder->countObjects(0,100,1));
+    
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 Exist ", false,
+                                      m_db->existsTag("A1_clone") );
+        folder->cloneTagAsUserTag("A1","A1_clone","clone of tag A1");
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 Exist ", true,
+                                      m_db->existsTag("A1_clone") );
+        
+        // check if A1_clone is correct
+        CPPUNIT_ASSERT_EQUAL_MESSAGE
+          ( "5 Count ", 2u, folder->countObjects(0,100,0,"A1_clone"));
+        CPPUNIT_ASSERT_EQUAL_MESSAGE
+          ( "6 Count ", 2u, folder->countObjects(0,100,1,"A1_clone"));
+        CPPUNIT_ASSERT_EQUAL_MESSAGE
+          ( "7 Count ", 3u, folder->countObjects(0,100,9,"A1_clone"));
+        CPPUNIT_ASSERT_EQUAL_MESSAGE
+          ( "Clone tag description ", 
+            std::string("clone of tag A1"), 
+            folder->tagDescription("A1_clone"));
+        
+        // head remains unchanged 
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "8 Count ", 
+                                      2u, folder->countObjects(0,100,0));
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "9 Count ", 
+                                      3u, folder->countObjects(0,100,1));
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "10 Count ", 
+                                      3u, folder->countObjects(0,100,9));    
+                
+        // inserting into head still works without bulk buffer
+        folder->storeObject( 55, 70, dummyPayload( 5570 ), 9);
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "11 Count ", 
+                                      4u, folder->countObjects(0,100,9));    
+
+        // can't reuse tag names for cloning
+        CPPUNIT_ASSERT_THROW( folder->cloneTagAsUserTag( "HEAD", "A1" ), 
+                              TagExists);
+        CPPUNIT_ASSERT_THROW( folder->cloneTagAsUserTag( "HEAD", "A1_clone" ), 
+                              TagExists);
+        
+        // but we can force to overwrite user tags
+        folder->cloneTagAsUserTag( "HEAD", "A1_clone",
+                                   "updated clone of tag HEAD",true);
+        CPPUNIT_ASSERT_EQUAL_MESSAGE
+            ( "12 Count ", 2u, folder->countObjects(0,100,0,"A1_clone"));
+        CPPUNIT_ASSERT_EQUAL_MESSAGE
+            ( "13 Count ", 3u, folder->countObjects(0,100,1,"A1_clone"));
+        CPPUNIT_ASSERT_EQUAL_MESSAGE
+            ( "14 Count ", 4u, folder->countObjects(0,100,9,"A1_clone"));
+
+      } 
+      catch ( std::exception& e ) 
+      {
+        std::cout << "Exception caught: '" << e.what() << "'" << std::endl;
+        throw;
+      } 
+    }
+    
+    /// Tests tagging behavior for user tagging with an already issued tag
+    void test_userTag_with_tag() {
+      try {
+        IFolderPtr folder = m_db->createFolder( "/a", 
+                                              payloadSpec,
+                                              "desc", 
+                                              FolderVersioning::MULTI_VERSION);
+        ChannelId ch = 0;
+        folder->storeObject( 0, 10, dummyPayload( 1 ), ch );
+        folder->tagCurrentHead( "A" );
+        CPPUNIT_ASSERT_MESSAGE( "tag exists", m_db->existsTag( "A" ) );
+        folder->storeObject( 0, 10, dummyPayload( 1 ), ch, "A" );      
+        CPPUNIT_FAIL( "this point should not be reached - exception expected" );
+      } catch ( TagExists& e ) {
+        CPPUNIT_ASSERT_EQUAL( string("Tag 'A' already exists"),
+                              string( e.what() ) );
+      }
+    }
+    
+    
+    /// Tests tagging behavior for tagging with an already issued user tag
+    void test_tag_with_userTag() {
+      try {
+        IFolderPtr folder = m_db->createFolder( "/a", 
+                                              payloadSpec,
+                                              "desc", 
+                                              FolderVersioning::MULTI_VERSION);
+        ChannelId ch = 0;
+        folder->storeObject( 0, 10, dummyPayload( 1 ), ch, "A" );
+        CPPUNIT_ASSERT_MESSAGE( "user tag exists", 
+                                folder->existsUserTag( "A" ) );
+        folder->tagCurrentHead( "A" );
+        CPPUNIT_FAIL( "this point should not be reached - exception expected" );
+      } catch ( TagExists& e ) {
+        CPPUNIT_ASSERT_EQUAL( string("Tag 'A' already exists"),
+                              string( e.what() ) );
+      }
+    }
+    
+    
+    /// Tests that storeObjects with a user tag on a SV folder throws an
+    /// exception.
+    void test_storeObject_userTag_SV() {
+      try {
+        IFolderPtr folder = m_db->createFolder( "/a", 
+                                              payloadSpec,
+                                              "desc", 
+                                              FolderVersioning::SINGLE_VERSION);
+        ChannelId ch = 0;
+        folder->storeObject( 0, 10, dummyPayload( 1 ), ch, "A" );      
+        CPPUNIT_FAIL( "this point should not be reached - exception expected" );
+      } catch ( FolderIsSingleVersion& e ) {
+        FolderIsSingleVersion 
+          eExp( "/a", "Cannot store a SV object with user tag: A", "" );
+        CPPUNIT_ASSERT_EQUAL
+          ( std::string( eExp.what() ), std::string( e.what() ) );
+      }
+    }
+      
+    
+    /// Tests storeObjects with a user tag and flag userTagOnly==true
+    void test_storeObject_userTag_userTagOnly() 
+    {
+      IFolderPtr folder = m_db->createFolder( "/a", 
+                                              payloadSpec,
+                                              "desc", 
+                                              FolderVersioning::MULTI_VERSION);
+      ChannelId ch = 0;
+      try
+      {
+        folder->storeObject(  0, 100, dummyPayload( 1 ), ch, "A", false );
+        folder->storeObject( 10,  20, dummyPayload( 2 ), ch,  "", false );
+        folder->storeObject( 80,  90, dummyPayload( 3 ), ch, "A", true );
+        folder->storeObject( 10,  90, dummyPayload( 4 ), ch, "B", true );
+        folder->storeObject( 30,  70, dummyPayload( 5 ), ch, "B", false );
+        
+        {
+          IObjectIteratorPtr objs = folder->browseObjects( ValidityKeyMin,
+                                                           ValidityKeyMax,
+                                                           ch,
+                                                           "" );
+          
+          CPPUNIT_ASSERT_EQUAL_MESSAGE( "object count", 5u, 
+                                        (unsigned int)objs->size() );
+          
+          IObjectPtr obj = getNext(objs);
+          CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 1 id", 8u, obj->objectId() );
+          CPPUNIT_ASSERT_MESSAGE( "obj 1 payload", 
+                                  dummyPayload( 1 ) == obj->payload() );
+          CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 1 since",
+                                        (ValidityKey)0, obj->since() );
+          CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 1 until",
+                                        (ValidityKey)10, obj->until() );
+          
+          obj = getNext(objs);
+          CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 2 id", 7u, obj->objectId() );
+          CPPUNIT_ASSERT_MESSAGE( "obj 2 payload", 
+                                  dummyPayload( 2 ) == obj->payload() );
+          CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 2 since",
+                                        (ValidityKey)10, obj->since() );
+          CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 2 until",
+                                        (ValidityKey)20, obj->until() );
+          
+          obj = getNext(objs);
+          CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 3 id", 26u, obj->objectId() );
+          CPPUNIT_ASSERT_MESSAGE( "obj 3 payload", 
+                                  dummyPayload( 1 ) == obj->payload() );
+          CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 3 since",
+                                        (ValidityKey)20, obj->since() );
+          CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 3 until",
+                                        (ValidityKey)30, obj->until() );
+
+          obj = getNext(objs);
+          CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 4 id", 25u, obj->objectId() );
+          CPPUNIT_ASSERT_MESSAGE( "obj 4 payload", 
+                                  dummyPayload( 5 ) == obj->payload() );
+          CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 4 since",
+                                        (ValidityKey)30, obj->since() );
+          CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 4 until",
+                                        (ValidityKey)70, obj->until() );
+
+          obj = getNext(objs);
+          CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 5 id", 27u, obj->objectId() );
+          CPPUNIT_ASSERT_MESSAGE( "obj 5 payload", 
+                                  dummyPayload( 1 ) == obj->payload() );
+          CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 5 since",
+                                        (ValidityKey)70, obj->since() );
+          CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 5 until",
+                                        (ValidityKey)100, obj->until() );
+        }
+        
+        {
+          IObjectIteratorPtr objs = folder->browseObjects( ValidityKeyMin,
+                                                           ValidityKeyMax,
+                                                           ch,
+                                                           "A" );
+          
+          CPPUNIT_ASSERT_EQUAL_MESSAGE( "object count", 3u, 
+                                        (unsigned int)objs->size() );
+          
+          IObjectPtr obj = getNext(objs);
+          CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 1 id", 17u, obj->objectId() );
+          CPPUNIT_ASSERT_MESSAGE( "obj 1 payload", 
+                                  dummyPayload( 1 ) == obj->payload() );
+          CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 1 since",
+                                        (ValidityKey)0, obj->since() );
+          CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 1 until",
+                                        (ValidityKey)80, obj->until() );
+          
+          obj = getNext(objs);
+          CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 2 id", 16u, obj->objectId() );
+          CPPUNIT_ASSERT_MESSAGE( "obj 2 payload", 
+                                  dummyPayload( 3 ) == obj->payload() );
+          CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 2 since",
+                                        (ValidityKey)80, obj->since() );
+          CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 2 until",
+                                        (ValidityKey)90, obj->until() );
+          
+          obj = getNext(objs);
+          CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 3 id", 18u, obj->objectId() );
+          CPPUNIT_ASSERT_MESSAGE( "obj 3 payload", 
+                                  dummyPayload( 1 ) == obj->payload() );
+          CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 3 since",
+                                        (ValidityKey)90, obj->since() );
+          CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 3 until",
+                                        (ValidityKey)100, obj->until() );
+        }
+        
+        {
+          IObjectIteratorPtr objs = folder->browseObjects( ValidityKeyMin,
+                                                           ValidityKeyMax,
+                                                           ch,
+                                                           "B" );
+          
+          CPPUNIT_ASSERT_EQUAL_MESSAGE( "object count", 3u, 
+                                        (unsigned int)objs->size() );
+          
+          IObjectPtr obj = getNext(objs);
+          CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 1 id", 29u, obj->objectId() );
+          CPPUNIT_ASSERT_MESSAGE( "obj 1 payload", 
+                                  dummyPayload( 4 ) == obj->payload() );
+          CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 1 since",
+                                        (ValidityKey)10, obj->since() );
+          CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 1 until",
+                                        (ValidityKey)30, obj->until() );
+          
+          obj = getNext(objs);
+          CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 2 id", 28u, obj->objectId() );
+          CPPUNIT_ASSERT_MESSAGE( "obj 2 payload", 
+                                  dummyPayload( 5 ) == obj->payload() );
+          CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 2 since",
+                                        (ValidityKey)30, obj->since() );
+          CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 2 until",
+                                        (ValidityKey)70, obj->until() );
+          
+          obj = getNext(objs);
+          CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 3 id", 30u, obj->objectId() );
+          CPPUNIT_ASSERT_MESSAGE( "obj 3 payload", 
+                                  dummyPayload( 4 ) == obj->payload() );
+          CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 3 since",
+                                        (ValidityKey)70, obj->since() );
+          CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 3 until",
+                                        (ValidityKey)90, obj->until() );
+        }
+        
+      } catch ( std::exception& e ) {
+        std::cout << "Exception caught: " << e.what() << std::endl;
+        throw;
+      }
+
+    }
+
+      
+    /// Tests exceptions from storeObjects with a user tag 
+    /// and flag userTagOnly==true
+    void test_storeObject_userTag_userTagOnly_exceptions() 
+    {
+      IFolderPtr fSV = m_db->createFolder( "/sv", 
+                                           payloadSpec,
+                                           "desc", 
+                                           FolderVersioning::SINGLE_VERSION);
+      IFolderPtr fMV = m_db->createFolder( "/mv", 
+                                           payloadSpec,
+                                           "desc", 
+                                           FolderVersioning::MULTI_VERSION);
+      ChannelId ch = 0;
+
+      // SV exceptions
+      {
+        try 
+        {
+          bool userTagOnly = true;
+          fSV->storeObject( 0, 10, dummyPayload( 1 ), ch, "A", userTagOnly );
+          CPPUNIT_FAIL( "userTagOnly==true should throw for SV" );
+        } 
+        catch ( RelationalException& ){}
+      }
+
+      // MV exception - userTag=""
+      {
+        try 
+        {
+          bool userTagOnly = true;
+          fMV->storeObject( 0, 10, dummyPayload( 1 ), ch, "", userTagOnly );
+          CPPUNIT_FAIL( "userTagOnly==true should throw for HEAD" );
+        } 
+        catch ( RelationalException& ){}
+      }
+
+      // MV exception - mix in bulk insertion
+      {
+        fMV->setupStorageBuffer( true );
+        bool userTagOnly = true;
+        fMV->storeObject( 0, 10, dummyPayload( 1 ), ch, "A", userTagOnly );
+        try 
+        {
+          userTagOnly = false;
+          fMV->storeObject( 10, 20, dummyPayload( 2 ), ch, "A", userTagOnly );
+          CPPUNIT_FAIL( "userTagOnly should throw if mixed" );
+        } 
+        catch ( RelationalException& ){}
+        userTagOnly = true;
+        fMV->storeObject( 20, 30, dummyPayload( 3 ), ch, "A", userTagOnly );
+        fMV->flushStorageBuffer();
+      }
+
+    }
+      
+    
+    // Tests the user tag implementation for example #1
+    void test_userTag_example1() {
+      IFolderPtr folder = m_db->createFolder( "/a", 
+                                            payloadSpec,
+                                            "desc", 
+                                            FolderVersioning::MULTI_VERSION);
+      ChannelId ch = 0;
+      folder->storeObject( 0, 10, dummyPayload( 1 ), ch );
+      folder->storeObject( 1, 5, dummyPayload( 2 ), ch, "A" );
+      folder->storeObject( 3, 8, dummyPayload( 3 ), ch, "B" );
+      folder->storeObject( 2, 4, dummyPayload( 4 ), ch, "A" );
+      folder->storeObject( 3, 7, dummyPayload( 5 ), ch, "B" );
+      
+      {
+        IObjectIteratorPtr objs = folder->browseObjects( ValidityKeyMin,
+                                                         ValidityKeyMax,
+                                                         ch );
+        
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "HEAD object count", 6u, 
+                                      (unsigned int)objs->size() );
+        
+        IObjectPtr obj = getNext(objs);
+        CPPUNIT_ASSERT_MESSAGE( "obj 1 payload", 
+                                dummyPayload( 1 ) == obj->payload() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 1 since",
+                                      (ValidityKey)0, obj->since() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 1 until",
+                                      (ValidityKey)1, obj->until() );
+        
+        obj = getNext(objs);
+        CPPUNIT_ASSERT_MESSAGE( "obj 2 payload", 
+                                dummyPayload( 2 ) == obj->payload() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 2 since",
+                                      (ValidityKey)1, obj->since() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 2 until",
+                                      (ValidityKey)2, obj->until() );
+        
+        obj = getNext(objs);
+        CPPUNIT_ASSERT_MESSAGE( "obj 3 payload", 
+                                dummyPayload( 4 ) == obj->payload() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 3 since",
+                                      (ValidityKey)2, obj->since() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 3 until",
+                                      (ValidityKey)3, obj->until() );
+        
+        obj = getNext(objs);
+        CPPUNIT_ASSERT_MESSAGE( "obj 4 payload", 
+                                dummyPayload( 5 ) == obj->payload() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 4 since",
+                                      (ValidityKey)3, obj->since() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 4 until",
+                                      (ValidityKey)7, obj->until() );
+        
+        obj = getNext(objs);
+        CPPUNIT_ASSERT_MESSAGE( "obj 5 payload", 
+                                dummyPayload( 3 ) == obj->payload() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 5 since",
+                                      (ValidityKey)7, obj->since() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 5 until",
+                                      (ValidityKey)8, obj->until() );
+        
+        obj = getNext(objs);
+        CPPUNIT_ASSERT_MESSAGE( "obj 6 payload", 
+                                dummyPayload( 1 ) == obj->payload() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 5 since",
+                                      (ValidityKey)8, obj->since() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 5 until",
+                                      (ValidityKey)10, obj->until() );
+      }
+      
+      {
+        CPPUNIT_ASSERT_MESSAGE( "tag 'A'", m_db->existsTag( "A" ) );
+        IObjectIteratorPtr objs = folder->browseObjects( ValidityKeyMin,
+                                                         ValidityKeyMax,
+                                                         ch,
+                                                         "A");
+        
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "tag A object count", 3u, 
+                                      (unsigned int)objs->size() );
+        
+        IObjectPtr obj = getNext(objs);
+        CPPUNIT_ASSERT_MESSAGE( "obj 1 payload", 
+                                dummyPayload( 2 ) == obj->payload() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 1 since",
+                                      (ValidityKey)1, obj->since() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 1 until",
+                                      (ValidityKey)2, obj->until() );
+        
+        obj = getNext(objs);
+        CPPUNIT_ASSERT_MESSAGE( "obj 2 payload", 
+                                dummyPayload( 4 ) == obj->payload() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 2 since",
+                                      (ValidityKey)2, obj->since() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 2 until",
+                                      (ValidityKey)4, obj->until() );
+        
+        obj = getNext(objs);
+        CPPUNIT_ASSERT_MESSAGE( "obj 3 payload", 
+                                dummyPayload( 2 ) == obj->payload() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 3 since",
+                                      (ValidityKey)4, obj->since() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 3 until",
+                                      (ValidityKey)5, obj->until() );
+      }
+      
+      {
+        CPPUNIT_ASSERT_MESSAGE( "tag 'B'", m_db->existsTag( "B" ) );
+        IObjectIteratorPtr objs = folder->browseObjects( ValidityKeyMin,
+                                                         ValidityKeyMax,
+                                                         ch,
+                                                         "B" );
+        
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "tag B object count", 2u, 
+                                      (unsigned int)objs->size() );
+        
+        IObjectPtr obj = getNext(objs);
+        CPPUNIT_ASSERT_MESSAGE( "obj 1 payload", 
+                                dummyPayload( 5 ) == obj->payload() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 1 since",
+                                      (ValidityKey)3, obj->since() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 1 until",
+                                      (ValidityKey)7, obj->until() );
+        
+        obj = getNext(objs);
+        CPPUNIT_ASSERT_MESSAGE( "obj 2 payload", 
+                                dummyPayload( 3 ) == obj->payload() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 2 since",
+                                      (ValidityKey)7, obj->since() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 2 until",
+                                      (ValidityKey)8, obj->until() );
+      }
+    }
+    
+  
+    /// Tests browsing a user tag selection
+    void test_browseObjects_userTag() {
+      try {
+      IFolderPtr folder = m_db->createFolder( "/a", 
+                                            payloadSpec,
+                                            "desc", 
+                                            FolderVersioning::MULTI_VERSION);
+      ChannelId ch = 0;
+      folder->storeObject( 0, 10, dummyPayload( 1 ), ch, "A" );
+      folder->storeObject( 1, 5, dummyPayload( 2 ), ch, "A" );
+
+      IObjectIteratorPtr objs = folder->browseObjects( ValidityKeyMin,
+                                                       ValidityKeyMax,
+                                                       ch,
+                                                       "A" );
+      
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "object count", 3u, 
+                                    (unsigned int)objs->size() );
+      
+      IObjectPtr obj = getNext(objs);
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 1 id", 11u, obj->objectId() );
+      CPPUNIT_ASSERT_MESSAGE( "obj 1 payload", 
+                              dummyPayload( 1 ) == obj->payload() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 1 since",
+                                    (ValidityKey)0, obj->since() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 1 until",
+                                    (ValidityKey)1, obj->until() );
+      
+      obj = getNext(objs);
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 2 id", 10u, obj->objectId() );
+      CPPUNIT_ASSERT_MESSAGE( "obj 2 payload", 
+                              dummyPayload( 2 ) == obj->payload() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 2 since",
+                                    (ValidityKey)1, obj->since() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 2 until",
+                                    (ValidityKey)5, obj->until() );
+      
+      obj = getNext(objs);
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 3 id", 12u, obj->objectId() );
+      CPPUNIT_ASSERT_MESSAGE( "obj 3 payload", 
+                              dummyPayload( 1 ) == obj->payload() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 3 since",
+                                    (ValidityKey)5, obj->since() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 3 until",
+                                    (ValidityKey)10, obj->until() );
+      } catch ( std::exception& e ) {
+        std::cout << "Exception caught: " << e.what() << std::endl;
+        throw;
+      }
+    }
+    
+    
+    // Tests that user tag insertion is treated like normal insertion 
+    // with respect to the HEAD
+    // In other words when the HEAD is browsed the following two insertions
+    // are absolutely identical:
+    // 1)
+    //    folder->storeObject( 0, 10, dummyPayload( 1 ), ch );
+    //    folder->storeObject( 1, 5, dummyPayload( 2 ), ch );
+    // 2)
+    //    folder->storeObject( 0, 10, dummyPayload( 1 ), ch );
+    //    folder->storeObject( 1, 5, dummyPayload( 2 ), ch, "A" );
+    void test_userTag_browseObjects_HEAD_insulation() {
+      IFolderPtr folder = m_db->createFolder( "/a", 
+                                            payloadSpec,
+                                            "desc", 
+                                            FolderVersioning::MULTI_VERSION);
+      ChannelId ch = 0;
+      folder->storeObject( 0, 10, dummyPayload( 1 ), ch );
+      folder->storeObject( 1, 5, dummyPayload( 2 ), ch, "A" );
+
+      IObjectIteratorPtr objs = folder->browseObjects( ValidityKeyMin,
+                                                       ValidityKeyMax,
+                                                       ch );
+        
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "HEAD object count", 3u, 
+                                    (unsigned int)objs->size() );
+        
+      IObjectPtr obj = getNext(objs);
+      CPPUNIT_ASSERT_MESSAGE( "obj 1 payload", 
+                              dummyPayload( 1 ) == obj->payload() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 1 since",
+                                    (ValidityKey)0, obj->since() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 1 until",
+                                    (ValidityKey)1, obj->until() );
+      
+      obj = getNext(objs);
+      CPPUNIT_ASSERT_MESSAGE( "obj 2 payload", 
+                              dummyPayload( 2 ) == obj->payload() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 2 since",
+                                    (ValidityKey)1, obj->since() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 2 until",
+                                    (ValidityKey)5, obj->until() );
+      
+      obj = getNext(objs);
+      CPPUNIT_ASSERT_MESSAGE( "obj 3 payload", 
+                              dummyPayload( 1 ) == obj->payload() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 3 since",
+                                    (ValidityKey)5, obj->since() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 3 until",
+                                    (ValidityKey)10, obj->until() );
+    }
+    
+    
+    /// Tests existsUserTag
+    void test_existsUserTag() {
+      IFolderPtr folder = m_db->createFolder( "/myfolder",
+                                            payloadSpec,
+                                            "my description",
+                                            FolderVersioning::MULTI_VERSION );
+      
+      CPPUNIT_ASSERT_MESSAGE( "no user tag yet", 
+                              ! folder->existsUserTag( "A" ) );
+      CPPUNIT_ASSERT_MESSAGE( "no tag yet", ! m_db->existsTag( "A" ) );
+      
+      folder->storeObject( 0, 10, dummyPayload( 1 ), (ChannelId)0, "A" );
+      
+      CPPUNIT_ASSERT_MESSAGE( "user tag exists", 
+                              folder->existsUserTag( "A" ) );
+      CPPUNIT_ASSERT_MESSAGE( "tag exists", m_db->existsTag( "A" ) );
+    }
+    
+    
+    /// Tests behavior when nodes with conflicting names are attempted to be
+    /// created
+    /// Issue raised by Shaun Roe 2005-12-14. Bug #14248
+    void test_node_nameclash() {
+      try {
+        IFolderPtr folder = m_db->createFolder( "/a", payloadSpec );
+        folder = m_db->createFolder( "/a/b", payloadSpec );                                            
+        CPPUNIT_FAIL( "exception expected" );
+      } catch ( cool::RelationalException& e ) {
+        std::string msg = "Cannot create node '/a/b', because the parent "
+                          "path contains a leaf node";
+        CPPUNIT_ASSERT_EQUAL( msg, std::string( e.what() ) );
+      }
+    }
+    
+    
+    /// Tests countObject for a MV folder
+    void test_objectCount_MV() {
+      IFolderPtr folder = m_db->createFolder( "/myfolder",
+                                            payloadSpec,
+                                            "desc",
+                                            FolderVersioning::MULTI_VERSION );
+      
+      folder->setupStorageBuffer();
+      for ( ChannelId ch = 0; ch < 5; ++ch ) {
+        folder->storeObject( 0, ValidityKeyMax, dummyPayload( 0 ), ch );
+        folder->storeObject( 1, ValidityKeyMax, dummyPayload( 1 ), ch );
+        folder->storeObject( 2, ValidityKeyMax, dummyPayload( 2 ), ch );
+        folder->storeObject( 3, ValidityKeyMax, dummyPayload( 3 ), ch );
+        folder->storeObject( 4, ValidityKeyMax, dummyPayload( 4 ), ch );
+      }
+      folder->flushStorageBuffer();
+      
+      folder->tagCurrentHead( "A" );
+
+      for ( ChannelId ch = 0; ch < 5; ++ch ) {
+        folder->storeObject( 0, ValidityKeyMax, dummyPayload( 0 ), ch );
+      }
+      folder->flushStorageBuffer();
+
+      folder->tagCurrentHead( "B" );
+
+      ValidityKey since = 1;
+      ValidityKey until = 3;
+      ChannelSelection channels( 2, 3 );
+      
+      int count = folder->countObjects( since, until, channels, "A" );
+      
+      CPPUNIT_ASSERT_EQUAL( 6, count );
+    }
+    
+    
+    /// Tests countObject for a SV folder
+    void test_objectCount_SV() {
+      IFolderPtr folder = m_db->createFolder( "/myfolder", payloadSpec );
+      
+      folder->setupStorageBuffer();
+      for ( ChannelId ch = 0; ch < 5; ++ch ) {
+        folder->storeObject( 0, ValidityKeyMax, dummyPayload( 0 ), ch );
+        folder->storeObject( 1, ValidityKeyMax, dummyPayload( 1 ), ch );
+        folder->storeObject( 2, ValidityKeyMax, dummyPayload( 2 ), ch );
+        folder->storeObject( 3, ValidityKeyMax, dummyPayload( 3 ), ch );
+        folder->storeObject( 4, ValidityKeyMax, dummyPayload( 4 ), ch );
+      }
+      folder->flushStorageBuffer();
+      
+      ValidityKey since = 1;
+      ValidityKey until = 3;
+      ChannelSelection channels( 2, 3 );
+      
+      int count = folder->countObjects( since, until, channels );
+      
+      CPPUNIT_ASSERT_EQUAL( 6, count );
+    }
+    
+
+    /// Tests storing unordered, non-overlapping SV IOVS (all closed).
+    /// See https://savannah.cern.ch/task/?func=detailitem&item_id=3138:
+    /// tests that the functionality of use case #3 is provided
+    /// (back-insertion is allowed for single-IOV single-channel insertion).
+    void test_storeObject_SV_unordered_closed()
+    {
+      IFolderPtr folder = m_db->createFolder( "/f1", payloadSpec );
+      folder->storeObject( 2, 4, dummyPayload( 2 ), 0 );
+      folder->storeObject( 0, 2, dummyPayload( 1 ), 0 );
+      
+      IObjectIteratorPtr objs = folder->browseObjects( ValidityKeyMin,
+                                                       ValidityKeyMax, 0 );
+      
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "object count", 2u, 
+                                    (unsigned int)objs->size() );
+      
+      IObjectPtr obj = getNext(objs);
+      CPPUNIT_ASSERT_MESSAGE( "obj 1 payload", 
+                              dummyPayload( 1 ) == obj->payload() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 1 since",
+                                    (ValidityKey)0, obj->since() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 1 until",
+                                    (ValidityKey)2, obj->until() );
+      
+      obj = getNext(objs);
+      CPPUNIT_ASSERT_MESSAGE( "obj 2 payload", 
+                              dummyPayload( 2 ) == obj->payload() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 2 since",
+                                    (ValidityKey)2, obj->since() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 2 until",
+                                    (ValidityKey)4, obj->until() );
+    }
+    
+    
+    /// Tests that the HAS_NEW_DATA flag is properly reset for back-inserted
+    /// IOVs.
+    void test_storeObject_SV_unordered_has_new_data_flag()
+    {
+      IFolderPtr folder = m_db->createFolder( "/f1", payloadSpec );
+      folder->storeObject( 2, 4, dummyPayload( 2 ), 0 );
+      folder->storeObject( 0, 2, dummyPayload( 1 ), 0 );
+      
+      /// We don't typically go below the public/relational interface layer
+      /// in this unit test suite. For that reason this test belongs more in
+      /// test_RalObjectMgr. However, with respect to what functionality is
+      /// being tested this test is more at home here.
+      RelationalFolder* relfolder = 
+        dynamic_cast<RelationalFolder*>(folder.get());
+      RalDatabase* ralDb = dynamic_cast<RalDatabase*>(m_db.get());
+
+      RelationalTransaction transaction( ralDb->transactionMgr() );
+      RelationalChannelTable channelTable( *ralDb, *relfolder );
+      RelationalTableRow row = channelTable.fetchRowForId( 0 );
+      CPPUNIT_ASSERT_EQUAL
+        ( (ChannelId)0, row["CHANNEL_ID"].data<ChannelId>() );
+      CPPUNIT_ASSERT_EQUAL
+        ( 1u, row["LAST_OBJECT_ID"].data<unsigned int>() );
+      CPPUNIT_ASSERT_EQUAL
+        ( false, row["HAS_NEW_DATA"].data<bool>() );
+      CPPUNIT_ASSERT_EQUAL
+        ( std::string(""), row["CHANNEL_NAME"].data<std::string>() );
+      transaction.commit();
+    }
+
+    
+    /// Tests storing unordered, non-overlapping SV IOVS (all closed but one).
+    /// See https://savannah.cern.ch/task/?func=detailitem&item_id=3138:
+    /// tests that the functionality of use case #3 is provided
+    /// (back-insertion is allowed for single-IOV single-channel insertion).
+    void test_storeObject_SV_unordered_open() 
+    {
+      IFolderPtr folder = m_db->createFolder( "/f1", payloadSpec );
+      folder->storeObject( 4, ValidityKeyMax, dummyPayload( 1 ), 0 );
+      folder->storeObject( 2, 3, dummyPayload( 2 ), 0 );
+      folder->storeObject( 5, 6, dummyPayload( 3 ), 0 );
+      
+      IObjectIteratorPtr objs = folder->browseObjects( ValidityKeyMin,
+                                                       ValidityKeyMax, 0 );
+      
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "object count", 3u, 
+                                    (unsigned int)objs->size() );
+      
+      IObjectPtr obj = getNext(objs);
+      CPPUNIT_ASSERT_MESSAGE( "obj 1 payload", 
+                              dummyPayload( 2 ) == obj->payload() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 1 since",
+                                    (ValidityKey)2, obj->since() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 1 until",
+                                    (ValidityKey)3, obj->until() );
+      
+      obj = getNext(objs);
+      CPPUNIT_ASSERT_MESSAGE( "obj 2 payload", 
+                              dummyPayload( 1 ) == obj->payload() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 2 since",
+                                    (ValidityKey)4, obj->since() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 2 until",
+                                    (ValidityKey)5, obj->until() );
+      
+      obj = getNext(objs);
+      CPPUNIT_ASSERT_MESSAGE( "obj 3 payload", 
+                              dummyPayload( 3 ) == obj->payload() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 3 since",
+                                    (ValidityKey)5, obj->since() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 3 until",
+                                    (ValidityKey)6, obj->until() );
+    }
+
+    
+    /// Tests storing unordered, non-overlapping SV IOVS (all closed).
+    /// See https://savannah.cern.ch/task/?func=detailitem&item_id=3138:
+    /// tests that the functionality of use case #1 is NOT YET provided
+    /// (back-insertion is not yet allowed for bulk inserting
+    /// more than one IOV per channel - in single or multi channel mode).
+    void test_storeObject_SV_unordered_bulk_closed() 
+    {
+      IFolderPtr folder = m_db->createFolder( "/f1", payloadSpec );
+      folder->setupStorageBuffer();
+      folder->storeObject( 2, 4, dummyPayload( 2 ), 0 );
+      folder->storeObject( 0, 2, dummyPayload( 1 ), 0 );
+      try 
+      {
+        folder->flushStorageBuffer();
+      }
+      catch ( std::exception& e ) 
+      {
+        CPPUNIT_ASSERT_EQUAL_MESSAGE
+          ( "4 until",
+            string( "Overlapping intervals "
+                    "not allowed in SINGLE_VERSION mode" ),
+            string( e.what() ) );
+      }
+      IObjectIteratorPtr objs = folder->browseObjects( ValidityKeyMin,
+                                                       ValidityKeyMax, 0 );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "object count", 0u, 
+                                    (unsigned int)objs->size() );      
+      /*
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "object count", 2u, 
+                                    (unsigned int)objs->size() );      
+      IObjectPtr obj = getNext(objs);
+      CPPUNIT_ASSERT_MESSAGE( "obj 1 payload", 
+                              dummyPayload( 1 ) == obj->payload() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 1 since",
+                                    (ValidityKey)0, obj->since() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 1 until",
+                                    (ValidityKey)2, obj->until() );
+      obj = getNext(objs);
+      CPPUNIT_ASSERT_MESSAGE( "obj 2 payload", 
+                              dummyPayload( 2 ) == obj->payload() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 2 since",
+                                    (ValidityKey)2, obj->since() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 2 until",
+                                    (ValidityKey)4, obj->until() );
+      */
+    }
+    
+    
+    /// Tests storing unordered, non-overlapping SV IOVS (all closed but one).
+    /// See https://savannah.cern.ch/task/?func=detailitem&item_id=3138:
+    /// tests that the functionality of use case #1 is NOT YET provided
+    /// (back-insertion is not yet allowed for bulk inserting
+    /// more than one IOV per channel - in single or multi channel mode).
+    void test_storeObject_SV_unordered_bulk_open() 
+    {
+      IFolderPtr folder = m_db->createFolder( "/f2", payloadSpec );
+      folder->setupStorageBuffer();
+      folder->storeObject( 4, ValidityKeyMax, dummyPayload( 1 ), 0 );
+      folder->storeObject( 2, 3, dummyPayload( 1 ), 0 );
+      folder->storeObject( 5, 6, dummyPayload( 1 ), 0 );
+      try 
+      {
+        folder->flushStorageBuffer();
+      }
+      catch ( std::exception& e ) 
+      {
+        CPPUNIT_ASSERT_EQUAL_MESSAGE
+          ( "4 until",
+            string( "Overlapping intervals "
+                    "not allowed in SINGLE_VERSION mode" ),
+            //string( "Back-insertion not possible "
+            //        "due to multiple objects in channel" ),
+            string( e.what() ) );
+      }
+      IObjectIteratorPtr objs = folder->browseObjects( ValidityKeyMin,
+                                                       ValidityKeyMax, 0 );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "object count", 0u, 
+                                    (unsigned int)objs->size() );
+      /*
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "object count", 3u, 
+                                    (unsigned int)objs->size() );
+      IObjectPtr obj = getNext(objs);
+      CPPUNIT_ASSERT_MESSAGE( "obj 1 payload", 
+                              dummyPayload( 2 ) == obj->payload() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 1 since",
+                                    (ValidityKey)2, obj->since() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 1 until",
+                                    (ValidityKey)3, obj->until() );
+      obj = getNext(objs);
+      CPPUNIT_ASSERT_MESSAGE( "obj 2 payload", 
+                              dummyPayload( 1 ) == obj->payload() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 2 since",
+                                    (ValidityKey)4, obj->since() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 2 until",
+                                    (ValidityKey)5, obj->until() );      
+      obj = getNext(objs);
+      CPPUNIT_ASSERT_MESSAGE( "obj 3 payload", 
+                              dummyPayload( 3 ) == obj->payload() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 3 since",
+                                    (ValidityKey)5, obj->since() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 3 until",
+                                    (ValidityKey)6, obj->until() );
+      */
+    }
+
+
+    /// Tests storing unordered, non-overlapping SV IOVS (all closed but one).
+    /// See https://savannah.cern.ch/task/?func=detailitem&item_id=3138:
+    /// tests that the functionality of use case #1 is NOT YET provided
+    /// (back-insertion is not yet allowed for bulk inserting
+    /// more than one IOV per channel - in single or multi channel mode).
+    /// NB - note the different exception message with respect to the 
+    /// previous test (different code segments)... is this correct?
+    /// sas: Yes, that's intentional to 
+    /// a) provide better feedback for the user in case of an exception. By
+    ///    giving them a clear idea what went wrong they can rearrange 
+    ///    insertion to comply with the implemented case #1 more easily
+    /// b) allow me/us to find which part is actually throwing the exception
+    ///    while we try to extend the functionality
+    void test_storeObject_SV_unordered_bulk_open_2() 
+    {
+      IFolderPtr folder = m_db->createFolder( "/f2", payloadSpec );
+      folder->storeObject( 4, ValidityKeyMax, dummyPayload( 1 ), 0 );
+      folder->setupStorageBuffer();
+      folder->storeObject( 2, 3, dummyPayload( 1 ), 0 );
+      folder->storeObject( 5, 6, dummyPayload( 1 ), 0 );
+      try 
+      {
+        folder->flushStorageBuffer();
+      }
+      catch ( std::exception& e ) 
+      {
+        CPPUNIT_ASSERT_EQUAL_MESSAGE
+          ( "4 until",
+            //string( "Overlapping intervals "
+            //        "not allowed in SINGLE_VERSION mode" ),
+            string( "Back-insertion not possible "
+                    "due to multiple objects in channel" ),
+            string( e.what() ) );
+      }
+      IObjectIteratorPtr objs = folder->browseObjects( ValidityKeyMin,
+                                                       ValidityKeyMax, 0 );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "object count", 1u, 
+                                    (unsigned int)objs->size() );
+      IObjectPtr obj = getNext(objs);
+      CPPUNIT_ASSERT_MESSAGE( "obj 2 payload", 
+                              dummyPayload( 1 ) == obj->payload() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 2 since",
+                                    (ValidityKey)4, obj->since() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 2 until",
+                                    ValidityKeyMax, obj->until() );      
+      /*
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "object count", 3u, 
+                                    (unsigned int)objs->size() );
+      IObjectPtr obj = getNext(objs);
+      CPPUNIT_ASSERT_MESSAGE( "obj 1 payload", 
+                              dummyPayload( 2 ) == obj->payload() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 1 since",
+                                    (ValidityKey)2, obj->since() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 1 until",
+                                    (ValidityKey)3, obj->until() );
+      obj = getNext(objs);
+      CPPUNIT_ASSERT_MESSAGE( "obj 2 payload", 
+                              dummyPayload( 1 ) == obj->payload() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 2 since",
+                                    (ValidityKey)4, obj->since() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 2 until",
+                                    (ValidityKey)5, obj->until() );      
+      obj = getNext(objs);
+      CPPUNIT_ASSERT_MESSAGE( "obj 3 payload", 
+                              dummyPayload( 3 ) == obj->payload() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 3 since",
+                                    (ValidityKey)5, obj->since() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 3 until",
+                                    (ValidityKey)6, obj->until() );
+      */
+    }
+    
+    
+    /// Tests storing unordered, non-overlapping SV IOVS (all closed but one).
+    /// See https://savannah.cern.ch/task/?func=detailitem&item_id=3138:
+    /// tests that the functionality of use case #1 is NOT YET provided
+    /// (back-insertion is not yet allowed for bulk inserting
+    /// more than one IOV per channel - in single or multi channel mode).
+    void test_storeObject_SV_unordered_bulk_open_3() 
+    {
+      IFolderPtr folder = m_db->createFolder( "/f2", payloadSpec );
+      folder->setupStorageBuffer();
+      folder->storeObject( 4, ValidityKeyMax, dummyPayload( 1 ), 0 );
+      folder->storeObject( 2, 3, dummyPayload( 1 ), 0 );
+      try 
+      {
+        folder->flushStorageBuffer();
+      }
+      catch ( std::exception& e ) 
+      {
+        CPPUNIT_ASSERT_EQUAL_MESSAGE
+          ( "4 until",
+            string( "Overlapping intervals "
+                    "not allowed in SINGLE_VERSION mode" ),
+            //string( "Back-insertion not possible "
+            //        "due to multiple objects in channel" ),
+            string( e.what() ) );
+      }
+      IObjectIteratorPtr objs = folder->browseObjects( ValidityKeyMin,
+                                                       ValidityKeyMax, 0 );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "object count", 0u, 
+                                    (unsigned int)objs->size() );
+      /*
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "object count", 2u, 
+                                    (unsigned int)objs->size() );
+      IObjectPtr obj = getNext(objs);
+      CPPUNIT_ASSERT_MESSAGE( "obj 1 payload", 
+                              dummyPayload( 2 ) == obj->payload() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 1 since",
+                                    (ValidityKey)2, obj->since() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 1 until",
+                                    (ValidityKey)3, obj->until() );
+      obj = getNext(objs);
+      CPPUNIT_ASSERT_MESSAGE( "obj 2 payload", 
+                              dummyPayload( 1 ) == obj->payload() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 2 since",
+                                    (ValidityKey)4, obj->since() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 2 until",
+                                    (ValidityKey)5, obj->until() );      
+      */
+    }
+
+
+    /// Tests storing unordered, non-overlapping SV MC IOVS (all closed).
+    /// See https://savannah.cern.ch/task/?func=detailitem&item_id=3138:
+    /// tests that the functionality of use case #3 is provided
+    /// (back-insertion is allowed for single-IOV multi-channel insertion).
+    void test_storeObject_SV_unordered_MC_closed()
+    {
+      IFolderPtr folder = m_db->createFolder( "/f1", payloadSpec );
+      folder->storeObject( 0, 2, dummyPayload( 1 ), 1 );
+      folder->storeObject( 2, 4, dummyPayload( 2 ), 1 );
+      folder->storeObject( 2, 4, dummyPayload( 2 ), 2 );
+      folder->storeObject( 0, 2, dummyPayload( 1 ), 2 ); 
+      {
+        IObjectIteratorPtr objs = folder->browseObjects( ValidityKeyMin,
+                                                         ValidityKeyMax, 1 );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "object count", 2u, 
+                                      (unsigned int)objs->size() );      
+        IObjectPtr obj = getNext(objs);
+        CPPUNIT_ASSERT_MESSAGE( "obj 1 payload", 
+                                dummyPayload( 1 ) == obj->payload() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 1 since",
+                                      (ValidityKey)0, obj->since() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 1 until",
+                                      (ValidityKey)2, obj->until() );      
+        obj = getNext(objs);
+        CPPUNIT_ASSERT_MESSAGE( "obj 2 payload", 
+                                dummyPayload( 2 ) == obj->payload() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 2 since",
+                                      (ValidityKey)2, obj->since() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 2 until",
+                                      (ValidityKey)4, obj->until() );
+      }
+      {
+        IObjectIteratorPtr objs = folder->browseObjects( ValidityKeyMin,
+                                                         ValidityKeyMax, 2 );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "object count", 2u, 
+                                      (unsigned int)objs->size() );      
+        IObjectPtr obj = getNext(objs);
+        CPPUNIT_ASSERT_MESSAGE( "obj 1 payload", 
+                                dummyPayload( 1 ) == obj->payload() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 1 since",
+                                      (ValidityKey)0, obj->since() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 1 until",
+                                      (ValidityKey)2, obj->until() );      
+        obj = getNext(objs);
+        CPPUNIT_ASSERT_MESSAGE( "obj 2 payload", 
+                                dummyPayload( 2 ) == obj->payload() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 2 since",
+                                      (ValidityKey)2, obj->since() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 2 until",
+                                      (ValidityKey)4, obj->until() );
+      }
+    }
+
+
+    /// Tests storing unordered, non-overlapping SV MC IOVS (all closed).
+    /// See https://savannah.cern.ch/task/?func=detailitem&item_id=3138:
+    /// tests that the functionality of use case #1 is NOT YET provided
+    /// (back-insertion is not yet allowed for bulk inserting
+    /// more than one IOV per channel - in single or multi channel mode).
+    void test_storeObject_SV_unordered_MC_bulk_closed()
+    {
+      IFolderPtr folder = m_db->createFolder( "/f1", payloadSpec );
+      folder->setupStorageBuffer();
+      folder->storeObject( 0, 2, dummyPayload( 1 ), 1 );
+      folder->storeObject( 2, 4, dummyPayload( 2 ), 1 );
+      folder->storeObject( 2, 4, dummyPayload( 2 ), 2 );
+      folder->storeObject( 0, 2, dummyPayload( 1 ), 2 ); 
+      try 
+      {
+        folder->flushStorageBuffer();
+      }
+      catch ( std::exception& e ) 
+      {
+        CPPUNIT_ASSERT_EQUAL_MESSAGE
+          ( "multichannel",
+            string( "Overlapping intervals "
+                    "not allowed in SINGLE_VERSION mode" ),
+            string( e.what() ) );
+      }
+      {
+        IObjectIteratorPtr objs = folder->browseObjects( ValidityKeyMin,
+                                                         ValidityKeyMax, 1 );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "object count", 0u, 
+                                      (unsigned int)objs->size() );      
+        /*
+        IObjectIteratorPtr objs = folder->browseObjects( ValidityKeyMin,
+                                                         ValidityKeyMax, 1 );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "object count", 2u, 
+                                      (unsigned int)objs->size() );      
+        IObjectPtr obj = getNext(objs);
+        CPPUNIT_ASSERT_MESSAGE( "obj 1 payload", 
+                                dummyPayload( 1 ) == obj->payload() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 1 since",
+                                      (ValidityKey)0, obj->since() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 1 until",
+                                      (ValidityKey)2, obj->until() );      
+        obj = getNext(objs);
+        CPPUNIT_ASSERT_MESSAGE( "obj 2 payload", 
+                                dummyPayload( 2 ) == obj->payload() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 2 since",
+                                      (ValidityKey)2, obj->since() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 2 until",
+                                      (ValidityKey)4, obj->until() );
+        */
+      }
+      {
+        IObjectIteratorPtr objs = folder->browseObjects( ValidityKeyMin,
+                                                         ValidityKeyMax, 2 );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "object count", 0u, 
+                                      (unsigned int)objs->size() );      
+        /*
+        IObjectIteratorPtr objs = folder->browseObjects( ValidityKeyMin,
+                                                         ValidityKeyMax, 2 );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "object count", 2u, 
+                                      (unsigned int)objs->size() );      
+        IObjectPtr obj = getNext(objs);
+        CPPUNIT_ASSERT_MESSAGE( "obj 1 payload", 
+                                dummyPayload( 1 ) == obj->payload() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 1 since",
+                                      (ValidityKey)0, obj->since() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 1 until",
+                                      (ValidityKey)2, obj->until() );      
+        obj = getNext(objs);
+        CPPUNIT_ASSERT_MESSAGE( "obj 2 payload", 
+                                dummyPayload( 2 ) == obj->payload() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 2 since",
+                                      (ValidityKey)2, obj->since() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 2 until",
+                                      (ValidityKey)4, obj->until() );
+        */
+      }
+    }
+
+
+    /// Tests storing unordered, non-overlapping SV MC IOVS (all closed).
+    /// See https://savannah.cern.ch/task/?func=detailitem&item_id=3138:
+    /// tests that the functionality of use case #2 is provided
+    /// (back-insertion is allowed for bulk inserting
+    /// at most one IOV per channel - in multi channel mode).
+    void test_storeObject_SV_unordered_MC_bulk_closed_oneperchannel()
+    {
+      IFolderPtr folder = m_db->createFolder( "/f1", payloadSpec );
+      folder->setupStorageBuffer();
+      folder->storeObject( 2, 4, dummyPayload( 2 ), 1 );
+      folder->storeObject( 2, 4, dummyPayload( 2 ), 2 );
+      folder->flushStorageBuffer();
+      folder->storeObject( 0, 2, dummyPayload( 1 ), 1 );
+      folder->storeObject( 0, 2, dummyPayload( 1 ), 2 ); 
+      folder->flushStorageBuffer(); // Bulk-back-insert two IOVs (one per ch)
+      {
+        IObjectIteratorPtr objs = folder->browseObjects( ValidityKeyMin,
+                                                         ValidityKeyMax, 1 );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "object count", 2u, 
+                                      (unsigned int)objs->size() );      
+        IObjectPtr obj = getNext(objs);
+        CPPUNIT_ASSERT_MESSAGE( "obj 1 payload", 
+                                dummyPayload( 1 ) == obj->payload() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 1 since",
+                                      (ValidityKey)0, obj->since() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 1 until",
+                                      (ValidityKey)2, obj->until() );      
+        obj = getNext(objs);
+        CPPUNIT_ASSERT_MESSAGE( "obj 2 payload", 
+                                dummyPayload( 2 ) == obj->payload() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 2 since",
+                                      (ValidityKey)2, obj->since() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 2 until",
+                                      (ValidityKey)4, obj->until() );
+      }
+      {
+        IObjectIteratorPtr objs = folder->browseObjects( ValidityKeyMin,
+                                                         ValidityKeyMax, 2 );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "object count", 2u, 
+                                      (unsigned int)objs->size() );      
+        IObjectPtr obj = getNext(objs);
+        CPPUNIT_ASSERT_MESSAGE( "obj 1 payload", 
+                                dummyPayload( 1 ) == obj->payload() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 1 since",
+                                      (ValidityKey)0, obj->since() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 1 until",
+                                      (ValidityKey)2, obj->until() );      
+        obj = getNext(objs);
+        CPPUNIT_ASSERT_MESSAGE( "obj 2 payload", 
+                                dummyPayload( 2 ) == obj->payload() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 2 since",
+                                      (ValidityKey)2, obj->since() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 2 until",
+                                      (ValidityKey)4, obj->until() );
+      }
+    }
+
+
+    /// Tests storing unordered, non-overlapping SV MC IOVS (all closed).
+    /// See https://savannah.cern.ch/task/?func=detailitem&item_id=3138:
+    /// tests that the functionality of use case #2 is provided
+    /// (back-insertion is allowed for bulk inserting
+    /// at most one IOV per channel - in multi channel mode:
+    /// it is also allowed for inserting several IOVs per channel, 
+    /// as long as there is only IOV per channel in the channels 
+    /// where one IOV is back-inserted).
+    void test_storeObject_SV_unordered_MC_bulk_closed_oneperchannel_2()
+    {
+      IFolderPtr folder = m_db->createFolder( "/f1", payloadSpec );
+      folder->setupStorageBuffer();
+      folder->storeObject( 2, 4, dummyPayload( 2 ), 1 );
+      folder->storeObject( 2, 4, dummyPayload( 2 ), 2 );
+      folder->flushStorageBuffer();
+      folder->storeObject( 0, 2, dummyPayload( 1 ), 1 );
+      folder->storeObject( 4, 6, dummyPayload( 3 ), 2 ); 
+      folder->storeObject( 6, 8, dummyPayload( 4 ), 2 ); 
+      folder->flushStorageBuffer(); // Bulk-back-insert three IOVs
+      {
+        IObjectIteratorPtr objs = folder->browseObjects( ValidityKeyMin,
+                                                         ValidityKeyMax, 1 );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "object count", 2u, 
+                                      (unsigned int)objs->size() );      
+        IObjectPtr obj = getNext(objs);
+        CPPUNIT_ASSERT_MESSAGE( "obj 1 payload", 
+                                dummyPayload( 1 ) == obj->payload() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 1 since",
+                                      (ValidityKey)0, obj->since() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 1 until",
+                                      (ValidityKey)2, obj->until() );      
+        obj = getNext(objs);
+        CPPUNIT_ASSERT_MESSAGE( "obj 2 payload", 
+                                dummyPayload( 2 ) == obj->payload() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 2 since",
+                                      (ValidityKey)2, obj->since() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 2 until",
+                                      (ValidityKey)4, obj->until() );
+      }
+      {
+        IObjectIteratorPtr objs = folder->browseObjects( ValidityKeyMin,
+                                                         ValidityKeyMax, 2 );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "object count", 3u, 
+                                      (unsigned int)objs->size() );      
+        IObjectPtr obj = getNext(objs);
+        CPPUNIT_ASSERT_MESSAGE( "obj 2 payload", 
+                                dummyPayload( 2 ) == obj->payload() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 2 since",
+                                      (ValidityKey)2, obj->since() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 2 until",
+                                      (ValidityKey)4, obj->until() );      
+        obj = getNext(objs);
+        CPPUNIT_ASSERT_MESSAGE( "obj 3 payload", 
+                                dummyPayload( 3 ) == obj->payload() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 3 since",
+                                      (ValidityKey)4, obj->since() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 3 until",
+                                      (ValidityKey)6, obj->until() );
+        obj = getNext(objs);
+        CPPUNIT_ASSERT_MESSAGE( "obj 4 payload", 
+                                dummyPayload( 4 ) == obj->payload() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 4 since",
+                                      (ValidityKey)6, obj->since() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 4 until",
+                                      (ValidityKey)8, obj->until() );
+      }
+    }
+
+
+    /// Tests storing unordered, non-overlapping SV IOVS (all closed).
+    /// See https://savannah.cern.ch/task/?func=detailitem&item_id=3138:
+    /// tests that the functionality of use case #1 is NOT YET provided
+    /// (back-insertion is not yet allowed for bulk inserting
+    /// more than one IOV per channel - in single or multi channel mode,
+    /// even if only one IOV is back-inserted and the others are not).
+    void test_storeObject_SV_unordered_bulk_closed_oneback() 
+    {
+      IFolderPtr folder = m_db->createFolder( "/f1", payloadSpec );
+      folder->storeObject( 2, 4, dummyPayload( 2 ), 0 );
+      folder->setupStorageBuffer();
+      folder->storeObject( 0, 2, dummyPayload( 1 ), 0 );
+      folder->storeObject( 4, 6, dummyPayload( 3 ), 0 );
+      try 
+      {
+        folder->flushStorageBuffer();
+      }
+      catch ( std::exception& e ) 
+      {
+        CPPUNIT_ASSERT_EQUAL_MESSAGE
+          ( "6 until",
+            string( "Back-insertion not possible "
+                    "due to multiple objects in channel" ),
+            string( e.what() ) );
+      }
+      IObjectIteratorPtr objs = folder->browseObjects( ValidityKeyMin,
+                                                       ValidityKeyMax, 0 );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "object count", 1u, 
+                                    (unsigned int)objs->size() );      
+      IObjectPtr obj = getNext(objs);
+      CPPUNIT_ASSERT_MESSAGE( "obj 2 payload", 
+                              dummyPayload( 2 ) == obj->payload() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 2 since",
+                                    (ValidityKey)2, obj->since() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 2 until",
+                                    (ValidityKey)4, obj->until() );
+      /*
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "object count", 3u, 
+                                    (unsigned int)objs->size() );      
+      IObjectPtr obj = getNext(objs);
+      CPPUNIT_ASSERT_MESSAGE( "obj 1 payload", 
+                              dummyPayload( 1 ) == obj->payload() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 1 since",
+                                    (ValidityKey)0, obj->since() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 1 until",
+                                    (ValidityKey)2, obj->until() );
+      obj = getNext(objs);
+      CPPUNIT_ASSERT_MESSAGE( "obj 2 payload", 
+                              dummyPayload( 2 ) == obj->payload() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 2 since",
+                                    (ValidityKey)2, obj->since() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 2 until",
+                                    (ValidityKey)4, obj->until() );
+      obj = getNext(objs);
+      CPPUNIT_ASSERT_MESSAGE( "obj 3 payload", 
+                              dummyPayload( 3 ) == obj->payload() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 3 since",
+                                    (ValidityKey)4, obj->since() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 3 until",
+                                    (ValidityKey)6, obj->until() );
+      */
+    }
+
+
+    /// Tests storeObject with overlapping intervals
+    /// bug #9212 reported 2005-06-24 by Federico
+    void test_storeObject_SV_overlap_bulk() 
+    {
+      try 
+      {
+        IFolderPtr folder = m_db->createFolder( "/f1", payloadSpec );
+        folder->setupStorageBuffer();
+        folder->storeObject( 300, 400, dummyPayload( 1 ), 0 );
+        folder->storeObject( 200, 400, dummyPayload( 1 ), 0 );
+        folder->flushStorageBuffer();
+        CPPUNIT_FAIL( "400 until exception expected" );
+      } 
+      catch ( std::exception& e ) 
+      {
+        CPPUNIT_ASSERT_EQUAL_MESSAGE
+          ( "400 until",
+            string( "Overlapping intervals "
+                    "not allowed in SINGLE_VERSION mode" ),
+            string( e.what() ) );
+      }  
+      try 
+      {
+        IFolderPtr folder = m_db->createFolder( "/f2", payloadSpec );
+        folder->setupStorageBuffer();
+        folder->storeObject( 300, 350, dummyPayload( 1 ), 0 );
+        folder->storeObject( 200, 400, dummyPayload( 1 ), 0 );
+        folder->flushStorageBuffer();
+        CPPUNIT_FAIL( "non-equal until exception expected" );
+      } 
+      catch ( std::exception& e ) 
+      {
+        CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "non-equal until",
+          string( "Overlapping intervals not allowed in SINGLE_VERSION mode" ),
+          string( e.what() ) );
+      }      
+      try 
+      {
+        IFolderPtr folder = m_db->createFolder( "/f3", payloadSpec );
+        folder->setupStorageBuffer();
+        folder->storeObject( 300, ValidityKeyMax, dummyPayload( 1 ), 0 );
+        folder->storeObject( 200, ValidityKeyMax, dummyPayload( 1 ), 0 );
+        folder->flushStorageBuffer();
+        CPPUNIT_FAIL( "ValidityKeyMax until exception expected" );
+      } 
+      catch ( std::exception& e ) 
+      {
+        CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "ValidityKeyMax until",
+          string( "Overlapping intervals not allowed in SINGLE_VERSION mode" ),
+          string( e.what() ) );
+      }
+    }
+    
+    
+    /// Tests storeObject with overlapping intervals
+    /// bug #9212 reported 2005-06-24 by Federico
+    void test_storeObject_SV_overlap() 
+    {
+      try 
+      {
+        IFolderPtr folder = m_db->createFolder( "/f1", payloadSpec );
+        folder->storeObject( 300, 400, dummyPayload( 1 ), 0 );
+        folder->storeObject( 200, 400, dummyPayload( 1 ), 0 );
+        CPPUNIT_FAIL( "400 until exception expected" );
+      } 
+      catch ( std::exception& e ) 
+      {
+        CPPUNIT_ASSERT_EQUAL_MESSAGE
+          ( "400 until",
+            string( "Back-insertion collision: overlapping intervals "
+                    "not allowed in SINGLE_VERSION mode" ),
+            string( e.what() ) );
+      }
+      try 
+      {
+        IFolderPtr folder = m_db->createFolder( "/f2", payloadSpec );
+        folder->storeObject( 300, 350, dummyPayload( 1 ), 0 );
+        folder->storeObject( 200, 400, dummyPayload( 1 ), 0 );
+        CPPUNIT_FAIL( "non-equal until exception expected" );
+      } 
+      catch ( std::exception& e ) 
+      {
+        CPPUNIT_ASSERT_EQUAL_MESSAGE
+          ( "non-equal until",
+            string( "Back-insertion collision: overlapping intervals "
+                    "not allowed in SINGLE_VERSION mode" ),
+            string( e.what() ) );
+      }
+      try 
+      {
+        IFolderPtr folder = m_db->createFolder( "/f3", payloadSpec );
+        folder->storeObject( 300, ValidityKeyMax, dummyPayload( 1 ), 0 );
+        folder->storeObject( 200, ValidityKeyMax, dummyPayload( 1 ), 0 );
+        CPPUNIT_FAIL( "ValidityKeyMax until exception expected" );
+      } 
+      catch ( std::exception& e ) 
+      {
+        CPPUNIT_ASSERT_EQUAL_MESSAGE
+          ( "ValidityKeyMax until",
+            string( "Back-insertion collision: overlapping intervals "
+                    "not allowed in SINGLE_VERSION mode" ),
+            string( e.what() ) );
+      }
+    }
+    
+    
+    /// Tests updating the folder description
+    void test_setDescription() {
+      {
+        IFolderPtr folder = m_db->createFolder( "/myfolder", 
+                                              payloadSpec, 
+                                              "a description" );
+        folder->setDescription( "new description" );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "internal desc update",
+                                      string( "new description" ),
+                                      folder->description() );
+      }
+      {
+        IFolderPtr folder = m_db->getFolder( "/myfolder" );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "db desc update",
+                                      string( "new description" ),
+                                      folder->description() );
+      }        
+    }
+    
+    /// Tests bulk insertion into multiple channels (SV mode)
+    void test_storeObjects_bulk_multichannel() {
+      IFolderPtr folder = m_db->createFolder( "/myfolder", payloadSpec );
+      
+      folder->setupStorageBuffer();
+
+      ChannelId nChannels = 10;
+      {
+        for ( ChannelId ch = 0; ch < nChannels; ++ch ) {
+          folder->storeObject( (ValidityKey)0, ValidityKeyMax, 
+                               dummyPayload( (int)ch ), ch );
+        }
+        for ( ChannelId ch = 0; ch < nChannels; ++ch ) {
+          folder->storeObject( (ValidityKey)5, ValidityKeyMax, 
+                               dummyPayload( (int)ch ), ch );
+        }
+      }
+
+      folder->flushStorageBuffer();
+      
+      unsigned int nObjsPerChannel = 2;
+      IObjectPtr obj;
+      for ( ChannelId ch = 0; ch < nChannels; ++ch ) {
+        for ( unsigned int i = 0; i < nObjsPerChannel; ++i ) {
+          stringstream s;
+          s << "object " << i << ", channel " << ch << " ";
+          
+          ValidityKey pointInTime = 5 * i; // 0, 5
+          obj = folder->findObject( pointInTime, ch );
+          
+          CPPUNIT_ASSERT_MESSAGE( ( s.str() + "payload" ).c_str(), 
+                                  dummyPayload( (int)ch ) == obj->payload() );
+          CPPUNIT_ASSERT_EQUAL_MESSAGE( ( s.str() + "since" ).c_str(), 
+                                        pointInTime, obj->since() );
+          
+          // until of last extends to ValidityKeyMax
+          if ( i < nObjsPerChannel-1 ) {
+            CPPUNIT_ASSERT_EQUAL_MESSAGE( ( s.str() + "until" ).c_str(), 
+                                          pointInTime +5, obj->until() );
+          } else {
+            CPPUNIT_ASSERT_EQUAL_MESSAGE( ( s.str() + "until" ).c_str(), 
+                                          ValidityKeyMax, obj->until() );
+          }
+        }
+      }
+    }
+    
+    
+    /// Tests tagDescription (MultiVersion only, SingleVersion does not have
+    /// tags and throws a RelationalException)
+    void test_tagDescription() {
+      try {
+        IFolderPtr folder = m_db->createFolder
+          ( "/myfolder", 
+            payloadSpec,
+            "my description",
+            FolderVersioning::MULTI_VERSION );
+        folder->storeObject( 0, ValidityKeyMax, dummyPayload( 0 ), 0 );
+        folder->tagCurrentHead( "A", "desc A" );
+      
+        std::string desc = folder->tagDescription( "A" );
+        
+        CPPUNIT_ASSERT_EQUAL_MESSAGE
+          ( "tag desc", std::string("desc A"), desc );
+        
+        try {
+          folder->tagDescription( "nonexisting tag" );
+          CPPUNIT_FAIL( "exception not thrown for nonexisting tag" );
+        } catch ( TagNotFound& /* ignored */ ) { }
+
+      } catch ( std::exception& e ) {
+        std::cout << "Exception caught: " << e.what() << std::endl;
+        throw;
+      }
+
+    }
+    
+    
+    /// Tests tagInsertionTime (MultiVersion only, SingleVersion does not have
+    /// tags and throws a RelationalException)
+    void test_tagInsertionTime() {
+      try{
+        IFolderPtr folder = m_db->createFolder
+          ( "/myfolder", 
+            payloadSpec,
+            "my description",
+            FolderVersioning::MULTI_VERSION );
+        folder->storeObject( 0, ValidityKeyMax, dummyPayload( 0 ), 0 );
+        
+        folder->tagCurrentHead( "A" );
+        
+        Time tagTime = folder->tagInsertionTime( "A" );
+        
+        // the real time functionality test 
+        // is implemented in test_RalDatabase.cpp
+        CPPUNIT_ASSERT_EQUAL_MESSAGE
+          ( "tagTime size", 
+            string("yyyy-mm-dd_hh:mm:ss.nnnnnnnnn GMT").size(),
+            timeToString(tagTime).size() );
+        
+        try {
+          folder->tagInsertionTime( "nonexisting tag" );
+          CPPUNIT_FAIL( "exception not thrown for nonexisting tag" );
+        } catch ( TagNotFound& /* ignored */ ) { }
+
+      } catch ( std::exception& e ) {
+        std::cout << "Exception caught: " << e.what() << std::endl;
+        throw;
+      }
+
+    }
+    
+    
+    /// Tests listTags for MV folders
+    void test_listTags_MV() {
+      try {
+        IFolderPtr folder = 
+          m_db->createFolder( "/myfolder", 
+                            payloadSpec,
+                            "my description",
+                            FolderVersioning::MULTI_VERSION );
+        folder->storeObject( 0, ValidityKeyMax, dummyPayload( 0 ), 0 );
+        folder->tagCurrentHead( "A" );
+        folder->tagCurrentHead( "B" );
+        std::vector<std::string> tags = folder->listTags();
+        CPPUNIT_ASSERT_EQUAL_MESSAGE
+          ( "tag count", 2u, (unsigned int)tags.size() );    
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "tag 1", std::string("A"), tags[0] );    
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "tag 2", std::string("B"), tags[1] );    
+      } catch ( std::exception& e ) {
+        std::cout << "Exception caught: " << e.what() << std::endl;
+        throw;
+      }
+    }
+    
+    
+    /// Tests listTags for SV folders: there are no tags
+    void test_listTags_SV() {
+      try {
+        IFolderPtr folder = 
+          m_db->createFolder( "/myfolder", 
+                            payloadSpec,
+                            "my description",
+                            FolderVersioning::SINGLE_VERSION );
+        std::vector<std::string> tags = folder->listTags();
+        CPPUNIT_ASSERT_EQUAL_MESSAGE
+          ( "tag count", 0u, (unsigned int)tags.size() );
+      } catch ( std::exception& e ) {
+        std::cout << "Exception caught: " << e.what() << std::endl;
+        throw;     
+      }
+    }
+  
+  
+    /// Tests object browsing in tags (MV folders)
+    void test_browseObjects_MV_tag() {
+      IFolderPtr folder = m_db->createFolder( "/myfolder", 
+                                            payloadSpec,
+                                            "my description",
+                                            FolderVersioning::MULTI_VERSION );
+      
+      folder->storeObject(  0, 10, dummyPayload( 0 ), 0 );
+      folder->storeObject( 10, 20, dummyPayload( 1 ), 0 );
+      folder->storeObject( 20, ValidityKeyMax, dummyPayload( 2 ), 0 );
+      
+      folder->tagCurrentHead( "mytag" );
+      
+      {
+        IObjectIteratorPtr objs = folder->browseObjects( 5, 15, 0, "mytag" );
+        
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "object count", 2u, 
+                                      (unsigned int)objs->size() );
+        
+        IObjectPtr obj = getNext(objs);
+        CPPUNIT_ASSERT_MESSAGE( "obj 1.1 payload", 
+                                dummyPayload( 0 ) == obj->payload() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 1.1 since",
+                                      (ValidityKey)0, obj->since() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 1.1 until",
+                                      (ValidityKey)10, obj->until() );
+        
+        obj = getNext(objs);
+        CPPUNIT_ASSERT_MESSAGE( "obj 1.2 payload", 
+                                dummyPayload( 1 ) == obj->payload() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 1.2 since",
+                                      (ValidityKey)10, obj->since() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 1.2 until",
+                                      (ValidityKey)20, obj->until() );
+      }
+      
+      {
+        IObjectIteratorPtr objs = folder->browseObjects( 10, 20, 0, "mytag" );
+        
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "object count", 2u, 
+                                      (unsigned int)objs->size() );
+        
+        IObjectPtr obj = getNext(objs);
+        CPPUNIT_ASSERT_MESSAGE( "obj 2.1 payload", 
+                                dummyPayload( 1 ) == obj->payload() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 2.1 since",
+                                      (ValidityKey)10, obj->since() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 2.1 until",
+                                      (ValidityKey)20, obj->until() );
+        
+        obj = getNext(objs);
+        CPPUNIT_ASSERT_MESSAGE( "obj 2.2 payload", 
+                                dummyPayload( 2 ) == obj->payload() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 2.1 since",
+                                      (ValidityKey)20, obj->since() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 2.1 until",
+                                      ValidityKeyMax, obj->until() );
+      }
+      
+      
+      {
+        IObjectIteratorPtr objs = folder->browseObjects( ValidityKeyMin,
+                                                         ValidityKeyMax,
+                                                         0, "mytag" );
+        
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "object count", 3u, 
+                                      (unsigned int)objs->size() );
+        
+        IObjectPtr obj = getNext(objs);
+        CPPUNIT_ASSERT_MESSAGE( "obj 3.1 payload", 
+                                dummyPayload( 0 ) == obj->payload() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 3.1 since",
+                                      (ValidityKey)0, obj->since() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 3.1 until",
+                                      (ValidityKey)10, obj->until() );
+        
+        obj = getNext(objs);
+        CPPUNIT_ASSERT_MESSAGE( "obj 3.2 payload", 
+                                dummyPayload( 1 ) == obj->payload() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 3.2 since",
+                                      (ValidityKey)10, obj->since() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 3.2 until",
+                                      (ValidityKey)20, obj->until() );
+        
+        obj = getNext(objs);
+        CPPUNIT_ASSERT_MESSAGE( "obj 3.3 payload", 
+                                dummyPayload( 2 ) == obj->payload() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 3.3 since",
+                                      (ValidityKey)20, obj->since() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 3.3 until",
+                                      ValidityKeyMax, obj->until() );
+      }
+    }
+    
+    
+    /// Tests object browsing (MV folders)
+    void test_browseObjects_MV() {
+      IFolderPtr folder = m_db->createFolder( "/myfolder", 
+                                            payloadSpec,
+                                            "my description",
+                                            FolderVersioning::MULTI_VERSION );
+      
+      folder->storeObject(  0, 10, dummyPayload( 0 ), 0 );
+      folder->storeObject( 10, 20, dummyPayload( 1 ), 0 );
+      folder->storeObject( 20, ValidityKeyMax, dummyPayload( 2 ), 0 );
+      
+      {
+        IObjectIteratorPtr objs = folder->browseObjects( 5, 15, 0 );
+        
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "object count", 2u, 
+                                      (unsigned int)objs->size() );
+        
+        IObjectPtr obj = getNext(objs);
+        CPPUNIT_ASSERT_MESSAGE( "obj 1.1 payload", 
+                                dummyPayload( 0 ) == obj->payload() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 1.1 since",
+                                      (ValidityKey)0, obj->since() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 1.1 until",
+                                      (ValidityKey)10, obj->until() );
+        
+        obj = getNext(objs);
+        CPPUNIT_ASSERT_MESSAGE( "obj 1.2 payload", 
+                                dummyPayload( 1 ) == obj->payload() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 1.2 since",
+                                      (ValidityKey)10, obj->since() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 1.2 until",
+                                      (ValidityKey)20, obj->until() );
+      }
+      
+      {
+        IObjectIteratorPtr objs = folder->browseObjects( 10, 20, 0 );
+        
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "object count", 2u, 
+                                      (unsigned int)objs->size() );
+        
+        IObjectPtr obj = getNext(objs);
+        CPPUNIT_ASSERT_MESSAGE( "obj 2.1 payload", 
+                                dummyPayload( 1 ) == obj->payload() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 2.1 since",
+                                      (ValidityKey)10, obj->since() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 2.1 until",
+                                      (ValidityKey)20, obj->until() );
+        
+        obj = getNext(objs);
+        CPPUNIT_ASSERT_MESSAGE( "obj 2.2 payload", 
+                                dummyPayload( 2 ) == obj->payload() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 2.1 since",
+                                      (ValidityKey)20, obj->since() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 2.1 until",
+                                      ValidityKeyMax, obj->until() );
+      }
+
+      
+      {
+        IObjectIteratorPtr objs = folder->browseObjects( ValidityKeyMin,
+                                                         ValidityKeyMax, 0 );
+        
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "object count", 3u, 
+                                      (unsigned int)objs->size() );
+        
+        IObjectPtr obj = getNext(objs);
+        CPPUNIT_ASSERT_MESSAGE( "obj 3.1 payload", 
+                                dummyPayload( 0 ) == obj->payload() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 3.1 since",
+                                      (ValidityKey)0, obj->since() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 3.1 until",
+                                      (ValidityKey)10, obj->until() );
+        
+        obj = getNext(objs);
+        CPPUNIT_ASSERT_MESSAGE( "obj 3.2 payload", 
+                                dummyPayload( 1 ) == obj->payload() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 3.2 since",
+                                      (ValidityKey)10, obj->since() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 3.2 until",
+                                      (ValidityKey)20, obj->until() );
+        
+        obj = getNext(objs);
+        CPPUNIT_ASSERT_MESSAGE( "obj 3.3 payload", 
+                                dummyPayload( 2 ) == obj->payload() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 3.3 since",
+                                      (ValidityKey)20, obj->since() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 3.3 until",
+                                      ValidityKeyMax, obj->until() );
+      }
+    }
+    
+    
+    /// Tests object browsing all channels (MV folders)
+    void test_browseObjects_all_channels_MV() {
+      IFolderPtr folder = m_db->createFolder( "/myfolder", 
+                                            payloadSpec,
+                                            "my description",
+                                            FolderVersioning::MULTI_VERSION );
+      
+      int index = 0;
+      for ( int i = 0; i < 3; ++i ) {
+        folder->storeObject(  0, 10, dummyPayload( index++ ), (ChannelId)i );
+        folder->storeObject( 10, 20, dummyPayload( index++ ), (ChannelId)i );
+        folder->storeObject( 20, ValidityKeyMax, 
+                             dummyPayload( index++ ), (ChannelId)i );
+      }
+      
+      {
+        ValidityKey since = 5;
+        ValidityKey until = 15;
+        IObjectIteratorPtr 
+          objs = folder->browseObjects( since, until,
+                                        ChannelSelection::all() );
+        
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "object count", 6u, 
+                                      (unsigned int)objs->size() );
+        
+        IObjectPtr obj = getNext(objs);
+        CPPUNIT_ASSERT_MESSAGE( "obj 1 payload", 
+                                dummyPayload( 0 ) == obj->payload() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 1 since",
+                                      (ValidityKey)0, obj->since() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 1 until",
+                                      (ValidityKey)10, obj->until() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 1 channel",
+                                      (ChannelId)0, obj->channelId() );
+        
+        obj = getNext(objs);
+        CPPUNIT_ASSERT_MESSAGE( "obj 2 payload", 
+                                dummyPayload( 1 ) == obj->payload() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 2 since",
+                                      (ValidityKey)10, obj->since() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 2 until",
+                                      (ValidityKey)20, obj->until() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 2 channel",
+                                      (ChannelId)0, obj->channelId() );
+        
+        obj = getNext(objs);
+        CPPUNIT_ASSERT_MESSAGE( "obj 3 payload", 
+                                dummyPayload( 3 ) == obj->payload() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 3 since",
+                                      (ValidityKey)0, obj->since() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 3 until",
+                                      (ValidityKey)10, obj->until() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 3 channel",
+                                      (ChannelId)1, obj->channelId() );
+        
+        obj = getNext(objs);
+        CPPUNIT_ASSERT_MESSAGE( "obj 4 payload", 
+                                dummyPayload( 4 ) == obj->payload() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 4 since",
+                                      (ValidityKey)10, obj->since() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 4 until",
+                                      (ValidityKey)20, obj->until() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 4 channel",
+                                      (ChannelId)1, obj->channelId() );
+        
+        obj = getNext(objs);
+        CPPUNIT_ASSERT_MESSAGE( "obj 5 payload", 
+                                dummyPayload( 6 ) == obj->payload() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 5 since",
+                                      (ValidityKey)0, obj->since() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 5 until",
+                                      (ValidityKey)10, obj->until() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 5 channel",
+                                      (ChannelId)2, obj->channelId() );
+        
+        obj = getNext(objs);
+        CPPUNIT_ASSERT_MESSAGE( "obj 6 payload", 
+                                dummyPayload( 7 ) == obj->payload() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 6 since",
+                                      (ValidityKey)10, obj->since() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 6 until",
+                                      (ValidityKey)20, obj->until() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 4 channel",
+                                      (ChannelId)2, obj->channelId() );
+      }
+      
+    }
+    
+    
+    /// Tests object browsing a channel range (MV folders)
+    void test_browseObjects_channel_range_MV() {
+      IFolderPtr folder = m_db->createFolder( "/myfolder", 
+                                            payloadSpec,
+                                            "my description",
+                                            FolderVersioning::MULTI_VERSION );
+      
+      int index = 0;
+      for ( int i = 0; i < 5; ++i ) {
+        folder->storeObject(  0, 10, dummyPayload( index++ ), (ChannelId)i );
+        folder->storeObject( 10, 20, dummyPayload( index++ ), (ChannelId)i );
+        folder->storeObject( 20, ValidityKeyMax, 
+                             dummyPayload( index++ ), (ChannelId)i );
+      }
+      
+      {
+        ValidityKey since = 5;
+        ValidityKey until = 15;
+        ChannelSelection channels( 2, 3 );
+        IObjectIteratorPtr objs = folder->browseObjects( since,
+                                                         until,
+                                                         channels );
+        
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "object count", 4u, 
+                                      (unsigned int)objs->size() );
+        
+        IObjectPtr obj = getNext(objs);
+        CPPUNIT_ASSERT_MESSAGE( "obj 1 payload", 
+                                dummyPayload( 6 ) == obj->payload() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 1 since",
+                                      (ValidityKey)0, obj->since() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 1 until",
+                                      (ValidityKey)10, obj->until() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 1 channel",
+                                      (ChannelId)2, obj->channelId() );
+        
+        obj = getNext(objs);
+        CPPUNIT_ASSERT_MESSAGE( "obj 2 payload", 
+                                dummyPayload( 7 ) == obj->payload() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 2 since",
+                                      (ValidityKey)10, obj->since() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 2 until",
+                                      (ValidityKey)20, obj->until() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 2 channel",
+                                      (ChannelId)2, obj->channelId() );
+        
+        obj = getNext(objs);
+        CPPUNIT_ASSERT_MESSAGE( "obj 3 payload", 
+                                dummyPayload( 9 ) == obj->payload() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 3 since",
+                                      (ValidityKey)0, obj->since() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 3 until",
+                                      (ValidityKey)10, obj->until() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 3 channel",
+                                      (ChannelId)3, obj->channelId() );
+        
+        obj = getNext(objs);
+        CPPUNIT_ASSERT_MESSAGE( "obj 4 payload", 
+                                dummyPayload( 10 ) == obj->payload() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 4 since",
+                                      (ValidityKey)10, obj->since() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 4 until",
+                                      (ValidityKey)20, obj->until() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 4 channel",
+                                      (ChannelId)3, obj->channelId() );
+      }
+      
+    }
+    
+    
+    /// Tests object browsing all channels (SV folders)
+    void test_browseObjects_all_channels_SV() {
+      IFolderPtr folder = m_db->createFolder( "/myfolder", 
+                                            payloadSpec,
+                                            "my description",
+                                            FolderVersioning::SINGLE_VERSION );
+      
+      int index = 0;
+      for ( int i = 0; i < 3; ++i ) {
+        folder->storeObject(  0, 10, dummyPayload( index++ ), (ChannelId)i );
+        folder->storeObject( 10, 20, dummyPayload( index++ ), (ChannelId)i );
+        folder->storeObject( 20, ValidityKeyMax, 
+                             dummyPayload( index++ ), (ChannelId)i );
+      }
+      
+      {
+        ValidityKey since = 5;
+        ValidityKey until = 15;
+        IObjectIteratorPtr 
+          objs = folder->browseObjects( since, until,
+                                        ChannelSelection::all() );
+        
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "object count", 6u, 
+                                      (unsigned int)objs->size() );
+        
+        IObjectPtr obj = getNext(objs);
+        CPPUNIT_ASSERT_MESSAGE( "obj 1 payload", 
+                                dummyPayload( 0 ) == obj->payload() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 1 since",
+                                      (ValidityKey)0, obj->since() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 1 until",
+                                      (ValidityKey)10, obj->until() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 1 channel",
+                                      (ChannelId)0, obj->channelId() );
+        
+        obj = getNext(objs);
+        CPPUNIT_ASSERT_MESSAGE( "obj 2 payload", 
+                                dummyPayload( 1 ) == obj->payload() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 2 since",
+                                      (ValidityKey)10, obj->since() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 2 until",
+                                      (ValidityKey)20, obj->until() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 2 channel",
+                                      (ChannelId)0, obj->channelId() );
+        
+        obj = getNext(objs);
+        CPPUNIT_ASSERT_MESSAGE( "obj 3 payload", 
+                                dummyPayload( 3 ) == obj->payload() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 3 since",
+                                      (ValidityKey)0, obj->since() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 3 until",
+                                      (ValidityKey)10, obj->until() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 3 channel",
+                                      (ChannelId)1, obj->channelId() );
+        
+        obj = getNext(objs);
+        CPPUNIT_ASSERT_MESSAGE( "obj 4 payload", 
+                                dummyPayload( 4 ) == obj->payload() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 4 since",
+                                      (ValidityKey)10, obj->since() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 4 until",
+                                      (ValidityKey)20, obj->until() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 4 channel",
+                                      (ChannelId)1, obj->channelId() );
+        
+        obj = getNext(objs);
+        CPPUNIT_ASSERT_MESSAGE( "obj 5 payload", 
+                                dummyPayload( 6 ) == obj->payload() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 5 since",
+                                      (ValidityKey)0, obj->since() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 5 until",
+                                      (ValidityKey)10, obj->until() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 5 channel",
+                                      (ChannelId)2, obj->channelId() );
+        
+        obj = getNext(objs);
+        CPPUNIT_ASSERT_MESSAGE( "obj 6 payload", 
+                                dummyPayload( 7 ) == obj->payload() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 6 since",
+                                      (ValidityKey)10, obj->since() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 6 until",
+                                      (ValidityKey)20, obj->until() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 4 channel",
+                                      (ChannelId)2, obj->channelId() );
+      }
+      
+    }
+    
+    
+    /// Tests object browsing a channel range (SV folders)
+    void test_browseObjects_channel_range_SV() {
+      IFolderPtr folder = m_db->createFolder( "/myfolder", 
+                                            payloadSpec,
+                                            "my description",
+                                            FolderVersioning::SINGLE_VERSION );
+      
+      int index = 0;
+      for ( int i = 0; i < 5; ++i ) {
+        folder->storeObject(  0, 10, dummyPayload( index++ ), (ChannelId)i );
+        folder->storeObject( 10, 20, dummyPayload( index++ ), (ChannelId)i );
+        folder->storeObject( 20, ValidityKeyMax, 
+                             dummyPayload( index++ ), (ChannelId)i );
+      }
+      
+      {
+        ValidityKey since = 5;
+        ValidityKey until = 15;
+        ChannelSelection channels( 2, 3 );
+        IObjectIteratorPtr objs = folder->browseObjects( since,
+                                                         until,
+                                                         channels );
+        
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "object count", 4u, 
+                                      (unsigned int)objs->size() );
+        
+        IObjectPtr obj = getNext(objs);
+        CPPUNIT_ASSERT_MESSAGE( "obj 1 payload", 
+                                dummyPayload( 6 ) == obj->payload() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 1 since",
+                                      (ValidityKey)0, obj->since() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 1 until",
+                                      (ValidityKey)10, obj->until() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 1 channel",
+                                      (ChannelId)2, obj->channelId() );
+        
+        obj = getNext(objs);
+        CPPUNIT_ASSERT_MESSAGE( "obj 2 payload", 
+                                dummyPayload( 7 ) == obj->payload() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 2 since",
+                                      (ValidityKey)10, obj->since() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 2 until",
+                                      (ValidityKey)20, obj->until() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 2 channel",
+                                      (ChannelId)2, obj->channelId() );
+
+        obj = getNext(objs);
+        CPPUNIT_ASSERT_MESSAGE( "obj 3 payload", 
+                                dummyPayload( 9 ) == obj->payload() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 3 since",
+                                      (ValidityKey)0, obj->since() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 3 until",
+                                      (ValidityKey)10, obj->until() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 3 channel",
+                                      (ChannelId)3, obj->channelId() );
+        
+        obj = getNext(objs);
+        CPPUNIT_ASSERT_MESSAGE( "obj 4 payload", 
+                                dummyPayload( 10 ) == obj->payload() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 4 since",
+                                      (ValidityKey)10, obj->since() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 4 until",
+                                      (ValidityKey)20, obj->until() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 4 channel",
+                                      (ChannelId)3, obj->channelId() );
+      }
+      
+    }
+    
+
+    /// Tests object browsing (SV folders)
+    void test_browseObjects_SV() {
+      IFolderPtr folder = m_db->createFolder( "/myfolder", 
+                                            payloadSpec,
+                                            "my description",
+                                            FolderVersioning::SINGLE_VERSION );
+      
+      folder->storeObject(  0, 10, dummyPayload( 0 ), 0 );
+      folder->storeObject( 10, 20, dummyPayload( 1 ), 0 );
+      folder->storeObject( 20, ValidityKeyMax, dummyPayload( 2 ), 0 );
+      
+      {
+        IObjectIteratorPtr objs = folder->browseObjects( 5, 15, 0 );
+        
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "object count", 2u, 
+                                      (unsigned int)objs->size() );
+        
+        IObjectPtr obj = getNext(objs);
+        CPPUNIT_ASSERT_MESSAGE( "obj 1.1 payload", 
+                                dummyPayload( 0 ) == obj->payload() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 1.1 since",
+                                      (ValidityKey)0, obj->since() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 1.1 until",
+                                      (ValidityKey)10, obj->until() );
+        
+        obj = getNext(objs);
+        CPPUNIT_ASSERT_MESSAGE( "obj 1.2 payload", 
+                                dummyPayload( 1 ) == obj->payload() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 1.2 since",
+                                      (ValidityKey)10, obj->since() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 1.2 until",
+                                      (ValidityKey)20, obj->until() );
+      }
+      
+      {
+        IObjectIteratorPtr objs = folder->browseObjects( 10, 20, 0 );
+        
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "object count", 2u, 
+                                      (unsigned int)objs->size() );
+        
+        IObjectPtr obj = getNext(objs);
+        CPPUNIT_ASSERT_MESSAGE( "obj 2.1 payload", 
+                                dummyPayload( 1 ) == obj->payload() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 2.1 since",
+                                      (ValidityKey)10, obj->since() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 2.1 until",
+                                      (ValidityKey)20, obj->until() );
+        
+        obj = getNext(objs);
+        CPPUNIT_ASSERT_MESSAGE( "obj 2.2 payload", 
+                                dummyPayload( 2 ) == obj->payload() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 2.1 since",
+                                      (ValidityKey)20, obj->since() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 2.1 until",
+                                      ValidityKeyMax, obj->until() );
+      }
+      
+      
+      {
+        IObjectIteratorPtr objs = folder->browseObjects( ValidityKeyMin,
+                                                         ValidityKeyMax, 0 );
+        
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "object count", 3u, 
+                                      (unsigned int)objs->size() );
+        
+        IObjectPtr obj = getNext(objs);
+        CPPUNIT_ASSERT_MESSAGE( "obj 3.1 payload", 
+                                dummyPayload( 0 ) == obj->payload() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 3.1 since",
+                                      (ValidityKey)0, obj->since() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 3.1 until",
+                                      (ValidityKey)10, obj->until() );
+        
+        obj = getNext(objs);
+        CPPUNIT_ASSERT_MESSAGE( "obj 3.2 payload", 
+                                dummyPayload( 1 ) == obj->payload() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 3.2 since",
+                                      (ValidityKey)10, obj->since() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 3.2 until",
+                                      (ValidityKey)20, obj->until() );
+        
+        obj = getNext(objs);
+        CPPUNIT_ASSERT_MESSAGE( "obj 3.3 payload", 
+                                dummyPayload( 2 ) == obj->payload() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 3.3 since",
+                                      (ValidityKey)20, obj->since() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 3.3 until",
+                                      ValidityKeyMax, obj->until() );
+      }
+    }
+    
+
+    /// Tests browsing a SV selection with lowercase payload
+    /// Test for Richard's ORA-00904 bug report
+    void test_browseObjects_SV_lowercasePayload() 
+    {
+      RecordSpecification payloadSpecNew( payloadSpec );
+      payloadSpecNew.extend( "float2", StorageType::Float);
+      Record payload( payloadSpecNew );
+      payload["I"].setValue<Int32>( 123 );
+      IFolderPtr folder = m_db->createFolder( "/myfolder", 
+                                            payloadSpecNew,
+                                            "my description",
+                                            FolderVersioning::SINGLE_VERSION );
+      
+      folder->storeObject(  0, 10, dummyPayload( 0 ), 0 );
+      folder->storeObject( 10, 20, dummyPayload( 1 ), 0 );
+      folder->storeObject( 20, ValidityKeyMax, dummyPayload( 2 ), 0 );
+      {
+        IObjectIteratorPtr objs = folder->browseObjects( ValidityKeyMin,
+                                                         ValidityKeyMax, 0 );
+        
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "object count", 3u, 
+                                      (unsigned int)objs->size() );
+        
+        IObjectPtr obj = getNext(objs);
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 3.1 since",
+                                      (ValidityKey)0, obj->since() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 3.1 until",
+                                      (ValidityKey)10, obj->until() );
+        
+        obj = getNext(objs);
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 3.2 since",
+                                      (ValidityKey)10, obj->since() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 3.2 until",
+                                      (ValidityKey)20, obj->until() );
+        
+        obj = getNext(objs);
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 3.3 since",
+                                      (ValidityKey)20, obj->since() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 3.3 until",
+                                      ValidityKeyMax, obj->until() );
+      }
+    }
+
+
+    /// Tests object browsing (SV folders)
+    void test_browseObjects_SV_bug42101() 
+    {
+      IFolderPtr folder = 
+        m_db->createFolder( "/myfolder", 
+                            payloadSpec,
+                            "my description",
+                            FolderVersioning::SINGLE_VERSION );
+      
+      folder->storeObject(  0, 10, dummyPayload( 0 ), 0 );
+      folder->storeObject( 10, 20, dummyPayload( 1 ), 0 );
+      folder->storeObject( 20, ValidityKeyMax, dummyPayload( 2 ), 0 );
+      
+      IObjectIteratorPtr objs = folder->browseObjects( 5, 15, 0, "HEAD" );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "object count", 2u, (unsigned int)objs->size() );
+    }
+    
+
+    /// Tests that the storage buffer is cleared and none of the objects
+    /// is stored if an exception is thrown during the bulk operation 
+    /// 'flushStorageBuffer' (for instance, because one IOV has until<since)
+    void test_flushStorageBuffer_exception() 
+    {
+      IFolderPtr folder = m_db->createFolder( "/myfolder", payloadSpec );
+      
+      folder->setupStorageBuffer();
+      folder->storeObject( 0, ValidityKeyMax, dummyPayload( 0 ), 0 );
+      folder->storeObject( 10, 20, dummyPayload( 1 ), 0 );
+      folder->flushStorageBuffer();
+      
+      folder->setupStorageBuffer();
+      folder->storeObject( 20, ValidityKeyMax, dummyPayload( 2 ), 0 );
+      folder->storeObject( 30, 20, dummyPayload( 3 ), 0 ); // INVALID!
+      folder->storeObject( 40, 50, dummyPayload( 4 ), 0 );
+      bool flushFailed = false;
+      try {
+        folder->flushStorageBuffer();
+      } catch ( ValidityKeyException& /* dummy */ ) {
+        flushFailed = true;
+      }
+      CPPUNIT_ASSERT_MESSAGE( "second insertion not OK", flushFailed );
+
+      folder->setupStorageBuffer();
+      folder->storeObject( 50, ValidityKeyMax, dummyPayload( 5 ), 0 );
+      folder->storeObject( 60, 70, dummyPayload( 6 ), 0 ); 
+      folder->flushStorageBuffer();
+      
+      IObjectPtr obj0 = folder->findObject( 0, 0 );
+      CPPUNIT_ASSERT_MESSAGE( "object 0 found",
+                              dummyPayload(0) == obj0->payload() );
+      IObjectPtr obj1 = folder->findObject( 10, 0 );
+      CPPUNIT_ASSERT_MESSAGE( "object 1 found", 
+                              dummyPayload(1) == obj1->payload() );
+
+      bool objectNotFound = false;
+      try {
+        IObjectPtr obj2 = folder->findObject( 20, 0 );
+        std::cout << "ERROR! Found object2: " << obj2 << std::endl;
+      } catch( ObjectNotFound& /* dummy */ ) {
+        objectNotFound = true;
+      }
+      CPPUNIT_ASSERT_MESSAGE( "object 2 not found", objectNotFound );
+
+      objectNotFound = false;
+      try {
+        folder->findObject( 30, 0 );
+      } catch( ObjectNotFound& /* dummy */ ) {
+        objectNotFound = true;
+      }
+      CPPUNIT_ASSERT_MESSAGE( "object 3 not found", objectNotFound );
+
+      objectNotFound = false;
+      try {
+        folder->findObject( 40, 0 );
+      } catch( ObjectNotFound& /* dummy */ ) {
+        objectNotFound = true;
+      }
+      CPPUNIT_ASSERT_MESSAGE( "object 4 not found", objectNotFound );
+
+      IObjectPtr obj5 = folder->findObject( 50, 0 );
+      CPPUNIT_ASSERT_MESSAGE( "object 5 found", 
+                              dummyPayload(5) == obj5->payload() );
+      IObjectPtr obj6 = folder->findObject( 60, 0 );
+      CPPUNIT_ASSERT_MESSAGE( "object 6 found", 
+                              dummyPayload(6) == obj6->payload() );
+
+    }    
+
+    /// Tests that the storage buffer is cleared and none of the objects
+    /// is stored if an exception is thrown during the bulk operation 
+    /// 'flushStorageBuffer' (for instance, because one IOV has until<since),
+    /// even if more than maxBufferSize objects are stored (bug #22474)
+    void test_flushStorageBuffer_exception_bug22474() 
+    {
+      IFolderPtr folder = m_db->createFolder( "/myfolder", payloadSpec );
+      RelationalFolder* relfolder = 
+        dynamic_cast<RelationalFolder*>(folder.get());
+      unsigned maxBufferSize = relfolder->maxBufferSize();
+
+      folder->setupStorageBuffer();
+      for ( unsigned key = 0; key < maxBufferSize; key++ ) 
+      {
+        folder->storeObject( key*10, (key+1)*10, dummyPayload( key ), 0 );
+      }
+      folder->storeObject( 1, 0, dummyPayload( 0 ), 0 ); // INVALID!
+
+      bool flushFailed = false;
+      try {
+        folder->flushStorageBuffer();
+      } catch ( ValidityKeyException& /* dummy */ ) {
+        flushFailed = true;
+      }
+      CPPUNIT_ASSERT_MESSAGE( "Flush should have failed", flushFailed );
+      
+      bool objectNotFound = false;
+      try {
+        IObjectPtr obj = folder->findObject( 0, 0 );
+        std::cout << "ERROR! Found object at 0: " << obj << std::endl;
+      } catch( ObjectNotFound& /* dummy */ ) {
+        objectNotFound = true;
+      }
+      CPPUNIT_ASSERT_MESSAGE( "Object at 0 should not exist", objectNotFound );
+    }    
+
+    /// Tests that a ValidityKeyException is thrown when since>until
+    /// and when since or until are out of boundaries
+    void test_ValidityKeyException() {
+      IFolderPtr folder = m_db->createFolder( "/myfolder", payloadSpec );
+      
+      bool storeFailed = false;
+      try {
+        folder->storeObject( 100, 0, dummyPayload( 0 ), 0 );
+      } catch ( ValidityKeyException& /* dummy */ ) {
+        storeFailed = true;
+      }
+      CPPUNIT_ASSERT_MESSAGE( "exception for [100,0]", storeFailed );      
+
+      storeFailed = false;
+      try {
+        folder->storeObject( 100, 100, dummyPayload( 0 ), 0 );
+      } catch ( ValidityKeyException& /* dummy */ ) {
+        storeFailed = true;
+      }
+      CPPUNIT_ASSERT_MESSAGE( "exception for [100,100]", storeFailed );      
+
+      storeFailed = false;
+      try {
+        // Split the following line on two lines (Windows compiler warning) 
+        //ValidityKey since = ValidityKeyMin-1;
+        ValidityKey since = ValidityKeyMin;
+        since = since-1;
+        ValidityKey until = ValidityKeyMin;
+        // NB: Now (ValidityKey=long_long, ValidityKeyMin=LONG_LONG_MIN)
+        //     ==> LONG_LONG_MIN-1 is an invalid int64 LONG_LONG_MAX > since
+        // NB: Previously (ValidityKey=long_long, ValidityKeyMin=LONG_MIN)
+        //     ==> LONG_MIN-1 is an invalid int64 > LONG_MIN=ValidityKeyMin
+        folder->storeObject( since, until, dummyPayload( 0 ), 0 ); 
+      } catch ( ValidityKeyException& /* dummy */ ) {
+        storeFailed = true;
+      }
+      CPPUNIT_ASSERT_MESSAGE( "exception for [min-1,min]", storeFailed );
+
+      storeFailed = false;
+      try {
+        ValidityKey since = ValidityKeyMax;
+        // Split the following line on two lines (Windows compiler warning) 
+        //ValidityKey until = ValidityKeyMax+1;
+        ValidityKey until = ValidityKeyMax;
+        until = until+1;
+        // NB: Now (ValidityKey=long_long, ValidityKeyMin=LONG_LONG_MIN)
+        //     ==> LONG_LONG_MIN-1 is an invalid int64 LONG_LONG_MAX > since
+        // NB: Previously (ValidityKey=long_long, ValidityKeyMin=LONG_MIN)
+        //     ==> LONG_MIN-1 is an invalid int64 > LONG_MIN=ValidityKeyMin
+        folder->storeObject( since, until, dummyPayload( 0 ), 0 ); 
+      } catch ( ValidityKeyException& /* dummy */ ) {
+        storeFailed = true;
+      }
+      CPPUNIT_ASSERT_MESSAGE( "exception for [max,max+1]", storeFailed );      
+
+    }    
+
+    /// Tests that the ValidityKey boundaries are those we expect
+    /// (use hardcoded numerical values)
+    void test_ValidityKey_boundaries() {
+      //CPPUNIT_ASSERT_EQUAL_MESSAGE
+      //  ( "ValidityKeyMin hardcoded", 
+      //    (ValidityKey)0, ValidityKeyMin + 9223372036854775808ULL );
+      //CPPUNIT_ASSERT_EQUAL_MESSAGE
+      //  ( "ValidityKeyMax hardcoded", 
+      //    (ValidityKey)0, ValidityKeyMax - 18446744073709551615ULL );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "ValidityKeyMin hardcoded", 
+          (ValidityKey)0, ValidityKeyMin );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "ValidityKeyMax hardcoded", 
+          (ValidityKey)0, 
+          (ValidityKey)(ValidityKeyMax - 9223372036854775807LL) );
+      //CPPUNIT_ASSERT_EQUAL_MESSAGE
+      //  ( "ValidityKeyMin Int64Min", 
+      //    (ValidityKey)Int64Min, ValidityKeyMin );
+      //CPPUNIT_ASSERT_EQUAL_MESSAGE
+      //  ( "ValidityKeyMin UInt64Max", 
+      //    (ValidityKey)UInt64Max, ValidityKeyMax );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "ValidityKeyMin UInt64Min", 
+          (ValidityKey)UInt64Min, ValidityKeyMin );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "ValidityKeyMin Int64Max", 
+          (ValidityKey)Int64Max, ValidityKeyMax );
+    }
+  
+
+    /// Stores objects to multiple folders and retrieves them in a loop
+    /// Tests against a problem first reported by Marco Clemencic on
+    /// 2005-01-27 -- cannot reproduce at the moment
+    void test_multiple_folders() {
+      bool showPrintout = false;
+      
+      int nFolders = 5;
+      vector<string> foldernames;
+      for ( int i = 0; i < nFolders; ++i ) {
+        stringstream s;
+        s << "/f_" << i;
+        foldernames.push_back( s.str() );
+      }
+      
+      long nObjs = 100;
+
+      for ( vector<string>::const_iterator fname = foldernames.begin();
+            fname != foldernames.end(); ++fname ) {
+        IFolderPtr folder = m_db->createFolder( *fname, payloadSpec );
+      }
+      
+      for ( vector<string>::const_iterator fname = foldernames.begin();
+            fname != foldernames.end(); ++fname ) {
+        IFolderPtr folder = m_db->getFolder( *fname );
+        folder->setupStorageBuffer();
+        for ( long i = 0; i < nObjs; ++i ) {
+          folder->storeObject( i, ValidityKeyMax, dummyPayload( i ), 0 );
+        }
+        folder->flushStorageBuffer();
+        
+        if ( showPrintout )
+          cout << "wrote " << nObjs
+            << " objects in folder '" << *fname << endl;
+      }
+      
+      for ( vector<string>::const_iterator fname = foldernames.begin();
+            fname != foldernames.end(); ++fname ) {
+        IFolderPtr folder = m_db->getFolder( *fname );
+        IObjectIteratorPtr objs 
+          = folder->browseObjects( ValidityKeyMin, ValidityKeyMax, 0, "" );
+
+        CPPUNIT_ASSERT_MESSAGE( "not empty", objs->size() > 0 );
+
+        long objIndex = 0;
+        //for ( IObjectIterator::const_iterator
+        //      i = objs->begin(); i != objs->end(); ++i ) {
+        //  const IObjectPtr& obj = *i;
+        while ( objs->goToNext() ) {
+          IObjectPtr obj( objs->currentRef().clone() );
+          
+          stringstream s;
+          s << "folder " << *fname << ": object " << objIndex << " ";
+          CPPUNIT_ASSERT_MESSAGE( ( s.str() + "payload" ).c_str(), 
+                                  dummyPayload( objIndex ) 
+                                  == obj->payload() );
+          
+          CPPUNIT_ASSERT_EQUAL_MESSAGE( ( s.str() + "since" ).c_str(), 
+                                        objIndex, (long)obj->since() );
+          
+          // last object's until extends to ValidityKeyMax
+          if ( objIndex < nObjs-1 ) {
+            CPPUNIT_ASSERT_EQUAL_MESSAGE( ( s.str() + "until" ).c_str(), 
+                                          objIndex+1, (long)obj->until() );
+          } else {
+            CPPUNIT_ASSERT_EQUAL_MESSAGE( ( s.str() + "until" ).c_str(), 
+                                          ValidityKeyMax, obj->until() );
+          }
+          
+          ++objIndex;
+        }
+        
+        if ( showPrintout )
+          cout << "checked " << objIndex
+            << " objects in folder " << *fname << endl;
+      }
+    }
+    
+    
+    /// Tests tagging and retagging when a tag exists in another folder
+    void test_tagExistsElsewhere() {
+      IFolderPtr folder1 = m_db->createFolder( "/myfolder1", 
+                                             payloadSpec,
+                                             "my description",
+                                             FolderVersioning::MULTI_VERSION );
+      IFolderPtr folder2 = m_db->createFolder( "/myfolder2", 
+                                             payloadSpec,
+                                             "my description",
+                                             FolderVersioning::MULTI_VERSION );
+
+      folder1->storeObject( 0, 10, dummyPayload( 0 ), 0 );
+      folder2->storeObject( 10, 20, dummyPayload( 1 ), 0 );
+      folder2->storeObject( 20, 30, dummyPayload( 2 ), 0 );
+
+      std::string tagA = "tagA";
+      std::string descA = "tagA description";
+      std::string tagB = "tagB";
+      std::string descB = "tagB description";
+
+      // TagA cannot be created in folder2 if it exists in folder1 already
+      folder1->tagCurrentHead( tagA, descA );
+      try {
+        folder2->tagCurrentHead( tagA, descA );
+        CPPUNIT_FAIL( "exception expected" );
+      }    
+      catch ( cool::TagExists& /*dummy*/) { 
+        try { 
+          folder2->deleteTag( tagA ); 
+          folder2->tagCurrentHead( tagA, descA );
+        }
+        catch ( cool::TagNotFound& /*e*/ ) {
+          //std::cout << "Caught as expected: " << e.what() << std::endl;
+        }
+        catch ( std::exception& e ) {
+          std::cout << "Exception caught: " << e.what() << std::endl;
+          throw;
+        }
+      }
+
+      // Create tagB in folder2: this has the same tagId=1 as tagA in folder1
+      // BUG in COOL_1_2_2: folder1->delete(tagA) also deletes tagB and fails
+      folder2->tagCurrentHead( tagB, descB );
+      try {
+        folder1->deleteTag( tagA );
+      }    
+      catch ( std::exception& e ) {
+        std::cout << "Exception caught: " << e.what() << std::endl;
+        throw;
+      }
+
+    }
+
+
+    /// Tests IDatabase::tagNameScope
+    void test_tagNameScope() {
+      std::string path1 = "/myfolder1";
+      std::string path2 = "/myfolder2";
+      IFolderPtr folder1 = m_db->createFolder( path1,
+                                             payloadSpec,
+                                             "folder description", 
+                                             FolderVersioning::MULTI_VERSION );
+      IFolderPtr folder2 = m_db->createFolder( path2,
+                                             payloadSpec,
+                                             "folder description",
+                                             FolderVersioning::MULTI_VERSION );
+
+      folder1->storeObject( 0, 10, dummyPayload( 0 ), 0 );
+      folder2->storeObject( 10, 20, dummyPayload( 1 ), 0 );
+      folder2->storeObject( 20, 30, dummyPayload( 2 ), 0 );
+
+      std::string tag1A = "tag1A";
+      std::string tag1B = "tag1B";
+      std::string tag1C = "tag1C";
+      std::string tag2A = "tag2A";
+      std::string tag2B = "tag2B";
+      std::string tag2C = "tag2C";
+
+      folder1->tagCurrentHead( tag1A, "tag description" );
+      folder1->tagCurrentHead( tag1B, "tag description" );
+      folder1->tagCurrentHead( tag1C, "tag description" );
+      folder2->tagCurrentHead( tag2A, "tag description" );
+      folder2->tagCurrentHead( tag2B, "tag description" );
+      folder2->tagCurrentHead( tag2C, "tag description" );
+
+      try {
+        CPPUNIT_ASSERT_EQUAL_MESSAGE
+          ( "tag1A scope", IHvsNode::LEAF_NODE, m_db->tagNameScope( tag1A ) );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE
+          ( "tag1B scope", IHvsNode::LEAF_NODE, m_db->tagNameScope( tag1B ) );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE
+          ( "tag1C scope", IHvsNode::LEAF_NODE, m_db->tagNameScope( tag1C ) );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE
+          ( "tag2A scope", IHvsNode::LEAF_NODE, m_db->tagNameScope( tag2A ) );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE
+          ( "tag2B scope", IHvsNode::LEAF_NODE, m_db->tagNameScope( tag2B ) );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE
+          ( "tag2C scope", IHvsNode::LEAF_NODE, m_db->tagNameScope( tag2C ) );
+        }
+      catch ( std::exception& e ) {
+          std::cout << "Exception caught: " << e.what() << std::endl;
+          throw;
+        }
+    }
+  
+
+    /// Tests IDatabase::taggedNodes
+    void test_taggedNodes() {
+      std::string path1 = "/myfolder1";
+      std::string path2 = "/myfolder2";
+      IFolderPtr folder1 = m_db->createFolder( path1,
+                                             payloadSpec,
+                                             "folder description", 
+                                             FolderVersioning::MULTI_VERSION );
+      IFolderPtr folder2 = m_db->createFolder( path2,
+                                             payloadSpec,
+                                             "folder description",
+                                             FolderVersioning::MULTI_VERSION );
+
+      folder1->storeObject( 0, 10, dummyPayload( 0 ), 0 );
+      folder2->storeObject( 10, 20, dummyPayload( 1 ), 0 );
+      folder2->storeObject( 20, 30, dummyPayload( 2 ), 0 );
+
+      std::string tag1A = "tag1A";
+      std::string tag1B = "tag1B";
+      std::string tag1C = "tag1C";
+      std::string tag2A = "tag2A";
+      std::string tag2B = "tag2B";
+      std::string tag2C = "tag2C";
+
+      folder1->tagCurrentHead( tag1A, "tag description" );
+      folder1->tagCurrentHead( tag1B, "tag description" );
+      folder1->tagCurrentHead( tag1C, "tag description" );
+      folder2->tagCurrentHead( tag2A, "tag description" );
+      folder2->tagCurrentHead( tag2B, "tag description" );
+      folder2->tagCurrentHead( tag2C, "tag description" );
+
+      try {
+        CPPUNIT_ASSERT_EQUAL_MESSAGE
+          ( "tag1A scope", path1, m_db->taggedNodes( tag1A )[0] );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE
+          ( "tag1B scope", path1, m_db->taggedNodes( tag1B )[0] );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE
+          ( "tag1C scope", path1, m_db->taggedNodes( tag1C )[0] );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE
+          ( "tag2A scope", path2, m_db->taggedNodes( tag2A )[0] );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE
+          ( "tag2B scope", path2, m_db->taggedNodes( tag2B )[0] );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE
+          ( "tag2C scope", path2, m_db->taggedNodes( tag2C )[0] );
+        }
+      catch ( std::exception& e ) {
+          std::cout << "Exception caught: " << e.what() << std::endl;
+          throw;
+        }
+    }
+  
+
+    /// Tests deleting a tag and retagging
+    void test_deleteTag_andRetag() {
+      try {
+        IFolderPtr folder = 
+          m_db->createFolder( "/myfolder", 
+                            payloadSpec,
+                            "my description",
+                            FolderVersioning::MULTI_VERSION );
+        
+        // First version of tagA
+        folder->storeObject( 0, 4, dummyPayload( 0 ), 0 );
+        folder->tagCurrentHead( "tagA", "an optional description" );
+        {
+          IObjectIteratorPtr objs1a = folder->browseObjects
+            ( ValidityKeyMin, ValidityKeyMax, (ChannelId)0, "tagA" );      
+          CPPUNIT_ASSERT_EQUAL_MESSAGE
+            ( "tagA1 object count", 1u, (unsigned int)objs1a->size() );
+          IObjectPtr obj1a = getNext(objs1a);
+          CPPUNIT_ASSERT_MESSAGE( "tagA1 obj 1 payload", 
+                                  dummyPayload( 0 ) == obj1a->payload() );
+          CPPUNIT_ASSERT_EQUAL_MESSAGE( "tagA1 obj 1 since",
+                                        (ValidityKey)0, obj1a->since() );
+          CPPUNIT_ASSERT_EQUAL_MESSAGE( "tagA1 obj 1 until",
+                                        (ValidityKey)4, obj1a->until() );
+        }
+        
+        // Retagging as tagA will fail now
+        try {
+          folder->tagCurrentHead( "tagA", "an optional description" );
+          CPPUNIT_FAIL( "retag as tagA succeeeds even with no deleteTag" );
+        } catch ( TagExists& /* dummy */ ) {
+        }      
+        
+        // Second version of tagA
+        folder->storeObject( 2, 6, dummyPayload( 1 ), 0 );
+        folder->deleteTag( "tagA" );
+        CPPUNIT_ASSERT_MESSAGE( "tagA deleted", ! m_db->existsTag( "tagA" ) );
+        folder->tagCurrentHead( "tagA", "an optional description" );
+        {
+          IObjectIteratorPtr objs2a = folder->browseObjects
+            ( ValidityKeyMin, ValidityKeyMax, (ChannelId)0, "tagA" );      
+          CPPUNIT_ASSERT_EQUAL_MESSAGE
+            ( "tagA2 object count", 2u, (unsigned int)objs2a->size() );
+          IObjectPtr obj2a = getNext(objs2a);
+          CPPUNIT_ASSERT_MESSAGE( "tagA2 obj 1 payload", 
+                                  dummyPayload( 0 ) == obj2a->payload() );
+          CPPUNIT_ASSERT_EQUAL_MESSAGE( "tagA2 obj 1 since",
+                                        (ValidityKey)0, obj2a->since() );
+          CPPUNIT_ASSERT_EQUAL_MESSAGE( "tagA2 obj 1 until",
+                                      (ValidityKey)2, obj2a->until() );
+          obj2a = getNext(objs2a);
+          CPPUNIT_ASSERT_MESSAGE( "tagA2 obj 2 payload", 
+                                  dummyPayload( 1 ) == obj2a->payload() );
+          CPPUNIT_ASSERT_EQUAL_MESSAGE( "tagA2 obj 2 since",
+                                        (ValidityKey)2, obj2a->since() );
+          CPPUNIT_ASSERT_EQUAL_MESSAGE( "tagA2 obj 2 until",
+                                        (ValidityKey)6, obj2a->until() );
+        }
+      } catch ( std::exception& e ) {
+        std::cout << "Exception caught: " << e.what() << std::endl;
+        throw;     
+      }
+    }
+
+    
+    /// Tests that attempting to delete the reserved HEAD tag throws
+    /// an exception.
+    void test_deleteTag_HEAD() {
+      IFolderPtr folder = m_db->createFolder( "/myfolder", 
+                                            payloadSpec,
+                                            "my description",
+                                            FolderVersioning::MULTI_VERSION );
+
+      folder->storeObject( 0, 4, dummyPayload( 0 ), 0 );
+      folder->tagCurrentHead( "tagA", "an optional description" );
+      CPPUNIT_ASSERT_THROW( folder->deleteTag( "HEAD" ),
+                            ReservedHeadTag );
+    }
+  
+
+    /// Tests MV tagging and retrieving
+    void test_MV_tag_and_retrieve() {
+      try {        
+        IFolderPtr folder = 
+          m_db->createFolder( "/myfolder", 
+                            payloadSpec,
+                            "my description",
+                            FolderVersioning::MULTI_VERSION );
+        folder->setupStorageBuffer();
+        folder->storeObject( 0, 4, dummyPayload( 0 ), 0 );
+        folder->storeObject( 2, 6, dummyPayload( 1 ), 0 );
+        folder->flushStorageBuffer();
+        
+        folder->tagCurrentHead( "tagA", "an optional description" );
+        Time asOfDate = folder->findObject( 0, 0 )->insertionTime();
+        
+        // MySQL now() has 1 second granularity: sleep at least 1 second
+        sleep(1);
+        
+        folder->setupStorageBuffer();
+        folder->storeObject( 3, 7, dummyPayload( 2 ), 0 );
+        folder->storeObject( 5, 9, dummyPayload( 3 ), 0 );
+        folder->flushStorageBuffer();
+        
+        folder->tagCurrentHead( "tagB" );
+        folder->tagHeadAsOfDate( asOfDate, "tagC" ); // == tagA
+
+        // fetch tagA
+        //std::cout << "Fetch tagA" << std::endl;
+        {          
+          IObjectIteratorPtr objs = 
+            folder->browseObjects
+            ( ValidityKeyMin, ValidityKeyMax, (ChannelId)0, "tagA" );
+        
+          CPPUNIT_ASSERT_EQUAL_MESSAGE( "tagA object count", 2u, 
+                                        (unsigned int)objs->size() );
+          
+          IObjectPtr obj = getNext(objs);
+          CPPUNIT_ASSERT_MESSAGE( "tagA obj 1 payload", 
+                                  dummyPayload( 0 ) == obj->payload() );
+          CPPUNIT_ASSERT_EQUAL_MESSAGE( "tagA obj 1 since",
+                                        (ValidityKey)0, obj->since() );
+          CPPUNIT_ASSERT_EQUAL_MESSAGE( "tagA obj 1 until",
+                                        (ValidityKey)2, obj->until() );
+          
+          obj = getNext(objs);
+          CPPUNIT_ASSERT_MESSAGE( "tagA obj 2 payload", 
+                                  dummyPayload( 1 ) == obj->payload() );
+          CPPUNIT_ASSERT_EQUAL_MESSAGE( "tagA obj 2 since",
+                                        (ValidityKey)2, obj->since() );
+          CPPUNIT_ASSERT_EQUAL_MESSAGE( "tagA obj 2 until",
+                                        (ValidityKey)6, obj->until() );
+        }
+        
+        // fetch tagB
+        //std::cout << "Fetch tagB" << std::endl;
+        {
+          IObjectIteratorPtr objs = 
+            folder->browseObjects
+            ( ValidityKeyMin, ValidityKeyMax, (ChannelId)0, "tagB" );
+        
+          CPPUNIT_ASSERT_EQUAL_MESSAGE( "tagB object count", 4u, 
+                                        (unsigned int)objs->size() );
+          
+          IObjectPtr obj = getNext(objs);
+          CPPUNIT_ASSERT_MESSAGE( "tagB obj 1 payload", 
+                                  dummyPayload( 0 ) == obj->payload() );
+          CPPUNIT_ASSERT_EQUAL_MESSAGE( "tagB obj 1 since",
+                                        (ValidityKey)0, obj->since() );
+          CPPUNIT_ASSERT_EQUAL_MESSAGE( "tagB obj 1 until",
+                                        (ValidityKey)2, obj->until() );
+          
+          obj = getNext(objs);
+          CPPUNIT_ASSERT_MESSAGE( "tagB obj 2 payload", 
+                                  dummyPayload( 1 ) == obj->payload() );
+          CPPUNIT_ASSERT_EQUAL_MESSAGE( "tagB obj 2 since",
+                                        (ValidityKey)2, obj->since() );
+          CPPUNIT_ASSERT_EQUAL_MESSAGE( "tagB obj 2 until",
+                                        (ValidityKey)3, obj->until() );
+          
+          obj = getNext(objs);
+          CPPUNIT_ASSERT_MESSAGE( "tagB obj 3 payload", 
+                                  dummyPayload( 2 ) == obj->payload() );
+          CPPUNIT_ASSERT_EQUAL_MESSAGE( "tagB obj 3 since",
+                                        (ValidityKey)3, obj->since() );
+          CPPUNIT_ASSERT_EQUAL_MESSAGE( "tagB obj 3 until",
+                                        (ValidityKey)5, obj->until() );
+          
+          obj = getNext(objs);
+          CPPUNIT_ASSERT_MESSAGE( "tagB obj 4 payload", 
+                                  dummyPayload( 3 ) == obj->payload() );
+          CPPUNIT_ASSERT_EQUAL_MESSAGE( "tagB obj 4 since",
+                                        (ValidityKey)5, obj->since() );
+          CPPUNIT_ASSERT_EQUAL_MESSAGE( "tagB obj 4 until",
+                                        (ValidityKey)9, obj->until() );      
+        }
+        
+        // fetch head
+        //std::cout << "Fetch HEAD" << std::endl;
+        {          
+          IObjectIteratorPtr objs = 
+            folder->browseObjects
+            ( ValidityKeyMin, ValidityKeyMax, (ChannelId)0 );
+          
+          CPPUNIT_ASSERT_EQUAL_MESSAGE( "HEAD object count", 4u, 
+                                        (unsigned int)objs->size() );
+          
+          IObjectPtr obj = getNext(objs);
+          CPPUNIT_ASSERT_MESSAGE( "HEAD obj 1 payload", 
+                                  dummyPayload( 0 ) == obj->payload() );
+          CPPUNIT_ASSERT_EQUAL_MESSAGE( "HEAD obj 1 since",
+                                        (ValidityKey)0, obj->since() );
+          CPPUNIT_ASSERT_EQUAL_MESSAGE( "HEAD obj 1 until",
+                                        (ValidityKey)2, obj->until() );
+          
+          obj = getNext(objs);
+          CPPUNIT_ASSERT_MESSAGE( "HEAD obj 2 payload", 
+                                  dummyPayload( 1 ) == obj->payload() );
+          CPPUNIT_ASSERT_EQUAL_MESSAGE( "HEAD obj 2 since",
+                                        (ValidityKey)2, obj->since() );
+          CPPUNIT_ASSERT_EQUAL_MESSAGE( "HEAD obj 2 until",
+                                        (ValidityKey)3, obj->until() );
+          
+          obj = getNext(objs);
+          CPPUNIT_ASSERT_MESSAGE( "HEAD obj 3 payload", 
+                                  dummyPayload( 2 ) == obj->payload() );
+          CPPUNIT_ASSERT_EQUAL_MESSAGE( "HEAD obj 3 since",
+                                        (ValidityKey)3, obj->since() );
+          CPPUNIT_ASSERT_EQUAL_MESSAGE( "HEAD obj 3 until",
+                                        (ValidityKey)5, obj->until() );
+          
+          obj = getNext(objs);
+          CPPUNIT_ASSERT_MESSAGE( "HEAD obj 4 payload", 
+                                  dummyPayload( 3 ) == obj->payload() );
+          CPPUNIT_ASSERT_EQUAL_MESSAGE( "HEAD obj 4 since",
+                                        (ValidityKey)5, obj->since() );
+          CPPUNIT_ASSERT_EQUAL_MESSAGE( "HEAD obj 4 until",
+                                        (ValidityKey)9, obj->until() );      
+        }
+        
+        // fetch tagC
+        //std::cout << "Fetch tagC" << std::endl;
+        {
+          IObjectIteratorPtr objs = 
+            folder->browseObjects
+            ( ValidityKeyMin, ValidityKeyMax, (ChannelId)0, "tagC" );
+        
+          CPPUNIT_ASSERT_EQUAL_MESSAGE( "tagC object count", 2u, 
+                                        (unsigned int)objs->size() );
+          
+          IObjectPtr obj = getNext(objs);
+          CPPUNIT_ASSERT_MESSAGE( "tagC obj 1 payload", 
+                                  dummyPayload( 0 ) == obj->payload() );
+          CPPUNIT_ASSERT_EQUAL_MESSAGE( "tagC obj 1 since",
+                                        (ValidityKey)0, obj->since() );
+          CPPUNIT_ASSERT_EQUAL_MESSAGE( "tagC obj 1 until",
+                                        (ValidityKey)2, obj->until() );
+          
+          obj = getNext(objs);
+          CPPUNIT_ASSERT_MESSAGE( "tagC obj 2 payload", 
+                                  dummyPayload( 1 ) == obj->payload() );
+          CPPUNIT_ASSERT_EQUAL_MESSAGE( "tagC obj 2 since",
+                                        (ValidityKey)2, obj->since() );
+          CPPUNIT_ASSERT_EQUAL_MESSAGE( "tagC obj 2 until",
+                                        (ValidityKey)6, obj->until() );
+        }
+      } catch ( std::exception& e ) {
+        std::cout << "Exception caught: " << e.what() << std::endl;
+        throw;     
+      }
+    }
+    
+    /// Tests bulk storeObject of MV objects
+    void test_storeObject_bulk_MV() {
+      IFolderPtr folder = m_db->createFolder( "/myfolder", 
+                                            payloadSpec,
+                                            "my description",
+                                            FolderVersioning::MULTI_VERSION );
+      
+      folder->setupStorageBuffer();
+      unsigned int nObjs = 10;
+      for ( unsigned int i = 0; i < nObjs; ++i ) {
+        folder->storeObject( i, ValidityKeyMax, dummyPayload( i ), 0 );
+      }
+      
+      // cppunit 1.8.0 does not have CPPUNIT_ASSERT_EXCEPTION
+      bool objectNotFound = false;
+      try {
+        folder->findObject( 0, 0 );
+      } catch( ObjectNotFound& /* dummy */ ) {
+        objectNotFound = true;
+      }
+      CPPUNIT_ASSERT_MESSAGE( "no objects", objectNotFound );
+      
+      folder->flushStorageBuffer();
+      
+      IObjectIteratorPtr objs = folder->browseObjects( ValidityKeyMin,
+                                                       ValidityKeyMax, 0 );
+      
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "size", 
+                                    10u, (unsigned int)objs->size() );
+      
+      for ( unsigned int i = 0; i < objs->size(); ++i ) {
+        IObjectPtr obj = getNext(objs);
+        stringstream s;
+        s << "object " << i << " ";
+        CPPUNIT_ASSERT_MESSAGE( ( s.str() + "payload" ).c_str(), 
+                                dummyPayload( i ) == obj->payload() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( ( s.str() + "since" ).c_str(), 
+                                      (ValidityKey)i, obj->since() );
+        // last object's until extends to ValidityKeyMax
+        if ( i < nObjs-1 ) {
+          CPPUNIT_ASSERT_EQUAL_MESSAGE( ( s.str() + "until" ).c_str(), 
+                                        (ValidityKey)i+1, obj->until() );
+        } else {
+          CPPUNIT_ASSERT_EQUAL_MESSAGE( ( s.str() + "until" ).c_str(), 
+                                        ValidityKeyMax, obj->until() );
+        }
+      }
+    }
+  
+    
+    
+    
+    /// Tests tag name case sensitivity
+    void test_tagName_case_sensitivity() {
+      try {        
+        IFolderPtr folder = 
+        m_db->createFolder( "/myfolder", 
+                            payloadSpec,
+                            "my description",
+                            FolderVersioning::MULTI_VERSION );
+        folder->storeObject( 0, 4, dummyPayload( 0 ), 0 );
+        
+        folder->tagCurrentHead( "tagA" );
+
+        folder->storeObject( 0, 4, dummyPayload( 1 ), 0 );
+
+        folder->tagCurrentHead( "taga" );
+
+        // fetch tagA
+        {          
+          IObjectIteratorPtr objs = 
+          folder->browseObjects
+          ( ValidityKeyMin, ValidityKeyMax, (ChannelId)0, "tagA" );
+          
+          CPPUNIT_ASSERT_EQUAL_MESSAGE( "tagA object count", 1u, 
+                                        (unsigned int)objs->size() );
+          
+          IObjectPtr obj = getNext(objs);
+          CPPUNIT_ASSERT_MESSAGE( "tagA obj payload", 
+                                  dummyPayload( 0 ) == obj->payload() );
+          CPPUNIT_ASSERT_EQUAL_MESSAGE( "tagA obj since",
+                                        (ValidityKey)0, obj->since() );
+          CPPUNIT_ASSERT_EQUAL_MESSAGE( "tagA obj until",
+                                        (ValidityKey)4, obj->until() );
+        }
+        
+        // fetch taga
+        {          
+          IObjectIteratorPtr objs = 
+          folder->browseObjects
+          ( ValidityKeyMin, ValidityKeyMax, (ChannelId)0, "taga" );
+          
+          CPPUNIT_ASSERT_EQUAL_MESSAGE( "taga object count", 1u, 
+                                        (unsigned int)objs->size() );
+          
+          IObjectPtr obj = getNext(objs);
+          CPPUNIT_ASSERT_MESSAGE( "taga obj payload", 
+                                  dummyPayload( 1 ) == obj->payload() );
+          CPPUNIT_ASSERT_EQUAL_MESSAGE( "taga obj since",
+                                        (ValidityKey)0, obj->since() );
+          CPPUNIT_ASSERT_EQUAL_MESSAGE( "taga obj until",
+                                        (ValidityKey)4, obj->until() );
+        }
+        
+      } catch ( std::exception& e ) {
+        std::cout << "Exception caught: " << e.what() << std::endl;
+        throw;     
+      }
+      
+    }
+      
+    
+    /// Tests bulk storeObject of 70k objects: this used to cause ORA-24381
+    /// before a workaround was added in RelationalFolder::flushStorageBuffer
+    /// (this is now fixed in CORAL for bulk inserts, but we keep our hack
+    /// in COOL because of better performance with 10k bulks in MySQL).
+    void test_storeObject_bulk_70k() {
+      IFolderPtr folder = m_db->createFolder( "/myfolder", payloadSpec );
+      
+      folder->setupStorageBuffer();
+      long nObjs = 70*1000;
+      for ( long i = 0; i < nObjs; ++i ) {
+        folder->storeObject( i, ValidityKeyMax, dummyPayload( i ), 0 );
+      }
+            
+      folder->flushStorageBuffer();
+      
+      IObjectPtr obj;
+      for ( long i = 0; i < nObjs; i += 1000 ) {
+        obj = folder->findObject( i, 0 );
+        stringstream s;
+        s << "object " << i << " ";
+        CPPUNIT_ASSERT_MESSAGE( ( s.str() + "payload" ).c_str(), 
+                                dummyPayload( i ) == obj->payload() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( ( s.str() + "since" ).c_str(), 
+                                      i, (long)obj->since() );
+        // last object's until extends to ValidityKeyMax
+        if ( i < nObjs-1 ) {
+          CPPUNIT_ASSERT_EQUAL_MESSAGE( ( s.str() + "until" ).c_str(), 
+                                        i+1, (long)obj->until() );
+        } else {
+          CPPUNIT_ASSERT_EQUAL_MESSAGE( ( s.str() + "until" ).c_str(), 
+                                        LONG_MAX, (long)obj->until() );
+        }
+      }
+    }
+
+
+    /// More recently the problem above reappeared for bulk updates: see bug
+    /// #17755, due to CORAL bug #17757, which is now also fixed (only bulk
+    /// inserts had been fixed, not bulk updates). In this case we do not
+    /// have an internal COOL hack, we rely on CORAL: we test this here too.
+    /// Keep the above test stand-alone because SV is much faster!
+    /// The tagBulk70k test is disabled because it is very slow
+    /// (roughly twice as slow as the storeObject_bulk_70k after fixing bug #17903)
+    /// and it tests CORAL code already covered by storeObject_bulk_70k.
+    void test_tagObject_bulk_70k() 
+    {
+      IFolderPtr folder = m_db->createFolder
+        ( "/myfolder", payloadSpec, "", FolderVersioning::MULTI_VERSION);
+      
+      folder->setupStorageBuffer();
+      long nObjs = 70*1000;
+      for ( long i = 0; i < nObjs; ++i ) {
+        folder->storeObject( i, i+1, dummyPayload( i ), 0 );
+      }
+            
+      folder->flushStorageBuffer();
+
+      folder->tagCurrentHead( "MYTAG" );
+      
+      IObjectPtr obj;
+      for ( long i = 0; i < nObjs; i += 1000 ) {
+        obj = folder->findObject( i, 0, "MYTAG" );
+        stringstream s;
+        s << "object " << i << " ";
+        CPPUNIT_ASSERT_MESSAGE( ( s.str() + "payload" ).c_str(), 
+                                dummyPayload( i ) == obj->payload() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( ( s.str() + "since" ).c_str(), 
+                                      i, (long)obj->since() );
+        // last object's until extends to ValidityKeyMax
+        if ( i < nObjs-1 ) {
+          CPPUNIT_ASSERT_EQUAL_MESSAGE( ( s.str() + "until" ).c_str(), 
+                                        i+1, (long)obj->until() );
+        } else {
+          CPPUNIT_ASSERT_EQUAL_MESSAGE( ( s.str() + "until" ).c_str(), 
+                                        LONG_MAX, (long)obj->until() );
+        }
+      }
+    }
+    
+    
+    /// Tests bulk storeObject of SV objects with a reused AttributeList
+    /// This test ensures that the payload data is copied, not referenced
+    /// inside the storage buffer.
+    void test_storeObject_bulk_SV_listReused() {
+      IFolderPtr folder = m_db->createFolder( "/myfolder", payloadSpec );
+      
+      Record payload = dummyPayload( 0 );
+      
+      folder->setupStorageBuffer();
+      unsigned int nObjs = 100;
+      for ( unsigned int i = 0; i < nObjs; ++i ) {
+        payload["I"].setValue<int>( (int)i );
+        folder->storeObject( i, ValidityKeyMax, payload, 0 );
+      }
+      
+      // cppunit 1.8.0 does not have CPPUNIT_ASSERT_EXCEPTION
+      bool objectNotFound = false;
+      try {
+        folder->findObject( 0, 0 );
+      } catch( ObjectNotFound& /* dummy */ ) {
+        objectNotFound = true;
+      }
+      CPPUNIT_ASSERT_MESSAGE( "no objects", objectNotFound );
+      
+      folder->flushStorageBuffer();
+      
+      IObjectIteratorPtr objs = folder->browseObjects( ValidityKeyMin,
+                                                       ValidityKeyMax, 0 );
+      
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "size", 
+                                    100u, (unsigned int)objs->size() );
+
+      for ( unsigned int i = 0; i < objs->size(); ++i ) {
+        IObjectPtr obj = getNext(objs);
+        stringstream s;
+        s << "object " << i << " ";
+        CPPUNIT_ASSERT_MESSAGE( ( s.str() + "payload I" ).c_str(), 
+                                (int)i == obj->payload()["I"].data<int>() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( ( s.str() + "since" ).c_str(), 
+                                      (ValidityKey)i, obj->since() );
+        // last object's until extends to ValidityKeyMax
+        if ( i < nObjs-1 ) {
+          CPPUNIT_ASSERT_EQUAL_MESSAGE( ( s.str() + "until" ).c_str(), 
+                                        (ValidityKey)i+1, obj->until() );
+        } else {
+          CPPUNIT_ASSERT_EQUAL_MESSAGE( ( s.str() + "until" ).c_str(), 
+                                        ValidityKeyMax, obj->until() );
+        }
+      }
+      
+    }
+    
+    
+    /// Tests bulk storeObject of SV objects
+    void test_storeObject_bulk_SV() {
+      try {
+      IFolderPtr folder = m_db->createFolder( "/myfolder", payloadSpec );
+      
+      folder->setupStorageBuffer();
+      unsigned int nObjs = 100;
+      for ( unsigned int i = 0; i < nObjs; ++i ) {
+        folder->storeObject( i, ValidityKeyMax, dummyPayload( i ), 0 );
+      }
+      
+      // cppunit 1.8.0 does not have CPPUNIT_ASSERT_EXCEPTION
+      bool objectNotFound = false;
+      try {
+        folder->findObject( 0, 0 );
+      } catch( ObjectNotFound& /* dummy */ ) {
+        objectNotFound = true;
+      }
+      CPPUNIT_ASSERT_MESSAGE( "no objects", objectNotFound );
+      
+      folder->flushStorageBuffer();
+      
+      IObjectIteratorPtr objs = folder->browseObjects( ValidityKeyMin,
+                                                       ValidityKeyMax, 0 );
+
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "size", 
+                                    100u, (unsigned int)objs->size() );
+
+      for ( unsigned int i = 0; i < objs->size(); ++i ) {
+        IObjectPtr obj = getNext(objs);
+        stringstream s;
+        s << "object " << i << " ";
+        CPPUNIT_ASSERT_MESSAGE( ( s.str() + "payload" ).c_str(), 
+                                dummyPayload( i ) == obj->payload() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( ( s.str() + "since" ).c_str(), 
+                                      (ValidityKey)i, obj->since() );
+        // last object's until extends to ValidityKeyMax
+        if ( i < nObjs-1 ) {
+          CPPUNIT_ASSERT_EQUAL_MESSAGE( ( s.str() + "until" ).c_str(), 
+                                        (ValidityKey)i+1, obj->until() );
+        } else {
+          CPPUNIT_ASSERT_EQUAL_MESSAGE( ( s.str() + "until" ).c_str(), 
+                                        ValidityKeyMax, obj->until() );
+        }
+      }
+      } catch ( std::exception& e ) {
+        cout << e.what() << endl;
+        throw;
+      }
+    }
+    
+    
+    /// Tests bulk operation 'flushStorageBuffer'
+    void test_flushStorageBuffer() {
+      IFolderPtr folder = m_db->createFolder( "/myfolder", payloadSpec );
+      
+      folder->setupStorageBuffer();
+      folder->storeObject( 0, ValidityKeyMax, dummyPayload( 0 ), 0 );
+      folder->storeObject( 1, ValidityKeyMax, dummyPayload( 1 ), 0 );
+      
+      // cppunit 1.8.0 does not have CPPUNIT_ASSERT_EXCEPTION
+      bool objectNotFound = false;
+      try {
+        folder->findObject( 1, 0 );
+      } catch( ObjectNotFound& /* dummy */ ) {
+        objectNotFound = true;
+      }
+      CPPUNIT_ASSERT_MESSAGE( "no objects", objectNotFound );
+      
+      try {
+        folder->flushStorageBuffer();
+      } catch ( RelationalException& e ) {
+        cout << e.what() << endl;
+        throw;
+      }
+      
+      IObjectPtr obj0 = folder->findObject( 0, 0 );
+      CPPUNIT_ASSERT_MESSAGE( "object 1 found", obj0.get() != 0 );
+      IObjectPtr obj1 = folder->findObject( 1, 0 );
+      CPPUNIT_ASSERT_MESSAGE( "object 1 found", obj1.get() != 0 );
+    }
+    
+    
+		/// Tests reading back of a folder from a db handle that went out of scope
+		void test_access_outofscope_db() {
+      IFolderPtr folder;
+      
+      {
+        CoralApplication app;
+        IDatabaseSvc& dbSvc = app.databaseService();
+        IDatabasePtr db1 = dbSvc.openDatabase( m_connectionString, false );
+        folder = db1->createFolder( "/myfolder", payloadSpec );
+        // db1 isgoing of of scope here but folder keeps 
+        // its own handle to the db
+      }
+      
+      folder->storeObject( 0, 2, dummyPayload( 1 ), 0 );
+    }
+		
+    
+		/// Tests reading back of an Object from a deleted MV folder
+    void test_findObject_after_dropNode_MV() {
+      IFolderPtr folder = m_db->createFolder( "/myfolder", 
+                                            payloadSpec, 
+                                            "my description",
+                                            FolderVersioning::MULTI_VERSION);
+      folder->storeObject( 0, 2, dummyPayload( 1 ), 0 );
+      m_db->dropNode( "/myfolder" );
+      CPPUNIT_ASSERT_THROW( folder->findObject( 1, 0 ),
+                            RelationalException );
+    }
+    
+    
+    /// Tests reading back of an Object from a deleted SV folder
+    void test_findObject_after_dropNode_SV() {
+      IFolderPtr folder = m_db->createFolder( "/myfolder", payloadSpec );
+      folder->storeObject( 0, 2, dummyPayload( 1 ), 0 );
+      m_db->dropNode( "/myfolder" );
+      // This is expected to throw a cool::TableNotFound exception
+      CPPUNIT_ASSERT_THROW( folder->findObject( 1, 0 ),
+                            RelationalException );
+    }
+    
+
+    /// Tests reading back of an Object from a channel that does not exist
+    void test_findObject_wrongChannel() {
+      IFolderPtr folder = m_db->createFolder( "/myfolder", payloadSpec );
+      ChannelId channel1 = 1;
+      ChannelId channel2 = 2;
+      folder->storeObject( 0, 2, dummyPayload( 1 ), channel1 );
+      folder->storeObject( 2, 4, dummyPayload( 2 ), channel1 ); 
+      CPPUNIT_ASSERT_THROW( IObjectPtr obj1 = folder->findObject( 1, channel2 ),
+                            ObjectNotFound );
+    }
+		
+    
+		/// Tests storing and reading back of an Object in a MultiVersion folder
+    /// This test is implemented in more detail with respect to the object
+    /// attributes in test_RalDatabase
+		void test_findObject_MV() {
+      IFolderPtr folder = m_db->createFolder( "/myfolder", 
+                                            payloadSpec,
+                                            "my description",
+                                            FolderVersioning::MULTI_VERSION );
+      
+      folder->storeObject( 0, 2, dummyPayload( 1 ), 0 );
+      folder->storeObject( 2, 4, dummyPayload( 2 ), 0 );
+      
+      IObjectPtr obj1 = folder->findObject( 1, 0 );
+      CPPUNIT_ASSERT_MESSAGE( "first object",
+                              dummyPayload( 1 ) == obj1->payload() );
+      
+      IObjectPtr obj2 = folder->findObject( 3, 0 );
+      CPPUNIT_ASSERT_MESSAGE( "second object",
+                              dummyPayload( 2 ) == obj2->payload() );
+		}
+		
+    
+		/// Tests storing and reading back of an Object
+    /// This test is implemented in more detail with respect to the object
+    /// attributes in test_RalDatabase
+		void test_findObject() {
+      IFolderPtr folder = m_db->createFolder( "/myfolder", payloadSpec );
+      
+      folder->storeObject( 0, 2, dummyPayload( 1 ), 0 );
+      folder->storeObject( 2, 4, dummyPayload( 2 ), 0 );
+      
+      IObjectPtr obj1 = folder->findObject( 1, 0 );
+      CPPUNIT_ASSERT_MESSAGE( "first object",
+                              dummyPayload( 1 ) == obj1->payload() );
+      
+      IObjectPtr obj2 = folder->findObject( 3, 0 );
+      CPPUNIT_ASSERT_MESSAGE( "second object",
+                              dummyPayload( 2 ) == obj2->payload() );
+		}
+		
+    
+    /// Tests creating and retrieving a folder.
+    /// This test is implemented in more detail with respect to the folder
+    /// attributes in test_RalDatabase
+    void test_getFolder() {
+      try {
+        string folderName( "/myfolder" );
+        m_db->createFolder( folderName, payloadSpec, "a description" );
+        
+        IFolderPtr folder = m_db->getFolder( folderName );
+        CPPUNIT_ASSERT( folder.get() != 0 );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE
+          ( "name", folderName, folder->fullPath() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE
+          ( "description", string( "a description" ), folder->description() );
+        CPPUNIT_ASSERT_MESSAGE
+          ( "isLeaf", folder->isLeaf() );
+        CPPUNIT_ASSERT_MESSAGE
+          ( "isStored", folder->isStored() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE
+          ( "insertionTime", string("yyyy-mm-dd_hh:mm:ss.nnnnnnnnn GMT").size(), 
+            timeToString(folder->insertionTime()).size() );    
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "id", 1u, folder->id() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "parentId", 0u, folder->parentId() );
+        
+      } catch ( Exception& e ) {
+        cout << e.what() << endl;
+        throw;
+      }
+    }
+
+    void test_renamePayload()
+    {
+      string folderName( "/myfolder" );
+      IFolderPtr folder = 
+        m_db->createFolder( folderName, payloadSpec, "a description" );
+      
+      folder->storeObject( 0, 2, dummyPayload( 1 ), 0 );
+      
+      folder->renamePayload("I","NewColumn");
+      folder.reset();
+      
+      // Avoid ORA-01466: table definition has changed
+      sleep(1);
+      
+      folder = m_db->getFolder( folderName );
+      IObjectPtr obj = folder->findObject( 1, 0 );
+      
+      CPPUNIT_ASSERT_THROW( obj->payload()["I"] , 
+                            cool::RecordSpecificationUnknownField );
+      
+      CPPUNIT_ASSERT( obj->payload()["NewColumn"].data<Int32>() == 1 );
+      
+      CPPUNIT_ASSERT_THROW( folder->renamePayload("S","X"),
+                            cool::RelationalException );
+      
+      CPPUNIT_ASSERT_THROW( folder->renamePayload("Z","DoesNotExists"),
+                            cool::RelationalException );
+      
+      CPPUNIT_ASSERT_THROW( folder->renamePayload("X","not-allowed name"),
+                            cool::RelationalException );
+      
+    }
+  
+  
+    void test_extendPayloadSpecificationExceptions()
+    {
+      string folderName( "/myfolder" );
+      IFolderPtr folder = 
+        m_db->createFolder( folderName, payloadSpec, "a description" );
+      
+      {
+        RecordSpecification spec;
+        spec.extend("I",StorageType::Int32); // already exists
+        Record rec( spec );
+        CPPUNIT_ASSERT_THROW
+          ( folder->extendPayloadSpecification( rec ),
+            cool::RelationalException );
+      }
+
+      {
+        RecordSpecification spec;
+        CPPUNIT_ASSERT_THROW
+          ( spec.extend("",StorageType::Int32),
+            cool::FieldSpecificationInvalidName );
+        //spec.extend("",StorageType::Int32);
+        //Record rec( spec );
+        //CPPUNIT_ASSERT_THROW
+        //  ( folder->extendPayloadSpecification( rec ),
+        //    cool::RelationalException );
+      }
+      
+      {
+        RecordSpecification spec;
+        spec.extend("not-allowed name",StorageType::Int32);
+        Record rec( spec );
+        CPPUNIT_ASSERT_THROW
+          ( folder->extendPayloadSpecification( rec ),
+            cool::RelationalException );
+      }
+
+    }
+  
+  
+    void test_extendPayloadSpecification()
+    {
+      string folderName( "/myfolder" );
+      IFolderPtr folder = 
+        m_db->createFolder( folderName, payloadSpec, "a description" );
+      
+      folder->storeObject( 0, 2, dummyPayload( 1 ), 0 );
+
+      RecordSpecification spec;
+      spec.extend( "J1", StorageType::Int32 );
+      spec.extend( "J2", StorageType::Int32 );
+      spec.extend( "J3", StorageType::Int32 );
+      Record rec( spec );
+      rec["J1"].setValue<Int32>( 1 );
+      rec["J2"].setNull();
+      rec["J3"].setValue<Int32>( 3 );
+
+      folder->extendPayloadSpecification(rec);
+      folder.reset();
+      
+      // Avoid ORA-01466: table definition has changed
+      sleep(1);
+      
+      folder = m_db->getFolder( folderName );
+      IObjectPtr obj = folder->findObject( 1, 0 );
+      
+      CPPUNIT_ASSERT( !obj->payload()["J1"].isNull() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "J1", 1, obj->payload()["J1"].data<Int32>() );
+      CPPUNIT_ASSERT( obj->payload()["J2"].isNull() );
+      CPPUNIT_ASSERT( !obj->payload()["J3"].isNull() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "J3", 3, obj->payload()["J3"].data<Int32>() );
+    }
+    
+  //+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+  IObjectVectorPtr RecordSelect( const IRecordSelection& sel,
+                                 IObjectIteratorPtr iter) 
+  { 
+    IObjectVectorPtr objects( new IObjectVector() );
+    while( iter->goToNext() ) 
+    {
+      IObjectPtr obj( iter->currentRef().clone() );
+      if (sel.select(obj->payload()))
+        objects->push_back( obj );
+    }
+    return objects;
+  }
+  
+  void test_RecordSelectionBrowseObjects() 
+  {
+    try
+    {        
+      RecordSpecification spec;
+      spec.extend ("I", StorageType::Int32);
+      spec.extend ("S", StorageType::String4k);
+      spec.extend ("X", StorageType::Float);
+      IFolderPtr folder = m_db->createFolder
+        ( "/a", spec, "desc", FolderVersioning::MULTI_VERSION);
+      
+      // fill with some test data
+      for ( int i=0; i<10; i++ )
+      {
+        Record rec( spec );
+        rec["I"].setValue<Int32>( i );
+        rec["X"].setValue<Float>( 1 - ((float)i)/10 );
+        std::stringstream str_value;
+        str_value << "Payload #" << i;
+        rec["S"].setValue<String4k>( str_value.str() );
+        folder->storeObject( i, i+2, rec, 0 );
+      }
+      
+      // store a null record
+      Record null_rec(spec);
+      null_rec["I"].setNull();
+      null_rec["X"].setNull();
+      null_rec["S"].setNull();
+      folder->storeObject(10,12,null_rec,0);
+      
+      // invalid selection (I is not a Float in this folder)
+      FieldSelection invalid_sel
+        ( "I", StorageType::Float, FieldSelection::EQ, (Float)6.0 );        
+      CPPUNIT_ASSERT_THROW
+        ( folder->countObjects( 0, 300, 0, "", &invalid_sel ), 
+          RelationalException );
+      
+      // invalid selection (DUMMY does not exist in this folder)
+      FieldSelection invalid_sel2
+        ( "DUMMY", StorageType::Float, FieldSelection::EQ, (Float)6.0 );  
+      CPPUNIT_ASSERT_THROW
+        ( folder->countObjects( 0, 300, 0, "", &invalid_sel2 ),
+          RelationalException );
+      
+      
+      // To test untrusted user selections, we wrap a class
+      // around FieldSelection
+      class SelectionWrapper : public IRecordSelection 
+      {
+      public:
+        IRecordSelection *sel;
+
+        SelectionWrapper( const IRecordSelection * sel) {
+            this->sel=sel->clone();
+        };
+
+        virtual ~SelectionWrapper() {
+          delete sel;
+        };
+        
+        bool canSelect( const IRecordSpecification& spec ) const
+        {
+          return sel->canSelect( spec );
+        };
+        
+        bool select( const IRecord& record ) const 
+        {
+          return sel->select( record ); 
+        };
+        
+        IRecordSelection* clone( ) const 
+        {
+          return new SelectionWrapper( sel );
+        };
+
+      };
+      
+      // switch on prefetching of rows to allow browseObject()->size()
+      // (otherwise this will throw on untrusted selections)
+      folder->setPrefetchAll(true);
+
+      
+      // selections on int (all 6 relations)
+      IObjectIteratorPtr objects;
+      {
+        FieldSelection sel
+          ( "I", StorageType::Int32, FieldSelection::EQ, (Int32)5 ); 
+        SelectionWrapper u_sel(&sel);      
+        CPPUNIT_ASSERT_EQUAL_MESSAGE
+          ( "1-I-EQ count objects", 
+            1u, folder->countObjects( 0, 300, 0, "", &sel) );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE
+          ( "untrusted 1-I-EQ count objects", 
+            1u, folder->browseObjects( 0, 300, 0, "", &u_sel)->size() );
+        objects = folder->browseObjects( 0, 300, 0 );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE
+          ( "1-I-EQ browse Objects size",
+            (size_t)1, RecordSelect(sel, objects )->size() );
+      }
+      {
+        FieldSelection sel
+          ( "I", StorageType::Int32, FieldSelection::NE, (Int32)5 );
+        SelectionWrapper u_sel(&sel);
+        CPPUNIT_ASSERT_EQUAL_MESSAGE
+          ( "2-I-NE count objects", 
+            9u, folder->countObjects( 0, 300, 0, "", &sel) );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE
+          ( "untrusted 2-I-NE count objects", 
+            9u, folder->browseObjects( 0, 300, 0, "", &u_sel)->size() );
+        objects = folder->browseObjects( 0, 300, 0 );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE
+          ( "2-I-NE browse Objects size",
+            (size_t)9, RecordSelect(sel, objects )->size() );
+      }
+      {
+        FieldSelection sel
+            ( "I", StorageType::Int32, FieldSelection::GT, (Int32)5 );
+        SelectionWrapper u_sel(&sel);
+        CPPUNIT_ASSERT_EQUAL_MESSAGE
+          ( "3-I-GT count objects", 
+            4u, folder->countObjects( 0, 300, 0, "", &sel) );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE
+          ( "untrusted 3-I-GT count objects", 
+            4u, folder->browseObjects( 0, 300, 0, "", &u_sel)->size() );
+        objects = folder->browseObjects( 0, 300, 0 );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE
+          ( "3-I-GT browse Objects size",
+            (size_t)4, RecordSelect(sel, objects )->size() );
+      }
+      {
+        FieldSelection sel
+          ( "I", StorageType::Int32, FieldSelection::GE, (Int32)5 );
+        SelectionWrapper u_sel(&sel);
+        CPPUNIT_ASSERT_EQUAL_MESSAGE
+          ( "4-I-GE count objects", 
+            5u, folder->countObjects( 0, 300, 0, "", &sel) );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE
+          ( "untrusted 4-I-GE count objects", 
+            5u, folder->browseObjects( 0, 300, 0, "", &u_sel)->size() );
+        objects = folder->browseObjects( 0, 300, 0 );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE
+          ( "4-I-GE browse Objects size",
+            (size_t)5, RecordSelect(sel, objects )->size() );
+      }
+      {
+        FieldSelection sel
+          ( "I", StorageType::Int32, FieldSelection::LT, (Int32)5 );
+        SelectionWrapper u_sel(&sel);
+        CPPUNIT_ASSERT_EQUAL_MESSAGE
+          ( "5-I-LT count objects", 
+            5u, folder->countObjects( 0, 300, 0, "", &sel) );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE
+          ( "untrusted 5-I-LT count objects", 
+            5u, folder->browseObjects( 0, 300, 0, "", &u_sel)->size() );
+        objects = folder->browseObjects( 0, 300, 0 );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE
+          ( "5-I-LT browse Objects size",
+            (size_t)5, RecordSelect(sel, objects )->size() );
+      }
+      {
+        FieldSelection sel
+          ( "I", StorageType::Int32, FieldSelection::LE, (Int32)5 );
+        SelectionWrapper u_sel(&sel);
+        CPPUNIT_ASSERT_EQUAL_MESSAGE
+          ( "6-I-LE count objects", 
+            6u, folder->countObjects( 0, 300, 0, "", &sel) );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE
+          ( "untrusted 6-I-LE count objects", 
+            6u, folder->browseObjects( 0, 300, 0, "", &u_sel)->size() );
+        objects = folder->browseObjects( 0, 300, 0 );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE
+          ( "6-I-LE browse Objects size",
+            (size_t)6, RecordSelect(sel, objects )->size() );
+      }
+      
+      // selections on int (nullness checks)
+      {
+        FieldSelection sel
+          ( "I", StorageType::Int32, FieldSelection::IS_NULL );
+        SelectionWrapper u_sel(&sel);
+        CPPUNIT_ASSERT_EQUAL_MESSAGE
+          ( "7-I-NULL count objects", 
+            1u, folder->countObjects( 0, 300, 0, "", &sel) );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE
+          ( "untrusted 7-I-NULL count objects", 
+            1u, folder->browseObjects( 0, 300, 0, "", &u_sel)->size() );
+        objects = folder->browseObjects( 0, 300, 0 );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE
+          ( "7-I-NULL browse Objects size",
+            (size_t)1, RecordSelect(sel, objects )->size() );
+      }
+      {
+        FieldSelection sel
+          ( "I", StorageType::Int32, FieldSelection::IS_NOT_NULL );
+        SelectionWrapper u_sel(&sel);
+        CPPUNIT_ASSERT_EQUAL_MESSAGE
+          ( "8-I-NOTNULL count objects", 
+            10u, folder->countObjects( 0, 300, 0, "", &sel) );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE
+          ( "untrusted 8-I-NOTNULL count objects", 
+            10u, folder->browseObjects( 0, 300, 0, "", &u_sel)->size() );
+        objects = folder->browseObjects( 0, 300, 0 );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE
+          ( "8-I-NOTNULL browse Objects size",
+            (size_t)10, RecordSelect(sel, objects )->size() );
+      }
+      
+      // selections on float (all 6 relations)
+      {
+        FieldSelection sel
+          ( "X", StorageType::Float, FieldSelection::EQ, (Float)0.5 );
+        SelectionWrapper u_sel(&sel);
+        CPPUNIT_ASSERT_EQUAL_MESSAGE
+          ( "1-X-EQ count objects",
+            1u, folder->countObjects( 0, 300, 0, "", &sel) );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE
+          ( "1-X-EQ count objects",
+            1u, folder->browseObjects( 0, 300, 0, "", &u_sel)->size() );
+        objects = folder->browseObjects( 0, 300, 0 );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE
+          ( "1-X-EQ browse Objects size",
+            (size_t)1, RecordSelect(sel, objects )->size() );
+      }
+      {
+        FieldSelection sel
+          ( "X", StorageType::Float, FieldSelection::NE, (Float)0.5 );
+        SelectionWrapper u_sel(&sel);
+        CPPUNIT_ASSERT_EQUAL_MESSAGE
+          ( "2-X-NE count objects", 
+            9u, folder->countObjects( 0, 300, 0, "", &sel) );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE
+          ( "unstrusted 2-X-NE count objects", 
+            9u, folder->browseObjects( 0, 300, 0, "", &sel)->size() );
+        objects = folder->browseObjects( 0, 300, 0 );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE
+          ( "2-X-NE browse Objects size",
+            (size_t)9, RecordSelect(sel, objects )->size() );
+      }
+      {
+        FieldSelection sel
+          ( "X", StorageType::Float, FieldSelection::GT, (Float)0.5 );
+        SelectionWrapper u_sel(&sel);
+        CPPUNIT_ASSERT_EQUAL_MESSAGE
+          ( "3-X-GT count objects", 
+            5u, folder->countObjects( 0, 300, 0, "", &sel) );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE
+          ( "untrusted 3-X-GT count objects", 
+            5u, folder->browseObjects( 0, 300, 0, "", &u_sel)->size() );
+        objects = folder->browseObjects( 0, 300, 0 );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE
+          ( "3-X-GT browse Objects size",
+            (size_t)5, RecordSelect(sel, objects )->size() );
+      }
+      {
+        FieldSelection sel
+          ( "X", StorageType::Float, FieldSelection::GE, (Float)0.5 );
+        SelectionWrapper u_sel(&sel);
+        CPPUNIT_ASSERT_EQUAL_MESSAGE
+          ( "4-X-GE count objects",
+            6u, folder->countObjects( 0, 300, 0, "", &sel) );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE
+          ( "untrusted 4-X-GE count objects",
+            6u, folder->browseObjects( 0, 300, 0, "", &u_sel)->size() );
+        objects = folder->browseObjects( 0, 300, 0 );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE
+          ( "4-X-GE browse Objects size",
+            (size_t)6, RecordSelect(sel, objects )->size() );
+      }
+      {
+        FieldSelection sel
+          ( "X", StorageType::Float, FieldSelection::LT, (Float)0.5 );      
+        SelectionWrapper u_sel(&sel);
+        CPPUNIT_ASSERT_EQUAL_MESSAGE
+          ( "5-X-LT count objects", 
+            4u, folder->countObjects( 0, 300, 0, "", &sel) );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE
+          ( "untrusted 5-X-LT count objects", 
+            4u, folder->browseObjects( 0, 300, 0, "", &u_sel)->size() );
+        objects = folder->browseObjects( 0, 300, 0 );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE
+          ( "5-X-LT browse Objects size",
+            (size_t)4, RecordSelect(sel, objects )->size() );
+      }
+      {
+        FieldSelection sel
+          ( "X", StorageType::Float, FieldSelection::LE, (Float)0.5 );
+        SelectionWrapper u_sel(&sel);
+        CPPUNIT_ASSERT_EQUAL_MESSAGE
+          ( "6-X-LE count objects", 
+            5u, folder->countObjects( 0, 300, 0, "", &sel) );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE
+          ( "untrusted 6-X-LE count objects", 
+            5u, folder->browseObjects( 0, 300, 0, "", &u_sel)->size() );
+        objects = folder->browseObjects( 0, 300, 0 );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE
+          ( "6-X-LE browse Objects size",
+            (size_t)5, RecordSelect(sel, objects )->size() );
+      }
+      
+      // selections on float (nullness checks)
+      {
+        FieldSelection sel
+          ( "X", StorageType::Float, FieldSelection::IS_NULL );
+        SelectionWrapper u_sel(&sel);
+        CPPUNIT_ASSERT_EQUAL_MESSAGE
+          ( "7-X-NULL count objects", 
+            1u, folder->countObjects( 0, 300, 0, "", &sel) );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE
+          ( "untrusted 7-X-NULL count objects", 
+            1u, folder->browseObjects( 0, 300, 0, "", &u_sel)->size() );
+        objects = folder->browseObjects( 0, 300, 0 );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE
+          ( "7-X-NULL browse Objects size",
+            (size_t)1, RecordSelect(sel, objects )->size() );
+      }
+      {
+        FieldSelection sel
+          ( "X", StorageType::Float, FieldSelection::IS_NOT_NULL );
+        SelectionWrapper u_sel(&sel);
+        CPPUNIT_ASSERT_EQUAL_MESSAGE
+          ( "8-X-NOTNULL count objects", 
+            10u, folder->countObjects( 0, 300, 0, "", &sel) );
+         CPPUNIT_ASSERT_EQUAL_MESSAGE
+          ( "untrusted 8-X-NOTNULL count objects", 
+            10u, folder->browseObjects( 0, 300, 0, "", &u_sel)->size() );
+         objects = folder->browseObjects( 0, 300, 0 );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE
+          ( "8-X-NOTNULL browse Objects size",
+            (size_t)10, RecordSelect(sel, objects )->size() );
+      }
+      
+      // composite selections        
+      {
+        FieldSelection sel1
+          ( "X", StorageType::Float, FieldSelection::IS_NULL );
+        FieldSelection sel2
+          ( "X", StorageType::Float, FieldSelection::LT, (Float)0.5 );
+        CompositeSelection comp( &sel1, CompositeSelection::OR, &sel2 );
+        SelectionWrapper u_sel(&comp);
+        CPPUNIT_ASSERT_EQUAL_MESSAGE
+          ( "X-OR count objects", 
+            5u, folder->countObjects( 0, 300, 0, "", &comp) );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE
+          ( "untrusted X-OR count objects", 
+            5u, folder->browseObjects( 0, 300, 0, "", &u_sel)->size() );
+        objects = folder->browseObjects( 0, 300, 0 );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE
+          ( "X-OR browse Objects size",
+            (size_t)5, RecordSelect(comp, objects )->size() );
+      }
+      {
+        FieldSelection sel1
+          ( "X", StorageType::Float, FieldSelection::GT, (Float)0.21 );
+        FieldSelection sel2
+          ( "X", StorageType::Float, FieldSelection::LT, (Float)0.49 );
+        CompositeSelection comp( &sel1, CompositeSelection::AND, &sel2 );
+        SelectionWrapper u_sel(&comp);
+        CPPUNIT_ASSERT_EQUAL_MESSAGE
+          ( "X-AND count objects", 
+            2u, folder->countObjects( 0, 300, 0, "", &comp) );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE
+          ( "untrusted X-AND count objects", 
+            2u, folder->browseObjects( 0, 300, 0, "", &u_sel)->size() );
+        objects = folder->browseObjects( 0, 300, 0 );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE
+          ( "X-AND browse Objects size",
+            (size_t)2, RecordSelect(comp, objects )->size() );
+      }
+      {
+        FieldSelection sel1
+          ( "X", StorageType::Float, FieldSelection::GT, (Float)0.21 );
+        FieldSelection sel2
+          ( "X", StorageType::Float, FieldSelection::LT, (Float)0.49 );
+        FieldSelection sel3
+          ( "I", StorageType::Int32, FieldSelection::EQ, (Int32)0 );
+        CompositeSelection comp12( &sel1, CompositeSelection::AND, &sel2 );
+        CompositeSelection comp( &comp12, CompositeSelection::OR, &sel3 );
+        SelectionWrapper u_sel(&comp);
+        CPPUNIT_ASSERT_EQUAL_MESSAGE
+          ( "AND-OR count objects", 
+            3u, folder->countObjects( 0, 300, 0, "", &comp) );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE
+          ( "AND-OR count objects", 
+            3u, folder->browseObjects( 0, 300, 0, "", &u_sel)->size() );
+        objects = folder->browseObjects( 0, 300, 0 );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE
+          ( "AND-OR browse Objects size",
+            (size_t)3, RecordSelect(comp, objects )->size() );
+      }        
+      {
+        std::vector<const IRecordSelection *> sel_vec(5);
+        for ( int i=0; i<5; i++ ) 
+        {
+          FieldSelection sel
+            ( "I", StorageType::Int32, FieldSelection::EQ, (Int32)i );
+          sel_vec[i] = sel.clone();
+        }
+        CompositeSelection comp( CompositeSelection::OR, sel_vec );
+        SelectionWrapper u_sel(&comp);
+        //objects = folder->browseObjects( 0, 300, 0  );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE
+          ( "OR-vec count objects", 
+            5u, folder->countObjects( 0, 300, 0, "", &comp) );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE
+          ( "OR-vec count objects", 
+            5u, folder->browseObjects( 0, 300, 0, "", &u_sel)->size() );
+        objects = folder->browseObjects( 0, 300, 0 );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE
+          ( "OR-vec browse Objects size",
+            (size_t)5, RecordSelect(comp, objects )->size() );
+        for ( int i=0; i<5; i++ ) 
+        {
+          delete sel_vec[i];
+        }        
+      }
+      
+      // selections on string (only 2 of 6 relations allowed)
+      {
+        FieldSelection sel
+          ( "S", StorageType::String4k, FieldSelection::EQ, 
+            (String4k)"Payload #1" );
+        SelectionWrapper u_sel(&sel);
+        CPPUNIT_ASSERT_EQUAL_MESSAGE
+          ( "1-S-EQ count objects", 
+            1u, folder->countObjects( 0, 300, 0, "", &sel) );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE
+          ( "untrusted 1-S-EQ count objects", 
+            1u, folder->browseObjects( 0, 300, 0, "", &u_sel)->size() );
+        objects = folder->browseObjects( 0, 300, 0 );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE
+          ( "1-S-EQ browse Objects size",
+            (size_t)1, RecordSelect(sel, objects )->size() );
+      }
+      {
+        FieldSelection sel
+          ( "S", StorageType::String4k, FieldSelection::NE,
+            (String4k)"Payload #1" );
+         SelectionWrapper u_sel(&sel);
+       // NB: the NULL value (stored as "") is counted ("" != "Payload #1")
+        CPPUNIT_ASSERT_EQUAL_MESSAGE
+          ( "2-S-NE count objects", 
+            10u, folder->countObjects( 0, 300, 0, "", &sel) );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE
+          ( "untrusted 2-S-NE count objects", 
+            10u, folder->browseObjects( 0, 300, 0, "", &u_sel)->size() );
+        objects = folder->browseObjects( 0, 300, 0 );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE
+          ( "2-S-NE browse Objects size",
+            (size_t)10, RecordSelect(sel, objects )->size() );
+      }
+      {
+        CPPUNIT_ASSERT_THROW
+          ( FieldSelection( "S", StorageType::String4k, FieldSelection::GT,
+                            (String4k)"Payload #1" ),
+            RecordSelectionException );
+      }
+      {
+        CPPUNIT_ASSERT_THROW
+          ( FieldSelection( "S", StorageType::String4k, FieldSelection::GE,
+                            (String4k)"Payload #1" ),
+            RecordSelectionException );
+      }
+      {
+        CPPUNIT_ASSERT_THROW
+          ( FieldSelection( "S", StorageType::String4k, FieldSelection::LT,
+                            (String4k)"Payload #1" ),
+            RecordSelectionException );
+      }
+      {
+        CPPUNIT_ASSERT_THROW
+          ( FieldSelection( "S", StorageType::String4k, FieldSelection::LE,
+                            (String4k)"Payload #1" ),
+            RecordSelectionException );
+      }
+          
+      // selections on string (nullness checks)
+      {
+        CPPUNIT_ASSERT_THROW
+          ( FieldSelection sel
+            ( "S", StorageType::String4k, FieldSelection::IS_NULL ),
+            RecordSelectionException );
+      }
+      {
+        CPPUNIT_ASSERT_THROW
+          ( FieldSelection sel
+            ( "S", StorageType::String4k, FieldSelection::IS_NOT_NULL ),
+            RecordSelectionException );
+      }
+      {
+        FieldSelection sel
+          ( "S", StorageType::String4k, FieldSelection::EQ, (String4k)"" );
+         SelectionWrapper u_sel(&sel);
+        CPPUNIT_ASSERT_EQUAL_MESSAGE
+          ( "7-S-EQ-EMPTYSTRING count objects", 
+            1u, folder->countObjects( 0, 300, 0, "", &sel) );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE
+          ( "untrusted 7-S-EQ-EMPTYSTRING count objects", 
+            1u, folder->browseObjects( 0, 300, 0, "", &u_sel)->size() );
+        objects = folder->browseObjects( 0, 300, 0 );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE
+          ( "7-S-EQ-EMPTYSTRING browse Objects size",
+            (size_t)1, RecordSelect(sel, objects )->size() );
+      }
+      {
+        FieldSelection sel
+          ( "S", StorageType::String4k, FieldSelection::NE, (String4k)"" );
+        SelectionWrapper u_sel(&sel);
+        CPPUNIT_ASSERT_EQUAL_MESSAGE
+          ( "8-S-NE-EMPTYSTRING count objects", 
+            10u, folder->countObjects( 0, 300, 0, "", &sel) );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE
+          ( "untrusted 8-S-NE-EMPTYSTRING count objects", 
+            10u, folder->browseObjects( 0, 300, 0, "", &u_sel)->size() );
+        objects = folder->browseObjects( 0, 300, 0 );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE
+          ( "8-S-NE-EMPTYSTRING browse Objects size",
+            (size_t)10, RecordSelect(sel, objects )->size() );
+      }
+      
+      class UserPayloadSelection : public IRecordSelection 
+      {
+      public:
+
+        UserPayloadSelection() {};
+
+        virtual ~UserPayloadSelection() {};
+        
+        /// Can the selection be applied to a record with the given spec?
+        bool canSelect( const IRecordSpecification& spec ) const
+        {
+          return spec.exists("I") && 
+            spec["I"].storageType()==StorageType::Int32;
+        };
+        
+        /// Apply the selection to the given record.
+        bool select( const IRecord& record ) const 
+        {
+          return !record["I"].isNull() && record["I"].data<Int32>()%2 ==0; 
+        };
+        
+        /// Clone the record selection (and any objects referenced therein).
+        IRecordSelection* clone( ) const 
+        {
+          return new UserPayloadSelection();
+        };
+
+      };
+      
+      {
+        UserPayloadSelection untrusted_sel;
+        
+        // countObject throws on untrusted selections
+        CPPUNIT_ASSERT_THROW
+          ( folder->countObjects( 0, 300, 0, "",&untrusted_sel),
+            RelationalException);
+        objects = folder->browseObjects( 0, 300, 0 );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE
+          ( "UserSel browse Objects size",
+            (size_t)5, RecordSelect(untrusted_sel, objects )->size() );
+        folder->setPrefetchAll(true);
+        objects = folder->browseObjects( 0, 300, 0, "", &untrusted_sel );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE
+          ( "UserSel Objects size", 5u, objects->size() );
+        folder->setPrefetchAll(false);
+        objects = folder->browseObjects( 0, 300, 0 ,"",&untrusted_sel);
+        
+        // can't query the size of the iterator for untrusted selections
+        // if prefetching is disabled
+        CPPUNIT_ASSERT_THROW( objects->size(), RelationalException );
+        
+      }
+    }    
+    catch ( std::exception& e ) 
+    {
+      std::cout << "Exception caught: " << e.what() << std::endl;
+      throw;
+    } 
+  }  
+ 
+  void test_truncateIOV() 
+    {
+      try 
+      {
+        IFolderPtr folder = m_db->createFolder( "/a", 
+                                              payloadSpec,
+                                              "desc", 
+                                              FolderVersioning::SINGLE_VERSION);
+
+        folder->storeObject(  0,             10, dummyPayload( 0010 ), 0);
+        folder->storeObject( 10, ValidityKeyMax, dummyPayload( 0520 ), 0);
+        folder->storeObject(  3,             30, dummyPayload( 0330 ), 1);
+        folder->storeObject( 30,          40000, dummyPayload( 2040 ), 1);
+        folder->storeObject(  3,             30, dummyPayload( 0330 ), 2);
+        folder->storeObject( 30,             40, dummyPayload( 2040 ), 2);
+        folder->storeObject( 40, ValidityKeyMax, dummyPayload( 2040 ), 2);
+
+
+        folder->storeObject(  0,          50000, dummyPayload( 2040 ), 3);
+        folder->storeObject(  0, ValidityKeyMax, dummyPayload( 2040 ), 4);
+        folder->storeObject(  0,             10, dummyPayload( 2040 ), 5);
+        folder->storeObject(  0, ValidityKeyMax, dummyPayload( 2040 ), 6);
+        folder->storeObject(  0,          80000, dummyPayload( 2040 ), 7);
+
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 Count ", 
+                                      2u, folder->countObjects(0,100,0));
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 Count ", 
+                                      2u, folder->countObjects(0,100,1));
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 Count ", 
+                                      3u, folder->countObjects(0,100,2));
+
+        // test truncating of a single channel
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "4 Count ",
+                                     1u, folder->countObjects(40,100,0));
+
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 IOV until ",
+                                ValidityKeyMax, 
+                                folder->findObject(10,0)->until());
+ 
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 truncate ",
+                                1,folder->truncateObjectValidity( 35, 0));
+        
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "5 Count ",
+                                     0u, folder->countObjects(40,100,0));
+
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 IOV until ",
+                                (ValidityKey)35, 
+                                folder->findObject(10,0)->until());
+
+        // can't truncate this IOV again
+        CPPUNIT_ASSERT_THROW( folder->truncateObjectValidity( 34, 0 ),
+                              RelationalException );
+
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 truncate ",
+                              0,
+                              folder->truncateObjectValidity( 45, 0 ) );
+ 
+        // truncating of an IOV with until < ValidityKeyMax doesn't work
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "6 Count ",
+                                     1u, folder->countObjects(40,100,1));
+
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 IOV until ",
+                            (ValidityKey)40000, 
+                            folder->findObject(30,1)->until());
+
+        CPPUNIT_ASSERT_THROW( folder->truncateObjectValidity( 35, 1),
+                             RelationalException );
+        
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "7 Count ",
+                                     1u, folder->countObjects(40,100,1));
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 IOV until ",
+                            (ValidityKey)40000, 
+                            folder->findObject(30,1)->until());
+
+
+        // truncating of an IOV with until < ValidityKeyMax doesn't work
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "4 IOV until ",
+                            (ValidityKey)40, 
+                            folder->findObject(30,2)->until());
+
+        CPPUNIT_ASSERT_THROW( folder->truncateObjectValidity( 35, 1),
+                              RelationalException );
+        
+        // check that nothing has changed
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "5 IOV until ",
+                            (ValidityKey)40, 
+                            folder->findObject(30,2)->until() );
+
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "6 IOV until ",
+                            ValidityKeyMax, 
+                            folder->findObject(40,2)->until() );
+
+        // but truncating [40, ValidityKeyMax[ works
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 truncate",
+                            1,
+                            folder->truncateObjectValidity( 45, 2) );
+
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "7 IOV until ",
+                            (ValidityKey)45, 
+                            folder->findObject(40,2)->until() );
+
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "8 IOV until ",
+                            (ValidityKey)40, 
+                            folder->findObject(30,2)->until() );
+
+        // truncate more channels at once
+
+        CPPUNIT_ASSERT_EQUAL_MESSAGE("10 IOV until ",
+                            (ValidityKey) 50000, 
+                            folder->findObject( 80, 3)->until() );
+
+        CPPUNIT_ASSERT_EQUAL_MESSAGE("9 IOV until ",
+                          ValidityKeyMax, 
+                            folder->findObject( 80, 4)->until() );
+
+        CPPUNIT_ASSERT_EQUAL_MESSAGE("10 IOV until ",
+                            (ValidityKey) 10, 
+                            folder->findObject( 5, 5)->until() );
+
+        CPPUNIT_ASSERT_EQUAL_MESSAGE("11 IOV until ",
+                            ValidityKeyMax, 
+                            folder->findObject( 80, 6)->until() );
+
+        CPPUNIT_ASSERT_EQUAL_MESSAGE("12 IOV until ",
+                            (ValidityKey)80000, 
+                            folder->findObject( 80, 7)->until() );
+
+        CPPUNIT_ASSERT_THROW( folder->truncateObjectValidity( 70, 
+                                        ChannelSelection::all() ),
+                              RelationalException );
+
+        CPPUNIT_ASSERT_EQUAL_MESSAGE("10 IOV until ",
+                            (ValidityKey) 50000, 
+                            folder->findObject( 80, 3)->until() );
+
+        CPPUNIT_ASSERT_EQUAL_MESSAGE("9 IOV until ",
+                          ValidityKeyMax, 
+                            folder->findObject( 80, 4)->until() );
+
+        CPPUNIT_ASSERT_EQUAL_MESSAGE("10 IOV until ",
+                            (ValidityKey) 10, 
+                            folder->findObject( 5, 5)->until() );
+
+        CPPUNIT_ASSERT_EQUAL_MESSAGE("11 IOV until ",
+                            ValidityKeyMax, 
+                            folder->findObject( 80, 6)->until() );
+
+        CPPUNIT_ASSERT_EQUAL_MESSAGE("12 IOV until ",
+                            (ValidityKey)80000, 
+                            folder->findObject( 80, 7)->until() );
+
+        ChannelSelection csel(4,6);
+        CPPUNIT_ASSERT_EQUAL_MESSAGE("4 truncate",
+                            2,
+                            folder->truncateObjectValidity( 70, 
+                                        csel ) );
+
+        CPPUNIT_ASSERT_THROW( folder->findObject( 80, 4), ObjectNotFound );
+
+        CPPUNIT_ASSERT_EQUAL_MESSAGE("13 IOV until ",
+                            (ValidityKey)70, 
+                            folder->findObject( 50, 4)->until() );
+
+        CPPUNIT_ASSERT_EQUAL_MESSAGE("14 IOV until ",
+                            (ValidityKey) 50000, 
+                            folder->findObject( 50, 3)->until() );
+
+        CPPUNIT_ASSERT_THROW( folder->findObject( 80, 4), ObjectNotFound );
+
+        CPPUNIT_ASSERT_EQUAL_MESSAGE("15 IOV until ",
+                            (ValidityKey)70, 
+                            folder->findObject( 50, 4)->until() );
+
+        CPPUNIT_ASSERT_EQUAL_MESSAGE("16 IOV until ",
+                            (ValidityKey)80000, 
+                            folder->findObject( 50, 7)->until() );
+     
+        // multi version folders are not allowed
+        IFolderPtr folderM = m_db->createFolder( "/a1", 
+                                              payloadSpec,
+                                              "desc", 
+                                              FolderVersioning::MULTI_VERSION);
+
+        folderM->storeObject(  0,             10, dummyPayload( 0010 ), 0);
+        folderM->storeObject( 10, ValidityKeyMax, dummyPayload( 0520 ), 0);
+        CPPUNIT_ASSERT_THROW( folderM->truncateObjectValidity(30,0),
+                              RelationalException );
+
+      } 
+      catch ( std::exception& e ) 
+      {
+        std::cout << "Exception caught: '" << e.what() << "'" << std::endl;
+        throw;
+      } 
+    }
+ 
+  /// Creates a dummy payload AttributeList for a given index
+  Record dummyPayload( int index ) 
+  {
+    Record payload( payloadSpec );
+    payload["I"].setValue<Int32>( index );
+    std::stringstream s;
+    s << "Object " << index;
+    payload["S"].setValue<String255>( s.str() );
+    payload["X"].setValue<Float>( (float)(index/1000.) );
+    return payload;
+  }
+  
+  RelationalFolderTest() 
+    : CoolDBUnitTest(), payloadSpec() 
+  {    
+    payloadSpec.extend( "I", StorageType::Int32 );
+    payloadSpec.extend( "S", StorageType::String255 );
+    payloadSpec.extend( "X", StorageType::Float );
+  }  
+  
+  void setUp() {
+    dropDB();
+    createDB();
+    openDB();
+  }
+  
+  void tearDown() {
+    closeDB(); // Fix for bug #27650 on OSX
+  }
+  
+};
+
+CPPUNIT_TEST_SUITE_REGISTRATION( RelationalFolderTest );
+
+} // namespace
+
+COOLTEST_MAIN(RelationalFolderTest)
diff --git a/RelationalCool/tests/RelationalFolder/test_RelationalFolder.cpp.gmtime b/RelationalCool/tests/RelationalFolder/test_RelationalFolder.cpp.gmtime
new file mode 100755
index 000000000..e7f622eda
--- /dev/null
+++ b/RelationalCool/tests/RelationalFolder/test_RelationalFolder.cpp.gmtime
@@ -0,0 +1,1738 @@
+/**
+ 
+ @file test_RelationalFolder.cpp
+ 
+ @author Sven A. Schmidt
+ 
+ @date 2004-11-05
+ 
+ */
+
+
+#include<cppunit/extensions/HelperMacros.h>
+
+#include "SealServices/Application.h"
+#include "SealKernel/ComponentLoader.h"
+#include "RelationalAccess/IRelationalService.h"
+
+#include "CoolApplication/DatabaseSvcFactory.h"
+#include "CoolKernel/IFolder.h"
+#include "CoolKernel/IObject.h"
+#include "CoolKernel/IObjectIterator.h"
+#include "CoolKernel/IDatabaseSvc.h"
+
+#include "src/RelationalException.h"
+#include "src/RelationalFolder.h"
+#include "src/timeToString.h"
+
+using pool::AttributeList;
+using pool::AttributeListSpecification;
+
+// include for 'sleep' (ORA-01466 workaround)
+#include "SealBase/TimeInfo.h"
+
+#include <string>
+using std::cout;
+using std::endl;
+using std::string;
+using std::stringstream;
+
+#include <vector>
+using std::vector;
+
+// Needed for _tzset on Windows
+#ifdef WIN32
+#include <time.h>
+#endif
+
+// Needed for gmtime and timegm on Windows
+#ifdef WIN32
+#include <time.h>
+inline static time_t timegm (struct tm *t)
+{
+    // This code is copied as-is from SEAL Time.cpp
+    time_t t1 = mktime (t);
+    struct tm gmt = *gmtime (&t1);
+    time_t t2 = mktime (&gmt);
+    return t1 + (t1 - t2);
+}
+#endif
+
+namespace cool {
+
+const char* COOLTESTDB = "COOLTESTDB";
+
+//! \brief RelationalFolder test class.
+class RelationalFolderTest : public CppUnit::TestFixture {
+		
+  CPPUNIT_TEST_SUITE( RelationalFolderTest );
+  
+  // The second test in this pair is kept only for reference: I thought that
+  // (not) calling tzset/_tzset would influence the result, but it does not!
+  //CPPUNIT_TEST( test_sealTimeFromDate );
+  //CPPUNIT_TEST( test_sealTimeFromDate_tzset );
+
+  //CPPUNIT_TEST( test_timegm_gmtime );
+  CPPUNIT_TEST( test_gmtime_timegm );
+  /*
+  CPPUNIT_TEST( test_timeToString );
+
+  CPPUNIT_TEST( test_getFolder );
+  CPPUNIT_TEST( test_findObject );
+  CPPUNIT_TEST( test_findObject_MV );
+
+  CPPUNIT_TEST_EXCEPTION( test_findObject_wrongChannel, ObjectNotFound );
+
+  CPPUNIT_TEST_EXCEPTION( test_findObject_after_dropNode_SV, FolderNotFound );
+  CPPUNIT_TEST_EXCEPTION( test_findObject_after_dropNode_MV, FolderNotFound );
+
+  CPPUNIT_TEST( test_access_outofscope_db );
+  CPPUNIT_TEST( test_flushStorageBuffer );
+  CPPUNIT_TEST( test_storeObject_bulk_SV );
+  CPPUNIT_TEST( test_storeObject_bulk_SV_listReused );
+
+  CPPUNIT_TEST( test_storeObject_bulk_70k );
+
+  CPPUNIT_TEST( test_storeObject_bulk_MV );
+  CPPUNIT_TEST( test_MV_tag_and_retrieve );
+
+  CPPUNIT_TEST( test_multiple_folders );
+
+  CPPUNIT_TEST( test_validityKeyBoundaries );
+
+  CPPUNIT_TEST( test_validityKeyException );
+  CPPUNIT_TEST( test_exceptionInFlushStorageBuffer );
+
+  CPPUNIT_TEST( test_browseObjects_SV );
+  CPPUNIT_TEST( test_browseObjects_MV );
+  CPPUNIT_TEST( test_browseObjects_MV_tag );
+
+  CPPUNIT_TEST( test_listChannels );
+
+  CPPUNIT_TEST( test_listTags );
+  CPPUNIT_TEST( test_tagInsertionTime );
+  CPPUNIT_TEST( test_tagDescription );
+
+  CPPUNIT_TEST( test_storeObjects_bulk_multichannel );
+
+  CPPUNIT_TEST( test_setDescription );
+
+  CPPUNIT_TEST( test_storeObject_SV_overlap );
+  CPPUNIT_TEST( test_storeObject_SV_overlap_bulk );
+  CPPUNIT_TEST( test_storeObject_SV_unordered );
+  */
+  CPPUNIT_TEST_SUITE_END();
+		
+public:
+			
+    AttributeListSpecification payloadSpec1;
+    string connectString;
+    IDatabasePtr db;
+  
+
+    /// Tests that timegm( gmtime ( time_t ) ) = ( time_t )
+    /// NB: tm_years are #years after 1900
+    /// NB: time_t measures seconds after 1970-1-1
+    /// On Windows use private implementation of timegm (see SEAL Time.cpp)
+    void test_timegm_gmtime() {
+      time_t aTimet = (31+2)*86400+12*3600+62; // 2894462 (1970-2-3 12:01:02)
+      struct tm aTm = *gmtime( &aTimet );
+      time_t aTimetNew = timegm( &aTm );
+      bool verbose = false;
+      if ( verbose ) {
+        std::cout << "Test test_timegm_gmtime" << std::endl;
+        std::cout << "aTimet = " << aTimet << std::endl;
+        std::cout 
+          << "aTm = " 
+          << 1900+aTm.tm_year << "-" << aTm.tm_mon+1 << "-" << aTm.tm_mday 
+          << " " << aTm.tm_hour << ":" << aTm.tm_min << ":" << aTm.tm_sec
+          << " (DST=" << aTm.tm_isdst << ")" << std::endl;
+        std::cout << "aTimetNew = " << aTimetNew << std::endl;
+      }
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "timegm(gmtime(time_t))==time_t", aTimet, aTimetNew );
+    }
+  
+    /// Tests that gmtime( gmtime ( tm ) ) = ( tm )
+    /// On Windows use private implementation of timegm (see SEAL Time.cpp)
+    void test_gmtime_timegm() {
+      bool verbose = true;
+      struct tm aTm;
+      int month; // Months in [0-11]
+      for ( month = 0; month < 12; month++ ) {
+        int year = 70; // Years after 1900
+        int day = 03;
+        int hour = 12;
+        int minute = 01;
+        int second = 02;
+        // It seems that the +1 case should fail, but I fail with -1... why???!
+        memset (&aTm, sizeof(aTm), 0); // As in SEAL Time.cpp
+        aTm.tm_year = year;
+        aTm.tm_mon = month;
+        aTm.tm_mday = day;
+        aTm.tm_hour = hour;
+        aTm.tm_min = minute;
+        aTm.tm_sec = second;
+        if ( verbose ) {        
+          std::cout << "Test test_gmtime_timegm" << std::endl;
+          std::cout 
+            << "Before setting isdst:  aTm = " 
+            << 1900+aTm.tm_year << "-" << aTm.tm_mon+1 << "-" << aTm.tm_mday 
+            << " " << aTm.tm_hour << ":" << aTm.tm_min << ":" << aTm.tm_sec
+            << std::endl;
+        }      
+        // Test with tm_idst = -1
+        aTm.tm_isdst = -1;
+        if ( verbose ) std::cout 
+          << "Before calling timegm: aTm = " 
+          << 1900+aTm.tm_year << "-" << aTm.tm_mon+1 << "-" << aTm.tm_mday 
+          << " " << aTm.tm_hour << ":" << aTm.tm_min << ":" << aTm.tm_sec
+          << " (DST=" << aTm.tm_isdst << ")" << std::endl;
+        time_t aTimetM1 = timegm( &aTm );
+        if ( verbose ) std::cout 
+          << "After  calling timegm: aTm = " 
+          << 1900+aTm.tm_year << "-" << aTm.tm_mon+1 << "-" << aTm.tm_mday 
+          << " " << aTm.tm_hour << ":" << aTm.tm_min << ":" << aTm.tm_sec
+          << " (DST=" << aTm.tm_isdst << ")" << std::endl;
+        struct tm aTmM1;
+        aTmM1 = *gmtime( &aTimetM1 );
+        // Test with tm_idst = 0
+        aTm.tm_year = year;
+        aTm.tm_mon = month;
+        aTm.tm_mday = day;
+        aTm.tm_hour = hour;
+        aTm.tm_min = minute;
+        aTm.tm_sec = second;
+        aTm.tm_isdst = 0;
+        if ( verbose ) std::cout 
+          << "Before calling timegm: aTm = " 
+          << 1900+aTm.tm_year << "-" << aTm.tm_mon+1 << "-" << aTm.tm_mday 
+          << " " << aTm.tm_hour << ":" << aTm.tm_min << ":" << aTm.tm_sec
+          << " (DST=" << aTm.tm_isdst << ")" << std::endl;
+        time_t aTimet0 = timegm( &aTm );
+        if ( verbose ) std::cout 
+          << "After  calling timegm: aTm = " 
+          << 1900+aTm.tm_year << "-" << aTm.tm_mon+1 << "-" << aTm.tm_mday 
+          << " " << aTm.tm_hour << ":" << aTm.tm_min << ":" << aTm.tm_sec
+          << " (DST=" << aTm.tm_isdst << ")" << std::endl;
+        struct tm aTm0;
+        aTm0 = *gmtime( &aTimet0 );
+        // Test with tm_idst = +1
+        aTm.tm_year = year;
+        aTm.tm_mon = month;
+        aTm.tm_mday = day;
+        aTm.tm_hour = hour;
+        aTm.tm_min = minute;
+        aTm.tm_sec = second;
+        aTm.tm_isdst = +1;
+        if ( verbose ) std::cout 
+          << "Before calling timegm: aTm = " 
+          << 1900+aTm.tm_year << "-" << aTm.tm_mon+1 << "-" << aTm.tm_mday 
+          << " " << aTm.tm_hour << ":" << aTm.tm_min << ":" << aTm.tm_sec
+          << " (DST=" << aTm.tm_isdst << ")" << std::endl;
+        time_t aTimetP1 = timegm( &aTm );
+        if ( verbose ) std::cout 
+          << "After  calling timegm: aTm = " 
+          << 1900+aTm.tm_year << "-" << aTm.tm_mon+1 << "-" << aTm.tm_mday 
+          << " " << aTm.tm_hour << ":" << aTm.tm_min << ":" << aTm.tm_sec
+          << " (DST=" << aTm.tm_isdst << ")" << std::endl;
+        struct tm aTmP1;
+        aTmP1 = *gmtime( &aTimetP1 );
+        // Verbose printout
+        if ( verbose ) {        
+          std::cout 
+            << "aTm = " 
+            << 1900+year << "-" << month+1 << "-" << day 
+            << " " << hour << ":" << minute << ":" << second
+            << " (DST=-1,0,+1)" << std::endl;
+          std::cout << "aTimetM1 = " << aTimetM1 << std::endl;
+          std::cout 
+            << "aTmM1 = " 
+            << 1900+aTmM1.tm_year << "-" << aTmM1.tm_mon+1 
+            << "-" <<aTmM1.tm_mday
+            << " " << aTmM1.tm_hour << ":" << aTmM1.tm_min 
+            << ":" << aTmM1.tm_sec
+            << " (DST=" << aTmM1.tm_isdst << ")" << std::endl;
+          std::cout << "aTimet0 = " << aTimet0 << std::endl;
+          std::cout 
+            << "aTm0 = " 
+            << 1900+aTm0.tm_year << "-" << aTm0.tm_mon+1 
+            << "-" << aTm0.tm_mday 
+            << " " << aTm0.tm_hour << ":" << aTm0.tm_min 
+            << ":" << aTm0.tm_sec
+            << " (DST=" << aTm0.tm_isdst << ")" << std::endl;
+          std::cout << "aTimetP1 = " << aTimetP1 << std::endl;
+          std::cout 
+            << "aTmP1 = " 
+            << 1900+aTmP1.tm_year << "-" << aTmP1.tm_mon+1 
+            << "-" <<aTmP1.tm_mday
+            << " " << aTmP1.tm_hour << ":" << aTmP1.tm_min 
+            << ":" << aTmP1.tm_sec
+            << " (DST=" << aTmP1.tm_isdst << ")" << std::endl;
+        }
+        // Actual tests 
+        // Do NOT test isdst: gmtime ALWAYS returns isdst=0!
+        std::stringstream msg;
+        msg << " (Month[0-11]=" << month << ")";
+        CPPUNIT_ASSERT_EQUAL_MESSAGE
+          ( std::string("gmtime(timegm(tm,isDst=0))==tm : hour")+msg.str(), 
+            hour, aTm0.tm_hour );
+//#ifndef WIN32
+        // The following tests FAIL on Windows!!!
+        CPPUNIT_ASSERT_EQUAL_MESSAGE
+          ( std::string("gmtime(timegm(tm,isDst=-1))==tm : hour")+msg.str(), 
+            hour, aTmM1.tm_hour );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE
+          ( std::string("gmtime(timegm(tm,isDst=+1))==tm : hour")+msg.str(), 
+            hour, aTmP1.tm_hour );
+//#endif
+      }
+    }
+
+
+    /// Tests seal::Time constructor from y,mo,d,h,mi,s,ns,local
+    /// The test fails on Windows only for months from April onwards
+    void test_sealTimeFromDate() {
+      bool local = false; // Use UTC-GMT times
+      int month; // Months in [0-11]
+      for ( month = 0; month < 12; month++ ) {
+        int year = 1970; // Years after 1900
+        int day = 03;
+        int hour = 12;
+        int minute = 01;
+        int second = 02;
+        long nsecond = 123456789;
+        // AV 28.06.2005 BUG in seal::Time constructor!
+        //seal::Time time( year, month, day, hour, minute, second, 
+        //                 (seal::Time::ValueType)nsecond, local );
+        seal::Time time =
+          mySealTimeConstructor( year, month, day, hour, minute, second, 
+                                 (seal::Time::ValueType)nsecond, local );
+        time_t s1970 = (31+2)*86400+12*3600+62; // 2894462 (1970-2-3 12:01:02)
+        if ( month == 0 ) s1970 -= 31*86400; // Remove January
+        if ( month >= 2 ) s1970 += 28*86400; // Add February (365 day year)
+        if ( month >= 3 ) s1970 += 31*86400; // Add March
+        if ( month >= 4 ) s1970 += 30*86400; // Add April
+        if ( month >= 5 ) s1970 += 31*86400; // Add May
+        if ( month >= 6 ) s1970 += 30*86400; // Add June
+        if ( month >= 7 ) s1970 += 31*86400; // Add July
+        if ( month >= 8 ) s1970 += 31*86400; // Add August
+        if ( month >= 9 ) s1970 += 30*86400; // Add September
+        if ( month >= 10 ) s1970 += 31*86400; // Add October
+        if ( month >= 11 ) s1970 += 30*86400; // Add November          
+        std::stringstream msg;
+        msg << " (Month[0-11]=" << month << ")";
+        CPPUNIT_ASSERT_EQUAL_MESSAGE
+          ( std::string("ns from 1900")+msg.str(),
+            (seal::Time::ValueType)s1970*1000000000 + nsecond, time.ns() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE
+          ( std::string("year")+msg.str(), year, time.year(local) );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE
+          ( std::string("month")+msg.str(), month, time.month(local) );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE
+          ( std::string("day")+msg.str(), day, time.day(local) );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE
+          ( std::string("hour")+msg.str(), hour, time.hour(local) );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE
+          ( std::string("minute")+msg.str(), minute, time.minute(local) );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE
+          ( std::string("second")+msg.str(), second, time.second(local) );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE
+          ( std::string("nsecond")+msg.str(), nsecond, time.nsecond() );
+      } 
+    } 
+
+
+    /// Tests seal::Time constructor AFTER CALLING tzset()
+    void test_sealTimeFromDate_tzset() {
+#ifdef WIN32
+      _tzset();
+#else
+      tzset();
+#endif
+      test_sealTimeFromDate();
+    }
+  
+
+    /// Tests timeToString and stringToTime conversions
+    void test_timeToString() {
+      std::string aString1 = "2005-06-21_12:00:01.123456789 GMT";
+      seal::Time aTime1 = stringToTime( aString1 );
+      std::string aString2 = timeToString( aTime1 );         
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "string 2 == string 1", aString1, aString2 );
+      seal::Time aTime2 = stringToTime( aString2 );
+      std::string aString3 = timeToString( aTime2 );         
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "string 3 == string 2", aString2, aString3 );
+    } 
+   
+    
+    /// Tests that storing SV objects 'non-ordered', i.e. without increasing
+    /// 'since' throws exceptions in both bulk and single object mode
+    void test_storeObject_SV_unordered() {
+      try {
+        IFolderPtr folder = db->createFolder( "/f1", payloadSpec1 );
+        folder->storeObject( 4, ValidityKeyMax, dummyPayload( 1 ) );
+        folder->storeObject( 2, 3, dummyPayload( 1 ) );
+        folder->storeObject( 5, 6, dummyPayload( 1 ) );
+        CPPUNIT_FAIL( "exception expected" );
+      } catch ( seal::Exception& e ) {
+        CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "exception text",
+          string( "Overlapping intervals not allowed in SINGLE_VERSION mode" ),
+          e.message() );
+      }
+
+      try {
+        IFolderPtr folder = db->createFolder( "/f2", payloadSpec1 );
+        folder->setupStorageBuffer();
+        folder->storeObject( 4, ValidityKeyMax, dummyPayload( 1 ) );
+        folder->storeObject( 2, 3, dummyPayload( 1 ) );
+        folder->storeObject( 5, 6, dummyPayload( 1 ) );
+        folder->flushStorageBuffer();
+        CPPUNIT_FAIL( "unordered bulk exception expected" );
+      } catch ( seal::Exception& e ) {
+        CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "unordered bulk exception text",
+          string( "Overlapping intervals not allowed in SINGLE_VERSION mode" ),
+          e.message() );
+      }
+    }
+    
+    
+    /// Tests storeObject with overlapping intervals
+    /// bug #9212 reported 2005-06-24 by Federico
+    void test_storeObject_SV_overlap_bulk() {
+      try {
+        IFolderPtr folder = db->createFolder( "/f1", payloadSpec1 );
+        folder->setupStorageBuffer();
+        folder->storeObject( 300, 400, dummyPayload( 1 ) );
+        folder->storeObject( 200, 400, dummyPayload( 1 ) );
+        folder->flushStorageBuffer();
+        CPPUNIT_FAIL( "400 until exception expected" );
+      } catch ( seal::Exception& e ) {
+        CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "400 until",
+          string( "Overlapping intervals not allowed in SINGLE_VERSION mode" ),
+          e.message() );
+      }
+      
+      try {
+        IFolderPtr folder = db->createFolder( "/f2", payloadSpec1 );
+        folder->setupStorageBuffer();
+        folder->storeObject( 300, 350, dummyPayload( 1 ) );
+        folder->storeObject( 200, 400, dummyPayload( 1 ) );
+        folder->flushStorageBuffer();
+        CPPUNIT_FAIL( "non-equal until exception expected" );
+      } catch ( seal::Exception& e ) {
+        CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "non-equal until",
+          string( "Overlapping intervals not allowed in SINGLE_VERSION mode" ),
+          e.message() );
+      }
+      
+      try {
+        IFolderPtr folder = db->createFolder( "/f3", payloadSpec1 );
+        folder->setupStorageBuffer();
+        folder->storeObject( 300, ValidityKeyMax, dummyPayload( 1 ) );
+        folder->storeObject( 200, ValidityKeyMax, dummyPayload( 1 ) );
+        folder->flushStorageBuffer();
+        CPPUNIT_FAIL( "ValidityKeyMax until exception expected" );
+      } catch ( seal::Exception& e ) {
+        CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "ValidityKeyMax until",
+          string( "Overlapping intervals not allowed in SINGLE_VERSION mode" ),
+          e.message() );
+      }
+    }
+    
+    
+    /// Tests storeObject with overlapping intervals
+    /// bug #9212 reported 2005-06-24 by Federico
+    void test_storeObject_SV_overlap() {
+      try {
+        IFolderPtr folder = db->createFolder( "/f1", payloadSpec1 );
+        folder->storeObject( 300, 400, dummyPayload( 1 ) );
+        folder->storeObject( 200, 400, dummyPayload( 1 ) );
+        CPPUNIT_FAIL( "400 until exception expected" );
+      } catch ( seal::Exception& e ) {
+        CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "400 until",
+          string( "Overlapping intervals not allowed in SINGLE_VERSION mode" ),
+          e.message() );
+      }
+
+      try {
+        IFolderPtr folder = db->createFolder( "/f2", payloadSpec1 );
+        folder->storeObject( 300, 350, dummyPayload( 1 ) );
+        folder->storeObject( 200, 400, dummyPayload( 1 ) );
+        CPPUNIT_FAIL( "non-equal until exception expected" );
+      } catch ( seal::Exception& e ) {
+        CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "non-equal until",
+          string( "Overlapping intervals not allowed in SINGLE_VERSION mode" ),
+          e.message() );
+      }
+
+       try {
+        IFolderPtr folder = db->createFolder( "/f3", payloadSpec1 );
+        folder->storeObject( 300, ValidityKeyMax, dummyPayload( 1 ) );
+        folder->storeObject( 200, ValidityKeyMax, dummyPayload( 1 ) );
+        CPPUNIT_FAIL( "ValidityKeyMax until exception expected" );
+      } catch ( seal::Exception& e ) {
+        CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "ValidityKeyMax until",
+          string( "Overlapping intervals not allowed in SINGLE_VERSION mode" ),
+          e.message() );
+      }
+    }
+    
+    
+    /// Tests updating the folder description
+    void test_setDescription() {
+      {
+        IFolderPtr folder = db->createFolder( "/myfolder", 
+                                              payloadSpec1, 
+                                              "a description" );
+        folder->setDescription( "new description" );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "internal desc update",
+                                      string( "new description" ),
+                                      folder->description() );
+      }
+      {
+        IFolderPtr folder = db->getFolder( "/myfolder" );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "db desc update",
+                                      string( "new description" ),
+                                      folder->description() );
+      }        
+    }
+    
+    /// Tests bulk insertion into multiple channels (SV mode)
+    void test_storeObjects_bulk_multichannel() {
+      IFolderPtr folder = db->createFolder( "/myfolder", payloadSpec1 );
+      
+      folder->setupStorageBuffer();
+
+      ChannelId nChannels = 10;
+      {
+        vector<IObjectPtr> objs;
+        for ( ChannelId ch = 0; ch < nChannels; ++ch ) {
+          folder->storeObject( (ValidityKey)0, ValidityKeyMax, 
+                               dummyPayload( (int)ch ), ch );
+        }
+        for ( ChannelId ch = 0; ch < nChannels; ++ch ) {
+          folder->storeObject( (ValidityKey)5, ValidityKeyMax, 
+                               dummyPayload( (int)ch ), ch );
+        }
+      }
+
+      folder->flushStorageBuffer();
+      
+      unsigned int nObjsPerChannel = 2;
+      IObjectPtr obj;
+      for ( ChannelId ch = 0; ch < nChannels; ++ch ) {
+        for ( unsigned int i = 0; i < nObjsPerChannel; ++i ) {
+          stringstream s;
+          s << "object " << i << ", channel " << ch << " ";
+          
+          ValidityKey pointInTime = 5 * i; // 0, 5
+          obj = folder->findObject( pointInTime, ch );
+          
+          CPPUNIT_ASSERT_MESSAGE( ( s.str() + "payload" ).c_str(), 
+                                  dummyPayload( (int)ch ) == obj->payload() );
+          CPPUNIT_ASSERT_EQUAL_MESSAGE( ( s.str() + "since" ).c_str(), 
+                                        pointInTime, obj->since() );
+          
+          // until of last extends to ValidityKeyMax
+          if ( i < nObjsPerChannel-1 ) {
+            CPPUNIT_ASSERT_EQUAL_MESSAGE( ( s.str() + "until" ).c_str(), 
+                                          pointInTime +5, obj->until() );
+          } else {
+            CPPUNIT_ASSERT_EQUAL_MESSAGE( ( s.str() + "until" ).c_str(), 
+                                          ValidityKeyMax, obj->until() );
+          }
+        }
+      }
+    }
+    
+    
+    /// Tests tagDescription (MultiVersion only, SingleVersion does not have
+    /// tags and throws a RelationalException)
+    void test_tagDescription() {
+      try {
+        IFolderPtr folder = db->createFolder
+          ( "/myfolder", 
+            payloadSpec1,
+            "my description",
+            FolderVersioning::MULTI_VERSION );
+        folder->storeObject( 0, ValidityKeyMax, dummyPayload( 0 ) );
+        folder->tag( "A", "desc A" );
+      
+        std::string desc = folder->tagDescription( "A" );
+        
+        CPPUNIT_ASSERT_EQUAL_MESSAGE
+          ( "tag desc", std::string("desc A"), desc );
+        
+        try {
+          folder->tagDescription( "nonexisting tag" );
+          CPPUNIT_FAIL( "exception not thrown for nonexisting tag" );
+        } catch ( TagNotFound& /* ignored */ ) { }
+
+      } catch ( seal::Exception& e ) {
+        std::cout << "Exception caught: " << e.message() << std::endl;
+        throw;
+      }
+
+    }
+    
+    
+    /// Tests tagInsertionTime (MultiVersion only, SingleVersion does not have
+    /// tags and throws a RelationalException)
+    void test_tagInsertionTime() {
+      try{
+        IFolderPtr folder = db->createFolder
+          ( "/myfolder", 
+            payloadSpec1,
+            "my description",
+            FolderVersioning::MULTI_VERSION );
+        folder->storeObject( 0, ValidityKeyMax, dummyPayload( 0 ) );
+        
+        folder->tag( "A" );
+        
+        seal::Time tagTime = folder->tagInsertionTime( "A" );
+        
+        // the real time functionality test 
+        // is implemented in test_RalDatabase.cpp
+        CPPUNIT_ASSERT_EQUAL_MESSAGE
+          ( "tagTime size", 
+            string("yyyy-mm-dd_hh:mm:ss.nnnnnnnnn GMT").size(),
+            timeToString(tagTime).size() );
+        
+        try {
+          folder->tagInsertionTime( "nonexisting tag" );
+          CPPUNIT_FAIL( "exception not thrown for nonexisting tag" );
+        } catch ( TagNotFound& /* ignored */ ) { }
+
+      } catch ( seal::Exception& e ) {
+        std::cout << "Exception caught: " << e.message() << std::endl;
+        throw;
+      }
+
+    }
+    
+    
+    /// Tests listTags (MultiVersion only, SingleVersion does not have tags
+    /// and returns an empty vector)
+    void test_listTags() {
+      IFolderPtr folder = db->createFolder( "/myfolder", 
+                                            payloadSpec1,
+                                            "my description",
+                                            FolderVersioning::MULTI_VERSION );
+      folder->storeObject( 0, ValidityKeyMax, dummyPayload( 0 ) );
+      folder->tag( "A" );
+      folder->tag( "B" );
+      
+      std::vector<std::string> tags = folder->listTags();
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "tag count", 2ul, (unsigned long)tags.size() );    
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "tag 1", std::string("A"), tags[0] );    
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "tag 2", std::string("B"), tags[1] );    
+    }
+    
+    
+    /// Tests listChannels (SingleVersion only, MultiVersion test in
+    /// test_RalDatabase)
+    void test_listChannels() {
+      IFolderPtr folder = db->createFolder( "/myfolder", payloadSpec1 );
+      ChannelId channel = 1;
+      folder->storeObject( 0, ValidityKeyMax, dummyPayload( 0 ), channel );
+      channel = 3;
+      folder->storeObject( 0, ValidityKeyMax, dummyPayload( 0 ), channel );
+      channel = 5;
+      folder->storeObject( 0, ValidityKeyMax, dummyPayload( 0 ), channel );
+      
+      std::vector<ChannelId> channels = folder->listChannels();
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "channel count", 3ul, (unsigned long)channels.size() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "channel 1", (ChannelId)1, channels[0] );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "channel 2", (ChannelId)3, channels[1] );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "channel 3", (ChannelId)5, channels[2] );
+
+      // check exceptional behavior
+      folder = db->createFolder( "/empty_folder", payloadSpec1 );
+      
+      // a folder without data has no channels
+      channels = folder->listChannels();
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "channel list size", 0ul, (unsigned long)channels.size() );
+    }
+
+    
+    /// Tests object browsing in tags (MV folders)
+    void test_browseObjects_MV_tag() {
+      IFolderPtr folder = db->createFolder( "/myfolder", 
+                                            payloadSpec1,
+                                            "my description",
+                                            FolderVersioning::MULTI_VERSION );
+      
+      folder->storeObject(  0, 10, dummyPayload( 0 ) );
+      folder->storeObject( 10, 20, dummyPayload( 1 ) );
+      folder->storeObject( 20, ValidityKeyMax, dummyPayload( 2 ) );
+      
+      folder->tag( "mytag" );
+      
+      {
+        IObjectIteratorPtr objs = folder->browseObjects( 5, 15, 0, "mytag" );
+        
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "object count", 2ul, objs->size() );
+        
+        IObjectPtr obj = objs->next();
+        CPPUNIT_ASSERT_MESSAGE( "obj 1.1 payload", 
+                                dummyPayload( 0 ) == obj->payload() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 1.1 since",
+                                      (ValidityKey)0, obj->since() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 1.1 until",
+                                      (ValidityKey)10, obj->until() );
+        
+        obj = objs->next();
+        CPPUNIT_ASSERT_MESSAGE( "obj 1.2 payload", 
+                                dummyPayload( 1 ) == obj->payload() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 1.2 since",
+                                      (ValidityKey)10, obj->since() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 1.2 until",
+                                      (ValidityKey)20, obj->until() );
+      }
+      
+      {
+        IObjectIteratorPtr objs = folder->browseObjects( 10, 20, 0, "mytag" );
+        
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "object count", 2ul, objs->size() );
+        
+        IObjectPtr obj = objs->next();
+        CPPUNIT_ASSERT_MESSAGE( "obj 2.1 payload", 
+                                dummyPayload( 1 ) == obj->payload() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 2.1 since",
+                                      (ValidityKey)10, obj->since() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 2.1 until",
+                                      (ValidityKey)20, obj->until() );
+        
+        obj = objs->next();
+        CPPUNIT_ASSERT_MESSAGE( "obj 2.2 payload", 
+                                dummyPayload( 2 ) == obj->payload() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 2.1 since",
+                                      (ValidityKey)20, obj->since() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 2.1 until",
+                                      ValidityKeyMax, obj->until() );
+      }
+      
+      
+      {
+        IObjectIteratorPtr objs = folder->browseObjects( ValidityKeyMin,
+                                                         ValidityKeyMax,
+                                                         0, "mytag" );
+        
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "object count", 3ul, objs->size() );
+        
+        IObjectPtr obj = objs->next();
+        CPPUNIT_ASSERT_MESSAGE( "obj 3.1 payload", 
+                                dummyPayload( 0 ) == obj->payload() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 3.1 since",
+                                      (ValidityKey)0, obj->since() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 3.1 until",
+                                      (ValidityKey)10, obj->until() );
+        
+        obj = objs->next();
+        CPPUNIT_ASSERT_MESSAGE( "obj 3.2 payload", 
+                                dummyPayload( 1 ) == obj->payload() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 3.2 since",
+                                      (ValidityKey)10, obj->since() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 3.2 until",
+                                      (ValidityKey)20, obj->until() );
+        
+        obj = objs->next();
+        CPPUNIT_ASSERT_MESSAGE( "obj 3.3 payload", 
+                                dummyPayload( 2 ) == obj->payload() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 3.3 since",
+                                      (ValidityKey)20, obj->since() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 3.3 until",
+                                      ValidityKeyMax, obj->until() );
+      }
+    }
+    
+    
+    /// Tests object browsing (MV folders)
+    void test_browseObjects_MV() {
+      IFolderPtr folder = db->createFolder( "/myfolder", 
+                                            payloadSpec1,
+                                            "my description",
+                                            FolderVersioning::MULTI_VERSION );
+      
+      folder->storeObject(  0, 10, dummyPayload( 0 ) );
+      folder->storeObject( 10, 20, dummyPayload( 1 ) );
+      folder->storeObject( 20, ValidityKeyMax, dummyPayload( 2 ) );
+      
+      {
+        IObjectIteratorPtr objs = folder->browseObjects( 5, 15 );
+        
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "object count", 2ul, objs->size() );
+        
+        IObjectPtr obj = objs->next();
+        CPPUNIT_ASSERT_MESSAGE( "obj 1.1 payload", 
+                                dummyPayload( 0 ) == obj->payload() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 1.1 since",
+                                      (ValidityKey)0, obj->since() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 1.1 until",
+                                      (ValidityKey)10, obj->until() );
+        
+        obj = objs->next();
+        CPPUNIT_ASSERT_MESSAGE( "obj 1.2 payload", 
+                                dummyPayload( 1 ) == obj->payload() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 1.2 since",
+                                      (ValidityKey)10, obj->since() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 1.2 until",
+                                      (ValidityKey)20, obj->until() );
+      }
+      
+      {
+        IObjectIteratorPtr objs = folder->browseObjects( 10, 20 );
+        
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "object count", 2ul, objs->size() );
+        
+        IObjectPtr obj = objs->next();
+        CPPUNIT_ASSERT_MESSAGE( "obj 2.1 payload", 
+                                dummyPayload( 1 ) == obj->payload() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 2.1 since",
+                                      (ValidityKey)10, obj->since() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 2.1 until",
+                                      (ValidityKey)20, obj->until() );
+        
+        obj = objs->next();
+        CPPUNIT_ASSERT_MESSAGE( "obj 2.2 payload", 
+                                dummyPayload( 2 ) == obj->payload() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 2.1 since",
+                                      (ValidityKey)20, obj->since() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 2.1 until",
+                                      ValidityKeyMax, obj->until() );
+      }
+
+      
+      {
+        IObjectIteratorPtr objs = folder->browseObjects( ValidityKeyMin,
+                                                         ValidityKeyMax );
+        
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "object count", 3ul, objs->size() );
+        
+        IObjectPtr obj = objs->next();
+        CPPUNIT_ASSERT_MESSAGE( "obj 3.1 payload", 
+                                dummyPayload( 0 ) == obj->payload() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 3.1 since",
+                                      (ValidityKey)0, obj->since() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 3.1 until",
+                                      (ValidityKey)10, obj->until() );
+        
+        obj = objs->next();
+        CPPUNIT_ASSERT_MESSAGE( "obj 3.2 payload", 
+                                dummyPayload( 1 ) == obj->payload() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 3.2 since",
+                                      (ValidityKey)10, obj->since() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 3.2 until",
+                                      (ValidityKey)20, obj->until() );
+        
+        obj = objs->next();
+        CPPUNIT_ASSERT_MESSAGE( "obj 3.3 payload", 
+                                dummyPayload( 2 ) == obj->payload() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 3.3 since",
+                                      (ValidityKey)20, obj->since() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 3.3 until",
+                                      ValidityKeyMax, obj->until() );
+      }
+    }
+    
+    
+    /// Tests object browsing (SV folders)
+    void test_browseObjects_SV() {
+      IFolderPtr folder = db->createFolder( "/myfolder", 
+                                            payloadSpec1,
+                                            "my description",
+                                            FolderVersioning::SINGLE_VERSION );
+      
+      folder->storeObject(  0, 10, dummyPayload( 0 ) );
+      folder->storeObject( 10, 20, dummyPayload( 1 ) );
+      folder->storeObject( 20, ValidityKeyMax, dummyPayload( 2 ) );
+      
+      {
+        IObjectIteratorPtr objs = folder->browseObjects( 5, 15 );
+        
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "object count", 2ul, objs->size() );
+        
+        IObjectPtr obj = objs->next();
+        CPPUNIT_ASSERT_MESSAGE( "obj 1.1 payload", 
+                                dummyPayload( 0 ) == obj->payload() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 1.1 since",
+                                      (ValidityKey)0, obj->since() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 1.1 until",
+                                      (ValidityKey)10, obj->until() );
+        
+        obj = objs->next();
+        CPPUNIT_ASSERT_MESSAGE( "obj 1.2 payload", 
+                                dummyPayload( 1 ) == obj->payload() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 1.2 since",
+                                      (ValidityKey)10, obj->since() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 1.2 until",
+                                      (ValidityKey)20, obj->until() );
+      }
+      
+      {
+        IObjectIteratorPtr objs = folder->browseObjects( 10, 20 );
+        
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "object count", 2ul, objs->size() );
+        
+        IObjectPtr obj = objs->next();
+        CPPUNIT_ASSERT_MESSAGE( "obj 2.1 payload", 
+                                dummyPayload( 1 ) == obj->payload() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 2.1 since",
+                                      (ValidityKey)10, obj->since() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 2.1 until",
+                                      (ValidityKey)20, obj->until() );
+        
+        obj = objs->next();
+        CPPUNIT_ASSERT_MESSAGE( "obj 2.2 payload", 
+                                dummyPayload( 2 ) == obj->payload() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 2.1 since",
+                                      (ValidityKey)20, obj->since() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 2.1 until",
+                                      ValidityKeyMax, obj->until() );
+      }
+      
+      
+      {
+        IObjectIteratorPtr objs = folder->browseObjects( ValidityKeyMin,
+                                                         ValidityKeyMax );
+        
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "object count", 3ul, objs->size() );
+        
+        IObjectPtr obj = objs->next();
+        CPPUNIT_ASSERT_MESSAGE( "obj 3.1 payload", 
+                                dummyPayload( 0 ) == obj->payload() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 3.1 since",
+                                      (ValidityKey)0, obj->since() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 3.1 until",
+                                      (ValidityKey)10, obj->until() );
+        
+        obj = objs->next();
+        CPPUNIT_ASSERT_MESSAGE( "obj 3.2 payload", 
+                                dummyPayload( 1 ) == obj->payload() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 3.2 since",
+                                      (ValidityKey)10, obj->since() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 3.2 until",
+                                      (ValidityKey)20, obj->until() );
+        
+        obj = objs->next();
+        CPPUNIT_ASSERT_MESSAGE( "obj 3.3 payload", 
+                                dummyPayload( 2 ) == obj->payload() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 3.3 since",
+                                      (ValidityKey)20, obj->since() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 3.3 until",
+                                      ValidityKeyMax, obj->until() );
+      }
+    }
+    
+    /// Tests that the storage buffer is cleared and none of the objects
+    /// is stored if an exception is thrown during the bulk operation 
+    /// 'flushStorageBuffer' (for instance, because one IOV has until<since)
+    void test_exceptionInFlushStorageBuffer() {
+      IFolderPtr folder = db->createFolder( "/myfolder", payloadSpec1 );
+      
+      folder->setupStorageBuffer();
+      folder->storeObject( 0, ValidityKeyMax, dummyPayload( 0 ) );
+      folder->storeObject( 10, 20, dummyPayload( 1 ) );
+      bool flushFailed = false;
+      try {
+        folder->flushStorageBuffer();
+      } catch ( ValidityKeyException& /* dummy */ ) {
+        flushFailed = true;
+      }
+      CPPUNIT_ASSERT_MESSAGE( "first insertion OK", ! flushFailed );
+      
+      folder->setupStorageBuffer();
+      folder->storeObject( 20, ValidityKeyMax, dummyPayload( 2 ) );
+      folder->storeObject( 30, 20, dummyPayload( 3 ) ); // INVALID!
+      folder->storeObject( 40, 50, dummyPayload( 4 ) );
+      flushFailed = false;
+      try {
+        folder->flushStorageBuffer();
+      } catch ( ValidityKeyException& /* dummy */ ) {
+        flushFailed = true;
+      }
+      CPPUNIT_ASSERT_MESSAGE( "second insertion not OK", flushFailed );
+
+      folder->setupStorageBuffer();
+      folder->storeObject( 50, ValidityKeyMax, dummyPayload( 5 ) );
+      folder->storeObject( 60, 70, dummyPayload( 6 ) ); 
+      flushFailed = false;
+      try {
+        folder->flushStorageBuffer();
+      } catch ( ValidityKeyException& /* dummy */ ) {
+        flushFailed = true;
+      }
+      CPPUNIT_ASSERT_MESSAGE( "third insertion OK", ! flushFailed );
+      
+      IObjectPtr obj0 = folder->findObject( 0 );
+      CPPUNIT_ASSERT_MESSAGE( "object 0 found", obj0.get() != 0 );
+      IObjectPtr obj1 = folder->findObject( 10 );
+      CPPUNIT_ASSERT_MESSAGE( "object 1 found", obj1.get() != 0 );
+
+      bool objectNotFound = false;
+      try {
+        folder->findObject( 20 );
+      } catch( ObjectNotFound& /* dummy */ ) {
+        objectNotFound = true;
+      }
+      CPPUNIT_ASSERT_MESSAGE( "object 2 not found", objectNotFound );
+
+      objectNotFound = false;
+      try {
+        folder->findObject( 30 );
+      } catch( ObjectNotFound& /* dummy */ ) {
+        objectNotFound = true;
+      }
+      CPPUNIT_ASSERT_MESSAGE( "object 3 not found", objectNotFound );
+
+      objectNotFound = false;
+      try {
+        folder->findObject( 40 );
+      } catch( ObjectNotFound& /* dummy */ ) {
+        objectNotFound = true;
+      }
+      CPPUNIT_ASSERT_MESSAGE( "object 4 not found", objectNotFound );
+
+      IObjectPtr obj5 = folder->findObject( 50 );
+      CPPUNIT_ASSERT_MESSAGE( "object 5 found", obj5.get() != 0 );
+      IObjectPtr obj6 = folder->findObject( 60 );
+      CPPUNIT_ASSERT_MESSAGE( "object 6 found", obj6.get() != 0 );
+
+    }    
+
+    /// Tests that a ValidityKeyException is thrown when since>until
+    /// and when since or until are out of boundaries
+    void test_validityKeyException() {
+      IFolderPtr folder = db->createFolder( "/myfolder", payloadSpec1 );
+      
+      bool storeFailed = false;
+      try {
+        folder->storeObject( 100, 0, dummyPayload( 0 ) );
+      } catch ( ValidityKeyException& /* dummy */ ) {
+        storeFailed = true;
+      }
+      CPPUNIT_ASSERT_MESSAGE( "exception for [100,0]", storeFailed );      
+
+      storeFailed = false;
+      try {
+        folder->storeObject( 100, 100, dummyPayload( 0 ) );
+      } catch ( ValidityKeyException& /* dummy */ ) {
+        storeFailed = true;
+      }
+      CPPUNIT_ASSERT_MESSAGE( "exception for [100,100]", storeFailed );      
+
+      storeFailed = false;
+      try {
+        // Split the following line on two lines (Windows compiler warning) 
+        //ValidityKey since = ValidityKeyMin-1;
+        ValidityKey since = ValidityKeyMin;
+        since = since-1;
+        ValidityKey until = ValidityKeyMin;
+        // NB: Now (ValidityKey=long_long, ValidityKeyMin=LONG_LONG_MIN)
+        //     ==> LONG_LONG_MIN-1 is an invalid int64 LONG_LONG_MAX > since
+        // NB: Previously (ValidityKey=long_long, ValidityKeyMin=LONG_MIN)
+        //     ==> LONG_MIN-1 is an invalid int64 > LONG_MIN=ValidityKeyMin
+        folder->storeObject( since, until, dummyPayload( 0 ) ); 
+      } catch ( ValidityKeyException& /* dummy */ ) {
+        storeFailed = true;
+      }
+      CPPUNIT_ASSERT_MESSAGE( "exception for [min-1,min]", storeFailed );
+
+      storeFailed = false;
+      try {
+        ValidityKey since = ValidityKeyMax;
+        // Split the following line on two lines (Windows compiler warning) 
+        //ValidityKey until = ValidityKeyMax+1;
+        ValidityKey until = ValidityKeyMax;
+        until = until+1;
+        // NB: Now (ValidityKey=long_long, ValidityKeyMin=LONG_LONG_MIN)
+        //     ==> LONG_LONG_MIN-1 is an invalid int64 LONG_LONG_MAX > since
+        // NB: Previously (ValidityKey=long_long, ValidityKeyMin=LONG_MIN)
+        //     ==> LONG_MIN-1 is an invalid int64 > LONG_MIN=ValidityKeyMin
+        folder->storeObject( since, until, dummyPayload( 0 ) ); 
+      } catch ( ValidityKeyException& /* dummy */ ) {
+        storeFailed = true;
+      }
+      CPPUNIT_ASSERT_MESSAGE( "exception for [max,max+1]", storeFailed );      
+
+    }    
+
+    /// Tests that the ValidityKey boundaries are those we expect
+    /// (use hardcoded numerical values)
+    void test_validityKeyBoundaries() {
+      //CPPUNIT_ASSERT_EQUAL_MESSAGE
+      //  ( "ValidityKeyMin hardcoded", 
+      //    (ValidityKey)0, ValidityKeyMin + 9223372036854775808ULL );
+      //CPPUNIT_ASSERT_EQUAL_MESSAGE
+      //  ( "ValidityKeyMax hardcoded", 
+      //    (ValidityKey)0, ValidityKeyMax - 18446744073709551615ULL );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "ValidityKeyMin hardcoded", 
+          (ValidityKey)0, ValidityKeyMin );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "ValidityKeyMax hardcoded", 
+          (ValidityKey)0, ValidityKeyMax - 9223372036854775807LL );
+      //CPPUNIT_ASSERT_EQUAL_MESSAGE
+      //  ( "ValidityKeyMin sInt64Min", 
+      //    (ValidityKey)sInt64Min, ValidityKeyMin );
+      //CPPUNIT_ASSERT_EQUAL_MESSAGE
+      //  ( "ValidityKeyMin uInt64Max", 
+      //    (ValidityKey)uInt64Max, ValidityKeyMax );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "ValidityKeyMin uInt64Min", 
+          (ValidityKey)uInt64Min, ValidityKeyMin );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "ValidityKeyMin sInt64Max", 
+          (ValidityKey)sInt64Max, ValidityKeyMax );
+    }
+  
+
+    /// Stores objects to multiple folders and retrieves them in a loop
+    /// Tests against a problem first reported by Marco Clemencic on
+    /// 2005-01-27 -- cannot reproduce at the moment
+    void test_multiple_folders() {
+      bool showPrintout = false;
+      
+      int nFolders = 5;
+      vector<string> foldernames;
+      for ( int i = 0; i < nFolders; ++i ) {
+        stringstream s;
+        s << "/f_" << i;
+        foldernames.push_back( s.str() );
+      }
+      
+      long nObjs = 100;
+
+      for ( vector<string>::const_iterator fname = foldernames.begin();
+            fname != foldernames.end(); ++fname ) {
+        IFolderPtr folder = db->createFolder( *fname, payloadSpec1 );
+      }
+      
+      for ( vector<string>::const_iterator fname = foldernames.begin();
+            fname != foldernames.end(); ++fname ) {
+        IFolderPtr folder = db->getFolder( *fname );
+        folder->setupStorageBuffer();
+        for ( long i = 0; i < nObjs; ++i ) {
+          folder->storeObject( i, ValidityKeyMax, dummyPayload( i ) );
+        }
+        folder->flushStorageBuffer();
+        
+        if ( showPrintout )
+          cout << "wrote " << nObjs
+            << " objects in folder '" << *fname << endl;
+      }
+      
+      for ( vector<string>::const_iterator fname = foldernames.begin();
+            fname != foldernames.end(); ++fname ) {
+        IFolderPtr folder = db->getFolder( *fname );
+        IObjectIteratorPtr objs 
+          = folder->browseObjects( ValidityKeyMin, ValidityKeyMax, 0, "" );
+
+        objs->goToStart();
+        
+        CPPUNIT_ASSERT_MESSAGE( "hasNext", objs->hasNext() );
+
+        long objIndex = 0;
+        while ( objs->hasNext() ) {
+          IObjectPtr obj = objs->next();
+
+          stringstream s;
+          s << "folder " << *fname << ": object " << objIndex << " ";
+          CPPUNIT_ASSERT_MESSAGE( ( s.str() + "payload" ).c_str(), 
+                                  dummyPayload( objIndex ) 
+                                  == obj->payload() );
+          
+          if ( showPrintout && objIndex % 10 == 0 ) {
+            for ( AttributeList::const_iterator attr = obj->payload().begin();
+                  attr != obj->payload().end(); ++attr ) {
+              cout << *fname << "[" << objIndex << "]:  "
+              << attr->spec().name() << ", "
+              << attr->spec().type_name() << ", "
+              << attr->getValueAsString() << endl;
+            }
+          }
+          
+          CPPUNIT_ASSERT_EQUAL_MESSAGE( ( s.str() + "since" ).c_str(), 
+                                        objIndex, (long)obj->since() );
+          
+          // last object's until extends to ValidityKeyMax
+          if ( objIndex < nObjs-1 ) {
+            CPPUNIT_ASSERT_EQUAL_MESSAGE( ( s.str() + "until" ).c_str(), 
+                                          objIndex+1, (long)obj->until() );
+          } else {
+            CPPUNIT_ASSERT_EQUAL_MESSAGE( ( s.str() + "until" ).c_str(), 
+                                          ValidityKeyMax, obj->until() );
+          }
+          
+          ++objIndex;
+        }
+        
+        if ( showPrintout )
+          cout << "checked " << objIndex
+            << " objects in folder " << *fname << endl;
+      }
+    }
+    
+    
+    /// Tests MV tagging and retrieving
+    void test_MV_tag_and_retrieve() {
+      IFolderPtr folder = db->createFolder( "/myfolder", 
+                                            payloadSpec1,
+                                            "my description",
+                                            FolderVersioning::MULTI_VERSION );
+      
+      folder->setupStorageBuffer();
+      folder->storeObject( 0, 4, dummyPayload( 0 ) );
+      folder->storeObject( 2, 6, dummyPayload( 1 ) );
+      folder->flushStorageBuffer();
+      
+      folder->tag( "tagA", "an optional description" );
+      seal::Time asOfDate = folder->findObject( 0 )->insertionTime();
+
+      // MySQL now() has 1 second granularity: need to sleep at least 1 second
+      seal::TimeInfo::sleep(1);
+
+      folder->setupStorageBuffer();
+      folder->storeObject( 3, 7, dummyPayload( 2 ) );
+      folder->storeObject( 5, 9, dummyPayload( 3 ) );
+      folder->flushStorageBuffer();
+            
+      folder->tag( "tagB" );
+      folder->tag( asOfDate, "tagC" ); // == tagA
+      
+      // fetch tagA
+      IObjectIteratorPtr objs = folder->browseObjects( ValidityKeyMin,
+                                                       ValidityKeyMax,
+                                                       (ChannelId)0,
+                                                       "tagA" );
+      
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "tagA object count", 2ul, objs->size() );
+      
+      IObjectPtr obj = objs->next();
+      CPPUNIT_ASSERT_MESSAGE( "tagA obj 1 payload", 
+                              dummyPayload( 0 ) == obj->payload() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "tagA obj 1 since",
+                                    (ValidityKey)0, obj->since() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "tagA obj 1 until",
+                                    (ValidityKey)2, obj->until() );
+      
+      obj = objs->next();
+      CPPUNIT_ASSERT_MESSAGE( "tagA obj 2 payload", 
+                              dummyPayload( 1 ) == obj->payload() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "tagA obj 2 since",
+                                    (ValidityKey)2, obj->since() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "tagA obj 2 until",
+                                    (ValidityKey)6, obj->until() );
+      
+      // fetch tagB
+      objs = folder->browseObjects( ValidityKeyMin, ValidityKeyMax,
+                                    (ChannelId)0, "tagB" );
+      
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "tagB object count", 4ul, objs->size() );
+      
+      obj = objs->next();
+      CPPUNIT_ASSERT_MESSAGE( "tagB obj 1 payload", 
+                              dummyPayload( 0 ) == obj->payload() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "tagB obj 1 since",
+                                    (ValidityKey)0, obj->since() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "tagB obj 1 until",
+                                    (ValidityKey)2, obj->until() );
+      
+      obj = objs->next();
+      CPPUNIT_ASSERT_MESSAGE( "tagB obj 2 payload", 
+                              dummyPayload( 1 ) == obj->payload() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "tagB obj 2 since",
+                                    (ValidityKey)2, obj->since() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "tagB obj 2 until",
+                                    (ValidityKey)3, obj->until() );
+      
+      obj = objs->next();
+      CPPUNIT_ASSERT_MESSAGE( "tagB obj 3 payload", 
+                              dummyPayload( 2 ) == obj->payload() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "tagB obj 3 since",
+                                    (ValidityKey)3, obj->since() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "tagB obj 3 until",
+                                    (ValidityKey)5, obj->until() );
+
+      obj = objs->next();
+      CPPUNIT_ASSERT_MESSAGE( "tagB obj 4 payload", 
+                              dummyPayload( 3 ) == obj->payload() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "tagB obj 4 since",
+                                    (ValidityKey)5, obj->since() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "tagB obj 4 until",
+                                    (ValidityKey)9, obj->until() );      
+
+      // fetch head
+      objs = folder->browseObjects( ValidityKeyMin, ValidityKeyMax,
+                                    (ChannelId)0 );
+      
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "HEAD object count", 4ul, objs->size() );
+      
+      obj = objs->next();
+      CPPUNIT_ASSERT_MESSAGE( "HEAD obj 1 payload", 
+                              dummyPayload( 0 ) == obj->payload() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "HEAD obj 1 since",
+                                    (ValidityKey)0, obj->since() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "HEAD obj 1 until",
+                                    (ValidityKey)2, obj->until() );
+      
+      obj = objs->next();
+      CPPUNIT_ASSERT_MESSAGE( "HEAD obj 2 payload", 
+                              dummyPayload( 1 ) == obj->payload() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "HEAD obj 2 since",
+                                    (ValidityKey)2, obj->since() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "HEAD obj 2 until",
+                                    (ValidityKey)3, obj->until() );
+      
+      obj = objs->next();
+      CPPUNIT_ASSERT_MESSAGE( "HEAD obj 3 payload", 
+                              dummyPayload( 2 ) == obj->payload() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "HEAD obj 3 since",
+                                    (ValidityKey)3, obj->since() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "HEAD obj 3 until",
+                                    (ValidityKey)5, obj->until() );
+      
+      obj = objs->next();
+      CPPUNIT_ASSERT_MESSAGE( "HEAD obj 4 payload", 
+                              dummyPayload( 3 ) == obj->payload() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "HEAD obj 4 since",
+                                    (ValidityKey)5, obj->since() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "HEAD obj 4 until",
+                                    (ValidityKey)9, obj->until() );      
+
+      // fetch tagC
+      objs = folder->browseObjects( ValidityKeyMin, ValidityKeyMax,
+                                    (ChannelId)0, "tagC" );
+      
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "tagC object count", 2ul, objs->size() );
+      
+      obj = objs->next();
+      CPPUNIT_ASSERT_MESSAGE( "tagC obj 1 payload", 
+                              dummyPayload( 0 ) == obj->payload() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "tagC obj 1 since",
+                                    (ValidityKey)0, obj->since() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "tagC obj 1 until",
+                                    (ValidityKey)2, obj->until() );
+      
+      obj = objs->next();
+      CPPUNIT_ASSERT_MESSAGE( "tagC obj 2 payload", 
+                              dummyPayload( 1 ) == obj->payload() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "tagC obj 2 since",
+                                    (ValidityKey)2, obj->since() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "tagC obj 2 until",
+                                    (ValidityKey)6, obj->until() );
+    }
+    
+    
+    /// Tests bulk storeObject of MV objects
+    void test_storeObject_bulk_MV() {
+      IFolderPtr folder = db->createFolder( "/myfolder", 
+                                            payloadSpec1,
+                                            "my description",
+                                            FolderVersioning::MULTI_VERSION );
+      
+      folder->setupStorageBuffer();
+      unsigned long nObjs = 10;
+      for ( unsigned long i = 0; i < nObjs; ++i ) {
+        folder->storeObject( i, ValidityKeyMax, dummyPayload( i ) );
+      }
+      
+      // cppunit 1.8.0 does not have CPPUNIT_ASSERT_EXCEPTION
+      bool objectNotFound = false;
+      try {
+        folder->findObject( 0 );
+      } catch( ObjectNotFound& /* dummy */ ) {
+        objectNotFound = true;
+      }
+      CPPUNIT_ASSERT_MESSAGE( "no objects", objectNotFound );
+      
+      folder->flushStorageBuffer();
+      
+      IObjectIteratorPtr objs = folder->browseObjects( ValidityKeyMin,
+                                                       ValidityKeyMax );
+      
+      for ( unsigned long i = 0; i < objs->size(); ++i ) {
+        IObjectPtr obj = objs->next();
+        stringstream s;
+        s << "object " << i << " ";
+        CPPUNIT_ASSERT_MESSAGE( ( s.str() + "payload" ).c_str(), 
+                                dummyPayload( i ) == obj->payload() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( ( s.str() + "since" ).c_str(), 
+                                      (ValidityKey)i, obj->since() );
+        // last object's until extends to ValidityKeyMax
+        if ( i < nObjs-1 ) {
+          CPPUNIT_ASSERT_EQUAL_MESSAGE( ( s.str() + "until" ).c_str(), 
+                                        (ValidityKey)i+1, obj->until() );
+        } else {
+          CPPUNIT_ASSERT_EQUAL_MESSAGE( ( s.str() + "until" ).c_str(), 
+                                        ValidityKeyMax, obj->until() );
+        }
+      }
+      
+    }
+    
+    
+    /// Tests bulk storeObject of 70k objects: this caused an ORA-24381
+    /// error before a sub-batching fix was applied
+    void test_storeObject_bulk_70k() {
+      IFolderPtr folder = db->createFolder( "/myfolder", payloadSpec1 );
+      
+      folder->setupStorageBuffer();
+      long nObjs = 70*1000;
+      for ( long i = 0; i < nObjs; ++i ) {
+        folder->storeObject( i, ValidityKeyMax, dummyPayload( i ) );
+      }
+            
+      folder->flushStorageBuffer();
+      
+      IObjectPtr obj;
+      for ( long i = 0; i < nObjs; i += 1000 ) {
+        obj = folder->findObject( i );
+        stringstream s;
+        s << "object " << i << " ";
+        CPPUNIT_ASSERT_MESSAGE( ( s.str() + "payload" ).c_str(), 
+                                dummyPayload( i ) == obj->payload() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( ( s.str() + "since" ).c_str(), 
+                                      i, (long)obj->since() );
+        // last object's until extends to ValidityKeyMax
+        if ( i < nObjs-1 ) {
+          CPPUNIT_ASSERT_EQUAL_MESSAGE( ( s.str() + "until" ).c_str(), 
+                                        i+1, (long)obj->until() );
+        } else {
+          CPPUNIT_ASSERT_EQUAL_MESSAGE( ( s.str() + "until" ).c_str(), 
+                                        LONG_MAX, (long)obj->until() );
+        }
+      }
+      
+    }
+    
+    
+    /// Tests bulk storeObject of SV objects with a reused AttributeList
+    /// This test ensures that the payload data is copied, not referenced
+    /// inside the storage buffer.
+    void test_storeObject_bulk_SV_listReused() {
+      IFolderPtr folder = db->createFolder( "/myfolder", payloadSpec1 );
+      
+      AttributeList payload = dummyPayload( 0 );
+      
+      folder->setupStorageBuffer();
+      unsigned long nObjs = 100;
+      for ( unsigned long i = 0; i < nObjs; ++i ) {
+        payload["I"].setValue<int>( (int)i );
+        folder->storeObject( i, ValidityKeyMax, payload );
+      }
+      
+      // cppunit 1.8.0 does not have CPPUNIT_ASSERT_EXCEPTION
+      bool objectNotFound = false;
+      try {
+        folder->findObject( 0 );
+      } catch( ObjectNotFound& /* dummy */ ) {
+        objectNotFound = true;
+      }
+      CPPUNIT_ASSERT_MESSAGE( "no objects", objectNotFound );
+      
+      folder->flushStorageBuffer();
+      
+      IObjectIteratorPtr objs = folder->browseObjects( ValidityKeyMin,
+                                                       ValidityKeyMax );
+      
+      for ( unsigned long i = 0; i < objs->size(); ++i ) {
+        IObjectPtr obj = objs->next();
+        stringstream s;
+        s << "object " << i << " ";
+        CPPUNIT_ASSERT_MESSAGE( ( s.str() + "payload I" ).c_str(), 
+                                (int)i == obj->payloadValue<int>( "I" ) );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( ( s.str() + "since" ).c_str(), 
+                                      (ValidityKey)i, obj->since() );
+        // last object's until extends to ValidityKeyMax
+        if ( i < nObjs-1 ) {
+          CPPUNIT_ASSERT_EQUAL_MESSAGE( ( s.str() + "until" ).c_str(), 
+                                        (ValidityKey)i+1, obj->until() );
+        } else {
+          CPPUNIT_ASSERT_EQUAL_MESSAGE( ( s.str() + "until" ).c_str(), 
+                                        ValidityKeyMax, obj->until() );
+        }
+      }
+      
+    }
+    
+    
+    /// Tests bulk storeObject of SV objects
+    void test_storeObject_bulk_SV() {
+      IFolderPtr folder = db->createFolder( "/myfolder", payloadSpec1 );
+      
+      folder->setupStorageBuffer();
+      unsigned long nObjs = 100;
+      for ( unsigned long i = 0; i < nObjs; ++i ) {
+        folder->storeObject( i, ValidityKeyMax, dummyPayload( i ) );
+      }
+      
+      // cppunit 1.8.0 does not have CPPUNIT_ASSERT_EXCEPTION
+      bool objectNotFound = false;
+      try {
+        folder->findObject( 0 );
+      } catch( ObjectNotFound& /* dummy */ ) {
+        objectNotFound = true;
+      }
+      CPPUNIT_ASSERT_MESSAGE( "no objects", objectNotFound );
+      
+      folder->flushStorageBuffer();
+      
+      IObjectIteratorPtr objs = folder->browseObjects( ValidityKeyMin,
+                                                       ValidityKeyMax );
+
+      for ( unsigned long i = 0; i < objs->size(); ++i ) {
+        IObjectPtr obj = objs->next();
+        stringstream s;
+        s << "object " << i << " ";
+        CPPUNIT_ASSERT_MESSAGE( ( s.str() + "payload" ).c_str(), 
+                                dummyPayload( i ) == obj->payload() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( ( s.str() + "since" ).c_str(), 
+                                      (ValidityKey)i, obj->since() );
+        // last object's until extends to ValidityKeyMax
+        if ( i < nObjs-1 ) {
+          CPPUNIT_ASSERT_EQUAL_MESSAGE( ( s.str() + "until" ).c_str(), 
+                                        (ValidityKey)i+1, obj->until() );
+        } else {
+          CPPUNIT_ASSERT_EQUAL_MESSAGE( ( s.str() + "until" ).c_str(), 
+                                        ValidityKeyMax, obj->until() );
+        }
+      }
+      
+    }
+    
+    
+    /// Tests bulk operation 'flushStorageBuffer'
+    void test_flushStorageBuffer() {
+      IFolderPtr folder = db->createFolder( "/myfolder", payloadSpec1 );
+      
+      folder->setupStorageBuffer();
+      folder->storeObject( 0, ValidityKeyMax, dummyPayload( 0 ) );
+      folder->storeObject( 1, ValidityKeyMax, dummyPayload( 1 ) );
+      
+      // cppunit 1.8.0 does not have CPPUNIT_ASSERT_EXCEPTION
+      bool objectNotFound = false;
+      try {
+        folder->findObject( 1 );
+      } catch( ObjectNotFound& /* dummy */ ) {
+        objectNotFound = true;
+      }
+      CPPUNIT_ASSERT_MESSAGE( "no objects", objectNotFound );
+      
+      try {
+        folder->flushStorageBuffer();
+      } catch ( RelationalException& e ) {
+        cout << e.message() << endl;
+        throw;
+      }
+      
+      IObjectPtr obj0 = folder->findObject( 0 );
+      CPPUNIT_ASSERT_MESSAGE( "object 1 found", obj0.get() != 0 );
+      IObjectPtr obj1 = folder->findObject( 1 );
+      CPPUNIT_ASSERT_MESSAGE( "object 1 found", obj1.get() != 0 );
+    }
+    
+    
+		/// Tests reading back of a folder from a db handle that went out of scope
+		void test_access_outofscope_db() {
+      IFolderPtr folder;
+      
+      {
+        IDatabaseSvc& dbSvc = DatabaseSvcFactory::databaseService();
+        IDatabasePtr db1 = dbSvc.openDatabase( connectString, false );
+        folder = db1->createFolder( "/myfolder", payloadSpec1 );
+        // db1 isgoing of of scope here but folder keeps 
+        // its own handle to the db
+      }
+      
+      folder->storeObject( 0, 2, dummyPayload( 1 ) );
+    }
+		
+    
+		/// Tests reading back of an Object from a deleted MV folder
+		void test_findObject_after_dropNode_MV() {
+      IFolderPtr folder = db->createFolder( "/myfolder", 
+                                            payloadSpec1,
+                                            "my description",
+                                            FolderVersioning::MULTI_VERSION);
+      folder->storeObject( 0, 2, dummyPayload( 1 ) );
+      db->dropNode( "/myfolder" );
+      
+      // this is expected to throw a FolderNotFound exception
+      IObjectPtr obj = folder->findObject( 1 );
+    }
+    
+    
+		/// Tests reading back of an Object from a SV deleted folder
+		void test_findObject_after_dropNode_SV() {
+      IFolderPtr folder = db->createFolder( "/myfolder", payloadSpec1 );
+      folder->storeObject( 0, 2, dummyPayload( 1 ) );
+      db->dropNode( "/myfolder" );
+      
+      // this is expected to throw a FolderNotFound exception
+      IObjectPtr obj = folder->findObject( 1 );
+    }
+    
+
+    /// Tests reading back of an Object from a channel that does not exist
+    void test_findObject_wrongChannel() {
+      IFolderPtr folder = db->createFolder( "/myfolder", payloadSpec1 );
+      ChannelId channel1 = 1;
+      ChannelId channel2 = 2;
+      folder->storeObject( 0, 2, dummyPayload( 1 ), channel1 );
+      folder->storeObject( 2, 4, dummyPayload( 2 ), channel1 );      
+      try {
+        // This is expected to throw an exception
+        IObjectPtr obj1 = folder->findObject( 1, channel2 );
+      } catch ( seal::Exception& /*e*/ ) {
+        //std::cout << "Exception caught: " << e.message() << std::endl;
+        throw;
+      }
+    }
+		
+    
+		/// Tests storing and reading back of an Object in a MultiVersion folder
+    /// This test is implemented in more detail with respect to the object
+    /// attributes in test_RalDatabase
+		void test_findObject_MV() {
+      IFolderPtr folder = db->createFolder( "/myfolder", 
+                                            payloadSpec1,
+                                            "my description",
+                                            FolderVersioning::MULTI_VERSION );
+      
+      folder->storeObject( 0, 2, dummyPayload( 1 ) );
+      folder->storeObject( 2, 4, dummyPayload( 2 ) );
+      
+      IObjectPtr obj1 = folder->findObject( 1 );
+      CPPUNIT_ASSERT_MESSAGE( "first object",
+                              dummyPayload( 1 ) == obj1->payload() );
+      
+      IObjectPtr obj2 = folder->findObject( 3 );
+      CPPUNIT_ASSERT_MESSAGE( "second object",
+                              dummyPayload( 2 ) == obj2->payload() );
+		}
+		
+    
+		/// Tests storing and reading back of an Object
+    /// This test is implemented in more detail with respect to the object
+    /// attributes in test_RalDatabase
+		void test_findObject() {
+      IFolderPtr folder = db->createFolder( "/myfolder", payloadSpec1 );
+      
+      folder->storeObject( 0, 2, dummyPayload( 1 ) );
+      folder->storeObject( 2, 4, dummyPayload( 2 ) );
+      
+      IObjectPtr obj1 = folder->findObject( 1 );
+      CPPUNIT_ASSERT_MESSAGE( "first object",
+                              dummyPayload( 1 ) == obj1->payload() );
+      
+      IObjectPtr obj2 = folder->findObject( 3 );
+      CPPUNIT_ASSERT_MESSAGE( "second object",
+                              dummyPayload( 2 ) == obj2->payload() );
+		}
+		
+    
+    /// Tests creating and retrieving a folder.
+    /// This test is implemented in more detail with respect to the folder
+    /// attributes in test_RalDatabase
+    void test_getFolder() {
+      try {
+        string folderName( "/myfolder" );
+        db->createFolder( folderName, payloadSpec1, "a description" );
+        
+        IFolderPtr folder = db->getFolder( folderName );
+        CPPUNIT_ASSERT( folder.get() != 0 );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE
+          ( "name", folderName, folder->fullPath() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE
+          ( "description", string( "a description" ), folder->description() );
+        CPPUNIT_ASSERT_MESSAGE
+          ( "isLeaf", folder->isLeaf() );
+        CPPUNIT_ASSERT_MESSAGE
+          ( "isStored", folder->isStored() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE
+          ( "insertionTime", string("yyyy-mm-dd_hh:mm:ss.nnnnnnnnn GMT").size(), 
+            timeToString(folder->insertionTime()).size() );    
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "id", 1ul, folder->id() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "parentId", 0ul, folder->parentId() );
+        
+      } catch ( Exception& e ) {
+        cout << e.message() << endl;
+        e.rethrow();
+      }
+    }
+    
+    
+    /// Creates a dummy payload AttributeList for a given index
+    AttributeList dummyPayload( int index ) {
+      AttributeList payload( payloadSpec1 );
+      payload["I"].setValue<int>( index );
+      stringstream s;
+      s << "Object " << index;
+      payload["S"].setValue<std::string>( s.str() );
+      payload["X"].setValue<float>( (float)(index/1000.) );
+      return payload;
+    }
+		
+    void setUp() {
+      /*      
+      try {
+        
+        if ( payloadSpec1.size() == 0 ) {
+          payloadSpec1.push_back("I","int");
+          payloadSpec1.push_back("S","string");
+          payloadSpec1.push_back("X","float");
+        }
+        
+        if ( getenv( COOLTESTDB ) ) {
+          connectString = getenv( COOLTESTDB );
+        } else {
+          cout << "Please provide a connect string by specifying "
+               << "one in the environment variable COOLTESTDB, e.g." 
+               << endl;
+          cout << "setenv COOLTESTDB "
+               << "\"oracle://devdb10;schema=lcg_cool;dbname=COOLTEST\"" 
+               << endl;
+          cout << "Aborting test" << endl;
+          exit(-1);
+        }
+      
+        IDatabaseSvc& dbSvc = DatabaseSvcFactory::databaseService();
+        dbSvc.dropDatabase( connectString );
+        db = dbSvc.createDatabase( connectString );
+
+      } catch ( seal::Exception& e ) {
+        cout << e.message() << endl;
+        throw;
+      }
+      */      
+    }
+		
+		void tearDown() {
+		}
+    
+};
+
+CPPUNIT_TEST_SUITE_REGISTRATION( RelationalFolderTest );
+
+} // namespace
+
+// sas: This file is from the OPAL package I believe. It allows for
+// shorter test classes and prepares the test class for OPAL
+#include<CppUnit_testdriver.icpp>
+
+
diff --git a/RelationalCool/tests/RelationalFolderSet/test_RelationalFolderSet.cpp b/RelationalCool/tests/RelationalFolderSet/test_RelationalFolderSet.cpp
new file mode 100644
index 000000000..9d39febf4
--- /dev/null
+++ b/RelationalCool/tests/RelationalFolderSet/test_RelationalFolderSet.cpp
@@ -0,0 +1,332 @@
+/**
+ 
+ @file test_RelationalFolderSet.cpp
+ 
+ @author Sven A. Schmidt and Andrea Valassi
+ 
+ @date 2005-06-08
+ 
+ */
+
+#include "../Common/CppUnit_headers.h" // Disable CppUnit header warnings
+
+#include "src/CoralApplication.h"
+
+#include "CoolKernel/IDatabase.h"
+#include "CoolKernel/IDatabaseSvc.h"
+#include "CoolKernel/IFolder.h"
+#include "CoolKernel/IFolderSet.h"
+#include "CoolKernel/Record.h"
+#include "CoolKernel/RecordSpecification.h"
+#include "CoolKernel/types.h"
+
+#include "CoralBase/AttributeList.h"
+#include "CoralBase/Attribute.h"
+using coral::AttributeList;
+
+#include <iostream>
+
+#include <string>
+using std::cout;
+using std::endl;
+using std::string;
+using std::stringstream;
+
+#include <vector>
+using std::vector;
+
+#include "src/timeToString.h"
+
+namespace cool {
+
+const char* COOLTESTDB = "COOLTESTDB";
+
+//! \brief RelationalFolderSet test class.
+class RelationalFolderSetTest : public CppUnit::TestFixture {
+		
+  CPPUNIT_TEST_SUITE( RelationalFolderSetTest );
+
+  CPPUNIT_TEST( test_getFolderSet );
+  
+  CPPUNIT_TEST( test_listFolders );
+  CPPUNIT_TEST( test_listFolderSets );
+
+  CPPUNIT_TEST( test_setDescription );
+
+  CPPUNIT_TEST( test_dropNode_nonempty_folderset );
+  
+  CPPUNIT_TEST( test_setTagDescription );
+  CPPUNIT_TEST( test_setTagDescription_bug33989 );
+  
+  CPPUNIT_TEST_SUITE_END();
+		
+public:
+			
+  string connectString;
+  IDatabasePtr db;
+  
+  RecordSpecification payloadSpec;
+  
+  
+  void test_setTagDescription_bug33989() 
+  {
+    IFolderSetPtr fsetroot = db->getFolderSet("/");
+    IFolderSetPtr fset = db->createFolderSet("/A");
+    IFolderPtr f = db->createFolder("/A/f1", payloadSpec, "", 
+                                    FolderVersioning::MULTI_VERSION);
+    f->storeObject(0, 2, dummyPayload(0), 0);
+    f->tagCurrentHead("F1");
+    f->createTagRelation("A", "F1");
+    try
+    { 
+      f->setTagDescription("A", "new desc"); // should fail!
+      CPPUNIT_FAIL( "setTagDescription from child should fail!" );
+    }
+    catch( Exception& /*e*/ ){}
+    try
+    { 
+      fsetroot->setTagDescription("A", "new desc"); // should fail!
+      CPPUNIT_FAIL( "setTagDescription from parent should fail!" );
+    }
+    catch( Exception& /*e*/ ){}
+  }
+  
+  void test_setTagDescription() {
+    IFolderSetPtr fsetroot = db->getFolderSet("/");
+    IFolderSetPtr fset = db->createFolderSet("/A");
+    IFolderPtr f = db->createFolder("/A/f1", payloadSpec, "", 
+                                    FolderVersioning::MULTI_VERSION);
+    f->storeObject(0, 2, dummyPayload(0), 0);
+    f->tagCurrentHead("F1");
+    f->createTagRelation("A", "F1");
+    CPPUNIT_ASSERT_EQUAL(std::string(""), fset->tagDescription("A"));
+    //f->setTagDescription("A", "new desc"); // should fail!
+    fset->setTagDescription("A", "new desc");
+    CPPUNIT_ASSERT_EQUAL(std::string("new desc"), fset->tagDescription("A"));
+    fset->createTagRelation("ROOT", "A");
+    CPPUNIT_ASSERT_EQUAL(std::string(""), fsetroot->tagDescription("ROOT"));
+    //f->setTagDescription("ROOT", "new desc2"); // should fail!
+    fsetroot->setTagDescription("ROOT", "new desc2");
+    CPPUNIT_ASSERT_EQUAL(std::string("new desc2"), fsetroot->tagDescription("ROOT"));
+  }
+  
+    
+    /// Tests behavior of dropNode being called on a nonempty folder set
+    void test_dropNode_nonempty_folderset() {
+      // Test dropping with a contained folderset
+      db->createFolderSet( "/folderset_1" );
+      db->createFolderSet( "/folderset_1/folderset_1" );
+
+      try {
+        db->dropNode( "/folderset_1" );
+      } catch ( Exception& e ) {
+        CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "error message (containing folderset)",
+          string( "Cannot drop folderset '/folderset_1', "
+                  "because it is not empty" ),
+          string( e.what() ) );
+      }
+
+      // Test dropping with a contained folder
+      db->createFolderSet( "/folderset_2" );
+      db->createFolder( "/folderset_2/folder", payloadSpec );
+    
+      try {
+        db->dropNode( "/folderset_2" );
+      } catch ( Exception& e ) {
+        CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "error message (containing folderset)",
+          string( "Cannot drop folderset '/folderset_2', "
+                  "because it is not empty" ),
+          string( e.what() ) );
+      }
+    }
+    
+    
+    /// Tests updating the folder description
+    void test_setDescription() {
+    {
+      IFolderSetPtr folderset = db->createFolderSet( "/myfolderset", 
+                                                     "a description" );
+      folderset->setDescription( "new description" );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "internal desc update",
+                                    string( "new description" ),
+                                    folderset->description() );
+    }
+      {
+        IFolderSetPtr folderset = db->getFolderSet( "/myfolderset" );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "db desc update",
+                                      string( "new description" ),
+                                      folderset->description() );
+      }        
+    }
+    
+    /// Tests listFolderSets
+    void test_listFolderSets() {
+      try {
+        IFolderSetPtr folderset = db->createFolderSet( "/folderset" );
+        db->createFolderSet( "/folderset/folderset_2" );
+        db->createFolderSet( "/folderset/folderset_3" );
+        db->createFolderSet( "/folderset/folderset_1" );
+        db->createFolder( "/folderset/folder", payloadSpec );
+        
+        bool ascending = true;
+        vector<string> foldersets = folderset->listFolderSets( ascending );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE
+          ( "folderset count", 3u, (unsigned int)foldersets.size() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE
+          ( "folderset_1", string( "/folderset/folderset_1" ), foldersets[0] );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE
+          ( "folderset_2", string( "/folderset/folderset_2" ), foldersets[1] );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE
+          ( "folderset_3", string( "/folderset/folderset_3" ), foldersets[2] );
+        
+        ascending = false;
+        foldersets = folderset->listFolderSets( ascending );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE
+          ( "folderset_1", string( "/folderset/folderset_3" ), foldersets[0] );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE
+          ( "folderset_2", string( "/folderset/folderset_2" ), foldersets[1] );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE
+          ( "folderset_3", string( "/folderset/folderset_1" ), foldersets[2] );
+        
+      } catch ( std::exception& e ) {
+        cout << e.what() << endl;
+        throw;
+      }
+    }
+    
+    
+    
+    /// Tests listFolders
+    void test_listFolders() {
+      try {
+      IFolderSetPtr folderset = db->createFolderSet( "/folderset" );
+      db->createFolder( "/folderset/folder_2", payloadSpec );
+      db->createFolder( "/folderset/folder_3", payloadSpec );
+      db->createFolder( "/folderset/folder_1", payloadSpec );
+      db->createFolderSet( "/folderset/folderset" );
+      
+      bool ascending = true;
+      vector<string> folders = folderset->listFolders( ascending );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "folder count", 3u, (unsigned int)folders.size() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "folder_1", string( "/folderset/folder_1" ), folders[0] );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "folder_2", string( "/folderset/folder_2" ), folders[1] );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "folder_3", string( "/folderset/folder_3" ), folders[2] );
+
+      ascending = false;
+      folders = folderset->listFolders( ascending );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "folder_1", string( "/folderset/folder_3" ), folders[0] );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "folder_2", string( "/folderset/folder_2" ), folders[1] );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "folder_3", string( "/folderset/folder_1" ), folders[2] );
+      
+      } catch ( std::exception& e ) {
+        cout << e.what() << endl;
+        throw;
+      }
+    }
+
+    
+    
+    /// Tests creating and retrieving a folderset.
+    void test_getFolderSet() {
+      try {
+      db->createFolderSet( "/folderset", "a description" );
+      
+      IFolderSetPtr folderset = db->getFolderSet( "/folderset" );
+      CPPUNIT_ASSERT( folderset.get() != 0 );
+
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "name", string( "/folderset" ), folderset->fullPath() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "description", string( "a description" ), folderset->description() );
+      CPPUNIT_ASSERT_MESSAGE
+        ( "isLeaf", ! folderset->isLeaf() );
+      CPPUNIT_ASSERT_MESSAGE
+        ( "isStored", folderset->isStored() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "insertionTime", string("yyyy-mm-dd_hh:mm:ss.nnnnnnnnn GMT").size(), 
+          timeToString(folderset->insertionTime()).size() );    
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "id", 1u, folderset->id() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "parentId", 0u, folderset->parentId() );
+
+      } catch ( Exception& e ) {
+        cout << e.what() << endl;
+        throw;
+      }
+    }
+    
+        
+    
+    
+    /// Creates a dummy payload AttributeList for a given index
+    Record dummyPayload( int index ) 
+    {
+      Record payload( payloadSpec );
+      payload["I"].setValue<Int32>( index );
+      std::stringstream s;
+      s << "Object " << index;
+      payload["S"].setValue<String255>( s.str() );
+      payload["X"].setValue<Float>( (float)(index/1000.) );
+      return payload;
+    }
+		
+    RelationalFolderSetTest() 
+      : payloadSpec() {
+        
+        payloadSpec.extend("I",StorageType::Int32);
+        payloadSpec.extend("S",StorageType::String255);
+        payloadSpec.extend("X",StorageType::Float);
+        
+        if ( getenv( COOLTESTDB ) ) {
+          connectString = getenv( COOLTESTDB );
+        } else {
+          std::cout << "Please provide a connect string by "
+          << "specifying one in the environment variable COOLTESTDB, e.g." 
+          << std::endl;
+          std::cout << "setenv COOLTESTDB "
+          << "\"oracle://devdb10;schema=lcg_cool;dbname=COOLTEST\"" << std::endl;
+          std::cout << "Aborting test" << std::endl;
+          exit(-1);
+        }
+      }
+    
+    ~RelationalFolderSetTest() {}
+    
+    void setUp() {
+      try 
+      {
+        CoralApplication app;
+        IDatabaseSvc& dbSvc = app.databaseService();
+        dbSvc.dropDatabase( connectString );
+        db = dbSvc.createDatabase( connectString );        
+      } 
+      catch ( std::exception& e ) 
+      {
+        cout << e.what() << endl;
+        throw;
+      }
+    }
+		
+		void tearDown() {
+      db.reset();
+		}
+    
+};
+
+CPPUNIT_TEST_SUITE_REGISTRATION( RelationalFolderSetTest );
+
+} // namespace
+
+// sas: This file is from the OPAL package I believe. It allows for
+// shorter test classes and prepares the test class for OPAL
+#include<CppUnit_testdriver.icpp>
+
+
diff --git a/RelationalCool/tests/RelationalObjectIterator/test_RelationalObjectIterator.cpp b/RelationalCool/tests/RelationalObjectIterator/test_RelationalObjectIterator.cpp
new file mode 100644
index 000000000..04b2adf81
--- /dev/null
+++ b/RelationalCool/tests/RelationalObjectIterator/test_RelationalObjectIterator.cpp
@@ -0,0 +1,585 @@
+// $Id: test_RelationalObjectIterator.cpp,v 1.2 2008-10-30 16:07:41 avalassi Exp $
+/**
+
+ @file test_RalObjectIterator.cpp
+ 
+ @author Core Team
+ 
+ @date 2005-10-21
+
+ */
+
+#include "../Common/CppUnit_headers.h" // Disable CppUnit header warnings
+
+#include "src/CoralApplication.h"
+
+#include "CoolKernel/IDatabase.h"
+#include "CoolKernel/IDatabaseSvc.h"
+#include "CoolKernel/IFolder.h"
+#include "CoolKernel/IObject.h"
+#include "CoolKernel/IObjectIterator.h"
+#include "CoolKernel/Record.h"
+#include "CoolKernel/RecordSpecification.h"
+#include "CoralBase/Attribute.h"
+
+#include "../Performance/Benchmark.h"
+#include "../../src/attributeListToString.h"
+#include "../../src/IteratorException.h"
+
+// ---- these things are needed to force a drop of the connection
+#include "src/RalDatabaseSvc.h"
+#include "RelationalAccess/IConnectionService.h"
+#include "RelationalAccess/IConnectionServiceConfiguration.h"
+
+using coral::AttributeList;
+
+#include <string>
+using std::cout;
+using std::endl;
+using std::string;
+using std::stringstream;
+
+namespace cool {
+  
+  const char* COOLTESTDB = "COOLTESTDB";
+  
+/**
+ RalObjectIterator test class
+*/
+ 
+class RalObjectIteratorTest : public CppUnit::TestFixture {
+		
+  CPPUNIT_TEST_SUITE( RalObjectIteratorTest );
+
+  CPPUNIT_TEST( test_browseObjects );
+  CPPUNIT_TEST( test_begin );
+  CPPUNIT_TEST( test_iterator_prefix_increment );
+  CPPUNIT_TEST( test_end );
+  CPPUNIT_TEST( test_for_loop );
+  CPPUNIT_TEST( test_cursor_read_concurrency );
+  CPPUNIT_TEST( test_cursor_read_concurrency2 );
+  CPPUNIT_TEST( test_cursor_write_concurrency );
+  CPPUNIT_TEST( test_goToNext );
+  CPPUNIT_TEST( test_close );
+  CPPUNIT_TEST( test_destructor );
+  CPPUNIT_TEST( test_reverse );
+
+  CPPUNIT_TEST( test_bug36646 );
+
+  CPPUNIT_TEST_SUITE_END();
+		
+public:
+  
+  // PORT This is a workaround to ease migration. We need to review the 
+  // whole ALS issue (best eliminate it)
+  RecordSpecification payloadSpec;
+  string connectString;
+  IDatabasePtr db;
+  IFolderPtr folder;
+  
+  
+  /// Test for bug #36646 in ConstRecordAdapter
+  void test_bug36646() 
+  { 
+    IFolderPtr folder = db->createFolder( "/myfolder", payloadSpec );
+    folder->storeObject( 0, 2, dummyPayload( 1 ), 0 );
+    folder->setPrefetchAll( false );
+    IObjectIteratorPtr objs = 
+      folder->browseObjects( 0, 10, ChannelSelection::all() );
+    objs->goToNext();
+    const IObject& obj1 = objs->currentRef();
+    CPPUNIT_ASSERT_MESSAGE
+      ( "first object", dummyPayload( 1 ) == obj1.payload() );
+    const IRecord& p = obj1.payload();
+    const coral::AttributeList& a = p.attributeList();
+    try 
+    {  
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "payload IRecord.size == AttributeList.size", 
+          (int)p.specification().size(), (int)a.size() );
+    }
+    catch( ... )
+    {
+      std::cout << "\npayload(): " << p << std::endl; 
+      std::cout << "payload().attributeList(): " 
+                << attributeListToString(a) << std::endl; 
+      throw;
+    }
+  }
+
+  IObjectPtr getNext( IObjectIteratorPtr objs) {
+        if (!objs->goToNext())
+                CPPUNIT_FAIL("no next object");
+        return IObjectPtr( objs->currentRef().clone() );
+  }
+
+  /// Tests basic reverse iterator behavior. 
+  /// More complex scenarios are tested in higher level tests.
+  void test_reverse() {
+    ChannelSelection ch( 0, 0, ChannelSelection::sinceDescBeforeChannel );
+    IObjectIteratorPtr objs = folder->browseObjects( 0, 30, ch, "" );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "object count", 
+                                  3u, (unsigned int)objs->size() );
+    IObjectPtr iter = getNext(objs);
+    CPPUNIT_ASSERT_MESSAGE( "obj 2 payload", 
+                            dummyPayload( 2 ) == iter->payload() );
+    iter = getNext(objs);
+    CPPUNIT_ASSERT_MESSAGE( "obj 1 payload", 
+                            dummyPayload( 1 ) == iter->payload() );
+    iter = getNext(objs);
+    CPPUNIT_ASSERT_MESSAGE( "obj 0 payload", 
+                            dummyPayload( 0 ) == iter->payload() );
+  }
+  
+  
+  /// Tests that the destructor ends the transaction
+  void test_destructor() {
+    try {
+      folder->setPrefetchAll( false );
+      IObjectIteratorPtr objs = folder->browseObjects( 5, 25, 0 );
+      IObjectIteratorPtr null;
+      //std::cout << "Delete iterator" << std::endl;
+      objs = null;
+      //std::cout << "Deleted iterator" << std::endl;
+      objs = folder->browseObjects( 5, 25, 0 );
+      CPPUNIT_ASSERT_MESSAGE( "goToNext", objs->goToNext() );
+    } catch ( std::exception& e ) {
+      std::cout << "Exception caught: " << e.what() << std::endl;
+      throw;     
+    }
+  }
+
+
+  /// Tests that close ends the transaction
+  void test_close() {
+    try {
+      folder->setPrefetchAll( false );
+      IObjectIteratorPtr objs = folder->browseObjects( 5, 25, 0 );
+      //std::cout << "Close iterator" << std::endl;
+      objs->close();
+      //std::cout << "Closed iterator" << std::endl;
+      objs = folder->browseObjects( 5, 25, 0 );
+      CPPUNIT_ASSERT_MESSAGE( "goToNext", objs->goToNext() );
+    } catch ( std::exception& e ) {
+      std::cout << "Exception caught: " << e.what() << std::endl;
+      throw;     
+    }
+  }
+  
+  
+  /// Test goToNext
+  void test_goToNext() {
+    IObjectIteratorPtr objs = folder->browseObjects( 5, 25, 0 );
+    CPPUNIT_ASSERT_MESSAGE( "goToNext", objs->goToNext() );
+  }
+
+
+  void test_browse_performance() {
+    folder->setPrefetchAll( false );
+    int nObjs = 100;
+    IFolderPtr folder = db->createFolder( "/myfolder", payloadSpec );
+    
+    {
+      folder->setupStorageBuffer();
+      
+      for ( int i = 0; i < nObjs; ++i ) {
+        folder->storeObject( i, ValidityKeyMax, dummyPayload( i ), 0 );
+      }
+      
+      folder->flushStorageBuffer();
+      
+    }
+    
+    if (1) {
+      Benchmark b;
+      b.start();
+      
+      IObjectIteratorPtr objs = 
+        folder->browseObjects( ValidityKeyMin, ValidityKeyMax, 0 );
+      
+      int nReadObjects = 0;
+      //for ( IObjectIterator::const_iterator 
+      //      i = objs->begin(); i != objs->end(); ++i ) {
+      //  ++nReadObjects;
+      //}
+      while ( objs->goToNext() ) {
+        ++nReadObjects;
+      }
+      
+      double secElapsed = b.stop();
+      
+      cout << "** browsing " << nObjs << " objects **" << endl;
+      cout << "read back " << nReadObjects << " objects" << endl;
+      cout << "sec total: " << secElapsed << endl;
+      cout << "obj/s:     " << nReadObjects/secElapsed << endl;
+    }
+
+    /*
+    if (1) {
+      Benchmark b;
+      b.start();
+      
+      IObjectIteratorPtr objs = 
+        folder->browseObjects( ValidityKeyMin, ValidityKeyMax, 0, "" );
+      
+      long nReadObjects = objs->size();
+      
+      double secElapsed = b.stop();
+      
+      cout << "** reading " << nObjs << " objects **" << endl;
+      cout << "read back " << nReadObjects << " objects" << endl;
+      cout << "sec total: " << secElapsed << endl;
+      cout << "obj/s:     " << nReadObjects/secElapsed << endl;
+    }
+     */
+
+  }
+
+  
+  /// Tests behavior of a cursor with a concurrent write operation.
+  void test_cursor_write_concurrency() {
+    folder->setPrefetchAll( false );
+    IObjectIteratorPtr objs1 = folder->browseObjects( 5, 25, 0 );
+    objs1->goToNext();
+    try {
+      folder->storeObject( 0, 2, dummyPayload( 0 ), 0 );
+      CPPUNIT_FAIL( "exception expected" );
+    } catch ( std::exception& e ) {
+      CPPUNIT_ASSERT_EQUAL
+      ( string( "Cannot start a concurrent write transaction" ),
+        string( e.what() ) );
+    }
+  }
+  
+  
+  /// Tests behavior of concurrent read-only cursors.
+  void test_cursor_read_concurrency() 
+  {
+    bool debug = false;
+    folder->setPrefetchAll( false );
+    
+    IObjectIteratorPtr objs1 = folder->browseObjects( 5, 25, 0 );
+    if ( debug ) std::cout << "1st iterator started" << std::endl;
+
+    try 
+    {
+      IObjectIteratorPtr objs2 = folder->browseObjects( 5, 25, 0 );
+      if ( debug ) std::cout << "2nd iterator started" << std::endl;
+      CPPUNIT_FAIL( "Should not be able to retrieve/start 2nd iterator" );
+  
+      // What follows is the old COOL210 test 
+      // (which succeeded before fixing bug #25151)
+      IObjectPtr obj;    
+      CPPUNIT_ASSERT( objs1->goToNext() );
+      obj = IObjectPtr( objs1->currentRef().clone() );
+      CPPUNIT_ASSERT( dummyPayload( 0 ) == obj->payload() );    
+      if ( debug ) std::cout << "1st iterator: next() executed" << std::endl;
+      
+      CPPUNIT_ASSERT( objs2->goToNext() );
+      obj = IObjectPtr( objs2->currentRef().clone() );
+      CPPUNIT_ASSERT( dummyPayload( 0 ) == obj->payload() );    
+      if ( debug ) std::cout << "2nd iterator: next() executed" << std::endl;
+      
+      CPPUNIT_ASSERT( objs1->goToNext() );
+      obj = IObjectPtr( objs1->currentRef().clone() );
+      CPPUNIT_ASSERT( dummyPayload( 1 ) == obj->payload() );    
+      if ( debug ) std::cout << "1st iterator: next() executed" << std::endl;
+      
+      CPPUNIT_ASSERT( objs2->goToNext() );
+      obj = IObjectPtr( objs2->currentRef().clone() );
+      CPPUNIT_ASSERT( dummyPayload( 1 ) == obj->payload() );    
+      if ( debug ) std::cout << "2nd iterator: next() executed" << std::endl;
+      
+      CPPUNIT_ASSERT( objs1->goToNext() );
+      obj = IObjectPtr( objs1->currentRef().clone() );
+      CPPUNIT_ASSERT( dummyPayload( 2 ) == obj->payload() );    
+      if ( debug ) std::cout << "1st iterator: next() executed" << std::endl;
+      
+      CPPUNIT_ASSERT( objs2->goToNext() );
+      obj = IObjectPtr( objs2->currentRef().clone() );
+      CPPUNIT_ASSERT( dummyPayload( 2 ) == obj->payload() );
+      if ( debug ) std::cout << "2nd iterator: next() executed" << std::endl;
+    }
+    catch ( TooManyIterators& ){}
+  }
+  
+  
+  /// Tests behavior of concurrent read-only cursors
+  /// (when one is closed before the end).
+  /// This fails catastrophically (abort and stack trace) in COOL210.
+  void test_cursor_read_concurrency2() 
+  {
+    bool debug = false;
+    folder->setPrefetchAll( false );
+    
+    IObjectIteratorPtr objs1 = folder->browseObjects( 5, 25, 0 );
+    if ( debug ) std::cout << "1st iterator started" << std::endl;
+
+    try 
+    {
+      IObjectIteratorPtr objs2 = folder->browseObjects( 5, 25, 0 );
+      if ( debug ) std::cout << "2nd iterator started" << std::endl;
+      CPPUNIT_FAIL( "Should not be able to retrieve/start 2nd iterator" );
+  
+      // What follows is the old COOL210 test 
+      // (which succeeded before fixing bug #25151)
+      IObjectPtr obj;
+      CPPUNIT_ASSERT( objs1->goToNext() );
+      obj = IObjectPtr( objs1->currentRef().clone() );
+      CPPUNIT_ASSERT( dummyPayload( 0 ) == obj->payload() );    
+      if ( debug ) 
+        std::cout << "1st iterator: currentRef().clone() executed" << std::endl;
+      
+      CPPUNIT_ASSERT( objs2->goToNext() );
+      obj = IObjectPtr( objs2->currentRef().clone() );
+      CPPUNIT_ASSERT( dummyPayload( 0 ) == obj->payload() );    
+      if ( debug ) 
+        std::cout << "2nd iterator: currentRef().clone() executed" << std::endl;
+      
+      CPPUNIT_ASSERT( objs1->goToNext() );
+      obj = IObjectPtr( objs1->currentRef().clone() );
+      CPPUNIT_ASSERT( dummyPayload( 1 ) == obj->payload() );    
+      if ( debug ) 
+        std::cout << "1st iterator: currentRef().clone() executed" << std::endl;
+      
+      CPPUNIT_ASSERT( objs2->goToNext() );
+      objs2->close();
+      if ( debug ) 
+        std::cout << "2nd iterator: close() executed" << std::endl;
+      
+      CPPUNIT_ASSERT( objs1->goToNext() );
+      obj = IObjectPtr( objs1->currentRef().clone() );
+      CPPUNIT_ASSERT( dummyPayload( 2 ) == obj->payload() );    
+      if ( debug ) 
+        std::cout << "1st iterator: currentRef().clone() executed" << std::endl;
+    }
+    catch ( TooManyIterators& ){}
+  }
+  
+  
+  /// Tests correct for-loop behavior.
+  void test_for_loop() {
+    folder->setPrefetchAll( false );
+    IObjectIteratorPtr objs = folder->browseObjects( 5, 25, 0 );
+    
+    int loop_count = 0;
+    //for ( IObjectIterator::const_iterator 
+    //      obj = objs->begin(); obj != objs->end(); ++obj ) {
+    while ( objs->goToNext() ) {
+      IObjectPtr obj( objs->currentRef().clone() );
+      CPPUNIT_ASSERT_MESSAGE
+        ( "obj payload", dummyPayload( loop_count ) == obj->payload() );
+      ++loop_count;
+    }
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "loop count", 3, loop_count );
+  }    
+  
+  
+  
+  /// Tests that the iterator correctly points at the end after the container
+  /// has been exhausted.
+  void test_end()  {
+    folder->setPrefetchAll( false );
+    try {
+      IObjectIteratorPtr objs = folder->browseObjects( 5, 25, 0 );      
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "object count", 3u, (unsigned int)objs->size() );
+      //IObjectIterator::const_iterator iter = objs->begin();
+      objs->goToNext();
+      //CPPUNIT_ASSERT_MESSAGE
+      //  ( "Iterator different from end()", iter != objs->end() );
+      //CPPUNIT_ASSERT_MESSAGE
+      //  ( "Iterator different from end()", objs->hasNext() );
+      //++iter;
+      //++iter;
+      //++iter;
+      objs->goToNext();    
+      objs->goToNext();    
+      //objs->next(); // next() can be called ONLY three times!    
+      //CPPUNIT_ASSERT_MESSAGE
+      //  ( "Iterator pointing at end", iter == objs->end() );
+      CPPUNIT_ASSERT_MESSAGE
+        ( "Iterator pointing at end", !objs->goToNext() );
+      try {
+        objs->currentRef(); // goToNext() can be called ONLY three times!
+        CPPUNIT_FAIL( "exception expected" );
+      } catch ( IteratorHasNoCurrentItem& ) {
+      } catch ( std::exception& e ) {
+        CPPUNIT_FAIL
+          ( "Exception caught (IteratorHasNoCurrentItem expected): " + 
+            std::string( e.what() ) );
+      } catch ( ... ) {
+        CPPUNIT_FAIL
+          ( "Unknown exception caught, IteratorHasNoNextItem expected" );
+      }
+    } catch ( std::exception& e ) {
+      std::cout << "Exception caught: " << e.what() << std::endl;
+      throw;     
+    }
+  }
+  
+  
+  /// Tests that prefix operator++ correctly iterates through the container.
+  void test_iterator_prefix_increment()  {
+    folder->setPrefetchAll( false );
+    IObjectIteratorPtr objs = folder->browseObjects( 5, 25, 0 );
+    
+    CPPUNIT_ASSERT_EQUAL_MESSAGE
+      ( "object count", 3u, (unsigned int)objs->size() );
+    
+    //IObjectIterator::const_iterator iter = objs->begin();
+    IObjectPtr iter;
+
+    //++iter;
+    iter=getNext( objs );
+    CPPUNIT_ASSERT_MESSAGE( "obj 1.1 payload", 
+                            dummyPayload( 0 ) == iter->payload() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 1.1 since",
+                                  (ValidityKey)0, iter->since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 1.1 until",
+                                  (ValidityKey)10, iter->until() );
+
+    //++iter;
+    iter = getNext( objs );
+    CPPUNIT_ASSERT_MESSAGE( "obj 1.2 payload", 
+                            dummyPayload( 1 ) == iter->payload() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 1.2 since",
+                                  (ValidityKey)10, iter->since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 1.2 until",
+                                  (ValidityKey)20, iter->until() );
+    
+    //++iter;
+    iter= getNext( objs );
+    CPPUNIT_ASSERT_MESSAGE( "obj 1.3 payload", 
+                            dummyPayload( 2 ) == iter->payload() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 1.3 since",
+                                  (ValidityKey)20, iter->since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 1.3 until",
+                                  ValidityKeyMax, iter->until() );
+  }
+  
+  
+  /// Tests that begin returns an iterator pointing at the first item.
+  void test_begin()  
+  {
+    folder->setPrefetchAll( false );
+    try {
+      IObjectIteratorPtr objs = folder->browseObjects( 5, 25, 0 );
+
+      CPPUNIT_ASSERT_MESSAGE( "no cursor", objs != 0 );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "object count", 3u, (unsigned int)objs->size() );
+    
+      //IObjectIterator::const_iterator iter = objs->begin();
+      IObjectPtr iter;
+      iter=getNext( objs );
+      
+      CPPUNIT_ASSERT_MESSAGE( "obj 1.1 payload", 
+                              dummyPayload( 0 ) == iter->payload() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 1.1 since",
+                                    (ValidityKey)0, iter->since() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 1.1 until",
+                                    (ValidityKey)10, iter->until() );
+
+    } catch ( std::exception& e ) {
+      std::cout << "Exception caught: " << e.what() << std::endl;
+      throw;     
+    }
+
+  }      
+  
+
+  /// Tests that browseObjects does not fail
+  /// (if this fails, test_begin will also fail)
+  void test_browseObjects()  
+  {
+    folder->setPrefetchAll( false );
+    try {
+      IObjectIteratorPtr objs = folder->browseObjects( 5, 25, 0 );
+    } catch ( std::exception& e ) {
+      std::cout << "Exception caught: " << e.what() << std::endl;
+      throw;     
+    }
+  }      
+  
+  
+  /// Creates a dummy payload AttributeList for a given index
+  Record dummyPayload( int index ) 
+  {
+    Record payload( payloadSpec );
+    payload["I"].setValue<Int32>( index );
+    std::stringstream s;
+    s << "Object " << index;
+    payload["S"].setValue<String255>( s.str() );
+    payload["X"].setValue<Float>( (float)(index/1000.) );
+    return payload;
+  }
+  
+  RalObjectIteratorTest()
+    : payloadSpec() {
+
+      payloadSpec.extend("I",StorageType::Int32);
+      payloadSpec.extend("S",StorageType::String255);
+      payloadSpec.extend("X",StorageType::Float);
+      
+      if ( getenv( COOLTESTDB ) ) {
+        connectString = getenv( COOLTESTDB );
+      } else {
+        cout << "Please provide a connect string by "
+        << "specifying one in the environment variable COOLTESTDB, e.g." 
+        << endl;
+        cout << "setenv COOLTESTDB "
+          << "\"oracle://devdb10;schema=lcg_cool;dbname=COOLTEST\"" << endl;
+        cout << "Aborting test" << endl;
+        exit(-1);
+      }
+      
+  }
+  
+  ~RalObjectIteratorTest() {}
+  
+  
+  void setUp() {
+    try {
+      CoralApplication app;
+      IDatabaseSvc& dbSvc = app.databaseService();
+      dbSvc.dropDatabase( connectString );
+      db = dbSvc.createDatabase( connectString );
+      
+      string folderName( "/folder_1" );
+      folder = db->createFolder( folderName, payloadSpec );
+      for ( int i = 0; i < 3; ++i ) {
+        ValidityKey since = i*10;
+        ValidityKey until = ValidityKeyMax;
+        Record payload = dummyPayload( i );
+        folder->storeObject( since, until, payload, 0 );
+      }
+    } catch ( std::exception& e ) {
+      std::cout << "Exception caught: " << e.what() << std::endl;
+      throw;     
+    }
+  }
+
+  void tearDown() {
+    db.reset();
+    folder.reset();
+    // Here I want to purge the connection pool
+    //cool::sleep(1);
+    CoralApplication app;
+    IDatabaseSvc& dbSvc = app.databaseService();
+    RalDatabaseSvc* rdbSvc = dynamic_cast<RalDatabaseSvc*>(&dbSvc);
+    rdbSvc->connectionSvc().configuration().setConnectionTimeOut(-1);
+    rdbSvc->connectionSvc().purgeConnectionPool();
+  }
+  
+};
+
+CPPUNIT_TEST_SUITE_REGISTRATION( RalObjectIteratorTest );
+
+} // namespace
+
+// sas: This file is from the OPAL package I believe. It allows for
+// shorter test classes and prepares the test class for OPAL
+#include<CppUnit_testdriver.icpp>
+
+
diff --git a/RelationalCool/tests/RelationalObjectMgr/test_RelationalObjectMgr.cpp b/RelationalCool/tests/RelationalObjectMgr/test_RelationalObjectMgr.cpp
new file mode 100644
index 000000000..cf0afd4a1
--- /dev/null
+++ b/RelationalCool/tests/RelationalObjectMgr/test_RelationalObjectMgr.cpp
@@ -0,0 +1,4938 @@
+// $Id: test_RelationalObjectMgr.cpp,v 1.3 2008-11-03 15:34:10 avalassi Exp $
+/**
+
+ @file test_RelationalObjectMgr.cpp
+ 
+ @author Sven A. Schmidt
+ 
+ @date 2006-04-19
+
+ */
+
+#include "CoolDBUnitTest.h"
+
+#include "src/HvsTagRecord.h"
+#include "src/RalDatabase.h"
+#include "src/RelationalObjectMgr.h"
+#include "src/RalQueryMgr.h"
+#include "src/RalSequenceMgr.h"
+#include "src/RelationalChannelTable.h"
+#include "src/RelationalObject.h"
+#include "src/RelationalObjectTable.h"
+#include "src/RelationalObjectTableRow.h"
+#include "src/RelationalSequence.h"
+#include "src/RelationalTagMgr.h"
+#include "src/RelationalTransaction.h"
+#include "src/SimpleObject.h"
+#include "src/timeToString.h"
+
+#include "CoolKernel/IObjectIterator.h"
+#include "CoolKernel/IObject.h"
+#include "CoolKernel/types.h"
+
+#include "RelationalAccess/ICursor.h"
+#include "RelationalAccess/ISchema.h"
+#include "RelationalAccess/ITable.h"
+
+using coral::AttributeList;
+using coral::AttributeListSpecification;
+
+#include <string>
+using std::cout;
+using std::endl;
+using std::string;
+#include <sstream>
+using std::stringstream;
+#include <vector>
+using std::vector;
+
+namespace cool 
+{
+
+  inline Time addOneNsToTime( ITime& time ) 
+  {
+    return Time( time.year(),
+                 time.month(),
+                 time.day(),
+                 time.hour(),
+                 time.minute(),
+                 time.second(),
+                 time.nanosecond()+1 );
+  }
+
+class RelationalObjectMgrTest : public CoolDBUnitTest 
+{
+		
+  CPPUNIT_TEST_SUITE( RelationalObjectMgrTest );
+
+  CPPUNIT_TEST( test_bulkUpdateObjectTableIov );
+
+  CPPUNIT_TEST( test_findObject );
+  
+  CPPUNIT_TEST( test_storeObjects_SV );
+  CPPUNIT_TEST( test_storeObjects_SV_different_channel );
+  CPPUNIT_TEST( test_storeObjects_empty_list );
+  CPPUNIT_TEST( test_storeObjects_bulk_100 );
+		
+  CPPUNIT_TEST( test_browseObjects_SV );
+  CPPUNIT_TEST( test_browseObjects_MV );
+  CPPUNIT_TEST( test_browseObjects_SV_reverse );
+  CPPUNIT_TEST( test_browseObjects_MV_reverse );
+  
+  CPPUNIT_TEST( test_mv_UInt64Max_iov );
+  CPPUNIT_TEST( test_sv_UInt64Max_iov );
+  
+  CPPUNIT_TEST( test_storeObjects_bulk_multichannel );
+ 
+  // ------ MV tests ------
+  
+  CPPUNIT_TEST( test_SimpleObject_filter );
+  CPPUNIT_TEST( test_SimpleObject_intersect );
+  CPPUNIT_TEST( test_SimpleObject_visisbleThrough );
+  CPPUNIT_TEST( test_SimpleObject_visisbleThrough2 );
+  
+  CPPUNIT_TEST( test_processMultiVersionObjects_case_0a );
+  CPPUNIT_TEST( test_processMultiVersionObjects_case_0b );
+  CPPUNIT_TEST( test_processMultiVersionObjects_case_1a );
+  CPPUNIT_TEST( test_processMultiVersionObjects_case_1b );
+  CPPUNIT_TEST( test_processMultiVersionObjects_case_1c );
+  CPPUNIT_TEST( test_processMultiVersionObjects_case_2 );
+  CPPUNIT_TEST( test_processMultiVersionObjects_case_3 );
+  CPPUNIT_TEST( test_processMultiVersionObjects_case_4 );
+  CPPUNIT_TEST( test_processMultiVersionObjects_case_5b );
+
+  CPPUNIT_TEST( test_updateObjectTableNewHeadId_1 );
+  CPPUNIT_TEST( test_updateObjectTableNewHeadId_2 );
+  CPPUNIT_TEST( test_updateObjectTableNewHeadId_3 );
+ 
+  // new algo, with prefetch 
+  CPPUNIT_TEST( test_mergeWithHead_case_1a_prefetch );
+  CPPUNIT_TEST( test_mergeWithHead_case_1b_prefetch );
+  CPPUNIT_TEST( test_mergeWithHead_case_3_prefetch );
+  
+  CPPUNIT_TEST( test_storeObjects_MV_newInsert_prefetch );
+  
+  CPPUNIT_TEST( test_storeObjects_MV_case_0a_prefetch );
+  CPPUNIT_TEST( test_storeObjects_MV_case_0b_prefetch );  
+  CPPUNIT_TEST( test_storeObjects_MV_case_1a_prefetch );
+  CPPUNIT_TEST( test_storeObjects_MV_case_2_prefetch );  
+  CPPUNIT_TEST( test_storeObjects_MV_case_3_prefetch );  
+  CPPUNIT_TEST( test_storeObjects_MV_case_4_prefetch );  
+  CPPUNIT_TEST( test_storeObjects_MV_case_5b_prefetch );
+  CPPUNIT_TEST( test_storeObjects_MV_case_6_prefetch );  
+  CPPUNIT_TEST( test_storeObjects_MV_case_0a_channels_prefetch );
+  CPPUNIT_TEST( test_storeObjects_MV_case_5b_6_channels_prefetch );
+  CPPUNIT_TEST( test_storeObjects_MV_identicalIov_case_1_prefetch );
+  CPPUNIT_TEST( test_storeObjects_MV_identicalIov_case_2_prefetch );
+
+#ifndef WIN32
+  // old algo, without prefetch (except on Windows)
+  CPPUNIT_TEST( test_mergeWithHead_case_1a_no_prefetch );
+  CPPUNIT_TEST( test_mergeWithHead_case_1b_no_prefetch );
+  CPPUNIT_TEST( test_mergeWithHead_case_3_no_prefetch );
+  
+  CPPUNIT_TEST( test_storeObjects_MV_newInsert_no_prefetch );
+  
+  CPPUNIT_TEST( test_storeObjects_MV_case_0a_no_prefetch );
+  CPPUNIT_TEST( test_storeObjects_MV_case_0b_no_prefetch );  
+  CPPUNIT_TEST( test_storeObjects_MV_case_1a_no_prefetch );
+  CPPUNIT_TEST( test_storeObjects_MV_case_2_no_prefetch );  
+  CPPUNIT_TEST( test_storeObjects_MV_case_3_no_prefetch );  
+  CPPUNIT_TEST( test_storeObjects_MV_case_4_no_prefetch );  
+  CPPUNIT_TEST( test_storeObjects_MV_case_5b_no_prefetch );
+  CPPUNIT_TEST( test_storeObjects_MV_case_6_no_prefetch );  
+  CPPUNIT_TEST( test_storeObjects_MV_case_0a_channels_no_prefetch );
+  CPPUNIT_TEST( test_storeObjects_MV_case_5b_6_channels_no_prefetch );
+  CPPUNIT_TEST( test_storeObjects_MV_identicalIov_case_1_no_prefetch );
+  CPPUNIT_TEST( test_storeObjects_MV_identicalIov_case_2_no_prefetch );
+#endif
+  
+  /// \todo these should be in a TagMgr test instead
+  CPPUNIT_TEST( test_insertTagTableRow_fetchTagTableRow );
+  CPPUNIT_TEST( test_insertTagTableRow_exists );
+  CPPUNIT_TEST( test_insertTagTableRow_HEAD );
+  CPPUNIT_TEST( test_fetchTagTableRow_notFound );
+  
+  CPPUNIT_TEST( test_existsTag_global );
+  
+  CPPUNIT_TEST( test_insertObject2TagTableRows_fetchObject2TagTableRow );
+  
+  CPPUNIT_TEST( test_tag_asOfDate_5c );
+  CPPUNIT_TEST( test_tag_HEAD_5c );
+  CPPUNIT_TEST( test_tag_exists );
+  
+  CPPUNIT_TEST( test_findObject_tag_5c );
+  CPPUNIT_TEST( test_findObject_HEAD_5c );
+  
+  CPPUNIT_TEST( test_insertGlobalTagTableRow_fetchGlobalTagTableRow );
+  CPPUNIT_TEST( test_tag_differentFolders_sameTag );
+  
+  CPPUNIT_TEST( test_tag_asOfObjectId_userObject_5c );  
+  
+  CPPUNIT_TEST( test_deleteObject2TagTableRows );
+  CPPUNIT_TEST( test_deleteTagTableRow );
+  CPPUNIT_TEST( test_deleteGlobalTagTableRow );
+  CPPUNIT_TEST( test_deleteTag );
+  CPPUNIT_TEST( test_deleteTag_nonexisting );
+  
+  CPPUNIT_TEST( test_insertionTimeOfLastObjectInTag );
+  
+  CPPUNIT_TEST( test_updateObjectTableNewHeadId_userTag );
+  CPPUNIT_TEST( test_existsUserTag );
+  CPPUNIT_TEST( test_existsUserTag_normal_tag );
+  CPPUNIT_TEST( test_userTag_systemObjects );
+  
+  // ----------- Channels table tests -----------
+  
+  CPPUNIT_TEST( test_insertChannelTableRow );
+  CPPUNIT_TEST( test_updateChannelTable );
+  CPPUNIT_TEST( test_bulkUpdateChannelTable );
+  CPPUNIT_TEST( test_fetchLastRowsWithNewData );
+  CPPUNIT_TEST( test_channelTableFK );
+  
+  // ----------- lastUpdate tests ---------------
+  
+  CPPUNIT_TEST( test_lastUpdate_SV );
+  CPPUNIT_TEST( test_lastUpdate_MV );
+
+  CPPUNIT_TEST_SUITE_END();
+		
+private:
+
+  bool updateObjectTableNewHeadId   
+  ( RelationalObjectMgr* mgr,
+    const std::string& objectTableName,   
+    const std::string& channelTableName,   
+    const ValidityKey& since,   
+    const ValidityKey& until,   
+    const ChannelId& channelId,   
+    const unsigned int newHeadId,   
+    const unsigned int userTagId = 0 )
+  {
+    SOVector newHeadUpdaters;
+    SimpleObject so( newHeadId, // NOTE THE MISUSE...
+                     channelId,
+                     since,
+                     until );
+    newHeadUpdaters.push_back( so );
+    return mgr->bulkUpdateObjectTableNewHeadId( objectTableName,
+                                                channelTableName,
+                                                newHeadUpdaters,
+                                                userTagId );
+  }
+  
+public:
+
+  inline void storeObjects
+  ( RelationalFolder* folder,
+    const std::vector<RelationalObjectPtr>& objects,
+    const bool userTagOnly = false ) const
+  {
+    RelationalTransaction transaction( ralDb->transactionMgr() ); // read-write
+    objMgr->__storeObjects( folder, objects, userTagOnly );  
+    transaction.commit();
+  }  
+  
+  RalDatabase* ralDb; // safely cast pointer to db
+  std::auto_ptr<RelationalObjectMgr> objMgr;
+
+  RecordSpecification payloadSpec;
+  
+  RelationalObjectMgrTest()
+    : payloadSpec() {
+      
+      payloadSpec.extend("I",StorageType::Int32);
+      payloadSpec.extend("S",StorageType::String255);
+      payloadSpec.extend("X",StorageType::Float);
+    }
+  
+  ~RelationalObjectMgrTest() {}
+
+#ifndef WIN32
+#define TEST_WITH_AND_WITHOUT_PREFETCH(test)            \
+  void test##_prefetch() {                              \
+    char *env=getenv("COOL_MVINSERTION_PREFETCH_MAXROWS"); \
+    unsetenv("COOL_MVINSERTION_PREFETCH_MAXROWS");      \
+    test();                                             \
+    if (env) {                                         \
+      setenv("COOL_MVINSERTION_PREFETCH_MAXROWS",env,1);\
+    };                                                  \
+  };                                                    \
+  void test##_no_prefetch() {                           \
+    char *env=getenv("COOL_MVINSERTION_PREFETCH_MAXROWS"); \
+    setenv("COOL_MVINSERTION_PREFETCH_MAXROWS","0",1);  \
+    test();                                             \
+    if (env) {                                         \
+      setenv("COOL_MVINSERTION_PREFETCH_MAXROWS",env,1);\
+    }                                                   \
+    else  unsetenv("COOL_MVINSERTION_PREFETCH_MAXROWS");\
+  }
+#else
+  // Test only the default case on Windows
+#define TEST_WITH_AND_WITHOUT_PREFETCH(test)            \
+  void test##_prefetch() {                              \
+    test();                                             \
+  }
+#endif
+
+  // test with old and new algo (with and without prefetch)
+  TEST_WITH_AND_WITHOUT_PREFETCH( test_mergeWithHead_case_1a );
+  TEST_WITH_AND_WITHOUT_PREFETCH( test_mergeWithHead_case_1b );
+  TEST_WITH_AND_WITHOUT_PREFETCH( test_mergeWithHead_case_3 );
+  
+  TEST_WITH_AND_WITHOUT_PREFETCH( test_storeObjects_MV_newInsert );
+  
+  TEST_WITH_AND_WITHOUT_PREFETCH( test_storeObjects_MV_case_0a );
+  TEST_WITH_AND_WITHOUT_PREFETCH( test_storeObjects_MV_case_0b );  
+  TEST_WITH_AND_WITHOUT_PREFETCH( test_storeObjects_MV_case_1a );
+  TEST_WITH_AND_WITHOUT_PREFETCH( test_storeObjects_MV_case_2 );  
+  TEST_WITH_AND_WITHOUT_PREFETCH( test_storeObjects_MV_case_3 );  
+  TEST_WITH_AND_WITHOUT_PREFETCH( test_storeObjects_MV_case_4 );  
+  TEST_WITH_AND_WITHOUT_PREFETCH( test_storeObjects_MV_case_5b );
+  TEST_WITH_AND_WITHOUT_PREFETCH( test_storeObjects_MV_case_6 );  
+  TEST_WITH_AND_WITHOUT_PREFETCH( test_storeObjects_MV_case_0a_channels );
+  TEST_WITH_AND_WITHOUT_PREFETCH( test_storeObjects_MV_case_5b_6_channels );
+  TEST_WITH_AND_WITHOUT_PREFETCH( test_storeObjects_MV_identicalIov_case_1 );
+  TEST_WITH_AND_WITHOUT_PREFETCH( test_storeObjects_MV_identicalIov_case_2 );
+  
+ 
+  
+  /// Tests findObject
+  void test_findObject() {
+    try{      
+      IFolderPtr folder = ralDb->createFolder( "/myfolder", payloadSpec );
+      RelationalFolder* relfolder = 
+        dynamic_cast<RelationalFolder*>(folder.get());
+      
+      // Create a temporary sequence to get the server SYSDATE before insertion
+      Time timeBef;
+      std::string tmpSeqName = string( m_coolDBName + "_TMP_CLOCK" );
+      {
+        RelationalTransaction transaction( ralDb->transactionMgr() );    
+        if ( ralDb->queryMgr().sequenceMgr().existsSequence( tmpSeqName ) )
+          ralDb->queryMgr().sequenceMgr().dropSequence( tmpSeqName );
+        boost::shared_ptr<RelationalSequence> tmpSeq = 
+          ralDb->queryMgr().sequenceMgr().createSequence( tmpSeqName );
+        tmpSeq->nextVal();    
+        timeBef = stringToTime( tmpSeq->currDate() ); // Time before insertion
+                                                      //std::cout << "Time before insertion: " << timeBef << std::endl;
+        transaction.commit();
+      }    
+      
+      // MySQL now() has 1 second granularity: need to sleep at least 1 second
+      // (if test checks for strict < or >; not needed if checks for <= or >=)
+      sleep(1);
+      
+      // Insert the objects into the folder
+      vector<RelationalObjectPtr> objs;
+      objs.push_back( dummyObject( 1, 0, 2 ) );
+      objs.push_back( dummyObject( 2, 2, 4 ) );
+      storeObjects( relfolder, objs );
+      
+      // MySQL now() has 1 second granularity: need to sleep at least 1 second
+      // (if test checks for strict < or >; not needed if checks for <= or >=)
+      sleep(1);
+      
+      // Get the server SYSDATE after insertion
+      Time timeAft;
+      {
+        RelationalTransaction transaction( ralDb->transactionMgr() );    
+        boost::shared_ptr<RelationalSequence> tmpSeq = 
+        ralDb->queryMgr().sequenceMgr().getSequence( tmpSeqName );
+        tmpSeq->nextVal();    
+        timeAft = stringToTime( tmpSeq->currDate() ); // Time before insertion
+                                                      //std::cout << "Time after  insertion: " << timeAft << std::endl;
+        transaction.commit();
+      }
+      
+      // Cleanup - drop the temporary sequence
+      {
+        RelationalTransaction transaction( ralDb->transactionMgr() );    
+        ralDb->queryMgr().sequenceMgr().dropSequence( tmpSeqName );
+        transaction.commit();
+      }
+      
+      // Retrieve the first object
+      IObjectPtr obj1 = objMgr->findObject( relfolder, 1, 0 );
+      CPPUNIT_ASSERT_MESSAGE( "first object",
+                              dummyPayload( 1 ) == obj1->payload() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "first object since", 
+                                    (ValidityKey)0, obj1->since() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "first object until", 
+                                    (ValidityKey)2, obj1->until() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "first object id", 
+                                    1u, obj1->objectId() );
+      
+      // Analyse the object insertion time
+      Time timeIns = obj1->insertionTime();
+      //std::cout << "Time before insertion: " << timeBef << std::endl;
+      //std::cout << "Time at     insertion: " << timeIns << std::endl;
+      //std::cout << "Time after  insertion: " << timeAft << std::endl;
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "year of insertion time is 200x",
+                                    200, timeIns.year()/10 );
+      CPPUNIT_ASSERT_MESSAGE( "insertion time > time before insertion",
+                              timeIns > timeBef );
+      CPPUNIT_ASSERT_MESSAGE( "insertion time < time after insertion",
+                              timeIns < timeAft );
+      
+      // Retrieve the second object
+      IObjectPtr obj2 = objMgr->findObject( relfolder, 3, 0 );
+      CPPUNIT_ASSERT_MESSAGE( "second object",
+                              dummyPayload( 2 ) == obj2->payload() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "second object since", 
+                                    (ValidityKey)2, obj2->since() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "second object until", 
+                                    (ValidityKey)4, obj2->until() );
+    } catch ( std::exception& e ) {
+      std::cout << "Exception caught: " << e.what() << std::endl;
+      throw;     
+    }
+    
+  }
+  
+  
+  /// Tests storeObject for SV objects
+  void test_storeObjects_SV() {
+    try {
+      IFolderPtr folder = ralDb->createFolder( "/myfolder", payloadSpec );
+      RelationalFolder* relfolder = 
+        dynamic_cast<RelationalFolder*>( folder.get() );
+      {
+        vector<RelationalObjectPtr> objs;
+        objs.push_back( dummyObject( 2, 2, ValidityKeyMax ) );
+        objs.push_back( dummyObject( 4, 4, ValidityKeyMax ) );
+        storeObjects( relfolder, objs );
+      }
+      {
+        vector<RelationalObjectPtr> objs;
+        objs.push_back( dummyObject( 6, 6, ValidityKeyMax ) );
+        objs.push_back( dummyObject( 8, 8, ValidityKeyMax ) );
+        storeObjects( relfolder, objs );
+      }
+      
+      IObjectPtr obj = objMgr->findObject( relfolder, 2, 0 );
+      CPPUNIT_ASSERT_MESSAGE( "first object", 
+                              dummyPayload( 2 ) == obj->payload() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "first object since", 
+                                    (ValidityKey)2, obj->since() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "first object until", 
+                                    (ValidityKey)4, obj->until() );
+      
+      obj = objMgr->findObject( relfolder, 4, 0 );
+      CPPUNIT_ASSERT_MESSAGE( "second object", 
+                              dummyPayload( 4 ) == obj->payload() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "second object since", 
+                                    (ValidityKey)4, obj->since() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "second object until", 
+                                    (ValidityKey)6, obj->until() );
+      
+      obj = objMgr->findObject( relfolder, 6, 0 );
+      CPPUNIT_ASSERT_MESSAGE( "third object", 
+                              dummyPayload( 6 ) == obj->payload() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "third object since", 
+                                    (ValidityKey)6, obj->since() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "third object until", 
+                                    (ValidityKey)8, obj->until() );
+      
+      obj = objMgr->findObject( relfolder, 8, 0 );
+      CPPUNIT_ASSERT_MESSAGE( "fourth object", 
+                              dummyPayload( 8 ) == obj->payload() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "fourth object since", 
+                                    (ValidityKey)8, obj->since() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "fourth object until", 
+                                    ValidityKeyMax, obj->until() );
+      
+    } catch ( std::exception& e ) {
+      std::cout << "Exception caught: " << e.what() << std::endl;
+      throw;     
+    }
+  }
+  
+  
+  /// Tests storeObject for SV objects in different channels
+  void test_storeObjects_SV_different_channel() {
+    IFolderPtr folder = ralDb->createFolder( "/myfolder", payloadSpec );
+    RelationalFolder* relfolder = 
+      dynamic_cast<RelationalFolder*>( folder.get() );
+    
+    relfolder->createChannel( 0, "0" );
+    relfolder->createChannel( 1, "1" );
+    
+    vector<RelationalObjectPtr> objs;
+    objs.push_back( dummyObject( 1, 0, ValidityKeyMax, 0 ) );
+    objs.push_back( dummyObject( 2, 2, ValidityKeyMax, 0 ) );
+    storeObjects( relfolder, objs );
+    objs.clear();
+    objs.push_back( dummyObject( 3, 4, ValidityKeyMax, 0 ) );
+    storeObjects( relfolder, objs );
+    objs.clear();
+    objs.push_back( dummyObject( 4, 0, ValidityKeyMax, 1 ) );
+    objs.push_back( dummyObject( 5, 2, ValidityKeyMax, 1 ) );
+    storeObjects( relfolder, objs );
+    objs.clear();
+    objs.push_back( dummyObject( 6, 4, ValidityKeyMax, 1 ) );
+    storeObjects( relfolder, objs );
+    
+    IObjectPtr obj = objMgr->findObject( relfolder, 0, 0 );
+    CPPUNIT_ASSERT( dummyPayload( 1 ) == obj->payload() );
+    CPPUNIT_ASSERT_EQUAL( (ValidityKey)0, obj->since() );
+    CPPUNIT_ASSERT_EQUAL( (ValidityKey)2, obj->until() );
+    CPPUNIT_ASSERT_EQUAL( (ChannelId)0, obj->channelId() );
+    
+    obj = objMgr->findObject( relfolder, 2, 0 );
+    CPPUNIT_ASSERT( dummyPayload( 2 ) == obj->payload() );
+    CPPUNIT_ASSERT_EQUAL( (ValidityKey)2, obj->since() );
+    CPPUNIT_ASSERT_EQUAL( (ValidityKey)4, obj->until() );
+    CPPUNIT_ASSERT_EQUAL( (ChannelId)0, obj->channelId() );
+    
+    obj = objMgr->findObject( relfolder, 4, 0 );
+    CPPUNIT_ASSERT( dummyPayload( 3 ) == obj->payload() );
+    CPPUNIT_ASSERT_EQUAL( (ValidityKey)4, obj->since() );
+    CPPUNIT_ASSERT_EQUAL( ValidityKeyMax, obj->until() );
+    CPPUNIT_ASSERT_EQUAL( (ChannelId)0, obj->channelId() );
+    
+    obj = objMgr->findObject( relfolder, 0, 1 );
+    CPPUNIT_ASSERT( dummyPayload( 4 ) == obj->payload() );
+    CPPUNIT_ASSERT_EQUAL( (ValidityKey)0, obj->since() );
+    CPPUNIT_ASSERT_EQUAL( (ValidityKey)2, obj->until() );
+    CPPUNIT_ASSERT_EQUAL( (ChannelId)1, obj->channelId() );
+
+    obj = objMgr->findObject( relfolder, 2, 1 );
+    CPPUNIT_ASSERT( dummyPayload( 5 ) == obj->payload() );
+    CPPUNIT_ASSERT_EQUAL( (ValidityKey)2, obj->since() );
+    CPPUNIT_ASSERT_EQUAL( (ValidityKey)4, obj->until() );
+    CPPUNIT_ASSERT_EQUAL( (ChannelId)1, obj->channelId() );
+    
+    obj = objMgr->findObject( relfolder, 4, 1 );
+    CPPUNIT_ASSERT( dummyPayload( 6 ) == obj->payload() );
+    CPPUNIT_ASSERT_EQUAL( (ValidityKey)4, obj->since() );
+    CPPUNIT_ASSERT_EQUAL( ValidityKeyMax, obj->until() );
+    CPPUNIT_ASSERT_EQUAL( (ChannelId)1, obj->channelId() );
+  }
+  
+  
+  /// Tests storeObject with an empty list of objects
+  void test_storeObjects_empty_list() {
+    IFolderPtr folder = ralDb->createFolder( "/myfolder", payloadSpec );
+    RelationalFolder* relfolder = 
+      dynamic_cast<RelationalFolder*>( folder.get() );
+    
+    vector<RelationalObjectPtr> objs;
+    storeObjects( relfolder, objs );
+    
+    CPPUNIT_ASSERT_MESSAGE( "reached without exception", true );
+  }
+  
+  
+  /// Tests storeObject for bulk r/w of 100 SV objects
+  void test_storeObjects_bulk_100() {
+    IFolderPtr folder = ralDb->createFolder( "/myfolder", payloadSpec );
+    RelationalFolder* relfolder = 
+      dynamic_cast<RelationalFolder*>( folder.get() );
+    
+    vector<RelationalObjectPtr> objs;
+    unsigned int nObjs = 100;
+    for ( unsigned int i = 0; i < nObjs; ++i ) {
+      objs.push_back( dummyObject( i, i, ValidityKeyMax ) );
+    }
+    storeObjects( relfolder, objs );
+    
+    IObjectPtr obj;
+    for ( unsigned int i = 0; i < nObjs; ++i ) {
+      obj = objMgr->findObject( relfolder, i, 0 );
+      stringstream s;
+      s << "object " << i << " ";
+      CPPUNIT_ASSERT_MESSAGE( ( s.str() + "payload" ).c_str(), 
+                              dummyPayload( i ) == obj->payload() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( ( s.str() + "since" ).c_str(), 
+                                    (ValidityKey)i, obj->since() );
+      // last object's until extends to ValidityKeyMax
+      if ( i < nObjs-1 ) {
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( ( s.str() + "until" ).c_str(), 
+                                      (ValidityKey)i+1, obj->until() );
+      } else {
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( ( s.str() + "until" ).c_str(), 
+                                      ValidityKeyMax, obj->until() );
+      }
+    }
+  }
+  
+  IObjectPtr getNext( IObjectIteratorPtr objs) {
+        if (!objs->goToNext())
+                CPPUNIT_FAIL("no next object");
+        return IObjectPtr( objs->currentRef().clone() );
+  }
+ 
+  /// Tests bulkUpdateObjectTableIov
+  void test_bulkUpdateObjectTableIov() {
+    IFolderPtr folder = ralDb->createFolder( "/myfolder", payloadSpec );
+    RelationalFolder* relfolder = 
+      dynamic_cast<RelationalFolder*>( folder.get() );
+    
+    vector<RelationalObjectPtr> objs;
+    objs.push_back( dummyObject( 1, 0, 1 ) );
+    objs.push_back( dummyObject( 2, 10, 11 ) );
+    objs.push_back( dummyObject( 3, 20, 21 ) );
+    storeObjects( relfolder, objs );
+
+    std::map<unsigned int,ValidityKey> objectIdNewUntil;
+    objectIdNewUntil[1] = 9;
+    objectIdNewUntil[2] = 19;
+    objectIdNewUntil[3] = 29;
+    
+    RelationalTransaction transaction( ralDb->transactionMgr() );
+    objMgr->bulkUpdateObjectTableIov( relfolder->objectTableName(),
+                                      objectIdNewUntil );
+    transaction.commit();
+    
+    {
+      IObjectIteratorPtr objs = 
+        relfolder->browseObjects( ValidityKeyMin, 
+                                  ValidityKeyMax, 
+                                  ChannelSelection::all() );
+      
+      CPPUNIT_ASSERT_EQUAL( 3u, objs->size() );
+      
+      IObjectPtr obj = getNext(objs);
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "Payload size", dummyPayload( 1 ).size(), obj->payload().size() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "Payload[I]", dummyPayload( 1 )["I"], obj->payload()["I"] );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "Payload[S]", dummyPayload( 1 )["S"], obj->payload()["S"] );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "Payload[X]", dummyPayload( 1 )["X"], obj->payload()["X"] );
+      try {        
+        CPPUNIT_ASSERT( dummyPayload( 1 ) == obj->payload() );
+      }
+      catch (...) {
+        std::cout << "Expected: " << dummyPayload( 1 ) << std::endl;
+        std::cout << "Actual: " << obj->payload() << std::endl;
+        throw;
+      }
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "Payload", (const IRecord&)dummyPayload( 1 ), obj->payload() );
+      CPPUNIT_ASSERT_EQUAL( (ValidityKey)0, obj->since() );
+      CPPUNIT_ASSERT_EQUAL( (ValidityKey)9, obj->until() );
+
+      obj = getNext(objs);
+      CPPUNIT_ASSERT( dummyPayload( 2 ) == obj->payload() );
+      CPPUNIT_ASSERT_EQUAL( (ValidityKey)10, obj->since() );
+      CPPUNIT_ASSERT_EQUAL( (ValidityKey)19, obj->until() );
+
+      obj = getNext(objs);
+      CPPUNIT_ASSERT( dummyPayload( 3 ) == obj->payload() );
+      CPPUNIT_ASSERT_EQUAL( (ValidityKey)20, obj->since() );
+      CPPUNIT_ASSERT_EQUAL( (ValidityKey)29, obj->until() );
+    }
+  }
+  
+
+  /// Tests browseObjects for a SV folder in reverse order
+  void test_browseObjects_SV_reverse() {
+    IFolderPtr folder = ralDb->createFolder( "/myfolder", payloadSpec );
+    RelationalFolder* relfolder = 
+      dynamic_cast<RelationalFolder*>( folder.get() );
+    
+    unsigned int nObjs = 100;
+    
+    for ( ChannelId channel = 0; channel < 5; ++channel ) {
+      vector<RelationalObjectPtr> objs;
+      for ( unsigned int i = 0; i < nObjs; ++i ) {
+        objs.push_back( dummyObject( i, i, ValidityKeyMax, channel ) );
+      }
+      storeObjects( relfolder, objs );
+    }
+    
+    try {
+      ValidityKey since = 50;
+      ValidityKey until = 70;
+      ChannelSelection channels( 2, 2, 
+                                 ChannelSelection::sinceDescBeforeChannel );
+      string tag = "";
+      IObjectIteratorPtr cursor = 
+        objMgr->browseObjects( relfolder, since, until, channels, tag );
+      
+      CPPUNIT_ASSERT_MESSAGE( "no cursor", cursor != 0 );
+      
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "size", 21u, 
+                                    (unsigned int)cursor->size() );
+      
+      // test content
+      unsigned int nBObjs = 0;
+      while ( cursor->goToNext() ) {
+        IObjectPtr obj( cursor->currentRef().clone() );
+        
+        stringstream s;
+        s << "object " << nBObjs << " ";
+        
+        CPPUNIT_ASSERT_MESSAGE
+          ( ( s.str() + "payload" ).c_str(), 
+            dummyPayload( (int)(until - nBObjs) ) == obj->payload() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( ( s.str() + "since" ).c_str(), 
+                                      until - nBObjs, obj->since() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( ( s.str() + "until" ).c_str(), 
+                                      until - nBObjs +1, obj->until() );
+        
+        ++nBObjs;
+      }
+      
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "number of objects", 21u, nBObjs );
+      
+    } catch ( std::exception& e ) {
+      cout << e.what() << endl;
+      throw;
+    }
+  }
+
+
+  /// Tests browseObjects for a MV folder in reverse order
+  void test_browseObjects_MV_reverse() {
+    IFolderPtr folder = ralDb->createFolder( "/myfolder", 
+                                             payloadSpec,
+                                             "desc", 
+                                             FolderVersioning::MULTI_VERSION );
+    RelationalFolder* relfolder = 
+      dynamic_cast<RelationalFolder*>( folder.get() );
+    
+    unsigned int nObjs = 100;
+    
+    for ( ChannelId channel = 0; channel < 5; ++channel ) {
+      vector<RelationalObjectPtr> objs;
+      for ( unsigned int i = 0; i < nObjs; ++i ) {
+        objs.push_back( dummyObject( i, i, ValidityKeyMax, channel ) );
+      }
+      storeObjects( relfolder, objs );
+    }
+    
+    try {
+      ValidityKey since = 50;
+      ValidityKey until = 70;
+      ChannelSelection channels( 2, 2, 
+                                 ChannelSelection::sinceDescBeforeChannel );
+      string tag = "";
+      IObjectIteratorPtr cursor = 
+        objMgr->browseObjects( relfolder, since, until, channels, tag );
+      
+      CPPUNIT_ASSERT_MESSAGE( "no cursor", cursor != 0 );
+      
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "size", 21u, 
+                                    (unsigned int)cursor->size() );
+      
+      // test content
+      unsigned int nBObjs = 0;
+      while ( cursor->goToNext() ) {
+        IObjectPtr obj( cursor->currentRef().clone() );
+        
+        stringstream s;
+        s << "object " << nBObjs << " ";
+        
+        CPPUNIT_ASSERT_MESSAGE
+          ( ( s.str() + "payload" ).c_str(), 
+            dummyPayload( (int)(until - nBObjs) ) == obj->payload() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( ( s.str() + "since" ).c_str(), 
+                                      until - nBObjs, obj->since() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( ( s.str() + "until" ).c_str(), 
+                                      until - nBObjs + 1, obj->until() );
+        
+        nBObjs++;
+      }
+      
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "number of objects", 21u, nBObjs );
+      
+    } catch ( std::exception& e ) {
+      cout << e.what() << endl;
+      throw;
+    }
+  }
+  
+  
+  /// Tests browseObjects for a SV folder
+  void test_browseObjects_SV() 
+  {
+    IFolderPtr folder = ralDb->createFolder( "/myfolder", payloadSpec );
+    RelationalFolder* relfolder = 
+      dynamic_cast<RelationalFolder*>( folder.get() );
+    
+    unsigned int nObjs = 100;
+    
+    for ( ChannelId channel = 0; channel < 5; ++channel ) {
+      vector<RelationalObjectPtr> objs;
+      for ( unsigned int i = 0; i < nObjs; ++i ) {
+        objs.push_back( dummyObject( i, i, ValidityKeyMax, channel ) );
+      }
+      storeObjects( relfolder, objs );
+    }
+    
+    try {
+      ValidityKey since = 50;
+      ValidityKey until = 70;
+      ChannelSelection channels( 2, 2 );
+      string tag = "";
+      
+      IObjectIteratorPtr cursor = 
+        objMgr->browseObjects( relfolder, since, until, channels, tag );
+      
+      CPPUNIT_ASSERT_MESSAGE( "no cursor", cursor != 0 );
+      
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "size", 21u, 
+                                    (unsigned int)cursor->size() );
+      
+      // test content
+      unsigned int nBObjs = 0;
+      //for ( IObjectIterator::const_iterator i = cursor->begin();
+      //      i != cursor->end(); ++ i ) {
+      //  IObjectPtr obj = *i;
+      while ( cursor->goToNext() ) {
+        IObjectPtr obj( cursor->currentRef().clone() );
+        
+        stringstream s;
+        s << "object " << nBObjs << " ";
+        
+        CPPUNIT_ASSERT_MESSAGE
+          ( ( s.str() + "payload" ).c_str(), 
+            dummyPayload( (int)(since+nBObjs) ) == obj->payload() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( ( s.str() + "since" ).c_str(), 
+                                      since + nBObjs, obj->since() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( ( s.str() + "until" ).c_str(), 
+                                      since + nBObjs + 1, obj->until() );
+        
+        nBObjs++;
+      }
+      
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "number of objects", 21u, nBObjs );
+      
+    } catch ( std::exception& e ) {
+      cout << e.what() << endl;
+      throw;
+    }
+  }
+
+
+  /// Tests browseObjects for a MV folder
+  void test_browseObjects_MV() {
+    IFolderPtr folder = ralDb->createFolder( "/myfolder", 
+                                             payloadSpec,
+                                             "desc", 
+                                             FolderVersioning::MULTI_VERSION );
+    RelationalFolder* relfolder = 
+      dynamic_cast<RelationalFolder*>( folder.get() );
+    
+    unsigned int nObjs = 100;
+    
+    for ( ChannelId channel = 0; channel < 5; ++channel ) {
+      vector<RelationalObjectPtr> objs;
+      for ( unsigned int i = 0; i < nObjs; ++i ) {
+        objs.push_back( dummyObject( i, i, ValidityKeyMax, channel ) );
+      }
+      storeObjects( relfolder, objs );
+    }
+    
+    try {
+      ValidityKey since = 50;
+      ValidityKey until = 70;
+      ChannelSelection channels( 2, 2 );
+      string tag = "";
+      
+      IObjectIteratorPtr cursor = 
+        objMgr->browseObjects( relfolder, since, until, channels, tag );
+      
+      CPPUNIT_ASSERT_MESSAGE( "no cursor", cursor != 0 );
+      
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "size", 21u, 
+                                    (unsigned int)cursor->size() );
+      
+      // test content
+      unsigned int nBObjs = 0;
+      //for ( IObjectIterator::const_iterator 
+      //      i = cursor->begin(); i != cursor->end(); ++ i ) {
+      //  IObjectPtr obj = *i;
+      while ( cursor->goToNext() ) {
+        IObjectPtr obj( cursor->currentRef().clone() );
+        
+        stringstream s;
+        s << "object " << nBObjs << " ";
+        
+        CPPUNIT_ASSERT_MESSAGE
+          ( ( s.str() + "payload" ).c_str(), 
+            dummyPayload( (int)(since+nBObjs) ) == obj->payload() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( ( s.str() + "since" ).c_str(), 
+                                      since + nBObjs, obj->since() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( ( s.str() + "until" ).c_str(), 
+                                      since + nBObjs + 1, obj->until() );
+        
+        nBObjs++;
+      }
+      
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "number of objects", 21u, nBObjs );
+      
+    } catch ( std::exception& e ) {
+      cout << e.what() << endl;
+      throw;
+    }
+  }
+  
+  
+  /// Checks that storing an until value of more that int63 (the current
+  /// limitation) throws a ValidityKeyOutOfBoundaries exception (SV storage)
+  void test_sv_UInt64Max_iov() {
+    IFolderPtr folder = 
+      ralDb->createFolder( "/myfolder", 
+                           payloadSpec,
+                           "my description",
+                           FolderVersioning::SINGLE_VERSION );
+    RelationalFolder* relfolder = 
+      dynamic_cast<RelationalFolder*>( folder.get() );
+    RelationalObjectPtr object
+      ( new RelationalObject( 0, UInt64Max, dummyPayload( 0 ), 0 ) );
+    vector<RelationalObjectPtr> objs( 1, object );
+    CPPUNIT_ASSERT_THROW(storeObjects( relfolder, objs ),
+                         ValidityKeyOutOfBoundaries);
+  }
+  
+
+  
+  /// Checks that storing an until value of more that int63 (the current
+  /// limitation) throws a ValidityKeyOutOfBoundaries exception (MV storage)
+  void test_mv_UInt64Max_iov() {
+    IFolderPtr folder = 
+      ralDb->createFolder( "/myfolder", 
+                           payloadSpec,
+                           "my description",
+                           FolderVersioning::MULTI_VERSION );
+    RelationalFolder* relfolder = 
+      dynamic_cast<RelationalFolder*>( folder.get() );
+    RelationalObjectPtr object
+      ( new RelationalObject( 0, UInt64Max, dummyPayload( 0 ), 0 ) );
+    vector<RelationalObjectPtr> objs( 1, object );
+    CPPUNIT_ASSERT_THROW(storeObjects( relfolder, objs ),
+                         ValidityKeyOutOfBoundaries);
+  }
+  
+  
+
+  /// Tests storeObject for bulk r/w into multiple channels (SV mode)
+  void test_storeObjects_bulk_multichannel() {
+    IFolderPtr folder = ralDb->createFolder( "/myfolder", payloadSpec );
+    RelationalFolder* relfolder = 
+      dynamic_cast<RelationalFolder*>( folder.get() );
+    
+    ChannelId nChannels = 10;
+    {
+      vector<RelationalObjectPtr> objs;
+      for ( ChannelId ch = 0; ch < nChannels; ++ch ) {
+        objs.push_back( dummyObject( (int)ch, (ValidityKey)0, ValidityKeyMax,
+                                     ch ) );
+      }
+      for ( ChannelId ch = 0; ch < nChannels; ++ch ) {
+        objs.push_back( dummyObject( (int)ch, (ValidityKey)5, ValidityKeyMax,
+                                     ch ) );
+      }
+      storeObjects( relfolder, objs );
+    }
+    {
+      vector<RelationalObjectPtr> objs;
+      for ( ChannelId ch = 0; ch < nChannels; ++ch ) {
+        objs.push_back( dummyObject( (int)ch, (ValidityKey)10, ValidityKeyMax,
+                                     ch ) );
+      }
+      for ( ChannelId ch = 0; ch < nChannels; ++ch ) {
+        objs.push_back( dummyObject( (int)ch, (ValidityKey)15, ValidityKeyMax,
+                                     ch ) );
+      }
+      storeObjects( relfolder, objs );
+    }
+    
+    unsigned int nObjs = 4;
+    IObjectPtr obj;
+    for ( ChannelId ch = 0; ch < nChannels; ++ch ) {
+      for ( unsigned int i = 0; i < nObjs; ++i ) {
+        stringstream s;
+        s << "object " << i << ", channel " << ch << " ";
+        
+        ValidityKey pointInTime = 5 * i; // 0, 5, 10, 15
+        obj = objMgr->findObject( relfolder, pointInTime, ch );
+        
+        CPPUNIT_ASSERT_MESSAGE( ( s.str() + "payload" ).c_str(), 
+                                dummyPayload( (int)ch ) == obj->payload() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( ( s.str() + "since" ).c_str(), 
+                                      pointInTime, obj->since() );
+        
+        // until of object 3 extends to ValidityKeyMax
+        if ( i < nObjs-1 ) {
+          CPPUNIT_ASSERT_EQUAL_MESSAGE( ( s.str() + "until" ).c_str(), 
+                                        pointInTime +5, obj->until() );
+        } else {
+          CPPUNIT_ASSERT_EQUAL_MESSAGE( ( s.str() + "until" ).c_str(), 
+                                        ValidityKeyMax, obj->until() );
+        }
+      }
+    }
+  }
+  
+  
+  /// Tests SimpleObject::filter
+  void test_SimpleObject_filter() {
+    SOVector i;
+    
+    i = SimpleObject( 1, 0, 2, 3 ).filter( SimpleObject( 1, 0, 1, 2 ) );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 size", 1u, (unsigned int)i.size() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 since", (ValidityKey)1, i[0].since );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 until", (ValidityKey)2, i[0].until );
+    
+    i = SimpleObject( 1, 0, 1, 2 ).filter( SimpleObject( 1, 0, 2, 3 ) );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 size", 1u, (unsigned int)i.size() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 since", (ValidityKey)2, i[0].since );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 until", (ValidityKey)3, i[0].until );
+    
+    i = SimpleObject( 1, 0, 1, 3 ).filter( SimpleObject( 1, 0, 1, 2 ) );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 size", 0u, (unsigned int)i.size() );
+    
+    i = SimpleObject( 1, 0, 1, 3 ).filter( SimpleObject( 1, 0, 2, 3 ) );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "4 size", 0u, (unsigned int)i.size() );
+    
+    i = SimpleObject( 1, 0, 1, 2 ).filter( SimpleObject( 1, 0, 1, 2 ) );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "5 size", 0u, (unsigned int)i.size() );
+    
+    i = SimpleObject( 1, 0, 1, 4 ).filter( SimpleObject( 1, 0, 2, 3 ) );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "6 size", 0u, (unsigned int)i.size() );
+    
+    i = SimpleObject( 1, 0, 2, 3 ).filter( SimpleObject( 1, 0, 1, 4 ) );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "7 size", 2u, (unsigned int)i.size() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "7 since", (ValidityKey)1, i[0].since );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "7 until", (ValidityKey)2, i[0].until );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "7 since", (ValidityKey)3, i[1].since );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "7 until", (ValidityKey)4, i[1].until );
+    
+    i = SimpleObject( 1, 0, 2, 3 ).filter( SimpleObject( 1, 0, 1, 3 ) );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "8 size", 1u, (unsigned int)i.size() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "8 since", (ValidityKey)1, i[0].since );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "8 until", (ValidityKey)2, i[0].until );
+    
+    i = SimpleObject( 1, 0, 1, 2 ).filter( SimpleObject( 1, 0, 1, 3 ) );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "9 size", 1u, (unsigned int)i.size() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "9 since", (ValidityKey)2, i[0].since );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "9 until", (ValidityKey)3, i[0].until );
+  }
+  
+  
+  /// Tests SimpleObject::intersect
+  void test_SimpleObject_intersect() {
+    SOVector v( 1, SimpleObject( 1, 0, 2, 4 ) );
+    SOVector i = SimpleObject( 2, 0, 2, 4 ).intersect( v );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "size", 1u, (unsigned int)i.size() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "objectId", 1u, i[0].objectId );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "since", (ValidityKey)2, i[0].since );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "until", (ValidityKey)4, i[0].until );
+  }
+  
+  
+  /// Tests SimpleObject::visibleThrough
+  void test_SimpleObject_visisbleThrough() {
+    SOVector v( 1, SimpleObject( 1, 0, 2, 4 ) );
+    SOVector i = SimpleObject( 2, 0, 2, 4 ).visibleThrough( v );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "size", 0u, (unsigned int)i.size() );
+    
+    v.clear();
+    v.push_back( SimpleObject( 1, 0, 1, 2 ) );
+    v.push_back( SimpleObject( 1, 0, 3, 4 ) );
+    
+    i = SimpleObject( 2, 0, 1, 4 ).visibleThrough( v );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "size", 1u, (unsigned int)i.size() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "since", (ValidityKey)2, i[0].since );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "until", (ValidityKey)3, i[0].until );
+    
+    v.clear();
+    v.push_back( SimpleObject( 1, 0, 2, 3 ) );
+    
+    i = SimpleObject( 2, 0, 1, 4 ).visibleThrough( v );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "size", 2u, (unsigned int)i.size() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "since", (ValidityKey)1, i[0].since );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "until", (ValidityKey)2, i[0].until );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "since", (ValidityKey)3, i[1].since );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "until", (ValidityKey)4, i[1].until );
+    
+    v.clear();
+    v.push_back( SimpleObject( 1, 0, 2, 4 ) );
+    
+    i = SimpleObject( 2, 0, 2, 4 ).visibleThrough( v );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "size", 0u, (unsigned int)i.size() );
+    
+    v.clear();
+    v.push_back( SimpleObject( 1, 0, 1, 3 ) );
+    v.push_back( SimpleObject( 1, 0, 6, 8 ) );
+    
+    i = SimpleObject( 2, 0, 2, 4 ).visibleThrough( v );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "size", 1u, (unsigned int)i.size() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "since", (ValidityKey)3, i[0].since );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "until", (ValidityKey)4, i[0].until );
+  }
+  
+  
+  /// Tests SimpleObject::visibleThrough
+  void test_SimpleObject_visisbleThrough2() {
+    SOVector v;
+    v.push_back( SimpleObject( 1, 0, 1, 3 ) );
+    v.push_back( SimpleObject( 1, 0, 6, 8 ) );
+    
+    SOVector i = SimpleObject( 2, 0, 2, 4 ).visibleThrough( v );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "size", 1u, (unsigned int)i.size() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "since", (ValidityKey)3, i[0].since );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "until", (ValidityKey)4, i[0].until );
+  }
+  
+  
+  /// Tests processMultiVersionObjects
+  void test_processMultiVersionObjects_case_0a() {
+    RelationalDatabasePtr dbPtr;
+    
+    vector<RelationalObjectPtr> objects;
+    objects.push_back( dummyObject( 1, 1, 2 ) );
+    objects.push_back( dummyObject( 2, 1, 2 ) );
+    
+    std::vector<RelationalObjectTableRow> rows;
+    
+    unsigned int idOffset = 1;
+    std::map<unsigned int, unsigned int> idToIndex;
+    std::vector<SimpleObject> splitters
+      = objMgr->processMultiVersionObjects( objects, rows, 
+                                           idOffset, idToIndex );
+    
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "splitters size", 
+                                  1u, (unsigned int)splitters.size() );
+    SimpleObject s = splitters[0];
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "int 1 object id", 1u, s.objectId );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "int 1 since", (ValidityKey)1, s.since );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "int 1 until", (ValidityKey)2, s.until );
+    
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "row count", 2u, (unsigned int)rows.size() );
+    
+    RelationalObjectTableRow row = rows[0];
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 object id", 1u, row.objectId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 payload", string("Object 1"),
+                                  row["S"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 since", (ValidityKey)1, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 until", (ValidityKey)2, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 original id", 0u, row.originalId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 new head id", 7u, row.newHeadId() );
+    
+    row = rows[1];
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 object id", 7u, row.objectId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 payload", string("Object 2"),
+                                  row["S"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 since", (ValidityKey)1, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 until", (ValidityKey)2, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 original id", 0u, row.originalId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 new head id", 0u, row.newHeadId() );
+  }
+  
+  
+  /// Tests processMultiVersionObjects
+  void test_processMultiVersionObjects_case_0b() {
+    RelationalDatabasePtr dbPtr;
+    
+    vector<RelationalObjectPtr> objects;
+    objects.push_back( dummyObject( 1, 2, 3 ) );
+    objects.push_back( dummyObject( 2, 1, 4 ) );
+    
+    std::vector<RelationalObjectTableRow> rows;
+    
+    unsigned int idOffset = 1;
+    std::map<unsigned int, unsigned int> idToIndex;
+    std::vector<SimpleObject> splitters
+      = objMgr->processMultiVersionObjects( objects, rows, 
+                                           idOffset, idToIndex );
+    
+    /*cout << "splitters:\n";
+    copy( splitters.begin(), splitters.end(),
+          std::ostream_iterator<SimpleObject>( cout, "\n" ) );*/
+    
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "splitters size", 
+                                  3u, (unsigned int)splitters.size() );
+    
+    SimpleObject s = splitters[0];
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "int 1 object id", 1u, s.objectId );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "int 1 since", (ValidityKey)2, s.since );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "int 1 until", (ValidityKey)3, s.until );
+    s = splitters[1];
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "int 2 object id", 7u, s.objectId );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "int 2 since", (ValidityKey)1, s.since );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "int 2 until", (ValidityKey)2, s.until );
+    s = splitters[2];
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "int 3 object id", 7u, s.objectId );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "int 3 since", (ValidityKey)3, s.since );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "int 3 until", (ValidityKey)4, s.until );
+    
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "row count", 2u, 
+                                  (unsigned int)rows.size() );
+    
+    RelationalObjectTableRow row = rows[0];
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 object id", 1u, row.objectId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 payload", string("Object 1"),
+                                  row["S"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 since", (ValidityKey)2, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 until", (ValidityKey)3, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 original id", 0u, row.originalId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 new head id", 7u, row.newHeadId() );
+    
+    row = rows[1];
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 object id", 7u, row.objectId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 payload", string("Object 2"),
+                                  row["S"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 since", (ValidityKey)1, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 until", (ValidityKey)4, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 original id", 0u, row.originalId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 new head id", 0u, row.newHeadId() );
+  }
+  
+  
+  /// Tests processMultiVersionObjects
+  void test_processMultiVersionObjects_case_1a() {
+    RelationalDatabasePtr dbPtr;
+    
+    vector<RelationalObjectPtr> objects;
+    objects.push_back( dummyObject( 1, 1, 3 ) );
+    objects.push_back( dummyObject( 2, 2, 4 ) );
+    
+    std::vector<RelationalObjectTableRow> rows;
+    
+    unsigned int idOffset = 1;
+    std::map<unsigned int, unsigned int> idToIndex;
+    std::vector<SimpleObject> splitters
+      = objMgr->processMultiVersionObjects( objects, rows, 
+                                           idOffset, idToIndex );
+    
+    //copy( splitters.begin(), splitters.end(),
+    //      std::ostream_iterator<SimpleObject>( cout, "\n" ) );
+    //copy( rows.begin(), rows.end(),
+    //      std::ostream_iterator<RelationalObjectTableRow>( cout, "\n" ) );
+    
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "splitters size", 
+                                  2u, (unsigned int)splitters.size() );
+    SimpleObject s = splitters[0];
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "int 1 object id", 1u, s.objectId );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "int 1 since", (ValidityKey)1, s.since );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "int 1 until", (ValidityKey)3, s.until );
+    s = splitters[1];
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "int 2 object id", 7u, s.objectId );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "int 2 since", (ValidityKey)3, s.since );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "int 2 until", (ValidityKey)4, s.until );
+    
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "row count", 3u, (unsigned int)rows.size() );
+    
+    RelationalObjectTableRow row = rows[0];
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 object id", 1u, row.objectId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 payload", string("Object 1"),
+                                  row["S"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 since", (ValidityKey)1, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 until", (ValidityKey)3, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 original id", 0u, row.originalId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 new head id", 7u, row.newHeadId() );
+    
+    row = rows[1];
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 object id", 7u, row.objectId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 payload", string("Object 2"),
+                                  row["S"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 since", (ValidityKey)2, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 until", (ValidityKey)4, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 original id", 0u, row.originalId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 new head id", 0u, row.newHeadId() );
+    
+    row = rows[2];
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 object id", 8u, row.objectId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 payload", string("Object 1"),
+                                  row["S"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 since", (ValidityKey)1, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 until", (ValidityKey)2, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 original id", 1u, row.originalId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 new head id", 0u, row.newHeadId() );
+  }
+  
+  
+  /// Tests processMultiVersionObjects
+  void test_processMultiVersionObjects_case_1b() {
+    RelationalDatabasePtr dbPtr;
+    
+    vector<RelationalObjectPtr> objects;
+    objects.push_back( dummyObject( 1, 2, 4 ) );
+    objects.push_back( dummyObject( 2, 1, 3 ) );
+    
+    std::vector<RelationalObjectTableRow> rows;
+    
+    unsigned int idOffset = 1;
+    std::map<unsigned int, unsigned int> idToIndex;
+    std::vector<SimpleObject> splitters
+      = objMgr->processMultiVersionObjects( objects, rows, 
+                                           idOffset, idToIndex );
+    
+    
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "splitters size", 
+                                  2u, (unsigned int)splitters.size() );
+    SimpleObject s = splitters[0];
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "int 1 object id", 1u, s.objectId );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "int 1 since", (ValidityKey)2, s.since );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "int 1 until", (ValidityKey)4, s.until );
+    s = splitters[1];
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "int 2 object id", 7u, s.objectId );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "int 2 since", (ValidityKey)1, s.since );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "int 2 until", (ValidityKey)2, s.until );
+    
+    //copy( rows.begin(), rows.end(),
+    //      std::ostream_iterator<RelationalObjectTableRow>( cout, "\n" ) );
+    
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "row count", 3u, (unsigned int)rows.size() );
+    
+    RelationalObjectTableRow row = rows[0];
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 object id", 1u, row.objectId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 payload", string("Object 1"),
+                                  row["S"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 since", (ValidityKey)2, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 until", (ValidityKey)4, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 original id", 0u, row.originalId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 new head id", 7u, row.newHeadId() );
+    
+    row = rows[1];
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 object id", 7u, row.objectId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 payload", string("Object 2"),
+                                  row["S"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 since", (ValidityKey)1, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 until", (ValidityKey)3, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 original id", 0u, row.originalId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 new head id", 0u, row.newHeadId() );
+    
+    row = rows[2];
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 object id", 9u, row.objectId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 payload", string("Object 1"),
+                                  row["S"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 since", (ValidityKey)3, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 until", (ValidityKey)4, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 original id", 1u, row.originalId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 new head id", 0u, row.newHeadId() );
+  }
+  
+  
+  /// Tests processMultiVersionObjects
+  void test_processMultiVersionObjects_case_1c() {
+    RelationalDatabasePtr dbPtr;
+    
+    vector<RelationalObjectPtr> objects;
+    objects.push_back( dummyObject( 1, 1, 4 ) );
+    objects.push_back( dummyObject( 2, 2, 3 ) );
+    
+    std::vector<RelationalObjectTableRow> rows;
+    
+    unsigned int idOffset = 1;
+    std::map<unsigned int, unsigned int> idToIndex;
+    std::vector<SimpleObject> splitters
+      = objMgr->processMultiVersionObjects( objects, rows, 
+                                           idOffset, idToIndex );
+    
+    
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "splitters size", 
+                                  1u, (unsigned int)splitters.size() );
+    SimpleObject s = splitters[0];
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "int 1 object id", 1u, s.objectId );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "int 1 since", (ValidityKey)1, s.since );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "int 1 until", (ValidityKey)4, s.until );
+    
+    //copy( rows.begin(), rows.end(),
+    //      std::ostream_iterator<RelationalObjectTableRow>( cout, "\n" ) );
+    
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "row count", 4u, (unsigned int)rows.size() );
+    
+    RelationalObjectTableRow row = rows[0];
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 object id", 1u, row.objectId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 payload", string("Object 1"),
+                                  row["S"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 since", (ValidityKey)1, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 until", (ValidityKey)4, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 original id", 0u, row.originalId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 new head id", 7u, row.newHeadId() );
+    
+    row = rows[1];
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 object id", 7u, row.objectId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 payload", string("Object 2"),
+                                  row["S"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 since", (ValidityKey)2, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 until", (ValidityKey)3, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 original id", 0u, row.originalId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 new head id", 0u, row.newHeadId() );
+    
+    row = rows[2];
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 object id", 8u, row.objectId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 payload", string("Object 1"),
+                                  row["S"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 since", (ValidityKey)1, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 until", (ValidityKey)2, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 original id", 1u, row.originalId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 new head id", 0u, row.newHeadId() );
+    
+    row = rows[3];
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "4 object id", 9u, row.objectId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "4 payload", string("Object 1"),
+                                  row["S"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "4 since", (ValidityKey)3, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "4 until", (ValidityKey)4, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "4 original id", 1u, row.originalId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "4 new head id", 0u, row.newHeadId() );
+  }
+  
+  
+  /// Tests processMultiVersionObjects
+  void test_processMultiVersionObjects_case_2() {
+    RelationalDatabasePtr dbPtr;
+    
+    vector<RelationalObjectPtr> objects;
+    objects.push_back( dummyObject( 1, 1, 5 ) );
+    objects.push_back( dummyObject( 2, 3, 6 ) );
+    objects.push_back( dummyObject( 3, 2, 4 ) );
+    
+    std::vector<RelationalObjectTableRow> rows;
+    
+    unsigned int idOffset = 1;
+    std::map<unsigned int, unsigned int> idToIndex;
+    std::vector<SimpleObject> splitters
+      = objMgr->processMultiVersionObjects( objects, rows, 
+                                           idOffset, idToIndex );
+    
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "splitters size", 
+                                  2u, (unsigned int)splitters.size() );
+    SimpleObject s = splitters[0];
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "int 1 object id", 1u, s.objectId );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "int 1 since", (ValidityKey)1, s.since );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "int 1 until", (ValidityKey)5, s.until );
+    s = splitters[1];
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "int 2 object id", 7u, s.objectId );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "int 2 since", (ValidityKey)5, s.since );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "int 2 until", (ValidityKey)6, s.until );
+    
+    
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "row count", 6u, (unsigned int)rows.size() );
+    
+    RelationalObjectTableRow row = rows[0];
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 object id", 1u, row.objectId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 since", (ValidityKey)1, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 until", (ValidityKey)5, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 payload", string("Object 1"),
+                                  row["S"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 original id", 0u, row.originalId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 new head id", 7u, row.newHeadId() );
+    
+    row = rows[1];
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 object id", 7u, row.objectId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 since", (ValidityKey)3, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 until", (ValidityKey)6, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 payload", string("Object 2"),
+                                  row["S"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 original id", 0u, row.originalId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 new head id", 13u, row.newHeadId() );
+    
+    row = rows[2];
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 object id", 8u, row.objectId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 since", (ValidityKey)1, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 until", (ValidityKey)3, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 payload", string("Object 1"),
+                                  row["S"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 original id", 1u, row.originalId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 new head id", 13u, row.newHeadId() );
+    
+    row = rows[3];
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "4 object id", 13u, row.objectId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "4 since", (ValidityKey)2, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "4 until", (ValidityKey)4, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "4 payload", string("Object 3"),
+                                  row["S"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "4 original id", 0u, row.originalId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "4 new head id", 0u, row.newHeadId() );
+    
+    row = rows[4];
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "5 object id", 14u, row.objectId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "5 since", (ValidityKey)1, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "5 until", (ValidityKey)2, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "5 payload", string("Object 1"),
+                                  row["S"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "5 original id", 8u, row.originalId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "5 new head id", 0u, row.newHeadId() );
+    
+    row = rows[5];
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "6 object id", 15u, row.objectId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "6 since", (ValidityKey)4, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "6 until", (ValidityKey)6, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "6 payload", string("Object 2"),
+                                  row["S"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "6 original id", 7u, row.originalId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "6 new head id", 0u, row.newHeadId() );
+  }
+  
+  
+  /// Tests processMultiVersionObjects
+  void test_processMultiVersionObjects_case_3() {
+    RelationalDatabasePtr dbPtr;
+    
+    vector<RelationalObjectPtr> objects;
+    objects.push_back( dummyObject( 1, 1, 8 ) );
+    objects.push_back( dummyObject( 2, 2, 5 ) );
+    objects.push_back( dummyObject( 3, 3, 6 ) );
+    objects.push_back( dummyObject( 4, 4, 7 ) );
+    
+    std::vector<RelationalObjectTableRow> rows;
+    
+    unsigned int idOffset = 1;
+    std::map<unsigned int, unsigned int> idToIndex;
+    std::vector<SimpleObject> splitters
+      = objMgr->processMultiVersionObjects( objects, rows, 
+                                           idOffset, idToIndex );
+    
+    /*cout << "splitters:\n";
+    copy( splitters.begin(), splitters.end(),
+          std::ostream_iterator<SimpleObject>( cout, "\n" ) );
+    cout << "rows:\n";
+    copy( rows.begin(), rows.end(),
+          std::ostream_iterator<RelationalObjectTableRow>( cout, "\n" ) );*/
+    
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "splitters size", 
+                                  1u, (unsigned int)splitters.size() );
+    SimpleObject s = splitters[0];
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "int 1 object id", 1u, s.objectId );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "int 1 since", (ValidityKey)1, s.since );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "int 1 until", (ValidityKey)8, s.until );
+    
+    
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "row count", 10u, (unsigned int)rows.size() );
+    
+    RelationalObjectTableRow row = rows[0];
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 object id", 1u, row.objectId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 since", (ValidityKey)1, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 until", (ValidityKey)8, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 payload", string("Object 1"),
+                                  row["S"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 original id", 0u, row.originalId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 new head id", 7u, row.newHeadId() );
+    
+    row = rows[1];
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 object id", 7u, row.objectId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 since", (ValidityKey)2, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 until", (ValidityKey)5, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 payload", string("Object 2"),
+                                  row["S"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 original id", 0u, row.originalId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 new head id", 13u, row.newHeadId() );
+    
+    row = rows[2];
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 object id", 8u, row.objectId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 since", (ValidityKey)1, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 until", (ValidityKey)2, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 payload", string("Object 1"),
+                                  row["S"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 original id", 1u, row.originalId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 new head id", 0u, row.newHeadId() );
+    
+    row = rows[3];
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "4 object id", 9u, row.objectId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "4 since", (ValidityKey)5, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "4 until", (ValidityKey)8, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "4 payload", string("Object 1"),
+                                  row["S"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "4 original id", 1u, row.originalId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "4 new head id", 13u, row.newHeadId() );
+    
+    row = rows[4];
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "5 object id", 13u, row.objectId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "5 since", (ValidityKey)3, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "5 until", (ValidityKey)6, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "5 payload", string("Object 3"),
+                                  row["S"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "5 original id", 0u, row.originalId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "5 new head id", 19u, row.newHeadId() );
+    
+    row = rows[5];
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "6 object id", 14u, row.objectId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "6 since", (ValidityKey)2, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "6 until", (ValidityKey)3, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "6 payload", string("Object 2"),
+                                  row["S"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "6 original id", 7u, row.originalId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "6 new head id", 0u, row.newHeadId() );
+    
+    row = rows[6];
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "7 object id", 15u, row.objectId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "7 since", (ValidityKey)6, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "7 until", (ValidityKey)8, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "7 payload", string("Object 1"),
+                                  row["S"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "7 original id", 9u, row.originalId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "7 new head id", 19u, row.newHeadId() );
+    
+    row = rows[7];
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "8 object id", 19u, row.objectId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "8 since", (ValidityKey)4, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "8 until", (ValidityKey)7, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "8 payload", string("Object 4"),
+                                  row["S"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "8 original id", 0u, row.originalId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "8 new head id", 0u, row.newHeadId() );
+    
+    row = rows[8];
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "9 object id", 20u, row.objectId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "9 since", (ValidityKey)3, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "9 until", (ValidityKey)4, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "9 payload", string("Object 3"),
+                                  row["S"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "9 original id", 13u, row.originalId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "9 new head id", 0u, row.newHeadId() );
+    
+    row = rows[9];
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "10 object id", 21u, row.objectId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "10 since", (ValidityKey)7, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "10 until", (ValidityKey)8, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "10 payload", string("Object 1"),
+                                  row["S"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "10 original id", 15u, row.originalId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "10 new head id", 0u, row.newHeadId() );
+  }
+  
+  
+  /// Tests processMultiVersionObjects
+  void test_processMultiVersionObjects_case_4() {
+    RelationalDatabasePtr dbPtr;
+    
+    vector<RelationalObjectPtr> objects;
+    objects.push_back( dummyObject( 1, 1, 4 ) );
+    objects.push_back( dummyObject( 2, 3, 7 ) );
+    objects.push_back( dummyObject( 3, 6, 8 ) );
+    objects.push_back( dummyObject( 4, 2, 5 ) );
+    
+    std::vector<RelationalObjectTableRow> rows;
+    
+    unsigned int idOffset = 1;
+    std::map<unsigned int, unsigned int> idToIndex;
+    std::vector<SimpleObject> splitters
+      = objMgr->processMultiVersionObjects( objects, rows, 
+                                           idOffset, idToIndex );
+    
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "splitters size", 
+                                  3u, (unsigned int)splitters.size() );
+    SimpleObject s = splitters[0];
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "int 1 object id", 1u, s.objectId );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "int 1 since", (ValidityKey)1, s.since );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "int 1 until", (ValidityKey)4, s.until );
+    s = splitters[1];
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "int 2 object id", 7u, s.objectId );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "int 2 since", (ValidityKey)4, s.since );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "int 2 until", (ValidityKey)7, s.until );
+    s = splitters[2];
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "int 3 object id", 13u, s.objectId );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "int 3 since", (ValidityKey)7, s.since );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "int 3 until", (ValidityKey)8, s.until );
+    
+    
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "row count", 8u, (unsigned int)rows.size() );
+    
+    RelationalObjectTableRow row = rows[0];
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 object id", 1u, row.objectId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 since", (ValidityKey)1, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 until", (ValidityKey)4, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 payload", string("Object 1"),
+                                  row["S"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 original id", 0u, row.originalId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 new head id", 7u, row.newHeadId() );
+    
+    row = rows[1];
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 object id", 7u, row.objectId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 since", (ValidityKey)3, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 until", (ValidityKey)7, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 payload", string("Object 2"),
+                                  row["S"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 original id", 0u, row.originalId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 new head id", 13u, row.newHeadId() );
+    
+    row = rows[2];
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 object id", 8u, row.objectId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 since", (ValidityKey)1, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 until", (ValidityKey)3, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 payload", string("Object 1"),
+                                  row["S"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 original id", 1u, row.originalId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 new head id", 19u, row.newHeadId() );
+    
+    row = rows[3];
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "4 object id", 13u, row.objectId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "4 since", (ValidityKey)6, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "4 until", (ValidityKey)8, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "4 payload", string("Object 3"),
+                                  row["S"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "4 original id", 0u, row.originalId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "4 new head id", 0u, row.newHeadId() );
+    
+    row = rows[4];
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "5 object id", 14u, row.objectId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "5 since", (ValidityKey)3, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "5 until", (ValidityKey)6, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "5 payload", string("Object 2"),
+                                  row["S"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "5 original id", 7u, row.originalId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "5 new head id", 19u, row.newHeadId() );
+    
+    row = rows[5];
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "6 object id", 19u, row.objectId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "6 since", (ValidityKey)2, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "6 until", (ValidityKey)5, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "6 payload", string("Object 4"),
+                                  row["S"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "6 original id", 0u, row.originalId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "6 new head id", 0u, row.newHeadId() );
+    
+    row = rows[6];
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "7 object id", 20u, row.objectId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "7 since", (ValidityKey)1, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "7 until", (ValidityKey)2, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "7 payload", string("Object 1"),
+                                  row["S"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "7 original id", 8u, row.originalId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "7 new head id", 0u, row.newHeadId() );
+    
+    row = rows[7];
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "8 object id", 21u, row.objectId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "8 since", (ValidityKey)5, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "8 until", (ValidityKey)6, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "8 payload", string("Object 2"),
+                                  row["S"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "8 original id", 14u, row.originalId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "8 new head id", 0u, row.newHeadId() );
+  }
+  
+  
+  /// Tests processMultiVersionObjects
+  void test_processMultiVersionObjects_case_5b() {
+    RelationalDatabasePtr dbPtr;
+    
+    vector<RelationalObjectPtr> objects;
+    objects.push_back( dummyObject( 1, 1, 3 ) );
+    objects.push_back( dummyObject( 2, 6, 8 ) );
+    objects.push_back( dummyObject( 3, 2, 4 ) );
+    objects.push_back( dummyObject( 4, 5, 7 ) );
+    
+    std::vector<RelationalObjectTableRow> rows;
+    
+    unsigned int idOffset = 1;
+    std::map<unsigned int, unsigned int> idToIndex;
+    
+    std::vector<SimpleObject> splitters
+      = objMgr->processMultiVersionObjects( objects, rows, 
+                                           idOffset, idToIndex );
+    
+    /*cout << "splitters:\n";
+    copy( splitters.begin(), splitters.end(),
+          std::ostream_iterator<SimpleObject>( cout, "\n" ) );
+    cout << "rows:\n";
+    copy( rows.begin(), rows.end(),
+          std::ostream_iterator<RelationalObjectTableRow>( cout, "\n" ) );*/
+    
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "splitters size", 
+                                  4u, (unsigned int)splitters.size() );
+    
+    SimpleObject s = splitters[0];
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "int 1 object id", 1u, s.objectId );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "int 1 since", (ValidityKey)1, s.since );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "int 1 until", (ValidityKey)3, s.until );
+    s = splitters[1];
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "int 2 object id", 7u, s.objectId );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "int 2 since", (ValidityKey)6, s.since );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "int 2 until", (ValidityKey)8, s.until );
+    s = splitters[2];
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "int 3 object id", 13u, s.objectId );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "int 3 since", (ValidityKey)3, s.since );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "int 3 until", (ValidityKey)4, s.until );
+    s = splitters[3];
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "int 2 object id", 19u, s.objectId );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "int 2 since", (ValidityKey)5, s.since );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "int 2 until", (ValidityKey)6, s.until );
+    
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "row count", 6u, (unsigned int)rows.size() );
+    
+    RelationalObjectTableRow row = rows[0];
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 object id", 1u, row.objectId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 since", (ValidityKey)1, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 until", (ValidityKey)3, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 payload", string("Object 1"),
+                                  row["S"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 original id", 0u, row.originalId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 new head id", 13u, row.newHeadId() );
+    
+    row = rows[1];
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 object id", 7u, row.objectId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 since", (ValidityKey)6, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 until", (ValidityKey)8, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 payload", string("Object 2"),
+                                  row["S"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 original id", 0u, row.originalId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 new head id", 19u, row.newHeadId() );
+    
+    row = rows[2];
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 object id", 13u, row.objectId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 since", (ValidityKey)2, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 until", (ValidityKey)4, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 payload", string("Object 3"),
+                                  row["S"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 original id", 0u, row.originalId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 new head id", 0u, row.newHeadId() );
+    
+    row = rows[3];
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "4 object id", 14u, row.objectId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "4 since", (ValidityKey)1, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "4 until", (ValidityKey)2, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "4 payload", string("Object 1"),
+                                  row["S"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "4 original id", 1u, row.originalId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "4 new head id", 0u, row.newHeadId() );
+    
+    row = rows[4];
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "5 object id", 19u, row.objectId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "5 since", (ValidityKey)5, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "5 until", (ValidityKey)7, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "5 payload", string("Object 4"),
+                                  row["S"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "5 original id", 0u, row.originalId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "5 new head id", 0u, row.newHeadId() );
+    
+    row = rows[5];
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "6 object id", 21u, row.objectId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "6 since", (ValidityKey)7, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "6 until", (ValidityKey)8, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "6 payload", string("Object 2"),
+                                  row["S"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "6 original id", 7u, row.originalId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "6 new head id", 0u, row.newHeadId() );
+    
+  }
+  
+  
+  /// Tests updateObjectTableNewHeadId
+  void test_updateObjectTableNewHeadId_1() {
+    IFolderPtr folder = ralDb->createFolder( "/myfolder", payloadSpec );
+    RelationalFolder* relfolder = dynamic_cast<RelationalFolder*>(folder.get());
+    
+    vector<RelationalObjectPtr> objs;
+    objs.push_back( dummyObject( 1, 1, 3 ) );
+    storeObjects( relfolder, objs );
+    
+    RelationalObjectTable 
+      objectTable( &(ralDb->queryMgr()), false, *relfolder );
+    {
+      RelationalTransaction transaction( ralDb->transactionMgr() );
+      bool fetchPayload = true;
+      RelationalObjectTableRow
+        row( objectTable.fetchRowForId( 1u, fetchPayload ) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "object_id 1", 1u, row.objectId() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "new_head_id 1", 0u, row.newHeadId() );
+      transaction.commit();
+    }
+    
+    {
+      RelationalTransaction transaction( ralDb->transactionMgr() );
+      
+      // now update the new head id
+      updateObjectTableNewHeadId( objMgr.get(),
+                                  relfolder->objectTableName(),
+                                  relfolder->channelTableName(),
+                                  (ValidityKey)2, 
+                                  (ValidityKey)4,
+                                  (ChannelId)0,
+                                  5u );
+      transaction.commit();
+    }
+    
+    {
+      RelationalTransaction transaction( ralDb->transactionMgr() );      
+      bool fetchPayload = true;
+      RelationalObjectTableRow
+        row( objectTable.fetchRowForId( 1u, fetchPayload ) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "object_id 2", 1u, row.objectId() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "new_head_id 2", 5u, row.newHeadId() );
+      transaction.commit();
+    }
+  }
+  
+  
+  /// Tests updateObjectTableNewHeadId
+  void test_updateObjectTableNewHeadId_2() {
+    IFolderPtr folder = ralDb->createFolder( "/myfolder", payloadSpec );
+    RelationalFolder* relfolder = dynamic_cast<RelationalFolder*>(folder.get());
+    
+    vector<RelationalObjectPtr> objs;
+    objs.push_back( dummyObject( 1, 0, 2 ) );
+    objs.push_back( dummyObject( 2, 2, 4 ) );
+    storeObjects( relfolder, objs );
+    
+    RelationalObjectTable 
+      objectTable( &(ralDb->queryMgr()), false, *relfolder );
+    {
+      RelationalTransaction transaction( ralDb->transactionMgr() );
+      bool fetchPayload = true;
+      
+      RelationalObjectTableRow
+        row1( objectTable.fetchRowForId( 1u, fetchPayload ) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "object_id 1", 1u, row1.objectId() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "new_head_id 1", 0u, row1.newHeadId() );
+      
+      RelationalObjectTableRow
+        row2( objectTable.fetchRowForId( 2u, fetchPayload ) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "object_id 2", 2u, row2.objectId() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "new_head_id 2", 0u,row2.newHeadId() );
+      transaction.commit();
+    }
+    
+    {
+      RelationalTransaction transaction( ralDb->transactionMgr() );
+      
+      // now update the new head id
+      updateObjectTableNewHeadId( objMgr.get(),
+                                  relfolder->objectTableName(),
+                                  relfolder->channelTableName(),
+                                  (ValidityKey)1, 
+                                  (ValidityKey)2,
+                                  (ChannelId)0,
+                                  5u );
+      transaction.commit();
+    }
+    
+    {
+      RelationalTransaction transaction( ralDb->transactionMgr() );      
+      bool fetchPayload = true;
+
+      RelationalObjectTableRow
+        row1( objectTable.fetchRowForId( 1u, fetchPayload ) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "object_id 3", 1u, row1.objectId() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "new_head_id 3", 5u, row1.newHeadId() );
+      
+      RelationalObjectTableRow
+        row2( objectTable.fetchRowForId( 2u, fetchPayload ) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "object_id 4", 2u, row2.objectId() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "new_head_id 4", 0u, row2.newHeadId() );      
+      transaction.commit();
+    }
+  }
+  
+  
+  /// Tests updateObjectTableNewHeadId
+  void test_updateObjectTableNewHeadId_3() {
+    IFolderPtr folder = ralDb->createFolder( "/myfolder", payloadSpec );
+    RelationalFolder* relfolder = dynamic_cast<RelationalFolder*>(folder.get());
+    
+    vector<RelationalObjectPtr> objs;
+    objs.push_back( dummyObject( 1, 2, 4 ) );
+    storeObjects( relfolder, objs );
+    
+    RelationalObjectTable 
+      objectTable( &(ralDb->queryMgr()), false, *relfolder );
+    
+    {
+      RelationalTransaction transaction( ralDb->transactionMgr() );
+      bool fetchPayload = true;
+      RelationalObjectTableRow
+        row( objectTable.fetchRowForId( 1u, fetchPayload ) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "object_id 1", 1u, row.objectId() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "new_head_id 1", 0u, row.newHeadId() );
+      transaction.commit();
+    }
+    
+    {
+      RelationalTransaction transaction( ralDb->transactionMgr() );
+      
+      // now update the new head id
+      updateObjectTableNewHeadId( objMgr.get(),
+                                  relfolder->objectTableName(),
+                                  relfolder->channelTableName(),
+                                  (ValidityKey)1, 
+                                  (ValidityKey)3,
+                                  (ChannelId)0,
+                                  5u );
+      transaction.commit();
+    }
+    
+    {
+      RelationalTransaction transaction( ralDb->transactionMgr() );
+      bool fetchPayload = true;      
+      RelationalObjectTableRow
+        row( objectTable.fetchRowForId( 1u, fetchPayload ) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "object_id 2", 1u, row.objectId() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "new_head_id 2", 5u, row.newHeadId() );
+      transaction.commit();
+    }
+  }
+  
+  
+  /// Tests mergeWithHead
+  void test_mergeWithHead_case_3() {
+    IFolderPtr folder = ralDb->createFolder( "/myfolder", 
+                                             payloadSpec,
+                                             "my description",
+                                             FolderVersioning::MULTI_VERSION );
+    RelationalFolder* relfolder = dynamic_cast<RelationalFolder*>(folder.get());
+    
+    // Prepare a persistent HEAD
+    { vector<RelationalObjectPtr> objects;
+      objects.push_back( dummyObject( 1, 1, 8 ) );
+      storeObjects( relfolder, objects );
+    }
+    
+    // Run the prerequisite logic of storeMultiVersionObjects
+    vector<RelationalObjectPtr> objects;
+    objects.push_back( dummyObject( 2, 2, 5 ) );
+    objects.push_back( dummyObject( 3, 3, 6 ) );
+    objects.push_back( dummyObject( 4, 4, 7 ) );
+
+    std::vector<RelationalObjectTableRow> rows;
+    
+    RelationalTransaction transaction( ralDb->transactionMgr() );
+    boost::shared_ptr<RelationalSequence> seq
+      ( ralDb->queryMgr().sequenceMgr().getSequence
+        ( RelationalObjectTable::sequenceName
+          ( relfolder->objectTableName() ) ) );
+    unsigned int objectIdOffset = seq->currVal() +1;
+    std::map<unsigned int, unsigned int> idToIndex;
+    std::vector<SimpleObject> intersectors
+      = objMgr->processMultiVersionObjects( objects, rows, 
+                                           objectIdOffset, idToIndex );
+
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "row count 1", 
+                                  5u, (unsigned int)rows.size() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "intersector count", 
+                                  3u, (unsigned int)intersectors.size() );
+
+    objMgr->mergeWithHead( relfolder, intersectors, 
+                          rows, idToIndex );
+    sort( rows.begin(), rows.end(), lt_objectId() );
+        
+    transaction.commit();
+    
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "row count 2", 
+                                  9u, (unsigned int)rows.size() );
+    
+    RelationalObjectTableRow row = rows[0];
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 object id", 7u, row.objectId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 since", (ValidityKey)2, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 until", (ValidityKey)5, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 payload", string("Object 2"),
+                                  row["S"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 original id", 0u, row.originalId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 new head id", 13u, row.newHeadId() );
+    
+    row = rows[1];
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 object id", 8u, row.objectId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 since", (ValidityKey)1, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 until", (ValidityKey)2, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 payload", string("Object 1"),
+                                  row["S"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 original id", 1u, row.originalId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 new head id", 0u, row.newHeadId() );
+    
+    row = rows[2];
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "4 object id", 9u, row.objectId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "4 since", (ValidityKey)5, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "4 until", (ValidityKey)8, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "4 payload", string("Object 1"),
+                                  row["S"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "4 original id", 1u, row.originalId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "4 new head id", 13u, row.newHeadId() );
+    
+    row = rows[3];
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "5 object id", 13u, row.objectId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "5 since", (ValidityKey)3, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "5 until", (ValidityKey)6, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "5 payload", string("Object 3"),
+                                  row["S"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "5 original id", 0u, row.originalId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "5 new head id", 19u, row.newHeadId() );
+    
+    row = rows[4];
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "6 object id", 14u, row.objectId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "6 since", (ValidityKey)2, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "6 until", (ValidityKey)3, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "6 payload", string("Object 2"),
+                                  row["S"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "6 original id", 7u, row.originalId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "6 new head id", 0u, row.newHeadId() );
+    
+    row = rows[5];
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "7 object id", 15u, row.objectId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "7 since", (ValidityKey)6, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "7 until", (ValidityKey)8, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "7 payload", string("Object 1"),
+                                  row["S"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "7 original id", 9u, row.originalId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "7 new head id", 19u, row.newHeadId() );
+    
+    row = rows[6];
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "8 object id", 19u, row.objectId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "8 since", (ValidityKey)4, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "8 until", (ValidityKey)7, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "8 payload", string("Object 4"),
+                                  row["S"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "8 original id", 0u, row.originalId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "8 new head id", 0u, row.newHeadId() );
+    
+    row = rows[7];
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "9 object id", 20u, row.objectId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "9 since", (ValidityKey)3, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "9 until", (ValidityKey)4, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "9 payload", string("Object 3"),
+                                  row["S"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "9 original id", 13u, row.originalId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "9 new head id", 0u, row.newHeadId() );
+    
+    row = rows[8];
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "10 object id", 21u, row.objectId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "10 since", (ValidityKey)7, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "10 until", (ValidityKey)8, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "10 payload", string("Object 1"),
+                                  row["S"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "10 original id", 15u, row.originalId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "10 new head id", 0u, row.newHeadId() );
+  }
+  
+  
+  /// Tests mergeWithHead
+  void test_mergeWithHead_case_1b() {
+    IFolderPtr folder = ralDb->createFolder( "/myfolder", 
+                                             payloadSpec,
+                                             "my description",
+                                             FolderVersioning::MULTI_VERSION );
+    RelationalFolder* relfolder = dynamic_cast<RelationalFolder*>(folder.get());
+    
+    // Prepare a persistent HEAD
+    { vector<RelationalObjectPtr> objects;
+      objects.push_back( dummyObject( 1, 2, 4 ) );
+      storeObjects( relfolder, objects );
+    }
+    
+    // Run the prerequisite logic of storeMultiVersionObjects
+    vector<RelationalObjectPtr> objects;
+    objects.push_back( dummyObject( 2, 1, 3 ) );
+    
+    std::vector<RelationalObjectTableRow> rows;
+    
+    RelationalTransaction transaction( ralDb->transactionMgr() );
+    boost::shared_ptr<RelationalSequence> seq
+      ( ralDb->queryMgr().sequenceMgr().getSequence
+        ( RelationalObjectTable::sequenceName
+          ( relfolder->objectTableName() ) ) );
+    unsigned int objectIdOffset = seq->currVal() +1;
+    std::map<unsigned int, unsigned int> idToIndex;
+    std::vector<SimpleObject> intersectors
+      = objMgr->processMultiVersionObjects( objects, rows, 
+                                           objectIdOffset, idToIndex );
+    
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "row count 1", 1u, 
+                                  (unsigned int)rows.size() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "intersector count", 
+                                  1u, (unsigned int)intersectors.size() );
+
+    objMgr->mergeWithHead( relfolder, intersectors, 
+                          rows, idToIndex );
+    
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "row count 2", 2u, 
+                                  (unsigned int)rows.size() );
+    
+    // check the persistent head
+    RelationalObjectTable 
+      objectTable( &(ralDb->queryMgr()), false, *relfolder );
+    bool fetchPayload = true;
+    RelationalObjectTableRow
+      row( objectTable.fetchRowForId( 1u, fetchPayload ) );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 object id", 1u, row.objectId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 since", (ValidityKey)2, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 until", (ValidityKey)4, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 payload", string("Object 1"),
+                                  row["S"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 original id", 0u, row.originalId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 new head id", 7u, row.newHeadId() );
+    
+    // and the transient rows
+    row = rows[0];
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 object id", 7u, row.objectId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 since", (ValidityKey)1, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 until", (ValidityKey)3, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 payload", string("Object 2"),
+                                  row["S"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 original id", 0u, row.originalId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 new head id", 0u, row.newHeadId() );
+    
+    row = rows[1];
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 object id", 9u, row.objectId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 since", (ValidityKey)3, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 until", (ValidityKey)4, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 payload", string("Object 1"),
+                                  row["S"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 original id", 1u, row.originalId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 new head id", 0u, row.newHeadId() );
+  }
+  
+  
+  /// Tests mergeWithHead
+  void test_mergeWithHead_case_1a() {
+    try {
+    IFolderPtr folder = ralDb->createFolder( "/myfolder", 
+                                             payloadSpec,
+                                             "my description",
+                                             FolderVersioning::MULTI_VERSION );
+    RelationalFolder* relfolder = dynamic_cast<RelationalFolder*>(folder.get());
+    
+    // Prepare a persistent HEAD
+    { vector<RelationalObjectPtr> objects;
+      objects.push_back( dummyObject( 1, 1, 3 ) );
+      storeObjects( relfolder, objects );
+    }
+    
+    // Run the prerequisite logic of storeMultiVersionObjects
+    vector<RelationalObjectPtr> objects;
+    objects.push_back( dummyObject( 2, 2, 4 ) );
+    
+    std::vector<RelationalObjectTableRow> rows;
+    
+    RelationalTransaction transaction( ralDb->transactionMgr() );
+    boost::shared_ptr<RelationalSequence> seq
+      ( ralDb->queryMgr().sequenceMgr().getSequence
+        ( RelationalObjectTable::sequenceName
+          ( relfolder->objectTableName() ) ) );
+    unsigned int objectIdOffset = seq->currVal() +1;
+    std::map<unsigned int, unsigned int> idToIndex;
+    std::vector<SimpleObject> intersectors
+      = objMgr->processMultiVersionObjects( objects, rows, 
+                                           objectIdOffset, idToIndex );
+    
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "row count 1", 
+                                  1u, (unsigned int)rows.size() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "intersector count", 
+                                  1u, (unsigned int)intersectors.size() );
+
+    objMgr->mergeWithHead( relfolder, intersectors, 
+                          rows, idToIndex );
+    
+    //copy( rows.begin(), rows.end(), 
+    //      std::ostream_iterator<RelationalObjectTableRow>( cout, "\n" ) );
+    
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "row count 2", 
+                                  2u, (unsigned int)rows.size() );
+    
+    // check the persistent head
+    RelationalObjectTable 
+      objectTable( &(ralDb->queryMgr()), false, *relfolder );
+    bool fetchPayload = true;
+    RelationalObjectTableRow
+      row( objectTable.fetchRowForId( 1u, fetchPayload ) );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 object id", 1u, row.objectId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 since", (ValidityKey)1, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 until", (ValidityKey)3, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 payload", string("Object 1"),
+                                  row["S"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 original id", 0u, row.originalId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 new head id", 7u, row.newHeadId() );
+    
+    // and the transient rows
+    row = rows[0];
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 object id", 7u, row.objectId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 since", (ValidityKey)2, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 until", (ValidityKey)4, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 payload", string("Object 2"),
+                                  row["S"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 original id", 0u, row.originalId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 new head id", 0u, row.newHeadId() );
+    
+    row = rows[1];
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 object id", 8u, row.objectId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 since", (ValidityKey)1, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 until", (ValidityKey)2, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 payload", string("Object 1"),
+                                  row["S"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 original id", 1u, row.originalId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 new head id", 0u, row.newHeadId() );
+    } catch ( std::exception& e ) {
+      cout << e.what() << endl;
+      throw;
+    }
+  }
+  
+  
+  /// Tests the writing of all object attributes in the MV mode
+  void test_storeObjects_MV_newInsert() {
+    try {
+      IFolderPtr folder = 
+        ralDb->createFolder( "/myfolder", 
+                             payloadSpec,
+                             "my description",
+                             FolderVersioning::MULTI_VERSION );
+      RelationalFolder* relfolder = 
+        dynamic_cast<RelationalFolder*>(folder.get());
+      
+      vector<RelationalObjectPtr> objs;
+      objs.push_back( dummyObject( 2, 2, 10 ) );
+      storeObjects( relfolder, objs );
+      
+      unsigned int object_id = 1;
+      
+      RelationalTransaction transaction( ralDb->transactionMgr() );
+      RelationalObjectTable 
+        objectTable( &(ralDb->queryMgr()), false, *relfolder );
+      bool fetchPayload = true;
+      RelationalObjectTableRow
+        row( objectTable.fetchRowForId( object_id, fetchPayload ) );
+      transaction.commit();
+      
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "object_id", 1u, row.objectId() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "channel id", 0u, row.channelId() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "since", (ValidityKey)2, row.since() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "until", (ValidityKey)10, row.until() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "instime", string("yyyy-mm-dd_hh:mm:ss.nnnnnnnnn GMT").size(), 
+          timeToString(row.insertionTime()).size() );    
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "field I", 2, 
+                                    row["I"].data<int>() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "field S", string("Object 2"), 
+                                    row["S"].data<std::string>() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "field X", 0.002f, 
+                                    row["X"].data<float>() );
+      
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "original id", 0u, row.originalId() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "new_head id", 0u, row.newHeadId() );
+    } catch ( std::exception& e ) {
+      cout << e.what() << endl;
+      throw;
+    }
+  }
+  
+  
+  /// Tests storeObjects in MV mode when inserting over an object with
+  /// identical IOVs
+  /// Followup on bug report by Marco Clemencic 2005-03-17
+  void test_storeObjects_MV_identicalIov_case_2() {
+    IFolderPtr folder = ralDb->createFolder( "/myfolder", 
+                                             payloadSpec,
+                                             "my description",
+                                             FolderVersioning::MULTI_VERSION );
+    RelationalFolder* relfolder = dynamic_cast<RelationalFolder*>(folder.get());
+    
+    { vector<RelationalObjectPtr> objs;
+      objs.push_back( dummyObject( 1, 0, 2 ) );
+      objs.push_back( dummyObject( 2, 2, 4 ) );
+      storeObjects( relfolder, objs );
+    }
+    { vector<RelationalObjectPtr> objs;
+      objs.push_back( dummyObject( 3, 0, 2 ) );
+      storeObjects( relfolder, objs );
+    }
+    
+    RelationalTransaction transaction( ralDb->transactionMgr() );
+    
+    {
+      coral::ITable& objectTable = 
+      ralDb->session().nominalSchema().tableHandle
+      ( relfolder->objectTableName() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "row count", 
+                                    3u, rowCount( objectTable ) );
+    }
+    
+    RelationalObjectTable 
+      objectTable( &(ralDb->queryMgr()), false, *relfolder );
+    bool fetchPayload = true;
+    
+    RelationalObjectTableRow
+      row( objectTable.fetchRowForId( 1u, fetchPayload ) );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 object id", 1u, row.objectId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 since", (ValidityKey)0, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 until", (ValidityKey)2, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 payload", string("Object 1"),
+                                  row["S"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 original id", 0u, row.originalId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 new head id", 13u, row.newHeadId() );
+    
+    row = objectTable.fetchRowForId( 7u, fetchPayload );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 object id", 7u, row.objectId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 since", (ValidityKey)2, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 until", (ValidityKey)4, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 payload", string("Object 2"),
+                                  row["S"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 original id", 0u, row.originalId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 new head id", 0u, row.newHeadId() );
+    
+    row = objectTable.fetchRowForId( 13u, fetchPayload );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 object id", 13u, row.objectId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 since", (ValidityKey)0, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 until", (ValidityKey)2, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 payload", string("Object 3"),
+                                  row["S"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 original id", 0u, row.originalId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 new head id", 0u, row.newHeadId() );
+  }
+  
+  
+  /// Tests storeObjects in MV mode when inserting over an object with
+  /// identical IOVs
+  /// Followup on bug report by Marco Clemencic 2005-03-17
+  void test_storeObjects_MV_identicalIov_case_1() {
+    IFolderPtr folder = ralDb->createFolder( "/myfolder", 
+                                             payloadSpec,
+                                             "my description",
+                                             FolderVersioning::MULTI_VERSION );
+    RelationalFolder* relfolder = dynamic_cast<RelationalFolder*>(folder.get());
+    
+    { vector<RelationalObjectPtr> objs;
+      objs.push_back( dummyObject( 1, 0, 2 ) );
+      objs.push_back( dummyObject( 2, 2, 4 ) );
+      storeObjects( relfolder, objs );
+    }
+    { vector<RelationalObjectPtr> objs;
+      objs.push_back( dummyObject( 3, 2, 4 ) );
+      storeObjects( relfolder, objs );
+    }
+    
+    RelationalTransaction transaction( ralDb->transactionMgr() );
+    
+    {
+      coral::ITable& objectTable = 
+      ralDb->session().nominalSchema().tableHandle
+      ( relfolder->objectTableName() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "row count", 
+                                    3u, rowCount( objectTable ) );
+    }
+    
+    RelationalObjectTable 
+      objectTable( &(ralDb->queryMgr()), false, *relfolder );
+    bool fetchPayload = true;
+
+    RelationalObjectTableRow
+      row( objectTable.fetchRowForId( 1u, fetchPayload ) );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 object id", 1u, row.objectId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 since", (ValidityKey)0, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 until", (ValidityKey)2, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 payload", string("Object 1"),
+                                  row["S"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 original id", 0u, row.originalId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 new head id", 0u, row.newHeadId() );
+    
+    row = objectTable.fetchRowForId( 7u, fetchPayload );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 object id", 7u, row.objectId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 since", (ValidityKey)2, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 until", (ValidityKey)4, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 payload", string("Object 2"),
+                                  row["S"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 original id", 0u, row.originalId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 new head id", 13u, row.newHeadId() );
+    
+    row = objectTable.fetchRowForId( 13u, fetchPayload );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 object id", 13u, row.objectId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 since", (ValidityKey)2, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 until", (ValidityKey)4, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 payload", string("Object 3"),
+                                  row["S"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 original id", 0u, row.originalId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 new head id", 0u, row.newHeadId() );
+  }
+  
+
+  /// Tests storeObjects in MV mode for different channels
+  /// This stores the same objects as the single channel test case_5b
+  /// into channel 1 and those from case_6 into channel 0
+  void test_storeObjects_MV_case_5b_6_channels() {
+    IFolderPtr folder = ralDb->createFolder( "/myfolder", 
+                                             payloadSpec,
+                                             "my description",
+                                             FolderVersioning::MULTI_VERSION );
+    RelationalFolder* relfolder = dynamic_cast<RelationalFolder*>(folder.get());
+    
+    { // begin case_5b storage in channel 1
+      ChannelId ch = 1;
+      { vector<RelationalObjectPtr> objs;
+        objs.push_back( dummyObject( 1, 1, 3, ch ) );
+        objs.push_back( dummyObject( 2, 6, 8, ch ) );
+        storeObjects( relfolder, objs );
+      }
+      
+      { vector<RelationalObjectPtr> objs;
+        objs.push_back( dummyObject( 3, 2, 4, ch ) );
+        objs.push_back( dummyObject( 4, 5, 7, ch ) );
+        storeObjects( relfolder, objs );
+      }
+    } // end
+    
+    { // begin case_6 storage in channel 2
+      ChannelId ch = 2;
+      { vector<RelationalObjectPtr> objs;
+        objs.push_back( dummyObject( 1, 7, 9, ch ) );
+        objs.push_back( dummyObject( 2, 6, 7, ch ) );
+        objs.push_back( dummyObject( 3, 1, 5, ch ) );
+        storeObjects( relfolder, objs );
+      }
+      
+      { vector<RelationalObjectPtr> objs;
+        objs.push_back( dummyObject( 4, 2, 3, ch ) );
+        objs.push_back( dummyObject( 5, 4, 8, ch ) );
+        storeObjects( relfolder, objs );
+      }
+    } // end
+
+    RelationalTransaction transaction( ralDb->transactionMgr() );
+    
+    {
+      coral::ITable& objectTable = 
+      ralDb->session().nominalSchema().tableHandle
+      ( relfolder->objectTableName() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "row count", 
+                                    15u, rowCount( objectTable ) );
+    }
+    
+    RelationalObjectTable 
+      objectTable( &(ralDb->queryMgr()), false, *relfolder );
+
+    // read back objects in channel 1
+    bool fetchPayload = true;
+    RelationalObjectTableRow
+      row( objectTable.fetchRowForId( 1u, fetchPayload ) );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 object id", 1u, row.objectId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 channel id", 1u, row.channelId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 since", (ValidityKey)1, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 until", (ValidityKey)3, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 payload", string("Object 1"),
+                                  row["S"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 original id", 0u, row.originalId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 new head id", 13u, row.newHeadId() );
+    
+    row = objectTable.fetchRowForId( 7u, fetchPayload );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 object id", 7u, row.objectId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 channel id", 1u, row.channelId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 since", (ValidityKey)6, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 until", (ValidityKey)8, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 payload", string("Object 2"),
+                                  row["S"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 original id", 0u, row.originalId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 new head id", 19u, row.newHeadId() );
+    
+    row = objectTable.fetchRowForId( 13u, fetchPayload );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 object id", 13u, row.objectId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 channel id", 1u, row.channelId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 since", (ValidityKey)2, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 until", (ValidityKey)4, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 payload", string("Object 3"),
+                                  row["S"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 original id", 0u, row.originalId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 new head id", 0u, row.newHeadId() );
+    
+    row = objectTable.fetchRowForId( 14u, fetchPayload );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "4 object id", 14u, row.objectId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "4 channel id", 1u, row.channelId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "4 since", (ValidityKey)1, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "4 until", (ValidityKey)2, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "4 payload", string("Object 1"),
+                                  row["S"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "4 original id", 1u, row.originalId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "4 new head id", 0u, row.newHeadId() );
+    
+    row = objectTable.fetchRowForId( 19u, fetchPayload );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "5 object id", 19u, row.objectId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "5 channel id", 1u, row.channelId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "5 since", (ValidityKey)5, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "5 until", (ValidityKey)7, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "5 payload", string("Object 4"),
+                                  row["S"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "5 original id", 0u, row.originalId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "5 new head id", 0u, row.newHeadId() );
+    
+    row = objectTable.fetchRowForId( 21u, fetchPayload );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "6 object id", 21u, row.objectId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "6 channel id", 1u, row.channelId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "6 since", (ValidityKey)7, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "6 until", (ValidityKey)8, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "6 payload", string("Object 2"),
+                                  row["S"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "6 original id", 7u, row.originalId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "6 new head id", 0u, row.newHeadId() );
+
+    // read back objects in channel 2
+    row = objectTable.fetchRowForId( 25u, fetchPayload );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "7 object id", 25u, row.objectId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "7 channel id", 2u, row.channelId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "7 since", (ValidityKey)7, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "7 until", (ValidityKey)9, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "7 payload", string("Object 1"),
+                                  row["S"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "7 original id", 0u, row.originalId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "7 new head id", 49u, row.newHeadId() );
+    
+    row = objectTable.fetchRowForId( 31u, fetchPayload );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "8 object id", 31u, row.objectId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "8 channel id", 2u, row.channelId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "8 since", (ValidityKey)6, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "8 until", (ValidityKey)7, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "8 payload", string("Object 2"),
+                                  row["S"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "8 original id", 0u, row.originalId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "8 new head id", 49u, row.newHeadId() );
+    
+    row = objectTable.fetchRowForId( 37u, fetchPayload );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "9 object id", 37u, row.objectId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "9 channel id", 2u, row.channelId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "9 since", (ValidityKey)1, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "9 until", (ValidityKey)5, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "9 payload", string("Object 3"),
+                                  row["S"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "9 original id", 0u, row.originalId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "9 new head id", 43u, row.newHeadId() );
+    
+    row = objectTable.fetchRowForId( 43u, fetchPayload );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "10 object id", 43u, row.objectId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "10 channel id", 2u, row.channelId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "10 since", (ValidityKey)2, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "10 until", (ValidityKey)3, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "10 payload", string("Object 4"),
+                                  row["S"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "10 original id", 0u, row.originalId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "10 new head id", 0u, row.newHeadId() );
+    
+    row = objectTable.fetchRowForId( 44u, fetchPayload );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "11 object id", 44u, row.objectId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "11 channel id", 2u, row.channelId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "11 since", (ValidityKey)1, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "11 until", (ValidityKey)2, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "11 payload", string("Object 3"),
+                                  row["S"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "11 original id", 37u, row.originalId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "11 new head id", 0u, row.newHeadId() );
+    
+    row = objectTable.fetchRowForId( 45u, fetchPayload );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "12 object id", 45u, row.objectId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "12 channel id", 2u, row.channelId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "12 since", (ValidityKey)3, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "12 until", (ValidityKey)5, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "12 payload", string("Object 3"),
+                                  row["S"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "12 original id", 37u, row.originalId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "12 new head id", 49u, row.newHeadId() );
+    
+    row = objectTable.fetchRowForId( 49u, fetchPayload );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "13 object id", 49u, row.objectId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "13 channel id", 2u, row.channelId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "13 since", (ValidityKey)4, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "13 until", (ValidityKey)8, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "13 payload", string("Object 5"),
+                                  row["S"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "13 original id", 0u, row.originalId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "13 new head id", 0u, row.newHeadId() );
+    
+    row = objectTable.fetchRowForId( 50u, fetchPayload );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "14 object id", 50u, row.objectId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "14 channel id", 2u, row.channelId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "14 since", (ValidityKey)3, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "14 until", (ValidityKey)4, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "14 payload", string("Object 3"),
+                                  row["S"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "14 original id", 45u, row.originalId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "14 new head id", 0u, row.newHeadId() );
+    
+    row = objectTable.fetchRowForId( 51u, fetchPayload );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "15 object id", 51u, row.objectId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "15 channel id", 2u, row.channelId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "15 since", (ValidityKey)8, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "15 until", (ValidityKey)9, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "15 payload", string("Object 1"),
+                                  row["S"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "15 original id", 25u, row.originalId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "15 new head id", 0u, row.newHeadId() );
+    
+  }    
+  
+  /// Tests storeObjects in MV mode in different channels
+  void test_storeObjects_MV_case_0a_channels() {
+    IFolderPtr folder = ralDb->createFolder( "/myfolder", 
+                                             payloadSpec,
+                                             "my description",
+                                             FolderVersioning::MULTI_VERSION );
+    RelationalFolder* relfolder = dynamic_cast<RelationalFolder*>(folder.get());
+    
+    { vector<RelationalObjectPtr> objs;
+      ChannelId ch = 0;
+      objs.push_back( dummyObject( 1, 2, 4, ch ) );
+      storeObjects( relfolder, objs );
+    }
+    
+    { vector<RelationalObjectPtr> objs;
+      ChannelId ch = 1;
+      objs.push_back( dummyObject( 2, 2, 4, ch ) );
+      storeObjects( relfolder, objs );
+    }
+    
+    RelationalTransaction transaction( ralDb->transactionMgr() );
+
+    {
+      coral::ITable& objectTable = ralDb->session().nominalSchema().tableHandle
+        ( relfolder->objectTableName() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "row count", 
+                                    2u, rowCount( objectTable ) );
+    }
+    
+    RelationalObjectTable 
+      objectTable( &(ralDb->queryMgr()), false, *relfolder );
+    bool fetchPayload = true;
+
+    RelationalObjectTableRow
+      row( objectTable.fetchRowForId( 1u, fetchPayload ) );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 object id", 1u, row.objectId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 channel id", 0u, row.channelId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 since", (ValidityKey)2, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 until", (ValidityKey)4, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 payload", string("Object 1"),
+                                  row["S"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 original id", 0u, row.originalId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 new head id", 0u, row.newHeadId() );
+    
+    row = objectTable.fetchRowForId( 7u, fetchPayload );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 object id", 7u, row.objectId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 channel id", 1u, row.channelId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 since", (ValidityKey)2, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 until", (ValidityKey)4, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 payload", string("Object 2"),
+                                  row["S"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 original id", 0u, row.originalId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 new head id", 0u, row.newHeadId() );
+  }
+  
+  
+  
+  /// Tests storeObjects in MV mode
+  void test_storeObjects_MV_case_6() {
+    IFolderPtr folder = ralDb->createFolder( "/myfolder", 
+                                             payloadSpec,
+                                             "my description",
+                                             FolderVersioning::MULTI_VERSION );
+    RelationalFolder* relfolder = dynamic_cast<RelationalFolder*>(folder.get());
+    
+    { vector<RelationalObjectPtr> objs;
+      objs.push_back( dummyObject( 1, 7, 9 ) );
+      objs.push_back( dummyObject( 2, 6, 7 ) );
+      objs.push_back( dummyObject( 3, 1, 5 ) );
+      storeObjects( relfolder, objs );
+    }
+    
+    { vector<RelationalObjectPtr> objs;
+      objs.push_back( dummyObject( 4, 2, 3 ) );
+      objs.push_back( dummyObject( 5, 4, 8 ) );
+      storeObjects( relfolder, objs );
+    }
+    
+    RelationalTransaction transaction( ralDb->transactionMgr() );
+    
+    {
+      coral::ITable& objectTable = ralDb->session().nominalSchema().tableHandle
+        ( relfolder->objectTableName() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "row count", 
+                                    9u, rowCount( objectTable ) );
+    }
+    
+    RelationalObjectTable 
+      objectTable( &(ralDb->queryMgr()), false, *relfolder );
+    bool fetchPayload = true;
+    RelationalObjectTableRow
+      row( objectTable.fetchRowForId( 1u, fetchPayload ) );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 object id", 1u, row.objectId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 since", (ValidityKey)7, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 until", (ValidityKey)9, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 payload", string("Object 1"),
+                                  row["S"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 original id", 0u, row.originalId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 new head id", 25u, row.newHeadId() );
+    
+    row = objectTable.fetchRowForId( 7u, fetchPayload );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 object id", 7u, row.objectId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 since", (ValidityKey)6, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 until", (ValidityKey)7, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 payload", string("Object 2"),
+                                  row["S"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 original id", 0u, row.originalId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 new head id", 25u, row.newHeadId() );
+    
+    row = objectTable.fetchRowForId( 13u, fetchPayload );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 object id", 13u, row.objectId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 since", (ValidityKey)1, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 until", (ValidityKey)5, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 payload", string("Object 3"),
+                                  row["S"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 original id", 0u, row.originalId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 new head id", 19u, row.newHeadId() );
+    
+    row = objectTable.fetchRowForId( 19u, fetchPayload );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "4 object id", 19u, row.objectId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "4 since", (ValidityKey)2, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "4 until", (ValidityKey)3, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "4 payload", string("Object 4"),
+                                  row["S"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "4 original id", 0u, row.originalId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "4 new head id", 0u, row.newHeadId() );
+    
+    row = objectTable.fetchRowForId( 20u, fetchPayload );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "5 object id", 20u, row.objectId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "5 since", (ValidityKey)1, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "5 until", (ValidityKey)2, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "5 payload", string("Object 3"),
+                                  row["S"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "5 original id", 13u, row.originalId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "5 new head id", 0u, row.newHeadId() );
+    
+    row = objectTable.fetchRowForId( 21u, fetchPayload );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "6 object id", 21u, row.objectId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "6 since", (ValidityKey)3, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "6 until", (ValidityKey)5, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "6 payload", string("Object 3"),
+                                  row["S"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "6 original id", 13u, row.originalId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "6 new head id", 25u, row.newHeadId() );
+    
+    row = objectTable.fetchRowForId( 25u, fetchPayload );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "7 object id", 25u, row.objectId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "7 since", (ValidityKey)4, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "7 until", (ValidityKey)8, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "7 payload", string("Object 5"),
+                                  row["S"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "7 original id", 0u, row.originalId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "7 new head id", 0u, row.newHeadId() );
+    
+    row = objectTable.fetchRowForId( 26u, fetchPayload );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "8 object id", 26u, row.objectId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "8 since", (ValidityKey)3, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "8 until", (ValidityKey)4, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "8 payload", string("Object 3"),
+                                  row["S"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "8 original id", 21u, row.originalId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "8 new head id", 0u, row.newHeadId() );
+    
+    row = objectTable.fetchRowForId( 27u, fetchPayload );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "9 object id", 27u, row.objectId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "9 since", (ValidityKey)8, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "9 until", (ValidityKey)9, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "9 payload", string("Object 1"),
+                                  row["S"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "9 original id", 1u, row.originalId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "9 new head id", 0u, row.newHeadId() );
+  }
+  
+  
+  /// Tests storeObjects in MV mode
+  void test_storeObjects_MV_case_5b() {
+    IFolderPtr folder = ralDb->createFolder( "/myfolder", 
+                                             payloadSpec,
+                                             "my description",
+                                             FolderVersioning::MULTI_VERSION );
+    RelationalFolder* relfolder = dynamic_cast<RelationalFolder*>(folder.get());
+    
+    { vector<RelationalObjectPtr> objs;
+      objs.push_back( dummyObject( 1, 1, 3 ) );
+      objs.push_back( dummyObject( 2, 6, 8 ) );
+      storeObjects( relfolder, objs );
+    }
+    
+    { vector<RelationalObjectPtr> objs;
+      objs.push_back( dummyObject( 3, 2, 4 ) );
+      objs.push_back( dummyObject( 4, 5, 7 ) );
+      storeObjects( relfolder, objs );
+    }
+    
+    RelationalTransaction transaction( ralDb->transactionMgr() );
+    
+    {
+      coral::ITable& objectTable = ralDb->session().nominalSchema().tableHandle
+        ( relfolder->objectTableName() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "row count", 
+                                    6u, rowCount( objectTable ) );
+    }
+    
+    RelationalObjectTable 
+      objectTable( &(ralDb->queryMgr()), false, *relfolder );
+    bool fetchPayload = true;
+    RelationalObjectTableRow
+      row( objectTable.fetchRowForId( 1u, fetchPayload ) );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 object id", 1u, row.objectId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 since", (ValidityKey)1, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 until", (ValidityKey)3, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 payload", string("Object 1"),
+                                  row["S"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 original id", 0u, row.originalId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 new head id", 13u, row.newHeadId() );
+    
+    row = objectTable.fetchRowForId( 7u, fetchPayload );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 object id", 7u, row.objectId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 since", (ValidityKey)6, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 until", (ValidityKey)8, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 payload", string("Object 2"),
+                                  row["S"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 original id", 0u, row.originalId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 new head id", 19u, row.newHeadId() );
+    
+    row = objectTable.fetchRowForId( 13u, fetchPayload );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 object id", 13u, row.objectId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 since", (ValidityKey)2, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 until", (ValidityKey)4, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 payload", string("Object 3"),
+                                  row["S"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 original id", 0u, row.originalId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 new head id", 0u, row.newHeadId() );
+    
+    row = objectTable.fetchRowForId( 14u, fetchPayload );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "4 object id", 14u, row.objectId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "4 since", (ValidityKey)1, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "4 until", (ValidityKey)2, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "4 payload", string("Object 1"),
+                                  row["S"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "4 original id", 1u, row.originalId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "4 new head id", 0u, row.newHeadId() );
+    
+    row = objectTable.fetchRowForId( 19u, fetchPayload );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "5 object id", 19u, row.objectId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "5 since", (ValidityKey)5, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "5 until", (ValidityKey)7, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "5 payload", string("Object 4"),
+                                  row["S"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "5 original id", 0u, row.originalId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "5 new head id", 0u, row.newHeadId() );
+    
+    row = objectTable.fetchRowForId( 21u, fetchPayload );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "6 object id", 21u, row.objectId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "6 since", (ValidityKey)7, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "6 until", (ValidityKey)8, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "6 payload", string("Object 2"),
+                                  row["S"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "6 original id", 7u, row.originalId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "6 new head id", 0u, row.newHeadId() );
+  }
+  
+  
+  /// Tests storeObjects in MV mode
+  void test_storeObjects_MV_case_4() {
+    IFolderPtr folder = ralDb->createFolder( "/myfolder", 
+                                             payloadSpec,
+                                             "my description",
+                                             FolderVersioning::MULTI_VERSION );
+    RelationalFolder* relfolder = dynamic_cast<RelationalFolder*>(folder.get());
+    
+    { vector<RelationalObjectPtr> objs;
+      objs.push_back( dummyObject( 1, 1, 4 ) );
+      storeObjects( relfolder, objs );
+    }
+    
+    { vector<RelationalObjectPtr> objs;
+      objs.push_back( dummyObject( 2, 3, 7 ) );
+      objs.push_back( dummyObject( 3, 6, 8 ) );
+      objs.push_back( dummyObject( 4, 2, 5 ) );
+      storeObjects( relfolder, objs );
+    }
+    
+    RelationalTransaction transaction( ralDb->transactionMgr() );
+    
+    {
+      coral::ITable& objectTable = ralDb->session().nominalSchema().tableHandle
+        ( relfolder->objectTableName() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "row count", 
+                                    8u, rowCount( objectTable ) );
+    }
+    
+    RelationalObjectTable 
+      objectTable( &(ralDb->queryMgr()), false, *relfolder );
+    bool fetchPayload = true;
+    RelationalObjectTableRow
+      row( objectTable.fetchRowForId( 1u, fetchPayload ) );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 object id", 1u, row.objectId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 since", (ValidityKey)1, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 until", (ValidityKey)4, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 payload", string("Object 1"),
+                                  row["S"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 original id", 0u, row.originalId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 new head id", 7u, row.newHeadId() );
+    
+    row = objectTable.fetchRowForId( 7u, fetchPayload );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 object id", 7u, row.objectId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 since", (ValidityKey)3, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 until", (ValidityKey)7, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 payload", string("Object 2"),
+                                  row["S"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 original id", 0u, row.originalId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 new head id", 13u, row.newHeadId() );
+    
+    row = objectTable.fetchRowForId( 8u, fetchPayload );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 object id", 8u, row.objectId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 since", (ValidityKey)1, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 until", (ValidityKey)3, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 payload", string("Object 1"),
+                                  row["S"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 original id", 1u, row.originalId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 new head id", 19u, row.newHeadId() );
+    
+    row = objectTable.fetchRowForId( 13u, fetchPayload );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "4 object id", 13u, row.objectId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "4 since", (ValidityKey)6, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "4 until", (ValidityKey)8, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "4 payload", string("Object 3"),
+                                  row["S"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "4 original id", 0u, row.originalId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "4 new head id", 0u, row.newHeadId() );
+    
+    row = objectTable.fetchRowForId( 14u, fetchPayload );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "5 object id", 14u, row.objectId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "5 since", (ValidityKey)3, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "5 until", (ValidityKey)6, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "5 payload", string("Object 2"),
+                                  row["S"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "5 original id", 7u, row.originalId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "5 new head id", 19u, row.newHeadId() );
+    
+    row = objectTable.fetchRowForId( 19u, fetchPayload );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "6 object id", 19u, row.objectId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "6 since", (ValidityKey)2, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "6 until", (ValidityKey)5, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "6 payload", string("Object 4"),
+                                  row["S"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "6 original id", 0u, row.originalId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "6 new head id", 0u, row.newHeadId() );
+    
+    row = objectTable.fetchRowForId( 20u, fetchPayload );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "7 object id", 20u, row.objectId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "7 since", (ValidityKey)1, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "7 until", (ValidityKey)2, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "7 payload", string("Object 1"),
+                                  row["S"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "7 original id", 8u, row.originalId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "7 new head id", 0u, row.newHeadId() );
+    
+    row = objectTable.fetchRowForId( 21u, fetchPayload );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "8 object id", 21u, row.objectId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "8 since", (ValidityKey)5, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "8 until", (ValidityKey)6, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "8 payload", string("Object 2"),
+                                  row["S"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "8 original id", 14u, row.originalId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "8 new head id", 0u, row.newHeadId() );
+  }
+  
+  
+  /// Tests storeObjects in MV mode
+  void test_storeObjects_MV_case_3() {
+    IFolderPtr folder = ralDb->createFolder( "/myfolder", 
+                                             payloadSpec,
+                                             "my description",
+                                             FolderVersioning::MULTI_VERSION );
+    RelationalFolder* relfolder = dynamic_cast<RelationalFolder*>(folder.get());
+    
+    { vector<RelationalObjectPtr> objs;
+      objs.push_back( dummyObject( 1, 1, 8 ) );
+      storeObjects( relfolder, objs );
+    }
+    
+    { vector<RelationalObjectPtr> objs;
+      objs.push_back( dummyObject( 2, 2, 5 ) );
+      objs.push_back( dummyObject( 3, 3, 6 ) );
+      objs.push_back( dummyObject( 4, 4, 7 ) );
+      storeObjects( relfolder, objs );
+    }
+    
+    RelationalTransaction transaction( ralDb->transactionMgr() );
+    
+    {
+      coral::ITable& objectTable = ralDb->session().nominalSchema().tableHandle
+        ( relfolder->objectTableName() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "row count", 
+                                    10u, rowCount( objectTable ) );
+    }
+    
+    RelationalObjectTable 
+      objectTable( &(ralDb->queryMgr()), false, *relfolder );
+    bool fetchPayload = true;
+    RelationalObjectTableRow
+      row( objectTable.fetchRowForId( 1u, fetchPayload ) );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 object id", 1u, row.objectId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 since", (ValidityKey)1, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 until", (ValidityKey)8, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 payload", string("Object 1"),
+                                  row["S"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 original id", 0u, row.originalId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 new head id", 7u, row.newHeadId() );
+    
+    row = objectTable.fetchRowForId( 7u, fetchPayload );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 object id", 7u, row.objectId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 since", (ValidityKey)2, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 until", (ValidityKey)5, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 payload", string("Object 2"),
+                                  row["S"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 original id", 0u, row.originalId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 new head id", 13u, row.newHeadId() );
+    
+    row = objectTable.fetchRowForId( 8u, fetchPayload );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 object id", 8u, row.objectId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 since", (ValidityKey)1, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 until", (ValidityKey)2, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 payload", string("Object 1"),
+                                  row["S"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 original id", 1u, row.originalId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 new head id", 0u, row.newHeadId() );
+    
+    row = objectTable.fetchRowForId( 9u, fetchPayload );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "4 object id", 9u, row.objectId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "4 since", (ValidityKey)5, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "4 until", (ValidityKey)8, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "4 payload", string("Object 1"),
+                                  row["S"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "4 original id", 1u, row.originalId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "4 new head id", 13u, row.newHeadId() );
+    
+    row = objectTable.fetchRowForId( 13u, fetchPayload );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "5 object id", 13u, row.objectId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "5 since", (ValidityKey)3, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "5 until", (ValidityKey)6, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "5 payload", string("Object 3"),
+                                  row["S"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "5 original id", 0u, row.originalId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "5 new head id", 19u, row.newHeadId() );
+    
+    row = objectTable.fetchRowForId( 14u, fetchPayload );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "6 object id", 14u, row.objectId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "6 since", (ValidityKey)2, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "6 until", (ValidityKey)3, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "6 payload", string("Object 2"),
+                                  row["S"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "6 original id", 7u, row.originalId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "6 new head id", 0u, row.newHeadId() );
+
+    row = objectTable.fetchRowForId( 15u, fetchPayload );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "7 object id", 15u, row.objectId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "7 since", (ValidityKey)6, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "7 until", (ValidityKey)8, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "7 payload", string("Object 1"),
+                                  row["S"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "7 original id", 9u, row.originalId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "7 new head id", 19u, row.newHeadId() );
+    
+    row = objectTable.fetchRowForId( 19u, fetchPayload );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "8 object id", 19u, row.objectId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "8 since", (ValidityKey)4, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "8 until", (ValidityKey)7, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "8 payload", string("Object 4"),
+                                  row["S"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "8 original id", 0u, row.originalId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "8 new head id", 0u, row.newHeadId() );
+    
+    row = objectTable.fetchRowForId( 20u, fetchPayload );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "9 object id", 20u, row.objectId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "9 since", (ValidityKey)3, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "9 until", (ValidityKey)4, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "9 payload", string("Object 3"),
+                                  row["S"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "9 original id", 13u, row.originalId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "9 new head id", 0u, row.newHeadId() );
+    
+    row = objectTable.fetchRowForId( 21u, fetchPayload );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "10 object id", 21u, row.objectId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "10 since", (ValidityKey)7, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "10 until", (ValidityKey)8, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "10 payload", string("Object 1"),
+                                  row["S"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "10 original id", 15u, row.originalId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "10 new head id", 0u, row.newHeadId() );
+    transaction.commit();
+  }
+  
+  
+  /// Tests storeObjects in MV mode
+  void test_storeObjects_MV_case_2() {
+    IFolderPtr folder = ralDb->createFolder( "/myfolder", 
+                                             payloadSpec,
+                                             "my description",
+                                             FolderVersioning::MULTI_VERSION );
+    RelationalFolder* relfolder = dynamic_cast<RelationalFolder*>(folder.get());
+    
+    { vector<RelationalObjectPtr> objs;
+      objs.push_back( dummyObject( 1, 1, 5 ) );
+      objs.push_back( dummyObject( 2, 3, 6 ) );
+      storeObjects( relfolder, objs );
+    }
+    
+    { vector<RelationalObjectPtr> objs;
+      objs.push_back( dummyObject( 3, 2, 4 ) );
+      storeObjects( relfolder, objs );
+    }
+    
+    RelationalTransaction transaction( ralDb->transactionMgr() );
+    
+    {
+      coral::ITable& objectTable = ralDb->session().nominalSchema().tableHandle
+        ( relfolder->objectTableName() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "row count", 
+                                    6u, rowCount( objectTable ) );
+    }
+    
+    RelationalObjectTable 
+      objectTable( &(ralDb->queryMgr()), false, *relfolder );
+    bool fetchPayload = true;
+    RelationalObjectTableRow
+      row( objectTable.fetchRowForId( 1u, fetchPayload ) );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 object id", 1u, row.objectId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 since", (ValidityKey)1, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 until", (ValidityKey)5, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 payload", string("Object 1"),
+                                  row["S"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 original id", 0u, row.originalId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 new head id", 7u, row.newHeadId() );
+    
+    row = objectTable.fetchRowForId( 7u, fetchPayload );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 object id", 7u, row.objectId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 since", (ValidityKey)3, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 until", (ValidityKey)6, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 payload", string("Object 2"),
+                                  row["S"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 original id", 0u, row.originalId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 new head id", 13u, row.newHeadId() );
+    
+    row = objectTable.fetchRowForId( 8u, fetchPayload );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 object id", 8u, row.objectId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 since", (ValidityKey)1, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 until", (ValidityKey)3, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 payload", string("Object 1"),
+                                  row["S"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 original id", 1u, row.originalId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 new head id", 13u, row.newHeadId() );
+    
+    row = objectTable.fetchRowForId( 13u, fetchPayload );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "4 object id", 13u, row.objectId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "4 since", (ValidityKey)2, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "4 until", (ValidityKey)4, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "4 payload", string("Object 3"),
+                                  row["S"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "4 original id", 0u, row.originalId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "4 new head id", 0u, row.newHeadId() );
+    
+    row = objectTable.fetchRowForId( 14u, fetchPayload );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "5 object id", 14u, row.objectId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "5 since", (ValidityKey)1, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "5 until", (ValidityKey)2, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "5 payload", string("Object 1"),
+                                  row["S"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "5 original id", 8u, row.originalId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "5 new head id", 0u, row.newHeadId() );
+    
+    row = objectTable.fetchRowForId( 15u, fetchPayload );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "6 object id", 15u, row.objectId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "6 since", (ValidityKey)4, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "6 until", (ValidityKey)6, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "6 payload", string("Object 2"),
+                                  row["S"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "6 original id", 7u, row.originalId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "6 new head id", 0u, row.newHeadId() );
+  }
+  
+  
+  /// Tests storeObjects in MV mode
+  void test_storeObjects_MV_case_1a() {
+    IFolderPtr folder = ralDb->createFolder( "/myfolder", 
+                                             payloadSpec,
+                                             "my description",
+                                             FolderVersioning::MULTI_VERSION );
+    RelationalFolder* relfolder = dynamic_cast<RelationalFolder*>(folder.get());
+
+    { vector<RelationalObjectPtr> 
+      objs( 1, dummyObject( 1, 1, 3 ) );
+      storeObjects( relfolder, objs );
+    }
+    
+    { vector<RelationalObjectPtr> 
+      objs( 1, dummyObject( 2, 2, 4 ) );
+      storeObjects( relfolder, objs );
+    }
+    
+    RelationalTransaction transaction( ralDb->transactionMgr() );
+    
+    {
+      coral::ITable& objectTable = ralDb->session().nominalSchema().tableHandle
+        ( relfolder->objectTableName() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "row count", 
+                                    3u, rowCount( objectTable ) );
+    }
+    
+    RelationalObjectTable 
+      objectTable( &(ralDb->queryMgr()), false, *relfolder );
+    bool fetchPayload = true;
+    RelationalObjectTableRow
+      row( objectTable.fetchRowForId( 1u, fetchPayload ) );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 object id", 1u, row.objectId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 since", (ValidityKey)1, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 until", (ValidityKey)3, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 payload", string("Object 1"),
+                                  row["S"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 original id", 0u, row.originalId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 new head id", 7u, row.newHeadId() );
+    
+    row = objectTable.fetchRowForId( 7u, fetchPayload );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 object id", 7u, row.objectId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 since", (ValidityKey)2, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 until", (ValidityKey)4, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 payload", string("Object 2"),
+                                  row["S"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 original id", 0u, row.originalId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 new head id", 0u, row.newHeadId() );
+
+    row = objectTable.fetchRowForId( 8u, fetchPayload );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 object id", 8u, row.objectId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 since", (ValidityKey)1, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 until", (ValidityKey)2, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 payload", string("Object 1"),
+                                  row["S"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 original id", 1u, row.originalId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 new head id", 0u, row.newHeadId() );
+  }
+  
+  
+  /// Tests storeObjects in MV mode
+  void test_storeObjects_MV_case_0b() {
+    IFolderPtr folder = ralDb->createFolder( "/myfolder", 
+                                             payloadSpec,
+                                             "my description",
+                                             FolderVersioning::MULTI_VERSION );
+    RelationalFolder* relfolder = dynamic_cast<RelationalFolder*>(folder.get());
+    
+    { vector<RelationalObjectPtr> objs;
+      objs.push_back( dummyObject( 1, 2, 3 ) );
+      storeObjects( relfolder, objs );
+    }
+    
+    { vector<RelationalObjectPtr> objs;
+      objs.push_back( dummyObject( 2, 1, 4 ) );
+      storeObjects( relfolder, objs );
+    }
+    
+    RelationalTransaction transaction( ralDb->transactionMgr() );
+    
+    {
+      coral::ITable& objectTable = ralDb->session().nominalSchema().tableHandle
+        ( relfolder->objectTableName() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "row count", 
+                                    2u, rowCount( objectTable ) );
+    }
+    
+    RelationalObjectTable 
+      objectTable( &(ralDb->queryMgr()), false, *relfolder );
+    bool fetchPayload = true;
+    RelationalObjectTableRow
+      row( objectTable.fetchRowForId( 1u, fetchPayload ) );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 object id", 1u, row.objectId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 since", (ValidityKey)2, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 until", (ValidityKey)3, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 payload", string("Object 1"),
+                                  row["S"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 original id", 0u, row.originalId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 new head id", 7u, row.newHeadId() );
+    
+    row = objectTable.fetchRowForId( 7u, fetchPayload );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 object id", 7u, row.objectId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 since", (ValidityKey)1, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 until", (ValidityKey)4, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 payload", string("Object 2"),
+                                  row["S"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 original id", 0u, row.originalId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 new head id", 0u, row.newHeadId() );
+    
+  }
+  
+  
+  /// Tests storeObjects in MV mode
+  void test_storeObjects_MV_case_0a() {
+    try{      
+      IFolderPtr folder = 
+        ralDb->createFolder( "/myfolder", 
+                             payloadSpec,
+                             "my description",
+                             FolderVersioning::MULTI_VERSION );
+      RelationalFolder* relfolder = 
+        dynamic_cast<RelationalFolder*>(folder.get());
+      { 
+        vector<RelationalObjectPtr> 
+          objs( 1, dummyObject( 1, 2, 4 ) );
+        storeObjects( relfolder, objs );
+      }
+      { 
+        vector<RelationalObjectPtr> 
+          objs( 1, dummyObject( 2, 2, 4 ) );
+        storeObjects( relfolder, objs );
+      }
+      RelationalTransaction transaction( ralDb->transactionMgr() );
+      {
+        coral::ITable& objectTable = 
+          ralDb->session().nominalSchema().tableHandle
+          ( relfolder->objectTableName() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "row count", 
+                                      2u, rowCount( objectTable ) );
+      }
+      
+      RelationalObjectTable 
+        objectTable( &(ralDb->queryMgr()), false, *relfolder );
+      bool fetchPayload = true;
+      RelationalObjectTableRow
+        row( objectTable.fetchRowForId( 1u, fetchPayload ) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 object id", 1u, row.objectId() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 since", (ValidityKey)2, row.since() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 until", (ValidityKey)4, row.until() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 payload", string("Object 1"),
+                                    row["S"].data<std::string>() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 original id", 0u, row.originalId() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 new head id", 7u, row.newHeadId() );
+      
+      row = objectTable.fetchRowForId( 7u, fetchPayload );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 object id", 7u, row.objectId() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 since", (ValidityKey)2, row.since() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 until", (ValidityKey)4, row.until() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 payload", string("Object 2"),
+                                    row["S"].data<std::string>() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 original id", 0u, row.originalId() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 new head id", 0u, row.newHeadId() );
+    } catch ( std::exception& e ) {
+      cout << e.what() << endl;
+      throw;
+    }
+  }
+  
+  
+  /// Tests a combination of insertTagTableRow and fetchTagTableRow
+  void test_insertTagTableRow_fetchTagTableRow() {
+    IFolderPtr folder = ralDb->createFolder( "/myfolder", 
+                                             payloadSpec,
+                                             "my description",
+                                             FolderVersioning::MULTI_VERSION );
+    RelationalFolder* relfolder = dynamic_cast<RelationalFolder*>(folder.get());
+    
+    RelationalTransaction transaction( ralDb->transactionMgr() );
+    unsigned int tagId = 
+      ralDb->tagMgr().createTag( relfolder->id(), "mytagA", "desc A" ).id();
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "tag A id", 1u, tagId );
+    
+    tagId = 
+      ralDb->tagMgr().createTag( relfolder->id(), "mytagB", "desc B" ).id();
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "tag B id", 2u, tagId );
+    
+    RelationalTableRow row = 
+      ralDb->tagMgr().fetchGlobalTagTableRows( "mytagB" )[0];
+    CPPUNIT_ASSERT_EQUAL_MESSAGE
+      ( "id", 2u, row["TAG_ID"].data<unsigned int>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE
+      ( "name", string("mytagB"), row["TAG_NAME"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE
+      ( "description", string("desc B"),
+        row["TAG_DESCRIPTION"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE
+      ( "instime", string("yyyy-mm-dd_hh:mm:ss.nnnnnnnnn GMT").size(),
+        row["SYS_INSTIME"].data<std::string>().size() );
+    
+    transaction.commit();
+  }
+  
+  
+  /// Tests insertTagTableRow if a tag already exists
+  void test_insertTagTableRow_exists() {
+    IFolderPtr folder = ralDb->createFolder( "/myfolder", 
+                                             payloadSpec,
+                                             "my description",
+                                             FolderVersioning::MULTI_VERSION );
+    RelationalFolder* relfolder = dynamic_cast<RelationalFolder*>(folder.get());
+    
+    RelationalTransaction transaction( ralDb->transactionMgr() );
+    ralDb->tagMgr().createTag( relfolder->id(), "mytagA", "desc A" );
+    CPPUNIT_ASSERT_THROW( ralDb->tagMgr().createTag( relfolder->id(),
+                                                     "mytagA", "desc A" ),
+                          TagExists );
+    transaction.commit();
+  }
+  
+  
+  /// Tests insertTagTableRow to confirm that trying to insert "HEAD"
+  /// throws an exception
+  void test_insertTagTableRow_HEAD() {
+    IFolderPtr folder = ralDb->createFolder( "/myfolder", 
+                                             payloadSpec,
+                                             "my description",
+                                             FolderVersioning::MULTI_VERSION );
+    RelationalFolder* relfolder = dynamic_cast<RelationalFolder*>(folder.get());
+    
+    RelationalTransaction transaction( ralDb->transactionMgr() );
+    
+    try {
+      ralDb->tagMgr().createTag( relfolder->id(), "HEAD", "" );
+      CPPUNIT_FAIL( "inserting HEAD tag did not throw" );
+    } catch ( TagExists& /* ignored */ ) { }
+    
+    try {
+      ralDb->tagMgr().createTag( relfolder->id(), "head", "" );
+      CPPUNIT_FAIL( "inserting head tag did not throw" );
+    } catch ( TagExists& /* ignored */ ) { }
+    
+    try {
+      ralDb->tagMgr().createTag( relfolder->id(), "Head", "" );
+      CPPUNIT_FAIL( "inserting Head tag did not throw" );
+    } catch ( TagExists& /* ignored */ ) { }
+    
+    transaction.commit();
+  }
+  
+  
+  /// Tests fetchTagTableRow for a nonexisting tag
+  void test_fetchTagTableRow_notFound() {
+    IFolderPtr folder = ralDb->createFolder( "/myfolder", 
+                                             payloadSpec,
+                                             "my description",
+                                             FolderVersioning::MULTI_VERSION );
+    RelationalFolder* relfolder = dynamic_cast<RelationalFolder*>(folder.get());
+    
+    RelationalTransaction transaction( ralDb->transactionMgr() );
+    ralDb->tagMgr().createTag( relfolder->id(), "mytagA", "desc A" );
+    CPPUNIT_ASSERT_THROW( ralDb->tagMgr().fetchGlobalTagTableRows( "mytagB" )[0],
+                          TagNotFound );
+    transaction.commit();
+  }
+  
+  
+  /// Tests the global version of existsTag
+  void test_existsTag_global() {
+    IFolderPtr folder = ralDb->createFolder( "/myfolder1", 
+                                             payloadSpec,
+                                             "my description",
+                                             FolderVersioning::MULTI_VERSION );
+    folder->storeObject( 0, 4, dummyPayload( 0 ), 0 );
+    folder->tagCurrentHead( "mytagA", "" );
+    
+    CPPUNIT_ASSERT_MESSAGE( "positive", ralDb->existsTag( "mytagA" ) );
+    CPPUNIT_ASSERT_MESSAGE( "negative", ! ralDb->existsTag( "mytagB" ) );
+    
+    folder = ralDb->createFolder( "/myfolder2", 
+                                  payloadSpec,
+                                  "my description",
+                                  FolderVersioning::MULTI_VERSION );
+    folder->storeObject( 0, 4, dummyPayload( 0 ), 0 );
+    folder->tagCurrentHead( "mytagC", "" );
+    
+    CPPUNIT_ASSERT_MESSAGE( "positive", ralDb->existsTag( "mytagC" ) );
+  }
+  
+  
+  /// Tests a combination of insertObject2TagTableRows and
+  /// fetchObject2TagTableRow
+  void test_insertObject2TagTableRows_fetchObject2TagTableRow() {
+    IFolderPtr folder = ralDb->createFolder( "/myfolder", 
+                                             payloadSpec,
+                                             "my description",
+                                             FolderVersioning::MULTI_VERSION );
+    RelationalFolder* relfolder = dynamic_cast<RelationalFolder*>(folder.get());
+    
+    { vector<RelationalObjectPtr> objs;
+      objs.push_back( dummyObject( 1, 1, 3 ) );
+      objs.push_back( dummyObject( 2, 6, 8 ) );
+      storeObjects( relfolder, objs );
+    }
+    
+    RelationalTransaction transaction( ralDb->transactionMgr() );
+    boost::shared_ptr<RelationalSequence> seq
+      ( ralDb->queryMgr().sequenceMgr().getSequence
+        ( RelationalObjectTable::sequenceName
+          ( relfolder->objectTableName() ) ) );
+    Time now = stringToTime( seq->currDate() );
+    RelationalObjectTable 
+      objectTable( &(ralDb->queryMgr()), false, *relfolder );
+    vector<RelationalObjectTableRow> rows =
+      objectTable.fetchRowsForTaggingHeadAsOfDate( now );
+    
+    unsigned int tagId = 
+      ralDb->tagMgr().createTag( relfolder->id(), "mytagA", "desc A" ).id();
+    
+    string insertionTime = seq->currDate();
+    relfolder->insertObject2TagTableRows( relfolder->object2TagTableName(), 
+                                          tagId, 
+                                          insertionTime,
+                                          rows );
+    
+    coral::ITable& table = 
+      ralDb->session().nominalSchema().tableHandle
+      ( relfolder->object2TagTableName() );
+    
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "row count", 2u, rowCount( table ) );
+    
+    unsigned int objectId = 1;
+    RelationalTableRow row = ralDb->fetchObject2TagTableRow
+      ( relfolder->object2TagTableName(), tagId, objectId );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE
+      ( "1 tag id", 1u, row["TAG_ID"].data<unsigned int>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE
+      ( "1 obj id", 1u, row["OBJECT_ID"].data<unsigned int>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE
+      ( "1 channel", (ChannelId)0, row["CHANNEL_ID"].data<ChannelId>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE
+      ( "1 since", (ValidityKey)1, row["IOV_SINCE"].data<ValidityKey>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE
+      ( "1 until", (ValidityKey)3, row["IOV_UNTIL"].data<ValidityKey>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE
+      ( "instime", insertionTime, row["SYS_INSTIME"].data<std::string>() );
+    
+    objectId = 7;
+    row = ralDb->fetchObject2TagTableRow
+      ( relfolder->object2TagTableName(), tagId, objectId );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE
+      ( "2 tag id", 1u, row["TAG_ID"].data<unsigned int>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE
+      ( "2 obj id", 7u, row["OBJECT_ID"].data<unsigned int>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE
+      ( "2 channel", (ChannelId)0, row["CHANNEL_ID"].data<ChannelId>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE
+      ( "2 since", (ValidityKey)6, row["IOV_SINCE"].data<ValidityKey>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE
+      ( "2 until", (ValidityKey)8, row["IOV_UNTIL"].data<ValidityKey>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE
+      ( "instime", insertionTime, row["SYS_INSTIME"].data<std::string>() );
+    
+    transaction.commit();
+  }
+  
+  
+  /// Tests tagging the HEAD as of a given date
+  void test_tag_asOfDate_5c() {
+    try {
+      IFolderPtr folder = ralDb->createFolder( "/myfolder", 
+                                               payloadSpec,
+                                               "my description",
+                                               FolderVersioning::MULTI_VERSION );
+      RelationalFolder* relfolder = dynamic_cast<RelationalFolder*>(folder.get());
+      
+      { vector<RelationalObjectPtr> objs;
+        objs.push_back( dummyObject( 1, 1, 3 ) );
+        objs.push_back( dummyObject( 2, 6, 8 ) );
+        storeObjects( relfolder, objs );
+      }
+      
+      RelationalTransaction t1( ralDb->transactionMgr() );
+      boost::shared_ptr<RelationalSequence> seq
+        ( ralDb->queryMgr().sequenceMgr().getSequence
+          ( RelationalObjectTable::sequenceName
+            ( relfolder->objectTableName() ) ) );
+      Time asOfDate = stringToTime( seq->currDate() );
+      asOfDate = addOneNsToTime( asOfDate );
+      t1.commit();
+      
+      // MySQL now() has 1 second granularity: need to sleep at least 1 second
+      sleep(1); 
+      //cout << "### Before 2nd insert: " << timeToString(asOfDate) << endl;
+      
+      { vector<RelationalObjectPtr> objs;
+        objs.push_back( dummyObject( 3, 2, 4 ) );
+        objs.push_back( dummyObject( 4, 3, 5 ) );
+        storeObjects( relfolder, objs );
+      }
+      
+      relfolder->tagHeadAsOfDate( asOfDate, "mytagA", "a tag A" );
+      relfolder->tagHeadAsOfDate( asOfDate, "mytagB", "a tag B" );
+      
+      RelationalTransaction transaction( ralDb->transactionMgr() );
+      {
+        coral::ITable& table = 
+        ralDb->session().nominalSchema().tableHandle
+        ( relfolder->tagTableName() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "tag table row count", 
+                                      2u, rowCount( table ) );
+        
+        // check tag table content (more detailed test in the insert/fetch test)
+        RelationalTableRow row = 
+          ralDb->tagMgr().fetchGlobalTagTableRows( "mytagB" )[0];
+        CPPUNIT_ASSERT_EQUAL_MESSAGE
+          ( "id", 2u, row["TAG_ID"].data<unsigned int>() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE
+          ( "name", string("mytagB"), row["TAG_NAME"].data<std::string>() );
+      }
+      
+      {
+        coral::ITable& table =
+        ralDb->session().nominalSchema().tableHandle
+        ( relfolder->object2TagTableName() );
+        
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj2tag table row count", 
+                                      4u, rowCount( table ) );
+        
+        // check tag2iov table content
+        unsigned int tagId = 2;
+        RelationalTableRow row = ralDb->fetchObject2TagTableRow
+          ( relfolder->object2TagTableName(), tagId, 1u );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE
+          ( "1 since", (ValidityKey)1, row["IOV_SINCE"].data<ValidityKey>() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE
+          ( "1 until", (ValidityKey)3, row["IOV_UNTIL"].data<ValidityKey>() );
+        
+        row = ralDb->fetchObject2TagTableRow
+          ( relfolder->object2TagTableName(), tagId, 7u );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE
+          ( "1 since", (ValidityKey)6, row["IOV_SINCE"].data<ValidityKey>() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE
+          ( "1 until", (ValidityKey)8, row["IOV_UNTIL"].data<ValidityKey>() );
+      }
+    } catch ( std::exception& e ) {
+      cout << endl << e.what() << endl;
+      throw;
+    }
+  }
+  
+
+  
+  /// Tests tagging the HEAD
+  void test_tag_HEAD_5c() {
+    IFolderPtr folder = ralDb->createFolder( "/myfolder", 
+                                             payloadSpec,
+                                             "my description",
+                                             FolderVersioning::MULTI_VERSION );
+    RelationalFolder* relfolder = dynamic_cast<RelationalFolder*>(folder.get());
+    
+    { vector<RelationalObjectPtr> objs;
+      objs.push_back( dummyObject( 1, 1, 3 ) );
+      objs.push_back( dummyObject( 2, 6, 8 ) );
+      storeObjects( relfolder, objs );
+    }
+    { vector<RelationalObjectPtr> objs;
+      objs.push_back( dummyObject( 3, 2, 4 ) );
+      objs.push_back( dummyObject( 4, 3, 5 ) );
+      storeObjects( relfolder, objs );
+    }
+    
+    folder->tagCurrentHead( "mytagA", "a tag A" );
+    folder->tagCurrentHead( "mytagB", "a tag B" );
+    
+    RelationalTransaction transaction( ralDb->transactionMgr() );
+    
+    {
+      coral::ITable& table = 
+      ralDb->session().nominalSchema().tableHandle( relfolder->tagTableName() );
+      
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "tag table row count", 
+                                    2u, rowCount( table ) );
+      
+      // check tag table content (more detailed test in the insert/fetch test)
+      RelationalTableRow row = 
+        ralDb->tagMgr().fetchGlobalTagTableRows( "mytagB" )[0];
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "id", 2u, row["TAG_ID"].data<unsigned int>() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "name", string("mytagB"), row["TAG_NAME"].data<std::string>() );
+    }
+    
+    {
+      coral::ITable& table =
+      ralDb->session().nominalSchema().tableHandle
+      ( relfolder->object2TagTableName() );
+      
+      // 4 rows from each tag
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj2tag table row count", 
+                                    8u, rowCount( table ) );
+      
+      // check tag2iov table content
+      unsigned int tagId = 2;
+      RelationalTableRow row = ralDb->fetchObject2TagTableRow
+        ( relfolder->object2TagTableName(), tagId, 14u );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "1 since", (ValidityKey)1, row["IOV_SINCE"].data<ValidityKey>() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "1 until", (ValidityKey)2, row["IOV_UNTIL"].data<ValidityKey>() );
+      
+      row = ralDb->fetchObject2TagTableRow
+        ( relfolder->object2TagTableName(), tagId, 20u );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "1 since", (ValidityKey)2, row["IOV_SINCE"].data<ValidityKey>() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "1 until", (ValidityKey)3, row["IOV_UNTIL"].data<ValidityKey>() );
+      
+      row = ralDb->fetchObject2TagTableRow
+        ( relfolder->object2TagTableName(), tagId, 19u );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "1 since", (ValidityKey)3, row["IOV_SINCE"].data<ValidityKey>() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "1 until", (ValidityKey)5, row["IOV_UNTIL"].data<ValidityKey>() );
+      
+      row = ralDb->fetchObject2TagTableRow
+        ( relfolder->object2TagTableName(), tagId, 7u );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "1 since", (ValidityKey)6, row["IOV_SINCE"].data<ValidityKey>() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "1 until", (ValidityKey)8, row["IOV_UNTIL"].data<ValidityKey>() );
+    }
+  }
+  
+  
+  /// Tests tagging with an existing tag throws an exception
+  void test_tag_exists() {
+    IFolderPtr folder = ralDb->createFolder( "/myfolder", 
+                                             payloadSpec,
+                                             "my description",
+                                             FolderVersioning::MULTI_VERSION );
+    RelationalFolder* relfolder = dynamic_cast<RelationalFolder*>(folder.get());
+    
+    vector<RelationalObjectPtr> objs;
+    objs.push_back( dummyObject( 1, 1, 3 ) );
+    objs.push_back( dummyObject( 2, 6, 8 ) );
+    storeObjects( relfolder, objs );
+    
+    folder->tagCurrentHead( "mytagA", "a tag A" );
+    CPPUNIT_ASSERT_THROW( folder->tagCurrentHead( "mytagA", "a tag A" ),
+                          TagExists );
+  }      
+  
+  
+  /// Tests findObject for a tag
+  void test_findObject_tag_5c() {
+    IFolderPtr folder = ralDb->createFolder( "/myfolder", 
+                                             payloadSpec,
+                                             "my description",
+                                             FolderVersioning::MULTI_VERSION );
+    RelationalFolder* relfolder = dynamic_cast<RelationalFolder*>(folder.get());
+    
+    { vector<RelationalObjectPtr> objs;
+      objs.push_back( dummyObject( 1, 1, 3 ) );
+      objs.push_back( dummyObject( 2, 6, 8 ) );
+      storeObjects( relfolder, objs );
+    }
+    
+    folder->tagCurrentHead( "mytagA", "a tag A" );
+    
+    { vector<RelationalObjectPtr> objs;
+      objs.push_back( dummyObject( 3, 2, 4 ) );
+      objs.push_back( dummyObject( 4, 3, 5 ) );
+      storeObjects( relfolder, objs );
+    }
+    
+    IObjectPtr obj
+      = objMgr->findObject( relfolder,
+                           (ValidityKey)2,
+                           (ChannelId)0,
+                           "mytagA" );
+    
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "object id", 1u, obj->objectId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "channel id", 0u, obj->channelId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "since", (ValidityKey)1, obj->since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "until", (ValidityKey)3, obj->until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "payload", string("Object 1"),
+                                  obj->payload()["S"].data<std::string>() );
+  }
+  
+  
+  
+  /// Tests findObject for the HEAD
+  void test_findObject_HEAD_5c() {
+    IFolderPtr folder = ralDb->createFolder( "/myfolder", 
+                                             payloadSpec,
+                                             "my description",
+                                             FolderVersioning::MULTI_VERSION );
+    RelationalFolder* relfolder = dynamic_cast<RelationalFolder*>(folder.get());
+    
+    { vector<RelationalObjectPtr> objs;
+      objs.push_back( dummyObject( 1, 1, 3 ) );
+      objs.push_back( dummyObject( 2, 6, 8 ) );
+      storeObjects( relfolder, objs );
+    }
+    
+    folder->tagCurrentHead( "mytagA", "a tag A" );
+    
+    { vector<RelationalObjectPtr> objs;
+      objs.push_back( dummyObject( 3, 2, 4 ) );
+      objs.push_back( dummyObject( 4, 3, 5 ) );
+      storeObjects( relfolder, objs );
+    }
+    
+    IObjectPtr obj
+      = objMgr->findObject( relfolder,
+                           (ValidityKey)2,
+                           (ChannelId)0,
+                           "HEAD" );
+    
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "object id", 20u, obj->objectId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "channel id", 0u, obj->channelId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "since", (ValidityKey)2, obj->since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "until", (ValidityKey)3, obj->until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "payload", string("Object 3"),
+                                  obj->payload()["S"].data<std::string>() );
+  }
+  
+  
+  /// Tests a combination of insertGlobalTagTableRow and fetchGlobalTagTableRow
+  void test_insertGlobalTagTableRow_fetchGlobalTagTableRow() 
+  {
+    ralDb->createFolderSet( "/fs1" );         // Make sure node 1 exists
+    ralDb->createFolderSet( "/fs1/fs2" );     // Needed to create node 3
+    ralDb->createFolderSet( "/fs1/fs2/fs3" ); // Make sure node 3 exists
+    RelationalTransaction transaction( ralDb->transactionMgr() );
+    Time now;
+    ralDb->tagMgr().insertGlobalTagTableRow
+      ( 1, 1, "mytagA", HvsTagLock::UNLOCKED, "desc A", timeToString( now ) );
+    ralDb->tagMgr().insertGlobalTagTableRow
+      ( 3, 2, "mytagB", HvsTagLock::UNLOCKED, "desc B", timeToString( now ) );
+    RelationalTableRow row = 
+      ralDb->tagMgr().fetchGlobalTagTableRows( "mytagB" )[0];
+    CPPUNIT_ASSERT_EQUAL_MESSAGE
+      ( "folder id", 3u,
+        row["NODE_ID"].data<unsigned int>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE
+      ( "tag id", 2u,
+        row["TAG_ID"].data<unsigned int>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE
+      ( "name", string("mytagB"),
+        row["TAG_NAME"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE
+      ( "description", string("desc B"), 
+        row["TAG_DESCRIPTION"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE
+      ( "instime", string("yyyy-mm-dd_hh:mm:ss.nnnnnnnnn GMT").size(),
+        row["SYS_INSTIME"].data<std::string>().size() );
+    transaction.commit();
+  }  
+  
+  
+  /// Tests global uniqueness of tags -- tagging in a folder with a tag
+  /// that exists in another foder throws an exception
+  void test_tag_differentFolders_sameTag() {
+    IFolderPtr folder1 = ralDb->createFolder( "/myfolderA", 
+                                              payloadSpec,
+                                              "my description",
+                                              FolderVersioning::MULTI_VERSION );
+    RelationalFolder* f1 = dynamic_cast<RelationalFolder*>(folder1.get());
+    
+    IFolderPtr folder2 = ralDb->createFolder( "/myfolderB", 
+                                              payloadSpec,
+                                              "my description",
+                                              FolderVersioning::MULTI_VERSION );
+    RelationalFolder* f2 = dynamic_cast<RelationalFolder*>(folder2.get());
+    
+    f1->storeObject( 0, 4, dummyPayload( 0 ), 0 );
+    f2->storeObject( 0, 4, dummyPayload( 0 ), 0 );
+    f1->tagCurrentHead( "tag A", "desc" );
+    CPPUNIT_ASSERT_THROW( f2->tagCurrentHead( "tag A", "desc" ), TagExists );
+  }
+  
+
+  /// Tests tagging the HEAD as of a given object_id (for a user object)
+  void test_tag_asOfObjectId_userObject_5c() {
+    IFolderPtr folder = ralDb->createFolder( "/myfolder", 
+                                             payloadSpec,
+                                             "my description",
+                                             FolderVersioning::MULTI_VERSION );
+    RelationalFolder* relfolder = 
+      dynamic_cast<RelationalFolder*>(folder.get());
+    
+    { vector<RelationalObjectPtr> objs;
+      objs.push_back( dummyObject( 1, 1, 3 ) );
+      objs.push_back( dummyObject( 2, 6, 8 ) );
+      storeObjects( relfolder, objs );
+    }        
+    
+    { vector<RelationalObjectPtr> objs;
+      objs.push_back( dummyObject( 3, 2, 4 ) );
+      objs.push_back( dummyObject( 4, 3, 5 ) );
+      storeObjects( relfolder, objs );
+    }
+    
+    // Ultimately this could be set from a storeObjects return value:
+    //   objectId = storeObjects( relfolder, objs );
+    unsigned int objectId = 7;
+    // WARNING! The tag asOfDate and asOfObjectId used to take compatible 
+    // arguments (implicit conversion from unsigned int to Time)
+    relfolder->tagHeadAsOfObjectId
+      ( objectId,   "mytagA", "tag from user object" );
+    relfolder->tagHeadAsOfObjectId
+      ( objectId+1, "mytagB", "tag from left sys object" );
+    relfolder->tagHeadAsOfObjectId
+      ( objectId+2, "mytagC", "tag from right sys object" );
+    
+    RelationalTransaction transaction( ralDb->transactionMgr() );
+    
+    {
+      coral::ITable& table = 
+      ralDb->session().nominalSchema().tableHandle( relfolder->tagTableName() );
+      
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "tag table row count", 
+                                    3u, rowCount( table ) );
+      
+      // check tag table content (more detailed test in the insert/fetch test)
+      RelationalTableRow row = 
+        ralDb->tagMgr().fetchGlobalTagTableRows( "mytagB" )[0];
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "id", 2u, row["TAG_ID"].data<unsigned int>() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "name", string("mytagB"), row["TAG_NAME"].data<std::string>() );
+    }
+    
+    {
+      coral::ITable& table =
+      ralDb->session().nominalSchema().tableHandle
+      ( relfolder->object2TagTableName() );
+      
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj2tag table row count", 
+                                    6u, rowCount( table ) );
+      
+      // check tag2iov table content
+      unsigned int tagId = 2;
+      RelationalTableRow row = ralDb->fetchObject2TagTableRow
+        ( relfolder->object2TagTableName(), tagId, 1u );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "1 since", (ValidityKey)1, row["IOV_SINCE"].data<ValidityKey>() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "1 until", (ValidityKey)3, row["IOV_UNTIL"].data<ValidityKey>() );
+      
+      row = ralDb->fetchObject2TagTableRow
+        ( relfolder->object2TagTableName(), tagId, 7u );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "1 since", (ValidityKey)6, row["IOV_SINCE"].data<ValidityKey>() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "1 until", (ValidityKey)8, row["IOV_UNTIL"].data<ValidityKey>() );
+    }
+  }
+  
+  
+  /// Tests that deleteTag throws a TagNotFound exception when deleting
+  /// a nonexisting tag.
+  void test_deleteTag_nonexisting() {
+    IFolderPtr folder = m_db->createFolder( "/myfolder", 
+                                          payloadSpec,
+                                          "my description",
+                                          FolderVersioning::MULTI_VERSION );
+    folder->storeObject( 0, 4, dummyPayload( 0 ), 0 );
+    folder->tagCurrentHead( "tagA" );
+    CPPUNIT_ASSERT_THROW( folder->deleteTag( "nonexisting tag" ),
+                          TagNotFound );
+  }
+  
+  
+  /// Tests deleteTag
+  void test_deleteTag() {
+    try {
+      IFolderPtr folder = 
+        m_db->createFolder( "/myfolder", 
+                            payloadSpec,
+                            "my description",
+                            FolderVersioning::MULTI_VERSION );
+      folder->storeObject( 0, 4, dummyPayload( 0 ), 0 );
+      folder->tagCurrentHead( "tagA" );
+      folder->tagCurrentHead( "tagB" );
+      
+      folder->deleteTag( "tagA" );
+      
+      CPPUNIT_ASSERT_MESSAGE( "tagA deleted", ! m_db->existsTag( "tagA" ) );
+      
+      folder->storeObject( 2, 6, dummyPayload( 1 ), 0 );
+      folder->tagCurrentHead( "tagA" );
+      
+      // fetch tagA
+      //std::cout << "fetch objects in tagA" << std::endl;
+      IObjectIteratorPtr objs = folder->browseObjects( ValidityKeyMin,
+                                                       ValidityKeyMax,
+                                                       (ChannelId)0,
+                                                       "tagA" );
+
+      //std::cout << "tagA object count is " << objs->size() << std::endl;
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "tagA object count", 2u, 
+                                    (unsigned int)objs->size() );
+      
+      IObjectPtr obj = getNext(objs);
+      CPPUNIT_ASSERT_MESSAGE( "tagA obj 1 payload", 
+                              dummyPayload( 0 ) == obj->payload() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "tagA obj 1 since",
+                                    (ValidityKey)0, obj->since() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "tagA obj 1 until",
+                                    (ValidityKey)2, obj->until() );
+      
+      obj = getNext(objs);
+      CPPUNIT_ASSERT_MESSAGE( "tagA obj 2 payload", 
+                              dummyPayload( 1 ) == obj->payload() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "tagA obj 2 since",
+                                    (ValidityKey)2, obj->since() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "tagA obj 2 until",
+                                    (ValidityKey)6, obj->until() );
+    } catch ( std::exception& e ) {
+      std::cout << "Exception caught: " << e.what() << std::endl;
+      throw;     
+    }
+  }
+
+  
+  /// Tests deleteGlobalTagTableRow
+  void test_deleteGlobalTagTableRow() {
+    IFolderPtr folder = m_db->createFolder( "/myfolder", 
+                                          payloadSpec,
+                                          "my description",
+                                          FolderVersioning::MULTI_VERSION );
+    
+    folder->storeObject( 0, 4, dummyPayload( 0 ), 0 );
+    folder->storeObject( 2, 6, dummyPayload( 1 ), 0 );
+    folder->storeObject( 4, 8, dummyPayload( 2 ), 0 );
+    folder->tagCurrentHead( "tagA" );
+    
+    folder->storeObject( 0, 5, dummyPayload( 3 ), 0 );
+    folder->storeObject( 3, 7, dummyPayload( 4 ), 0 );
+    folder->storeObject( 5, 9, dummyPayload( 5 ), 0 );
+    folder->tagCurrentHead( "tagB" );
+    
+    RelationalTransaction transaction( ralDb->transactionMgr() );
+    coral::ITable& table = ralDb->session().nominalSchema().tableHandle
+      ( ralDb->globalTagTableName() );
+    
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "row count before delete", 
+                                  2u, rowCount( table ) );
+    
+    // Delete the first tagA (we know it has id = 1 in a new db)
+    // We need to delete from the object2tag table first or we violate
+    // the integrity constraint.
+    unsigned int tagId = 1;
+    ralDb->tagMgr().deleteGlobalTagTableRow( folder->id(), tagId );
+    
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "row count after delete", 
+                                  1u, rowCount( table ) );
+    
+    // Check the values of the remaining row
+    RelationalTableRow row = 
+      ralDb->tagMgr().fetchGlobalTagTableRows( "tagB" )[0];
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "tag id", 2u,
+                                  row["TAG_ID"].data<unsigned int>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "tag name", string("tagB"),
+                                  row["TAG_NAME"].data<std::string>() );
+    transaction.commit();
+  }
+  
+  
+  /// Tests deleteTagTableRow
+  void test_deleteTagTableRow() {
+    IFolderPtr folder = m_db->createFolder( "/myfolder", 
+                                          payloadSpec,
+                                          "my description",
+                                          FolderVersioning::MULTI_VERSION );
+    RelationalFolder* relfolder = dynamic_cast<RelationalFolder*>(folder.get());
+    
+    folder->storeObject( 0, 4, dummyPayload( 0 ), 0 );
+    folder->storeObject( 2, 6, dummyPayload( 1 ), 0 );
+    folder->storeObject( 4, 8, dummyPayload( 2 ), 0 );
+    folder->tagCurrentHead( "tagA" );
+    
+    folder->storeObject( 0, 5, dummyPayload( 3 ), 0 );
+    folder->storeObject( 3, 7, dummyPayload( 4 ), 0 );
+    folder->storeObject( 5, 9, dummyPayload( 5 ), 0 );
+    folder->tagCurrentHead( "tagB" );
+
+    RelationalTransaction transaction( ralDb->transactionMgr() );
+    coral::ITable& table = ralDb->session().nominalSchema().tableHandle
+      ( ralDb->globalTagTableName() );
+
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "row count before delete", 
+                                  2u, rowCount( table ) );
+    
+    // Delete the first tagA (we know it has id = 1 in a new db)
+    // We need to delete from the object2tag table first or we violate
+    // the integrity constraint.
+    unsigned int tagId = 1;
+    relfolder->deleteObject2TagTableRows
+      ( relfolder->object2TagTableName(), tagId );
+    ralDb->tagMgr().deleteGlobalTagTableRow( folder->id(), tagId );
+    
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "row count after delete", 
+                                  1u, rowCount( table ) );
+    
+    // Check the values of the remaining row
+    RelationalTableRow row
+      = ralDb->tagMgr().fetchGlobalTagTableRows( "tagB" )[0];    
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 tag id", 2u,
+                                  row["TAG_ID"].data<unsigned int>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 obj id", string("tagB"),
+                                  row["TAG_NAME"].data<std::string>() );
+    transaction.commit();
+  }
+  
+  
+  
+  /// Tests deleteObject2TagTableRows
+  void test_deleteObject2TagTableRows() {
+    IFolderPtr folder = m_db->createFolder( "/myfolder", 
+                                          payloadSpec,
+                                          "my description",
+                                          FolderVersioning::MULTI_VERSION );
+    RelationalFolder* relfolder = dynamic_cast<RelationalFolder*>(folder.get());
+
+    folder->storeObject( 0, 4, dummyPayload( 0 ), 0 );
+    folder->storeObject( 2, 6, dummyPayload( 1 ), 0 );
+    folder->storeObject( 4, 8, dummyPayload( 2 ), 0 );
+    folder->tagCurrentHead( "tagA" );
+
+    folder->storeObject( 0, 5, dummyPayload( 3 ), 0 );
+    folder->storeObject( 3, 7, dummyPayload( 4 ), 0 );
+    folder->storeObject( 5, 9, dummyPayload( 5 ), 0 );
+    folder->tagCurrentHead( "tagB" );
+
+    RelationalTransaction transaction( ralDb->transactionMgr() );
+    coral::ITable& table = ralDb->session().nominalSchema().tableHandle
+      ( relfolder->object2TagTableName() );
+    
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "row count before delete", 
+                                  6u, rowCount( table ) );
+    
+    // Delete the first tagA (we know it has id = 1 in a new db)
+    unsigned int tagId = 1;
+    relfolder->deleteObject2TagTableRows
+      ( relfolder->object2TagTableName(), tagId );
+    
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "row count after delete", 
+                                  3u, rowCount( table ) );
+    
+    // Check the values of the remaining rows (tagB == tagId 2)
+    tagId = 2;
+    unsigned int objectId = 26;
+    RelationalTableRow row = ralDb->fetchObject2TagTableRow
+      ( relfolder->object2TagTableName(), tagId, objectId );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE
+      ( "1 tag id", 2u, row["TAG_ID"].data<unsigned int>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE
+      ( "1 obj id", 26u, row["OBJECT_ID"].data<unsigned int>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE
+      ( "1 since", (ValidityKey)0, row["IOV_SINCE"].data<ValidityKey>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE
+      ( "1 until", (ValidityKey)3, row["IOV_UNTIL"].data<ValidityKey>() );
+    objectId = 31;
+
+    row = ralDb->fetchObject2TagTableRow
+      ( relfolder->object2TagTableName(), tagId, objectId );    
+    CPPUNIT_ASSERT_EQUAL_MESSAGE
+      ( "2 tag id", 2u, row["TAG_ID"].data<unsigned int>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE
+      ( "2 obj id", 31u, row["OBJECT_ID"].data<unsigned int>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE
+      ( "2 since", (ValidityKey)5, row["IOV_SINCE"].data<ValidityKey>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE
+      ( "2 until", (ValidityKey)9, row["IOV_UNTIL"].data<ValidityKey>() );
+
+    objectId = 32;
+    row = ralDb->fetchObject2TagTableRow
+      ( relfolder->object2TagTableName(), tagId, objectId );    
+    CPPUNIT_ASSERT_EQUAL_MESSAGE
+      ( "3 tag id", 2u, row["TAG_ID"].data<unsigned int>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE
+      ( "3 obj id", 32u, row["OBJECT_ID"].data<unsigned int>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE
+      ( "3 since", (ValidityKey)3, row["IOV_SINCE"].data<ValidityKey>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE
+      ( "3 until", (ValidityKey)5, row["IOV_UNTIL"].data<ValidityKey>() );
+    
+    transaction.commit();
+  }
+    
+  
+  
+  /// Tests insertionTimeOfLastObjectInTag (bug #40812)
+  void test_insertionTimeOfLastObjectInTag() {
+    IFolderPtr folder = m_db->createFolder( "/myfolder", 
+                                          payloadSpec,
+                                          "my description",
+                                          FolderVersioning::MULTI_VERSION );
+    
+    folder->storeObject( 0, 4, dummyPayload( 0 ), 0 );
+    IObjectPtr obj = folder->findObject( 1, 0 );
+    Time lastObjectInsTime = obj->insertionTime();
+    folder->tagCurrentHead( "tag A" );
+    
+    folder->storeObject( 1, 5, dummyPayload( 1 ), 0 );
+    folder->storeObject( 2, 6, dummyPayload( 2 ), 0 );
+     
+    CPPUNIT_ASSERT_EQUAL_MESSAGE
+      ( "tag time", 
+        lastObjectInsTime, 
+        folder->insertionTimeOfLastObjectInTag( "tag A" ) );
+ 
+    // test user tags
+    folder->storeObject( 3, 8, dummyPayload( 3 ), 0, "tag B" );
+    IObjectPtr obj2 = folder->findObject( 3, 0, "tag B" );
+    Time lastObjectInsTime2  = obj2->insertionTime();
+    folder->storeObject( 4, 9, dummyPayload( 3 ), 0 );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE
+      ( "user tag time", 
+      lastObjectInsTime2, 
+        folder->insertionTimeOfLastObjectInTag( "tag B" ) );
+  
+  }
+  
+  
+  /// Tests that user tagged objects correctly create system objects
+  /// in their 'tag space'
+  void test_userTag_systemObjects() {
+    IFolderPtr folder = m_db->createFolder( "/a", 
+                                          payloadSpec,
+                                          "desc", 
+                                          FolderVersioning::MULTI_VERSION);
+    RelationalFolder* relfolder = dynamic_cast<RelationalFolder*>(folder.get());
+
+    ChannelId ch = 0;
+    folder->storeObject( 0, 10, dummyPayload( 1 ), ch, "A" );
+    folder->storeObject( 1, 5, dummyPayload( 2 ), ch, "A" );
+    
+    RelationalTransaction transaction( ralDb->transactionMgr() );
+    coral::ITable& table = ralDb->session().nominalSchema().tableHandle
+      ( relfolder->objectTableName() );
+    
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "row count", 8u, rowCount( table ) );
+    
+    RelationalObjectTable 
+      objectTable( &(ralDb->queryMgr()), false, *relfolder );
+    bool fetchPayload = true;
+    RelationalObjectTableRow
+      row( objectTable.fetchRowForId( 1u, fetchPayload ) );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "object id", 1u, row.objectId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "since", (ValidityKey)0, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "until", (ValidityKey)10
+     
+                                  , row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "user tag id", 0u, row.userTagId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "payload", string("Object 1"),
+                                  row["S"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "original id", 0u, row.originalId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "new head id", 7u, row.newHeadId() );
+
+    row = objectTable.fetchRowForId( 4u, fetchPayload );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "object id", 4u, row.objectId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "since", (ValidityKey)0, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "until", (ValidityKey)10, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "user tag id", 1u, row.userTagId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "payload", string("Object 1"),
+                                  row["S"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "original id", 0u, row.originalId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "new head id", 10u, row.newHeadId() );    
+    
+    row = objectTable.fetchRowForId( 7u, fetchPayload );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "object id", 7u, row.objectId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "since", (ValidityKey)1, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "until", (ValidityKey)5, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "user tag id", 0u, row.userTagId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "payload", string("Object 2"),
+                                  row["S"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "original id", 0u, row.originalId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "new head id", 0u, row.newHeadId() );    
+    
+    row = objectTable.fetchRowForId( 8u, fetchPayload );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "object id", 8u, row.objectId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "since", (ValidityKey)0, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "until", (ValidityKey)1, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "user tag id", 0u, row.userTagId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "payload", string("Object 1"),
+                                  row["S"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "original id", 1u, row.originalId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "new head id", 0u, row.newHeadId() );    
+    
+    row = objectTable.fetchRowForId( 9u, fetchPayload );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "object id", 9u, row.objectId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "since", (ValidityKey)5, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "until", (ValidityKey)10, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "user tag id", 0u, row.userTagId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "payload", string("Object 1"),
+                                  row["S"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "original id", 1u, row.originalId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "new head id", 0u, row.newHeadId() );    
+    
+    row = objectTable.fetchRowForId( 10u, fetchPayload );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "object id", 10u, row.objectId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "since", (ValidityKey)1, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "until", (ValidityKey)5, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "user tag id", 1u, row.userTagId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "payload", string("Object 2"),
+                                  row["S"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "original id", 0u, row.originalId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "new head id", 0u, row.newHeadId() );    
+    
+    row = objectTable.fetchRowForId( 11u, fetchPayload );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "object id", 11u, row.objectId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "since", (ValidityKey)0, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "until", (ValidityKey)1, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "user tag id", 1u, row.userTagId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "payload", string("Object 1"),
+                                  row["S"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "original id", 4u, row.originalId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "new head id", 0u, row.newHeadId() );    
+    
+    row = objectTable.fetchRowForId( 12u, fetchPayload );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "object id", 12u, row.objectId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "since", (ValidityKey)5, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "until", (ValidityKey)10, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "user tag id", 1u, row.userTagId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "payload", string("Object 1"),
+                                  row["S"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "original id", 4u, row.originalId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "new head id", 0u, row.newHeadId() );    
+    
+    transaction.commit();
+  }
+  
+  
+  /// Tests existsUserTag behavior in concert with normal tags
+  void test_existsUserTag_normal_tag() {
+    IFolderPtr folder = ralDb->createFolder( "/myfolder",
+                                             payloadSpec,
+                                             "my description",
+                                             FolderVersioning::MULTI_VERSION );
+    RelationalFolder* relfolder = dynamic_cast<RelationalFolder*>(folder.get());
+    
+    CPPUNIT_ASSERT_MESSAGE( "no user tag yet", 
+                            ! relfolder->existsUserTag( "A" ) );
+    CPPUNIT_ASSERT_MESSAGE( "no tag yet", ! ralDb->existsTag( "A" ) );
+    
+    folder->storeObject( 0, 10, dummyPayload( 1 ), (ChannelId)0 );
+    folder->tagCurrentHead( "A" );
+    
+    CPPUNIT_ASSERT_MESSAGE( "user tag does not exist", 
+                            ! relfolder->existsUserTag( "A" ) );
+    CPPUNIT_ASSERT_MESSAGE( "tag exists", ralDb->existsTag( "A" ) );
+  }
+  
+  
+  /// Tests existsUserTag
+  void test_existsUserTag() {
+    IFolderPtr folder = ralDb->createFolder( "/myfolder",
+                                             payloadSpec,
+                                             "my description",
+                                             FolderVersioning::MULTI_VERSION );
+    RelationalFolder* relfolder = dynamic_cast<RelationalFolder*>(folder.get());
+
+    CPPUNIT_ASSERT_MESSAGE( "no user tag yet", 
+                            ! relfolder->existsUserTag( "A" ) );
+    CPPUNIT_ASSERT_MESSAGE( "no tag yet", ! ralDb->existsTag( "A" ) );
+    
+    folder->storeObject( 0, 10, dummyPayload( 1 ), (ChannelId)0, "A" );
+    
+    CPPUNIT_ASSERT_MESSAGE( "user tag exists", 
+                            relfolder->existsUserTag( "A" ) );
+    CPPUNIT_ASSERT_MESSAGE( "tag exists", ralDb->existsTag( "A" ) );
+  }
+  
+  
+  /// Tests updateObjectTableNewHeadId for a given user tag id and makes
+  /// sure the userTagId parameter correctly selects the intended row
+  /// for updating.
+  void test_updateObjectTableNewHeadId_userTag() {
+      IFolderPtr folder = ralDb->createFolder( "/myfolder",
+                                               payloadSpec,
+                                               "my description",
+                                               FolderVersioning::MULTI_VERSION );
+      RelationalFolder* relfolder = dynamic_cast<RelationalFolder*>(folder.get());
+      
+      // this creates two objects, ids 1 (tagId 0) and 4 (tagId 1)
+      folder->storeObject( 0, 10, dummyPayload( 1 ), (ChannelId)0, "A" );
+      
+      RelationalObjectTable 
+        objectTable( &(ralDb->queryMgr()), false, *relfolder );
+      {
+        RelationalTransaction transaction( ralDb->transactionMgr() );        
+        bool fetchPayload = true;
+        RelationalObjectTableRow
+          row( objectTable.fetchRowForId( 1u, fetchPayload ) );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "object_id 1", 1u, row.objectId() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "new_head_id 1", 0u,row.newHeadId() );
+        row = objectTable.fetchRowForId( 4u, fetchPayload );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "object_id 2", 4u, row.objectId() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "new_head_id 2", 0u,row.newHeadId() );
+        transaction.commit();
+      }
+      
+      {
+        RelationalTransaction transaction( ralDb->transactionMgr() );
+        
+        // now update the new head ids
+        unsigned int newHeadId = 5;
+        unsigned int userTagId = 0;
+        updateObjectTableNewHeadId( objMgr.get(),
+                                    relfolder->objectTableName(),
+                                    relfolder->channelTableName(),
+                                    (ValidityKey)2, 
+                                    (ValidityKey)4,
+                                    (ChannelId)0,
+                                    newHeadId, 
+                                    userTagId );
+        newHeadId = 6;
+        userTagId = 1;
+        updateObjectTableNewHeadId( objMgr.get(),
+                                    relfolder->objectTableName(),
+                                    relfolder->channelTableName(),
+                                    (ValidityKey)2, 
+                                    (ValidityKey)4,
+                                    (ChannelId)0,
+                                    newHeadId, 
+                                    userTagId );
+        transaction.commit();
+      }
+      
+      {
+        RelationalTransaction transaction( ralDb->transactionMgr() );
+        bool fetchPayload = true;
+        RelationalObjectTableRow
+          row( objectTable.fetchRowForId( 1u, fetchPayload ) );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "object_id 3", 1u, row.objectId() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "new_head_id 3", 5u,row.newHeadId() );
+        row = objectTable.fetchRowForId( 4u, fetchPayload );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "object_id 4", 4u, row.objectId() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE( "new_head_id 4", 6u,row.newHeadId() );
+        transaction.commit();
+      }
+  }
+  
+  
+  
+  // -----------------------------------------------------------------------
+  
+  void test_insertChannelTableRow() {
+    IFolderPtr folder = ralDb->createFolder( "/myfolder", payloadSpec );
+    RelationalFolder* relfolder = 
+      dynamic_cast<RelationalFolder*>(folder.get());
+    RelationalObjectMgr objMgr( *ralDb );
+    
+    {
+      RelationalTransaction transaction( ralDb->transactionMgr() );
+      objMgr.insertChannelTableRow( relfolder->channelTableName(),
+                                    (ChannelId)1,
+                                    2u,
+                                    true,
+                                    "ch name",
+                                    "ch desc" );
+      transaction.commit();
+    }
+    {
+      RelationalTransaction transaction( ralDb->transactionMgr() );
+      RelationalChannelTable channelTable( *ralDb, *relfolder );
+      RelationalTableRow row = channelTable.fetchRowForId( 1 );
+      CPPUNIT_ASSERT_EQUAL
+        ( (ChannelId)1, row["CHANNEL_ID"].data<ChannelId>() );
+      CPPUNIT_ASSERT_EQUAL
+        ( 2u, row["LAST_OBJECT_ID"].data<unsigned int>() );
+      CPPUNIT_ASSERT_EQUAL
+        ( true, row["HAS_NEW_DATA"].data<bool>() );
+      CPPUNIT_ASSERT_EQUAL
+        ( std::string("ch name"), row["CHANNEL_NAME"].data<std::string>() );
+      CPPUNIT_ASSERT_EQUAL
+        ( std::string("ch desc"), row["DESCRIPTION"].data<std::string>() );
+      transaction.commit();
+    }
+  }
+  
+  // -----------------------------------------------------------------------
+  
+  
+  void test_updateChannelTable() {
+    try{      
+      IFolderPtr folder = ralDb->createFolder( "/myfolder", payloadSpec );
+      RelationalFolder* relfolder = 
+        dynamic_cast<RelationalFolder*>(folder.get());
+      RelationalObjectMgr objMgr( *ralDb );
+      
+      {
+        RelationalTransaction transaction( ralDb->transactionMgr() );
+        objMgr.updateChannelTable
+          ( relfolder->channelTableName(), (ChannelId)2, 0, true );
+        transaction.commit();
+      }
+      {
+        RelationalTransaction transaction( ralDb->transactionMgr() );
+        RelationalChannelTable channelTable( *ralDb, *relfolder );
+        RelationalTableRow row = channelTable.fetchRowForId( 2 );
+        CPPUNIT_ASSERT_EQUAL
+          ( (ChannelId)2, row["CHANNEL_ID"].data<ChannelId>() );
+        CPPUNIT_ASSERT_EQUAL
+          ( 0u, row["LAST_OBJECT_ID"].data<unsigned int>() );
+        CPPUNIT_ASSERT_EQUAL
+          ( true, row["HAS_NEW_DATA"].data<bool>() );
+        CPPUNIT_ASSERT_EQUAL
+          ( std::string(""), row["CHANNEL_NAME"].data<std::string>() );
+        transaction.commit();
+      }
+      
+    } catch ( std::exception& e ) {
+      std::cout << "Exception caught: " << e.what() << std::endl;
+      throw;     
+    }
+  }
+  
+ 
+  // -----------------------------------------------------------------------
+  
+  
+  void test_bulkUpdateChannelTable() {
+    try{      
+      IFolderPtr folder = ralDb->createFolder( "/myfolder", payloadSpec );
+      RelationalFolder* relfolder = 
+        dynamic_cast<RelationalFolder*>(folder.get());
+      RelationalObjectMgr objMgr( *ralDb );
+      
+      {
+        RelationalTransaction transaction( ralDb->transactionMgr() );
+        // use updateChannelTable to populate the channels table
+        objMgr.updateChannelTable
+          ( relfolder->channelTableName(), (ChannelId)2, 0, true );
+        objMgr.updateChannelTable
+          ( relfolder->channelTableName(), (ChannelId)3, 0, false );
+        objMgr.updateChannelTable
+          ( relfolder->channelTableName(), (ChannelId)4, 0, true );
+        objMgr.updateChannelTable
+          ( relfolder->channelTableName(), (ChannelId)5, 0, false );
+        
+        std::map< ChannelId, unsigned int > updateDataMap;
+        updateDataMap[3] = 30;
+        updateDataMap[4] = 40;
+        objMgr.bulkUpdateChannelTable
+          ( relfolder->channelTableName(), updateDataMap, false );
+        transaction.commit();
+      }
+      {
+        RelationalTransaction transaction( ralDb->transactionMgr() );
+        RelationalChannelTable channelTable( *ralDb, *relfolder );
+        RelationalTableRow row = channelTable.fetchRowForId( 2 );
+        CPPUNIT_ASSERT_EQUAL
+          ( (ChannelId)2, row["CHANNEL_ID"].data<ChannelId>() );
+        CPPUNIT_ASSERT_EQUAL
+          ( 0u, row["LAST_OBJECT_ID"].data<unsigned int>() );
+        CPPUNIT_ASSERT_EQUAL
+          ( true, row["HAS_NEW_DATA"].data<bool>() );
+        CPPUNIT_ASSERT_EQUAL
+          ( std::string(""), row["CHANNEL_NAME"].data<std::string>() );
+        transaction.commit();
+      }
+      {
+        RelationalTransaction transaction( ralDb->transactionMgr() );
+        RelationalChannelTable channelTable( *ralDb, *relfolder );
+        RelationalTableRow row = channelTable.fetchRowForId( 3 );
+        CPPUNIT_ASSERT_EQUAL
+          ( (ChannelId)3, row["CHANNEL_ID"].data<ChannelId>() );
+        CPPUNIT_ASSERT_EQUAL
+          ( 30u, row["LAST_OBJECT_ID"].data<unsigned int>() );
+        CPPUNIT_ASSERT_EQUAL
+          ( false, row["HAS_NEW_DATA"].data<bool>() );
+        CPPUNIT_ASSERT_EQUAL
+          ( std::string(""), row["CHANNEL_NAME"].data<std::string>() );
+        transaction.commit();
+      }
+      {
+        RelationalTransaction transaction( ralDb->transactionMgr() );
+        RelationalChannelTable channelTable( *ralDb, *relfolder );
+        RelationalTableRow row = channelTable.fetchRowForId( 4 );
+        CPPUNIT_ASSERT_EQUAL
+          ( (ChannelId)4, row["CHANNEL_ID"].data<ChannelId>() );
+        CPPUNIT_ASSERT_EQUAL
+          ( 40u, row["LAST_OBJECT_ID"].data<unsigned int>() );
+        CPPUNIT_ASSERT_EQUAL
+          ( false, row["HAS_NEW_DATA"].data<bool>() );
+        CPPUNIT_ASSERT_EQUAL
+          ( std::string(""), row["CHANNEL_NAME"].data<std::string>() );
+        transaction.commit();
+      }
+      {
+        RelationalTransaction transaction( ralDb->transactionMgr() );
+        RelationalChannelTable channelTable( *ralDb, *relfolder );
+        RelationalTableRow row = channelTable.fetchRowForId( 5 );
+        CPPUNIT_ASSERT_EQUAL
+          ( (ChannelId)5, row["CHANNEL_ID"].data<ChannelId>() );
+        CPPUNIT_ASSERT_EQUAL
+          ( 0u, row["LAST_OBJECT_ID"].data<unsigned int>() );
+        CPPUNIT_ASSERT_EQUAL
+          ( false, row["HAS_NEW_DATA"].data<bool>() );
+        CPPUNIT_ASSERT_EQUAL
+          ( std::string(""), row["CHANNEL_NAME"].data<std::string>() );
+        transaction.commit();
+      }
+      
+    } catch ( std::exception& e ) {
+      std::cout << "Exception caught: " << e.what() << std::endl;
+      throw;     
+    }
+  }
+  
+  
+  // -----------------------------------------------------------------------
+  
+  
+  void test_fetchLastRowsWithNewData() 
+  {
+    IFolderPtr folder = ralDb->createFolder( "/myfolder", payloadSpec );
+    RelationalFolder* relfolder = 
+      dynamic_cast<RelationalFolder*>(folder.get());
+    RelationalObjectMgr objMgr( *ralDb );
+    
+    std::vector<RelationalObjectTableRow> rows;
+    for ( int i = 0; i < 10; ++i ) 
+    {
+      ChannelId ch = i;
+      rows.push_back( RelationalObjectTableRow( dummyObject( i, 0, 1, ch ) ) );
+      rows[rows.size()-1].setObjectId( i );
+    }
+    { 
+      // First fill the channels table
+      RelationalTransaction transaction( ralDb->transactionMgr() );
+      // use updateChannelTable to populate the channels table
+      for ( int i = 0; i < 10; ++i ) 
+      {
+        objMgr.updateChannelTable
+          ( relfolder->channelTableName(), (ChannelId)i, 0, false );
+      }
+      transaction.commit();
+    }    
+    {
+      // Then populate the object table
+      RelationalTransaction transaction( ralDb->transactionMgr() );
+      objMgr.bulkInsertObjectTableRows( relfolder->objectTableName(),
+                                        rows, 
+                                        folder->payloadSpecification() );
+      transaction.commit();
+    }
+    {
+      // Update rows with new data in the channels table
+      RelationalTransaction transaction( ralDb->transactionMgr() );
+      std::map< ChannelId, unsigned int > updateDataMap;
+      updateDataMap[2] = 2;
+      updateDataMap[3] = 3;
+      objMgr.bulkUpdateChannelTable
+        ( relfolder->channelTableName(), updateDataMap, false );
+      objMgr.updateChannelTable
+        ( relfolder->channelTableName(), (ChannelId)2, 0, true );
+      objMgr.updateChannelTable
+        ( relfolder->channelTableName(), (ChannelId)3, 0, true );
+      transaction.commit();
+    }    
+    {
+      RelationalTransaction transaction( ralDb->transactionMgr() );
+      std::vector<RelationalObjectTableRow> rows;
+      objMgr.fetchLastRowsWithNewData( relfolder, rows );
+      CPPUNIT_ASSERT_EQUAL( (size_t)2, rows.size() );
+      CPPUNIT_ASSERT_EQUAL( (ChannelId)2, rows[0].channelId() );
+      CPPUNIT_ASSERT_EQUAL( (ChannelId)3, rows[1].channelId() );
+      transaction.commit();
+    }
+  }
+  
+  
+  // -----------------------------------------------------------------------
+
+
+  void test_channelTableFK() 
+  {
+    const MSG::Level oldOutputLevel = application().outputLevel();
+    // Remove "ORA-02291 integrity constraint violated" printout from CORAL
+    application().setOutputLevel( MSG::FATAL );
+    try {
+      IFolderPtr folder = ralDb->createFolder( "/myfolder", payloadSpec );
+      RelationalFolder* relfolder = 
+        dynamic_cast<RelationalFolder*>(folder.get());
+      RelationalObjectMgr objMgr( *ralDb );
+      // Prepare some rows to insert into the IOV table
+      std::vector<RelationalObjectTableRow> rows;
+      for ( int i = 0; i < 10; ++i ) 
+      {
+        ChannelId ch = i;
+        rows.push_back( RelationalObjectTableRow( dummyObject(i,0,1,ch) ) );
+        rows[rows.size()-1].setObjectId( i );
+      }
+      // Try to populate the IOV table without first filling the channel table
+      try
+      {
+        RelationalTransaction transaction( ralDb->transactionMgr() );
+        objMgr.bulkInsertObjectTableRows( relfolder->objectTableName(),
+                                          rows, 
+                                          folder->payloadSpecification() );
+        transaction.commit();
+      }
+      // Warning: the test will succeed on Oracle (exception is caught),
+      // but it will print an error message from OracleAccess anyway
+      catch ( std::exception& ) 
+      {
+        if ( ralDb->sessionMgr()->databaseTechnology() == "SQLite" ) 
+          CPPUNIT_FAIL( "Expected FK not to be enforced on sqlite...???" );
+      }
+    }
+    catch ( ... ) 
+    {
+      application().setOutputLevel( oldOutputLevel );
+      throw;
+    }    
+    application().setOutputLevel( oldOutputLevel );
+  }
+  
+  
+  // -----------------------------------------------------------------------
+  
+  
+  void test_lastUpdate_SV() {
+    try {
+      IFolderPtr folder = ralDb->createFolder( "/myfolder", payloadSpec );
+      RelationalFolder* relfolder = 
+        dynamic_cast<RelationalFolder*>(folder.get());
+      {
+        vector<RelationalObjectPtr> objs;
+        objs.push_back( dummyObject( 1, 0, ValidityKeyMax ) );
+        storeObjects( relfolder, objs );
+      }
+      // sleep for one second to make sure the update time change is properly
+      // picked up (MySQL has a 1s granularity for example)
+      sleep(1);
+      {
+        vector<RelationalObjectPtr> objs;
+        objs.push_back( dummyObject( 2, 10, ValidityKeyMax ) );
+        storeObjects( relfolder, objs );
+      }
+      
+      RelationalTransaction transaction( ralDb->transactionMgr() );
+      RelationalObjectTable 
+        objectTable( &(ralDb->queryMgr()), false, *relfolder );
+      bool fetchPayload = true;
+      RelationalObjectTableRow row = 
+        objectTable.fetchRowForId( 1u, fetchPayload );
+      CPPUNIT_ASSERT( row.insertionTime() < row.lastModDate() );
+      row = objectTable.fetchRowForId( 2u, fetchPayload );
+      CPPUNIT_ASSERT( row.insertionTime() == row.lastModDate() );
+      transaction.commit();
+      
+    } catch ( std::exception& e ) {
+      std::cout << "Exception caught: " << e.what() << std::endl;
+      throw;     
+    }
+  }
+  
+  
+  // -----------------------------------------------------------------------
+  
+  
+  void test_lastUpdate_MV() {
+    try {
+      IFolderPtr folder = 
+      ralDb->createFolder( "/myfolder", 
+                           payloadSpec,
+                           "desc", 
+                           FolderVersioning::MULTI_VERSION );
+      RelationalFolder* relfolder = 
+        dynamic_cast<RelationalFolder*>(folder.get());
+      {
+        vector<RelationalObjectPtr> objs;
+        objs.push_back( dummyObject( 1, 0, ValidityKeyMax ) );
+        storeObjects( relfolder, objs );
+      }
+      // sleep for one second to make sure the update time change is properly
+      // picked up (MySQL has a 1s granularity for example)
+      sleep(1);
+      {
+        vector<RelationalObjectPtr> objs;
+        objs.push_back( dummyObject( 2, 10, ValidityKeyMax ) );
+        storeObjects( relfolder, objs );
+      }
+      
+      RelationalTransaction transaction( ralDb->transactionMgr() );      
+      RelationalObjectTable 
+        objectTable( &(ralDb->queryMgr()), false, *relfolder );
+      bool fetchPayload = true;
+      RelationalObjectTableRow row = 
+        objectTable.fetchRowForId( 1u, fetchPayload );
+      CPPUNIT_ASSERT( row.insertionTime() < row.lastModDate() );
+      row = objectTable.fetchRowForId( 7u, fetchPayload );
+      CPPUNIT_ASSERT( row.insertionTime() == row.lastModDate() );
+      transaction.commit();
+      
+    } catch ( std::exception& e ) {
+      std::cout << "Exception caught: " << e.what() << std::endl;
+      throw;     
+    }
+  }
+  
+  
+  // -----------------------------------------------------------------------
+  
+  
+  unsigned int rowCount( const coral::ITable& tableHandle ) 
+  {
+    // TEMPORARY -- working around a bug in the sqlite backend
+    if ( ralDb->sessionMgr()->databaseTechnology() == "SQLite" ) {
+      std::auto_ptr<coral::IQuery> query( tableHandle.newQuery() );
+      
+      coral::AttributeList output;
+      output.extend( "count(*)", "unsigned int" );
+      query->addToOutputList( "count(*)" );
+      query->defineOutput( output );
+      
+      coral::ICursor& cursor = query->execute();
+      
+      if ( cursor.next() ) {
+        const coral::AttributeList& row( cursor.currentRow() );
+        return row["count(*)"].data<unsigned int>();
+      } else {
+        throw RelationalException
+        ( "Could not fetch row count", "RalObjectTable" );
+      }
+    } else {
+      std::auto_ptr<coral::IQuery> query( tableHandle.newQuery() );
+      
+      query->addToOutputList( "count(*)", "count" );
+      
+      coral::ICursor& cursor = query->execute();
+      
+      if ( cursor.next() ) {
+        const coral::Attribute& count = cursor.currentRow()["count"];
+        if ( count.specification().type() == typeid(int) )
+          return count.data<int>();
+        else if ( count.specification().type() == typeid(long) )
+          return static_cast<unsigned int>( count.data<long>() );
+        else if ( count.specification().type() == typeid(double) )
+          return static_cast<unsigned int>( count.data<double>() );
+        else
+          return static_cast<unsigned int>
+            ( count.data<Int64>() );
+      } else {
+        throw RelationalException( "Could not fetch row count", 
+                                   "RalObjectTable" );
+      }
+    }
+  }
+  
+  
+  /// Utility method to return a dummy object with a distinct payload
+  /// (determined by 'index') for a given set of since/until/channel
+  RelationalObjectPtr dummyObject( int index,
+                                   const ValidityKey& since,
+                                   const ValidityKey& until,
+                                   const ChannelId& channel = 0 ) {
+    RelationalObjectPtr 
+    obj( new RelationalObject( since, 
+                               until,
+                               dummyPayload( index ),
+                               channel ) );
+    return obj;
+  }
+  
+  
+  /// Utility method to generate a distinct payload for a given index
+  Record dummyPayload( int index ) 
+  {
+    Record payload( payloadSpec );
+    payload["I"].setValue<Int32>( index );
+    std::stringstream s;
+    s << "Object " << index;
+    payload["S"].setValue<String255>( s.str() );
+    payload["X"].setValue<Float>( (float)(index/1000.) );
+    return payload;
+  }
+  
+  void setUp() {  
+    try {
+      createDB();
+      openDB(false);
+      ralDb = dynamic_cast<RalDatabase*>(m_db.get());
+      objMgr = std::auto_ptr<RelationalObjectMgr>( new RelationalObjectMgr( *ralDb ) );
+    } catch ( std::exception& e ) {
+      std::cout << "Exception caught: " << e.what() << std::endl;
+      throw;     
+    }
+  }
+		
+
+  void tearDown() {
+    forceDisconnect();
+  }
+		
+		
+};
+
+CPPUNIT_TEST_SUITE_REGISTRATION( RelationalObjectMgrTest );
+
+} // namespace
+
+
+COOLTEST_MAIN(RelationalObjectMgrTest)
+
diff --git a/RelationalCool/tests/RelationalObjectSet/test_RelationalObjectSet.cpp b/RelationalCool/tests/RelationalObjectSet/test_RelationalObjectSet.cpp
new file mode 100644
index 000000000..8a84d1fcd
--- /dev/null
+++ b/RelationalCool/tests/RelationalObjectSet/test_RelationalObjectSet.cpp
@@ -0,0 +1,244 @@
+// $Id: test_RelationalObjectSet.cpp,v 1.24 2008-04-10 08:32:52 avalassi Exp $
+
+// Disable CppUnit header warnings from gcc41 nightlies (task #5837)
+#include "../Common/CppUnit_headers.h" 
+
+// Include files
+#include <iostream>
+#include <string>
+#include <cppunit/extensions/HelperMacros.h>
+#include "CoolKernel/IDatabase.h"
+#include "CoolKernel/IDatabaseSvc.h"
+#include "CoolKernel/IFolder.h"
+#include "CoolKernel/IObject.h"
+#include "CoolKernel/IObjectIterator.h"
+#include "CoolKernel/types.h"
+#include "CoolKernel/Record.h"
+#include "CoolKernel/RecordSpecification.h"
+#include "CoralBase/Attribute.h"
+
+// Local include files
+#include "src/CoralApplication.h"
+#include "src/timeToString.h"
+
+namespace cool {
+  const char* COOLTESTDB = "COOLTESTDB";
+  class ObjectSetTest;
+}
+
+//-----------------------------------------------------------------------------
+
+class cool::ObjectSetTest : public CppUnit::TestFixture {
+
+  CPPUNIT_TEST_SUITE( ObjectSetTest );
+
+  CPPUNIT_TEST( test_begin );
+  CPPUNIT_TEST( test_iterator_prefix_increment );
+  CPPUNIT_TEST( test_end );
+  CPPUNIT_TEST( test_iterator_equality );
+  CPPUNIT_TEST( test_iterator_copy_constructor );
+
+  CPPUNIT_TEST_SUITE_END();
+
+public:
+
+  std::string connectString;
+  IDatabasePtr db;
+  IFolderPtr folder;
+
+  RecordSpecification payloadSpec;
+  
+  // Tests that iterator copies are equal and iterate independently.
+  void test_iterator_copy_constructor() {
+    folder->setPrefetchAll( true );
+    IObjectVectorPtr objs = folder->browseObjects( 5, 25, 0 )->fetchAllAsVector();
+    IObjectVector::const_iterator iter = objs->begin();
+
+    IObjectVector::const_iterator
+      iter_copy = IObjectVector::const_iterator( iter );
+
+    CPPUNIT_ASSERT_MESSAGE( "iter_copy before increment",
+                            dummyPayload( 0 ) == (*iter_copy)->payload() );
+
+    ++iter;
+
+    CPPUNIT_ASSERT_MESSAGE( "iter after after first increment",
+                            dummyPayload( 1 ) == (*iter)->payload() );
+    CPPUNIT_ASSERT_MESSAGE( "iter_copy after first increment",
+                            dummyPayload( 0 ) == (*iter_copy)->payload() );
+
+    ++iter_copy;
+
+    CPPUNIT_ASSERT_MESSAGE( "iter after second increment",
+                            dummyPayload( 1 ) == (*iter)->payload() );
+    CPPUNIT_ASSERT_MESSAGE( "iter_copy after second increment",
+                            dummyPayload( 1 ) == (*iter_copy)->payload() );
+  }
+
+
+  /// Tests const_iterator::operator==.
+  void test_iterator_equality() {
+    folder->setPrefetchAll( true );
+    IObjectVectorPtr objs = folder->browseObjects( 5, 25, 0 )->fetchAllAsVector();
+    IObjectVector::const_iterator i1 = objs->begin();
+    IObjectVector::const_iterator i2 = objs->begin();
+
+    CPPUNIT_ASSERT_MESSAGE( "before increment", i1 == i2 );
+
+    ++i1;
+
+    CPPUNIT_ASSERT_MESSAGE( "iter after i1 increment", i1 != i2 );
+
+    ++i2;
+
+    CPPUNIT_ASSERT_MESSAGE( "iter after i2 increment", i1 == i2 );
+  }
+
+
+  /// Tests that the iterator correctly points at the end after the container
+  /// has been exhausted.
+  void test_end()  {
+    folder->setPrefetchAll( true );
+    IObjectVectorPtr objs = folder->browseObjects( 5, 25, 0 )->fetchAllAsVector();
+
+    CPPUNIT_ASSERT_EQUAL_MESSAGE
+      ( "object count", 3ul, (unsigned long)objs->size() );
+
+    IObjectVector::const_iterator iter = objs->begin();
+    ++iter;
+    ++iter;
+    ++iter;
+    CPPUNIT_ASSERT_MESSAGE
+      ( "Iterator pointing at end", iter == objs->end() );
+  }
+
+
+  /// Tests that prefix operator++ correctly iterates through the container.
+  void test_iterator_prefix_increment()  {
+    folder->setPrefetchAll( true );
+    IObjectVectorPtr objs = folder->browseObjects( 5, 25, 0 )->fetchAllAsVector();
+
+    CPPUNIT_ASSERT_EQUAL_MESSAGE
+      ( "object count", 3ul, (unsigned long)objs->size() );
+
+    IObjectVector::const_iterator iter = objs->begin();
+
+    CPPUNIT_ASSERT_MESSAGE( "obj 1.1 payload",
+                            dummyPayload( 0 ) == (*iter)->payload() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 1.1 since",
+                                  (ValidityKey)0, (*iter)->since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 1.1 until",
+                                  (ValidityKey)10, (*iter)->until() );
+
+    ++iter;
+    CPPUNIT_ASSERT_MESSAGE( "obj 1.2 payload",
+                            dummyPayload( 1 ) == (*iter)->payload() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 1.2 since",
+                                  (ValidityKey)10, (*iter)->since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 1.2 until",
+                                  (ValidityKey)20, (*iter)->until() );
+
+    ++iter;
+    CPPUNIT_ASSERT_MESSAGE( "obj 1.3 payload",
+                            dummyPayload( 2 ) == (*iter)->payload() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 1.3 since",
+                                  (ValidityKey)20, (*iter)->since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 1.3 until",
+                                  ValidityKeyMax, (*iter)->until() );
+  }
+
+
+  /// Tests that begin returns an iterator pointing to the first item.
+  void test_begin()  {
+    folder->setPrefetchAll( true );
+    IObjectVectorPtr objs = folder->browseObjects( 5, 25, 0 )->fetchAllAsVector();
+
+    CPPUNIT_ASSERT_EQUAL_MESSAGE
+      ( "object count", 3ul, (unsigned long)objs->size() );
+
+    IObjectVector::const_iterator iter = objs->begin();
+
+    CPPUNIT_ASSERT_MESSAGE( "obj 1.1 payload",
+                            dummyPayload( 0 ) == (*iter)->payload() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 1.1 since",
+                                  (ValidityKey)0, (*iter)->since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "obj 1.1 until",
+                                  (ValidityKey)10, (*iter)->until() );
+  }
+
+
+  /// Creates a dummy payload AttributeList for a given index
+  Record dummyPayload( int index ) 
+  {
+    Record payload( payloadSpec );
+    payload["I"].setValue<Int32>( index );
+    std::stringstream s;
+    s << "Object " << index;
+    payload["S"].setValue<String255>( s.str() );
+    payload["X"].setValue<Float>( (float)(index/1000.) );
+    return payload;
+  }
+
+  ObjectSetTest() 
+  : payloadSpec() {
+      
+      payloadSpec.extend("I",StorageType::Int32);
+      payloadSpec.extend("S",StorageType::String255);
+      payloadSpec.extend("X",StorageType::Float);
+      
+      if ( getenv( COOLTESTDB ) ) {
+        connectString = getenv( COOLTESTDB );
+      } else {
+        std::cout << "Please provide a connect string by "
+        << "specifying one in the environment variable COOLTESTDB, e.g." 
+        << std::endl;
+        std::cout << "setenv COOLTESTDB "
+        << "\"oracle://devdb10;schema=lcg_cool;dbname=COOLTEST\"" << std::endl;
+        std::cout << "Aborting test" << std::endl;
+        exit(-1);
+      }
+    }
+  
+  ~ObjectSetTest() {}
+  
+  void setUp() 
+  {
+    try 
+    {
+      CoralApplication app;
+      IDatabaseSvc& dbSvc = app.databaseService();
+      dbSvc.dropDatabase( connectString );
+      db = dbSvc.createDatabase( connectString );
+      std::string folderName( "/folder_1" );
+      folder = db->createFolder( folderName, payloadSpec );
+      for ( int i = 0; i < 3; ++i ) 
+      {
+        ValidityKey since = i*10;
+        ValidityKey until = ValidityKeyMax;
+        Record payload = dummyPayload( i );
+        folder->storeObject( since, until, payload, 0 );
+      }
+    } 
+    catch ( std::exception& e ) 
+    {
+      std::cout << e.what() << std::endl;
+      throw;
+    }
+  }
+
+
+  void tearDown() {
+    // add cleanup code here (e.g. deletion of table data, releasing of
+    // resources)
+    // setup() and tearDown() will be called before and after *each test*
+    db.reset();
+  }
+
+};
+
+CPPUNIT_TEST_SUITE_REGISTRATION( cool::ObjectSetTest );
+
+//-----------------------------------------------------------------------------
+
+// Include CppUnit test driver
+#include <CppUnit_testdriver.icpp>
diff --git a/RelationalCool/tests/RelationalObjectTable/test_RelationalObjectTable.cpp b/RelationalCool/tests/RelationalObjectTable/test_RelationalObjectTable.cpp
new file mode 100644
index 000000000..7d90d8800
--- /dev/null
+++ b/RelationalCool/tests/RelationalObjectTable/test_RelationalObjectTable.cpp
@@ -0,0 +1,3002 @@
+// $Id: test_RelationalObjectTable.cpp,v 1.1 2008-09-26 17:46:47 avalassi Exp $
+
+// Include files
+#include "CoolKernel/IDatabaseSvc.h"
+#include "CoolKernel/ChannelSelection.h"
+#include "CoolKernel/Record.h"
+#include "CoolKernel/RecordSpecification.h"
+#include "CoralBase/AttributeListException.h"
+#include "CoralBase/Exception.h"
+#include "RelationalAccess/ISchema.h"
+#include "RelationalAccess/ITable.h"
+#include "RelationalAccess/ITableDataEditor.h"
+
+// Local include files
+#include "src/HvsTagRecord.h"
+#include "src/IRelationalQueryDefinition.h"
+#include "src/RalDatabase.h"
+#include "src/RelationalChannelTable.h"
+#include "src/RelationalObjectMgr.h"
+#include "src/RelationalObjectTable.h"
+#include "src/RelationalObjectTableRow.h"
+#include "src/RelationalFolder.h"
+#include "src/RelationalSequence.h"
+#include "src/RelationalSequenceMgr.h"
+#include "src/RelationalTagMgr.h"
+#include "src/RelationalTransaction.h"
+#include "src/timeToString.h"
+
+// Test Base Class
+#include "CoolDBUnitTest.h"
+
+//-----------------------------------------------------------------------------
+
+namespace cool 
+{
+  // Forward declaration (needed by gcc4.1 on slc4_ia32_gcc41
+  // to avoid the error "qualified name does not name a class")
+  class RelationalObjectTableTest;
+}
+
+//-----------------------------------------------------------------------------
+
+namespace cool 
+{
+  inline Time addOneNsToTime( ITime& time ) 
+  {
+    return Time( time.year(),
+                 time.month(),
+                 time.day(),
+                 time.hour(),
+                 time.minute(),
+                 time.second(),
+                 time.nanosecond()+1 );
+  }
+}
+
+//---------------------------------------------------------------------------
+
+class cool::RelationalObjectTableTest : public cool::CoolDBUnitTest 
+{		
+  CPPUNIT_TEST_SUITE( RelationalObjectTableTest );
+  
+  CPPUNIT_TEST( test_fetchRowForId_data );
+
+  // AV 19.05.2006 This method is not used anymore
+  //CPPUNIT_TEST( test_fetchRowAtTimeSV );
+  //CPPUNIT_TEST( test_fetchRowAtTimeSV64bit );
+
+  CPPUNIT_TEST( test_fetchRowForId );
+  
+  //CPPUNIT_TEST( test_fetchRowsSV_channel_range );
+  //CPPUNIT_TEST( test_fetchRowsSV_channel_range_ordering );
+  //CPPUNIT_TEST( test_fetchRowsSV_all_channels );
+  
+  //CPPUNIT_TEST( test_fetchLastRowSV );
+  CPPUNIT_TEST( test_fetchLastRowForTagId );
+
+  CPPUNIT_TEST( test_fetchRowAtTimeInHead_5b );
+  CPPUNIT_TEST( test_fetchRowAtTimeInHead_5b_with_userTag );
+  CPPUNIT_TEST( test_findObjectAtTimeInTag_5b );
+  CPPUNIT_TEST( test_fetchRowAtTimeInTag_5c );
+
+  CPPUNIT_TEST( test_fetchRowsForTaggingCurrentHead_5c );
+  CPPUNIT_TEST( test_fetchRowsForTaggingCurrentHead_5c_with_userTag );
+  
+  CPPUNIT_TEST( test_fetchRowsForTaggingHeadAsOfDate_5c );
+  CPPUNIT_TEST( test_fetchRowsForTaggingHeadAsOfDate_5c_with_userTag );
+
+  CPPUNIT_TEST( test_fetchRowsForTaggingHeadAsOfObjectId_5c );
+  CPPUNIT_TEST( test_fetchRowsForTaggingHeadAsOfObjectId_duplIOV );
+
+  CPPUNIT_TEST( test_fetchRowsForTaggingHeadAsOfObjectId_5c_with_userTag );
+
+  CPPUNIT_TEST( test_fetchRowsInHead_5c );
+  CPPUNIT_TEST( test_fetchRowsInHead_identicalRange );
+  CPPUNIT_TEST( test_fetchRowsInHead_channel_range );
+  CPPUNIT_TEST( test_fetchRowsInHead_channel_range_ordering );
+  CPPUNIT_TEST( test_fetchRowsInHead_all_channels );    
+  
+  CPPUNIT_TEST( test_fetchRowsInTag );
+  CPPUNIT_TEST( test_fetchRowsInTag_channel_range );
+  CPPUNIT_TEST( test_fetchRowsInTag_channel_range_ordering );
+  CPPUNIT_TEST( test_fetchRowsInTag_all_channels );
+
+  // This is the test that may crash or hang on RH73
+  // Interesting: this is also the test that used to fail on Windows before 
+  // the COOL_1_2_0 release because of the bug in the Time constructor
+  CPPUNIT_TEST( test_fetchRowsInPastHead_5c );
+  CPPUNIT_TEST( test_fetchRowsInPastHead_identicalRange );
+
+  CPPUNIT_TEST( test_fetchRowsInPastHead_5c_with_userTag );
+
+  CPPUNIT_TEST( test_objectCountSV_all_channels );
+  CPPUNIT_TEST( test_objectCountSV_channel_range );
+  CPPUNIT_TEST( test_objectCountSV_iov_range );
+  
+  CPPUNIT_TEST( test_objectCountInHead_all_channels );
+  CPPUNIT_TEST( test_objectCountInHead_channel_range );
+  CPPUNIT_TEST( test_objectCountInHead_iov_range );
+  CPPUNIT_TEST( test_objectCountInHead_hidden_objects );
+
+  CPPUNIT_TEST( test_objectCountInTag_all_channels );
+  CPPUNIT_TEST( test_objectCountInTag_channel_range );
+  CPPUNIT_TEST( test_objectCountInTag_iov_range );
+
+  //CPPUNIT_TEST( test_rowCount );
+
+  CPPUNIT_TEST_SUITE_END();
+		
+public:
+    
+  RalDatabase* ralDb; // safely cast pointer to db
+
+  RecordSpecification payloadSpec; 
+
+  //-------------------------------------------------------------------------
+
+  std::vector<RelationalObjectTableRow> fetchRowsInTag
+  ( RelationalObjectTable& objectTable,
+    const ValidityKey& since,
+    const ValidityKey& until,
+    const ChannelSelection& channels,
+    const std::string& tagName )
+  {
+    //std::cout << "Fetch tag '" << tagName << "'"
+    //          << " from table " << objectTable.objectTableName()
+    //          << " for channel=[" << channels.firstChannel()
+    //          << "," << channels.lastChannel() << "]"
+    //          << ", since=" << since
+    //          << ", until=" << until
+    //          << std::endl;
+    const std::auto_ptr<IRelationalQueryDefinition> 
+      def( objectTable.queryDefinitionTag( since, until, channels, tagName ) );
+    try 
+    {
+      std::string desc = "";
+      const std::vector<RelationalTableRow> rows
+        ( objectTable.queryMgr().fetchOrderedRows( *def, desc ) );      
+      std::vector<RelationalObjectTableRow> objectRows;
+      for ( std::vector<RelationalTableRow>::const_iterator 
+              row = rows.begin(); row != rows.end(); ++row ) 
+      {
+        RelationalObjectTableRow objectRow( *row );
+        objectRows.push_back( objectRow );
+      }
+      return objectRows;
+    } 
+    catch( NoRowsFound& ) 
+    {
+      std::stringstream s;
+      throw ObjectNotFound
+        ( s.str(), objectTable.objectTableName(), "test_RelationalObjectTable" );
+    }
+  }  
+
+  //-------------------------------------------------------------------------
+  
+  std::vector<RelationalObjectTableRow> fetchRowsInHead
+  ( RelationalObjectTable& objectTable,
+    const ValidityKey& since,
+    const ValidityKey& until,
+    const ChannelSelection& channels )
+  {
+    //std::cout << "Fetch HEAD from table " << objectTable.objectTableName()
+    //          << " for channel=[" << channels.firstChannel()
+    //          << "," << channels.lastChannel() << "]"
+    //          << ", since=" << since
+    //          << ", until=" << until
+    //          << std::endl;
+    std::string tagName = "HEAD";
+    const std::auto_ptr<IRelationalQueryDefinition> 
+      def( objectTable.queryDefinitionHeadAndUserTag
+           ( since, until, channels, tagName ) );
+    try 
+    {
+      std::string desc = "";
+      const std::vector<RelationalTableRow> rows
+        ( objectTable.queryMgr().fetchOrderedRows( *def, desc ) );
+      std::vector<RelationalObjectTableRow> objectRows;
+      for ( std::vector<RelationalTableRow>::const_iterator 
+              row = rows.begin(); row != rows.end(); ++row ) 
+      {
+        RelationalObjectTableRow objectRow( *row );
+        objectRows.push_back( objectRow );
+      }
+      return objectRows;
+    } 
+    catch( NoRowsFound& ) 
+    {
+      std::stringstream s;
+      throw ObjectNotFound
+        ( s.str(), objectTable.objectTableName(), "RelationalObjectTable" );
+    }
+  }
+
+  //-------------------------------------------------------------------------
+
+  std::vector<RelationalObjectTableRow> fetchRowsInPastHead
+  ( RelationalObjectTable& objectTable,
+    const ValidityKey& since,
+    const ValidityKey& until,
+    const ChannelId& channelId,
+    const ITime& asOfDate )
+  {
+    // Define the list of tables to query
+    // NB Use UPPERCASE table aliases for Frontier (see task #3536)
+    RelationalQueryMgr::TableNamesWithAliases tables;
+    tables.push_back
+      ( RelationalQueryMgr::TableNameWithAlias
+        ( objectTable.objectTableName(), "I" ) );
+    tables.push_back
+      ( RelationalQueryMgr::TableNameWithAlias
+        ( objectTable.objectTableName(), "O" ) );
+    // Add all columns to the output list and define the output format
+    RelationalQueryMgr::SelectListWithRSetSpec columns =
+      RelationalQueryMgr::columnList
+      ( objectTable.tableSpecification(), "I." );
+    // Define the WHERE clause for the selection using bind variables
+    // MIND THE ORDER! For MySQL, match the order in which they are bound!
+    RecordSpecification spec;
+    spec.extend( "userTagId",
+                 RelationalObjectTable::columnTypeIds::userTagId );
+    spec.extend( "since1",
+                 RelationalObjectTable::columnTypeIds::iovSince );
+    spec.extend( "since2",
+                 RelationalObjectTable::columnTypeIds::iovSince );
+    spec.extend( "since3",
+                 RelationalObjectTable::columnTypeIds::iovSince );
+    spec.extend( "until",
+                 RelationalObjectTable::columnTypeIds::iovUntil );
+    spec.extend( "asOfDate1",
+                 RelationalObjectTable::columnTypeIds::sysInsTime );
+    spec.extend( "channel",
+                 RelationalObjectTable::columnTypeIds::channelId );
+    spec.extend( "newHeadId",
+                 RelationalObjectTable::columnTypeIds::newHeadId );
+    spec.extend( "asOfDate2",
+                 RelationalObjectTable::columnTypeIds::sysInsTime );
+    Record whereData( spec );  
+    whereData["userTagId"].setValue( 0u );
+    whereData["since1"].setValue( since );
+    whereData["since2"].setValue( since );
+    whereData["since3"].setValue( since );
+    whereData["until"].setValue( until );
+    whereData["asOfDate1"].setValue( timeToString( asOfDate ) );
+    whereData["channel"].setValue( (unsigned int)channelId );
+    whereData["newHeadId"].setValue( 0u );
+    whereData["asOfDate2"].setValue( timeToString( asOfDate ) );
+    // Also see SimpleObject::overlaps for this clause
+    // but note that the upper end is *included* (<= :until)
+    std::string s  = RelationalObjectTable::columnNames::iovSince();
+    std::string u  = RelationalObjectTable::columnNames::iovUntil();
+    std::string ch  = RelationalObjectTable::columnNames::channelId();
+    std::string ins = RelationalObjectTable::columnNames::sysInsTime();
+    std::string oid = RelationalObjectTable::columnNames::objectId();
+    std::string nhid = RelationalObjectTable::columnNames::newHeadId();
+    std::string 
+      whereClause = "I." + RelationalObjectTable::columnNames::userTagId();
+    whereClause += "= :userTagId";
+    whereClause += " AND ";
+    whereClause += "(";
+    whereClause += " ( ( I." + s + " <= :since1 )";
+    whereClause += "   AND ( :since2 < I." + u + " ) )";
+    whereClause += " OR ";
+    whereClause += " ( ( :since3 <= I." + s + " )";
+    whereClause += "   AND ( I." + s + " <= :until ) )";
+    whereClause += ")";
+    whereClause += " AND I." + ins + " <= :asOfDate1";
+    whereClause += " AND I." + ch + " = :channel";
+    whereClause += " AND ( ";
+    whereClause += "( I." + nhid + " = :newHeadId";
+    whereClause += " AND I." + oid + " = O." + oid; // constrains self join
+    whereClause += " ) ";
+    whereClause += " OR ";
+    whereClause += "( I." + nhid + " = O." + oid;
+    whereClause += " AND O." + ins + " > :asOfDate2";
+    whereClause += " ) ";
+    whereClause += ")";
+    /// Results are ordered by ascending values of the "since" start of IOV
+    std::vector<std::string> orderBy;
+    orderBy.push_back
+      ( std::string("I.") + 
+        RelationalObjectTable::columnNames::iovSince() + " ASC" );
+    // Delegate the query to the RalQueryMgr
+    std::string desc = "";
+    std::vector<RelationalTableRow> rows =
+      objectTable.queryMgr().fetchOrderedRowsFromTables
+      ( tables, columns, 
+        whereClause, whereData.attributeList(), orderBy, desc );
+    // TEMPORARY? Conversion to RelationalObjectTableRow
+    std::vector<RelationalObjectTableRow> objectRows;
+    for ( std::vector<RelationalTableRow>::const_iterator
+            row = rows.begin(); row != rows.end(); ++row ) 
+    {
+      RelationalObjectTableRow objectRow( *row );
+      objectRows.push_back( objectRow );
+    }
+    // Return the results
+    return objectRows;
+  }
+
+  //-------------------------------------------------------------------------
+
+  /*
+  /// Tests rowCount
+  void test_rowCount() {
+    IFolderPtr folder = ralDb->createFolder( "/myfolder", 
+                                             payloadSpec,
+                                             "my description",
+                                             FolderVersioning::MULTI_VERSION );
+    
+    folder->setupStorageBuffer();
+    // this creates three rows per channel: the two inserted ones plus a
+    // system object
+    for ( ChannelId ch = 0; ch < 5; ++ch ) {
+      folder->storeObject( 0, ValidityKeyMax, dummyPayload( 0 ), ch );
+      folder->storeObject( 1, ValidityKeyMax, dummyPayload( 1 ), ch );
+    }
+    folder->flushStorageBuffer();
+    
+    for ( ChannelId ch = 0; ch < 5; ++ch ) {
+      folder->storeObject( 0, ValidityKeyMax, dummyPayload( 0 ), ch );
+    }
+    folder->flushStorageBuffer();
+    
+    RelationalFolder* relfolder = 
+      dynamic_cast<RelationalFolder*>(folder.get());
+    
+    RelationalTransaction transaction( ralDb->transactionMgr() );
+    RelationalObjectTable 
+      objectTable( &(ralDb->queryMgr()), false, *relfolder );
+    
+    int count = objectTable.rowCount();
+    
+    CPPUNIT_ASSERT_EQUAL( 20, count );
+  }
+  */
+  
+  /// Tests countObjectInTag for all channels
+  void test_objectCountInTag_all_channels() {
+    IFolderPtr folder = ralDb->createFolder( "/myfolder", 
+                                             payloadSpec,
+                                             "my description",
+                                             FolderVersioning::MULTI_VERSION );
+    
+    folder->setupStorageBuffer();
+    for ( ChannelId ch = 0; ch < 5; ++ch ) {
+      folder->storeObject( 0, ValidityKeyMax, dummyPayload( 0 ), ch );
+      folder->storeObject( 1, ValidityKeyMax, dummyPayload( 1 ), ch );
+    }
+    folder->flushStorageBuffer();
+    
+    folder->tagCurrentHead( "A" );
+    
+    for ( ChannelId ch = 0; ch < 5; ++ch ) {
+      folder->storeObject( 0, ValidityKeyMax, dummyPayload( 0 ), ch );
+    }
+    folder->flushStorageBuffer();
+    
+    folder->tagCurrentHead( "B" );
+    
+    RelationalFolder* relfolder = 
+      dynamic_cast<RelationalFolder*>(folder.get());
+    
+    RelationalTransaction transaction( ralDb->transactionMgr() );
+    RelationalObjectTable 
+      objectTable( &(ralDb->queryMgr()), false, *relfolder );
+
+    std::auto_ptr<IRelationalQueryDefinition> pQueryDef = 
+      objectTable.queryDefinitionTag( ValidityKeyMin, 
+                                      ValidityKeyMax,
+                                      ChannelSelection::all(), 
+                                      "A" );
+    int count = objectTable.queryMgr().countRows( *pQueryDef );
+
+    CPPUNIT_ASSERT_EQUAL( 10, count );
+  }
+  
+  
+  /// Tests countObjectInTag for a channel range
+  void test_objectCountInTag_channel_range() {
+    IFolderPtr folder = ralDb->createFolder( "/myfolder", 
+                                             payloadSpec,
+                                             "my description",
+                                             FolderVersioning::MULTI_VERSION );
+    
+    folder->setupStorageBuffer();
+    for ( ChannelId ch = 0; ch < 5; ++ch ) {
+      folder->storeObject( 0, ValidityKeyMax, dummyPayload( 0 ), ch );
+      folder->storeObject( 1, ValidityKeyMax, dummyPayload( 1 ), ch );
+    }
+    folder->flushStorageBuffer();
+    
+    folder->tagCurrentHead( "A" );
+    
+    for ( ChannelId ch = 0; ch < 5; ++ch ) {
+      folder->storeObject( 0, ValidityKeyMax, dummyPayload( 0 ), ch );
+    }
+    folder->flushStorageBuffer();
+    
+    folder->tagCurrentHead( "B" );
+    
+    ChannelSelection channels( 2, 3 );
+
+    RelationalFolder* relfolder = 
+      dynamic_cast<RelationalFolder*>(folder.get());
+    
+    RelationalTransaction transaction( ralDb->transactionMgr() );
+    RelationalObjectTable 
+      objectTable( &(ralDb->queryMgr()), false, *relfolder );
+    
+    std::auto_ptr<IRelationalQueryDefinition> pQueryDef = 
+      objectTable.queryDefinitionTag( ValidityKeyMin, 
+                                      ValidityKeyMax,
+                                      channels, 
+                                      "A" );
+    int count = objectTable.queryMgr().countRows( *pQueryDef );
+
+    CPPUNIT_ASSERT_EQUAL( 4, count );
+  }
+  
+  
+  /// Tests countObjectInTag for an IOV range
+  void test_objectCountInTag_iov_range() {
+    IFolderPtr folder = ralDb->createFolder( "/myfolder", 
+                                             payloadSpec,
+                                             "my description",
+                                             FolderVersioning::MULTI_VERSION );
+    
+    folder->setupStorageBuffer();
+    for ( int i = 0; i < 10; ++i ) {
+      folder->storeObject( i, ValidityKeyMax, dummyPayload( i ), 0 );
+    }
+    folder->flushStorageBuffer();
+    
+    folder->tagCurrentHead( "A" );
+    
+    for ( int i = 0; i < 5; ++i ) {
+      folder->storeObject( i, ValidityKeyMax, dummyPayload( i ), 0 );
+    }
+    folder->flushStorageBuffer();
+    
+    folder->tagCurrentHead( "B" );
+    
+    RelationalFolder* relfolder =
+      dynamic_cast<RelationalFolder*>(folder.get());
+    
+    RelationalTransaction transaction( ralDb->transactionMgr() );
+    RelationalObjectTable 
+      objectTable( &(ralDb->queryMgr()), false, *relfolder );
+    
+    std::auto_ptr<IRelationalQueryDefinition> pQueryDef = 
+      objectTable.queryDefinitionTag( (ValidityKey)3, 
+                                      (ValidityKey)5,
+                                      ChannelSelection::all(), 
+                                      "A" );
+    int count = objectTable.queryMgr().countRows( *pQueryDef );
+    CPPUNIT_ASSERT_EQUAL( 3, count );
+  }
+  
+  
+  /// Tests countObjectInHead for all channels
+  void test_objectCountInHead_all_channels() {
+    IFolderPtr folder = ralDb->createFolder( "/myfolder", 
+                                             payloadSpec,
+                                             "my description",
+                                             FolderVersioning::MULTI_VERSION );
+    
+    folder->setupStorageBuffer();
+    for ( ChannelId ch = 0; ch < 5; ++ch ) {
+      folder->storeObject( 0, ValidityKeyMax, dummyPayload( 0 ), ch );
+      folder->storeObject( 1, ValidityKeyMax, dummyPayload( 1 ), ch );
+    }
+    folder->flushStorageBuffer();
+    
+    RelationalFolder* relfolder = 
+      dynamic_cast<RelationalFolder*>(folder.get());
+    
+    RelationalTransaction transaction( ralDb->transactionMgr() );
+    RelationalObjectTable 
+      objectTable( &(ralDb->queryMgr()), false, *relfolder );
+    
+    std::auto_ptr<IRelationalQueryDefinition> pQueryDef = 
+      objectTable.queryDefinitionHeadAndUserTag( ValidityKeyMin, 
+                                                 ValidityKeyMax,
+                                                 ChannelSelection::all(), 
+                                                 "HEAD" );
+    int count = objectTable.queryMgr().countRows( *pQueryDef );
+    CPPUNIT_ASSERT_EQUAL( 10, count );
+  }
+  
+  
+  /// Tests countObjectInHead for a channel range
+  void test_objectCountInHead_channel_range() {
+    IFolderPtr folder = ralDb->createFolder( "/myfolder", 
+                                             payloadSpec,
+                                             "my description",
+                                             FolderVersioning::MULTI_VERSION );
+    
+    folder->setupStorageBuffer();
+    for ( ChannelId ch = 0; ch < 5; ++ch ) {
+      folder->storeObject( 0, ValidityKeyMax, dummyPayload( 0 ), ch );
+      folder->storeObject( 1, ValidityKeyMax, dummyPayload( 1 ), ch );
+    }
+    folder->flushStorageBuffer();
+    
+    ChannelSelection channels( 2, 3 );
+    
+    RelationalFolder* relfolder =
+      dynamic_cast<RelationalFolder*>(folder.get());
+    
+    RelationalTransaction transaction( ralDb->transactionMgr() );
+    RelationalObjectTable 
+      objectTable( &(ralDb->queryMgr()), false, *relfolder );
+    
+    std::auto_ptr<IRelationalQueryDefinition> pQueryDef = 
+      objectTable.queryDefinitionHeadAndUserTag( ValidityKeyMin, 
+                                                 ValidityKeyMax,
+                                                 channels, 
+                                                 "HEAD" );
+    int count = objectTable.queryMgr().countRows( *pQueryDef );
+    CPPUNIT_ASSERT_EQUAL( 4, count );
+  }
+  
+  
+  /// Tests countObjectInHead for an IOV range
+  void test_objectCountInHead_iov_range() {
+    IFolderPtr folder = ralDb->createFolder( "/myfolder", 
+                                             payloadSpec,
+                                             "my description",
+                                             FolderVersioning::MULTI_VERSION );
+    
+    folder->setupStorageBuffer();
+    for ( int i = 0; i < 10; ++i ) {
+      folder->storeObject( i, ValidityKeyMax, dummyPayload( i ), 0 );
+    }
+    folder->flushStorageBuffer();
+    
+    RelationalFolder* relfolder = 
+      dynamic_cast<RelationalFolder*>(folder.get());
+    
+    RelationalTransaction transaction( ralDb->transactionMgr() );
+    RelationalObjectTable 
+      objectTable( &(ralDb->queryMgr()), false, *relfolder );
+    
+    std::auto_ptr<IRelationalQueryDefinition> pQueryDef = 
+      objectTable.queryDefinitionHeadAndUserTag( (ValidityKey)3, 
+                                                 (ValidityKey)5,
+                                                 ChannelSelection::all(), 
+                                                 "HEAD" );
+    int count = objectTable.queryMgr().countRows( *pQueryDef );
+    CPPUNIT_ASSERT_EQUAL( 3, count );
+  }
+  
+  
+  /// Tests countObjectInHead with some objects being fully overlapped by
+  /// later insertions.
+  void test_objectCountInHead_hidden_objects() {
+    IFolderPtr folder = ralDb->createFolder( "/myfolder", 
+                                             payloadSpec,
+                                             "my description",
+                                             FolderVersioning::MULTI_VERSION );
+    
+    folder->setupStorageBuffer();
+    for ( int i = 0; i < 6; ++i ) {
+      folder->storeObject( i, i+1, dummyPayload( i ), 0 );
+    }
+    folder->flushStorageBuffer();
+    
+    folder->storeObject( 0, 3, dummyPayload( 0 ), 0 );
+    folder->flushStorageBuffer();
+
+    RelationalFolder* relfolder =
+      dynamic_cast<RelationalFolder*>(folder.get());
+    
+    RelationalTransaction transaction( ralDb->transactionMgr() );
+    RelationalObjectTable 
+      objectTable( &(ralDb->queryMgr()), false, *relfolder );
+    
+    std::auto_ptr<IRelationalQueryDefinition> pQueryDef = 
+      objectTable.queryDefinitionHeadAndUserTag( ValidityKeyMin, 
+                                                 ValidityKeyMax,
+                                                 ChannelSelection::all(), 
+                                                 "HEAD" );
+    int count = objectTable.queryMgr().countRows( *pQueryDef );
+    CPPUNIT_ASSERT_EQUAL( 4, count );
+  }
+  
+  
+  /// Tests countObjectSV for all channels
+  void test_objectCountSV_all_channels() {
+    try{
+      IFolderPtr folder = ralDb->createFolder( "/myfolder", payloadSpec );
+      folder->setupStorageBuffer();
+      for ( ChannelId ch = 0; ch < 5; ++ch ) {
+        folder->storeObject( 0, ValidityKeyMax, dummyPayload( 0 ), ch );
+        folder->storeObject( 1, ValidityKeyMax, dummyPayload( 1 ), ch );
+      }
+      folder->flushStorageBuffer();
+      RelationalFolder* relfolder = 
+        dynamic_cast<RelationalFolder*>(folder.get());
+      RelationalTransaction transaction( ralDb->transactionMgr() );
+      RelationalObjectTable 
+        objectTable( &(ralDb->queryMgr()), false, *relfolder );
+
+    std::auto_ptr<IRelationalQueryDefinition> pQueryDef =
+      objectTable.queryDefinitionSV( ValidityKeyMin,
+                                     ValidityKeyMax,
+                                     ChannelSelection::all() );
+    int count = objectTable.queryMgr().countRows( *pQueryDef );
+
+      CPPUNIT_ASSERT_EQUAL( 10, count );
+    }    
+    catch( std::exception& e ) {
+      std::cout << "Exception caught: " << e.what() << std::endl;
+      throw;
+    }  
+  }
+  
+  
+  /// Tests countObjectSV for a channel range
+  void test_objectCountSV_channel_range() {
+    IFolderPtr folder = ralDb->createFolder( "/myfolder", payloadSpec );
+    
+    folder->setupStorageBuffer();
+    for ( ChannelId ch = 0; ch < 5; ++ch ) {
+      folder->storeObject( 0, ValidityKeyMax, dummyPayload( 0 ), ch );
+      folder->storeObject( 1, ValidityKeyMax, dummyPayload( 1 ), ch );
+    }
+    folder->flushStorageBuffer();
+    
+    ChannelSelection channels( 2, 3 );
+
+    RelationalFolder* relfolder = 
+      dynamic_cast<RelationalFolder*>(folder.get());
+    
+    RelationalTransaction transaction( ralDb->transactionMgr() );
+    RelationalObjectTable 
+      objectTable( &(ralDb->queryMgr()), false, *relfolder );
+
+    std::auto_ptr<IRelationalQueryDefinition> pQueryDef =
+      objectTable.queryDefinitionSV( ValidityKeyMin,
+                                     ValidityKeyMax,
+                                     channels );
+    int count = objectTable.queryMgr().countRows( *pQueryDef );
+
+    CPPUNIT_ASSERT_EQUAL( 4, count );
+  }
+  
+  
+  /// Tests countObjectSV for an IOV range
+  void test_objectCountSV_iov_range() {
+    IFolderPtr folder = ralDb->createFolder( "/myfolder", payloadSpec );
+    
+    folder->setupStorageBuffer();
+    for ( int i = 0; i < 10; ++i ) {
+      folder->storeObject( i, ValidityKeyMax, dummyPayload( i ), 0 );
+    }
+    folder->flushStorageBuffer();
+    
+    RelationalFolder* relfolder = 
+      dynamic_cast<RelationalFolder*>(folder.get());
+    
+    RelationalTransaction transaction( ralDb->transactionMgr() );
+    RelationalObjectTable 
+      objectTable( &(ralDb->queryMgr()), false, *relfolder );
+    
+    std::auto_ptr<IRelationalQueryDefinition> pQueryDef =
+      objectTable.queryDefinitionSV( (ValidityKey)3,
+                                     (ValidityKey)5,
+                                     ChannelSelection::all() );
+    int count = objectTable.queryMgr().countRows( *pQueryDef );
+
+    CPPUNIT_ASSERT_EQUAL( 3, count );
+  }
+  
+  
+  /// Tests fetchRowAtTimeInHead
+  void test_fetchRowAtTimeInHead_5b_with_userTag() {
+    try{
+      IFolderPtr folder = ralDb->createFolder( "/myfolder", 
+                                               payloadSpec,
+                                               "my description",
+                                               FolderVersioning::MULTI_VERSION );
+      folder->storeObject( 1, 3, dummyPayload( 1 ), 0 );
+      folder->storeObject( 6, 8, dummyPayload( 2 ), (ChannelId)0, "A" );
+      folder->storeObject( 2, 4, dummyPayload( 3 ), (ChannelId)0, "B" );
+      folder->storeObject( 5, 7, dummyPayload( 4 ), (ChannelId)0, "A" );
+      
+      RelationalFolder* relfolder = 
+        dynamic_cast<RelationalFolder*>(folder.get());
+      
+      RelationalTransaction transaction( ralDb->transactionMgr() );
+      RelationalObjectTable 
+        objectTable( &(ralDb->queryMgr()), false, *relfolder );
+      
+      RelationalObjectTableRow row = 
+        objectTable.fetchRowAtTimeInHead( (ValidityKey)1, 
+                                          (ChannelId)0 );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "object_id time 1", 14u, row.objectId() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "since time 1", (ValidityKey)1, row.since() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "until time 1", (ValidityKey)2, row.until() );
+      
+      row = objectTable.fetchRowAtTimeInHead( (ValidityKey)3, 
+                                              (ChannelId)0 );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "object_id time 2", 13u, row.objectId() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "since time 2", (ValidityKey)2, row.since() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "until time 2", (ValidityKey)4, row.until() );
+      
+      try {
+        row = objectTable.fetchRowAtTimeInHead( (ValidityKey)4, 
+                                                (ChannelId)0 );
+        CPPUNIT_FAIL( "expected RelationalObjectNotFound exception" );
+      } catch ( ObjectNotFound& /* ignored */ ) { }
+      
+      row = objectTable.fetchRowAtTimeInHead( (ValidityKey)5, 
+                                              (ChannelId)0 );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "object_id time 4", 19u, row.objectId() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "since time 4", (ValidityKey)5, row.since() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "until time 4", (ValidityKey)7, row.until() );
+      
+      row = objectTable.fetchRowAtTimeInHead( (ValidityKey)7, 
+                                              (ChannelId)0 );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "object_id time 5", 21u, row.objectId() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "since time 5", (ValidityKey)7, row.since() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "until time 5", (ValidityKey)8, row.until() );
+      
+      transaction.commit();
+    }
+    catch( std::exception& e ) {
+      std::cout << "Exception caught: " << e.what() << std::endl;
+      throw;
+    }
+  }
+  
+  
+  /// Tests fetchRowAtTimeInHead
+  void test_fetchRowAtTimeInHead_5b() {
+    try{
+      IFolderPtr folder = ralDb->createFolder( "/myfolder", 
+                                               payloadSpec,
+                                               "my description",
+                                               FolderVersioning::MULTI_VERSION );
+      folder->setupStorageBuffer();
+      folder->storeObject( 1, 3, dummyPayload( 1 ), 0 );
+      folder->storeObject( 6, 8, dummyPayload( 2 ), 0 );
+      folder->storeObject( 2, 4, dummyPayload( 3 ), 0 );
+      folder->storeObject( 5, 7, dummyPayload( 4 ), 0 );
+      folder->flushStorageBuffer();
+
+      RelationalFolder* relfolder =
+        dynamic_cast<RelationalFolder*>(folder.get());
+      
+      RelationalTransaction transaction( ralDb->transactionMgr() );
+      RelationalObjectTable 
+        objectTable( &(ralDb->queryMgr()), false, *relfolder );
+      
+      RelationalObjectTableRow row = 
+        objectTable.fetchRowAtTimeInHead( (ValidityKey)1, 
+                                          (ChannelId)0 );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "object_id time 1", 14u, row.objectId() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "since time 1", (ValidityKey)1, row.since() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "until time 1", (ValidityKey)2, row.until() );
+      
+      row = objectTable.fetchRowAtTimeInHead( (ValidityKey)3, 
+                                              (ChannelId)0 );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "object_id time 2", 13u, row.objectId() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "since time 2", (ValidityKey)2, row.since() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "until time 2", (ValidityKey)4, row.until() );
+      
+      try {
+        row = objectTable.fetchRowAtTimeInHead( (ValidityKey)4, 
+                                                (ChannelId)0 );
+        CPPUNIT_FAIL( "expected RelationalObjectNotFound exception" );
+      } catch ( ObjectNotFound& /* ignored */ ) { }
+      
+      row = objectTable.fetchRowAtTimeInHead( (ValidityKey)5, 
+                                              (ChannelId)0 );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "object_id time 4", 19u, row.objectId() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "since time 4", (ValidityKey)5, row.since() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "until time 4", (ValidityKey)7, row.until() );
+      
+      row = objectTable.fetchRowAtTimeInHead( (ValidityKey)7, 
+                                              (ChannelId)0 );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "object_id time 5", 21u, row.objectId() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "since time 5", (ValidityKey)7, row.since() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "until time 5", (ValidityKey)8, row.until() );
+      
+      transaction.commit();
+    }
+    catch( std::exception& e ) {
+      std::cout << "Exception caught: " << e.what() << std::endl;
+      throw;
+    }
+  }
+  
+  
+  /// Tests tags in a way similar to fetchRowAtTimeInHead_5b (bug #33256)
+  void test_findObjectAtTimeInTag_5b() {
+    try {
+      IFolderPtr folder = ralDb->createFolder( "/myfolder", 
+                                               payloadSpec,
+                                               "my description",
+                                               FolderVersioning::MULTI_VERSION );
+      folder->setupStorageBuffer();
+      folder->storeObject( 1, 3, dummyPayload( 1 ), 0 );
+      folder->storeObject( 6, 8, dummyPayload( 2 ), 0 );
+      folder->storeObject( 2, 4, dummyPayload( 3 ), 0 );
+      folder->storeObject( 5, 7, dummyPayload( 4 ), 0 );
+      folder->flushStorageBuffer();
+
+      std::string mytag = "mytag";
+      folder->tagCurrentHead( mytag );
+
+      IObjectPtr obj = 
+        folder->findObject( (ValidityKey)1, (ChannelId)0, mytag );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "object_id time 1", 14u, obj->objectId() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "since time 1", (ValidityKey)1, obj->since() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "until time 1", (ValidityKey)2, obj->until() );
+      
+      obj = folder->findObject( (ValidityKey)3, (ChannelId)0, mytag );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "object_id time 2", 13u, obj->objectId() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "since time 2", (ValidityKey)2, obj->since() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "until time 2", (ValidityKey)4, obj->until() );
+      
+      try {
+        obj = folder->findObject( (ValidityKey)4, (ChannelId)0, mytag );
+        CPPUNIT_FAIL( "expected ObjectNotFound exception" );
+      } catch ( ObjectNotFound& /* ignored */ ) { }
+      
+      obj = folder->findObject( (ValidityKey)5, (ChannelId)0, mytag );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "object_id time 4", 19u, obj->objectId() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "since time 4", (ValidityKey)5, obj->since() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "until time 4", (ValidityKey)7, obj->until() );
+      
+      obj = folder->findObject( (ValidityKey)7, (ChannelId)0, mytag );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "object_id time 5", 21u, obj->objectId() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "since time 5", (ValidityKey)7, obj->since() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "until time 5", (ValidityKey)8, obj->until() );
+
+    }
+    catch( std::exception& e ) {
+      std::cout << "Exception caught: " << e.what() << std::endl;
+      throw;
+    }
+  }
+  
+  
+  /// Tests fetchRowsInPastHead for case 5c and selection 
+  /// between T2 and T3 in the context of user tags
+  void test_fetchRowsInPastHead_5c_with_userTag() {
+    IFolderPtr folder = ralDb->createFolder( "/myfolder", 
+                                             payloadSpec,
+                                             "my description",
+                                             FolderVersioning::MULTI_VERSION );
+    
+    folder->storeObject( 1, 3, dummyPayload( 1 ), (ChannelId)0, "A" );
+    folder->storeObject( 6, 8, dummyPayload( 2 ), (ChannelId)0, "B" );
+    
+    RelationalFolder* relfolder = 
+      dynamic_cast<RelationalFolder*>(folder.get());
+    
+    RelationalTransaction t1( ralDb->transactionMgr() );
+    boost::shared_ptr<RelationalSequence> seq
+      ( ralDb->queryMgr().sequenceMgr().getSequence
+        ( RelationalObjectTable::sequenceName
+          ( relfolder->objectTableName() ) ) );
+    Time asOfDate = stringToTime( seq->currDate() );
+    asOfDate = addOneNsToTime( asOfDate );
+    t1.commit();
+    
+    // MySQL now() has 1 second granularity: need to sleep at least 1 second
+    sleep(1); 
+    
+    folder->storeObject( 2, 4, dummyPayload( 3 ), (ChannelId)0, "A" );
+    folder->storeObject( 3, 5, dummyPayload( 4 ), (ChannelId)0, "B" );
+    
+    RelationalTransaction transaction( ralDb->transactionMgr() );
+    
+    ralDb->log()
+      << "rh7 issue: I may soon crash (seg fault) or hang (mutex lock)" 
+      << coral::MessageStream::endmsg;
+    
+    RelationalObjectTable 
+      objectTable( &(ralDb->queryMgr()), false, *relfolder );
+    std::vector<RelationalObjectTableRow> rows = 
+      fetchRowsInPastHead( objectTable, 
+                           ValidityKeyMin,
+                           ValidityKeyMax,
+                           (ChannelId)0,
+                           asOfDate );
+    
+    ralDb->log() << "rh7 issue: I did not crash or hang" << coral::MessageStream::endmsg;
+    
+    //copy( rows.begin(), rows.end(), 
+    //      std::ostream_iterator<RelationalObjectTableRow>( std::cout, "\n" ) );
+    
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "row count", 2u, (unsigned int)rows.size() );
+    
+    RelationalObjectTableRow& row = rows[0];
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 object id", 1u, row.objectId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 channel id", 0u, row.channelId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 since", (ValidityKey)1, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 until", (ValidityKey)3, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 payload", std::string("Object 1"),
+                                  row["S"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 original id", 0u, row.originalId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 new head id", 13u, row.newHeadId() );
+    
+    row = rows[1];
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 object id", 7u, row.objectId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 channel id", 0u, row.channelId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 since", (ValidityKey)6, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 until", (ValidityKey)8, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 payload", std::string("Object 2"),
+                                  row["S"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 original id", 0u, row.originalId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 new head id", 0u, row.newHeadId() );
+  }
+  
+  
+  
+  /// Tests fetchRowsInPastHead for case 5c and selection 
+  /// between T2 and T3
+  void test_fetchRowsInPastHead_5c() {
+    IFolderPtr folder = ralDb->createFolder( "/myfolder", 
+                                             payloadSpec,
+                                             "my description",
+                                             FolderVersioning::MULTI_VERSION );
+    
+    folder->setupStorageBuffer();
+    folder->storeObject( 1, 3, dummyPayload( 1 ), 0 );
+    folder->storeObject( 6, 8, dummyPayload( 2 ), 0 );
+    folder->flushStorageBuffer();
+    
+    RelationalFolder* relfolder = 
+      dynamic_cast<RelationalFolder*>(folder.get());
+
+    RelationalTransaction t1( ralDb->transactionMgr() );
+    boost::shared_ptr<RelationalSequence> seq
+      ( ralDb->queryMgr().sequenceMgr().getSequence
+        ( RelationalObjectTable::sequenceName
+          ( relfolder->objectTableName() ) ) );
+    Time asOfDate = stringToTime( seq->currDate() );
+    asOfDate = addOneNsToTime( asOfDate );
+    t1.commit();
+    
+    // MySQL now() has 1 second granularity: need to sleep at least 1 second
+    sleep(1); 
+    
+    folder->storeObject( 2, 4, dummyPayload( 3 ), 0 );
+    folder->storeObject( 3, 5, dummyPayload( 4 ), 0 );
+    folder->flushStorageBuffer();
+    
+    RelationalTransaction transaction( ralDb->transactionMgr() );
+    
+    ralDb->log()
+      << "rh7 issue: I may soon crash (seg fault) or hang (mutex lock)" 
+      << coral::MessageStream::endmsg;
+    
+    RelationalObjectTable 
+      objectTable( &(ralDb->queryMgr()), false, *relfolder );
+    std::vector<RelationalObjectTableRow> rows = 
+      fetchRowsInPastHead( objectTable, 
+                           ValidityKeyMin,
+                           ValidityKeyMax,
+                           (ChannelId)0,
+                           asOfDate );
+    
+    ralDb->log() << "rh7 issue: I did not crash or hang" << coral::MessageStream::endmsg;
+    
+    //copy( rows.begin(), rows.end(), 
+    //      std::ostream_iterator<RelationalObjectTableRow>( std::cout, "\n" ) );
+    
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "row count", 2u, (unsigned int)rows.size() );
+    
+    RelationalObjectTableRow& row = rows[0];
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 object id", 1u, row.objectId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 channel id", 0u, row.channelId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 since", (ValidityKey)1, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 until", (ValidityKey)3, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 payload", std::string("Object 1"),
+                                  row["S"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 original id", 0u, row.originalId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 new head id", 13u, row.newHeadId() );
+    
+    row = rows[1];
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 object id", 7u, row.objectId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 channel id", 0u, row.channelId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 since", (ValidityKey)6, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 until", (ValidityKey)8, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 payload", std::string("Object 2"),
+                                  row["S"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 original id", 0u, row.originalId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 new head id", 0u, row.newHeadId() );
+  }
+  
+  
+  
+  /// Tests fetchRowsInTag
+  void test_fetchRowsInTag() {
+    IFolderPtr folder = ralDb->createFolder( "/myfolder", 
+                                             payloadSpec,
+                                             "my description",
+                                             FolderVersioning::MULTI_VERSION );
+
+    folder->storeObject( 0, ValidityKeyMax, dummyPayload( 1 ), 0 );
+    folder->tagCurrentHead( "mytagA", "a tag A" );
+    
+    RelationalFolder* relfolder = 
+      dynamic_cast<RelationalFolder*>(folder.get());
+    
+    RelationalTransaction transaction( ralDb->transactionMgr() );
+    RelationalObjectTable 
+      objectTable( &(ralDb->queryMgr()), false, *relfolder );
+    std::vector<RelationalObjectTableRow> rows = 
+      fetchRowsInTag( objectTable,
+                      ValidityKeyMin,
+                      ValidityKeyMax,
+                      ChannelSelection( 0, 0 ),
+                      "mytagA" );
+    
+    //copy( rows.begin(), rows.end(), 
+    //      std::ostream_iterator<RelationalObjectTableRow>( std::cout, "\n" ) );
+    
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "row count", 1u, 
+                                  (unsigned int)rows.size() );
+    
+    RelationalObjectTableRow& row = rows[0];
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 object id", 1u, row.objectId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 since", (ValidityKey)0, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 until", ValidityKeyMax, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 payload", std::string("Object 1"),
+                                  row["S"].data<std::string>() );
+  }
+  
+  
+  
+  /// Tests fetchRowsInPastHead
+  void test_fetchRowsInPastHead_identicalRange() {
+    IFolderPtr folder = ralDb->createFolder( "/myfolder", 
+                                             payloadSpec,
+                                             "my description",
+                                             FolderVersioning::MULTI_VERSION );
+
+    folder->storeObject( 0, ValidityKeyMax, dummyPayload( 1 ), 0 );
+    
+    RelationalFolder* relfolder = 
+      dynamic_cast<RelationalFolder*>(folder.get());    
+
+    RelationalTransaction transaction( ralDb->transactionMgr() );
+    
+    boost::shared_ptr<RelationalSequence> seq
+      ( ralDb->queryMgr().sequenceMgr().getSequence
+        ( RelationalObjectTable::sequenceName
+          ( relfolder->objectTableName() ) ) );
+    Time asOfDate = stringToTime( seq->currDate() );
+    asOfDate = addOneNsToTime( asOfDate );
+    
+    RelationalObjectTable 
+      objectTable( &(ralDb->queryMgr()), false, *relfolder );
+    std::vector<RelationalObjectTableRow> rows = 
+      fetchRowsInPastHead( objectTable, 
+                           ValidityKeyMin,
+                           ValidityKeyMax,
+                           (ChannelId)0,
+                           asOfDate );
+    
+    //copy( rows.begin(), rows.end(), 
+    //      std::ostream_iterator<RelationalObjectTableRow>( std::cout, "\n" ) );
+    
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "row count", 1u, 
+                                  (unsigned int)rows.size() );
+    
+    RelationalObjectTableRow& row = rows[0];
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 object id", 1u, row.objectId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 since", (ValidityKey)0, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 until", ValidityKeyMax, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 payload", std::string("Object 1"),
+                                  row["S"].data<std::string>() );
+  }
+  
+  
+  
+  /// Tests fetchRowsInHead
+  void test_fetchRowsInHead_5c() {
+    IFolderPtr folder = ralDb->createFolder( "/myfolder", 
+                                             payloadSpec,
+                                             "my description",
+                                             FolderVersioning::MULTI_VERSION );
+    
+    folder->setupStorageBuffer();
+    folder->storeObject( 1, 3, dummyPayload( 1 ), 0 );
+    folder->storeObject( 6, 8, dummyPayload( 2 ), 0 );
+    folder->flushStorageBuffer();
+    
+    folder->storeObject( 2, 4, dummyPayload( 3 ), 0 );
+    folder->storeObject( 3, 5, dummyPayload( 4 ), 0 );
+    folder->flushStorageBuffer();
+    
+    RelationalFolder* relfolder = 
+      dynamic_cast<RelationalFolder*>(folder.get());
+
+    RelationalTransaction transaction( ralDb->transactionMgr() );
+    RelationalObjectTable 
+      objectTable( &(ralDb->queryMgr()), false, *relfolder );
+    std::vector<RelationalObjectTableRow> rows =
+      fetchRowsInHead( objectTable, 
+                       ValidityKeyMin,
+                       ValidityKeyMax,
+                       ChannelSelection( 0, 0 ) );
+    
+    //copy( rows.begin(), rows.end(), 
+    //      std::ostream_iterator<RelationalObjectTableRow>( std::cout, "\n" ) );
+    
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "row count", 4u, 
+                                  (unsigned int)rows.size() );
+    
+    RelationalObjectTableRow& row = rows[0];
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 object id", 14u, row.objectId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 channel id", 0u, row.channelId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 since", (ValidityKey)1, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 until", (ValidityKey)2, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 payload", std::string("Object 1"),
+                                  row["S"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 original id", 1u, row.originalId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 new head id", 0u, row.newHeadId() );
+    
+    row = rows[1];
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 object id", 20u, row.objectId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 channel id", 0u, row.channelId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 since", (ValidityKey)2, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 until", (ValidityKey)3, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 payload", std::string("Object 3"),
+                                  row["S"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 original id", 13u, row.originalId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 new head id", 0u, row.newHeadId() );
+    
+    row = rows[2];
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 object id", 19u, row.objectId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 channel id", 0u, row.channelId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 since", (ValidityKey)3, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 until", (ValidityKey)5, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 payload", std::string("Object 4"),
+                                  row["S"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 original id", 0u, row.originalId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 new head id", 0u, row.newHeadId() );
+    
+    row = rows[3];
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 object id", 7u, row.objectId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 channel id", 0u, row.channelId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 since", (ValidityKey)6, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 until", (ValidityKey)8, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 payload", std::string("Object 2"),
+                                  row["S"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 original id", 0u, row.originalId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 new head id", 0u, row.newHeadId() );
+  }
+  
+  
+  
+  /// Tests fetchRowsHead
+  void test_fetchRowsInHead_identicalRange() {
+    IFolderPtr folder = ralDb->createFolder( "/myfolder", 
+                                             payloadSpec,
+                                             "my description",
+                                             FolderVersioning::MULTI_VERSION );
+
+    folder->storeObject( 0, ValidityKeyMax, dummyPayload( 1 ), 0 );
+
+    RelationalFolder* relfolder = 
+      dynamic_cast<RelationalFolder*>(folder.get());
+
+    RelationalTransaction transaction( ralDb->transactionMgr() );
+    RelationalObjectTable 
+      objectTable( &(ralDb->queryMgr()), false, *relfolder );
+    std::vector<RelationalObjectTableRow> rows = 
+      fetchRowsInHead( objectTable, 
+                       ValidityKeyMin,
+                       ValidityKeyMax,
+                       ChannelSelection( 0, 0 ) );
+    
+    //copy( rows.begin(), rows.end(), 
+    //      std::ostream_iterator<RelationalObjectTableRow>( std::cout, "\n" ) );
+    
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "row count", 1u, 
+                                  (unsigned int)rows.size() );
+    
+    RelationalObjectTableRow& row = rows[0];
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 object id", 1u, row.objectId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 since", (ValidityKey)0, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 until", ValidityKeyMax, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 payload", std::string("Object 1"),
+                                  row["S"].data<std::string>() );
+  }
+  
+  
+  
+  /// Tests fetchRowsForTaggingCurrentHead in the context of user tags
+  void test_fetchRowsForTaggingCurrentHead_5c_with_userTag() {
+    IFolderPtr folder = ralDb->createFolder( "/myfolder", 
+                                             payloadSpec,
+                                             "my description",
+                                             FolderVersioning::MULTI_VERSION );
+    folder->storeObject( 1, 3, dummyPayload( 1 ), 0 );
+    folder->storeObject( 6, 8, dummyPayload( 2 ), (ChannelId)0, "A" );
+    
+    folder->storeObject( 2, 4, dummyPayload( 3 ), (ChannelId)0, "B" );
+    folder->storeObject( 3, 5, dummyPayload( 4 ), (ChannelId)0, "A" );
+    
+    folder->storeObject( 1, 5, dummyPayload( 5 ), (ChannelId)1 );
+    
+    RelationalFolder* relfolder = 
+      dynamic_cast<RelationalFolder*>(folder.get());    
+    
+    RelationalTransaction transaction( ralDb->transactionMgr() );
+    RelationalObjectTable 
+      objectTable( &(ralDb->queryMgr()), false, *relfolder );
+    std::vector<RelationalObjectTableRow> rows = 
+      objectTable.fetchRowsForTaggingCurrentHead();
+    sort( rows.begin(), rows.end(), lt_objectId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE
+      ( "row count", 5u, (unsigned int)rows.size() );
+    
+    RelationalObjectTableRow& row = rows[0];
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "0 object id", 7u, row.objectId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "0 channel id", 0u, row.channelId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "0 since", (ValidityKey)6, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "0 until", (ValidityKey)8, row.until() );
+    
+    row = rows[1];
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 object id", 14u, row.objectId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 channel id", 0u, row.channelId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 since", (ValidityKey)1, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 until", (ValidityKey)2, row.until() );
+    
+    row = rows[2];
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 object id", 19u, row.objectId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 channel id", 0u, row.channelId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 since", (ValidityKey)3, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 until", (ValidityKey)5, row.until() );
+    
+    row = rows[3];
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 object id", 20u, row.objectId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 channel id", 0u, row.channelId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 since", (ValidityKey)2, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 until", (ValidityKey)3, row.until() );
+    
+    row = rows[4];
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "4 object id", 25u, row.objectId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "4 channel id", 1u, row.channelId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "4 since", (ValidityKey)1, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "4 until", (ValidityKey)5, row.until() );
+  }
+  
+  
+  /// Tests fetchRowsForTaggingCurrentHead
+  void test_fetchRowsForTaggingCurrentHead_5c() {
+    IFolderPtr folder = ralDb->createFolder( "/myfolder", 
+                                             payloadSpec,
+                                             "my description",
+                                             FolderVersioning::MULTI_VERSION );
+    folder->setupStorageBuffer();
+    folder->storeObject( 1, 3, dummyPayload( 1 ), 0 );
+    folder->storeObject( 6, 8, dummyPayload( 2 ), 0 );
+    folder->flushStorageBuffer();
+    
+    folder->storeObject( 2, 4, dummyPayload( 3 ), 0 );
+    folder->storeObject( 3, 5, dummyPayload( 4 ), 0 );
+    folder->flushStorageBuffer();
+
+    folder->storeObject( 1, 5, dummyPayload( 5 ), (ChannelId)1 );
+    folder->flushStorageBuffer();
+    
+    RelationalFolder* relfolder = 
+      dynamic_cast<RelationalFolder*>(folder.get());    
+    
+    RelationalTransaction transaction( ralDb->transactionMgr() );
+    RelationalObjectTable 
+      objectTable( &(ralDb->queryMgr()), false, *relfolder );
+    std::vector<RelationalObjectTableRow> rows = 
+      objectTable.fetchRowsForTaggingCurrentHead();
+    sort( rows.begin(), rows.end(), lt_objectId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE
+      ( "row count", 5u, (unsigned int)rows.size() );
+    
+    RelationalObjectTableRow& row = rows[0];
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "0 object id", 7u, row.objectId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "0 channel id", 0u, row.channelId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "0 since", (ValidityKey)6, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "0 until", (ValidityKey)8, row.until() );
+    
+    row = rows[1];
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 object id", 14u, row.objectId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 channel id", 0u, row.channelId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 since", (ValidityKey)1, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 until", (ValidityKey)2, row.until() );
+    
+    row = rows[2];
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 object id", 19u, row.objectId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 channel id", 0u, row.channelId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 since", (ValidityKey)3, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 until", (ValidityKey)5, row.until() );
+    
+    row = rows[3];
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 object id", 20u, row.objectId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 channel id", 0u, row.channelId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 since", (ValidityKey)2, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "3 until", (ValidityKey)3, row.until() );
+    
+    row = rows[4];
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "4 object id", 25u, row.objectId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "4 channel id", 1u, row.channelId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "4 since", (ValidityKey)1, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "4 until", (ValidityKey)5, row.until() );
+  }
+  
+  
+  /// Tests fetchRowsForTaggingHeadAsOfDate in the context of user tags
+  void test_fetchRowsForTaggingHeadAsOfDate_5c_with_userTag() {
+    IFolderPtr folder = ralDb->createFolder( "/myfolder", 
+                                             payloadSpec,
+                                             "my description",
+                                             FolderVersioning::MULTI_VERSION );
+    
+    folder->storeObject( 1, 3, dummyPayload( 1 ), (ChannelId)0, "A" );
+    folder->storeObject( 6, 8, dummyPayload( 2 ), (ChannelId)0, "B" );
+    
+    RelationalFolder* relfolder = 
+      dynamic_cast<RelationalFolder*>(folder.get());    
+    
+    RelationalTransaction t1( ralDb->transactionMgr() );
+    boost::shared_ptr<RelationalSequence> seq
+      ( ralDb->queryMgr().sequenceMgr().getSequence
+        ( RelationalObjectTable::sequenceName
+          ( relfolder->objectTableName() ) ) );
+    Time asOfDate = stringToTime( seq->currDate() );
+    asOfDate = addOneNsToTime( asOfDate );
+    t1.commit();
+    
+    // MySQL now() has 1 second granularity: need to sleep at least 1 second
+    sleep(1); 
+    
+    folder->storeObject( 2, 4, dummyPayload( 3 ), (ChannelId)0, "A" );
+    folder->storeObject( 3, 5, dummyPayload( 4 ), (ChannelId)0, "B" );
+    
+    RelationalTransaction transaction( ralDb->transactionMgr() );
+    RelationalObjectTable 
+      objectTable( &(ralDb->queryMgr()), false, *relfolder );
+    std::vector<RelationalObjectTableRow> rows = 
+      objectTable.fetchRowsForTaggingHeadAsOfDate( asOfDate );
+    
+    //copy( rows.begin(), rows.end(), 
+    //      std::ostream_iterator<RelationalObjectTableRow>( std::cout, "\n" ) );
+    
+    CPPUNIT_ASSERT_EQUAL_MESSAGE
+      ( "row count", 2u, (unsigned int)rows.size() );
+    RelationalObjectTableRow& row = rows[0];
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 object id", 1u, row.objectId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 channel id", 0u, row.channelId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 since", (ValidityKey)1, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 until", (ValidityKey)3, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE
+      ( "1 instime", std::string("yyyy-mm-dd_hh:mm:ss.nnnnnnnnn GMT").size(), 
+        timeToString(row.insertionTime()).size() );
+    
+    row = rows[1];
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 object id", 7u, row.objectId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 channel id", 0u, row.channelId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 since", (ValidityKey)6, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 until", (ValidityKey)8, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE
+      ( "2 instime", std::string("yyyy-mm-dd_hh:mm:ss.nnnnnnnnn GMT").size(), 
+        timeToString(row.insertionTime()).size() );
+  }
+  
+  
+  /// Tests fetchRowsForTaggingHeadAsOfDate
+  void test_fetchRowsForTaggingHeadAsOfDate_5c() {
+    IFolderPtr folder = ralDb->createFolder( "/myfolder", 
+                                             payloadSpec,
+                                             "my description",
+                                             FolderVersioning::MULTI_VERSION );
+    
+    folder->setupStorageBuffer();
+    folder->storeObject( 1, 3, dummyPayload( 1 ), 0 );
+    folder->storeObject( 6, 8, dummyPayload( 2 ), 0 );
+    folder->flushStorageBuffer();
+    
+    RelationalFolder* relfolder = 
+      dynamic_cast<RelationalFolder*>(folder.get());    
+
+    RelationalTransaction t1( ralDb->transactionMgr() );
+    boost::shared_ptr<RelationalSequence> seq
+      ( ralDb->queryMgr().sequenceMgr().getSequence
+        ( RelationalObjectTable::sequenceName
+          ( relfolder->objectTableName() ) ) );
+    Time asOfDate = stringToTime( seq->currDate() );
+    asOfDate = addOneNsToTime( asOfDate );
+    t1.commit();
+    
+    // MySQL now() has 1 second granularity: need to sleep at least 1 second
+    sleep(1); 
+    
+    folder->storeObject( 2, 4, dummyPayload( 3 ), 0 );
+    folder->storeObject( 3, 5, dummyPayload( 4 ), 0 );
+    folder->flushStorageBuffer();
+
+    RelationalTransaction transaction( ralDb->transactionMgr() );
+    RelationalObjectTable 
+      objectTable( &(ralDb->queryMgr()), false, *relfolder );
+    std::vector<RelationalObjectTableRow> rows = 
+      objectTable.fetchRowsForTaggingHeadAsOfDate( asOfDate );
+    
+    //copy( rows.begin(), rows.end(), 
+    //      std::ostream_iterator<RelationalObjectTableRow>( std::cout, "\n" ) );
+    
+    CPPUNIT_ASSERT_EQUAL_MESSAGE
+      ( "row count", 2u, (unsigned int)rows.size() );
+    RelationalObjectTableRow& row = rows[0];
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 object id", 1u, row.objectId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 channel id", 0u, row.channelId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 since", (ValidityKey)1, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "1 until", (ValidityKey)3, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE
+      ( "1 instime", std::string("yyyy-mm-dd_hh:mm:ss.nnnnnnnnn GMT").size(), 
+        timeToString(row.insertionTime()).size() );
+    
+    row = rows[1];
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 object id", 7u, row.objectId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 channel id", 0u, row.channelId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 since", (ValidityKey)6, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "2 until", (ValidityKey)8, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE
+      ( "2 instime", std::string("yyyy-mm-dd_hh:mm:ss.nnnnnnnnn GMT").size(), 
+        timeToString(row.insertionTime()).size() );
+  }
+  
+  
+  /// Tests fetchRowsInTag of all channels
+  void test_fetchRowsInTag_all_channels() {
+    IFolderPtr folder = ralDb->createFolder( "/myfolder", 
+                                             payloadSpec,
+                                             "desc",
+                                             FolderVersioning::MULTI_VERSION );
+
+    int index = 0;
+    folder->setupStorageBuffer();
+    for ( ChannelId ch = 0; ch < 2; ++ch ) {
+      folder->storeObject( 0, ValidityKeyMax, dummyPayload( index++ ), ch );
+      folder->storeObject( 1, ValidityKeyMax, dummyPayload( index++ ), ch );
+    }
+    folder->flushStorageBuffer();
+    
+    folder->tagCurrentHead( "A" );
+
+    for ( ChannelId ch = 0; ch < 2; ++ch ) {
+      folder->storeObject( 0, ValidityKeyMax, dummyPayload( index++ ), ch );
+      folder->storeObject( 1, ValidityKeyMax, dummyPayload( index++ ), ch );
+    }
+    folder->flushStorageBuffer();
+    
+    RelationalFolder* relfolder = 
+      dynamic_cast<RelationalFolder*>(folder.get());    
+    
+    RelationalTransaction transaction( ralDb->transactionMgr() );
+    RelationalObjectTable 
+      objectTable( &(ralDb->queryMgr()), false, *relfolder );
+    std::vector<RelationalObjectTableRow> rows =
+      fetchRowsInTag( objectTable,
+                      ValidityKeyMin, 
+                      ValidityKeyMax, 
+                      ChannelSelection::all(),
+                      "A" );
+    
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "size", 4, (int)rows.size() );
+    
+    RelationalObjectTableRow row = rows[0];
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "payload 0", 
+                                  std::string("Object 0"),
+                                  row["S"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "since 0", 
+                                  (ValidityKey)0, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "until 0", 
+                                  (ValidityKey)1, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "channel 0", 
+                                  (ChannelId)0, row.channelId() );
+    
+    row = rows[1];
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "payload 1", 
+                                  std::string("Object 1"),
+                                  row["S"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "since 1", 
+                                  (ValidityKey)1, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "until 1", 
+                                  ValidityKeyMax, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "channel 1", 
+                                  (ChannelId)0, row.channelId() );
+    
+    row = rows[2];
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "payload 2", 
+                                  std::string("Object 2"),
+                                  row["S"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "since 2", 
+                                  (ValidityKey)0, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "until 2", 
+                                  (ValidityKey)1, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "channel 2", 
+                                  (ChannelId)1, row.channelId() );
+    
+    
+    row = rows[3];
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "payload 3", 
+                                  std::string("Object 3"),
+                                  row["S"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "since 3", 
+                                  (ValidityKey)1, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "until 3", 
+                                  ValidityKeyMax, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "channel 3", 
+                                  (ChannelId)1, row.channelId() );
+    
+  }
+  
+  
+  
+  /// Tests fetchRowsInTag with a channel range and
+  /// since-before-channel ordering
+  void test_fetchRowsInTag_channel_range_ordering() {
+    IFolderPtr folder = ralDb->createFolder( "/myfolder", 
+                                             payloadSpec,
+                                             "desc",
+                                             FolderVersioning::MULTI_VERSION );
+    
+    int index = 0;
+    folder->setupStorageBuffer();
+    for ( ChannelId ch = 0; ch < 5; ++ch ) {
+      folder->storeObject( 0, ValidityKeyMax, dummyPayload( index++ ), ch );
+      folder->storeObject( 1, ValidityKeyMax, dummyPayload( index++ ), ch );
+    }
+    folder->flushStorageBuffer();
+    
+    folder->tagCurrentHead( "A" );
+
+    for ( ChannelId ch = 0; ch < 5; ++ch ) {
+      folder->storeObject( 0, ValidityKeyMax, dummyPayload( index++ ), ch );
+      folder->storeObject( 1, ValidityKeyMax, dummyPayload( index++ ), ch );
+    }
+    folder->flushStorageBuffer();
+    
+    ChannelSelection channels( 2, 3, ChannelSelection::sinceBeforeChannel );
+
+    RelationalFolder* relfolder = 
+      dynamic_cast<RelationalFolder*>(folder.get());    
+    
+    RelationalTransaction transaction( ralDb->transactionMgr() );
+    RelationalObjectTable 
+      objectTable( &(ralDb->queryMgr()), false, *relfolder );
+    std::vector<RelationalObjectTableRow> rows =
+      fetchRowsInTag( objectTable,
+                      ValidityKeyMin, 
+                      ValidityKeyMax, 
+                      channels,
+                      "A" );
+    
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "size", 4, (int)rows.size() );
+    
+    RelationalObjectTableRow row = rows[0];
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "payload 0", 
+                                  std::string("Object 4"),
+                                  row["S"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "since 0", 
+                                  (ValidityKey)0, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "until 0", 
+                                  (ValidityKey)1, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "channel 0", 
+                                  (ChannelId)2, row.channelId() );
+    
+    row = rows[1];
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "payload 1", 
+                                  std::string("Object 6"),
+                                  row["S"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "since 1", 
+                                  (ValidityKey)0, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "until 1", 
+                                  (ValidityKey)1, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "channel 1", 
+                                  (ChannelId)3, row.channelId() );
+    
+    row = rows[2];
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "payload 2", 
+                                  std::string("Object 5"),
+                                  row["S"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "since 2", 
+                                  (ValidityKey)1, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "until 2", 
+                                  ValidityKeyMax, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "channel 2", 
+                                  (ChannelId)2, row.channelId() );
+    
+    
+    row = rows[3];
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "payload 3", 
+                                  std::string("Object 7"),
+                                  row["S"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "since 3", 
+                                  (ValidityKey)1, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "until 3", 
+                                  ValidityKeyMax, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "channel 3", 
+                                  (ChannelId)3, row.channelId() );
+    
+  }
+  
+  
+  
+  
+  
+  /// Tests fetchRowsInTag with a channel range
+  void test_fetchRowsInTag_channel_range() {
+    IFolderPtr folder = ralDb->createFolder( "/myfolder", 
+                                             payloadSpec,
+                                             "desc",
+                                             FolderVersioning::MULTI_VERSION );
+    
+    int index = 0;
+    folder->setupStorageBuffer();
+    for ( ChannelId ch = 0; ch < 5; ++ch ) {
+      folder->storeObject( 0, ValidityKeyMax, dummyPayload( index++ ), ch );
+      folder->storeObject( 1, ValidityKeyMax, dummyPayload( index++ ), ch );
+    }
+    folder->flushStorageBuffer();
+
+    folder->tagCurrentHead( "A" );
+    
+    for ( ChannelId ch = 0; ch < 5; ++ch ) {
+      folder->storeObject( 0, ValidityKeyMax, dummyPayload( index++ ), ch );
+      folder->storeObject( 1, ValidityKeyMax, dummyPayload( index++ ), ch );
+    }
+    folder->flushStorageBuffer();
+    
+    RelationalFolder* relfolder = 
+      dynamic_cast<RelationalFolder*>(folder.get());    
+
+    RelationalTransaction transaction( ralDb->transactionMgr() );
+    RelationalObjectTable 
+      objectTable( &(ralDb->queryMgr()), false, *relfolder );
+    std::vector<RelationalObjectTableRow> rows =
+      fetchRowsInTag( objectTable,
+                      ValidityKeyMin, 
+                      ValidityKeyMax, 
+                      ChannelSelection( 2, 3 ),
+                      "A" );
+    
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "size", 4, (int)rows.size() );
+    
+    RelationalObjectTableRow row = rows[0];
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "payload 0", 
+                                  std::string("Object 4"),
+                                  row["S"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "since 0", 
+                                  (ValidityKey)0, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "until 0", 
+                                  (ValidityKey)1, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "channel 0", 
+                                  (ChannelId)2, row.channelId() );
+    
+    row = rows[1];
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "payload 1", 
+                                  std::string("Object 5"),
+                                  row["S"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "since 1", 
+                                  (ValidityKey)1, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "until 1", 
+                                  ValidityKeyMax, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "channel 1", 
+                                  (ChannelId)2, row.channelId() );
+    
+    row = rows[2];
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "payload 2", 
+                                  std::string("Object 6"),
+                                  row["S"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "since 2", 
+                                  (ValidityKey)0, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "until 2", 
+                                  (ValidityKey)1, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "channel 2", 
+                                  (ChannelId)3, row.channelId() );
+    
+    
+    row = rows[3];
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "payload 3", 
+                                  std::string("Object 7"), 
+                                  row["S"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "since 3", 
+                                  (ValidityKey)1, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "until 3", 
+                                  ValidityKeyMax, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "channel 3", 
+                                  (ChannelId)3, row.channelId() );
+    
+  }
+  
+  
+    
+  /// Tests fetchRowsInHead of all channels
+  void test_fetchRowsInHead_all_channels() {
+    IFolderPtr folder = ralDb->createFolder( "/myfolder", 
+                                             payloadSpec,
+                                             "desc",
+                                             FolderVersioning::MULTI_VERSION );
+    
+    int index = 0;
+    folder->setupStorageBuffer();
+    for ( ChannelId ch = 0; ch < 2; ++ch ) {
+      folder->storeObject( 0, ValidityKeyMax, dummyPayload( index++ ), ch );
+      folder->storeObject( 1, ValidityKeyMax, dummyPayload( index++ ), ch );
+    }
+    folder->flushStorageBuffer();
+
+    RelationalFolder* relfolder = 
+      dynamic_cast<RelationalFolder*>(folder.get());    
+
+    RelationalTransaction transaction( ralDb->transactionMgr() );
+    RelationalObjectTable 
+      objectTable( &(ralDb->queryMgr()), false, *relfolder );
+    std::vector<RelationalObjectTableRow> rows =
+      fetchRowsInHead( objectTable, 
+                       ValidityKeyMin, 
+                       ValidityKeyMax, 
+                       ChannelSelection::all() );
+    
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "size", 4, (int)rows.size() );
+    
+    RelationalObjectTableRow row = rows[0];
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "payload 0", 
+                                  std::string("Object 0"),
+                                  row["S"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "since 0", 
+                                  (ValidityKey)0, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "until 0", 
+                                  (ValidityKey)1, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "channel 0", 
+                                  (ChannelId)0, row.channelId() );
+    
+    row = rows[1];
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "payload 1", 
+                                  std::string("Object 1"),
+                                  row["S"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "since 1", 
+                                  (ValidityKey)1, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "until 1", 
+                                  ValidityKeyMax, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "channel 1", 
+                                  (ChannelId)0, row.channelId() );
+    
+    row = rows[2];
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "payload 2", 
+                                  std::string("Object 2"),
+                                  row["S"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "since 2", 
+                                  (ValidityKey)0, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "until 2", 
+                                  (ValidityKey)1, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "channel 2", 
+                                  (ChannelId)1, row.channelId() );
+    
+    
+    row = rows[3];
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "payload 3", 
+                                  std::string("Object 3"), 
+                                  row["S"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "since 3", 
+                                  (ValidityKey)1, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "until 3", 
+                                  ValidityKeyMax, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "channel 3", 
+                                  (ChannelId)1, row.channelId() );
+    
+  }
+  
+  
+  
+  
+  /// Tests fetchRowsInHead with a channel range and
+  /// since-before-channel ordering
+  void test_fetchRowsInHead_channel_range_ordering() {
+    IFolderPtr folder = ralDb->createFolder( "/myfolder", 
+                                             payloadSpec,
+                                             "desc",
+                                             FolderVersioning::MULTI_VERSION );
+    
+    int index = 0;
+    folder->setupStorageBuffer();
+    for ( ChannelId ch = 0; ch < 5; ++ch ) {
+      folder->storeObject( 0, ValidityKeyMax, dummyPayload( index++ ), ch );
+      folder->storeObject( 1, ValidityKeyMax, dummyPayload( index++ ), ch );
+    }
+    folder->flushStorageBuffer();
+    
+    ChannelSelection channels( 2, 3, ChannelSelection::sinceBeforeChannel );
+    
+    RelationalFolder* relfolder = 
+      dynamic_cast<RelationalFolder*>(folder.get());    
+
+    RelationalTransaction transaction( ralDb->transactionMgr() );
+    RelationalObjectTable 
+      objectTable( &(ralDb->queryMgr()), false, *relfolder );
+    std::vector<RelationalObjectTableRow> rows =
+      fetchRowsInHead( objectTable, 
+                       ValidityKeyMin, 
+                       ValidityKeyMax, 
+                       channels );
+    
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "size", 4, (int)rows.size() );
+    
+    RelationalObjectTableRow row = rows[0];
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "payload 0", 
+                                  std::string("Object 4"), 
+                                  row["S"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "since 0", 
+                                  (ValidityKey)0, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "until 0", 
+                                  (ValidityKey)1, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "channel 0", 
+                                  (ChannelId)2, row.channelId() );
+    
+    row = rows[1];
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "payload 1", 
+                                  std::string("Object 6"),
+                                  row["S"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "since 1", 
+                                  (ValidityKey)0, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "until 1", 
+                                  (ValidityKey)1, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "channel 1", 
+                                  (ChannelId)3, row.channelId() );
+    
+    row = rows[2];
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "payload 2", 
+                                  std::string("Object 5"),
+                                  row["S"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "since 2", 
+                                  (ValidityKey)1, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "until 2", 
+                                  ValidityKeyMax, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "channel 2", 
+                                  (ChannelId)2, row.channelId() );
+    
+    
+    row = rows[3];
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "payload 3", 
+                                  std::string("Object 7"), 
+                                  row["S"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "since 3", 
+                                  (ValidityKey)1, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "until 3", 
+                                  ValidityKeyMax, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "channel 3", 
+                                  (ChannelId)3, row.channelId() );
+    
+  }
+  
+  
+  
+  
+  /// Tests fetchRowsInHead with a channel range
+  void test_fetchRowsInHead_channel_range() {
+    IFolderPtr folder = ralDb->createFolder( "/myfolder", 
+                                             payloadSpec,
+                                             "desc",
+                                             FolderVersioning::MULTI_VERSION );
+    
+    int index = 0;
+    folder->setupStorageBuffer();
+    for ( ChannelId ch = 0; ch < 5; ++ch ) {
+      folder->storeObject( 0, ValidityKeyMax, dummyPayload( index++ ), ch );
+      folder->storeObject( 1, ValidityKeyMax, dummyPayload( index++ ), ch );
+    }
+    folder->flushStorageBuffer();
+    
+    RelationalFolder* relfolder = 
+      dynamic_cast<RelationalFolder*>(folder.get());    
+    
+    RelationalTransaction transaction( ralDb->transactionMgr() );
+    RelationalObjectTable 
+      objectTable( &(ralDb->queryMgr()), false, *relfolder );
+    std::vector<RelationalObjectTableRow> rows =
+      fetchRowsInHead( objectTable, 
+                       ValidityKeyMin, 
+                       ValidityKeyMax, 
+                       ChannelSelection( 2, 3 ) );
+    
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "size", 4, (int)rows.size() );
+    
+    RelationalObjectTableRow row = rows[0];
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "payload 0", 
+                                  std::string("Object 4"),
+                                  row["S"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "since 0", 
+                                  (ValidityKey)0, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "until 0", 
+                                  (ValidityKey)1, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "channel 0", 
+                                  (ChannelId)2, row.channelId() );
+    
+    row = rows[1];
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "payload 1", 
+                                  std::string("Object 5"), 
+                                  row["S"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "since 1", 
+                                  (ValidityKey)1, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "until 1", 
+                                  ValidityKeyMax, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "channel 1", 
+                                  (ChannelId)2, row.channelId() );
+    
+    row = rows[2];
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "payload 2", 
+                                  std::string("Object 6"),
+                                  row["S"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "since 2", 
+                                  (ValidityKey)0, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "until 2", 
+                                  (ValidityKey)1, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "channel 2", 
+                                  (ChannelId)3, row.channelId() );
+    
+    
+    row = rows[3];
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "payload 3", 
+                                  std::string("Object 7"), 
+                                  row["S"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "since 3", 
+                                  (ValidityKey)1, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "until 3", 
+                                  ValidityKeyMax, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "channel 3", 
+                                  (ChannelId)3, row.channelId() );
+    
+  }
+  
+  
+    
+  /// Tests fetchRowAtTimeInTag
+  void test_fetchRowAtTimeInTag_5c() 
+  {
+    try 
+    {
+      IFolderPtr folder = 
+        ralDb->createFolder( "/myfolder", 
+                             payloadSpec,
+                             "my description",
+                             FolderVersioning::MULTI_VERSION );
+      
+      folder->setupStorageBuffer();
+      folder->storeObject( 1, 3, dummyPayload( 1 ), 0 );
+      folder->storeObject( 6, 8, dummyPayload( 2 ), 0 );
+      folder->flushStorageBuffer();
+      
+      folder->tagCurrentHead( "mytagA", "a tag A" );
+      
+      folder->storeObject( 2, 4, dummyPayload( 3 ), 0 );
+      folder->storeObject( 3, 5, dummyPayload( 4 ), 0 );
+      folder->flushStorageBuffer();
+      
+      RelationalFolder* relfolder = 
+        dynamic_cast<RelationalFolder*>(folder.get());    
+      
+      RelationalTransaction transaction( ralDb->transactionMgr() );
+      RelationalObjectTable 
+        objectTable( &(ralDb->queryMgr()), false, *relfolder );
+
+      //RelationalObjectTableRow row =
+      //  objectTable.fetchRowAtTimeInTag( (ValidityKey)2,
+      //                                   (ChannelId)0,
+      //                                   "mytagA" );
+      RelationalTableRow row0;
+      {
+        const ValidityKey pointInTime = (ValidityKey)2;
+        const ChannelId channelId = (ChannelId)0;
+        const std::string tagName = "mytagA";
+        const std::auto_ptr<IRelationalQueryDefinition> 
+          def( objectTable.queryDefinitionTag
+               ( pointInTime, pointInTime, channelId, tagName ) );
+        // Delegate the query to the RalQueryMgr
+        try 
+        {
+          std::string desc = "";
+          const std::vector<RelationalTableRow> rows
+            ( objectTable.queryMgr().fetchOrderedRows( *def, desc, 1 ) );
+          row0 = rows[0];
+        } 
+        catch( NoRowsFound& ) 
+        {
+          std::stringstream s;
+          s << pointInTime;
+          throw ObjectNotFound
+            ( s.str(), objectTable.objectTableName(), "RelationalObjectTable" );
+        }
+      }      
+
+      RelationalObjectTableRow row(row0);
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "object id", 1u, row.objectId() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "channel id", 0u, row.channelId() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "since", (ValidityKey)1, row.since() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "until", (ValidityKey)3, row.until() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "payload", std::string("Object 1"),
+                                    row["S"].data<std::string>() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "original id", 0u, row.originalId() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "new head id", 13u, row.newHeadId() );
+    } 
+    catch ( std::exception& e ) 
+    {
+      std::cout << "Exception caught: " << e.what() << std::endl;
+      throw;
+    }
+  }
+  
+  
+  /// Tests test_fetchRowsForTaggingHeadAsOfObjectId_5c in the context of user
+  /// tags
+  void test_fetchRowsForTaggingHeadAsOfObjectId_5c_with_userTag() {
+    try {
+      IFolderPtr folder = ralDb->createFolder( "/myfolder", 
+                                               payloadSpec,
+                                               "my description",
+                                               FolderVersioning::MULTI_VERSION );
+      
+      folder->storeObject( 1, 3, dummyPayload( 1 ), (ChannelId)0, "A" );
+      folder->storeObject( 6, 8, dummyPayload( 2 ), (ChannelId)0, "B" );
+      
+      folder->storeObject( 2, 4, dummyPayload( 3 ), (ChannelId)0, "A" );
+      folder->storeObject( 3, 5, dummyPayload( 4 ), (ChannelId)0, "B" );
+      
+      RelationalFolder* relfolder = 
+        dynamic_cast<RelationalFolder*>(folder.get());    
+      
+      RelationalTransaction transaction( ralDb->transactionMgr() );
+      RelationalObjectTable 
+        objectTable( &(ralDb->queryMgr()), false, *relfolder );
+      unsigned int uObjectId = 7; // user object 
+      unsigned int lObjectId = 8; // left system object
+      unsigned int rObjectId = 9; // right system object
+      std::vector<RelationalObjectTableRow> uRows = 
+        objectTable.fetchRowsForTaggingHeadAsOfObjectId( uObjectId );
+      std::vector<RelationalObjectTableRow> lRows = 
+        objectTable.fetchRowsForTaggingHeadAsOfObjectId( lObjectId );
+      std::vector<RelationalObjectTableRow> rRows = 
+        objectTable.fetchRowsForTaggingHeadAsOfObjectId( rObjectId );
+      
+      //copy( uRows.begin(), uRows.end(), 
+      //      std::ostream_iterator<RelationalObjectTableRow>( std::cout, "\n" ) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "(u) row count", 2u, (unsigned int)uRows.size() );
+      RelationalObjectTableRow& row = uRows[0];
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "(u) 1 object id", 1u, row.objectId() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "(u) 1 channel id", 0u, row.channelId() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "(u) 1 since", (ValidityKey)1, row.since() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "(u) 1 until", (ValidityKey)3, row.until() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "(u) 1 instime", std::string("yyyy-mm-dd_hh:mm:ss.nnnnnnnnn GMT").size(), 
+          timeToString(row.insertionTime()).size() );    
+      row = uRows[1];
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "(u) 2 object id", 7u, row.objectId() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "(u) 2 channel id", 0u, row.channelId() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "(u) 2 since", (ValidityKey)6, row.since() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "(u) 2 until", (ValidityKey)8, row.until() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "(u) 2 instime", std::string("yyyy-mm-dd_hh:mm:ss.nnnnnnnnn GMT").size(), 
+          timeToString(row.insertionTime()).size() );
+      
+      //copy( lRows.begin(), lRows.end(), 
+      //      std::ostream_iterator<RelationalObjectTableRow>( std::cout, "\n" ) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "(l) row count", 2u, (unsigned int)lRows.size() );
+      row = lRows[0];
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "(l) 1 object id", 1u, row.objectId() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "(l) 1 channel id", 0u, row.channelId() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "(l) 1 since", (ValidityKey)1, row.since() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "(l) 1 until", (ValidityKey)3, row.until() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "(l) 1 instime", std::string("yyyy-mm-dd_hh:mm:ss.nnnnnnnnn GMT").size(), 
+          timeToString(row.insertionTime()).size() );    
+      row = lRows[1];
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "(l) 2 object id", 7u, row.objectId() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "(l) 2 channel id", 0u, row.channelId() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "(l) 2 since", (ValidityKey)6, row.since() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "(l) 2 until", (ValidityKey)8, row.until() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "(l) 2 instime", std::string("yyyy-mm-dd_hh:mm:ss.nnnnnnnnn GMT").size(), 
+          timeToString(row.insertionTime()).size() );
+      
+      //copy( rRows.begin(), rRows.end(), 
+      //      std::ostream_iterator<RelationalObjectTableRow>( std::cout, "\n" ) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "(r) row count", 2u, (unsigned int)rRows.size() );
+      row = rRows[0];
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "(r) 1 object id", 1u, row.objectId() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "(r) 1 channel id", 0u, row.channelId() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "(r) 1 since", (ValidityKey)1, row.since() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "(r) 1 until", (ValidityKey)3, row.until() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "(r) 1 instime", std::string("yyyy-mm-dd_hh:mm:ss.nnnnnnnnn GMT").size(), 
+          timeToString(row.insertionTime()).size() );    
+      row = rRows[1];
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "(r) 2 object id", 7u, row.objectId() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "(r) 2 channel id", 0u, row.channelId() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "(r) 2 since", (ValidityKey)6, row.since() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "(r) 2 until", (ValidityKey)8, row.until() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "(r) 2 instime", std::string("yyyy-mm-dd_hh:mm:ss.nnnnnnnnn GMT").size(), 
+          timeToString(row.insertionTime()).size() );
+    } catch ( std::exception& e ) {
+      std::cout << e.what() << std::endl;
+      throw;
+    }
+  }
+  
+  
+  /// Tests test_fetchRowsForTaggingHeadAsOfObjectId_5c
+  void test_fetchRowsForTaggingHeadAsOfObjectId_5c() {
+    try {
+      IFolderPtr folder = ralDb->createFolder( "/myfolder", 
+                                               payloadSpec,
+                                               "my description",
+                                               FolderVersioning::MULTI_VERSION );
+      
+      folder->setupStorageBuffer();
+      folder->storeObject( 1, 3, dummyPayload( 1 ), 0 );
+      folder->storeObject( 6, 8, dummyPayload( 2 ), 0 );
+      folder->flushStorageBuffer();
+
+      folder->storeObject( 2, 4, dummyPayload( 3 ), 0 );
+      folder->storeObject( 3, 5, dummyPayload( 4 ), 0 );
+      folder->flushStorageBuffer();
+      
+      RelationalFolder* relfolder = 
+        dynamic_cast<RelationalFolder*>(folder.get());    
+      
+      RelationalTransaction transaction( ralDb->transactionMgr() );
+      RelationalObjectTable 
+        objectTable( &(ralDb->queryMgr()), false, *relfolder );
+      unsigned int uObjectId = 7; // user object 
+      unsigned int lObjectId = 8; // left system object
+      unsigned int rObjectId = 9; // right system object
+      std::vector<RelationalObjectTableRow> uRows = 
+        objectTable.fetchRowsForTaggingHeadAsOfObjectId( uObjectId );
+      std::vector<RelationalObjectTableRow> lRows = 
+        objectTable.fetchRowsForTaggingHeadAsOfObjectId( lObjectId );
+      std::vector<RelationalObjectTableRow> rRows = 
+        objectTable.fetchRowsForTaggingHeadAsOfObjectId( rObjectId );
+      
+      //copy( uRows.begin(), uRows.end(), 
+      //      std::ostream_iterator<RelationalObjectTableRow>( std::cout, "\n" ) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "(u) row count", 2u, (unsigned int)uRows.size() );
+      RelationalObjectTableRow& row = uRows[0];
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "(u) 1 object id", 1u, row.objectId() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "(u) 1 channel id", 0u, row.channelId() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "(u) 1 since", (ValidityKey)1, row.since() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "(u) 1 until", (ValidityKey)3, row.until() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "(u) 1 instime", std::string("yyyy-mm-dd_hh:mm:ss.nnnnnnnnn GMT").size(), 
+          timeToString(row.insertionTime()).size() );    
+      row = uRows[1];
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "(u) 2 object id", 7u, row.objectId() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "(u) 2 channel id", 0u, row.channelId() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "(u) 2 since", (ValidityKey)6, row.since() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "(u) 2 until", (ValidityKey)8, row.until() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "(u) 2 instime", std::string("yyyy-mm-dd_hh:mm:ss.nnnnnnnnn GMT").size(), 
+          timeToString(row.insertionTime()).size() );
+      
+      //copy( lRows.begin(), lRows.end(), 
+      //      std::ostream_iterator<RelationalObjectTableRow>( std::cout, "\n" ) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "(l) row count", 2u, (unsigned int)lRows.size() );
+      row = lRows[0];
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "(l) 1 object id", 1u, row.objectId() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "(l) 1 channel id", 0u, row.channelId() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "(l) 1 since", (ValidityKey)1, row.since() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "(l) 1 until", (ValidityKey)3, row.until() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "(l) 1 instime", std::string("yyyy-mm-dd_hh:mm:ss.nnnnnnnnn GMT").size(), 
+          timeToString(row.insertionTime()).size() );    
+      row = lRows[1];
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "(l) 2 object id", 7u, row.objectId() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "(l) 2 channel id", 0u, row.channelId() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "(l) 2 since", (ValidityKey)6, row.since() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "(l) 2 until", (ValidityKey)8, row.until() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "(l) 2 instime", std::string("yyyy-mm-dd_hh:mm:ss.nnnnnnnnn GMT").size(), 
+          timeToString(row.insertionTime()).size() );
+      
+      //copy( rRows.begin(), rRows.end(), 
+      //      std::ostream_iterator<RelationalObjectTableRow>( std::cout, "\n" ) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "(r) row count", 2u, (unsigned int)rRows.size() );
+      row = rRows[0];
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "(r) 1 object id", 1u, row.objectId() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "(r) 1 channel id", 0u, row.channelId() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "(r) 1 since", (ValidityKey)1, row.since() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "(r) 1 until", (ValidityKey)3, row.until() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "(r) 1 instime", std::string("yyyy-mm-dd_hh:mm:ss.nnnnnnnnn GMT").size(), 
+          timeToString(row.insertionTime()).size() );    
+      row = rRows[1];
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "(r) 2 object id", 7u, row.objectId() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "(r) 2 channel id", 0u, row.channelId() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "(r) 2 since", (ValidityKey)6, row.since() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "(r) 2 until", (ValidityKey)8, row.until() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "(r) 2 instime", std::string("yyyy-mm-dd_hh:mm:ss.nnnnnnnnn GMT").size(), 
+          timeToString(row.insertionTime()).size() );
+    } catch ( std::exception& e ) {
+      std::cout << e.what() << std::endl;
+      throw;
+    }
+  }
+  
+  
+  /// Tests fetchRowsForTaggingHeadAsOfObjectId for a duplicate IOV
+  void test_fetchRowsForTaggingHeadAsOfObjectId_duplIOV() {
+    IFolderPtr folder = ralDb->createFolder( "/myfolder", 
+                                             payloadSpec,
+                                             "my description",
+                                             FolderVersioning::MULTI_VERSION );
+
+    folder->setupStorageBuffer();
+    folder->storeObject( 1, 3, dummyPayload( 1 ), 0 );
+    folder->storeObject( 6, 8, dummyPayload( 2 ), 0 );
+    // DUPLICATE!
+    folder->storeObject( 6, 8, dummyPayload( 5 ), 0 );
+    folder->flushStorageBuffer();
+
+    folder->storeObject( 2, 4, dummyPayload( 3 ), 0 );
+    folder->storeObject( 3, 5, dummyPayload( 4 ), 0 );
+    folder->flushStorageBuffer();
+    
+    RelationalFolder* relfolder = 
+      dynamic_cast<RelationalFolder*>(folder.get());    
+
+    RelationalTransaction transaction( ralDb->transactionMgr() );
+    RelationalObjectTable 
+      objectTable( &(ralDb->queryMgr()), false, *relfolder );
+    unsigned int uObjectId = 7; // user object 
+    unsigned int lObjectId = 8; // left system object
+    unsigned int rObjectId = 9; // right system object
+    std::vector<RelationalObjectTableRow> uRows = 
+      objectTable.fetchRowsForTaggingHeadAsOfObjectId( uObjectId );
+    std::vector<RelationalObjectTableRow> lRows = 
+      objectTable.fetchRowsForTaggingHeadAsOfObjectId( lObjectId );
+    std::vector<RelationalObjectTableRow> rRows = 
+      objectTable.fetchRowsForTaggingHeadAsOfObjectId( rObjectId );
+    
+    //copy( uRows.begin(), uRows.end(), 
+    //      std::ostream_iterator<RelationalObjectTableRow>( std::cout, "\n" ) );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE
+      ( "(u) row count", 2u, (unsigned int)uRows.size() );
+    RelationalObjectTableRow& row = uRows[0];
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "(u) 1 object id", 1u, row.objectId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "(u) 1 channel id", 0u, row.channelId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "(u) 1 since", (ValidityKey)1, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "(u) 1 until", (ValidityKey)3, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE
+      ( "(u) 1 instime", std::string("yyyy-mm-dd_hh:mm:ss.nnnnnnnnn GMT").size(), 
+        timeToString(row.insertionTime()).size() );    
+    row = uRows[1];
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "(u) 2 object id", 7u, row.objectId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "(u) 2 channel id", 0u, row.channelId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "(u) 2 since", (ValidityKey)6, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "(u) 2 until", (ValidityKey)8, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE
+      ( "(u) 2 instime", std::string("yyyy-mm-dd_hh:mm:ss.nnnnnnnnn GMT").size(), 
+        timeToString(row.insertionTime()).size() );
+    
+    //copy( lRows.begin(), lRows.end(), 
+    //      std::ostream_iterator<RelationalObjectTableRow>( std::cout, "\n" ) );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE
+      ( "(l) row count", 2u, (unsigned int)lRows.size() );
+    row = lRows[0];
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "(l) 1 object id", 1u, row.objectId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "(l) 1 channel id", 0u, row.channelId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "(l) 1 since", (ValidityKey)1, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "(l) 1 until", (ValidityKey)3, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE
+      ( "(l) 1 instime", std::string("yyyy-mm-dd_hh:mm:ss.nnnnnnnnn GMT").size(), 
+        timeToString(row.insertionTime()).size() );    
+    row = lRows[1];
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "(l) 2 object id", 7u, row.objectId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "(l) 2 channel id", 0u, row.channelId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "(l) 2 since", (ValidityKey)6, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "(l) 2 until", (ValidityKey)8, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE
+      ( "(l) 2 instime", std::string("yyyy-mm-dd_hh:mm:ss.nnnnnnnnn GMT").size(), 
+        timeToString(row.insertionTime()).size() );
+    
+    //copy( rRows.begin(), rRows.end(), 
+    //      std::ostream_iterator<RelationalObjectTableRow>( std::cout, "\n" ) );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE
+      ( "(r) row count", 2u, (unsigned int)rRows.size() );
+    row = rRows[0];
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "(r) 1 object id", 1u, row.objectId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "(r) 1 channel id", 0u, row.channelId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "(r) 1 since", (ValidityKey)1, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "(r) 1 until", (ValidityKey)3, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE
+      ( "(r) 1 instime", std::string("yyyy-mm-dd_hh:mm:ss.nnnnnnnnn GMT").size(), 
+        timeToString(row.insertionTime()).size() );    
+    row = rRows[1];
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "(r) 2 object id", 7u, row.objectId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "(r) 2 channel id", 0u, row.channelId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "(r) 2 since", (ValidityKey)6, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "(r) 2 until", (ValidityKey)8, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE
+      ( "(r) 2 instime", std::string("yyyy-mm-dd_hh:mm:ss.nnnnnnnnn GMT").size(), 
+        timeToString(row.insertionTime()).size() );
+  }
+  
+
+  /// Tests fetchLastRowForTagId (bug #40812)
+  void test_fetchLastRowForTagId() {
+    IFolderPtr folder = m_db->createFolder( "/myfolder", 
+                                          payloadSpec,
+                                          "my description",
+                                          FolderVersioning::MULTI_VERSION );
+    RelationalFolder* relfolder = 
+      dynamic_cast<RelationalFolder*>(folder.get());
+    
+    folder->setupStorageBuffer();
+    folder->storeObject( 0, 4, dummyPayload( 0 ), 0 );
+    folder->storeObject( 1, 5, dummyPayload( 1 ), 0 );
+    folder->storeObject( 2, 6, dummyPayload( 2 ), 0 );
+    folder->flushStorageBuffer();
+
+    folder->tagCurrentHead( "tag A" );
+    
+    folder->storeObject( 1, 5, dummyPayload( 1 ), 0 );
+    folder->storeObject( 2, 6, dummyPayload( 2 ), 0 );
+    folder->flushStorageBuffer();
+    folder->storeObject( 3, 8, dummyPayload( 3 ), 0, "tag B");
+    folder->storeObject( 2, 6, dummyPayload( 4 ), 0, "tag B");
+    folder->flushStorageBuffer();
+    folder->storeObject( 4, 5, dummyPayload( 5 ), 0);
+    folder->flushStorageBuffer();
+    
+    // test IOV tag
+    RelationalTransaction transaction( ralDb->transactionMgr() );
+    RelationalObjectTable 
+      objectTable( &(ralDb->queryMgr()), false, *relfolder );
+    unsigned int tagId = 1;
+    bool fetchPayload = true;
+    RelationalObjectTableRow row = 
+      objectTable.fetchLastRowForTagId( tagId, fetchPayload );
+    transaction.commit();
+    
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "objectId", 14u, row.objectId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "since", (ValidityKey)1, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "until", (ValidityKey)2, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "payload", 
+                                  std::string( "Object 1" ), 
+                                  row["S"].data<std::string>() );
+    // test user tag
+    {
+    RelationalTransaction transaction( ralDb->transactionMgr() );
+    RelationalObjectTable 
+      objectTable( &(ralDb->queryMgr()), false, *relfolder );
+    unsigned int tagId = 2;
+    bool fetchPayload = true;
+    RelationalObjectTableRow row = 
+      objectTable.fetchLastRowForTagId( tagId, fetchPayload );
+    transaction.commit();
+    
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "objectId", 42u, row.objectId() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "since", (ValidityKey)6, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "until", (ValidityKey)8, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "payload", 
+                                  std::string( "Object 3" ), 
+                                  row["S"].data<std::string>() );
+    }
+  }
+  
+  /*
+  /// Tests fetchRowAtTimeSV
+  void test_fetchRowAtTimeSV() {
+    try {
+      IFolderPtr folder = ralDb->createFolder( "/myfolder", payloadSpec );
+      RelationalFolder* relfolder = 
+        dynamic_cast<RelationalFolder*>( folder.get() );
+      
+      folder->setupStorageBuffer();
+      folder->storeObject( 0, 2, dummyPayload( 1 ), 0 );
+      folder->storeObject( 2, 4, dummyPayload( 2 ), 0 );
+      folder->flushStorageBuffer();
+      
+      RelationalTransaction transaction( ralDb->transactionMgr() );
+      RelationalObjectTable 
+        objectTable( &(ralDb->queryMgr()), false, *relfolder );
+      RelationalObjectTableRow 
+      row( objectTable.fetchRowAtTimeSV( (ValidityKey)3, 
+                                         (ChannelId)0 ) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "object_id", 2u, row.objectId() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "channel id", 0u, row.channelId() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "iov since", (ValidityKey)2, row.since() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "iov until", (ValidityKey)4, row.until() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "instime length", 
+          std::string("yyyy-mm-dd_hh:mm:ss.nnnnnnnnn GMT").size(), 
+          timeToString(row.insertionTime()).size() );    
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "field I", 2, row["I"].data<int>() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "field S", std::string("Object 2"), row["S"].data<std::string>() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "field X", 0.002f, row["X"].data<float>() );
+      transaction.commit();
+    } catch ( std::exception& e ) {
+      std::cout << "Exception caught: " << e.what() << std::endl;
+      throw;     
+    }
+  }
+  */
+
+  /*
+  /// Test for bug #16903 - all three backends fail with "No rows selected"
+  /// (Oracle with "ORA-01455: converting column overflows integer datatype")
+  void test_fetchRowAtTimeSV64bit() {
+    try {
+      IFolderPtr folder = ralDb->createFolder( "/myfolder", payloadSpec );
+      RelationalFolder* relfolder = 
+        dynamic_cast<RelationalFolder*>( folder.get() );
+      ValidityKey vk0 = ValidityKeyMax-10;
+      folder->setupStorageBuffer();
+      folder->storeObject( vk0, vk0+2, dummyPayload( 1 ), 0 );
+      folder->storeObject( vk0+2, vk0+4, dummyPayload( 2 ), 0 );
+      folder->flushStorageBuffer();
+      
+      RelationalTransaction transaction( ralDb->transactionMgr() );
+      RelationalObjectTable 
+        objectTable( &(ralDb->queryMgr()), false, *relfolder );
+      RelationalObjectTableRow 
+      row( objectTable.fetchRowAtTimeSV( vk0+3, (ChannelId)0 ) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "object_id", 2u, row.objectId() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "channel id", 0u, row.channelId() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "iov since", vk0+2, row.since() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "iov until", vk0+4, row.until() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "instime length", 
+          std::string("yyyy-mm-dd_hh:mm:ss.nnnnnnnnn GMT").size(), 
+          timeToString(row.insertionTime()).size() );    
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "field I", 2, row["I"].data<int>() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "field S", std::string("Object 2"), row["S"].data<std::string>() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "field X", 0.002f, row["X"].data<float>() );
+      transaction.commit();
+    } catch ( std::exception& e ) {
+      std::cout << "Exception caught: " << e.what() << std::endl;
+      throw;     
+    }
+  }
+  */
+  
+  /// Tests fetchRowForId
+  void test_fetchRowForId() {
+
+    try {
+      
+      IFolderPtr folder = ralDb->createFolder( "/myfolder", payloadSpec );
+      RelationalFolder* relfolder = 
+        dynamic_cast<RelationalFolder*>( folder.get() );    
+      
+      folder->setupStorageBuffer();
+      folder->storeObject( 0, 2, dummyPayload( 1 ), 0 );
+      folder->storeObject( 2, 4, dummyPayload( 2 ), 0 );
+      folder->flushStorageBuffer();
+      
+      unsigned int object_id = 1;
+      
+      RelationalTransaction transaction( ralDb->transactionMgr() );
+      RelationalObjectTable 
+        objectTable( &(ralDb->queryMgr()), false, *relfolder );
+      bool fetchPayload = true;
+      RelationalObjectTableRow 
+        row1( objectTable.fetchRowForId( object_id, fetchPayload ) );
+      fetchPayload = false;
+      RelationalObjectTableRow 
+        row2( objectTable.fetchRowForId( object_id, fetchPayload ) );
+      transaction.commit();
+      
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "object_id", 1u, row1.objectId() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "channel id", 0u, row1.channelId() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "iov since", (ValidityKey)0, row1.since() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "iov until", (ValidityKey)2, row1.until() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "NODE_INSTIME length",
+          std::string("yyyy-mm-dd_hh:mm:ss.nnnnnnnnn GMT").size(),
+          timeToString(row1.insertionTime()).size() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "field I", 1, row1["I"].data<int>() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "field S", std::string("Object 1"), row1["S"].data<std::string>() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "field X", 0.001f, row1["X"].data<float>() );
+      
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "object_id", 1u, row2.objectId() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "channel id", 0u, row2.channelId() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "iov since", (ValidityKey)0, row2.since() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "iov until", (ValidityKey)2, row2.until() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "NODE_INSTIME length",
+          std::string("yyyy-mm-dd_hh:mm:ss.nnnnnnnnn GMT").size(),
+          timeToString(row2.insertionTime()).size() );
+      
+      try { row2["I"]; CPPUNIT_FAIL( "row2[I] - no exception thrown" ); } 
+      catch ( coral::AttributeListException& ) {}
+      catch ( ... ) { CPPUNIT_FAIL( "row2[I] - unknown exception caught" ); }
+      
+      try { row2["S"]; CPPUNIT_FAIL( "row2[S] - no exception thrown" ); } 
+      catch ( coral::AttributeListException& ) {}
+      catch ( ... ) { CPPUNIT_FAIL( "row2[S] - unknown exception caught" ); }
+      
+      try { row2["X"]; CPPUNIT_FAIL( "row2[X] - no exception thrown" ); } 
+      catch ( coral::AttributeListException& ) {}
+      catch ( ... ) { CPPUNIT_FAIL( "row2[X] - unknown exception caught" ); }
+      
+    }
+    catch( std::exception& e ) {
+      std::cout << "Exception caught: " << e.what() << std::endl;
+      throw;
+    }  
+    
+  }
+  
+  
+  /*
+  /// Tests fetchLastRowSV
+  void test_fetchLastRowSV() {
+    IFolderPtr folder = 
+      ralDb->createFolder( "/myfolder", payloadSpec );
+    RelationalFolder* relfolder = 
+      dynamic_cast<RelationalFolder*>( folder.get() );
+    
+    folder->setupStorageBuffer();
+    folder->storeObject( 0, 2, dummyPayload( 0 ), 1 );
+    folder->storeObject( 2, 4, dummyPayload( 0 ), 1 );
+    
+    folder->storeObject( 0, 2, dummyPayload( 0 ), 2 );
+    folder->storeObject( 2, 4, dummyPayload( 0 ), 2 );
+    
+    folder->storeObject( 0, 2, dummyPayload( 0 ), 3 );
+    folder->storeObject( 2, 4, dummyPayload( 0 ), 3 );
+    
+    folder->storeObject( 4, 6, dummyPayload( 0 ), 1 );
+    folder->flushStorageBuffer();
+    
+    RelationalTransaction transaction( ralDb->transactionMgr() );
+    
+    {
+      RelationalObjectTable 
+        objectTable( &(ralDb->queryMgr()), false, *relfolder );
+      RelationalObjectTableRow 
+        row( objectTable.fetchLastRowSV( (ChannelId)1 ) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "first channel", 7u, row.objectId() );
+    }
+    
+    {
+      RelationalObjectTable 
+        objectTable( &(ralDb->queryMgr()), false, *relfolder );
+      RelationalObjectTableRow 
+        row( objectTable.fetchLastRowSV( (ChannelId)2 ) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "second channel", 4u, row.objectId() );
+    }
+    
+    {
+      RelationalObjectTable 
+        objectTable( &(ralDb->queryMgr()), false, *relfolder );
+      RelationalObjectTableRow 
+        row( objectTable.fetchLastRowSV( (ChannelId)3 ) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "third channel", 6u, row.objectId() );
+    }
+    
+    transaction.commit();
+  }
+  */
+
+  
+  /// Tests fetchRowForId for a directly stored row (not via the API)
+  void test_fetchRowForId_data() {
+    IFolderPtr folder = 
+    ralDb->createFolder( "/myfolder", payloadSpec );
+    RelationalFolder* relfolder = 
+      dynamic_cast<RelationalFolder*>( folder.get() );
+    
+    {
+      RelationalTransaction transaction( ralDb->transactionMgr() );
+      
+      coral::ITable& chTable = ralDb->session().nominalSchema().tableHandle
+        ( relfolder->channelTableName() );
+      RecordSpecification chSpec =
+        RelationalChannelTable::tableSpecification();
+      coral::AttributeList chData = Record( chSpec ).attributeList();
+      chData["CHANNEL_ID"].setValue( 2u );
+      chTable.dataEditor().insertRow( chData );
+
+      coral::ITable& table = ralDb->session().nominalSchema().tableHandle
+      ( relfolder->objectTableName() );
+      RecordSpecification spec =
+        RelationalObjectTable::tableSpecification( payloadSpec );
+      coral::AttributeList data = Record( spec ).attributeList();
+      data["OBJECT_ID"].setValue( 1u );
+      data["CHANNEL_ID"].setValue( 2u );
+      data["IOV_SINCE"].setValue( (ValidityKey)3 );
+      data["IOV_UNTIL"].setValue( (ValidityKey)4 );
+      data["USER_TAG_ID"].setValue( 5u );
+      std::string insertionTime = "2006-03-04_18:38:59.803342000 GMT";
+      data["SYS_INSTIME"].setValue( insertionTime );
+      data["ORIGINAL_ID"].setValue( 6u );
+      data["NEW_HEAD_ID"].setValue( 7u );
+      data["I"].setValue( 8 );
+      data["S"].setValue( std::string( "9" ) );
+      data["X"].setValue( 10.0f );      
+      table.dataEditor().insertRow( data );
+
+      transaction.commit();
+    }
+    {
+      RelationalTransaction transaction( ralDb->transactionMgr() );
+      RelationalObjectTable 
+        objectTable( &(ralDb->queryMgr()), false, *relfolder );
+      bool fetchPayload = true;
+      RelationalObjectTableRow 
+        row( objectTable.fetchRowForId( 1, fetchPayload ) );
+      transaction.commit();
+      
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "object_id", 1u, row.objectId() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "channel id", 2u, row.channelId() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "iov since", (ValidityKey)3, row.since() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "iov until", (ValidityKey)4, row.until() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "user_tag_id", 5u, row.userTagId() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( std::string("NODE_INSTIME"),
+          std::string("2006-03-04_18:38:59.803342000 GMT"),
+          timeToString(row.insertionTime()) );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "orignal id", 6u, row.originalId() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "new head id", 7u, row.newHeadId() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "field I", 8, row["I"].data<int>() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "field S", std::string("9"), 
+                                    row["S"].data<std::string>() );
+      CPPUNIT_ASSERT_EQUAL_MESSAGE( "field X", 10.0f, row["X"].data<float>() );
+    }
+  }
+  
+  
+  /*
+  /// Tests fetchRowsSV with a channel range and
+  /// since-before-channel ordering
+  void test_fetchRowsSV_channel_range_ordering() {
+    IFolderPtr folder = ralDb->createFolder( "/myfolder", payloadSpec );
+    RelationalFolder* relfolder = 
+      dynamic_cast<RelationalFolder*>( folder.get() );
+    
+    int index = 0;
+    folder->setupStorageBuffer();
+    for ( ChannelId ch = 0; ch < 5; ++ch ) {
+      folder->storeObject( 0, ValidityKeyMax, dummyPayload( index++ ), ch );
+      folder->storeObject( 1, ValidityKeyMax, dummyPayload( index++ ), ch );
+    }
+    folder->flushStorageBuffer();
+    
+    ChannelSelection channels( 2, 3, ChannelSelection::sinceBeforeChannel );
+    
+    RelationalTransaction transaction( ralDb->transactionMgr() );
+    RelationalObjectTable 
+      objectTable( &(ralDb->queryMgr()), false, *relfolder );
+    std::vector<RelationalObjectTableRow> rows =
+      objectTable.fetchRowsSV( relfolder->payloadSpecification(), 
+                               ValidityKeyMin, 
+                               ValidityKeyMax, 
+                               channels );
+    
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "size", 4, (int)rows.size() );
+    
+    RelationalObjectTableRow row = rows[0];
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "payload 0", 
+                                  std::string("Object 4"),
+                                  row["S"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "since 0", 
+                                  (ValidityKey)0, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "until 0", 
+                                  (ValidityKey)1, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "channel 0", 
+                                  (ChannelId)2, row.channelId() );
+    
+    row = rows[1];
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "payload 1", 
+                                  std::string("Object 6"),
+                                  row["S"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "since 1", 
+                                  (ValidityKey)0, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "until 1", 
+                                  (ValidityKey)1, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "channel 1", 
+                                  (ChannelId)3, row.channelId() );
+    
+    row = rows[2];
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "payload 2", 
+                                  std::string("Object 5"), 
+                                  row["S"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "since 2", 
+                                  (ValidityKey)1, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "until 2", 
+                                  ValidityKeyMax, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "channel 2", 
+                                  (ChannelId)2, row.channelId() );
+    
+    
+    row = rows[3];
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "payload 3", 
+                                  std::string("Object 7"), 
+                                  row["S"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "since 3", 
+                                  (ValidityKey)1, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "until 3", 
+                                  ValidityKeyMax, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "channel 3", 
+                                  (ChannelId)3, row.channelId() );
+    
+  }
+  
+  
+  
+  /// Tests fetchRowsSV with a channel range
+  void test_fetchRowsSV_channel_range() {
+    IFolderPtr folder = ralDb->createFolder( "/myfolder", payloadSpec );
+    RelationalFolder* relfolder = 
+      dynamic_cast<RelationalFolder*>( folder.get() );
+    
+    int index = 0;
+    folder->setupStorageBuffer();
+    for ( ChannelId ch = 0; ch < 5; ++ch ) {
+      folder->storeObject( 0, ValidityKeyMax, dummyPayload( index++ ), ch );
+      folder->storeObject( 1, ValidityKeyMax, dummyPayload( index++ ), ch );
+    }
+    folder->flushStorageBuffer();
+
+    ChannelSelection channels( 2, 3 );
+    
+    RelationalTransaction transaction( ralDb->transactionMgr() );
+    RelationalObjectTable 
+      objectTable( &(ralDb->queryMgr()), false, *relfolder );
+    std::vector<RelationalObjectTableRow> rows =
+      objectTable.fetchRowsSV( relfolder->payloadSpecification(), 
+                               ValidityKeyMin, 
+                               ValidityKeyMax, 
+                               channels );
+    
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "size", 4u, (unsigned int)rows.size() );
+    
+    RelationalObjectTableRow row = rows[0];
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "payload 0", 
+                                  std::string("Object 4"), 
+                                  row["S"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "since 0", 
+                                  (ValidityKey)0, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "until 0", 
+                                  (ValidityKey)1, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "channel 0", 
+                                  (ChannelId)2, row.channelId() );
+    
+    row = rows[1];
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "payload 1", 
+                                  std::string("Object 5"), 
+                                  row["S"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "since 1", 
+                                  (ValidityKey)1, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "until 1", 
+                                  ValidityKeyMax, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "channel 1", 
+                                  (ChannelId)2, row.channelId() );
+    
+    row = rows[2];
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "payload 2", 
+                                  std::string("Object 6"), 
+                                  row["S"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "since 2", 
+                                  (ValidityKey)0, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "until 2", 
+                                  (ValidityKey)1, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "channel 2", 
+                                  (ChannelId)3, row.channelId() );
+    
+    
+    row = rows[3];
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "payload 3", 
+                                  std::string("Object 7"), 
+                                  row["S"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "since 3", 
+                                  (ValidityKey)1, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "until 3", 
+                                  ValidityKeyMax, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "channel 3", 
+                                  (ChannelId)3, row.channelId() );
+    
+  }
+  
+  
+  
+  /// Tests fetchRowsSV of all channels
+  void test_fetchRowsSV_all_channels() {
+    IFolderPtr folder = ralDb->createFolder( "/myfolder", payloadSpec );
+    
+    int index = 0;
+    folder->setupStorageBuffer();
+    for ( ChannelId ch = 0; ch < 2; ++ch ) {
+      folder->storeObject( 0, ValidityKeyMax, dummyPayload( index++ ), ch );
+      folder->storeObject( 1, ValidityKeyMax, dummyPayload( index++ ), ch );
+    }
+    folder->flushStorageBuffer();
+    
+    RelationalFolder* relfolder = 
+      dynamic_cast<RelationalFolder*>(folder.get());
+
+    RelationalTransaction transaction( ralDb->transactionMgr() );    
+    RelationalObjectTable 
+      objectTable( &(ralDb->queryMgr()), false, *relfolder );
+    std::vector<RelationalObjectTableRow> rows =
+      objectTable.fetchRowsSV( relfolder->payloadSpecification(), 
+                               ValidityKeyMin, 
+                               ValidityKeyMax, 
+                               ChannelSelection::all() );
+    
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "size", 4, (int)rows.size() );
+    
+    RelationalObjectTableRow row = rows[0];
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "payload 0", 
+                                  std::string("Object 0"),
+                                  row["S"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "since 0", 
+                                  (ValidityKey)0, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "until 0", 
+                                  (ValidityKey)1, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "channel 0", 
+                                  (ChannelId)0, row.channelId() );
+    
+    row = rows[1];
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "payload 1", 
+                                  std::string("Object 1"), 
+                                  row["S"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "since 1", 
+                                  (ValidityKey)1, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "until 1", 
+                                  ValidityKeyMax, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "channel 1", 
+                                  (ChannelId)0, row.channelId() );
+    
+    row = rows[2];
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "payload 2", 
+                                  std::string("Object 2"), 
+                                  row["S"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "since 2", 
+                                  (ValidityKey)0, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "until 2", 
+                                  (ValidityKey)1, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "channel 2", 
+                                  (ChannelId)1, row.channelId() );
+    
+    
+    row = rows[3];
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "payload 3", 
+                                  std::string("Object 3"), 
+                                  row["S"].data<std::string>() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "since 3", 
+                                  (ValidityKey)1, row.since() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "until 3", 
+                                  ValidityKeyMax, row.until() );
+    CPPUNIT_ASSERT_EQUAL_MESSAGE( "channel 3", 
+                                  (ChannelId)1, row.channelId() );
+    
+  }  
+  */
+    
+  /// Utility method to generate a distinct payload for a given index
+  Record dummyPayload( int index ) 
+  {
+    Record payload( payloadSpec );
+    payload["I"].setValue<Int32>( index );
+    std::stringstream s;
+    s << "Object " << index;
+    payload["S"].setValue<String255>( s.str() );
+    payload["X"].setValue<Float>( (float)(index/1000.) );
+    return payload;
+  }
+  
+  RelationalObjectTableTest() 
+    : payloadSpec() 
+  {    
+    payloadSpec.extend("I",StorageType::Int32);
+    payloadSpec.extend("S",StorageType::String255);
+    payloadSpec.extend("X",StorageType::Float);
+    
+    if ( getenv( COOLTESTDB ) ) {
+      m_connectionString = getenv( COOLTESTDB );
+    } else {
+      std::cout 
+        << "Please provide a connect string by "
+        << "specifying one in the environment variable COOLTESTDB, e.g." 
+        << std::endl;
+      std::cout 
+        << "setenv COOLTESTDB "
+        << "\"oracle://devdb10;schema=lcg_cool;dbname=COOLTEST\"" << std::endl;
+      std::cout << "Aborting test" << std::endl;
+      exit(-1);
+    }
+  }
+  
+  void setUp() 
+  {
+    createDB();
+    openDB();
+    ralDb = dynamic_cast<RalDatabase*>(m_db.get());
+  }
+  
+  void tearDown() 
+  {
+    forceDisconnect();
+  }
+  
+};
+
+CPPUNIT_TEST_SUITE_REGISTRATION( cool::RelationalObjectTableTest );
+
+//-----------------------------------------------------------------------------
+
+COOLTEST_MAIN(RelationalObjectTableTest)
+
diff --git a/RelationalCool/tests/SchemaDump/coolSchemaDump.csh b/RelationalCool/tests/SchemaDump/coolSchemaDump.csh
new file mode 100755
index 000000000..eb8098477
--- /dev/null
+++ b/RelationalCool/tests/SchemaDump/coolSchemaDump.csh
@@ -0,0 +1,150 @@
+#!/bin/csh -f
+
+#---------------------------------------------------------------------------
+# NB: Make sure $HOME/private/authentication.xml contains YOUR credentials!
+#---------------------------------------------------------------------------
+
+# The path ${HOME}/private/authentication.xml is set in seal.opts.error
+if ( ! -f ${HOME}/private/authentication.xml ) then
+  echo "ERROR! File ${HOME}/private/authentication.xml not found!"
+  exit 1
+endif
+
+#-----------------------------------------------------------------------------
+
+if ( "$1" == "" || "$2" != "" ) then
+  echo Usage: $0 dbId
+  echo Example: $0 '"oracle://devdb10;schema=lcg_cool;dbname=COOL_REF"';
+  #echo Example: $0 '"mysql://SERVER;schema=SCHEMA;dbname=DB"';
+  exit 1
+endif
+
+unsetenv ORACLE_HOME
+unsetenv SCRAM_HOME
+setenv PATH /afs/cern.ch/sw/lcg/app/spi/scram:"${PATH}"
+
+eval `scram runtime -csh`
+setenv TNS_ADMIN ${LOCALRT}/src/RelationalCool/tests
+setenv SEAL_CONFIGURATION_FILE ${LOCALRT}/src/RelationalCool/tests/seal.opts.error
+
+#-----------------------------------------------------------------------------
+# 1. Create reference schema
+
+#setenv COOLTESTDB "$1"
+#unitTest_RelationalCool_SchemaDump 
+
+#-----------------------------------------------------------------------------
+# 2. Dump reference schema
+
+set theAuth = `coolAuthentication "$1" | & grep '==>'`
+set theAuth = `echo "$theAuth ==>"`
+#echo "theAuth   = $theAuth"
+
+set theUrl = `echo "$theAuth" | awk '{str=$0; sep="==> urlHidePswd = "; ind=index(str,sep)+length(sep); str=substr(str,ind); sep=" ==>"; ind=index(str,sep)-1; print substr(str,0,ind);};'`
+#echo "theUrl    = $theUrl"
+
+if ( "$theUrl" == "" ) then
+  echo "ERROR! Could not dump schema for COOL database "\""$1"\"
+  echo "ERROR! Invalid COOL databaseId or missing authentication credentials"
+  exit 1
+endif
+
+echo Dump schema for COOL database \""$theUrl"\"
+
+set theTech = `echo "$theAuth" | awk '{str=$0; sep="==> technology = "; ind=index(str,sep)+length(sep); str=substr(str,ind); sep=" ==>"; ind=index(str,sep)-1; print substr(str,0,ind);};'`
+set theHost = `echo "$theAuth" | awk '{str=$0; sep="==> server = "; ind=index(str,sep)+length(sep); str=substr(str,ind); sep=" ==>"; ind=index(str,sep)-1; print substr(str,0,ind);};'`
+set theSchema = `echo "$theAuth" | awk '{str=$0; sep="==> schema = "; ind=index(str,sep)+length(sep); str=substr(str,ind); sep=" ==>"; ind=index(str,sep)-1; print substr(str,0,ind);};'`
+set theUser = `echo "$theAuth" | awk '{str=$0; sep="==> user = "; ind=index(str,sep)+length(sep); str=substr(str,ind); sep=" ==>"; ind=index(str,sep)-1; print substr(str,0,ind);};'`
+set thePswd = `echo "$theAuth" | awk '{str=$0; sep="==> password = "; ind=index(str,sep)+length(sep); str=substr(str,ind); sep=" ==>"; ind=index(str,sep)-1; print substr(str,0,ind);};'`
+set theDbName = `echo "$theAuth" | awk '{str=$0; sep="==> dbname = "; ind=index(str,sep)+length(sep); str=substr(str,ind); sep=" ==>"; ind=index(str,sep)-1; print substr(str,0,ind);};'`
+
+#echo "theTech   = $theTech"
+#echo "theHost   = $theHost"
+#echo "theSchema = $theSchema"
+#echo "theUser   = $theUser"
+#echo "thePswd   = $thePswd"
+#echo "theDbName = $theDbName"
+#exit
+
+#--------
+# Oracle
+#--------
+if ( "$theTech" == "oracle" ) then
+
+  set theScript = `which $0`
+  set theSqlDir = `dirname ${theScript}`/sql
+  #echo "theScript = $theScript"
+  #echo "theSqlDir = $theSqlDir"
+
+  # HACK on Windows (limit to the size of file names)
+  pushd $theSqlDir > /dev/null
+  set theSqlDir = .
+  #echo "theSqlDir = $theSqlDir"
+
+  # No special treatment is needed for the user/password@host:port/service 
+  # syntax: this is supported out-of-the-box by Oracle EasyConnect
+
+  set theSchema = `echo $theSchema | awk '{print toupper($1)}'`
+  set theDbName = `echo $theDbName | awk '{print toupper($1)}'`
+  ###echo Dump Oracle schema
+
+  #set theHtml = "OFF"
+  set theHtml = "ON"
+
+  if ( "$theHtml" == "ON" ) then
+    set theOutFile = oracleRefSchema.html
+    set theOut = `cd ..; pwd`/$theOutFile
+    \rm -f ${theOut}
+    echo Results will be in ${theOut}
+    echo "<center><h1>" > ${theOut}
+    echo Schema for COOL database \""$theUrl"\" >> ${theOut}
+    echo "</h1></center><br>" >> ${theOut}
+  else
+    set theOut = /dev/stdout
+  endif
+  sqlplus -S -L -M "HTML ${theHtml}" ${theUser}/${thePswd}@${theHost} @${theSqlDir}/oracleSchemaDump.sql ${theSchema} ${theDbName} | grep -v "rows selected" >> ${theOut}
+
+  set theTables = `sqlplus -S -L ${theUser}/${thePswd}@${theHost} @${theSqlDir}/oracleShowTables.sql ${theSchema} ${theDbName} | grep ${theDbName}_`
+  #echo "theTables = $theTables"
+  foreach aTable ( $theTables )
+    #echo Describe Oracle table ${aTable}
+    sqlplus -S -L -M "HTML ${theHtml}" ${theUser}/${thePswd}@${theHost} @${theSqlDir}/oracleDescTable.sql ${aTable} "${theSchema}.${aTable}" >> ${theOut}
+  end
+
+  # Copy the results in a directory visible from the Web
+  if ( "${USER}" == "avalassi" ) then
+    \cp ${theOut} ~/myLCG/www/tmp/${theOutFile}
+    echo "Results can be browsed on"
+    echo "  http://lcgapp.cern.ch/project/CondDB/tmp/${theOutFile}"
+  endif
+
+  # HACK on Windows 
+  popd > /dev/null
+
+#-------
+# MySQL
+#-------
+else if ( "$theTech" == "mysql" ) then
+
+  # A special treatment is needed for the host:port syntax: 
+  # the port number must be parsed out and passed explicitly
+  set thePort = `echo "$theHost" | awk '{str=$0; sep=":"; ind=index(str,sep); if (ind>0) print "-P" substr(str,ind+length(sep)); else print "";};'`
+  set theHost = `echo "$theHost" | awk '{str=$0; sep=":"; ind=index(str,sep); if (ind>0) print substr(str,0,ind-length(sep)); else print str;};'`
+  #echo "theHost   = $theHost"
+  #echo "thePort   = $thePort"
+
+  ###echo Dump MySQL schema
+  #mysql -u${theUser} -p${thePswd} -h${theHost} ${thePort} ${theSchema} -e "drop table ${aTable};"
+  echo NOT YET SUPPORTED
+
+#--------
+# SQLite
+#--------
+else if ( "$theTech" == "sqlite" ) then
+
+  ###echo Dump SQLite schema
+  echo NOT YET SUPPORTED
+
+endif
+
+
diff --git a/RelationalCool/tests/SchemaDump/oracleRefSchema.html b/RelationalCool/tests/SchemaDump/oracleRefSchema.html
new file mode 100644
index 000000000..ea9f638bc
--- /dev/null
+++ b/RelationalCool/tests/SchemaDump/oracleRefSchema.html
@@ -0,0 +1,2377 @@
+<center><h1>
+Schema for COOL database "oracle://devdb10;schema=lcg_cool;dbname=COOL_REF"
+</h1></center><br>
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-9">
+<meta name="generator" content="SQL*Plus 10.2.0">
+<style type='text/css'> body {font:10pt Arial,Helvetica,sans-serif; color:black; background:White;} p {font:10pt Arial,Helvetica,sans-serif; color:black; background:White;} table,tr,td {font:10pt Arial,Helvetica,sans-serif; color:Black; background:#f7f7e7; padding:0px 0px 0px 0px; margin:0px 0px 0px 0px;} th {font:bold 10pt Arial,Helvetica,sans-serif; color:#336699; background:#cccc99; padding:0px 0px 0px 0px;} h1 {font:16pt Arial,Helvetica,Geneva,sans-serif; color:#336699; background-color:White; border-bottom:1px solid #cccc99; margin-top:0pt; margin-bottom:0pt; padding:0px 0px 0px 0px;} h2 {font:bold 10pt Arial,Helvetica,Geneva,sans-serif; color:#336699; background-color:White; margin-top:4pt; margin-bottom:0pt;} a {font:9pt Arial,Helvetica,sans-serif; color:#663300; background:#ffffff; margin-top:0pt; margin-bottom:0pt; vertical-align:top;}</style><title>SQL*Plus Report</title>
+</head>
+<body>
+
+<h2>TABLES</h2>
+<br>
+<p>
+<table border='1' width='90%' align='center' summary='Script output'>
+<tr>
+<th scope="col">
+TABLE_NAME
+</th>
+</tr>
+<tr>
+<td>
+COOL_REF_DB_ATTRIBUTES
+</td>
+</tr>
+<tr>
+<td>
+COOL_REF_NODES
+</td>
+</tr>
+<tr>
+<td>
+COOL_REF_NODES_SEQ
+</td>
+</tr>
+<tr>
+<td>
+COOL_REF_TAGS
+</td>
+</tr>
+<tr>
+<td>
+COOL_REF_F0002_IOVS
+</td>
+</tr>
+<tr>
+<td>
+COOL_REF_F0002_IOVS_SEQ
+</td>
+</tr>
+<tr>
+<td>
+COOL_REF_F0003_IOV2TAG
+</td>
+</tr>
+<tr>
+<td>
+COOL_REF_F0003_IOVS
+</td>
+</tr>
+<tr>
+<td>
+COOL_REF_F0003_IOVS_SEQ
+</td>
+</tr>
+<tr>
+<td>
+COOL_REF_F0003_TAGS
+</td>
+</tr>
+<tr>
+<td>
+COOL_REF_F0003_TAGS_SEQ
+</td>
+</tr>
+</table>
+<p>
+
+<br>
+
+
+<h2>INDEXES</h2>
+<br>
+<p>
+<table border='1' width='90%' align='center' summary='Script output'>
+<tr>
+<th scope="col">
+TABLE_NAME
+</th>
+<th scope="col">
+INDEX_NAME
+</th>
+<th scope="col">
+UNIQUENES
+</th>
+</tr>
+<tr>
+<td>
+COOL_REF_DB_ATTRIBUTES
+</td>
+<td>
+COOL_REF_DB_ATTRIBUTES_PK
+</td>
+<td>
+UNIQUE
+</td>
+</tr>
+<tr>
+<td>
+COOL_REF_NODES
+</td>
+<td>
+COOL_REF_NODES_PK
+</td>
+<td>
+UNIQUE
+</td>
+</tr>
+<tr>
+<td>
+COOL_REF_NODES_SEQ
+</td>
+<td>
+COOL_REF_NODES_SEQ_PK
+</td>
+<td>
+UNIQUE
+</td>
+</tr>
+<tr>
+<td>
+COOL_REF_TAGS
+</td>
+<td>
+COOL_REF_TAGS_PK
+</td>
+<td>
+UNIQUE
+</td>
+</tr>
+<tr>
+<td>
+COOL_REF_F0002_IOVS
+</td>
+<td>
+COOL_REF_F0002_IOVS_CO_2INDX
+</td>
+<td>
+NONUNIQUE
+</td>
+</tr>
+<tr>
+<td>
+COOL_REF_F0002_IOVS
+</td>
+<td>
+COOL_REF_F0002_IOVS_CSU_3INDX
+</td>
+<td>
+NONUNIQUE
+</td>
+</tr>
+<tr>
+<td>
+COOL_REF_F0002_IOVS
+</td>
+<td>
+COOL_REF_F0002_IOVS_PK
+</td>
+<td>
+UNIQUE
+</td>
+</tr>
+<tr>
+<td>
+COOL_REF_F0002_IOVS_SEQ
+</td>
+<td>
+COOL_REF_F0002_IOVS_SEQ_PK
+</td>
+<td>
+UNIQUE
+</td>
+</tr>
+<tr>
+<td>
+COOL_REF_F0003_IOVS
+</td>
+<td>
+COOL_REF_F0003_IOVS_CO_2INDX
+</td>
+<td>
+NONUNIQUE
+</td>
+</tr>
+<tr>
+<td>
+COOL_REF_F0003_IOVS
+</td>
+<td>
+COOL_REF_F0003_IOVS_CSU_3INDX
+</td>
+<td>
+NONUNIQUE
+</td>
+</tr>
+<tr>
+<td>
+COOL_REF_F0003_IOVS
+</td>
+<td>
+COOL_REF_F0003_IOVS_PK
+</td>
+<td>
+UNIQUE
+</td>
+</tr>
+<tr>
+<td>
+COOL_REF_F0003_IOV2TAG
+</td>
+<td>
+COOL_REF_F0003_IOV2TAG_4INDX
+</td>
+<td>
+NONUNIQUE
+</td>
+</tr>
+<tr>
+<td>
+COOL_REF_F0003_IOV2TAG
+</td>
+<td>
+COOL_REF_F0003_IOV2TAG_PK
+</td>
+<td>
+UNIQUE
+</td>
+</tr>
+<tr>
+<td>
+COOL_REF_F0003_IOVS
+</td>
+<td>
+COOL_REF_F0003_IOVS_OCSU_4INDX
+</td>
+<td>
+UNIQUE
+</td>
+</tr>
+<tr>
+<td>
+COOL_REF_F0003_IOVS_SEQ
+</td>
+<td>
+COOL_REF_F0003_IOVS_SEQ_PK
+</td>
+<td>
+UNIQUE
+</td>
+</tr>
+<tr>
+<td>
+COOL_REF_F0003_TAGS
+</td>
+<td>
+COOL_REF_F0003_TAGS_PK
+</td>
+<td>
+UNIQUE
+</td>
+</tr>
+<tr>
+<td>
+COOL_REF_F0003_TAGS_SEQ
+</td>
+<td>
+COOL_REF_F0003_TAGS_SEQ_PK
+</td>
+<td>
+UNIQUE
+</td>
+</tr>
+</table>
+<p>
+
+<br>
+
+
+<h2>CONSTRAINTS</h2>
+<br>
+<p>
+<table border='1' width='90%' align='center' summary='Script output'>
+<tr>
+<th scope="col">
+TABLE_NAME
+</th>
+<th scope="col">
+CONSTRAINT_NAME
+</th>
+<th scope="col">
+TYPE
+</th>
+<th scope="col">
+R_CONSTRAINT_NAME
+</th>
+<th scope="col">
+INDEX_NAME
+</th>
+</tr>
+<tr>
+<td>
+COOL_REF_DB_ATTRIBUTES
+</td>
+<td>
+COOL_REF_DB_ATTRIBUTES_PK
+</td>
+<td>
+P
+</td>
+<td>
+&nbsp;
+</td>
+<td>
+COOL_REF_DB_ATTRIBUTES_PK
+</td>
+</tr>
+<tr>
+<td>
+COOL_REF_NODES
+</td>
+<td>
+COOL_REF_NODES_PK
+</td>
+<td>
+P
+</td>
+<td>
+&nbsp;
+</td>
+<td>
+COOL_REF_NODES_PK
+</td>
+</tr>
+<tr>
+<td>
+COOL_REF_NODES_SEQ
+</td>
+<td>
+COOL_REF_NODES_SEQ_PK
+</td>
+<td>
+P
+</td>
+<td>
+&nbsp;
+</td>
+<td>
+COOL_REF_NODES_SEQ_PK
+</td>
+</tr>
+<tr>
+<td>
+COOL_REF_TAGS
+</td>
+<td>
+COOL_REF_TAGS_PK
+</td>
+<td>
+P
+</td>
+<td>
+&nbsp;
+</td>
+<td>
+COOL_REF_TAGS_PK
+</td>
+</tr>
+<tr>
+<td>
+COOL_REF_F0002_IOVS
+</td>
+<td>
+COOL_REF_F0002_IOVS_PK
+</td>
+<td>
+P
+</td>
+<td>
+&nbsp;
+</td>
+<td>
+COOL_REF_F0002_IOVS_PK
+</td>
+</tr>
+<tr>
+<td>
+COOL_REF_F0002_IOVS_SEQ
+</td>
+<td>
+COOL_REF_F0002_IOVS_SEQ_PK
+</td>
+<td>
+P
+</td>
+<td>
+&nbsp;
+</td>
+<td>
+COOL_REF_F0002_IOVS_SEQ_PK
+</td>
+</tr>
+<tr>
+<td>
+COOL_REF_F0003_IOVS
+</td>
+<td>
+COOL_REF_F0003_IOVS_PK
+</td>
+<td>
+P
+</td>
+<td>
+&nbsp;
+</td>
+<td>
+COOL_REF_F0003_IOVS_PK
+</td>
+</tr>
+<tr>
+<td>
+COOL_REF_F0003_IOV2TAG
+</td>
+<td>
+COOL_REF_F0003_IOV2TAG_PK
+</td>
+<td>
+P
+</td>
+<td>
+&nbsp;
+</td>
+<td>
+COOL_REF_F0003_IOV2TAG_PK
+</td>
+</tr>
+<tr>
+<td>
+COOL_REF_F0003_IOVS_SEQ
+</td>
+<td>
+COOL_REF_F0003_IOVS_SEQ_PK
+</td>
+<td>
+P
+</td>
+<td>
+&nbsp;
+</td>
+<td>
+COOL_REF_F0003_IOVS_SEQ_PK
+</td>
+</tr>
+<tr>
+<td>
+COOL_REF_F0003_TAGS
+</td>
+<td>
+COOL_REF_F0003_TAGS_PK
+</td>
+<td>
+P
+</td>
+<td>
+&nbsp;
+</td>
+<td>
+COOL_REF_F0003_TAGS_PK
+</td>
+</tr>
+<tr>
+<td>
+COOL_REF_F0003_TAGS_SEQ
+</td>
+<td>
+COOL_REF_F0003_TAGS_SEQ_PK
+</td>
+<td>
+P
+</td>
+<td>
+&nbsp;
+</td>
+<td>
+COOL_REF_F0003_TAGS_SEQ_PK
+</td>
+</tr>
+<tr>
+<td>
+COOL_REF_NODES
+</td>
+<td>
+COOL_REF_NODES_PARENT_FK
+</td>
+<td>
+R
+</td>
+<td>
+COOL_REF_NODES_PK
+</td>
+<td>
+&nbsp;
+</td>
+</tr>
+<tr>
+<td>
+COOL_REF_F0003_IOV2TAG
+</td>
+<td>
+COOL_REF_F0003_IOV2TAG_O_FK
+</td>
+<td>
+R
+</td>
+<td>
+COOL_REF_F0003_IOVS_PK
+</td>
+<td>
+&nbsp;
+</td>
+</tr>
+<tr>
+<td>
+COOL_REF_F0003_IOV2TAG
+</td>
+<td>
+COOL_REF_F0003_IOV2TAG_T_FK
+</td>
+<td>
+R
+</td>
+<td>
+COOL_REF_F0003_TAGS_PK
+</td>
+<td>
+&nbsp;
+</td>
+</tr>
+</table>
+<p>
+
+<br>
+
+
+<h2>INDEXED COLUMNS</h2>
+<br>
+<p>
+<table border='1' width='90%' align='center' summary='Script output'>
+<tr>
+<th scope="col">
+TABLE_NAME
+</th>
+<th scope="col">
+INDEX_NAME
+</th>
+<th scope="col">
+COL_NAME
+</th>
+<th scope="col">
+COL_POS
+</th>
+<th scope="col">
+DESC
+</th>
+</tr>
+<tr>
+<td>
+COOL_REF_DB_ATTRIBUTES
+</td>
+<td>
+COOL_REF_DB_ATTRIBUTES_PK
+</td>
+<td>
+DB_ATTRIBUTE_NAME
+</td>
+<td align="right">
+	 1
+</td>
+<td>
+ASC
+</td>
+</tr>
+<tr>
+<td>
+COOL_REF_NODES
+</td>
+<td>
+COOL_REF_NODES_PK
+</td>
+<td>
+NODE_ID
+</td>
+<td align="right">
+	 1
+</td>
+<td>
+ASC
+</td>
+</tr>
+<tr>
+<td>
+COOL_REF_NODES_SEQ
+</td>
+<td>
+COOL_REF_NODES_SEQ_PK
+</td>
+<td>
+SEQUENCE_NAME
+</td>
+<td align="right">
+	 1
+</td>
+<td>
+ASC
+</td>
+</tr>
+<tr>
+<td>
+COOL_REF_TAGS
+</td>
+<td>
+COOL_REF_TAGS_PK
+</td>
+<td>
+TAG_ID
+</td>
+<td align="right">
+	 1
+</td>
+<td>
+ASC
+</td>
+</tr>
+<tr>
+<td>
+COOL_REF_TAGS
+</td>
+<td>
+COOL_REF_TAGS_PK
+</td>
+<td>
+NODE_ID
+</td>
+<td align="right">
+	 2
+</td>
+<td>
+ASC
+</td>
+</tr>
+<tr>
+<td>
+COOL_REF_F0002_IOVS
+</td>
+<td>
+COOL_REF_F0002_IOVS_CO_2INDX
+</td>
+<td>
+CHANNEL_ID
+</td>
+<td align="right">
+	 1
+</td>
+<td>
+ASC
+</td>
+</tr>
+<tr>
+<td>
+COOL_REF_F0002_IOVS
+</td>
+<td>
+COOL_REF_F0002_IOVS_CO_2INDX
+</td>
+<td>
+OBJECT_ID
+</td>
+<td align="right">
+	 2
+</td>
+<td>
+ASC
+</td>
+</tr>
+<tr>
+<td>
+COOL_REF_F0002_IOVS
+</td>
+<td>
+COOL_REF_F0002_IOVS_CSU_3INDX
+</td>
+<td>
+CHANNEL_ID
+</td>
+<td align="right">
+	 1
+</td>
+<td>
+ASC
+</td>
+</tr>
+<tr>
+<td>
+COOL_REF_F0002_IOVS
+</td>
+<td>
+COOL_REF_F0002_IOVS_CSU_3INDX
+</td>
+<td>
+IOV_SINCE
+</td>
+<td align="right">
+	 2
+</td>
+<td>
+ASC
+</td>
+</tr>
+<tr>
+<td>
+COOL_REF_F0002_IOVS
+</td>
+<td>
+COOL_REF_F0002_IOVS_CSU_3INDX
+</td>
+<td>
+IOV_UNTIL
+</td>
+<td align="right">
+	 3
+</td>
+<td>
+ASC
+</td>
+</tr>
+<tr>
+<td>
+COOL_REF_F0002_IOVS
+</td>
+<td>
+COOL_REF_F0002_IOVS_PK
+</td>
+<td>
+OBJECT_ID
+</td>
+<td align="right">
+	 1
+</td>
+<td>
+ASC
+</td>
+</tr>
+<tr>
+<td>
+COOL_REF_F0002_IOVS_SEQ
+</td>
+<td>
+COOL_REF_F0002_IOVS_SEQ_PK
+</td>
+<td>
+SEQUENCE_NAME
+</td>
+<td align="right">
+	 1
+</td>
+<td>
+ASC
+</td>
+</tr>
+<tr>
+<td>
+COOL_REF_F0003_IOVS
+</td>
+<td>
+COOL_REF_F0003_IOVS_CO_2INDX
+</td>
+<td>
+CHANNEL_ID
+</td>
+<td align="right">
+	 1
+</td>
+<td>
+ASC
+</td>
+</tr>
+<tr>
+<td>
+COOL_REF_F0003_IOVS
+</td>
+<td>
+COOL_REF_F0003_IOVS_CO_2INDX
+</td>
+<td>
+OBJECT_ID
+</td>
+<td align="right">
+	 2
+</td>
+<td>
+ASC
+</td>
+</tr>
+<tr>
+<td>
+COOL_REF_F0003_IOVS
+</td>
+<td>
+COOL_REF_F0003_IOVS_CSU_3INDX
+</td>
+<td>
+CHANNEL_ID
+</td>
+<td align="right">
+	 1
+</td>
+<td>
+ASC
+</td>
+</tr>
+<tr>
+<td>
+COOL_REF_F0003_IOVS
+</td>
+<td>
+COOL_REF_F0003_IOVS_CSU_3INDX
+</td>
+<td>
+IOV_SINCE
+</td>
+<td align="right">
+	 2
+</td>
+<td>
+ASC
+</td>
+</tr>
+<tr>
+<td>
+COOL_REF_F0003_IOVS
+</td>
+<td>
+COOL_REF_F0003_IOVS_CSU_3INDX
+</td>
+<td>
+IOV_UNTIL
+</td>
+<td align="right">
+	 3
+</td>
+<td>
+ASC
+</td>
+</tr>
+<tr>
+<td>
+COOL_REF_F0003_IOVS
+</td>
+<td>
+COOL_REF_F0003_IOVS_PK
+</td>
+<td>
+OBJECT_ID
+</td>
+<td align="right">
+	 1
+</td>
+<td>
+ASC
+</td>
+</tr>
+<tr>
+<td>
+COOL_REF_F0003_IOV2TAG
+</td>
+<td>
+COOL_REF_F0003_IOV2TAG_4INDX
+</td>
+<td>
+TAG_ID
+</td>
+<td align="right">
+	 1
+</td>
+<td>
+ASC
+</td>
+</tr>
+<tr>
+<td>
+COOL_REF_F0003_IOV2TAG
+</td>
+<td>
+COOL_REF_F0003_IOV2TAG_4INDX
+</td>
+<td>
+CHANNEL_ID
+</td>
+<td align="right">
+	 2
+</td>
+<td>
+ASC
+</td>
+</tr>
+<tr>
+<td>
+COOL_REF_F0003_IOV2TAG
+</td>
+<td>
+COOL_REF_F0003_IOV2TAG_4INDX
+</td>
+<td>
+IOV_SINCE
+</td>
+<td align="right">
+	 3
+</td>
+<td>
+ASC
+</td>
+</tr>
+<tr>
+<td>
+COOL_REF_F0003_IOV2TAG
+</td>
+<td>
+COOL_REF_F0003_IOV2TAG_4INDX
+</td>
+<td>
+IOV_UNTIL
+</td>
+<td align="right">
+	 4
+</td>
+<td>
+ASC
+</td>
+</tr>
+<tr>
+<td>
+COOL_REF_F0003_IOV2TAG
+</td>
+<td>
+COOL_REF_F0003_IOV2TAG_PK
+</td>
+<td>
+TAG_ID
+</td>
+<td align="right">
+	 1
+</td>
+<td>
+ASC
+</td>
+</tr>
+<tr>
+<td>
+COOL_REF_F0003_IOV2TAG
+</td>
+<td>
+COOL_REF_F0003_IOV2TAG_PK
+</td>
+<td>
+OBJECT_ID
+</td>
+<td align="right">
+	 2
+</td>
+<td>
+ASC
+</td>
+</tr>
+<tr>
+<td>
+COOL_REF_F0003_IOVS
+</td>
+<td>
+COOL_REF_F0003_IOVS_OCSU_4INDX
+</td>
+<td>
+OBJECT_ID
+</td>
+<td align="right">
+	 1
+</td>
+<td>
+ASC
+</td>
+</tr>
+<tr>
+<td>
+COOL_REF_F0003_IOVS
+</td>
+<td>
+COOL_REF_F0003_IOVS_OCSU_4INDX
+</td>
+<td>
+CHANNEL_ID
+</td>
+<td align="right">
+	 2
+</td>
+<td>
+ASC
+</td>
+</tr>
+<tr>
+<td>
+COOL_REF_F0003_IOVS
+</td>
+<td>
+COOL_REF_F0003_IOVS_OCSU_4INDX
+</td>
+<td>
+IOV_SINCE
+</td>
+<td align="right">
+	 3
+</td>
+<td>
+ASC
+</td>
+</tr>
+<tr>
+<td>
+COOL_REF_F0003_IOVS
+</td>
+<td>
+COOL_REF_F0003_IOVS_OCSU_4INDX
+</td>
+<td>
+IOV_UNTIL
+</td>
+<td align="right">
+	 4
+</td>
+<td>
+ASC
+</td>
+</tr>
+<tr>
+<td>
+COOL_REF_F0003_IOVS_SEQ
+</td>
+<td>
+COOL_REF_F0003_IOVS_SEQ_PK
+</td>
+<td>
+SEQUENCE_NAME
+</td>
+<td align="right">
+	 1
+</td>
+<td>
+ASC
+</td>
+</tr>
+<tr>
+<td>
+COOL_REF_F0003_TAGS
+</td>
+<td>
+COOL_REF_F0003_TAGS_PK
+</td>
+<td>
+TAG_ID
+</td>
+<td align="right">
+	 1
+</td>
+<td>
+ASC
+</td>
+</tr>
+<tr>
+<td>
+COOL_REF_F0003_TAGS_SEQ
+</td>
+<td>
+COOL_REF_F0003_TAGS_SEQ_PK
+</td>
+<td>
+SEQUENCE_NAME
+</td>
+<td align="right">
+	 1
+</td>
+<td>
+ASC
+</td>
+</tr>
+</table>
+<p>
+
+<br>
+
+
+<h2>FOREIGN KEY COLUMNS</h2>
+<br>
+<p>
+<table border='1' width='90%' align='center' summary='Script output'>
+<tr>
+<th scope="col">
+TABLE_NAME
+</th>
+<th scope="col">
+CONSTRAINT_NAME
+</th>
+<th scope="col">
+R_CONSTRAINT_NAME
+</th>
+<th scope="col">
+COL_NAME
+</th>
+<th scope="col">
+COL_POS
+</th>
+<th scope="col">
+R_COL_NAME
+</th>
+<th scope="col">
+R_COL_POS
+</th>
+</tr>
+<tr>
+<td>
+COOL_REF_NODES
+</td>
+<td>
+COOL_REF_NODES_PARENT_FK
+</td>
+<td>
+COOL_REF_NODES_PK
+</td>
+<td>
+NODE_PARENTID
+</td>
+<td align="right">
+	 1
+</td>
+<td>
+NODE_ID
+</td>
+<td align="right">
+	 1
+</td>
+</tr>
+<tr>
+<td>
+COOL_REF_F0003_IOV2TAG
+</td>
+<td>
+COOL_REF_F0003_IOV2TAG_O_FK
+</td>
+<td>
+COOL_REF_F0003_IOVS_PK
+</td>
+<td>
+OBJECT_ID
+</td>
+<td align="right">
+	 1
+</td>
+<td>
+OBJECT_ID
+</td>
+<td align="right">
+	 1
+</td>
+</tr>
+<tr>
+<td>
+COOL_REF_F0003_IOV2TAG
+</td>
+<td>
+COOL_REF_F0003_IOV2TAG_T_FK
+</td>
+<td>
+COOL_REF_F0003_TAGS_PK
+</td>
+<td>
+TAG_ID
+</td>
+<td align="right">
+	 1
+</td>
+<td>
+TAG_ID
+</td>
+<td align="right">
+	 1
+</td>
+</tr>
+</table>
+<p>
+
+<br><hr><br>
+<br>
+</body>
+</html>
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-9">
+<meta name="generator" content="SQL*Plus 10.2.0">
+<style type='text/css'> body {font:10pt Arial,Helvetica,sans-serif; color:black; background:White;} p {font:10pt Arial,Helvetica,sans-serif; color:black; background:White;} table,tr,td {font:10pt Arial,Helvetica,sans-serif; color:Black; background:#f7f7e7; padding:0px 0px 0px 0px; margin:0px 0px 0px 0px;} th {font:bold 10pt Arial,Helvetica,sans-serif; color:#336699; background:#cccc99; padding:0px 0px 0px 0px;} h1 {font:16pt Arial,Helvetica,Geneva,sans-serif; color:#336699; background-color:White; border-bottom:1px solid #cccc99; margin-top:0pt; margin-bottom:0pt; padding:0px 0px 0px 0px;} h2 {font:bold 10pt Arial,Helvetica,Geneva,sans-serif; color:#336699; background-color:White; margin-top:4pt; margin-bottom:0pt;} a {font:9pt Arial,Helvetica,sans-serif; color:#663300; background:#ffffff; margin-top:0pt; margin-bottom:0pt; vertical-align:top;}</style><title>SQL*Plus Report</title>
+</head>
+<body>
+
+<h2>TABLE COOL_REF_DB_ATTRIBUTES</h2>
+<br>
+<table border='1' width='90%' align='center' summary='Script output'>
+<tr>
+<th scope="col">
+Name
+</th>
+<th scope="col">
+Null?
+</th>
+<th scope="col">
+Type
+</th>
+</tr>
+<tr>
+<td>
+DB_ATTRIBUTE_NAME
+</td>
+<td>
+NOT NULL
+</td>
+<td>
+VARCHAR2(255)
+</td>
+</tr>
+<tr>
+<td>
+DB_ATTRIBUTE_VALUE
+</td>
+<td>
+&nbsp;
+</td>
+<td>
+VARCHAR2(4000)
+</td>
+</tr>
+</table>
+<p>
+
+</body>
+</html>
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-9">
+<meta name="generator" content="SQL*Plus 10.2.0">
+<style type='text/css'> body {font:10pt Arial,Helvetica,sans-serif; color:black; background:White;} p {font:10pt Arial,Helvetica,sans-serif; color:black; background:White;} table,tr,td {font:10pt Arial,Helvetica,sans-serif; color:Black; background:#f7f7e7; padding:0px 0px 0px 0px; margin:0px 0px 0px 0px;} th {font:bold 10pt Arial,Helvetica,sans-serif; color:#336699; background:#cccc99; padding:0px 0px 0px 0px;} h1 {font:16pt Arial,Helvetica,Geneva,sans-serif; color:#336699; background-color:White; border-bottom:1px solid #cccc99; margin-top:0pt; margin-bottom:0pt; padding:0px 0px 0px 0px;} h2 {font:bold 10pt Arial,Helvetica,Geneva,sans-serif; color:#336699; background-color:White; margin-top:4pt; margin-bottom:0pt;} a {font:9pt Arial,Helvetica,sans-serif; color:#663300; background:#ffffff; margin-top:0pt; margin-bottom:0pt; vertical-align:top;}</style><title>SQL*Plus Report</title>
+</head>
+<body>
+
+<h2>TABLE COOL_REF_NODES</h2>
+<br>
+<table border='1' width='90%' align='center' summary='Script output'>
+<tr>
+<th scope="col">
+Name
+</th>
+<th scope="col">
+Null?
+</th>
+<th scope="col">
+Type
+</th>
+</tr>
+<tr>
+<td>
+NODE_ID
+</td>
+<td>
+NOT NULL
+</td>
+<td>
+NUMBER(10)
+</td>
+</tr>
+<tr>
+<td>
+NODE_PARENTID
+</td>
+<td>
+&nbsp;
+</td>
+<td>
+NUMBER(10)
+</td>
+</tr>
+<tr>
+<td>
+NODE_NAME
+</td>
+<td>
+&nbsp;
+</td>
+<td>
+VARCHAR2(255)
+</td>
+</tr>
+<tr>
+<td>
+NODE_FULLPATH
+</td>
+<td>
+&nbsp;
+</td>
+<td>
+VARCHAR2(255)
+</td>
+</tr>
+<tr>
+<td>
+NODE_DESCRIPTION
+</td>
+<td>
+&nbsp;
+</td>
+<td>
+VARCHAR2(255)
+</td>
+</tr>
+<tr>
+<td>
+NODE_ISLEAF
+</td>
+<td>
+&nbsp;
+</td>
+<td>
+NUMBER(1)
+</td>
+</tr>
+<tr>
+<td>
+NODE_INSTIME
+</td>
+<td>
+&nbsp;
+</td>
+<td>
+VARCHAR2(255)
+</td>
+</tr>
+<tr>
+<td>
+FOLDER_PAYLOADSPEC
+</td>
+<td>
+&nbsp;
+</td>
+<td>
+VARCHAR2(4000)
+</td>
+</tr>
+<tr>
+<td>
+FOLDER_VERSIONING
+</td>
+<td>
+&nbsp;
+</td>
+<td>
+NUMBER(10)
+</td>
+</tr>
+<tr>
+<td>
+FOLDER_IOVTABLENAME
+</td>
+<td>
+&nbsp;
+</td>
+<td>
+VARCHAR2(255)
+</td>
+</tr>
+<tr>
+<td>
+FOLDER_TAGTABLENAME
+</td>
+<td>
+&nbsp;
+</td>
+<td>
+VARCHAR2(255)
+</td>
+</tr>
+<tr>
+<td>
+FOLDER_IOV2TAGTABLENAME
+</td>
+<td>
+&nbsp;
+</td>
+<td>
+VARCHAR2(255)
+</td>
+</tr>
+</table>
+<p>
+
+</body>
+</html>
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-9">
+<meta name="generator" content="SQL*Plus 10.2.0">
+<style type='text/css'> body {font:10pt Arial,Helvetica,sans-serif; color:black; background:White;} p {font:10pt Arial,Helvetica,sans-serif; color:black; background:White;} table,tr,td {font:10pt Arial,Helvetica,sans-serif; color:Black; background:#f7f7e7; padding:0px 0px 0px 0px; margin:0px 0px 0px 0px;} th {font:bold 10pt Arial,Helvetica,sans-serif; color:#336699; background:#cccc99; padding:0px 0px 0px 0px;} h1 {font:16pt Arial,Helvetica,Geneva,sans-serif; color:#336699; background-color:White; border-bottom:1px solid #cccc99; margin-top:0pt; margin-bottom:0pt; padding:0px 0px 0px 0px;} h2 {font:bold 10pt Arial,Helvetica,Geneva,sans-serif; color:#336699; background-color:White; margin-top:4pt; margin-bottom:0pt;} a {font:9pt Arial,Helvetica,sans-serif; color:#663300; background:#ffffff; margin-top:0pt; margin-bottom:0pt; vertical-align:top;}</style><title>SQL*Plus Report</title>
+</head>
+<body>
+
+<h2>TABLE COOL_REF_NODES_SEQ</h2>
+<br>
+<table border='1' width='90%' align='center' summary='Script output'>
+<tr>
+<th scope="col">
+Name
+</th>
+<th scope="col">
+Null?
+</th>
+<th scope="col">
+Type
+</th>
+</tr>
+<tr>
+<td>
+SEQUENCE_NAME
+</td>
+<td>
+NOT NULL
+</td>
+<td>
+VARCHAR2(255)
+</td>
+</tr>
+<tr>
+<td>
+CURRENT_VALUE
+</td>
+<td>
+&nbsp;
+</td>
+<td>
+NUMBER(10)
+</td>
+</tr>
+<tr>
+<td>
+LASTMOD_DATE
+</td>
+<td>
+&nbsp;
+</td>
+<td>
+VARCHAR2(255)
+</td>
+</tr>
+</table>
+<p>
+
+</body>
+</html>
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-9">
+<meta name="generator" content="SQL*Plus 10.2.0">
+<style type='text/css'> body {font:10pt Arial,Helvetica,sans-serif; color:black; background:White;} p {font:10pt Arial,Helvetica,sans-serif; color:black; background:White;} table,tr,td {font:10pt Arial,Helvetica,sans-serif; color:Black; background:#f7f7e7; padding:0px 0px 0px 0px; margin:0px 0px 0px 0px;} th {font:bold 10pt Arial,Helvetica,sans-serif; color:#336699; background:#cccc99; padding:0px 0px 0px 0px;} h1 {font:16pt Arial,Helvetica,Geneva,sans-serif; color:#336699; background-color:White; border-bottom:1px solid #cccc99; margin-top:0pt; margin-bottom:0pt; padding:0px 0px 0px 0px;} h2 {font:bold 10pt Arial,Helvetica,Geneva,sans-serif; color:#336699; background-color:White; margin-top:4pt; margin-bottom:0pt;} a {font:9pt Arial,Helvetica,sans-serif; color:#663300; background:#ffffff; margin-top:0pt; margin-bottom:0pt; vertical-align:top;}</style><title>SQL*Plus Report</title>
+</head>
+<body>
+
+<h2>TABLE COOL_REF_TAGS</h2>
+<br>
+<table border='1' width='90%' align='center' summary='Script output'>
+<tr>
+<th scope="col">
+Name
+</th>
+<th scope="col">
+Null?
+</th>
+<th scope="col">
+Type
+</th>
+</tr>
+<tr>
+<td>
+TAG_ID
+</td>
+<td>
+NOT NULL
+</td>
+<td>
+NUMBER(10)
+</td>
+</tr>
+<tr>
+<td>
+NODE_ID
+</td>
+<td>
+NOT NULL
+</td>
+<td>
+NUMBER(10)
+</td>
+</tr>
+<tr>
+<td>
+TAG_NAME
+</td>
+<td>
+&nbsp;
+</td>
+<td>
+VARCHAR2(255)
+</td>
+</tr>
+<tr>
+<td>
+TAG_DESCRIPTION
+</td>
+<td>
+&nbsp;
+</td>
+<td>
+VARCHAR2(255)
+</td>
+</tr>
+<tr>
+<td>
+SYS_INSTIME
+</td>
+<td>
+&nbsp;
+</td>
+<td>
+VARCHAR2(255)
+</td>
+</tr>
+</table>
+<p>
+
+</body>
+</html>
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-9">
+<meta name="generator" content="SQL*Plus 10.2.0">
+<style type='text/css'> body {font:10pt Arial,Helvetica,sans-serif; color:black; background:White;} p {font:10pt Arial,Helvetica,sans-serif; color:black; background:White;} table,tr,td {font:10pt Arial,Helvetica,sans-serif; color:Black; background:#f7f7e7; padding:0px 0px 0px 0px; margin:0px 0px 0px 0px;} th {font:bold 10pt Arial,Helvetica,sans-serif; color:#336699; background:#cccc99; padding:0px 0px 0px 0px;} h1 {font:16pt Arial,Helvetica,Geneva,sans-serif; color:#336699; background-color:White; border-bottom:1px solid #cccc99; margin-top:0pt; margin-bottom:0pt; padding:0px 0px 0px 0px;} h2 {font:bold 10pt Arial,Helvetica,Geneva,sans-serif; color:#336699; background-color:White; margin-top:4pt; margin-bottom:0pt;} a {font:9pt Arial,Helvetica,sans-serif; color:#663300; background:#ffffff; margin-top:0pt; margin-bottom:0pt; vertical-align:top;}</style><title>SQL*Plus Report</title>
+</head>
+<body>
+
+<h2>TABLE COOL_REF_F0002_IOVS</h2>
+<br>
+<table border='1' width='90%' align='center' summary='Script output'>
+<tr>
+<th scope="col">
+Name
+</th>
+<th scope="col">
+Null?
+</th>
+<th scope="col">
+Type
+</th>
+</tr>
+<tr>
+<td>
+OBJECT_ID
+</td>
+<td>
+NOT NULL
+</td>
+<td>
+NUMBER(10)
+</td>
+</tr>
+<tr>
+<td>
+CHANNEL_ID
+</td>
+<td>
+&nbsp;
+</td>
+<td>
+NUMBER(10)
+</td>
+</tr>
+<tr>
+<td>
+IOV_SINCE
+</td>
+<td>
+&nbsp;
+</td>
+<td>
+NUMBER(20)
+</td>
+</tr>
+<tr>
+<td>
+IOV_UNTIL
+</td>
+<td>
+&nbsp;
+</td>
+<td>
+NUMBER(20)
+</td>
+</tr>
+<tr>
+<td>
+USER_TAG_ID
+</td>
+<td>
+&nbsp;
+</td>
+<td>
+NUMBER(10)
+</td>
+</tr>
+<tr>
+<td>
+SYS_INSTIME
+</td>
+<td>
+&nbsp;
+</td>
+<td>
+VARCHAR2(255)
+</td>
+</tr>
+<tr>
+<td>
+ORIGINAL_ID
+</td>
+<td>
+&nbsp;
+</td>
+<td>
+NUMBER(10)
+</td>
+</tr>
+<tr>
+<td>
+NEW_HEAD_ID
+</td>
+<td>
+&nbsp;
+</td>
+<td>
+NUMBER(10)
+</td>
+</tr>
+<tr>
+<td>
+A_BOOL
+</td>
+<td>
+&nbsp;
+</td>
+<td>
+NUMBER(1)
+</td>
+</tr>
+<tr>
+<td>
+A_SHRT
+</td>
+<td>
+&nbsp;
+</td>
+<td>
+NUMBER(5)
+</td>
+</tr>
+<tr>
+<td>
+A_USHRT
+</td>
+<td>
+&nbsp;
+</td>
+<td>
+NUMBER(5)
+</td>
+</tr>
+<tr>
+<td>
+A_INT
+</td>
+<td>
+&nbsp;
+</td>
+<td>
+NUMBER(10)
+</td>
+</tr>
+<tr>
+<td>
+A_UINT
+</td>
+<td>
+&nbsp;
+</td>
+<td>
+NUMBER(10)
+</td>
+</tr>
+<tr>
+<td>
+A_LONG
+</td>
+<td>
+&nbsp;
+</td>
+<td>
+NUMBER(10)
+</td>
+</tr>
+<tr>
+<td>
+A_ULONG
+</td>
+<td>
+&nbsp;
+</td>
+<td>
+NUMBER(10)
+</td>
+</tr>
+<tr>
+<td>
+A_ULONGLONG
+</td>
+<td>
+&nbsp;
+</td>
+<td>
+NUMBER(20)
+</td>
+</tr>
+<tr>
+<td>
+A_FLOAT
+</td>
+<td>
+&nbsp;
+</td>
+<td>
+BINARY_FLOAT
+</td>
+</tr>
+<tr>
+<td>
+A_DOUBLE
+</td>
+<td>
+&nbsp;
+</td>
+<td>
+BINARY_DOUBLE
+</td>
+</tr>
+<tr>
+<td>
+A_STRING
+</td>
+<td>
+&nbsp;
+</td>
+<td>
+VARCHAR2(4000)
+</td>
+</tr>
+</table>
+<p>
+
+</body>
+</html>
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-9">
+<meta name="generator" content="SQL*Plus 10.2.0">
+<style type='text/css'> body {font:10pt Arial,Helvetica,sans-serif; color:black; background:White;} p {font:10pt Arial,Helvetica,sans-serif; color:black; background:White;} table,tr,td {font:10pt Arial,Helvetica,sans-serif; color:Black; background:#f7f7e7; padding:0px 0px 0px 0px; margin:0px 0px 0px 0px;} th {font:bold 10pt Arial,Helvetica,sans-serif; color:#336699; background:#cccc99; padding:0px 0px 0px 0px;} h1 {font:16pt Arial,Helvetica,Geneva,sans-serif; color:#336699; background-color:White; border-bottom:1px solid #cccc99; margin-top:0pt; margin-bottom:0pt; padding:0px 0px 0px 0px;} h2 {font:bold 10pt Arial,Helvetica,Geneva,sans-serif; color:#336699; background-color:White; margin-top:4pt; margin-bottom:0pt;} a {font:9pt Arial,Helvetica,sans-serif; color:#663300; background:#ffffff; margin-top:0pt; margin-bottom:0pt; vertical-align:top;}</style><title>SQL*Plus Report</title>
+</head>
+<body>
+
+<h2>TABLE COOL_REF_F0002_IOVS_SEQ</h2>
+<br>
+<table border='1' width='90%' align='center' summary='Script output'>
+<tr>
+<th scope="col">
+Name
+</th>
+<th scope="col">
+Null?
+</th>
+<th scope="col">
+Type
+</th>
+</tr>
+<tr>
+<td>
+SEQUENCE_NAME
+</td>
+<td>
+NOT NULL
+</td>
+<td>
+VARCHAR2(255)
+</td>
+</tr>
+<tr>
+<td>
+CURRENT_VALUE
+</td>
+<td>
+&nbsp;
+</td>
+<td>
+NUMBER(10)
+</td>
+</tr>
+<tr>
+<td>
+LASTMOD_DATE
+</td>
+<td>
+&nbsp;
+</td>
+<td>
+VARCHAR2(255)
+</td>
+</tr>
+</table>
+<p>
+
+</body>
+</html>
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-9">
+<meta name="generator" content="SQL*Plus 10.2.0">
+<style type='text/css'> body {font:10pt Arial,Helvetica,sans-serif; color:black; background:White;} p {font:10pt Arial,Helvetica,sans-serif; color:black; background:White;} table,tr,td {font:10pt Arial,Helvetica,sans-serif; color:Black; background:#f7f7e7; padding:0px 0px 0px 0px; margin:0px 0px 0px 0px;} th {font:bold 10pt Arial,Helvetica,sans-serif; color:#336699; background:#cccc99; padding:0px 0px 0px 0px;} h1 {font:16pt Arial,Helvetica,Geneva,sans-serif; color:#336699; background-color:White; border-bottom:1px solid #cccc99; margin-top:0pt; margin-bottom:0pt; padding:0px 0px 0px 0px;} h2 {font:bold 10pt Arial,Helvetica,Geneva,sans-serif; color:#336699; background-color:White; margin-top:4pt; margin-bottom:0pt;} a {font:9pt Arial,Helvetica,sans-serif; color:#663300; background:#ffffff; margin-top:0pt; margin-bottom:0pt; vertical-align:top;}</style><title>SQL*Plus Report</title>
+</head>
+<body>
+
+<h2>TABLE COOL_REF_F0003_IOV2TAG</h2>
+<br>
+<table border='1' width='90%' align='center' summary='Script output'>
+<tr>
+<th scope="col">
+Name
+</th>
+<th scope="col">
+Null?
+</th>
+<th scope="col">
+Type
+</th>
+</tr>
+<tr>
+<td>
+TAG_ID
+</td>
+<td>
+NOT NULL
+</td>
+<td>
+NUMBER(10)
+</td>
+</tr>
+<tr>
+<td>
+OBJECT_ID
+</td>
+<td>
+NOT NULL
+</td>
+<td>
+NUMBER(10)
+</td>
+</tr>
+<tr>
+<td>
+CHANNEL_ID
+</td>
+<td>
+&nbsp;
+</td>
+<td>
+NUMBER(10)
+</td>
+</tr>
+<tr>
+<td>
+IOV_SINCE
+</td>
+<td>
+&nbsp;
+</td>
+<td>
+NUMBER(20)
+</td>
+</tr>
+<tr>
+<td>
+IOV_UNTIL
+</td>
+<td>
+&nbsp;
+</td>
+<td>
+NUMBER(20)
+</td>
+</tr>
+<tr>
+<td>
+SYS_INSTIME
+</td>
+<td>
+&nbsp;
+</td>
+<td>
+VARCHAR2(255)
+</td>
+</tr>
+</table>
+<p>
+
+</body>
+</html>
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-9">
+<meta name="generator" content="SQL*Plus 10.2.0">
+<style type='text/css'> body {font:10pt Arial,Helvetica,sans-serif; color:black; background:White;} p {font:10pt Arial,Helvetica,sans-serif; color:black; background:White;} table,tr,td {font:10pt Arial,Helvetica,sans-serif; color:Black; background:#f7f7e7; padding:0px 0px 0px 0px; margin:0px 0px 0px 0px;} th {font:bold 10pt Arial,Helvetica,sans-serif; color:#336699; background:#cccc99; padding:0px 0px 0px 0px;} h1 {font:16pt Arial,Helvetica,Geneva,sans-serif; color:#336699; background-color:White; border-bottom:1px solid #cccc99; margin-top:0pt; margin-bottom:0pt; padding:0px 0px 0px 0px;} h2 {font:bold 10pt Arial,Helvetica,Geneva,sans-serif; color:#336699; background-color:White; margin-top:4pt; margin-bottom:0pt;} a {font:9pt Arial,Helvetica,sans-serif; color:#663300; background:#ffffff; margin-top:0pt; margin-bottom:0pt; vertical-align:top;}</style><title>SQL*Plus Report</title>
+</head>
+<body>
+
+<h2>TABLE COOL_REF_F0003_IOVS</h2>
+<br>
+<table border='1' width='90%' align='center' summary='Script output'>
+<tr>
+<th scope="col">
+Name
+</th>
+<th scope="col">
+Null?
+</th>
+<th scope="col">
+Type
+</th>
+</tr>
+<tr>
+<td>
+OBJECT_ID
+</td>
+<td>
+NOT NULL
+</td>
+<td>
+NUMBER(10)
+</td>
+</tr>
+<tr>
+<td>
+CHANNEL_ID
+</td>
+<td>
+&nbsp;
+</td>
+<td>
+NUMBER(10)
+</td>
+</tr>
+<tr>
+<td>
+IOV_SINCE
+</td>
+<td>
+&nbsp;
+</td>
+<td>
+NUMBER(20)
+</td>
+</tr>
+<tr>
+<td>
+IOV_UNTIL
+</td>
+<td>
+&nbsp;
+</td>
+<td>
+NUMBER(20)
+</td>
+</tr>
+<tr>
+<td>
+USER_TAG_ID
+</td>
+<td>
+&nbsp;
+</td>
+<td>
+NUMBER(10)
+</td>
+</tr>
+<tr>
+<td>
+SYS_INSTIME
+</td>
+<td>
+&nbsp;
+</td>
+<td>
+VARCHAR2(255)
+</td>
+</tr>
+<tr>
+<td>
+ORIGINAL_ID
+</td>
+<td>
+&nbsp;
+</td>
+<td>
+NUMBER(10)
+</td>
+</tr>
+<tr>
+<td>
+NEW_HEAD_ID
+</td>
+<td>
+&nbsp;
+</td>
+<td>
+NUMBER(10)
+</td>
+</tr>
+<tr>
+<td>
+A_BOOL
+</td>
+<td>
+&nbsp;
+</td>
+<td>
+NUMBER(1)
+</td>
+</tr>
+<tr>
+<td>
+A_SHRT
+</td>
+<td>
+&nbsp;
+</td>
+<td>
+NUMBER(5)
+</td>
+</tr>
+<tr>
+<td>
+A_USHRT
+</td>
+<td>
+&nbsp;
+</td>
+<td>
+NUMBER(5)
+</td>
+</tr>
+<tr>
+<td>
+A_INT
+</td>
+<td>
+&nbsp;
+</td>
+<td>
+NUMBER(10)
+</td>
+</tr>
+<tr>
+<td>
+A_UINT
+</td>
+<td>
+&nbsp;
+</td>
+<td>
+NUMBER(10)
+</td>
+</tr>
+<tr>
+<td>
+A_LONG
+</td>
+<td>
+&nbsp;
+</td>
+<td>
+NUMBER(10)
+</td>
+</tr>
+<tr>
+<td>
+A_ULONG
+</td>
+<td>
+&nbsp;
+</td>
+<td>
+NUMBER(10)
+</td>
+</tr>
+<tr>
+<td>
+A_ULONGLONG
+</td>
+<td>
+&nbsp;
+</td>
+<td>
+NUMBER(20)
+</td>
+</tr>
+<tr>
+<td>
+A_FLOAT
+</td>
+<td>
+&nbsp;
+</td>
+<td>
+BINARY_FLOAT
+</td>
+</tr>
+<tr>
+<td>
+A_DOUBLE
+</td>
+<td>
+&nbsp;
+</td>
+<td>
+BINARY_DOUBLE
+</td>
+</tr>
+<tr>
+<td>
+A_STRING
+</td>
+<td>
+&nbsp;
+</td>
+<td>
+VARCHAR2(4000)
+</td>
+</tr>
+</table>
+<p>
+
+</body>
+</html>
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-9">
+<meta name="generator" content="SQL*Plus 10.2.0">
+<style type='text/css'> body {font:10pt Arial,Helvetica,sans-serif; color:black; background:White;} p {font:10pt Arial,Helvetica,sans-serif; color:black; background:White;} table,tr,td {font:10pt Arial,Helvetica,sans-serif; color:Black; background:#f7f7e7; padding:0px 0px 0px 0px; margin:0px 0px 0px 0px;} th {font:bold 10pt Arial,Helvetica,sans-serif; color:#336699; background:#cccc99; padding:0px 0px 0px 0px;} h1 {font:16pt Arial,Helvetica,Geneva,sans-serif; color:#336699; background-color:White; border-bottom:1px solid #cccc99; margin-top:0pt; margin-bottom:0pt; padding:0px 0px 0px 0px;} h2 {font:bold 10pt Arial,Helvetica,Geneva,sans-serif; color:#336699; background-color:White; margin-top:4pt; margin-bottom:0pt;} a {font:9pt Arial,Helvetica,sans-serif; color:#663300; background:#ffffff; margin-top:0pt; margin-bottom:0pt; vertical-align:top;}</style><title>SQL*Plus Report</title>
+</head>
+<body>
+
+<h2>TABLE COOL_REF_F0003_IOVS_SEQ</h2>
+<br>
+<table border='1' width='90%' align='center' summary='Script output'>
+<tr>
+<th scope="col">
+Name
+</th>
+<th scope="col">
+Null?
+</th>
+<th scope="col">
+Type
+</th>
+</tr>
+<tr>
+<td>
+SEQUENCE_NAME
+</td>
+<td>
+NOT NULL
+</td>
+<td>
+VARCHAR2(255)
+</td>
+</tr>
+<tr>
+<td>
+CURRENT_VALUE
+</td>
+<td>
+&nbsp;
+</td>
+<td>
+NUMBER(10)
+</td>
+</tr>
+<tr>
+<td>
+LASTMOD_DATE
+</td>
+<td>
+&nbsp;
+</td>
+<td>
+VARCHAR2(255)
+</td>
+</tr>
+</table>
+<p>
+
+</body>
+</html>
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-9">
+<meta name="generator" content="SQL*Plus 10.2.0">
+<style type='text/css'> body {font:10pt Arial,Helvetica,sans-serif; color:black; background:White;} p {font:10pt Arial,Helvetica,sans-serif; color:black; background:White;} table,tr,td {font:10pt Arial,Helvetica,sans-serif; color:Black; background:#f7f7e7; padding:0px 0px 0px 0px; margin:0px 0px 0px 0px;} th {font:bold 10pt Arial,Helvetica,sans-serif; color:#336699; background:#cccc99; padding:0px 0px 0px 0px;} h1 {font:16pt Arial,Helvetica,Geneva,sans-serif; color:#336699; background-color:White; border-bottom:1px solid #cccc99; margin-top:0pt; margin-bottom:0pt; padding:0px 0px 0px 0px;} h2 {font:bold 10pt Arial,Helvetica,Geneva,sans-serif; color:#336699; background-color:White; margin-top:4pt; margin-bottom:0pt;} a {font:9pt Arial,Helvetica,sans-serif; color:#663300; background:#ffffff; margin-top:0pt; margin-bottom:0pt; vertical-align:top;}</style><title>SQL*Plus Report</title>
+</head>
+<body>
+
+<h2>TABLE COOL_REF_F0003_TAGS</h2>
+<br>
+<table border='1' width='90%' align='center' summary='Script output'>
+<tr>
+<th scope="col">
+Name
+</th>
+<th scope="col">
+Null?
+</th>
+<th scope="col">
+Type
+</th>
+</tr>
+<tr>
+<td>
+TAG_ID
+</td>
+<td>
+NOT NULL
+</td>
+<td>
+NUMBER(10)
+</td>
+</tr>
+<tr>
+<td>
+TAG_NAME
+</td>
+<td>
+&nbsp;
+</td>
+<td>
+VARCHAR2(255)
+</td>
+</tr>
+<tr>
+<td>
+TAG_DESCRIPTION
+</td>
+<td>
+&nbsp;
+</td>
+<td>
+VARCHAR2(255)
+</td>
+</tr>
+<tr>
+<td>
+SYS_INSTIME
+</td>
+<td>
+&nbsp;
+</td>
+<td>
+VARCHAR2(255)
+</td>
+</tr>
+</table>
+<p>
+
+</body>
+</html>
+<html>
+<head>
+<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-9">
+<meta name="generator" content="SQL*Plus 10.2.0">
+<style type='text/css'> body {font:10pt Arial,Helvetica,sans-serif; color:black; background:White;} p {font:10pt Arial,Helvetica,sans-serif; color:black; background:White;} table,tr,td {font:10pt Arial,Helvetica,sans-serif; color:Black; background:#f7f7e7; padding:0px 0px 0px 0px; margin:0px 0px 0px 0px;} th {font:bold 10pt Arial,Helvetica,sans-serif; color:#336699; background:#cccc99; padding:0px 0px 0px 0px;} h1 {font:16pt Arial,Helvetica,Geneva,sans-serif; color:#336699; background-color:White; border-bottom:1px solid #cccc99; margin-top:0pt; margin-bottom:0pt; padding:0px 0px 0px 0px;} h2 {font:bold 10pt Arial,Helvetica,Geneva,sans-serif; color:#336699; background-color:White; margin-top:4pt; margin-bottom:0pt;} a {font:9pt Arial,Helvetica,sans-serif; color:#663300; background:#ffffff; margin-top:0pt; margin-bottom:0pt; vertical-align:top;}</style><title>SQL*Plus Report</title>
+</head>
+<body>
+
+<h2>TABLE COOL_REF_F0003_TAGS_SEQ</h2>
+<br>
+<table border='1' width='90%' align='center' summary='Script output'>
+<tr>
+<th scope="col">
+Name
+</th>
+<th scope="col">
+Null?
+</th>
+<th scope="col">
+Type
+</th>
+</tr>
+<tr>
+<td>
+SEQUENCE_NAME
+</td>
+<td>
+NOT NULL
+</td>
+<td>
+VARCHAR2(255)
+</td>
+</tr>
+<tr>
+<td>
+CURRENT_VALUE
+</td>
+<td>
+&nbsp;
+</td>
+<td>
+NUMBER(10)
+</td>
+</tr>
+<tr>
+<td>
+LASTMOD_DATE
+</td>
+<td>
+&nbsp;
+</td>
+<td>
+VARCHAR2(255)
+</td>
+</tr>
+</table>
+<p>
+
+</body>
+</html>
diff --git a/RelationalCool/tests/SchemaDump/schemaDump.cpp b/RelationalCool/tests/SchemaDump/schemaDump.cpp
new file mode 100644
index 000000000..5a5eb9a47
--- /dev/null
+++ b/RelationalCool/tests/SchemaDump/schemaDump.cpp
@@ -0,0 +1,169 @@
+// $Id: schemaDump.cpp,v 1.10 2008-08-27 09:34:30 avalassi Exp $
+
+// Include files
+#include <iostream>
+#include <sstream>
+#include <string>
+#include "CoolKernel/DatabaseId.h"
+#include "CoolKernel/IDatabase.h"
+#include "CoolKernel/IDatabaseSvc.h"
+#include "CoolKernel/IFolder.h"
+#include "CoolKernel/IObject.h"
+#include "CoolKernel/IObjectIterator.h"
+#include "CoralBase/AttributeList.h"
+#include "src/CoralApplication.h"
+#include "src/sleep.h"
+#include "src/timeToString.h"
+#include "src/uppercaseString.h"
+#include "../Common/releaser.h"
+
+// Environment variable name (connection string)
+namespace cool {
+  const char* COOLTESTDB = "COOLTESTDB";
+}
+
+// Namespace
+using namespace cool;
+
+// Message output
+#define LOG std::cout << "__main "
+
+//-----------------------------------------------------------------------------
+
+int main ( int /*argc*/, char* /*argv[]*/ )
+{
+
+  LOG << "Entering main" << std::endl;
+  int status = -1;
+
+  try {
+    
+    //------------------------
+    // DEFINE THE DATABASE ID
+    //------------------------
+
+    // Command line input: connection string
+    std::string dbIdString;
+    if ( getenv( COOLTESTDB ) ) {
+      dbIdString = getenv( COOLTESTDB );
+    } else {
+      std::cout << "ERROR! Please provide a connect string "
+                << "in the environment variable COOLTESTDB" << std::endl;
+      exit(-1);
+    }
+    cool::DatabaseId dbId = dbIdString;
+    
+    //-------------------------------
+    // RETRIEVE THE DATABASE SERVICE
+    //-------------------------------
+    
+    LOG << "Get a handle to the COOL database service" << std::endl;
+    CoralApplication app;
+    IDatabaseSvc& dbSvc = app.databaseService();
+  
+    //--------------------------------
+    // DROP THE DATABASE IF IT EXISTS
+    //--------------------------------
+    
+    // Drop the COOL conditions database if it already exists
+    LOG << "Drop if it exists the conditions database: " << dbId << std::endl;
+    dbSvc.dropDatabase( dbId );
+
+    //-----------------------
+    // CREATE A NEW DATABASE
+    //-----------------------
+    
+    // Create a new COOL conditions database
+    LOG << "Create a new conditions database: " << dbId << std::endl;
+    cool::IDatabasePtr db = dbSvc.createDatabase( dbId );
+    LOG << "Conditions database created: " << std::endl;
+    LOG << "-> Database ID: " << db->databaseId() << std::endl;
+    std::ostringstream dbAttr;
+    db->databaseAttributes().toOutputStream( dbAttr );
+    LOG << "-> Database attributes: " << dbAttr.str() << std::endl;
+
+    // TEMPORARY? Patch for the ORA-01466 problem: sleep one second
+    cool::sleep(1);
+
+    // Create two new folders (one SV, one MV) with the same payload spec
+    boost::shared_ptr<coral::AttributeListSpecification>
+    spec( new coral::AttributeListSpecification(), releaser() );
+    spec->extend( "A_BOOL", "bool" );
+    //spec->extend( "A_CHAR", "char" ); // RAL MySQL error on retrieval
+    //spec->extend( "A_UCHAR", "unsigned char" ); // Bad RAL MYSQL mapping
+    spec->extend( "A_SHRT", "short" );
+    spec->extend( "A_USHRT", "unsigned short" );
+    spec->extend( "A_INT", "int" );
+    spec->extend( "A_UINT", "unsigned int" );
+    spec->extend( "A_LONG", "long" );
+    spec->extend( "A_ULONG", "unsigned long" );
+    //spec->extend( "A_LONGLONG", "long long" ); // OCI-22053 must be fixed
+    spec->extend( "A_ULONGLONG", "unsigned long long" );
+    spec->extend( "A_FLOAT", "float" );
+    spec->extend( "A_DOUBLE", "double" );
+    //spec->extend( "A_LONGDOUBLE", "long double" ); // NO RAL MySQL DEFAULT
+    spec->extend( "A_STRING", "string" );
+    //spec->extend( "A_TOKEN", "Token" ); // THIS WILL NOT BE SUPPORTED!
+
+    // Create SV folder
+    std::string folderNameSV( "/myfolders/SV" );
+    cool::IFolderPtr folderSV = db->createFolder
+      ( folderNameSV, *spec, "", FolderVersioning::SINGLE_VERSION, true );
+    LOG << "Folder created: " << std::endl;
+    LOG << "-> Folder name: " << folderSV->fullPath() << std::endl;
+    //std::ostringstream folderAttrSV;
+    //folderSV->payloadSpecification().print( folderAttrSV );
+    //LOG << "-> Folder payload specification: " 
+    //    << folderAttrSV.str() << std::endl;
+
+    // Create MV folder
+    std::string folderNameMV( "/myfolders/MV" );
+    cool::IFolderPtr folderMV = db->createFolder
+      ( folderNameMV, *spec, "", FolderVersioning::MULTI_VERSION, true );
+    LOG << "Folder created: " << std::endl;
+    LOG << "-> Folder name: " << folderMV->fullPath() << std::endl;
+    //std::ostringstream folderAttrMV;
+    //folderMV->payloadSpecification().print( folderAttrMV );
+    //LOG << "-> Folder payload specification: " 
+    //    << folderAttrMV.str() << std::endl;
+
+    // TEMPORARY? Patch for the ORA-01466 problem: sleep one second
+    cool::sleep(1);
+
+    /*
+    // Print the list of folders
+    std::vector<std::string> folderList;
+    std::vector<std::string>::iterator folderIt;
+    folderList = db->listFolders();
+    LOG << "-> List of folders in the database:" << std::endl;
+    for( folderIt = folderList.begin(); 
+         folderIt != folderList.end(); 
+         folderIt++ ) {
+      std::cout << *folderIt << std::endl;
+    }
+    */
+
+    // Successful completion
+    LOG << "Program terminating succesfully" << std::endl;
+    status = 0;
+    
+  }
+  catch(std::exception& e)
+  {
+    LOG << "ERROR! Standard C++ exception: '" << e.what() << "'" << std::endl;
+    status = 1;
+  }
+  catch(...) 
+  {
+    LOG << "ERROR! Unknown exception caught" << std::endl;
+    status = 1;
+  }
+
+  // Program termination
+  LOG << "Exiting main" << std::endl;
+  return status;
+  
+}
+
+//-----------------------------------------------------------------------------
+
diff --git a/RelationalCool/tests/SchemaDump/sql/oracleDescTable.sql b/RelationalCool/tests/SchemaDump/sql/oracleDescTable.sql
new file mode 100644
index 000000000..a2a651619
--- /dev/null
+++ b/RelationalCool/tests/SchemaDump/sql/oracleDescTable.sql
@@ -0,0 +1,7 @@
+SET MARKUP HTML ENTMAP OFF
+prompt <h2>TABLE &1</h2>
+SET MARKUP HTML ENTMAP ON
+
+desc &2
+
+quit;
diff --git a/RelationalCool/tests/SchemaDump/sql/oracleDumpConstraints.sql b/RelationalCool/tests/SchemaDump/sql/oracleDumpConstraints.sql
new file mode 100755
index 000000000..cfcc8940e
--- /dev/null
+++ b/RelationalCool/tests/SchemaDump/sql/oracleDumpConstraints.sql
@@ -0,0 +1,15 @@
+define owner  = "&1";
+define dbname = "&2";
+
+--column table_name format a30;
+--column constraint_name format a30;
+--column constraint_type format a10;
+--column r_constraint_name format a30;
+--column index_name format a30;
+
+select table_name, constraint_name, --last_change ddl_date, 
+constraint_type||'   ' type, r_constraint_name, index_name
+from all_constraints
+where owner = '&owner'
+and table_name like '&dbname%'
+order by constraint_type, last_change, constraint_name;
diff --git a/RelationalCool/tests/SchemaDump/sql/oracleDumpFKColumns.sql b/RelationalCool/tests/SchemaDump/sql/oracleDumpFKColumns.sql
new file mode 100755
index 000000000..e88240ef4
--- /dev/null
+++ b/RelationalCool/tests/SchemaDump/sql/oracleDumpFKColumns.sql
@@ -0,0 +1,29 @@
+define owner  = "&1";
+define dbname = "&2";
+
+--column table_name format a30;
+--column constraint_name format a30;
+--column r_constraint_name format a30;
+--column ddl_date format a15;
+--column col_name format a15;
+--column r_col_name format a15;
+
+select table_name, constraint_name, r_constraint_name, --ddl_date,
+col_name, col_pos, r_col_name, r_col_pos
+from (
+select c.table_name, c.constraint_name, o.r_constraint_name, 
+o.last_change ddl_date,
+c.column_name col_name, c.position col_pos,
+(select r.column_name from user_ind_columns r 
+where r.index_name=o.r_constraint_name) r_col_name,
+(select r.column_position from user_ind_columns r 
+where r.index_name=o.r_constraint_name) r_col_pos
+from all_cons_columns c, all_constraints o
+where c.constraint_name=o.constraint_name
+and o.owner = '&owner'
+and c.owner = '&owner'
+and c.table_name like '&dbname%'
+and o.constraint_type like 'R'
+) order by ddl_date,
+table_name, constraint_name, col_pos;
+
diff --git a/RelationalCool/tests/SchemaDump/sql/oracleDumpIndColumns.sql b/RelationalCool/tests/SchemaDump/sql/oracleDumpIndColumns.sql
new file mode 100755
index 000000000..2ccf3fb3f
--- /dev/null
+++ b/RelationalCool/tests/SchemaDump/sql/oracleDumpIndColumns.sql
@@ -0,0 +1,20 @@
+define owner  = "&1";
+define dbname = "&2";
+
+--column table_name format a30;
+--column index_name format a30;
+--column ddl_date format a15;
+--column col_name format a20;
+--column descend format a10;
+
+select table_name, index_name, --ddl_date, 
+col_name, col_pos, descend
+from (
+select c.table_name, c.index_name, o.last_ddl_time ddl_date,
+c.column_name col_name, c.column_position col_pos, c.descend
+from all_ind_columns c, all_objects o
+where c.index_name=o.object_name
+and o.owner = '&owner'
+and c.table_owner = '&owner'
+and c.table_name like '&dbname%'
+) order by ddl_date, table_name, index_name, col_pos;
diff --git a/RelationalCool/tests/SchemaDump/sql/oracleDumpIndexes.sql b/RelationalCool/tests/SchemaDump/sql/oracleDumpIndexes.sql
new file mode 100755
index 000000000..8f0c93568
--- /dev/null
+++ b/RelationalCool/tests/SchemaDump/sql/oracleDumpIndexes.sql
@@ -0,0 +1,18 @@
+define owner  = "&1";
+define dbname = "&2";
+
+--column table_name format a30;
+--column index_name format a30;
+--column ddl_date format a15;
+--column uniqueness format a15;
+
+select i.table_name, o.object_name index_name, 
+--o.last_ddl_time ddl_date, 
+i.uniqueness
+from all_objects o, all_indexes i
+where o.object_type='INDEX'
+and o.object_name=i.index_name
+and o.owner = '&owner'
+and i.owner = '&owner'
+and i.table_name like '&dbname%'
+order by o.last_ddl_time, o.object_name;
diff --git a/RelationalCool/tests/SchemaDump/sql/oracleDumpTables.sql b/RelationalCool/tests/SchemaDump/sql/oracleDumpTables.sql
new file mode 100755
index 000000000..8f10483a5
--- /dev/null
+++ b/RelationalCool/tests/SchemaDump/sql/oracleDumpTables.sql
@@ -0,0 +1,12 @@
+define owner  = "&1";
+define dbname = "&2";
+
+--column table_name format a30;
+--column ddl_date format a15;
+
+select object_name table_name --, last_ddl_time ddl_date
+from all_objects
+where object_type='TABLE'
+and owner = '&owner' 
+and object_name like '&dbname%'
+order by last_ddl_time, object_name;
diff --git a/RelationalCool/tests/SchemaDump/sql/oracleSchemaDump.sql b/RelationalCool/tests/SchemaDump/sql/oracleSchemaDump.sql
new file mode 100644
index 000000000..a4e94799b
--- /dev/null
+++ b/RelationalCool/tests/SchemaDump/sql/oracleSchemaDump.sql
@@ -0,0 +1,35 @@
+set verify off;
+
+--set linesize 132;
+set pagesize 10000;
+
+SET MARKUP HTML ENTMAP OFF
+prompt <h2>TABLES</h2>
+SET MARKUP HTML ENTMAP ON
+@oracleDumpTables.sql &1 &2
+
+SET MARKUP HTML ENTMAP OFF
+prompt <h2>INDEXES</h2>
+SET MARKUP HTML ENTMAP ON
+@oracleDumpIndexes.sql &1 &2
+
+SET MARKUP HTML ENTMAP OFF
+prompt <h2>CONSTRAINTS</h2>
+SET MARKUP HTML ENTMAP ON
+@oracleDumpConstraints.sql &1 &2
+
+SET MARKUP HTML ENTMAP OFF
+prompt <h2>INDEXED COLUMNS</h2>
+SET MARKUP HTML ENTMAP ON
+@oracleDumpIndColumns.sql &1 &2
+
+SET MARKUP HTML ENTMAP OFF
+prompt <h2>FOREIGN KEY COLUMNS</h2>
+SET MARKUP HTML ENTMAP ON
+@oracleDumpFKColumns.sql &1 &2
+
+SET MARKUP HTML ENTMAP OFF
+prompt <br><hr><br>
+SET MARKUP HTML ENTMAP ON
+
+quit;
\ No newline at end of file
diff --git a/RelationalCool/tests/SchemaDump/sql/oracleShowTables.sql b/RelationalCool/tests/SchemaDump/sql/oracleShowTables.sql
new file mode 100644
index 000000000..714608fb4
--- /dev/null
+++ b/RelationalCool/tests/SchemaDump/sql/oracleShowTables.sql
@@ -0,0 +1,6 @@
+set pagesize 1000;
+select object_name table_name from all_objects 
+where object_type='TABLE'
+and owner='&1' and object_name like '&2%'
+order by last_ddl_time, table_name;
+exit;
diff --git a/RelationalCool/tests/Skeleton/test_Skeleton.cpp b/RelationalCool/tests/Skeleton/test_Skeleton.cpp
new file mode 100644
index 000000000..de805476d
--- /dev/null
+++ b/RelationalCool/tests/Skeleton/test_Skeleton.cpp
@@ -0,0 +1,52 @@
+// $Id: test_Skeleton.cpp,v 1.8 2006-05-19 09:39:37 marcocle Exp $
+#include "CoolUnitTest.h"
+
+// Include files 
+
+namespace cool {
+  class SkeletonTest:public CoolUnitTest {
+    
+    CPPUNIT_TEST_SUITE( SkeletonTest );
+
+    CPPUNIT_TEST( test_myTest );
+
+    CPPUNIT_TEST_SUITE_END();
+		
+  public:
+    
+    void setUp() {
+      /// prepare for the test
+    }
+
+    void tearDown(){
+      /// clean up after the test
+    }    
+
+    // ------------------------------------------------------
+    // The tests
+    // ------------------------------------------------------
+
+    // ------------------------------------------------------
+    void test_myTest() {
+    // ------------------------------------------------------
+
+      /// do the test
+
+      // -- allowed macros
+      // CPPUNIT_ASSERT(condition)
+      // CPPUNIT_ASSERT_MESSAGE(message,condition)
+      // CPPUNIT_ASSERT_EQUAL(expected,actual)
+      // CPPUNIT_ASSERT_EQUAL_MESSAGE(message,expected,actual)
+      // CPPUNIT_ASSERT_DOUBLES_EQUAL(expected,actual,delta)
+      // CPPUNIT_ASSERT_THROW( expression, ExceptionType )
+      // CPPUNIT_ASSERT_NO_THROW( expression )
+
+    }
+    
+  };
+
+CPPUNIT_TEST_SUITE_REGISTRATION( SkeletonTest );
+  
+}
+
+COOLTEST_MAIN(SkeletonTest)
diff --git a/RelationalCool/tests/Skeleton/test_SkeletonDb.cpp b/RelationalCool/tests/Skeleton/test_SkeletonDb.cpp
new file mode 100644
index 000000000..64844a67a
--- /dev/null
+++ b/RelationalCool/tests/Skeleton/test_SkeletonDb.cpp
@@ -0,0 +1,51 @@
+// $Id: test_SkeletonDb.cpp,v 1.1 2006-05-19 09:39:37 marcocle Exp $
+#include "CoolDBUnitTest.h"
+
+// Include files 
+
+namespace cool {
+  class SkeletonDbTest:public CoolDBUnitTest {
+    
+    CPPUNIT_TEST_SUITE( SkeletonDbTest );
+
+    CPPUNIT_TEST( test_myTest );
+
+    CPPUNIT_TEST_SUITE_END();
+		
+  public:
+    
+    void setUp() {
+      /// prepare for the test
+    }
+
+    void tearDown(){
+      /// clean up after the test
+    }    
+
+    // ------------------------------------------------------
+    // The tests
+    // ------------------------------------------------------
+
+    // ------------------------------------------------------
+    void test_myTest() {
+    // ------------------------------------------------------
+
+      /// do the test
+
+      // -- allowed macros
+      // CPPUNIT_ASSERT(condition)
+      // CPPUNIT_ASSERT_MESSAGE(message,condition)
+      // CPPUNIT_ASSERT_EQUAL(expected,actual)
+      // CPPUNIT_ASSERT_EQUAL_MESSAGE(message,expected,actual)
+      // CPPUNIT_ASSERT_DOUBLES_EQUAL(expected,actual,delta)
+      // CPPUNIT_ASSERT_THROW( expression, ExceptionType )
+      // CPPUNIT_ASSERT_NO_THROW( expression )
+    }
+    
+  };
+
+CPPUNIT_TEST_SUITE_REGISTRATION( SkeletonDbTest );
+  
+}
+
+COOLTEST_MAIN(SkeletonDbTest)
diff --git a/RelationalCool/tests/StressTest/stressTest.cpp b/RelationalCool/tests/StressTest/stressTest.cpp
new file mode 100644
index 000000000..487fa77a9
--- /dev/null
+++ b/RelationalCool/tests/StressTest/stressTest.cpp
@@ -0,0 +1,245 @@
+// PORT -- temporarily disabled: not part of our official test suite
+int main() { return 0; }
+#ifdef NOPORT
+
+// $Id: stressTest.cpp,v 1.8 2008-08-27 09:34:30 avalassi Exp $
+
+// Include files
+#include <iostream>
+#include <sstream>
+#include <string>
+#include "AttributeList/AttributeList.h"
+#include "CoolKernel/DatabaseId.h"
+#include "CoolKernel/IDatabase.h"
+#include "CoolKernel/IDatabaseSvc.h"
+#include "CoolKernel/IFolder.h"
+#include "CoolKernel/IObject.h"
+#include "CoolKernel/IObjectIterator.h"
+#include "SealKernel/Exception.h"
+#include "SealUtil/SealTimer.h"
+#include "SealUtil/TimingItem.h"
+#include "src/CoralApplication.h"
+#include "src/sleep.h"
+#include "src/TimingReport.h"
+#include "src/timeToString.h"
+#include "src/uppercaseString.h"
+
+// Namespace
+using namespace cool;
+
+// Message output
+#define LOG std::cout << "__main "
+
+// Global settings
+#define DBCREATE false
+
+//-----------------------------------------------------------------------------
+
+int main ( int argc, char* argv[] )
+{
+
+  LOG << "Entering main" << std::endl;
+  int status = -1;
+
+  // Global settings
+  bool dbCreate = DBCREATE;
+  bool dbWrite = dbCreate;
+  bool dbRead = ! dbWrite;
+  
+  try {
+    
+    //------------------------
+    // DEFINE THE DATABASE ID
+    //------------------------
+
+    // Command line input: connection string
+    std::string dbIdString;
+    if ( argc == 1 || argc > 2 ) {    
+      LOG << "Usage: " << argv[0] << " dbId" << std::endl;
+      LOG << "Example: " << argv[0] 
+          << " 'oracle://cooldev;schema=lcg_cool;dbname=STRESTST'" 
+          << std::endl;
+      return 1;
+    } else {      
+      dbIdString = argv[1];
+    }
+    cool::DatabaseId dbId = dbIdString;
+    
+    //-------------------------------
+    // RETRIEVE THE DATABASE SERVICE
+    //-------------------------------
+    
+    LOG << "Get a handle to the COOL database service" << std::endl;
+    CoralApplication app;
+    IDatabaseSvc& dbSvc = app.databaseService();
+  
+    //-----------------------
+    // CREATE A NEW DATABASE
+    //-----------------------
+    
+    std::string folderName = "/myfolders/SV";
+
+    if ( dbCreate ) {
+
+      // Drop the COOL conditions database if it already exists
+      LOG << "Drop if it exists the conditions database: " << dbId 
+          << std::endl;
+      dbSvc.dropDatabase( dbId );
+      
+      // Create a new COOL conditions database
+      LOG << "Create a new conditions database: " << dbId << std::endl;
+      cool::IDatabasePtr db = dbSvc.createDatabase( dbId );
+      LOG << "Conditions database created: " << std::endl;
+      LOG << "-> Database ID: " << db->databaseId() << std::endl;
+      std::ostringstream dbAttr;
+      db->databaseAttributes().print( dbAttr );
+      LOG << "-> Database attributes: " << dbAttr.str() << std::endl;
+      
+      // TEMPORARY? Patch for the ORA-01466 problem: sleep one second
+      cool::Sleep(1);
+      
+      // Create SV folder
+      pool::AttributeListSpecification spec;
+      spec.push_back( "A_STRING", "string" );
+      std::string folderNameSV( folderName );
+      cool::IFolderPtr folderSV = db->createFolder
+        ( folderNameSV, spec, "", FolderVersioning::SINGLE_VERSION, true );
+      LOG << "Folder created: " << std::endl;
+      LOG << "-> Folder name: " << folderSV->fullPath() << std::endl;
+      std::ostringstream folderAttrSV;
+      folderSV->payloadSpecification().print( folderAttrSV );
+      LOG << "-> Folder payload specification: " 
+          << folderAttrSV.str() << std::endl;
+
+      // TEMPORARY? Patch for the ORA-01466 problem: sleep one second
+      cool::Sleep(1);
+      
+      /*
+      // Print the list of folders
+      std::vector<std::string> folderList;
+      std::vector<std::string>::iterator folderIt;
+      folderList = db->listFolders();
+      LOG << "-> List of folders in the database:" << std::endl;
+      for( folderIt = folderList.begin(); 
+           folderIt != folderList.end(); 
+           folderIt++ ) {
+        std::cout << *folderIt << std::endl;
+      }
+      */
+      
+    }
+    
+    //---------------------------
+    // OPEN AN EXISTING DATABASE
+    //---------------------------
+
+    // Open an existing COOL conditions database
+    LOG << "Open an existing conditions database: " << dbId << std::endl;
+    cool::IDatabasePtr db = dbSvc.openDatabase( dbId, false );
+    LOG << "Conditions database opened: " << std::endl;
+    LOG << "-> Database ID: " << db->databaseId() << std::endl;
+    LOG << "Retrieve folder: " << folderName << std::endl;
+    IFolderPtr folder = db->getFolder( folderName );
+    LOG << "Folder retrieved" << std::endl;
+   
+    //------------
+    // WRITE DATA
+    //------------
+
+    if ( dbWrite ) {
+
+      unsigned nBulks = 100;
+      unsigned nInBulk = 1000;
+
+      unsigned iBulk;
+      unsigned iInBulk;
+      
+      // HERE WAS A BUG! THIS HAD BEEN FORGOTTEN! :-(
+      folder->setupStorageBuffer( nInBulk );
+
+      // Bulk-insert data
+      LOG << "INSERT DATA" << std::endl;
+      ValidityKey plusInfinity = ValidityKeyMax;
+      pool::AttributeList payload( folder->payloadSpecification() );
+      payload["A_STRING"].setValue<std::string>( "DUMMY" );
+      for ( iBulk=0; iBulk<nBulks; iBulk++ ) {
+        cool::TimingReport timeReport;
+        std::stringstream msg;
+        msg << "Bulk insertion # " << iBulk+1 
+            << " of " << nInBulk << " IOVS each";      
+        seal::TimingItem& timeItem = timeReport.item( msg.str() );
+        seal::SealTimer* timer = new seal::SealTimer( timeItem );
+        LOG << "Bulk insertion #" << iBulk+1 << std::endl;
+        for ( iInBulk=0; iInBulk<nInBulk; iInBulk++ ) {
+          ValidityKey bulkSince = iBulk*nInBulk + iInBulk;
+          folder->storeObject( bulkSince*1000, plusInfinity, payload, 1 );
+        }
+        folder->flushStorageBuffer();
+        delete timer;        
+        timeReport.dumpFull();
+      }
+      LOG << "INSERTED DATA" << std::endl;      
+    }    
+  
+    //------------
+    // WRITE DATA
+    //------------
+
+    if ( dbRead ) {
+
+      unsigned nBulks = 100;
+      unsigned nInBulk = 1000;
+
+      unsigned iBulk;
+      unsigned iInBulk;
+      
+      // READ DATA one by one
+      LOG << "READ DATA (one IOV by one IOV)" << std::endl;
+      for ( iBulk=0; iBulk<nBulks; iBulk++ ) {
+        cool::TimingReport timeReport;
+        std::stringstream msg;
+        msg << "Reading group # " << iBulk+1 
+            << " of " << nInBulk << " IOVS each";      
+        seal::TimingItem& timeItem = timeReport.item( msg.str() );
+        seal::SealTimer* timer = new seal::SealTimer( timeItem );
+        LOG << "Reading group #" << iBulk+1 << std::endl;
+        for ( iInBulk=0; iInBulk<nInBulk; iInBulk++ ) {
+          ValidityKey bulkSince = iBulk*nInBulk + iInBulk;
+          folder->findObject( bulkSince*1000+1, 1 );
+        }
+        delete timer;        
+        timeReport.dumpFull();
+      }
+      LOG << "READ DATA" << std::endl;      
+    }    
+  
+    // Successful completion
+    LOG << "Program terminating succesfully" << std::endl;
+    status = 0;
+    
+  }
+  catch(seal::Exception& se) 
+  {
+    LOG << "ERROR! Seal Exception: '" << se << "'" << std::endl;
+    status = 1;
+  }
+  catch(std::exception& e)
+  {
+    LOG << "ERROR! Standard C++ exception: '" << e.what() << "'" << std::endl;
+    status = 1;
+  }
+  catch(...) 
+  {
+    LOG << "ERROR! Unknown exception caught" << std::endl;
+    status = 1;
+  }
+
+  // Program termination
+  LOG << "Exiting main" << std::endl;
+  return status;
+  
+}
+
+//-----------------------------------------------------------------------------
+
+#endif // NOPORT
diff --git a/RelationalCool/tests/TransactionHandling/test_TransactionHandling.cpp b/RelationalCool/tests/TransactionHandling/test_TransactionHandling.cpp
new file mode 100644
index 000000000..b0c08bbc6
--- /dev/null
+++ b/RelationalCool/tests/TransactionHandling/test_TransactionHandling.cpp
@@ -0,0 +1,282 @@
+// PORT -- temporarily disabled: not part of our official test suite
+int main() { return 0; }
+#ifdef NOPORT
+
+/**
+
+@file test_TransactionHandling.cpp
+
+@author Sven A. Schmidt, Ulrich Moosbrugger
+
+@date 2005-09-30
+
+*/
+
+
+#include<cppunit/extensions/HelperMacros.h>
+
+#include "CoolKernel/IFolder.h"
+#include "CoolKernel/IObject.h"
+#include "CoolKernel/IObjectIterator.h"
+#include "CoolKernel/IDatabaseSvc.h"
+#include "CoolKernel/Exception.h"
+#include "src/RalDatabase.h"
+#include "src/RelationalTransaction.h"
+
+#include "AttributeList/AttributeValueAccessor.h"
+using coral::AttributeList;
+using coral::AttributeListSpecification;
+typedef boost::shared_ptr<AttributeListSpecification> SpecPtr;
+
+#include "src/sleep.h"
+
+#include <string>
+using std::cout;
+using std::cerr;
+using std::endl;
+using std::string;
+using std::stringstream;
+
+#include <vector>
+using std::vector;
+
+#ifndef WIN32
+
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <unistd.h>
+#include <pthread.h>
+
+#else
+
+#include <windows.h>
+
+#endif
+
+namespace cool {
+  
+  /// Function to be excuted by the secondary thread.
+  /// To avoid extra C++ packages for multithreading support,
+  /// the standard c- pthread library has been used. Therefore
+  /// this method has to be static.
+    
+#ifndef WIN32
+  void* 
+#else
+  DWORD WINAPI
+#endif
+  fetch( void* folder ) {
+    try {
+      IFolder* ifolder = static_cast<IFolder*>(folder);
+      ifolder->browseObjects( (ValidityKey)0, ValidityKeyMax );
+    } catch ( std::exception& e ) {
+      cout << "std::exception (secondary thread): " << e.what() << endl;
+      throw e;
+    }
+    
+#ifndef WIN32
+    pthread_exit(0);
+#else
+    ExitThread(0);
+#endif
+  }
+
+  const char* COOLTESTDB = "COOLTESTDB";
+  
+  /// Multiple transactions test class
+  class MultipleTransaction : public CppUnit::TestFixture {
+		
+    CPPUNIT_TEST_SUITE( MultipleTransaction );
+    
+#ifndef WIN32
+    CPPUNIT_TEST( test_Fork );  
+#endif
+    CPPUNIT_TEST( test_RelationalTransaction );
+    CPPUNIT_TEST( test_MultiThread );  
+    
+    CPPUNIT_TEST_SUITE_END();
+		
+public:
+    
+    AttributeListSpecification mixedPayloadSpec;
+    string connectString;
+    IDatabasePtr db;
+    
+    //----------------------------------------------------------------------------
+    
+    /// Start two RAL transactions to provoke a seal exception
+    void test_RelationalTransaction()
+    {
+      bool readOnly = true;
+      RalDatabase* ralDb; // safely cast pointer to db
+      ralDb = dynamic_cast<RalDatabase*>(db.get());
+      
+      try {
+        RelationalTransaction t1( ralDb->transactionMgr(), readOnly );
+        RelationalTransaction t2( ralDb->transactionMgr(), readOnly );
+        CPPUNIT_FAIL( "expected exception" );
+      } catch ( std::exception& e ) {
+        CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "expected transaction related exception",
+          string( "Could not start a new read-only transaction" ), 
+          string( e.what() ) );
+      }
+    }
+    
+
+#ifndef WIN32
+    /// Test transaction behavior from a forked process. Note that while this
+    /// (currently) works in the read only case, it probably does because
+    /// the read only case is safe. Forking copies the process and we are
+    /// probably tricking RAL to think that it has only one transaction open
+    /// as we copy its state with only one transaction open.
+    /// Most likely this will break horribly if one process does writing. This
+    /// should be implemented in a separate test.
+    /// There is no easy way to assert the test condition with CPPUNIT macros.
+    /// It therefore relies on the printout to be inspected.
+    void test_Fork() 
+    {
+      cout << "** test_Fork start **" << endl;
+
+      IFolderPtr folder = db->createFolder( "/myfolder", mixedPayloadSpec );
+      folder->setupStorageBuffer();
+      for ( long i = 0; i < 5000; ++i ) {
+        folder->storeObject( (ValidityKey)i, ValidityKeyMax, 
+                             mixedPayload( i ) );
+      }
+      folder->flushStorageBuffer();
+      
+      // Get a child process.
+      int pid, status;
+      if ( (pid = fork()) < 0 )
+      {
+        cerr << "Could not fork process!" << endl;
+        exit(1);
+      }
+      
+      // The child executes the code inside the if.
+      if (pid == 0)
+      {
+        cout << "Child process (PID " << pid << ") starts browseObjects" 
+             << endl;
+        folder->browseObjects( (ValidityKey)0, ValidityKeyMax );
+        cout << "Finished child process " << pid << endl;
+        exit(1);
+      } 
+      
+      // The parent executes  the same browseObject and then waits.
+      if (pid != 0)
+      {
+        cout << "Parent process (PID " << pid << " ) starts browseObjects"
+             << endl;
+        folder->browseObjects( (ValidityKey)0, ValidityKeyMax );
+        cout << "Finished parent process " << pid << endl;
+      } 
+      
+      while ( wait(&status) != pid);
+      
+      cout << "This test passed if the second process successfully started a "
+           << "browseObjects operation before the first process finished its "
+           << "own." << endl;
+      cout << "** test_Fork end **" << endl;
+    }
+#endif
+    
+    /// Check on multi threaded access
+    /// and provoke a seal exception
+    void test_MultiThread() {
+      IFolderPtr folder = db->createFolder( "/myfolder", mixedPayloadSpec );
+      
+      folder->setupStorageBuffer();
+      for ( long i = 0; i < 5000; ++i ) {
+        folder->storeObject( (ValidityKey)i, ValidityKeyMax, 
+                             mixedPayload( i ) );
+      }
+      folder->flushStorageBuffer();
+      
+      // pthread_create expects void* as argument
+      void* threadFolderPtr = folder.get();
+#ifndef WIN32
+      pthread_t helper;
+      pthread_create(&helper, NULL, fetch, threadFolderPtr );
+#else
+      HANDLE a_thread;
+      DWORD a_threadId;
+      DWORD thread_result;
+      a_thread = CreateThread(NULL, 0, fetch, threadFolderPtr,0, &a_threadId);
+#endif
+
+      try {
+        // try to assure that the main thread tries to open the 
+        // second transaction and hence  throws the exception
+        // which can be caught by the CPPUNIT framework
+        // If 1s is not sufficient, increase the number of objects
+        // in the folder.
+        cool::sleep(1);
+        folder->browseObjects( (ValidityKey)0, ValidityKeyMax );
+        CPPUNIT_FAIL( "expected exception" );
+      } catch ( std::exception& e ) {
+        CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "expected transaction related exception",
+          string( "Could not start a new read-only transaction" ), 
+          string( e.what() ) );
+      }
+      
+#ifndef WIN32
+      pthread_join(helper, NULL);
+#else
+      if (WaitForSingleObject(a_thread, INFINITE) != WAIT_OBJECT_0) {
+        CPPUNIT_FAIL("Thread join failed");
+      }
+#endif
+    }    
+    
+    /// Creates a dummy payload AttributeList for a given index
+    AttributeList mixedPayload( int index ) {
+      AttributeList payload( mixedPayloadSpec );
+      payload["I"].setValue<int>( index );
+      return payload;
+    }
+    
+    
+    /// Setup prerequisites for all unit tests
+    void setUp() 
+    {
+      if ( mixedPayloadSpec.size() == 0 )
+      {
+        mixedPayloadSpec.push_back("I","int");
+      }
+      
+      if ( getenv( COOLTESTDB ) ) {
+        connectString = getenv( COOLTESTDB );
+      } else {
+        cout << "Please provide a connect string by "
+        << "specifying one in the environment variable COOLTESTDB, e.g." 
+        << endl;
+        cout << "setenv COOLTESTDB "
+          << "\"oracle://devdb10;schema=lcg_cool;dbname=COOLTEST\"" << endl;
+        cout << "Aborting test" << endl;
+        exit(-1);
+      }
+      
+      static CoralApplication app;
+      IDatabaseSvc& dbSvc = app.databaseService();
+      dbSvc.dropDatabase( connectString );
+      db = dbSvc.createDatabase( connectString );
+    }
+		
+    void tearDown() {
+      db.reset();
+    }
+    
+  };
+  
+  CPPUNIT_TEST_SUITE_REGISTRATION( MultipleTransaction );
+  
+} // namespace
+
+// sas: This file is from the OPAL package I believe. It allows for
+// shorter test classes and prepares the test class for OPAL
+#include<CppUnit_testdriver.icpp>
+
+#endif // NOPORT
diff --git a/RelationalCool/tests/VersionNumber/test_VersionNumber.cpp b/RelationalCool/tests/VersionNumber/test_VersionNumber.cpp
new file mode 100644
index 000000000..3bc24262e
--- /dev/null
+++ b/RelationalCool/tests/VersionNumber/test_VersionNumber.cpp
@@ -0,0 +1,114 @@
+// $Id: test_VersionNumber.cpp,v 1.2 2006-11-28 08:35:30 avalassi Exp $
+#include "CoolUnitTest.h"
+
+// Include files 
+#include "../../src/VersionNumber.h"
+
+namespace cool {
+  class VersionNumberTest:public CoolUnitTest {
+    
+    CPPUNIT_TEST_SUITE( VersionNumberTest );
+
+    CPPUNIT_TEST( test_constructor );
+    CPPUNIT_TEST( test_conversion );
+    CPPUNIT_TEST( test_print );
+    CPPUNIT_TEST( test_comparison );
+
+    CPPUNIT_TEST_SUITE_END();
+		
+  public:
+    
+    void setUp() {
+      /// prepare for the test
+    }
+
+    void tearDown(){
+      /// clean up after the test
+    }    
+
+    // ------------------------------------------------------
+    // The tests
+    // ------------------------------------------------------
+
+    // -- allowed macros
+    // CPPUNIT_ASSERT(condition)
+    // CPPUNIT_ASSERT_MESSAGE(message,condition)
+    // CPPUNIT_ASSERT_EQUAL(expected,actual)
+    // CPPUNIT_ASSERT_EQUAL_MESSAGE(message,expected,actual)
+    // CPPUNIT_ASSERT_DOUBLES_EQUAL(expected,actual,delta)
+    // CPPUNIT_ASSERT_THROW( expression, ExceptionType )
+    // CPPUNIT_ASSERT_NO_THROW( expression )
+
+    // ------------------------------------------------------
+    void test_constructor() {
+    // ------------------------------------------------------
+      VersionNumber a("1.2.3");
+      CPPUNIT_ASSERT_MESSAGE("char * constructor failed",
+                             a.majorVersion() == 1 
+                             && a.minorVersion() == 2 
+                             && a.patchVersion() == 3);
+      
+      VersionNumber b(std::string("3.4.5"));
+      CPPUNIT_ASSERT_MESSAGE("std::string constructor failed",
+                             b.majorVersion() == 3 
+                             && b.minorVersion() == 4 
+                             && b.patchVersion() == 5);
+      
+      CPPUNIT_ASSERT_THROW( VersionNumber("x.y") , std::runtime_error );
+    }
+    
+    // ------------------------------------------------------
+    void test_conversion() {
+    // ------------------------------------------------------
+      VersionNumber a("1.2.3");
+      std::string s = a;
+      CPPUNIT_ASSERT( s == "1.2.3" );
+    }
+    
+    // ------------------------------------------------------
+    void test_print() {
+    // ------------------------------------------------------
+      VersionNumber a("9.8.7");
+      std::ostringstream o;
+      o << a;
+      CPPUNIT_ASSERT( o.str() == (std::string)a );
+    }
+
+#define TEST_CMP_LT(A,B) CPPUNIT_ASSERT_MESSAGE \
+      ( A " < "  B, VersionNumber(A) < B )
+    
+#define TEST_CMP_EQ(A,B) CPPUNIT_ASSERT_MESSAGE \
+      ( A " == " B, VersionNumber(A) == B )
+    
+#define TEST_CMP_GT(A,B) CPPUNIT_ASSERT_MESSAGE \
+      ( A " > " B, VersionNumber(A) > B )
+    
+#define TEST_CMP(A,B) TEST_CMP_LT(A,B);\
+                      TEST_CMP_EQ(A,A);\
+                      TEST_CMP_EQ(B,B);\
+                      TEST_CMP_GT(B,A);
+    // ------------------------------------------------------
+    void test_comparison() {
+    // ------------------------------------------------------
+    
+      TEST_CMP( "1.0.0", "2.0.0" );
+      TEST_CMP( "0.1.0", "0.2.0" );
+      TEST_CMP( "0.0.1", "0.0.2" );
+      
+      TEST_CMP( "0.999.0", "1.0.2" );
+      TEST_CMP( "0.0.999", "0.1.0" );
+      
+    }
+
+#undef  TEST_CMP_LT 
+#undef  TEST_CMP_EQ 
+#undef  TEST_CMP_GT 
+#undef  TEST_CMP 
+    
+  };
+
+CPPUNIT_TEST_SUITE_REGISTRATION( VersionNumberTest );
+  
+}
+
+COOLTEST_MAIN(VersionNumberTest)
diff --git a/RelationalCool/tests/authentication.xml b/RelationalCool/tests/authentication.xml
new file mode 100755
index 000000000..de4a031e7
--- /dev/null
+++ b/RelationalCool/tests/authentication.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0" ?>
+<connectionlist>
+
+<!-- Oracle server for COOL tests -->
+<connection name="oracle://lcg_cool_nightly/lcg_cool_nightly">
+  <parameter name="user" value="lcg_cool_nightly" />
+  <parameter name="password" value="PASSWORD" />
+</connection>
+
+<!-- MySQL server for COOL tests -->
+<connection name="mysql://itrac424.cern.ch:3306/LCG_COOL_NIGHTLY">
+  <parameter name="user" value="LCG_COOL_NIGHTLY" />
+  <parameter name="password" value="PASSWORD" />
+</connection>
+
+</connectionlist>
diff --git a/RelationalCool/tests/dblookup.xml b/RelationalCool/tests/dblookup.xml
new file mode 100644
index 000000000..b2611d913
--- /dev/null
+++ b/RelationalCool/tests/dblookup.xml
@@ -0,0 +1,124 @@
+<?xml version="1.0" ?>
+<servicelist>
+
+
+  <logicalservice name="Oracle-avalassi">
+    <service name="oracle://lcg_cool_nightly/lcg_cool" accessMode="update" authentication="password" />
+  </logicalservice>
+  
+  <logicalservice name="Oracle-marcocle">
+    <service name="oracle://lcg_cool_nightly/marcocle" accessMode="update" authentication="password" />
+    <!--service name="oracle://devdb10/lhcb_lcg_cool_dev" accessMode="update" authentication="password" /-->
+  </logicalservice>
+
+  <logicalservice name="Oracle-clemenci">
+    <service name="oracle://lcg_cool_nightly/marcocle" accessMode="update" authentication="password" />
+  </logicalservice>
+
+  <logicalservice name="Oracle-sas">
+    <service name="oracle://devdb10/atlas_cool_sas" accessMode="update" authentication="password" />
+  </logicalservice>
+
+
+  <logicalservice name="MySQL-avalassi">
+    <service name="mysql://itrac424.cern.ch:3306/LCG_COOL" accessMode="update" authentication="password" />
+    <!--service name="mysql://pcitdb59/COOLDB" accessMode="update" authentication="password" /-->
+    <!--service name="mysql://pclhcb55.cern.ch/AVALASSI" accessMode="update" authentication="password" /-->
+  </logicalservice>
+
+  <logicalservice name="MySQL-marcocle">
+    <service name="mysql://pclhcb55.cern.ch/MARCOCLE" accessMode="update" authentication="password" />
+  </logicalservice>
+
+  <logicalservice name="MySQL-clemenci">
+    <service name="mysql://pclhcb55.cern.ch/MARCOCLE" accessMode="update" authentication="password" />
+  </logicalservice>
+
+  <logicalservice name="MySQL-sas">
+    <service name="mysql://localhost/cooltest" accessMode="update" authentication="password" />
+  </logicalservice>
+
+
+  <!-- Oracle on pdbr, Frontier and squid on frontier3d:8080 and :8000 -->
+  <logicalservice name="Frontier-avalassi">
+    <!--service name="frontier://frontier3d:8080/lcg_cool_nightly/lcg_cool" accessMode="readonly" authentication="password" /-->
+    <!-- DISABLE THE CLIENT-SIDE CACHE (clientcachemaxresultsize=0) -->
+    <service name="frontier://(serverurl=http://frontier3d:8080/lcg_cool_nightly)(clientcachemaxresultsize=0)/lcg_cool" accessMode="readonly" authentication="password" />
+    <service name="oracle://lcg_cool_nightly/lcg_cool" accessMode="update" authentication="password" />
+  </logicalservice>
+
+  <logicalservice name="FrontierCache-avalassi">
+    <!--service name="frontier://frontier3d:8000/lcg_cool_nightly/lcg_cool" accessMode="readonly" authentication="password" /-->
+    <!-- DISABLE THE CLIENT-SIDE CACHE (clientcachemaxresultsize=0) -->
+    <!-- USE ENV VARIABLE FRONTIER_FORCERELOAD TO DETERMINE RELOAD SETTINGS -->
+    <service name="frontier://(serverurl=http://frontier3d:8000/lcg_cool_nightly)(clientcachemaxresultsize=0)/lcg_cool" accessMode="readonly" authentication="password" />
+    <!-- DISABLE THE CLIENT-SIDE CACHE (clientcachemaxresultsize=0) -->
+    <!-- DO NOT FORCE IMMEDIATE RELOAD OF ANY QUERIES (forcereload=none) -->
+    <!--service name="frontier://(serverurl=http://frontier3d:8000/lcg_cool_nightly)(clientcachemaxresultsize=0)(forcereload=none)/lcg_cool" accessMode="readonly" authentication="password" /-->
+    <!-- DISABLE THE CLIENT-SIDE CACHE (clientcachemaxresultsize=0) -->
+    <!-- FORCE IMMEDIATE RELOAD OF SHORT-LIVED QUERIES (forcereload=short) -->
+    <!--service name="frontier://(serverurl=http://frontier3d:8000/lcg_cool_nightly)(clientcachemaxresultsize=0)(forcereload=short)/lcg_cool" accessMode="readonly" authentication="password" /-->
+    <!-- DISABLE THE CLIENT-SIDE CACHE (clientcachemaxresultsize=0) -->
+    <!-- FORCE IMMEDIATE RELOAD OF ALL QUERIES (forcereload=long) -->
+    <!--service name="frontier://(serverurl=http://frontier3d:8000/lcg_cool_nightly)(clientcachemaxresultsize=0)(forcereload=long)/lcg_cool" accessMode="readonly" authentication="password" /-->
+    <service name="oracle://lcg_cool_nightly/lcg_cool" accessMode="update" authentication="password" />
+  </logicalservice>
+
+  <!--logicalservice name="FrontierR-avalassi">
+    <service name="frontier://frontier3d:8080/lcg_cool_nightly/lcg_cool" accessMode="readonly" authentication="password" />
+  </logicalservice-->  
+
+  <!-- Oracle on pdbr, Frontier and squid on frontier3d:8080 and :8000 -->  
+  <logicalservice name="Frontier-marcocle">
+    <!--service name="frontier://frontier3d:8080/lcg_cool_nightly/marcocle" accessMode="readonly" authentication="password" /-->
+    <service name="frontier://(serverurl=http://frontier3d:8080/lcg_cool_nightly)(clientcachemaxresultsize=0)/marcocle" accessMode="readonly" authentication="password" />
+    <service name="oracle://lcg_cool_nightly/marcocle" accessMode="update" authentication="password" />
+  </logicalservice>
+  
+  <logicalservice name="FrontierCache-marcocle">
+    <service name="frontier://(serverurl=http://frontier3d:8000/lcg_cool_nightly)(clientcachemaxresultsize=0)/marcocle" accessMode="readonly" authentication="password" />
+    <service name="oracle://lcg_cool_nightly/marcocle" accessMode="update" authentication="password" />
+  </logicalservice>
+
+  <!--logicalservice name="FrontierR-marcocle">
+    <service name="frontier://frontier3d:8080/lcg_cool_nightly/marcocle" accessMode="readonly" authentication="password" />
+  </logicalservice-->
+
+  <!-- Coral Server tests -->  
+  <logicalservice name="/tests/db_ora/admin">
+    <service name="oracle://lcg_cool_nightly/lcg_cool" accessMode="update" authentication="password" />
+  </logicalservice>
+  <logicalservice name="/tests/db_cor/admin">
+    <service name="coral://localhost:8080|oracle://lcg_cool_nightly/lcg_cool" accessMode="update" authentication="password" />
+  </logicalservice>
+
+  <!-- COOL nightly tests - START -->
+
+  <logicalservice name="Oracle-lcgnight">
+    <service name="oracle://lcg_cool_nightly/lcg_cool_nightly" accessMode="update" authentication="password" />
+  </logicalservice>
+
+  <logicalservice name="MySQL-lcgnight">
+    <service name="mysql://itrac424.cern.ch:3306/LCG_COOL_NIGHTLY" accessMode="update" authentication="password" />
+  </logicalservice>
+
+  <logicalservice name="Frontier-lcgnight">
+    <!--service name="frontier://frontier3d:8080/lcg_cool_nightly/lcg_cool_nightly" accessMode="readonly" authentication="password" /-->
+    <!-- DISABLE THE CLIENT-SIDE CACHE (clientcachemaxresultsize=0) -->
+    <service name="frontier://(serverurl=http://frontier3d:8080/lcg_cool_nightly)(clientcachemaxresultsize=0)/lcg_cool_nightly" accessMode="readonly" authentication="password" />
+    <service name="oracle://lcg_cool_nightly/lcg_cool_nightly" accessMode="update" authentication="password" />
+  </logicalservice>
+
+  <logicalservice name="FrontierCache-lcgnight">
+    <service name="frontier://(serverurl=http://frontier3d:8000/lcg_cool_nightly)(clientcachemaxresultsize=0)/lcg_cool_nightly" accessMode="readonly" authentication="password" />
+    <service name="oracle://lcg_cool_nightly/lcg_cool_nightly" accessMode="update" authentication="password" />
+  </logicalservice>
+
+  <!-- This is only needed for LCG54 (dev3) tests -->
+  <logicalservice name="FrontierR-lcgnight">
+    <service name="frontier://frontier3d:8080/lcg_cool_nightly/lcg_cool_nightly" accessMode="readonly" authentication="password" />
+  </logicalservice>
+
+  <!-- COOL nightly tests - END -->
+
+</servicelist>
diff --git a/RelationalCool/tests/seal.opts b/RelationalCool/tests/seal.opts
new file mode 100644
index 000000000..a9a384d9a
--- /dev/null
+++ b/RelationalCool/tests/seal.opts
@@ -0,0 +1,19 @@
+// SEAL MessageService verbosity level
+// Verbose=1, Debug=2, Info=3, Warning=4, Error=5, Fatal=6
+SEAL/Services/MessageService.OutputLevel=2;
+
+// SEAL MessageService output format
+// Note: MessageService.cpp implements reportMessage() using Msg::LevelTxt[]
+// Note: MessageStream.cpp defines Msg::LevelTxt[] using lowercase strings
+SEAL/Services/MessageService.Format="%-36s %-8s %s";
+
+// CORAL XMLAuthenticationService authentication file
+// The path to this file may be set in the CORAL_AUTH_PATH environment variable
+CORAL/Services/XMLAuthenticationService.AuthenticationFile="$CORAL_AUTH_PATH/authentication.xml";
+
+// CORAL XMLLookupService db file
+// The path to this file may be set in the CORAL_DBLOOKUP_PATH environment variable
+CORAL/Services/XMLLookupService.LookupFile="$CORAL_DBLOOKUP_PATH/dblookup.xml";
+
+// CORAL ConnectionService connection pool purge frequency (seconds)
+CORAL/Services/ConnectionService.PoolCleanUpPeriod = 1;
diff --git a/RelationalCool/tests/seal.opts.error b/RelationalCool/tests/seal.opts.error
new file mode 100644
index 000000000..44f7fb580
--- /dev/null
+++ b/RelationalCool/tests/seal.opts.error
@@ -0,0 +1,19 @@
+// SEAL MessageService verbosity level
+// Verbose=1, Debug=2, Info=3, Warning=4, Error=5, Fatal=6
+SEAL/Services/MessageService.OutputLevel=5;
+
+// SEAL MessageService output format
+// Note: MessageService.cpp implements reportMessage() using Msg::LevelTxt[]
+// Note: MessageStream.cpp defines Msg::LevelTxt[] using lowercase strings
+SEAL/Services/MessageService.Format="%-36s %-8s %s";
+
+// CORAL XMLAuthenticationService authentication file
+// The path to this file may be set in the CORAL_AUTH_PATH environment variable
+CORAL/Services/XMLAuthenticationService.AuthenticationFile="$CORAL_AUTH_PATH/authentication.xml";
+
+// CORAL XMLLookupService db file
+// The path to this file may be set in the CORAL_DBLOOKUP_PATH environment variable
+CORAL/Services/XMLLookupService.LookupFile="$CORAL_DBLOOKUP_PATH/dblookup.xml";
+
+// CORAL ConnectionService connection pool purge frequency (seconds)
+CORAL/Services/ConnectionService.PoolCleanUpPeriod = 1;
diff --git a/RelationalCool/tests/seal.opts.info b/RelationalCool/tests/seal.opts.info
new file mode 100644
index 000000000..329ac1961
--- /dev/null
+++ b/RelationalCool/tests/seal.opts.info
@@ -0,0 +1,19 @@
+// SEAL MessageService verbosity level
+// Verbose=1, Debug=2, Info=3, Warning=4, Error=5, Fatal=6
+SEAL/Services/MessageService.OutputLevel=3;
+
+// SEAL MessageService output format
+// Note: MessageService.cpp implements reportMessage() using Msg::LevelTxt[]
+// Note: MessageStream.cpp defines Msg::LevelTxt[] using lowercase strings
+SEAL/Services/MessageService.Format="%-36s %-8s %s";
+
+// CORAL XMLAuthenticationService authentication file
+// The path to this file may be set in the CORAL_AUTH_PATH environment variable
+CORAL/Services/XMLAuthenticationService.AuthenticationFile="$CORAL_AUTH_PATH/authentication.xml";
+
+// CORAL XMLLookupService db file
+// The path to this file may be set in the CORAL_DBLOOKUP_PATH environment variable
+CORAL/Services/XMLLookupService.LookupFile="$CORAL_DBLOOKUP_PATH/dblookup.xml";
+
+// CORAL ConnectionService connection pool purge frequency (seconds)
+CORAL/Services/ConnectionService.PoolCleanUpPeriod = 1;
diff --git a/RelationalCool/tests/seal.opts.verbose b/RelationalCool/tests/seal.opts.verbose
new file mode 100644
index 000000000..ae374f8c9
--- /dev/null
+++ b/RelationalCool/tests/seal.opts.verbose
@@ -0,0 +1,19 @@
+// SEAL MessageService verbosity level
+// Verbose=1, Debug=2, Info=3, Warning=4, Error=5, Fatal=6
+SEAL/Services/MessageService.OutputLevel=1;
+
+// SEAL MessageService output format
+// Note: MessageService.cpp implements reportMessage() using Msg::LevelTxt[]
+// Note: MessageStream.cpp defines Msg::LevelTxt[] using lowercase strings
+SEAL/Services/MessageService.Format="%-36s %-8s %s";
+
+// CORAL XMLAuthenticationService authentication file
+// The path to this file may be set in the CORAL_AUTH_PATH environment variable
+CORAL/Services/XMLAuthenticationService.AuthenticationFile="$CORAL_AUTH_PATH/authentication.xml";
+
+// CORAL XMLLookupService db file
+// The path to this file may be set in the CORAL_DBLOOKUP_PATH environment variable
+CORAL/Services/XMLLookupService.LookupFile="$CORAL_DBLOOKUP_PATH/dblookup.xml";
+
+// CORAL ConnectionService connection pool purge frequency (seconds)
+CORAL/Services/ConnectionService.PoolCleanUpPeriod = 1;
diff --git a/RelationalCool/tests/seal.opts.warning b/RelationalCool/tests/seal.opts.warning
new file mode 100644
index 000000000..492314cad
--- /dev/null
+++ b/RelationalCool/tests/seal.opts.warning
@@ -0,0 +1,19 @@
+// SEAL MessageService verbosity level
+// Verbose=1, Debug=2, Info=3, Warning=4, Error=5, Fatal=6
+SEAL/Services/MessageService.OutputLevel=4;
+
+// SEAL MessageService output format
+// Note: MessageService.cpp implements reportMessage() using Msg::LevelTxt[]
+// Note: MessageStream.cpp defines Msg::LevelTxt[] using lowercase strings
+SEAL/Services/MessageService.Format="%-36s %-8s %s";
+
+// CORAL XMLAuthenticationService authentication file
+// The path to this file may be set in the CORAL_AUTH_PATH environment variable
+CORAL/Services/XMLAuthenticationService.AuthenticationFile="$CORAL_AUTH_PATH/authentication.xml";
+
+// CORAL XMLLookupService db file
+// The path to this file may be set in the CORAL_DBLOOKUP_PATH environment variable
+CORAL/Services/XMLLookupService.LookupFile="$CORAL_DBLOOKUP_PATH/dblookup.xml";
+
+// CORAL ConnectionService connection pool purge frequency (seconds)
+CORAL/Services/ConnectionService.PoolCleanUpPeriod = 1;
diff --git a/RelationalCool/tests/setupLocalTns.csh b/RelationalCool/tests/setupLocalTns.csh
new file mode 100644
index 000000000..04f8dd025
--- /dev/null
+++ b/RelationalCool/tests/setupLocalTns.csh
@@ -0,0 +1 @@
+setenv TNS_ADMIN /$LOCALRT/src/RelationalCool/tests
diff --git a/RelationalCool/tests/sqlnet.ora b/RelationalCool/tests/sqlnet.ora
new file mode 100644
index 000000000..169f717d9
--- /dev/null
+++ b/RelationalCool/tests/sqlnet.ora
@@ -0,0 +1,2 @@
+IFILE = /afs/cern.ch/project/oracle/admin/sqlnet.ora
+
diff --git a/RelationalCool/tests/test_SealPluginDump.sh b/RelationalCool/tests/test_SealPluginDump.sh
new file mode 100755
index 000000000..1167e4717
--- /dev/null
+++ b/RelationalCool/tests/test_SealPluginDump.sh
@@ -0,0 +1,183 @@
+#! /bin/bash
+
+# Welcome printout
+echo "Executing SealPluginDump test"
+
+# Check SCRAM vs CMT
+if [ -z "$SCRAM_ARCH" ] && [ -n "$CMTCONFIG" ]; then
+    echo "SealPluginDump test will use CMT"
+    export SCRAM_ARCH="$CMTCONFIG"
+    export USECMT=yes
+else
+    echo "SealPluginDump test will use SCRAM"
+fi
+
+# Check O/S
+if [ "$OS" = "Windows_NT" ]; then
+    if [ "${SCRAM_ARCH:0:5}" != "win32" ]; then
+        echo "ERROR! Invalid SCRAM_ARCH $SCRAM_ARCH on $OS for $0"
+        exit 1
+    fi
+fi
+
+# Make sure LOCALRT is defined
+if [ -z "$USECMT" ]; then
+    export PATH=/afs/cern.ch/sw/lcg/app/spi/scram:"${PATH}"
+    eval `scram runtime -sh`
+    if [ "$LOCALRT" = "" ] ; then
+	echo "ERROR! Undefined LOCALRT - are you in a valid SCRAM directory?"
+	exit 1
+    fi
+else
+    export LOCALRT=`dirname $0`
+    export LOCALRT=`cd $LOCALRT/../../..; pwd`
+fi    
+export theLOCALRT=$LOCALRT
+
+# Keep the current SEAL options file if already defined
+export SEAL_CONFIGURATION_FILE_OLD=${SEAL_CONFIGURATION_FILE}
+
+# Load common functions
+if [ -r $theLOCALRT/config/test_functions.sh ] ; then
+    . $theLOCALRT/config/test_functions.sh
+elif [ -r $theLOCALRT/src/config/scram/test_functions.sh ] ; then
+    . $theLOCALRT/src/config/scram/test_functions.sh
+else
+    echo "ERROR! Cannot find common test functions"
+    exit 1
+fi
+
+# Prepare the environment
+set_preliminar_env
+if [ -z "$USECMT" ]; then
+    eval `scram runtime -sh`
+    export SEAL_CONFIGURATION_FILE=${theLOCALRT}/src/RelationalCool/tests/seal.opts.error
+    export unixToWinPathWine=${theLOCALRT}/src/config/scram/unixToWinPathWine.py
+else
+    source ${theLOCALRT}/src/config/cmt/setup.sh # NB this redefines LOCALRT
+fi
+fix_win_paths
+if [ "${SCRAM_ARCH:0:3}" = "win" ]; then
+    echo Time zone setting is TZ=\"$TZ\"
+fi
+
+# Keep the current SEAL options file if already defined
+if [ "$SEAL_CONFIGURATION_FILE_OLD" != "" ] ; then
+    export SEAL_CONFIGURATION_FILE=$SEAL_CONFIGURATION_FILE_OLD
+fi
+
+# Delete the COOL cache to test this test script
+###\rm $theLOCALRT/SCRAM/$SCRAM_ARCH/lib/modules/.cache
+
+# Execute SealPluginDump once to load the COOL plugins if not yet done
+cmd_wrapper SealPluginDump > /dev/null 2>&1 
+
+# Make a temporary directory
+tmpDir=`mktemp -d -t tmp.XXXXXXXXXX`
+
+# Execute SealPluginDump again and check the output
+( cmd_wrapper SealPluginDump > ${tmpDir}/stdout ) 2> ${tmpDir}/stderr
+
+# Fix problems under Wine
+dos2unix ${tmpDir}/stdout > /dev/null 2>&1
+dos2unix ${tmpDir}/stderr > /dev/null 2>&1
+
+# Analyse stderr: this should be empty
+###echo "*** STDERR: ***"; more ${tmpDir}/stderr
+if [ -s ${tmpDir}/stderr ]; then
+  more ${tmpDir}/stderr
+  echo "ERROR! Standard error is not empty!"
+  echo ""
+  echo "Failures !!!"
+  echo "Run: 1   Failure total: 1   Failures: 1   Errors: 0"
+  echo "[OVAL] Cppunit-result =1"
+  \rm -rf ${tmpDir}
+  exit 1
+fi
+
+# Analyse stdout: this should contain all relevant plugins
+###echo "*** STDOUT: ***"; more ${tmpDir}/stdout
+if [ "${SCRAM_ARCH:0:3}" = "win" ]; then
+    # Windows: all plugins but Frontier and LFC
+    expPlugins="COOL/Services/DatabaseService\
+                CORAL/RelationalPlugins/mysql\
+                CORAL/RelationalPlugins/oracle\
+                CORAL/RelationalPlugins/sqlite\
+                CORAL/Services/ConnectionService\
+                CORAL/Services/EnvironmentAuthenticationService\
+                CORAL/Services/MonitoringService\
+                CORAL/Services/RelationalService\
+                CORAL/Services/XMLAuthenticationService\
+                CORAL/Services/XMLLookupService\
+                CORAL/mysql/TypeConverter\
+                SEAL/Services/ConfigurationService\
+                SEAL/Services/DictionaryService\
+                SEAL/Services/MessageService\
+                SEAL/Services/PropertyCatalogue"
+elif [ "${SCRAM_ARCH:0:3}" = "osx" ]; then
+    # MacOSX: all plugins but Oracle and LFC
+    expPlugins="COOL/Services/DatabaseService\
+                CORAL/RelationalPlugins/frontier\
+                CORAL/RelationalPlugins/mysql\
+                CORAL/RelationalPlugins/sqlite\
+                CORAL/Services/ConnectionService\
+                CORAL/Services/EnvironmentAuthenticationService\
+                CORAL/Services/MonitoringService\
+                CORAL/Services/RelationalService\
+                CORAL/Services/XMLAuthenticationService\
+                CORAL/Services/XMLLookupService\
+                CORAL/mysql/TypeConverter\
+                SEAL/Services/ConfigurationService\
+                SEAL/Services/DictionaryService\
+                SEAL/Services/MessageService\
+                SEAL/Services/PropertyCatalogue"
+else
+    # Linux: all plugins
+    expPlugins="COOL/Services/DatabaseService\
+                CORAL/RelationalPlugins/frontier\
+                CORAL/RelationalPlugins/mysql\
+                CORAL/RelationalPlugins/oracle\
+                CORAL/RelationalPlugins/sqlite\
+                CORAL/Services/ConnectionService\
+                CORAL/Services/EnvironmentAuthenticationService\
+                CORAL/Services/LFCLookupService\
+                CORAL/Services/LFCReplicaService\
+                CORAL/Services/MonitoringService\
+                CORAL/Services/RelationalService\
+                CORAL/Services/XMLAuthenticationService\
+                CORAL/Services/XMLLookupService\
+                CORAL/mysql/TypeConverter\
+                SEAL/Services/ConfigurationService\
+                SEAL/Services/DictionaryService\
+                SEAL/Services/MessageService\
+                SEAL/Services/PropertyCatalogue"
+fi
+obsPlugins=`cat ${tmpDir}/stdout | grep -v "Category Loadable Component:"`
+for expPlugin in $expPlugins; do
+    found=0
+    ###echo Looking for \"$expPlugin\"
+    for obsPlugin in $obsPlugins; do
+        ###echo Testing \"$obsPlugin\"
+	if [ $expPlugin = $obsPlugin ]; then	    
+	    found=1
+	    echo Found $expPlugin
+	fi
+    done
+    if [ $found != 1 ]; then	    
+        more ${tmpDir}/stdout
+	echo "ERROR! Plugin $expPlugin not found!"
+	echo ""
+	echo "Failures !!!"
+	echo "Run: 1   Failure total: 1   Failures: 1   Errors: 0"
+	echo "[OVAL] Cppunit-result =1"
+	\rm -rf ${tmpDir}
+	exit 1
+    fi
+done
+
+# Success
+echo ""
+echo "OK (1)"
+echo "[OVAL] Cppunit-result =0"
+\rm -rf ${tmpDir}
+exit 0
diff --git a/RelationalCool/tests/tnsnames.ora b/RelationalCool/tests/tnsnames.ora
new file mode 100644
index 000000000..8dd5b0863
--- /dev/null
+++ b/RelationalCool/tests/tnsnames.ora
@@ -0,0 +1,24 @@
+# Add here the description of your private server
+# myserver =
+#   (DESCRIPTION =
+#      (ADDRESS_LIST =
+#        (ADDRESS = (PROTOCOL = TCP)(HOST = myhost.cern.ch)(PORT = 1521))
+#      )
+#      (CONNECT_DATA =
+#        (SERVICE_NAME = myservicename)
+#      )
+#    )
+
+# 3D Frontier test server
+bd3d =
+  (DESCRIPTION =
+    (ADDRESS = (PROTOCOL = TCP)(HOST = lxfs6043.cern.ch)(PORT = 1521))
+    (CONNECT_DATA =
+      (SID = bd3d)
+    )
+  )
+
+# Under cygwin, this path MUST start with '//'
+# Under Linux, both '/' and '//' would work
+IFILE = //afs/cern.ch/project/oracle/admin/tnsnames.ora
+
diff --git a/RelationalCool/tests/utility_methods/test_utilities.cpp b/RelationalCool/tests/utility_methods/test_utilities.cpp
new file mode 100644
index 000000000..841a68bf0
--- /dev/null
+++ b/RelationalCool/tests/utility_methods/test_utilities.cpp
@@ -0,0 +1,347 @@
+/**
+
+@file test_utilities.cpp
+
+@author Sven A. Schmidt and Andrea Valassi
+
+@date 2004-12-08
+
+*/
+
+#include "../Common/CppUnit_headers.h" // Disable CppUnit header warnings
+
+#include "src/timeToString.h"
+#include "CoolKernel/ChannelSelection.h"
+#include "CoolKernel/../src/SealTime.h"
+
+#include <cstring> // for memset
+#include <iostream>
+using std::string;
+using std::cout;
+using std::endl;
+
+// Needed for _tzset on Windows
+#ifdef WIN32
+#include <time.h>
+#endif
+
+// Needed for gmtime and timegm on Windows
+#ifdef WIN32
+#include <time.h>
+inline static time_t timegm (struct tm *t)
+{
+  // This code is copied as-is from SEAL Time.cpp
+  time_t t1 = mktime (t);
+  struct tm gmt = *gmtime (&t1);
+  time_t t2 = mktime (&gmt);
+  return t1 + (t1 - t2);
+}
+#endif
+
+
+namespace cool {
+  
+  
+  /// Test class for utility_methods
+  
+  class utility_methodsTest : public CppUnit::TestFixture {
+		
+    CPPUNIT_TEST_SUITE( utility_methodsTest );
+		
+    CPPUNIT_TEST( test_stringToTime );
+    CPPUNIT_TEST( test_timeToString );
+		
+    // The second test in this pair is kept only for reference: I thought that
+    // (not) calling tzset/_tzset would influence the result, but it does not!
+    CPPUNIT_TEST( test_sealTimeFromDate );
+    CPPUNIT_TEST( test_sealTimeFromDate_tzset );
+    
+    CPPUNIT_TEST( test_timegm_gmtime );
+    CPPUNIT_TEST( test_gmtime_timegm );
+    
+    CPPUNIT_TEST_SUITE_END();
+		
+public:
+      
+    void setUp() {  
+    }
+		
+    void tearDown() {
+    }
+		
+    
+    /// Tests that timegm( gmtime ( time_t ) ) = ( time_t )
+    /// NB: tm_years are # years after 1900
+    /// NB: time_t measures seconds after 1970-1-1
+    /// On Windows use private implementation of timegm (see SEAL Time.cpp)
+    void test_timegm_gmtime() {
+      time_t aTimet = (31+2)*86400+12*3600+62; // 2894462 (1970-2-3 12:01:02)
+      struct tm aTm = *gmtime( &aTimet );
+      time_t aTimetNew = timegm( &aTm );
+      bool verbose = false;
+      if ( verbose ) {
+        std::cout << "Test test_timegm_gmtime" << std::endl;
+        std::cout << "aTimet = " << aTimet << std::endl;
+        std::cout 
+        << "aTm = " 
+        << 1900+aTm.tm_year << "-" << aTm.tm_mon+1 << "-" << aTm.tm_mday 
+        << " " << aTm.tm_hour << ":" << aTm.tm_min << ":" << aTm.tm_sec
+        << " (DST=" << aTm.tm_isdst << ")" << std::endl;
+        std::cout << "aTimetNew = " << aTimetNew << std::endl;
+      }
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "timegm(gmtime(time_t))==time_t", aTimet, aTimetNew );
+    }
+    
+    /// Tests that gmtime( gmtime ( tm ) ) = ( tm )
+    /// On Windows use private implementation of timegm (see SEAL Time.cpp)
+    void test_gmtime_timegm() {
+      bool verbose = false;
+      struct tm aTm;
+      int month; // Months in [0-11]
+      for ( month = 0; month < 12; month++ ) {
+        int year = 70; // Years after 1900
+        int day = 03;
+        int hour = 12;
+        int minute = 01;
+        int second = 02;
+        // It seems that the +1 case should fail, but I fail with -1... why???!
+        memset (&aTm, sizeof(aTm), 0); // As in SEAL Time.cpp
+        aTm.tm_year = year;
+        aTm.tm_mon = month;
+        aTm.tm_mday = day;
+        aTm.tm_hour = hour;
+        aTm.tm_min = minute;
+        aTm.tm_sec = second;
+        if ( verbose ) {        
+          std::cout << "Test test_gmtime_timegm" << std::endl;
+          std::cout 
+          << "Before setting isdst:  aTm = " 
+          << 1900+aTm.tm_year << "-" << aTm.tm_mon+1 << "-" << aTm.tm_mday 
+          << " " << aTm.tm_hour << ":" << aTm.tm_min << ":" << aTm.tm_sec
+          << std::endl;
+        }      
+        // Test with tm_idst = -1
+        aTm.tm_isdst = -1;
+        if ( verbose ) std::cout 
+          << "Before calling timegm: aTm = " 
+          << 1900+aTm.tm_year << "-" << aTm.tm_mon+1 << "-" << aTm.tm_mday 
+          << " " << aTm.tm_hour << ":" << aTm.tm_min << ":" << aTm.tm_sec
+          << " (DST=" << aTm.tm_isdst << ")" << std::endl;
+        time_t aTimetM1 = timegm( &aTm );
+        if ( verbose ) std::cout 
+          << "After  calling timegm: aTm = " 
+          << 1900+aTm.tm_year << "-" << aTm.tm_mon+1 << "-" << aTm.tm_mday 
+          << " " << aTm.tm_hour << ":" << aTm.tm_min << ":" << aTm.tm_sec
+          << " (DST=" << aTm.tm_isdst << ")" << std::endl;
+        struct tm aTmM1;
+        aTmM1 = *gmtime( &aTimetM1 );
+        // Test with tm_idst = 0
+        aTm.tm_year = year;
+        aTm.tm_mon = month;
+        aTm.tm_mday = day;
+        aTm.tm_hour = hour;
+        aTm.tm_min = minute;
+        aTm.tm_sec = second;
+        aTm.tm_isdst = 0;
+        if ( verbose ) std::cout 
+          << "Before calling timegm: aTm = " 
+          << 1900+aTm.tm_year << "-" << aTm.tm_mon+1 << "-" << aTm.tm_mday 
+          << " " << aTm.tm_hour << ":" << aTm.tm_min << ":" << aTm.tm_sec
+          << " (DST=" << aTm.tm_isdst << ")" << std::endl;
+        time_t aTimet0 = timegm( &aTm );
+        if ( verbose ) std::cout 
+          << "After  calling timegm: aTm = " 
+          << 1900+aTm.tm_year << "-" << aTm.tm_mon+1 << "-" << aTm.tm_mday 
+          << " " << aTm.tm_hour << ":" << aTm.tm_min << ":" << aTm.tm_sec
+          << " (DST=" << aTm.tm_isdst << ")" << std::endl;
+        struct tm aTm0;
+        aTm0 = *gmtime( &aTimet0 );
+        // Test with tm_idst = +1
+        aTm.tm_year = year;
+        aTm.tm_mon = month;
+        aTm.tm_mday = day;
+        aTm.tm_hour = hour;
+        aTm.tm_min = minute;
+        aTm.tm_sec = second;
+        aTm.tm_isdst = +1;
+        if ( verbose ) std::cout 
+          << "Before calling timegm: aTm = " 
+          << 1900+aTm.tm_year << "-" << aTm.tm_mon+1 << "-" << aTm.tm_mday 
+          << " " << aTm.tm_hour << ":" << aTm.tm_min << ":" << aTm.tm_sec
+          << " (DST=" << aTm.tm_isdst << ")" << std::endl;
+        time_t aTimetP1 = timegm( &aTm );
+        if ( verbose ) std::cout 
+          << "After  calling timegm: aTm = " 
+          << 1900+aTm.tm_year << "-" << aTm.tm_mon+1 << "-" << aTm.tm_mday 
+          << " " << aTm.tm_hour << ":" << aTm.tm_min << ":" << aTm.tm_sec
+          << " (DST=" << aTm.tm_isdst << ")" << std::endl;
+        struct tm aTmP1;
+        aTmP1 = *gmtime( &aTimetP1 );
+        // Verbose printout
+        if ( verbose ) {        
+          std::cout 
+          << "aTm = " 
+          << 1900+year << "-" << month+1 << "-" << day 
+          << " " << hour << ":" << minute << ":" << second
+          << " (DST=-1,0,+1)" << std::endl;
+          std::cout << "aTimetM1 = " << aTimetM1 << std::endl;
+          std::cout 
+          << "aTmM1 = " 
+          << 1900+aTmM1.tm_year << "-" << aTmM1.tm_mon+1 
+          << "-" <<aTmM1.tm_mday
+          << " " << aTmM1.tm_hour << ":" << aTmM1.tm_min 
+          << ":" << aTmM1.tm_sec
+          << " (DST=" << aTmM1.tm_isdst << ")" << std::endl;
+          std::cout << "aTimet0 = " << aTimet0 << std::endl;
+          std::cout 
+          << "aTm0 = " 
+          << 1900+aTm0.tm_year << "-" << aTm0.tm_mon+1 
+          << "-" << aTm0.tm_mday 
+          << " " << aTm0.tm_hour << ":" << aTm0.tm_min 
+          << ":" << aTm0.tm_sec
+          << " (DST=" << aTm0.tm_isdst << ")" << std::endl;
+          std::cout << "aTimetP1 = " << aTimetP1 << std::endl;
+          std::cout 
+          << "aTmP1 = " 
+          << 1900+aTmP1.tm_year << "-" << aTmP1.tm_mon+1 
+          << "-" <<aTmP1.tm_mday
+          << " " << aTmP1.tm_hour << ":" << aTmP1.tm_min 
+          << ":" << aTmP1.tm_sec
+          << " (DST=" << aTmP1.tm_isdst << ")" << std::endl;
+        }
+        // Actual tests 
+        // Do NOT test isdst: gmtime ALWAYS returns isdst=0!
+        std::stringstream msg;
+        msg << " (Month[0-11]=" << month << ")";
+        CPPUNIT_ASSERT_EQUAL_MESSAGE
+          ( std::string("gmtime(timegm(tm,isDst=0))==tm : hour")+msg.str(), 
+            hour, aTm0.tm_hour );
+#ifndef WIN32
+        // The following tests FAIL on Windows!!!
+        CPPUNIT_ASSERT_EQUAL_MESSAGE
+          ( std::string("gmtime(timegm(tm,isDst=-1))==tm : hour")+msg.str(), 
+            hour, aTmM1.tm_hour );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE
+          ( std::string("gmtime(timegm(tm,isDst=+1))==tm : hour")+msg.str(), 
+            hour, aTmP1.tm_hour );
+#endif
+      }
+    }
+    
+    
+    /// Tests seal::Time constructor from y,mo,d,h,mi,s,ns,local
+    /// The test fails on Windows only for months from April onwards
+    void test_sealTimeFromDate() {
+      bool local = false; // Use UTC-GMT times
+      int month; // Months in [0-11]
+      for ( month = 0; month < 12; month++ ) {
+        int year = 1970; // Years after 1900
+        int day = 03;
+        int hour = 12;
+        int minute = 01;
+        int second = 02;
+        long nsecond = 123456789;
+        // AV 28.06.2005 Test for the BUG in seal::Time constructor...
+        // AV 18.01.2007 cool::SealTime uses months in [1-12]!!!
+        SealTime cTime( year, month+1, day, hour, minute, second, nsecond );
+        seal::Time sTime = cTime.sealTime();
+        time_t s1970 = (31+2)*86400+12*3600+62; // 2894462 (1970-2-3 12:01:02)
+        if ( month == 0 ) s1970 -= 31*86400; // Remove January
+        if ( month >= 2 ) s1970 += 28*86400; // Add February (365 day year)
+        if ( month >= 3 ) s1970 += 31*86400; // Add March
+        if ( month >= 4 ) s1970 += 30*86400; // Add April
+        if ( month >= 5 ) s1970 += 31*86400; // Add May
+        if ( month >= 6 ) s1970 += 30*86400; // Add June
+        if ( month >= 7 ) s1970 += 31*86400; // Add July
+        if ( month >= 8 ) s1970 += 31*86400; // Add August
+        if ( month >= 9 ) s1970 += 30*86400; // Add September
+        if ( month >= 10 ) s1970 += 31*86400; // Add October
+        if ( month >= 11 ) s1970 += 30*86400; // Add November          
+        std::stringstream msg;
+        msg << " (Month[0-11]=" << month << ")";
+        CPPUNIT_ASSERT_EQUAL_MESSAGE
+          ( std::string("ns from 1900")+msg.str(),
+            (seal::Time::ValueType)s1970*1000000000 + nsecond, sTime.ns() );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE
+          ( std::string("year")+msg.str(), year, sTime.year(local) );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE
+          ( std::string("month")+msg.str(), month, sTime.month(local) );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE
+          ( std::string("day")+msg.str(), day, sTime.day(local) );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE
+          ( std::string("hour")+msg.str(), hour, sTime.hour(local) );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE
+          ( std::string("minute")+msg.str(), minute, sTime.minute(local) );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE
+          ( std::string("second")+msg.str(), second, sTime.second(local) );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE
+          ( std::string("nsecond")+msg.str(), nsecond, sTime.nsecond() );
+      } 
+    } 
+    
+    
+    /// Tests seal::Time constructor AFTER CALLING tzset()
+    void test_sealTimeFromDate_tzset() {
+#ifdef WIN32
+      _tzset();
+#else
+      tzset();
+#endif
+      test_sealTimeFromDate();
+    }
+    
+    
+    /// Tests timeToString and stringToTime conversions
+    void test_timeToString() {
+      std::string aString1 = "2005-06-21_12:00:01.123456789 GMT";
+      Time aTime1 = stringToTime( aString1 );
+      std::string aString2 = timeToString( aTime1 );         
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "string 2 == string 1", aString1, aString2 );
+      Time aTime2 = stringToTime( aString2 );
+      std::string aString3 = timeToString( aTime2 );         
+      CPPUNIT_ASSERT_EQUAL_MESSAGE
+        ( "string 3 == string 2", aString2, aString3 );
+    } 
+    
+    
+    /// tests stringToTime
+    void test_stringToTime() {
+      try {
+        string s = "1970-02-03_12:01:02.123456789 GMT";
+        SealTime cTime = stringToTime( s );
+        seal::Time sTime = cTime.sealTime();
+        bool local = false;
+        CPPUNIT_ASSERT_EQUAL_MESSAGE
+          ( std::string("year"), 1970, sTime.year(local) );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE
+          ( std::string("month"), 2, sTime.month(local)+1 ); // month in [1-12]
+        CPPUNIT_ASSERT_EQUAL_MESSAGE
+          ( std::string("day"), 3, sTime.day(local) );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE
+          ( std::string("hour"), 12, sTime.hour(local) );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE
+          ( std::string("minute"), 01, sTime.minute(local) );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE
+          ( std::string("second"), 02, sTime.second(local) );
+        CPPUNIT_ASSERT_EQUAL_MESSAGE
+          ( std::string("nanoseconds"), (long)123456789, sTime.nsecond() );
+      } catch ( std::exception& e ) {
+        cout << e.what() << endl;
+        throw;
+      }
+      
+    }
+		
+  };
+  
+  CPPUNIT_TEST_SUITE_REGISTRATION( utility_methodsTest );
+  
+} // namespace
+
+// sas: This file is from the OPAL package I believe. It allows for
+// shorter test classes and prepares the test class for OPAL
+#include<CppUnit_testdriver.icpp>
+
+
diff --git a/RelationalCool/utilities/DBA/oracleCreateGenericReader.sql b/RelationalCool/utilities/DBA/oracleCreateGenericReader.sql
new file mode 100644
index 000000000..e7fbb5b7e
--- /dev/null
+++ b/RelationalCool/utilities/DBA/oracleCreateGenericReader.sql
@@ -0,0 +1,38 @@
+-- Experiment prefix
+--define EXPERIMENT=ATLAS;
+define EXPERIMENT=TESTEXP;
+
+-- Data tablespace
+define DATA_TS=USERS;
+--define DATA_TS=DATA01;
+
+-- Temp tablespace
+define TEMP_TS=TEMP;
+--define TEMP_TS=TEMP01;
+
+-- Generic reader user
+define USER_R_SUFFIX=_COOL_READER
+define USER_R=&EXPERIMENT&USER_R_SUFFIX;
+
+-- Password
+define PSWD_SUFFIX=_password
+define PSWD_R=&USER_R&PSWD_SUFFIX
+
+-- CROSS CHECK!
+--select '&EXPERIMENT', '&DATA_TS', '&TEMP_TS', '&USER_R', '&PSWD_R' from DUAL;
+
+/*
+--DROP USER &USER_R CASCADE;
+--*/
+
+--/*
+-- Create generic reader
+CREATE USER &USER_R
+PROFILE CERN_APP_PROFILE
+IDENTIFIED BY &PSWD_R
+DEFAULT TABLESPACE &DATA_TS
+TEMPORARY TABLESPACE &TEMP_TS
+QUOTA 10M ON &DATA_TS;
+
+GRANT CERN_APP_ROLE TO &USER_R;
+--*/
diff --git a/RelationalCool/utilities/DBA/oracleCreateSchemaOwner.sql b/RelationalCool/utilities/DBA/oracleCreateSchemaOwner.sql
new file mode 100644
index 000000000..de3d45c59
--- /dev/null
+++ b/RelationalCool/utilities/DBA/oracleCreateSchemaOwner.sql
@@ -0,0 +1,105 @@
+-- Experiment prefix
+--define EXPERIMENT=ATLAS;
+define EXPERIMENT=TESTEXP;
+
+-- Temp tablespace
+define TEMP_TS=TEMP;
+--define TEMP_TS=TEMP01;
+
+-- Generic reader user
+define USER_R_SUFFIX=_COOL_READER
+define USER_R=&EXPERIMENT&USER_R_SUFFIX;
+
+/* For tests */
+define DETECTOR=TESTDET;
+
+/* Accounts created on 2005/07/26 */
+--define DETECTOR=INDET;
+--define DETECTOR=TRT;
+--define DETECTOR=LAR;
+--define DETECTOR=TILE;
+--define DETECTOR=MUON;
+--define DETECTOR=MUONALIGN;
+--define DETECTOR=MDT;
+--define DETECTOR=TDAQ;
+--define DETECTOR=DCS;
+--define DETECTOR=GLOBAL;
+
+/* Accounts created on 2005/09/29 */
+--define DETECTOR=SCT;
+--define DETECTOR=PIXEL;
+
+-- Owner user
+define USER_SUFFIX=_COOL_
+define USER_O=&EXPERIMENT&USER_SUFFIX&DETECTOR;
+
+-- Data tablespace
+define DATA_TS_SUFFIX=_DATA01;
+define DATA_TS=&USER_O&DATA_TS_SUFFIX;
+
+-- Password
+define PSWD_SUFFIX=_password
+define PSWD_O=&USER_O&PSWD_SUFFIX
+
+-- Roles
+define R_ROLE_SUFFIX=_R;
+define R_ROLE=R_&USER_O&R_ROLE_SUFFIX;
+define W_ROLE_SUFFIX=_W;
+define W_ROLE=R_&USER_O&W_ROLE_SUFFIX;
+define T_ROLE_SUFFIX=_T;
+define T_ROLE=R_&USER_O&T_ROLE_SUFFIX;
+
+-- Writer user
+define USER_W=&USER_O&W_ROLE_SUFFIX;
+define PSWD_W=&USER_W&PSWD_SUFFIX
+
+-- CROSS CHECK!
+--select '&DETECTOR', '&USER_R', '&USER_O', '&DATA_TS', '&R_ROLE', '&W_ROLE', '&T_ROLE', '&USER_W', '&PSWD_O', '&PSWD_W' from DUAL;
+
+/*
+--DROP TABLESPACE &DATA_TS INCLUDING CONTENTS AND DATAFILES;
+--DROP USER &USER_O CASCADE;
+--DROP ROLE &R_ROLE;
+--DROP ROLE &W_ROLE;
+--DROP ROLE &T_ROLE;
+--DROP USER &USER_W CASCADE;
+--*/
+
+--/*
+-- Create tablespace
+CREATE TABLESPACE &DATA_TS
+DATAFILE SIZE 128M AUTOEXTEND ON NEXT 128M MAXSIZE 8192M LOGGING
+EXTENT MANAGEMENT LOCAL SEGMENT SPACE MANAGEMENT AUTO;
+
+-- Create owner
+CREATE USER &USER_O
+PROFILE CERN_DEV_PROFILE
+IDENTIFIED BY &PSWD_O
+DEFAULT TABLESPACE &DATA_TS
+TEMPORARY TABLESPACE &TEMP_TS
+QUOTA UNLIMITED ON &DATA_TS;
+
+GRANT CERN_DEV_ROLE TO &USER_O;
+
+-- Create roles
+CREATE ROLE &R_ROLE;
+CREATE ROLE &W_ROLE;
+CREATE ROLE &T_ROLE;
+
+-- Create writer
+CREATE USER &USER_W
+PROFILE CERN_APP_PROFILE
+IDENTIFIED BY &PSWD_W
+DEFAULT TABLESPACE &DATA_TS
+TEMPORARY TABLESPACE &TEMP_TS
+QUOTA 10M ON &DATA_TS;
+
+GRANT CERN_APP_ROLE TO &USER_W;
+
+GRANT &R_ROLE TO &USER_W;
+GRANT &W_ROLE TO &USER_W;
+GRANT &T_ROLE TO &USER_W;
+
+-- Grant reader role to generic reader
+GRANT &R_ROLE TO &USER_R;
+--*/
diff --git a/RelationalCool/utilities/coolAuthentication/coolAuthentication.cpp b/RelationalCool/utilities/coolAuthentication/coolAuthentication.cpp
new file mode 100644
index 000000000..e5548b49d
--- /dev/null
+++ b/RelationalCool/utilities/coolAuthentication/coolAuthentication.cpp
@@ -0,0 +1,389 @@
+// $Id: coolAuthentication.cpp,v 1.19 2009-02-09 18:56:15 avalassi Exp $
+
+// Include files
+#include <iostream>
+#include "CoolKernel/Exception.h"
+#include "CoolKernel/InternalErrorException.h"
+#include "RelationalAccess/AuthenticationServiceException.h"
+#include "RelationalAccess/IAuthenticationService.h"
+#include "RelationalAccess/IAuthenticationCredentials.h"
+#include "RelationalAccess/IDatabaseServiceSet.h"
+#include "RelationalAccess/IDatabaseServiceDescription.h"
+#include "RelationalAccess/ILookupService.h"
+#include "CoralKernel/Context.h"
+
+// Local include files
+#include "../../src/RalSessionMgr.h"
+#include "../../src/RelationalDatabaseId.h"
+
+// Namespace
+using namespace cool;
+
+// Message output
+#define LOG std::cout
+
+// flag to know if we already loaded the LFCReplicaSvc
+static bool lfcReplicaSvcLoaded = false;
+
+static coral::Context& context() {
+  static coral::Context& context = coral::Context::instance();
+  return context;
+}
+static void load(const std::string &component) {
+  context().loadComponent(component);
+}
+
+//-----------------------------------------------------------------------------
+
+coral::IHandle<coral::ILookupService> lookupSvc() 
+{
+  std::string svc_name;
+  // If we can access a LFC and the user is not explicitely forbidding it,
+  // we try to use CORAL LFCReplicaService
+  if ( ::getenv("COOL_IGNORE_LFC") == NULL && ::getenv("LFC_HOST") != NULL ) {
+    svc_name = "CORAL/Services/LFCReplicaService";
+    if ( ! lfcReplicaSvcLoaded ) {
+      // try to load CORAL LFCReplicaService
+      load( svc_name );
+      lfcReplicaSvcLoaded = true;
+    }
+  } else {
+    // We should check if the component is already loaded before loading it, 
+    // but I know that it will be loaded only once by the application
+    svc_name = "CORAL/Services/XMLLookupService";
+    load( svc_name );
+  }
+  
+  coral::IHandle<coral::ILookupService> svc =
+    context().query<coral::ILookupService>();
+  if ( ! svc.isValid() )
+    throw Exception
+      ( "Could not retrieve "+svc_name, "coolAuthentication" );
+  return svc;
+}
+
+//-----------------------------------------------------------------------------
+
+coral::IHandle<coral::IAuthenticationService> authSvc() 
+{
+  std::string svc_name; 
+  // If we can access a LFC and the user is not explicitely forbidding it,
+  // we try to use CORAL LFCReplicaService
+  if ( ::getenv("COOL_IGNORE_LFC") == NULL && ::getenv("LFC_HOST") != NULL ) {
+    svc_name = "CORAL/Services/LFCReplicaService";
+    if ( ! lfcReplicaSvcLoaded ) {
+      // try to load CORAL LFCReplicaService
+      load( svc_name );
+      lfcReplicaSvcLoaded = true;
+    }
+  } else {
+    // We should check if the component is already loaded before loading it, 
+    // but I know that it will be loaded only once by the application
+    svc_name = "CORAL/Services/XMLAuthenticationService";
+    load( svc_name );
+  }
+  
+  coral::IHandle<coral::IAuthenticationService> svc =
+    context().query<coral::IAuthenticationService>();
+  if ( ! svc.isValid() )
+    throw Exception
+      ( "Could not retrieve "+svc_name, "coolAuthentication" );
+  return svc;
+}
+
+//-----------------------------------------------------------------------------
+
+void authenticate( const std::string& coralReplica,
+                   const std::string& technology,
+                   std::string& user,
+                   std::string& password )
+{
+  try
+  {
+    // Get the authentication credentials from CORAL
+    const coral::IAuthenticationCredentials& cred = 
+      authSvc()->credentials( coralReplica );
+    user = cred.valueForItem( "user" );
+    password = cred.valueForItem( "password" );
+    if ( user == "" )
+      throw Exception
+        ( "Empty username credentials '' found for " + coralReplica,
+          "coolAuthentication" );
+    if ( password == "" ) 
+      throw Exception
+        ( "Empty password credentials '' found for " + coralReplica,
+          "coolAuthentication" );
+  }
+  catch( coral::UnknownConnectionException& /*exc*/ )
+  {
+    if ( technology == "sqlite" || technology == "frontier" ) 
+    {
+      //LOG << "WARNING: '" << exc.what() << "'" << std::endl;
+      //LOG << "WARNING: set DUMMY user and DUMMY password" << std::endl;
+      user = "DUMMY";
+      password = "DUMMY";
+    }
+    else throw;
+  }  
+}
+
+//-----------------------------------------------------------------------------
+
+void printOut( const std::string& coralReplica,
+               const std::string& coralMode,
+               const std::string& technology,
+               const std::string& server,
+               const std::string& schema,
+               const std::string& user,
+               const std::string& password )
+{
+  // Print out the database server properties
+  LOG << "==> coralReplica = " << coralReplica << std::endl;
+  LOG << "==> coralMode    = " << coralMode << std::endl;
+  LOG << "==> technology   = " << technology << std::endl;
+  LOG << "==> server       = " << server << std::endl;
+  LOG << "==> schema       = " << schema << std::endl;
+  
+  // Print out the authentication credentials
+  //LOG << "CORAL authentication credentials:" << std::endl;
+  LOG << "==> user         = " << user << std::endl;
+  LOG << "==> password     = " << password << std::endl;
+}
+
+//-----------------------------------------------------------------------------
+
+int main( int argc, char** argv )
+{
+
+  // *** TRY ***
+
+  try {
+    
+    // Get the COOL database identifier  
+    bool rwOnly = false;
+    bool firstOnly = false;
+    std::string dbId;
+    if ( argc == 3 && std::string(argv[1]) == "-1" ) 
+    {
+      firstOnly = true;
+      dbId = argv[2];
+    }
+    else if ( argc == 3 && std::string(argv[1]) == "-1RW" ) 
+    {
+      rwOnly = true;
+      firstOnly = true;
+      dbId = argv[2];
+    }
+    else if ( argc == 2 ) 
+    {
+      dbId = argv[1];
+    } 
+    else 
+    {
+      LOG << "Usage: " << argv[0] << " [-1|-1RW] dbId" << std:: endl;
+      LOG << "[Option -1: display only the first replica]" << std::endl;
+      LOG << "[Option -1RW: display only the first RW replica]" << std::endl;
+      std::string dbId1 = 
+        "oracle://SERVER;schema=SCHEMA;user=USER;password=PSWD;dbname=DB";
+      std::string dbId2 = 
+        "oracle://SERVER;schema=SCHEMA;dbname=DB";
+      std::string dbId3 = 
+        "alias/DB";
+      LOG << std::endl;
+      LOG << "Example: " << argv[0] << " '" << dbId1 << "'\n"
+          << "[Decode user and password from explicit credentials]"
+          << std::endl;
+      LOG << std::endl;
+      LOG << "Example: " << argv[0] << " '" << dbId2 << "'\n"
+          << "[Get user and password from authentication service]"
+          << std::endl;
+      LOG << std::endl;
+      LOG << "Example: " << argv[0] << " '" << dbId3 << "'\n"
+          << "[Get alias translation from dblookup service]"
+          << std::endl
+          << "[Get user and password from authentication service]"
+          << std::endl;
+      return 1;
+    }
+  
+    // --- TRANSLATE COOL URL into CORAL alias or explicit replica
+
+    // Parse the dbId URL as RelationalDatabaseId connection parameters
+    RelationalDatabaseId relationalDbId( dbId );
+
+    // Print out the database identification
+    LOG << "COOL databaseId" << std::endl;
+    LOG << "==> middleTier   = "
+        << relationalDbId.middleTier() << std::endl;
+    LOG << "==> url          = "
+        << relationalDbId.url() << std::endl;
+    LOG << "==> urlHidePswd  = "
+        << relationalDbId.urlHidePswd() << std::endl;
+
+    // Extract the connection parameters from the RelationalDbId
+    std::string middleTier ( relationalDbId.middleTier() );
+    std::string technology ( relationalDbId.technology() );
+    std::string server     ( relationalDbId.server()     );
+    std::string schema     ( relationalDbId.schema()     );
+    std::string dbName     ( relationalDbId.dbName()     );
+    std::string user       ( relationalDbId.user()       );
+    std::string password   ( relationalDbId.password()   );
+    
+    // PANIC if the database name is not given explicitly
+    // (RelationalDatabaseId should have already failed!)
+    if ( dbName == "" )
+      throw InternalErrorException
+        ( "PANIC! No database name specified in COOL database URL",
+          "coolAuthentication" );
+    LOG << "==> dbName       = "
+        << dbName << std::endl;
+
+    // Get the CORAL connection string
+    std::string coralUrl;
+    if ( middleTier == "" ) 
+      coralUrl = RalConnectionString( relationalDbId );
+    else
+      coralUrl = RalConnectionString( relationalDbId.url() );
+    std::string coralMode = "N/A";
+
+    // --- Case 1: CORAL alias (loop over replicas)
+
+    // If the connection string looks like an alias, pass it to the LookupSvc
+    if ( coralUrl.find("://") == std::string::npos &&
+         coralUrl.substr(0,12) != "sqlite_file:" )
+    {
+      LOG << "CORAL logical alias" << std::endl;
+      LOG << "==> coralAlias   = " << coralUrl << std::endl;
+
+      // PANIC if technology, server, schema, user or password 
+      // are defined at this point (this should never happen!)
+      if ( technology != "" )
+        throw InternalErrorException
+          ( "PANIC! COOL URL based on CORAL alias explicitly contains "
+            "technology '" + technology + "'",
+            "coolAuthentication" );
+      if ( server != "" )
+        throw InternalErrorException
+          ( "PANIC! COOL URL based on CORAL alias explicitly contains "
+            "server '" + server + "'",
+            "coolAuthentication" );
+      if ( schema != "" )
+        throw InternalErrorException
+          ( "PANIC! COOL URL based on CORAL alias explicitly contains "
+            "schema '" + schema + "'",
+            "coolAuthentication" );
+      if ( user != "" )
+        throw InternalErrorException
+          ( "PANIC! COOL URL based on CORAL alias explicitly contains "
+            "user '" + user + "'",
+            "coolAuthentication" );
+      if ( password != "" )
+        throw InternalErrorException
+          ( "PANIC! COOL URL based on CORAL alias explicitly contains "
+            "password '" + password + "'",
+            "coolAuthentication" );
+
+      // Lookup the replicas
+      coral::AccessMode mode = ( rwOnly ? coral::Update : coral::ReadOnly );
+      std::auto_ptr<coral::IDatabaseServiceSet> replicas 
+        ( lookupSvc()->lookup( coralUrl, mode ) );
+      int nReplicas = replicas->numberOfReplicas();
+      if ( nReplicas  == 0 ) 
+        throw Exception
+          ( "No dblookup replicas found for " + coralUrl,
+            "coolAuthentication" );
+
+      // Loop over the replicas
+      // Reuse variables coralUrl, technology, server, schema, user, password
+      for ( int iReplica = 0; iReplica < nReplicas; iReplica++ )
+      {
+        const coral::IDatabaseServiceDescription& 
+          dsd = replicas->replica( iReplica );
+        coralUrl = dsd.connectionString();
+        coralMode = ( dsd.accessMode() == coral::ReadOnly ? "R/O" : "R/W" );
+ 
+        // Extract technology, server and schema
+        if ( coralUrl.substr(0,12) == "sqlite_file:" )
+        { 
+          // Special case for SQLite
+          technology = "sqlite";
+          server = "";
+          schema = coralUrl.substr(12);
+        }
+        else
+        { 
+          // Backends other than SQLite
+          std::string::size_type pos = coralUrl.find("://");
+          if ( pos == std::string::npos )
+            throw Exception
+              ( "The connection string returned by the lookup service "
+                "does not contain \"://\": " + coralUrl,
+                "coolAuthentication" );
+          technology = coralUrl.substr(0,pos);
+          pos += 3;
+          std::string::size_type pos2 = coralUrl.find_last_of('/');
+          if ( pos2 == std::string::npos )
+            throw Exception
+              ( "The connection string returned by the lookup service "
+                "does not contain the schema name: " + coralUrl,
+                "coolAuthentication" );
+          server = coralUrl.substr(pos,pos2 - pos);
+          schema = coralUrl.substr(pos2+1);
+        }
+
+        // Retrieve user and password using the authentication service
+        user = "";
+        password = "";
+        authenticate( coralUrl, technology, user, password );
+
+        // Print out the results
+        LOG << "CORAL physical replica (" 
+            << iReplica+1 << " of " << nReplicas << ")" << std::endl;
+        printOut(coralUrl,coralMode,technology,server,schema,user,password );
+
+        // Use only the first replica if required
+        if ( firstOnly ) break;
+        
+      }
+
+    }
+
+    // --- Case 2: explicit CORAL replica
+
+    else
+
+    {
+
+      // If the user name or password are not given explicitly,
+      // retrieve them using the CORAL authentication service
+      if ( user == "" || password == "" )
+        authenticate( coralUrl, technology, user, password );
+
+      // Print out the results
+      LOG << "CORAL physical replica (1 of 1)" << std::endl;
+      printOut(coralUrl,coralMode,technology,server,schema,user,password );
+
+    }
+    
+  }
+
+  // *** CATCH exceptions ***
+
+  catch( std::exception& e )
+  {
+    LOG << "ERROR! Standard C++ exception: '" << e.what() << "'" << std::endl;
+    return 1;
+  }
+
+  catch( ... ) 
+  {
+    LOG << "ERROR! Unknown exception caught" << std::endl;
+    return 1;
+  }
+
+  // Successful program termination
+  return 0;
+  
+}
+
+//-----------------------------------------------------------------------------
diff --git a/RelationalCool/utilities/coolDropDB/coolDropDB.cpp b/RelationalCool/utilities/coolDropDB/coolDropDB.cpp
new file mode 100644
index 000000000..2cb670eaf
--- /dev/null
+++ b/RelationalCool/utilities/coolDropDB/coolDropDB.cpp
@@ -0,0 +1,233 @@
+// $Id: coolDropDB.cpp,v 1.24 2008-04-10 15:31:14 avalassi Exp $
+
+// Include files 
+#include <iostream>
+#include "CoolKernel/Exception.h"
+#include "CoralBase/Exception.h"
+#include "RelationalAccess/IConnectionServiceConfiguration.h"
+#include "RelationalAccess/ISessionProxy.h"
+#include "RelationalAccess/ISchema.h"
+#include "RelationalAccess/ITransaction.h"
+
+// Local include files
+#include "../../src/CoralApplication.h"
+#include "../../src/CoralConnectionServiceProxy.h"
+#include "../../src/RalSessionMgr.h"
+#include "../../src/RelationalDatabaseId.h"
+
+// Message output
+#define LOG std::cout
+
+//-----------------------------------------------------------------------------
+
+int main( int argc, char** argv ) 
+{
+  
+  try 
+  {
+    
+    // Have all tables been dropped successfully?
+    bool success = true;
+
+    // Get the command line arguments
+    std::string dbId;
+    if ( argc == 2 ) {
+      dbId = argv[1];
+    } else {
+      LOG << "Usage: " << argv[0] << " dbId" << std:: endl;
+      std::string dbId1 = 
+        "oracle://SERVER;schema=SCHEMA;user=USER;password=PSWD;dbname=DB";
+      std::string dbId2 = 
+        "oracle://SERVER;schema=SCHEMA;dbname=DB";
+      LOG << std::endl;
+      LOG << "Example: " << argv[0] << " '" << dbId1 << "'\n"
+          << "[Decode user and password from explicit credentials]"
+          << std::endl;
+      LOG << std::endl;
+      LOG << "Example: " << argv[0] << " '" << dbId2 << "'\n"
+          << "[Get user and password from authentication service]"
+          << std::endl;
+      return 1;
+    }
+ 
+    // Decode and print out the database URL
+    cool::RelationalDatabaseId relationalDbId(dbId);
+    std::string dbName = relationalDbId.dbName();    
+    LOG << "Drop COOL database \"" << relationalDbId.urlHidePswd() << "\"" 
+        << std::endl;
+
+    // Instantiate a COOL Application
+    cool::CoralApplication app;
+
+    // Disable CORAL automatic pool clean up thread 
+    LOG << "Getting CORAL Connection Service configurator" << std::endl;
+    coral::IConnectionServiceConfiguration &connSvcConf =
+      app.connectionSvc().configuration();
+
+    // If we can access a LFC and the user is not explicitely forbidding it,
+    // we try to use CORAL LFCReplicaService
+    if ( ::getenv("COOL_IGNORE_LFC") == NULL &&
+         ::getenv("LFC_HOST") != NULL ) {
+      // use CORAL LFCReplicaService
+      connSvcConf.setAuthenticationService("CORAL/Services/LFCReplicaService");
+      connSvcConf.setLookupService("CORAL/Services/LFCReplicaService");
+    }
+    
+    LOG << "Disabling CORAL connection automatic clean up" << std::endl;
+    connSvcConf.disablePoolAutomaticCleanUp();
+    connSvcConf.setConnectionTimeOut( 0 );    
+
+    // Create a session manager and start a transaction
+    const bool readOnly = false;
+    cool::CoralConnectionServiceProxyPtr ppConnSvc
+      ( new cool::CoralConnectionServiceProxy( &app.connectionSvc() ) );
+    cool::RalSessionMgr rsm( ppConnSvc, dbId, readOnly );
+    LOG << "Start transaction." << std::endl;
+    rsm.session().transaction().start();
+    std::set<std::string> existingTables = 
+      rsm.session().nominalSchema().listTables();
+    
+    // Mark for deletion all tables whose names start with dbName + "_"
+    // Tables must be deleted in a specific order because of FK constraints
+    std::string signature = dbName + "_";
+    std::list<std::string> tablesToDelete;
+    // Management tables are deleted last (and in a specific order)
+    std::list<std::string> mgmtTables;
+    mgmtTables.push_back( signature + "DB_ATTRIBUTES" );
+    // *** START *** 3.0.0 schema extensions (task #4307)
+    mgmtTables.push_back( signature + "IOVTABLES" );
+    mgmtTables.push_back( signature + "CHANNELTABLES" );
+    // **** END **** 3.0.0 schema extensions (task #4307)
+    mgmtTables.push_back( signature + "NODES" );
+    mgmtTables.push_back( signature + "NODES_SEQ" );
+    mgmtTables.push_back( signature + "TAGS" );
+    // *** START *** 3.0.0 schema extensions (task #4396)
+    mgmtTables.push_back( signature + "USERTAGS" );
+    mgmtTables.push_back( signature + "HEADTAGS" );
+    // **** END **** 3.0.0 schema extensions (task #4396)
+    mgmtTables.push_back( signature + "TAG2TAG" );
+    mgmtTables.push_back( signature + "TAG2TAG_SEQ" );
+    mgmtTables.push_back( signature + "TAGS_SEQ" );
+    mgmtTables.push_back( signature + "IOVS_SEQ" );
+    std::list<std::string>::const_iterator mgmtTable;
+    for ( mgmtTable = mgmtTables.begin(); 
+          mgmtTable != mgmtTables.end(); 
+          ++mgmtTable )
+    {
+      if ( existingTables.find( *mgmtTable ) != existingTables.end() ) 
+      {
+        existingTables.erase( *mgmtTable );
+        // First inserted will be at the back of the list - and deleted last
+        tablesToDelete.push_front( *mgmtTable );
+      }
+    }
+    // Tables that are not associated to individual nodes (and are not 
+    // management tables either) are deleted before the management tables
+    // [NB: There should be no such tables, but delete them anyway!]
+    std::set<std::string>::reverse_iterator existingTable;
+    for ( existingTable = existingTables.rbegin(); 
+          existingTable != existingTables.rend(); 
+          ++existingTable )
+    {
+      if ( existingTable->find( signature ) == 0 &&
+           existingTable->find( signature+"F" ) != 0 ) 
+      {
+        // First inserted will be at the back of the list - and deleted last
+        // [i.e. delete these tables in alphabetical order - as in COOL133c]
+        tablesToDelete.push_front( *existingTable );
+      }
+    }
+    // Tables that are associated to individual nodes are deleted first
+    // Delete all channel tables last, because of FK constraints
+    // (first inserted will be at the back of the list, and deleted last)
+    for ( existingTable = existingTables.rbegin(); 
+          existingTable != existingTables.rend(); 
+          ++existingTable )
+    {
+      if ( existingTable->find( signature ) == 0 &&
+           existingTable->find( signature+"F" ) == 0 &&
+           existingTable->rfind( "_CHANNELS" ) == existingTable->size()-9 ) 
+      {
+        tablesToDelete.push_front( *existingTable );
+      }
+    }
+    // Tables that are associated to individual nodes are deleted first
+    // Delete all tables other than the channel tables first
+    for ( existingTable = existingTables.rbegin(); 
+          existingTable != existingTables.rend(); 
+          ++existingTable )
+    {
+      if ( existingTable->find( signature ) == 0 &&
+           existingTable->find( signature+"F" ) == 0 &&
+           existingTable->rfind( "_CHANNELS" ) != existingTable->size()-9 ) 
+      {
+        // First inserted will be at the back of the list - and deleted last
+        // [i.e. delete these tables in alphabetical order - as in COOL133c]
+        tablesToDelete.push_front( *existingTable );
+      }
+    }
+
+    // Drop the tables
+    std::list<std::string>::iterator tableToDelete;
+    for ( tableToDelete = tablesToDelete.begin(); 
+          tableToDelete != tablesToDelete.end(); 
+          ++tableToDelete ) 
+    {
+      LOG << "Dropping table \"" << *tableToDelete << "\" ... " << std::flush;
+      try {
+        rsm.session().nominalSchema().dropTable(*tableToDelete);
+        LOG << "done." << std::endl;
+      }
+      catch(...){
+        LOG << "failed." << std::endl;
+        success = false;
+      }        
+    }
+
+    // Commit the transaction
+    LOG << "Commit transaction." << std::endl;
+    rsm.session().transaction().commit();  
+
+    // Close the session manager access to the CORAL connection service
+    ppConnSvc->purgeConnectionPool();
+    ppConnSvc->resetICS();
+
+    // Have all tables been dropped successfully?
+    if ( success ) 
+      LOG << "All database tables have been dropped successfully." 
+          << std::endl;
+    else 
+      LOG << "WARNING! One or more database tables could not be dropped." 
+          << std::endl;
+  }
+  
+  catch( cool::Exception& e ) 
+  {
+    LOG << "ERROR! Cool Exception: '" << e.what() << "'" << std::endl;
+    return 1;
+  }
+
+  catch( coral::Exception& e ) 
+  {
+    LOG << "ERROR! Coral Exception: '" << e.what() << "'" << std::endl;
+    return 1;
+  }
+  
+  catch( std::exception& e )
+  {
+    LOG << "ERROR! Standard C++ exception: '" << e.what() << "'" << std::endl;
+    return 1;
+  }
+
+  catch( ... ) 
+  {
+    LOG << "ERROR! Unknown exception caught" << std::endl;
+    return 1;
+  }
+
+  // Successful program termination
+  return 0;
+
+}
+
+//-----------------------------------------------------------------------------
diff --git a/RelationalCool/utilities/coolDumpSchema/coolDumpSchema.cpp b/RelationalCool/utilities/coolDumpSchema/coolDumpSchema.cpp
new file mode 100755
index 000000000..62779af17
--- /dev/null
+++ b/RelationalCool/utilities/coolDumpSchema/coolDumpSchema.cpp
@@ -0,0 +1,110 @@
+// $Id: coolDumpSchema.cpp,v 1.9 2008-04-10 15:31:15 avalassi Exp $
+
+// Include files 
+#include <algorithm>
+#include <iostream>
+#include "RelationalAccess/IColumn.h"
+#include "RelationalAccess/IConnectionService.h"
+#include "RelationalAccess/IConnectionServiceConfiguration.h"
+#include "RelationalAccess/ISessionProxy.h"
+#include "RelationalAccess/ISchema.h"
+#include "RelationalAccess/ITable.h"
+#include "RelationalAccess/ITableDescription.h"
+#include "RelationalAccess/ITransaction.h"
+
+// Local include files
+#include "../../src/CoralApplication.h"
+#include "../../src/CoralConnectionServiceProxy.h"
+#include "../../src/RalSessionMgr.h"
+#include "../../src/RelationalDatabaseId.h"
+
+// Message output
+#define LOG std::cout
+
+int main( int argc, char** argv ) {
+  
+  std::string dbId;
+  if ( argc == 2 ) {
+    dbId = argv[1];
+  } else {
+    LOG << "Usage: " << argv[0] << " dbId" << std:: endl;
+    std::string dbId1 = 
+      "oracle://SERVER;schema=SCHEMA;user=USER;password=PSWD;dbname=DB";
+    std::string dbId2 = 
+      "oracle://SERVER;schema=SCHEMA;dbname=DB";
+    LOG << std::endl;
+    LOG << "Example: " << argv[0] << " '" << dbId1 << "'\n"
+        << "[Decode user and password from explicit credentials]"
+        << std::endl;
+    LOG << std::endl;
+    LOG << "Example: " << argv[0] << " '" << dbId2 << "'\n"
+        << "[Get user and password from authentication service]"
+        << std::endl;
+    return 1;
+  }
+ 
+  // Instantiate a COOL Application
+  cool::CoralApplication app;
+  
+  // If we can access a LFC and the user is not explicitely forbidding it,
+  // we try to use CORAL LFCReplicaService
+  if ( ::getenv("COOL_IGNORE_LFC") == NULL &&
+       ::getenv("LFC_HOST") != NULL ) {
+    // try to load CORAL LFCReplicaService
+    coral::IConnectionServiceConfiguration &connSvcConf =
+          app.connectionSvc().configuration();
+    connSvcConf.setAuthenticationService("CORAL/Services/LFCReplicaService");
+    connSvcConf.setLookupService("CORAL/Services/LFCReplicaService");
+  }
+
+  cool::RelationalDatabaseId relationalDbId(dbId);
+  std::string dbName = relationalDbId.dbName();
+
+  LOG << "Dump COOL database schema \"" << relationalDbId.urlHidePswd() << "\"" << std::endl;
+
+  const bool readOnly = false;
+  cool::CoralConnectionServiceProxyPtr ppConnSvc
+    ( new cool::CoralConnectionServiceProxy( &app.connectionSvc() ) );
+  cool::RalSessionMgr rsm( ppConnSvc, dbId, readOnly );
+  LOG << "Start transaction." << std::endl;
+  rsm.session().transaction().start();
+  std::set<std::string> tableSet = rsm.session().nominalSchema().listTables();
+
+  // need to copy this over as set sorting does not work
+  std::vector<std::string> tables;
+  for ( std::set<std::string>::const_iterator 
+        t = tableSet.begin(); t != tableSet.end(); ++t ){
+    tables.push_back( *t );
+  }
+  sort( tables.begin(), tables.end() );
+
+  std::string signature = dbName + "_";
+  for ( std::vector<std::string>::const_iterator 
+        t = tables.begin(); t != tables.end(); ++t ){
+    if ( t->find(signature) == 0 ){ // table name starts with dbName + "_"
+      LOG << "------------------------------------------------" << std::endl;
+      LOG << "Table " << *t << std::endl;
+      LOG << "------------------------------------------------" << std::endl;
+      coral::ITable& table( rsm.session().nominalSchema().tableHandle( *t ) );
+      const coral::ITableDescription& tableDescription( table.description() );
+      std::vector<std::string> colNames;
+      for ( int i = 0; i < tableDescription.numberOfColumns(); ++i ) {
+        const coral::IColumn& col( tableDescription.columnDescription( i ) );
+        colNames.push_back( col.name() );
+      }
+      sort( colNames.begin(), colNames.end() );
+      for ( std::vector<std::string>::const_iterator
+            n = colNames.begin(); n != colNames.end(); ++n ) {
+        const coral::IColumn& col( tableDescription.columnDescription( *n ) );
+        LOG << col.name() << "\t" << col.type() << "\t" << col.size() 
+          << std::endl;
+      }
+    }
+  }
+
+  rsm.session().transaction().commit();
+  ppConnSvc->purgeConnectionPool();
+  ppConnSvc->resetICS();
+
+  return 0;
+}
diff --git a/RelationalCool/utilities/coolEvolveSchema/RalSchemaEvolution.cpp b/RelationalCool/utilities/coolEvolveSchema/RalSchemaEvolution.cpp
new file mode 100644
index 000000000..9c0fd2a8d
--- /dev/null
+++ b/RelationalCool/utilities/coolEvolveSchema/RalSchemaEvolution.cpp
@@ -0,0 +1,2263 @@
+// $Id: RalSchemaEvolution.cpp,v 1.106 2009-01-16 11:08:53 avalassi Exp $
+
+// Include files
+#include "CoolKernel/Record.h"
+#include "CoralBase/Attribute.h"
+#include "RelationalAccess/IColumn.h"
+#include "RelationalAccess/IIndex.h"
+#include "RelationalAccess/ISchema.h"
+#include "RelationalAccess/ITable.h"
+#include "RelationalAccess/ITableDataEditor.h"
+#include "RelationalAccess/ITableSchemaEditor.h"
+#include "RelationalAccess/SchemaException.h"
+
+// Local include files
+#include "RalSchemaEvolution.h"
+#include "../../src/HvsPathHandler.h"
+#include "../../src/ObjectId.h"
+#include "../../src/RalDatabase.h"
+#include "../../src/RelationalChannelTable.h"
+#include "../../src/RelationalDatabaseTable.h"
+#include "../../src/RelationalException.h"
+#include "../../src/RelationalFolder.h"
+#include "../../src/RelationalGlobalTagTable.h"
+#include "../../src/RelationalIovSharedSequenceTable.h"
+#include "../../src/RelationalNodeTable.h"
+#include "../../src/RelationalObjectTable.h"
+#include "../../src/RelationalObjectTableRow.h"
+#include "../../src/RelationalQueryMgr.h"
+#include "../../src/RelationalSchemaMgr.h"
+#include "../../src/RelationalTagSequence.h"
+#include "../../src/RelationalTagSharedSequenceTable.h"
+#include "../../src/RelationalTag2TagTable.h"
+#include "../../src/RelationalTableRow.h"
+#include "../../src/RelationalTransaction.h"
+#include "../../src/VersionInfo.h"
+
+// Additional VersionInfo specific to RalSchemaEvolution.cpp
+namespace cool
+{
+  namespace VersionInfo {
+    const std::string cvsCheckout = "$Name: not supported by cvs2svn $";
+    const std::string cvsCheckin = "$Id: RalSchemaEvolution.cpp,v 1.106 2009-01-16 11:08:53 avalassi Exp $";
+  }
+}
+
+// Namespace
+using namespace cool;
+
+//-----------------------------------------------------------------------------
+
+RalSchemaEvolution::RalSchemaEvolution( CoralConnectionServiceProxyPtr ppConnSvc,
+                                        const DatabaseId& dbId )
+  : m_db( new RalDatabase( ppConnSvc, dbId, false ) )
+  , m_log( new coral::MessageStream( "RalSchemaEvolution" ) )
+{
+  log() << coral::Info 
+        << "Instantiate a RalSchemaEvolution manager for '" 
+        << m_db->databaseId() << "'" << coral::MessageStream::endmsg;
+
+  // DIRTY HACK - open the database
+  RelationalTransaction transaction( db().transactionMgr(), true ); // r/o
+  m_db->m_dbAttr = db().fetchDatabaseAttributes();
+  transaction.commit();
+  m_db->m_isOpen = true;
+}
+
+//-----------------------------------------------------------------------------
+
+RalSchemaEvolution::~RalSchemaEvolution() 
+{
+  log() << coral::Info
+        << "Delete the RalSchemaEvolution manager for '" 
+        << m_db->databaseId() << "'" << coral::MessageStream::endmsg;
+  if ( m_db ) delete m_db;
+}
+ 
+//-----------------------------------------------------------------------------
+
+coral::MessageStream& RalSchemaEvolution::log() 
+{
+  *m_log << coral::Verbose;
+  return *m_log;
+}
+
+//-----------------------------------------------------------------------------
+
+void RalSchemaEvolution::evolveDatabase() 
+{
+  // WELCOME
+  log() << coral::Info << "Evolve database schema... START" << coral::MessageStream::endmsg;
+  RelationalTransaction transaction( db().transactionMgr(), false ); // r/w
+
+  // Can the schema of this database be evolved? Does it need to?
+  const Record& dbAttr = db().databaseAttributes();
+  std::string releaseNumber =
+    dbAttr[RelationalDatabaseTable::attributeNames::release]
+    .data<std::string>();
+  std::string schemaVersion =
+    dbAttr[RelationalDatabaseTable::attributeNames::schemaVersion].
+    data<std::string>();
+  bool dbNeedsEvolution = false;
+  try 
+  {
+    dbNeedsEvolution = 
+      !db().areReleaseAndSchemaCompatible( releaseNumber, schemaVersion );
+  } catch ( IncompatibleReleaseNumber& e ) {
+    log() << coral::Error << "Exception caught: '" 
+          << e.what() << "'" << std::endl;
+    log() << coral::Error
+          << "Schema evolution is not possible for this database - abort"
+          << coral::MessageStream::endmsg;
+    throw e;
+  }
+
+  // DATABASE NEEDS SCHEMA EVOLUTION FROM 130 TO 200
+  if ( dbNeedsEvolution ) 
+  {
+    log() << coral::Info 
+          << "Database needs schema evolution: proceed"
+          << coral::MessageStream::endmsg;
+    if ( schemaVersion == "1.2.0" ) {
+      std::stringstream msg;
+      msg << "Schema evolution from schema version " << schemaVersion
+          << " is not possible using this tool from release " 
+          << VersionInfo::release << ". Please evolve the schema in two steps:"
+          << " first to 1.3.0 using the tools from the COOL 1.3 releases,"
+          << " and then to 2.0.0 using the tools from the current release.";
+      msg << " Schema evolution is not possible for this database - abort";
+      log() << coral::Error << msg.str() << coral::MessageStream::endmsg;
+      throw IncompatibleReleaseNumber( msg.str(), "RalSchemaEvolution" );
+    } else if ( schemaVersion == "1.3.0" ) {
+#ifndef _WIN32
+      evolveDatabase_130_to_200();
+#else
+      // Schema evolution from 1.3.x is not supported any longer on Windows
+      std::stringstream msg;
+      msg << "ERROR! Schema evolution from COOL 1.3.x to "
+          << VersionInfo::release << " is not supported on Windows: "
+          << "please perform schema evolution "
+          << "on a COOL 1.3.x supported platform";
+      log() << coral::Error << msg.str() << coral::MessageStream::endmsg;
+      throw RelationalException
+        ( msg.str(), "RalSchemaEvolution" );
+#endif
+    } else {
+      std::stringstream msg;
+      msg << "Unsupported schema version: '" << schemaVersion << "'.";
+      msg << " Schema evolution is not possible for this database - abort";
+      log() << coral::Error << msg.str() << coral::MessageStream::endmsg;
+      throw IncompatibleReleaseNumber( msg.str(), "RalSchemaEvolution" );
+    }
+  }  
+  // DATABASE DOES NOT NEED SCHEMA EVOLUTION FROM 130 TO 200
+  else 
+  {
+    log() << coral::Info
+          << "Database does not need schema evolution" << coral::MessageStream::endmsg;
+  }
+
+  // CHECK INDIVIDUAL NODES FOR SCHEMA EVOLUTION FROM 200 TO 220
+  log() << coral::Info
+        << "Alter MySQL SQL types and "
+        << "check if individual nodes need schema evolution" << coral::MessageStream::endmsg;
+  evolveDatabase_200_to_220();
+  
+  // GOODBYE
+  transaction.commit();
+  log() << coral::Info << "Evolve database schema... DONE!" << coral::MessageStream::endmsg;
+}
+
+//-----------------------------------------------------------------------------
+
+void RalSchemaEvolution::evolveDatabase_130_to_200() 
+{
+  log() << coral::Info 
+        << "Evolve database schema (130->200)..." << coral::MessageStream::endmsg;
+
+  // -------------------------------------------------------------------
+  // Alter selected SQL types of columns in all existing tables:
+  // (1a) Alter MySQL "VARCHAR(255) BINARY" into "VARCHAR(255) BINARY"
+  // *** NB: This is actually a no-op in evolving schemas from COOL1xx to 200.
+  // *** BINARY was by mistake added in versions COOL200 to 211 (bug #24393,
+  // *** aka bug #26484). Schema version number remains 2.0.0 in the change
+  // *** from COOL211 to 220 (there are no production databases on MySQL).
+  // (1b) %%% DISABLED %%% Alter MySQL "TEXT" into "TEXT BINARY"
+  // ( 2) Alter SQLite "LONG" into "INT"
+  // ( 3) Alter SQLite "UNSIGNEDLONG" into "UNSIGNEDINT"
+  // -------------------------------------------------------------------
+
+  i_alterSqlTypes_130_to_200();
+
+  // -------------------------------------------------------------------
+  // Evolve the node table:
+  // ( 4) Change the FOLDER_PAYLOADSPEC column size from 4k to 64k
+  // ( 5) Add the FOLDER_PAYLOAD_INLINE column (default: NULL)
+  // ( 6) Add the FOLDER_PAYLOAD_EXTREF column (default: NULL)
+  // ( 7) Add the FOLDER_CHANNELSPEC column (default: NULL)
+  // ( 8) Add the FOLDER_CHANNEL_EXTREF column (default: NULL)
+  // ( 9) Add the FOLDER_CHANNELTABLENAME column (default: NULL)
+  // (10) Add the LASTMOD_DATE column (default: NOW)
+  // (11) Add the SCHEMA_VERSION column (default: 2.0.0)
+  // (12) Update the versioning mode of the root "/" folder set to -1
+  // (13) Add the UK constraint on (nodeFullPath)
+  // (14) Add the UK constraint on (nodeId, nodeParentId)
+  // -------------------------------------------------------------------
+  
+  i_evolveNodeTable_130_200();
+  
+  // -------------------------------------------------------------------
+  // Evolve the global tag table:
+  // (15) Add the TAG_LOCK_STATUS column (default: 0)
+  // (16) Recreate the PK on (nodeId, tagId) - invert the present order
+  // (17) Add the UK constraint on tagName
+  // (18) Add the FK constraint on nodeId to the NODES table
+  // -------------------------------------------------------------------
+  
+  i_evolveGlobalTagTable_130_200();
+  
+  // -------------------------------------------------------------------
+  // Evolve the tag2tag table:
+  // (19) Add the FK constraint on the parent tag to the TAGS table
+  // (20) Add the FK constraint on the child tag to the TAGS table
+  // (21) Add the FK constraint on the parent/child to the NODES table
+  // -------------------------------------------------------------------
+  
+  i_evolveTag2TagTable_130_200();
+  
+  // -------------------------------------------------------------------
+  // (22) Create the tag shared sequence
+  // -------------------------------------------------------------------
+  
+  i_createTagSharedSequence_130_200();
+  
+  // -------------------------------------------------------------------
+  // (23) Create the IOV shared sequence
+  // -------------------------------------------------------------------
+  
+  i_createIovSharedSequence_130_200();
+  
+  // -------------------------------------------------------------------
+  // Evolve each folder from 130 to 200
+  // (24) Add the LASTMOD_DATE column (default: NOW) to each IOV table
+  // (25) Create each channels table
+  // (26) Update the node table with each channels table name
+  // -------------------------------------------------------------------
+  {    
+    // List all folders ordered by nodeId
+    coral::AttributeList whereData;
+    whereData.extend
+      ( "isLeaf", 
+        typeIdToCoralType(RelationalNodeTable::columnTypeIds::nodeIsLeaf) );
+    whereData["isLeaf"].setValue
+      ( true ); // select folders only
+    std::string whereClause = RelationalNodeTable::columnNames::nodeIsLeaf;
+    whereClause += "= :isLeaf";
+    std::vector<std::string> orderBy;
+    std::string orderClause = RelationalNodeTable::columnNames::nodeId;
+    orderClause += " ASC";
+    orderBy.push_back( orderClause );
+    std::vector<RelationalTableRow> rows =
+      db().queryMgr().fetchOrderedRowsFromTables
+      ( RelationalQueryMgr::tableList( db().nodeTableName() ), 
+        RelationalQueryMgr::columnList
+        ( RelationalNodeTable::tableSpecification
+          ( VersionNumber( "1.3.0" ) ) ),
+        whereClause, whereData, orderBy, "" );
+    // Evolve all folders one by one
+    for ( std::vector<RelationalTableRow>::const_iterator
+          row = rows.begin(); row != rows.end(); ++row ) 
+    {
+      i_evolveIovTable_130_to_200( *row );    
+      i_createChannelsTable_130_to_200( *row );
+      i_fillChannelsTableSV_130_to_200( *row );
+      i_updateNodeTable_130_to_200( *row );
+    }
+  }
+  
+  // -------------------------------------------------------------------
+  // Update the main database table
+  // (27) Insert schema evolution metadata
+  // (28) Update current database schema to 2.0.0
+  // (29) Insert names of new top-level tables
+  // -------------------------------------------------------------------
+
+  i_evolveMainTable_130_to_200();
+
+  // Success
+  log() << coral::Info 
+        << "Evolve database schema (130->200)... DONE!" << coral::MessageStream::endmsg;
+}
+
+//-----------------------------------------------------------------------------
+
+void RalSchemaEvolution::i_evolveNodeTable_130_200()
+{
+  log() << coral::Info 
+        << "Evolve node table schema (130->200)... START" << coral::MessageStream::endmsg;
+  std::string nodeTableName = db().nodeTableName();
+  
+  // 1. Change the folderPayloadSpecDesc column size from 4k to 64k
+  // First attempt - this fails with ORA-22858 on Oracle
+  // (cannot ALTER a non-CLOB column into a CLOB column)
+  if ( false ) {
+    std::string columnName = 
+      RelationalNodeTable::columnNames::folderPayloadSpecDesc;
+    const StorageType::TypeId columnTypeId = 
+      RelationalNodeTable::columnTypeIds::folderPayloadSpecDesc;
+    const cool::StorageType& columnType = 
+      StorageType::storageType( columnTypeId );
+    log() << coral::Info 
+          << "Node table needs schema evolution"
+          << ": alter type of column '" << columnName 
+          << "' in table '" << nodeTableName 
+          << "' to type '" << columnType.name() << "'" << coral::MessageStream::endmsg;
+    coral::ITable& table = db().sessionMgr()->session()
+      .nominalSchema().tableHandle( nodeTableName );
+    try {
+      const bool fixedSize = false;
+      table.schemaEditor().changeColumnType
+        ( columnName, 
+          coral::AttributeSpecification::typeNameForId( columnType.cppType() ),
+          columnType.maxSize(), fixedSize );
+    } catch ( std::exception& e ) {
+      log() << coral::Error 
+            << "Exception caught: '" << e.what() << "'" << coral::MessageStream::endmsg;
+      log() << coral::Error 
+            << "Failed to alter type of column '" << columnName 
+            << "' in table '" << nodeTableName
+            << "' to type '" << columnType.name() << "'" << coral::MessageStream::endmsg;
+      throw RelationalException
+        ( "Schema evolution failed", "RalSchemaEvolution" );
+    }    
+  }
+  // Second attempt - workaround: rename the 4k column, add a new 64k column
+  // with the correct name, copy the contents, then drop the old column
+  if ( true ) {
+    std::string columnName = 
+      RelationalNodeTable::columnNames::folderPayloadSpecDesc;
+    const StorageType::TypeId columnTypeId = 
+      RelationalNodeTable::columnTypeIds::folderPayloadSpecDesc;
+    const cool::StorageType& columnType = 
+      StorageType::storageType( columnTypeId );
+    log() << coral::Info 
+          << "Node table needs schema evolution"
+          << ": alter type of column '" << columnName 
+          << "' in table '" << nodeTableName 
+          << "' to type '" << columnType.name() << "'" << coral::MessageStream::endmsg;
+    coral::ITable& table = db().sessionMgr()->session()
+      .nominalSchema().tableHandle( nodeTableName );
+    try {
+      // Rename the old 4k column
+      std::string columnName4k = 
+        RelationalNodeTable::columnNames::folderPayloadSpecDesc + "_TMP";
+      table.schemaEditor().renameColumn( columnName, columnName4k );
+      // Add a new 64k column
+      const bool fixedSize = false;
+      table.schemaEditor().insertColumn
+        ( columnName, 
+          coral::AttributeSpecification::typeNameForId( columnType.cppType() ),
+          columnType.maxSize(), fixedSize );
+      // Copy the value of the old 4k column into the new 64k column
+      std::string whereClause = ""; // No WHERE clause
+      std::string setClause = columnName + "=" + columnName4k;
+      coral::AttributeList updateData; // No bind variables
+      db().queryMgr().updateTableRows
+        ( nodeTableName, setClause, whereClause, updateData );
+      // Drop the old 4k column
+      table.schemaEditor().dropColumn( columnName4k );      
+    } catch ( std::exception& e ) {
+      log() << coral::Error 
+            << "Exception caught: '" << e.what() << "'" << coral::MessageStream::endmsg;
+      log() << coral::Error 
+            << "Failed to alter type of column '" << columnName 
+            << "' in table '" << nodeTableName
+            << "' to type '" << columnType.name() << "'" << coral::MessageStream::endmsg;
+      throw RelationalException
+        ( "Schema evolution failed", "RalSchemaEvolution" );
+    }    
+  }
+
+  // 2. Add the folderPayloadInline column. 
+  {
+    std::string columnName = 
+      RelationalNodeTable::columnNames::folderPayloadInline;
+    const StorageType::TypeId columnTypeId = 
+      RelationalNodeTable::columnTypeIds::folderPayloadInline;
+    const cool::StorageType& columnType = 
+      StorageType::storageType( columnTypeId );
+    log() << coral::Info 
+          << "Node table needs schema evolution"
+          << ": add column '" << columnName 
+          << "' of type '" << columnType.name()
+          << "' to table '" << nodeTableName << "'" << coral::MessageStream::endmsg;
+    coral::ITable& table = db().sessionMgr()->session()
+      .nominalSchema().tableHandle( nodeTableName );
+    try {
+      const bool fixedSize = false;
+      table.schemaEditor().insertColumn
+        ( columnName, 
+          coral::AttributeSpecification::typeNameForId( columnType.cppType() ),
+          columnType.maxSize(), fixedSize );
+    } catch ( std::exception& e ) {
+      log() << coral::Error 
+            << "Exception caught: '" << e.what() << "'" << coral::MessageStream::endmsg;
+      log() << coral::Error 
+            << "Failed to add column '" << columnName 
+            << "' of type '" << columnType.name()
+            << "' to table '" << nodeTableName << "'" << coral::MessageStream::endmsg;
+      throw RelationalException
+        ( "Schema evolution failed", "RalSchemaEvolution" );
+    }    
+  }
+
+  // 3. Add the folderPayloadExtRef column. 
+  {
+    std::string columnName = 
+      RelationalNodeTable::columnNames::folderPayloadExtRef;
+    const StorageType::TypeId columnTypeId = 
+      RelationalNodeTable::columnTypeIds::folderPayloadExtRef;
+    const cool::StorageType& columnType = 
+      StorageType::storageType( columnTypeId );
+    log() << coral::Info 
+          << "Node table needs schema evolution"
+          << ": add column '" << columnName 
+          << "' of type '" << columnType.name()
+          << "' to table '" << nodeTableName << "'" << coral::MessageStream::endmsg;
+    coral::ITable& table = db().sessionMgr()->session()
+      .nominalSchema().tableHandle( nodeTableName );
+    try {
+      const bool fixedSize = false;
+      table.schemaEditor().insertColumn
+        ( columnName, 
+          coral::AttributeSpecification::typeNameForId( columnType.cppType() ),
+          columnType.maxSize(), fixedSize );
+    } catch ( std::exception& e ) {
+      log() << coral::Error 
+            << "Exception caught: '" << e.what() << "'" << coral::MessageStream::endmsg;
+      log() << coral::Error 
+            << "Failed to add column '" << columnName 
+            << "' of type '" << columnType.name()
+            << "' to table '" << nodeTableName << "'" << coral::MessageStream::endmsg;
+      throw RelationalException
+        ( "Schema evolution failed", "RalSchemaEvolution" );
+    }    
+  }
+
+  // 4. Add the folderChannelSpecDesc column. 
+  {
+    std::string columnName = 
+      RelationalNodeTable::columnNames::folderChannelSpecDesc;
+    const StorageType::TypeId columnTypeId = 
+      RelationalNodeTable::columnTypeIds::folderChannelSpecDesc;
+    const cool::StorageType& columnType = 
+      StorageType::storageType( columnTypeId );
+    log() << coral::Info 
+          << "Node table needs schema evolution"
+          << ": add column '" << columnName 
+          << "' of type '" << columnType.name()
+          << "' to table '" << nodeTableName << "'" << coral::MessageStream::endmsg;
+    coral::ITable& table = db().sessionMgr()->session()
+      .nominalSchema().tableHandle( nodeTableName );
+    try {
+      const bool fixedSize = false;
+      table.schemaEditor().insertColumn
+        ( columnName, 
+          coral::AttributeSpecification::typeNameForId( columnType.cppType() ),
+          columnType.maxSize(), fixedSize );
+    } catch ( std::exception& e ) {
+      log() << coral::Error 
+            << "Exception caught: '" << e.what() << "'" << coral::MessageStream::endmsg;
+      log() << coral::Error 
+            << "Failed to add column '" << columnName 
+            << "' of type '" << columnType.name()
+            << "' to table '" << nodeTableName << "'" << coral::MessageStream::endmsg;
+      throw RelationalException
+        ( "Schema evolution failed", "RalSchemaEvolution" );
+    }    
+  }
+
+  // 5. Add the folderChannelExtRef column. 
+  {
+    std::string columnName = 
+      RelationalNodeTable::columnNames::folderChannelExtRef;
+    const StorageType::TypeId columnTypeId = 
+      RelationalNodeTable::columnTypeIds::folderChannelExtRef;
+    const cool::StorageType& columnType = 
+      StorageType::storageType( columnTypeId );
+    log() << coral::Info 
+          << "Node table needs schema evolution"
+          << ": add column '" << columnName 
+          << "' of type '" << columnType.name()
+          << "' to table '" << nodeTableName << "'" << coral::MessageStream::endmsg;
+    coral::ITable& table = db().sessionMgr()->session()
+      .nominalSchema().tableHandle( nodeTableName );
+    try {
+      const bool fixedSize = false;
+      table.schemaEditor().insertColumn
+        ( columnName, 
+          coral::AttributeSpecification::typeNameForId( columnType.cppType() ),
+          columnType.maxSize(), fixedSize );
+    } catch ( std::exception& e ) {
+      log() << coral::Error 
+            << "Exception caught: '" << e.what() << "'" << coral::MessageStream::endmsg;
+      log() << coral::Error 
+            << "Failed to add column '" << columnName 
+            << "' of type '" << columnType.name()
+            << "' to table '" << nodeTableName << "'" << coral::MessageStream::endmsg;
+      throw RelationalException
+        ( "Schema evolution failed", "RalSchemaEvolution" );
+    }    
+  }
+
+  // 6. Add the folderChannelTableName column.
+  {
+    std::string columnName = 
+      RelationalNodeTable::columnNames::folderChannelTableName;
+    const StorageType::TypeId columnTypeId = 
+      RelationalNodeTable::columnTypeIds::folderChannelTableName;
+    const cool::StorageType& columnType = 
+      StorageType::storageType( columnTypeId );
+    log() << coral::Info 
+          << "Node table needs schema evolution"
+          << ": add column '" << columnName 
+          << "' of type '" << columnType.name()
+          << "' to table '" << nodeTableName << "'" << coral::MessageStream::endmsg;
+    coral::ITable& table = db().sessionMgr()->session()
+      .nominalSchema().tableHandle( nodeTableName );
+    try {
+      const bool fixedSize = false;
+      table.schemaEditor().insertColumn
+        ( columnName, 
+          coral::AttributeSpecification::typeNameForId( columnType.cppType() ),
+          columnType.maxSize(), fixedSize );
+    } catch ( std::exception& e ) {
+      log() << coral::Error 
+            << "Exception caught: '" << e.what() << "'" << coral::MessageStream::endmsg;
+      log() << coral::Error 
+            << "Failed to add column '" << columnName 
+            << "' of type '" << columnType.name()
+            << "' to table '" << nodeTableName << "'" << coral::MessageStream::endmsg;
+      throw RelationalException
+        ( "Schema evolution failed", "RalSchemaEvolution" );
+    }
+  }
+
+  // 7. Add the lastModDate column and set its value to NOW.
+  {
+    std::string columnName = 
+      RelationalNodeTable::columnNames::lastModDate;
+    // Add the lastModDate column.
+    const StorageType::TypeId columnTypeId = 
+      RelationalNodeTable::columnTypeIds::lastModDate;
+    const cool::StorageType& columnType = 
+      StorageType::storageType( columnTypeId );
+    log() << coral::Info 
+          << "Node table needs schema evolution"
+          << ": add column '" << columnName 
+          << "' of type '" << columnType.name()
+          << "' to table '" << nodeTableName << "'" << coral::MessageStream::endmsg;
+    coral::ITable& table = db().sessionMgr()->session()
+      .nominalSchema().tableHandle( nodeTableName );
+    try {
+      const bool fixedSize = false;
+      table.schemaEditor().insertColumn
+        ( columnName, 
+          coral::AttributeSpecification::typeNameForId( columnType.cppType() ),
+          columnType.maxSize(), fixedSize );
+    } catch ( std::exception& e ) {
+      log() << coral::Error 
+            << "Exception caught: '" << e.what() << "'" << coral::MessageStream::endmsg;
+      log() << coral::Error 
+            << "Failed to add column '" << columnName 
+            << "' of type '" << columnType.name()
+            << "' to table '" << nodeTableName << "'" << coral::MessageStream::endmsg;
+      throw RelationalException
+        ( "Schema evolution failed", "RalSchemaEvolution" );
+    }
+    // Set the value of the lastModDate column to NOW.
+    try {
+      std::string whereClause = ""; // No WHERE clause
+      std::string columnValue = RelationalQueryMgr::serverTimeClause
+        ( db().sessionMgr()->databaseTechnology() );
+      std::string setClause = columnName + "=" + columnValue;
+      coral::AttributeList updateData; // No bind variables
+      db().queryMgr().updateTableRows
+        ( nodeTableName, setClause, whereClause, updateData );
+    } catch ( std::exception& e ) {
+      log() << coral::Error 
+            << "Exception caught: '" << e.what() << "'" << coral::MessageStream::endmsg;
+      log() << coral::Error 
+            << "Failed to update table '" << nodeTableName << "'" 
+            << coral::MessageStream::endmsg;
+      throw RelationalException
+        ( "Schema evolution failed", "RalSchemaEvolution" );
+    }
+  }
+  
+  // 8. Add the SCHEMA_VERSION column and set its value to 2.0.0.
+  {
+    std::string columnName = 
+      RelationalNodeTable::columnNames::nodeSchemaVersion;
+    // Add the nodeSchemaVersion column. 
+    const StorageType::TypeId columnTypeId = 
+      RelationalNodeTable::columnTypeIds::nodeSchemaVersion;
+    const cool::StorageType& columnType = 
+      StorageType::storageType( columnTypeId );
+    log() << coral::Info 
+          << "Node table needs schema evolution"
+          << ": add column '" << columnName 
+          << "' of type '" << columnType.name()
+          << "' to table '" << nodeTableName << "'" << coral::MessageStream::endmsg;
+    coral::ITable& table = db().sessionMgr()->session()
+      .nominalSchema().tableHandle( nodeTableName );
+    try {
+      const bool fixedSize = false;
+      table.schemaEditor().insertColumn
+        ( columnName, 
+          coral::AttributeSpecification::typeNameForId( columnType.cppType() ),
+          columnType.maxSize(), fixedSize );
+    } catch ( std::exception& e ) {
+      log() << coral::Error 
+            << "Exception caught: '" << e.what() << "'" << coral::MessageStream::endmsg;
+      log() << coral::Error 
+            << "Failed to add column '" << columnName 
+            << "' of type '" << columnType.name()
+            << "' to table '" << nodeTableName << "'" << coral::MessageStream::endmsg;
+      throw RelationalException
+        ( "Schema evolution failed", "RalSchemaEvolution" );
+    }    
+    // Set the value of the nodeSchemaVersion column to 2.0.0.
+    // *** NB Hardcode the value to '2.0.0' (as in COOL_2_0_0): for folders
+    // *** (but not for folder sets), this will be changed later to '2.0.1'.
+    try {
+      std::string whereClause; // No WHERE clause
+      std::string setClause = 
+        columnName + "='" + std::string( VersionInfo::schemaVersion ) + "'";
+      coral::AttributeList updateData; // No bind variables
+      db().queryMgr().updateTableRows
+        ( nodeTableName, setClause, whereClause, updateData );
+    } catch ( std::exception& e ) {
+      log() << coral::Error 
+            << "Exception caught: '" << e.what() << "'" << coral::MessageStream::endmsg;
+      log() << coral::Error 
+            << "Failed to update table '" << nodeTableName << "'" 
+            << coral::MessageStream::endmsg;
+      throw RelationalException
+        ( "Schema evolution failed", "RalSchemaEvolution" );
+    }
+  }  
+
+  // 9. Update the versioning mode of the root "/" folder set to -1
+  {
+    std::string columnName = 
+      RelationalNodeTable::columnNames::folderVersioningMode;
+    HvsPathHandler handler;
+    std::stringstream noneMode;
+    noneMode << FolderVersioning::NONE;
+    std::string rootFullPath = handler.rootFullPath();
+    log() << coral::Info 
+          << "Node table needs schema evolution"
+          << ": set value of column '" << columnName 
+          << "' to '" << noneMode.str()
+          << "' for the root folder set '" << rootFullPath << "'" 
+          << coral::MessageStream::endmsg;
+    try {
+      std::string whereClause = 
+        RelationalNodeTable::columnNames::nodeFullPath 
+        + "='" + rootFullPath + "'";
+      std::string setClause = columnName + "=" + noneMode.str();
+      coral::AttributeList updateData; // No bind variables
+      db().queryMgr().updateTableRows
+        ( nodeTableName, setClause, whereClause, updateData, 1 );
+    } catch ( std::exception& e ) {
+      log() << coral::Error 
+            << "Exception caught: '" << e.what() << "'" << coral::MessageStream::endmsg;
+      log() << coral::Error 
+            << "Failed to update table '" << nodeTableName << "'" 
+            << coral::MessageStream::endmsg;
+      throw RelationalException
+        ( "Schema evolution failed", "RalSchemaEvolution" );
+    }
+  }
+
+  // 10. Add the UK constraint on (nodeFullPath)
+  {
+    log() << coral::Info 
+          << "Node table needs schema evolution"
+          << ": create UK constraint on (nodeFullPath)"
+          << " in table '" << nodeTableName << "'" << coral::MessageStream::endmsg;
+    coral::ITable& table = db().sessionMgr()->session()
+      .nominalSchema().tableHandle( nodeTableName );
+    try {
+      table.schemaEditor().setUniqueConstraint
+        ( RelationalNodeTable::columnNames::nodeFullPath, 
+          nodeTableName+"_FULLPATH_UK" );
+    } catch ( std::exception& e ) {
+      log() << coral::Error 
+            << "Exception caught: '" << e.what() << "'" << coral::MessageStream::endmsg;
+      log() << coral::Error 
+            << "Failed to create UK constraint on (nodeFullPath)"
+            << " in table '" << nodeTableName << "'" << coral::MessageStream::endmsg;
+      throw RelationalException
+        ( "Schema evolution failed", "RalSchemaEvolution" );
+    }
+  }
+
+  // 11. Add the UK constraint on (nodeId, nodeParentId)
+  {
+    std::vector<std::string> ukColumns;
+    ukColumns.push_back( RelationalNodeTable::columnNames::nodeId );
+    ukColumns.push_back( RelationalNodeTable::columnNames::nodeParentId ); 
+    log() << coral::Info 
+          << "Node table needs schema evolution"
+          << ": create UK constraint on (nodeId, parentId)"
+          << " in table '" << nodeTableName << "'" << coral::MessageStream::endmsg;
+    coral::ITable& table = db().sessionMgr()->session()
+      .nominalSchema().tableHandle( nodeTableName );
+    try {
+      table.schemaEditor().setUniqueConstraint
+        ( ukColumns, nodeTableName+"_PARENT_UK" );
+    } catch ( std::exception& e ) {
+      log() << coral::Error 
+            << "Exception caught: '" << e.what() << "'" << coral::MessageStream::endmsg;
+      log() << coral::Error 
+            << "Failed to create UK constraint on (nodeId, parentId)"
+            << " in table '" << nodeTableName << "'" << coral::MessageStream::endmsg;
+      throw RelationalException
+        ( "Schema evolution failed", "RalSchemaEvolution" );
+    }
+  }
+
+  // Success
+  log() << coral::Info 
+        << "Evolve node table schema (130->200)... DONE!" << coral::MessageStream::endmsg;
+} 
+
+//-----------------------------------------------------------------------------
+
+void RalSchemaEvolution::i_evolveGlobalTagTable_130_200()
+{
+  log() << coral::Info 
+        << "Evolve global tag table schema (130->200)... START" << coral::MessageStream::endmsg;
+  std::string globalTagTableName = db().globalTagTableName();
+   
+  // 1. Add the tagLockStatus column and set its value to 0. 
+  {
+    std::string columnName = 
+      RelationalGlobalTagTable::columnNames::tagLockStatus;
+    const StorageType::TypeId columnTypeId = 
+      RelationalGlobalTagTable::columnTypeIds::tagLockStatus;
+    const cool::StorageType& columnType = 
+      StorageType::storageType( columnTypeId );
+    // Add the tagLockStatus column. 
+    log() << coral::Info 
+          << "Global tag table needs schema evolution"
+          << ": add column '" << columnName 
+          << "' of type '" << columnType.name()
+          << "' to table '" << globalTagTableName << "'" << coral::MessageStream::endmsg;
+    coral::ITable& table = db().sessionMgr()->session()
+      .nominalSchema().tableHandle( globalTagTableName );
+    try {
+      const bool fixedSize = false;
+      table.schemaEditor().insertColumn
+        ( columnName, 
+          coral::AttributeSpecification::typeNameForId( columnType.cppType() ),
+          columnType.maxSize(), fixedSize );
+    } catch ( std::exception& e ) {
+      log() << coral::Error 
+            << "Exception caught: '" << e.what() << "'" << coral::MessageStream::endmsg;
+      log() << coral::Error 
+            << "Failed to add column '" << columnName 
+            << "' of type '" << columnType.name()
+            << "' to table '" << globalTagTableName << "'" << coral::MessageStream::endmsg;
+      throw RelationalException
+        ( "Schema evolution failed", "RalSchemaEvolution" );
+    }    
+    // Set the value of the tagLockStatus column to 0.
+    try {
+      std::string whereClause; // No WHERE clause
+      std::string setClause = columnName + "=0";
+      coral::AttributeList updateData; // No bind variables
+      db().queryMgr().updateTableRows
+        ( globalTagTableName, setClause, whereClause, updateData );
+    } catch ( std::exception& e ) {
+      log() << coral::Error 
+            << "Exception caught: '" << e.what() << "'" << coral::MessageStream::endmsg;
+      log() << coral::Error 
+            << "Failed to update table '" << globalTagTableName << "'" 
+            << coral::MessageStream::endmsg;
+      throw RelationalException
+        ( "Schema evolution failed", "RalSchemaEvolution" );
+    }
+  }
+  
+  // 2. Recreate the PK on (nodeId, tagId) - invert the present order
+  {
+    log() << coral::Info 
+          << "Global tag table needs schema evolution"
+          << ": recreate PK on (nodeId, tagId)"
+          << " in table '" << globalTagTableName << "'" << coral::MessageStream::endmsg;
+    std::vector<std::string> pkColumns;
+    pkColumns.push_back( RelationalGlobalTagTable::columnNames::nodeId );
+    pkColumns.push_back( RelationalGlobalTagTable::columnNames::tagId );
+    coral::ITable& table = db().sessionMgr()->session()
+      .nominalSchema().tableHandle( globalTagTableName );
+    try {
+      table.schemaEditor().dropPrimaryKey();
+      table.schemaEditor().setPrimaryKey( pkColumns );
+    } catch ( std::exception& e ) {
+      log() << coral::Error 
+            << "Exception caught: '" << e.what() << "'" << coral::MessageStream::endmsg;
+      log() << coral::Error 
+            << "Failed to recreate PK on (nodeId, tagId)"
+            << " in table '" << globalTagTableName << "'" << coral::MessageStream::endmsg;
+      throw RelationalException
+        ( "Schema evolution failed", "RalSchemaEvolution" );
+    }    
+  }
+
+  // 3. Add the UK constraint on tagName
+  {
+    log() << coral::Info 
+          << "Global tag table needs schema evolution"
+          << ": create UK constraint on (tagName)"
+          << " in table '" << globalTagTableName << "'" << coral::MessageStream::endmsg;
+    coral::ITable& table = db().sessionMgr()->session()
+      .nominalSchema().tableHandle( globalTagTableName );
+    try {
+      table.schemaEditor().setUniqueConstraint
+        ( RelationalTagTable::columnNames::tagName,
+          globalTagTableName+"_TAGNAME_UK" );
+    } catch ( std::exception& e ) {
+      log() << coral::Error 
+            << "Exception caught: '" << e.what() << "'" << coral::MessageStream::endmsg;
+      log() << coral::Error 
+            << "Failed to create UK constraint on (tagName)"
+            << " in table '" << globalTagTableName << "'" << coral::MessageStream::endmsg;
+      throw RelationalException
+        ( "Schema evolution failed", "RalSchemaEvolution" );
+    }
+  }
+
+  // 4. Add the FK constraint on nodeId to the NODES table
+  {
+    std::string columnNameSrc = 
+      RelationalGlobalTagTable::columnNames::nodeId;
+    std::string columnNameTgt = 
+      RelationalNodeTable::columnNames::nodeId;
+    std::string nodeTableName = db().nodeTableName();
+    log() << coral::Info 
+          << "Global tag table needs schema evolution"
+          << ": create FK reference from '" << columnNameSrc 
+          << "' in table '" << globalTagTableName
+          << "' to '" << columnNameTgt
+          << "' in table '" << nodeTableName << "'" << coral::MessageStream::endmsg;
+    coral::ITable& table = db().sessionMgr()->session()
+      .nominalSchema().tableHandle( globalTagTableName );
+    try {
+      table.schemaEditor().createForeignKey
+        ( globalTagTableName + "_NODEID_FK", columnNameSrc,
+          nodeTableName, columnNameTgt );
+    } catch ( std::exception& e ) {
+      log() << coral::Error 
+            << "Exception caught: '" << e.what() << "'" << coral::MessageStream::endmsg;
+      log() << coral::Error 
+            << "Failed to create FK reference from '" << columnNameSrc 
+            << "' in table '" << globalTagTableName
+            << "' to '" << columnNameTgt
+            << "' in table '" << nodeTableName << "'" << coral::MessageStream::endmsg;
+      throw RelationalException
+        ( "Schema evolution failed", "RalSchemaEvolution" );
+    }    
+  }
+
+  // Success
+  log() << coral::Info 
+        << "Evolve global tag table schema (130->200)... DONE" << coral::MessageStream::endmsg;
+} 
+
+//-----------------------------------------------------------------------------
+
+void RalSchemaEvolution::i_evolveTag2TagTable_130_200()
+{
+  log() << coral::Info 
+        << "Evolve tag2tag table schema (130->200)... START" << coral::MessageStream::endmsg;
+  std::string tag2TagTableName = db().tag2TagTableName();
+   
+  // 1. Add the FK constraint on the parent tag to the TAGS table
+  {
+    std::string globalTagTableName = db().globalTagTableName();
+    std::vector<std::string> fkColumnsSrc;
+    fkColumnsSrc.push_back
+      ( RelationalTag2TagTable::columnNames::parentNodeId );
+    fkColumnsSrc.push_back
+      ( RelationalTag2TagTable::columnNames::parentTagId );
+    std::vector<std::string> fkColumnsTgt;
+    fkColumnsTgt.push_back
+      ( RelationalGlobalTagTable::columnNames::nodeId );
+    fkColumnsTgt.push_back
+      ( RelationalGlobalTagTable::columnNames::tagId );
+    log() << coral::Info 
+          << "Tag2tag table needs schema evolution"
+          << ": create FK reference from parent tag"
+          << " in table '" << tag2TagTableName
+          << "' to parent tag"
+          << " in table '" << globalTagTableName << "'" << coral::MessageStream::endmsg;
+    coral::ITable& table = db().sessionMgr()->session()
+      .nominalSchema().tableHandle( tag2TagTableName );
+    try {
+      table.schemaEditor().createForeignKey
+        ( tag2TagTableName + "_PTAG_FK", fkColumnsSrc,
+          globalTagTableName, fkColumnsTgt );
+    } catch ( std::exception& e ) {
+      log() << coral::Error 
+            << "Exception caught: '" << e.what() << "'" << coral::MessageStream::endmsg;
+      log() << coral::Error 
+            << "Failed to create FK reference from parent tag"
+            << " in table '" << tag2TagTableName
+            << "' to parent tag"
+            << " in table '" << globalTagTableName << "'" << coral::MessageStream::endmsg;
+      throw RelationalException
+        ( "Schema evolution failed", "RalSchemaEvolution" );
+    }    
+  }
+
+  // 2. Add the FK constraint on the child tag to the TAGS table
+  {
+    std::string globalTagTableName = db().globalTagTableName();
+    std::vector<std::string> fkColumnsSrc;
+    fkColumnsSrc.push_back
+      ( RelationalTag2TagTable::columnNames::childNodeId );
+    fkColumnsSrc.push_back
+      ( RelationalTag2TagTable::columnNames::childTagId );
+    std::vector<std::string> fkColumnsTgt;
+    fkColumnsTgt.push_back
+      ( RelationalGlobalTagTable::columnNames::nodeId );
+    fkColumnsTgt.push_back
+      ( RelationalGlobalTagTable::columnNames::tagId );
+    log() << coral::Info 
+          << "Tag2tag table needs schema evolution"
+          << ": create FK reference from child tag"
+          << " in table '" << tag2TagTableName
+          << "' to child tag"
+          << " in table '" << globalTagTableName << "'" << coral::MessageStream::endmsg;
+    coral::ITable& table = db().sessionMgr()->session()
+      .nominalSchema().tableHandle( tag2TagTableName );
+    try {
+      table.schemaEditor().createForeignKey
+        ( tag2TagTableName + "_CTAG_FK", fkColumnsSrc,
+          globalTagTableName, fkColumnsTgt );
+    } catch ( std::exception& e ) {
+      log() << coral::Error 
+            << "Exception caught: '" << e.what() << "'" << coral::MessageStream::endmsg;
+      log() << coral::Error 
+            << "Failed to create FK reference from child tag"
+            << " in table '" << tag2TagTableName
+            << "' to child tag"
+            << " in table '" << globalTagTableName << "'" << coral::MessageStream::endmsg;
+      throw RelationalException
+        ( "Schema evolution failed", "RalSchemaEvolution" );
+    }    
+  }
+
+  // 3. Add the FK constraint on the parent/child to the NODES table
+  {
+    std::string nodeTableName = db().nodeTableName();
+    std::vector<std::string> fkColumnsSrc;
+    fkColumnsSrc.push_back
+      ( RelationalTag2TagTable::columnNames::childNodeId );
+    fkColumnsSrc.push_back
+      ( RelationalTag2TagTable::columnNames::parentNodeId );
+    std::vector<std::string> fkColumnsTgt;
+    fkColumnsTgt.push_back
+      ( RelationalNodeTable::columnNames::nodeId );
+    fkColumnsTgt.push_back
+      ( RelationalNodeTable::columnNames::nodeParentId );
+    log() << coral::Info 
+          << "Tag2tag table needs schema evolution"
+          << ": create FK reference from parent/child"
+          << " in table '" << tag2TagTableName
+          << "' to parent/child"
+          << " in table '" << nodeTableName << "'" << coral::MessageStream::endmsg;
+    coral::ITable& table = db().sessionMgr()->session()
+      .nominalSchema().tableHandle( tag2TagTableName );
+    try {
+      table.schemaEditor().createForeignKey
+        ( tag2TagTableName + "_NODES_FK", fkColumnsSrc,
+          nodeTableName, fkColumnsTgt );
+    } catch ( std::exception& e ) {
+      log() << coral::Error 
+            << "Exception caught: '" << e.what() << "'" << coral::MessageStream::endmsg;
+      log() << coral::Error 
+            << "Failed to create FK reference from parent/child"
+            << " in table '" << tag2TagTableName
+            << "' to parent/child"
+            << " in table '" << nodeTableName << "'" << coral::MessageStream::endmsg;
+      throw RelationalException
+        ( "Schema evolution failed", "RalSchemaEvolution" );
+    }    
+  }
+
+  // Success
+  log() << coral::Info 
+        << "Evolve tag2tag table schema (130->200)... DONE" << coral::MessageStream::endmsg;
+} 
+
+//-----------------------------------------------------------------------------
+
+void RalSchemaEvolution::i_createTagSharedSequence_130_200()
+{
+  log() << coral::Info 
+        << "Create tag shared sequence (130->200)... START" << coral::MessageStream::endmsg;
+  const Record& dbAttr = db().databaseAttributes();
+  std::string defaultTablePrefix =
+    dbAttr[RelationalDatabaseTable::attributeNames::defaultTablePrefix]
+    .data<std::string>();
+  std::string tagSharedSequenceName =
+    RelationalTagSharedSequenceTable::defaultTableName( defaultTablePrefix );
+
+  // 1. Create the tag shared sequence
+  {
+    std::string nodeTableName = db().nodeTableName();
+    log() << coral::Info 
+          << "Database needs schema evolution"
+          << ": create tag shared sequence"
+          << " table '" << tagSharedSequenceName << "'" << coral::MessageStream::endmsg;
+    try {
+      db().schemaMgr().createSharedSequence
+        ( tagSharedSequenceName, nodeTableName );
+    } catch ( std::exception& e ) {
+      log() << coral::Error 
+            << "Exception caught: '" << e.what() << "'" << coral::MessageStream::endmsg;
+      log() << coral::Error 
+            << "Failed to create tag shared sequence"
+            << " table '" << tagSharedSequenceName << "'" << coral::MessageStream::endmsg;
+      throw RelationalException
+        ( "Schema evolution failed", "RalSchemaEvolution" );
+    }    
+  }
+
+  // Success
+  log() << coral::Info 
+        << "Create tag shared sequence (130->200)... DONE" << coral::MessageStream::endmsg;
+} 
+
+//-----------------------------------------------------------------------------
+
+void RalSchemaEvolution::i_createIovSharedSequence_130_200()
+{
+  log() << coral::Info 
+        << "Create IOV shared sequence (130->200)... START" << coral::MessageStream::endmsg;
+  const Record& dbAttr = db().databaseAttributes();
+  std::string defaultTablePrefix =
+    dbAttr[RelationalDatabaseTable::attributeNames::defaultTablePrefix]
+    .data<std::string>();
+  std::string iovSharedSequenceName =
+    RelationalIovSharedSequenceTable::defaultTableName( defaultTablePrefix );
+
+  // 1. Create the IOV shared sequence
+  {
+    std::string nodeTableName = db().nodeTableName();
+    log() << coral::Info 
+          << "Database needs schema evolution"
+          << ": create IOV shared sequence"
+          << " table '" << iovSharedSequenceName << "'" << coral::MessageStream::endmsg;
+    try {
+      db().schemaMgr().createSharedSequence
+        ( iovSharedSequenceName, nodeTableName );
+    } catch ( std::exception& e ) {
+      log() << coral::Error 
+            << "Exception caught: '" << e.what() << "'" << coral::MessageStream::endmsg;
+      log() << coral::Error 
+            << "Failed to create IOV shared sequence"
+            << " table '" << iovSharedSequenceName << "'" << coral::MessageStream::endmsg;
+      throw RelationalException
+        ( "Schema evolution failed", "RalSchemaEvolution" );
+    }    
+  }
+
+  // Success
+  log() << coral::Info 
+        << "Create IOV shared sequence (130->200)... DONE" << coral::MessageStream::endmsg;
+} 
+
+//-----------------------------------------------------------------------------
+
+void RalSchemaEvolution::i_evolveIovTable_130_to_200
+( const RelationalTableRow& row )
+{
+  log() << coral::Info 
+        << "Evolve IOV table schema (130->200)... START" << coral::MessageStream::endmsg;
+  std::string fullPath = 
+    row[RelationalNodeTable::columnNames::nodeFullPath]
+    .data<std::string>();
+  std::string objectTableName = 
+    row[RelationalNodeTable::columnNames::folderObjectTableName]
+    .data<std::string>();
+  
+  // 1. Add the lastModDate column and set its value to NOW.
+  std::string columnName = RelationalObjectTable::columnNames::lastModDate();
+  // Add the lastModDate column.
+  // This is done by simply altering the table to add the column at the end:
+  // with respect to tables created by COOL14x, the column order is different.
+  const StorageType::TypeId columnTypeId = 
+    RelationalObjectTable::columnTypeIds::lastModDate;
+  const cool::StorageType& columnType = 
+    StorageType::storageType( columnTypeId );
+  log() << coral::Info 
+        << "Folder '" << fullPath << "' needs schema evolution"
+        << ": add column '" << columnName 
+        << "' of type '" << columnType.name()
+        << "' to table '" << objectTableName << "'" << coral::MessageStream::endmsg;
+  coral::ITable& table = db().sessionMgr()->session()
+    .nominalSchema().tableHandle( objectTableName );
+  try {
+    const bool fixedSize = false;
+    table.schemaEditor().insertColumn
+      ( columnName, 
+        coral::AttributeSpecification::typeNameForId( columnType.cppType() ),
+        columnType.maxSize(), fixedSize );
+  } catch ( std::exception& e ) {
+    log() << coral::Error 
+          << "Exception caught: '" << e.what() << "'" << coral::MessageStream::endmsg;
+    log() << coral::Error 
+          << "Failed to add column '" << columnName 
+          << "' of type '" << columnType.name()
+          << "' to table '" << objectTableName << "'" << coral::MessageStream::endmsg;
+    throw RelationalException
+      ( "Schema evolution failed", "RalSchemaEvolution" );
+  }  
+  // Set the value of the lastModDate column to NOW.
+  try {
+    std::string whereClause = ""; // No WHERE clause
+    std::string columnValue = RelationalQueryMgr::serverTimeClause
+      ( db().sessionMgr()->databaseTechnology() );
+    std::string setClause = columnName + "=" + columnValue;
+    coral::AttributeList updateData; // No bind variables
+    db().queryMgr().updateTableRows
+      ( objectTableName, setClause, whereClause, updateData );
+  } catch ( std::exception& e ) {
+    log() << coral::Error 
+          << "Exception caught: '" << e.what() << "'" << coral::MessageStream::endmsg;
+    log() << coral::Error 
+          << "Failed to update table '" << objectTableName << "'" 
+          << coral::MessageStream::endmsg;
+    throw RelationalException
+      ( "Schema evolution failed", "RalSchemaEvolution" );
+  }
+
+  // Success
+  log() << coral::Info 
+        << "Evolve IOV table schema (130->200)... DONE!" << coral::MessageStream::endmsg;
+}
+
+//-----------------------------------------------------------------------------
+
+void RalSchemaEvolution::i_evolveMainTable_130_to_200()
+{
+  log() << coral::Info 
+        << "Evolve main table schema (130->200)... START" << coral::MessageStream::endmsg;
+  std::string mainTableName = db().mainTableName();
+
+  // 1a. Insert new rows:
+  // X_Y_Z_SE_OLD_RELEASE (previous RELEASE before X_Y_Z upgrade)
+  // X_Y_Z_SE_OLD_SCHEMA_VERSION (previous SCHEMA_VERSION before X_Y_Z upgrade)
+  // X_Y_Z_SE_TIME (time of the X_Y_Z upgrade)
+  RelationalDatabaseTable::columnTypes::attributeName attrName;
+  RelationalDatabaseTable::columnTypes::attributeValue attrValue;
+  try{
+    const Record& dbAttr = db().databaseAttributes();
+    std::string defaultTablePrefix =
+      dbAttr[RelationalDatabaseTable::attributeNames::defaultTablePrefix]
+      .data<std::string>();
+    std::string oldRelease =
+      dbAttr[RelationalDatabaseTable::attributeNames::release]
+      .data<std::string>();
+    std::string oldSchemaVersion =
+      dbAttr[RelationalDatabaseTable::attributeNames::schemaVersion]
+      .data<std::string>();
+    coral::AttributeList data;
+    data.extend
+      ( RelationalDatabaseTable::columnNames::attributeName,
+        typeIdToCoralType
+        ( RelationalDatabaseTable::columnTypeIds::attributeName ) );
+    data.extend
+      ( RelationalDatabaseTable::columnNames::attributeValue,
+        typeIdToCoralType
+        ( RelationalDatabaseTable::columnTypeIds::attributeValue ) );
+    
+    // X_Y_Z_SE_OLD_RELEASE (previous RELEASE before X_Y_Z upgrade)
+    attrName = VersionInfo::schemaEvolutionPrefix + "OLD_" +
+      RelationalDatabaseTable::attributeNames::release;
+    attrValue = oldRelease;
+    data[RelationalDatabaseTable::columnNames::attributeName]
+      .setValue( attrName );
+    data[RelationalDatabaseTable::columnNames::attributeValue]
+      .setValue( attrValue );
+    db().queryMgr().insertTableRow( mainTableName, data );
+    
+    // X_Y_Z_SE_OLD_SCHEMA_VERSION (previous SCHEMA_VERSION before XYZ upgrade)
+    attrName = VersionInfo::schemaEvolutionPrefix + "OLD_" +
+      RelationalDatabaseTable::attributeNames::schemaVersion;
+    attrValue = oldSchemaVersion;
+    data[RelationalDatabaseTable::columnNames::attributeName]
+      .setValue( attrName );
+    data[RelationalDatabaseTable::columnNames::attributeValue]
+      .setValue( attrValue );
+    db().queryMgr().insertTableRow( mainTableName, data );
+    
+    // X_Y_Z_SE_TIME (time of the X_Y_Z upgrade)
+    // NB THIS ONLY INSERTS THE ROW - need SQL injection via UPDATE statement
+    attrName = VersionInfo::schemaEvolutionPrefix + "TIME";
+    attrValue = RelationalQueryMgr::serverTimeClause
+      ( db().sessionMgr()->databaseTechnology() );
+    RelationalQueryMgr::serverTimeClause
+      ( db().sessionMgr()->databaseTechnology() );
+    data[RelationalDatabaseTable::columnNames::attributeName]
+      .setValue( attrName );
+    data[RelationalDatabaseTable::columnNames::attributeValue]
+      .setValue( attrValue );
+    db().queryMgr().insertTableRow( mainTableName, data );
+  }
+  catch ( std::exception& e ) 
+  {
+    log() << coral::Error 
+          << "Exception caught: '" << e.what() << "'" << coral::MessageStream::endmsg;
+    log() << coral::Error 
+          << "Failed to insert schema evolution metadata"
+          << " into table '" << mainTableName << "'" << coral::MessageStream::endmsg;
+    throw RelationalException
+      ( "Schema evolution failed", "RalSchemaEvolution" );
+  }
+  
+  // 1b. Update the value of X_Y_Z_SE_TIME 
+  try 
+  {
+    std::string whereClause = 
+      RelationalDatabaseTable::columnNames::attributeName 
+      + "='" + attrName + "'";
+    std::string setClause = 
+      RelationalDatabaseTable::columnNames::attributeValue 
+      + "=" + attrValue;
+    coral::AttributeList updateData; // No bind variables
+    db().queryMgr().updateTableRows
+      ( mainTableName, setClause, whereClause, updateData, 1 );
+  } 
+  catch ( std::exception& e ) 
+  {
+    log() << coral::Error 
+          << "Exception caught: '" << e.what() << "'" << coral::MessageStream::endmsg;
+    log() << coral::Error 
+          << "Failed to update table '" << mainTableName << "'" 
+          << coral::MessageStream::endmsg;
+    throw RelationalException
+      ( "Schema evolution failed", "RalSchemaEvolution" );
+  }
+  
+  // 2. Update the values of already existing rows.
+  try 
+  {
+    coral::AttributeList updateData;
+    updateData.extend
+      ( "newAttrValue",
+        typeIdToCoralType
+        ( RelationalDatabaseTable::columnTypeIds::attributeValue ) );
+    updateData.extend
+      ( "attrName",
+        typeIdToCoralType
+        ( RelationalDatabaseTable::columnTypeIds::attributeName ) );
+    std::string setClause = 
+      RelationalDatabaseTable::columnNames::attributeValue + "=:newAttrValue";
+    std::string whereClause = 
+      RelationalDatabaseTable::columnNames::attributeName + "=:attrName";
+    // RELEASE (after X_Y_Z upgrade)
+    updateData["newAttrValue"].setValue<std::string>
+      ( VersionInfo::release );
+    updateData["attrName"].setValue
+      ( RelationalDatabaseTable::attributeNames::release );
+    db().queryMgr().updateTableRows
+      ( mainTableName, setClause, whereClause, updateData, 1 );
+    // SCHEMA_VERSION (after X_Y_Z upgrade)
+    updateData["newAttrValue"].setValue<std::string>
+      ( VersionInfo::schemaVersion );
+    updateData["attrName"].setValue
+      ( RelationalDatabaseTable::attributeNames::schemaVersion );
+    db().queryMgr().updateTableRows
+      ( mainTableName, setClause, whereClause, updateData, 1 );
+    // CVS_CHECKOUT (after X_Y_Z upgrade)
+    updateData["newAttrValue"].setValue<std::string>
+      ( VersionInfo::cvsCheckout );
+    updateData["attrName"].setValue
+      ( RelationalDatabaseTable::attributeNames::cvsCheckout );
+    db().queryMgr().updateTableRows
+      ( mainTableName, setClause, whereClause, updateData, 1 );
+    // CVS_CHECKIN (after X_Y_Z upgrade)
+    updateData["newAttrValue"].setValue<std::string>
+      ( VersionInfo::cvsCheckin );
+    updateData["attrName"].setValue
+      ( RelationalDatabaseTable::attributeNames::cvsCheckin );
+    db().queryMgr().updateTableRows
+      ( mainTableName, setClause, whereClause, updateData, 1 );
+  } 
+  catch ( std::exception& e ) 
+  {
+    log() << coral::Error 
+          << "Exception caught: '" << e.what() << "'" << coral::MessageStream::endmsg;
+    log() << coral::Error 
+          << "Failed to update table '" << mainTableName << "'" 
+          << coral::MessageStream::endmsg;
+    throw RelationalException
+      ( "Schema evolution failed", "RalSchemaEvolution" );
+  }
+  
+  // 3. Insert new rows with the names of the new top-level tables
+  try 
+  {
+    const Record& dbAttr = db().databaseAttributes();
+    std::string defaultTablePrefix =
+      dbAttr[RelationalDatabaseTable::attributeNames::defaultTablePrefix]
+      .data<std::string>();
+    std::string tagSharedSequenceName =
+      RelationalTagSharedSequenceTable::defaultTableName( defaultTablePrefix );
+    std::string iovSharedSequenceName =
+      RelationalIovSharedSequenceTable::defaultTableName( defaultTablePrefix );
+    coral::AttributeList data;
+    data.extend
+      ( RelationalDatabaseTable::columnNames::attributeName,
+        typeIdToCoralType
+        ( RelationalDatabaseTable::columnTypeIds::attributeName ) );
+    data.extend
+      ( RelationalDatabaseTable::columnNames::attributeValue,
+        typeIdToCoralType
+        ( RelationalDatabaseTable::columnTypeIds::attributeValue ) );
+    RelationalDatabaseTable::columnTypes::attributeName attrName;
+    RelationalDatabaseTable::columnTypes::attributeValue attrValue;
+    
+    // Tag shared sequence name
+    attrName = RelationalDatabaseTable::attributeNames::tagSharedSequenceName;
+    attrValue = tagSharedSequenceName;
+    data[RelationalDatabaseTable::columnNames::attributeName]
+      .setValue( attrName );
+    data[RelationalDatabaseTable::columnNames::attributeValue]
+      .setValue( attrValue );
+    db().queryMgr().insertTableRow( mainTableName, data );
+    
+    // IOV shared sequence name
+    attrName = RelationalDatabaseTable::attributeNames::iovSharedSequenceName;
+    attrValue = iovSharedSequenceName;
+    data[RelationalDatabaseTable::columnNames::attributeName]
+      .setValue( attrName );
+    data[RelationalDatabaseTable::columnNames::attributeValue]
+      .setValue( attrValue );
+    db().queryMgr().insertTableRow( mainTableName, data );    
+  } 
+  catch ( std::exception& e ) 
+  {
+    log() << coral::Error 
+          << "Exception caught: '" << e.what() << "'" << coral::MessageStream::endmsg;
+    log() << coral::Error 
+          << "Failed to insert names of new top-level tables"
+          << " into table '" << mainTableName << "'" << coral::MessageStream::endmsg;
+    throw RelationalException
+      ( "Schema evolution failed", "RalSchemaEvolution" );
+  }
+  
+  // Success
+  log() << coral::Info 
+        << "Evolve main table schema (130->200)... DONE!" << coral::MessageStream::endmsg;
+}  
+
+//-----------------------------------------------------------------------------
+
+void RalSchemaEvolution::i_createChannelsTable_130_to_200
+( const RelationalTableRow& row )
+{
+  unsigned int nodeId =
+    row[RelationalNodeTable::columnNames::nodeId].data<unsigned int>();
+  std::string channelTableName =
+    RelationalChannelTable::defaultTableName
+    ( db().defaultTablePrefix(), nodeId );
+  log() << coral::Info 
+        << "Creating channels table " << channelTableName 
+        << " (130->200)..." << coral::MessageStream::endmsg;
+  db().schemaMgr().createChannelTable( channelTableName );
+  log() << coral::Info 
+        << "Creating channels table " << channelTableName 
+        << " (130->200)... DONE!" << coral::MessageStream::endmsg;
+}
+
+//-----------------------------------------------------------------------------
+
+void RalSchemaEvolution::i_fillChannelsTableSV_130_to_200
+( const RelationalTableRow& row )
+{
+  int folderVersioningMode = 
+    row[RelationalNodeTable::columnNames::folderVersioningMode].data<int>();
+  
+  // Only SV folders need to be updated
+  if ( folderVersioningMode != FolderVersioning::SINGLE_VERSION ) return;
+  
+  unsigned int nodeId =
+    row[RelationalNodeTable::columnNames::nodeId].data<unsigned int>();
+  std::string channelTableName =
+    RelationalChannelTable::defaultTableName
+    ( db().defaultTablePrefix(), nodeId );
+  log() << coral::Info 
+        << "Fill the SV channels table " << channelTableName 
+        << " (130->200)..." << coral::MessageStream::endmsg;
+  
+  std::string objectTableName = 
+    row[RelationalNodeTable::columnNames::folderObjectTableName]
+    .data<std::string>();
+  std::vector<ChannelId> channels = listChannels( objectTableName );
+
+  for ( std::vector<ChannelId>::const_iterator
+          ch = channels.begin(); ch != channels.end(); ++ch ) 
+  {
+    //std::cout << "Channel: " << *ch << std::endl;
+    RelationalObjectTableRow objRow = fetchLastRow( objectTableName, *ch );
+    bool hasNewData = false;
+    std::string channelName = "";
+    std::string description = "";
+    insertChannelTableRow( channelTableName, 
+                           *ch,
+                           objRow.objectId(),
+                           hasNewData,
+                           channelName,
+                           description );
+  }
+    
+  log() << coral::Info 
+        << "Fill the SV channels table " << channelTableName 
+        << " (130->200)... DONE!" << coral::MessageStream::endmsg;
+}
+
+//-----------------------------------------------------------------------------
+
+void RalSchemaEvolution::i_updateNodeTable_130_to_200
+( const RelationalTableRow& row )
+{ 
+  unsigned int nodeId =
+    row[RelationalNodeTable::columnNames::nodeId].data<unsigned int>();
+  
+  // 1. Update FOLDER_CHANNELTABLENAME
+  {
+    std::string channelTableName =
+      RelationalChannelTable::defaultTableName
+      ( db().defaultTablePrefix(), nodeId );
+    log() << coral::Info 
+          << "Updating channels table name " << channelTableName
+          << " in node table (130->200)..." << coral::MessageStream::endmsg;
+    std::string columnName = 
+      RelationalNodeTable::columnNames::folderChannelTableName;
+    const StorageType::TypeId columnTypeId = 
+      RelationalNodeTable::columnTypeIds::folderChannelTableName;
+    const cool::StorageType& columnType = 
+      StorageType::storageType( columnTypeId );
+    coral::AttributeList updateData;
+    updateData.extend
+      ( "channelTableName", columnType.cppType() );
+    updateData.extend
+      ( "nodeId", 
+        StorageType::storageType
+        ( RelationalNodeTable::columnTypeIds::nodeId ).cppType() );
+    updateData["channelTableName"]
+      .setValue<RelationalNodeTable::columnTypes::folderChannelTableName>
+      ( channelTableName );
+    updateData["nodeId"].
+      setValue<RelationalNodeTable::columnTypes::nodeId>
+      ( nodeId );
+    std::string setClause = columnName + "=:channelTableName";
+    std::string whereClause = 
+      RelationalNodeTable::columnNames::nodeId + "=:nodeId";
+    unsigned int expectedRows = 1;
+    if ( ! db().queryMgr().updateTableRows
+         ( db().nodeTableName(), setClause, whereClause, 
+           updateData, expectedRows ) ) 
+    {
+      log() << coral::Error 
+            << "Failed to set value to in column '" << columnName 
+            << "' of table '" << db().nodeTableName() << "'" << coral::MessageStream::endmsg;
+      throw RelationalException
+        ( "Schema evolution failed", "RalSchemaEvolution" );
+    }
+    log() << coral::Info 
+          << "Updating channels table name " << channelTableName
+          << " in node table (130->200)... DONE!" << coral::MessageStream::endmsg;
+  }
+  
+  // 2. Update FOLDER_PAYLOADSPEC
+  {
+    log() << coral::Info 
+          << "Updating folder payload specification "
+          << " in node table (130->200)..." << coral::MessageStream::endmsg;
+    std::string oldSpecDesc = 
+      row[RelationalNodeTable::columnNames::folderPayloadSpecDesc]
+      .data<std::string>();
+    RecordSpecification spec = decodeRecordSpecification130( oldSpecDesc );
+    std::string newSpecDesc = 
+      RelationalDatabase::encodeRecordSpecification( spec );
+    std::string columnName = 
+      RelationalNodeTable::columnNames::folderPayloadSpecDesc;
+    const StorageType::TypeId columnTypeId = 
+      RelationalNodeTable::columnTypeIds::folderPayloadSpecDesc;
+    const cool::StorageType& columnType = 
+      StorageType::storageType( columnTypeId );
+    coral::AttributeList updateData;
+    updateData.extend
+      ( "payloadSpecDesc", columnType.cppType() );
+    updateData.extend
+      ( "nodeId", 
+        StorageType::storageType
+        ( RelationalNodeTable::columnTypeIds::nodeId ).cppType() );
+    updateData["payloadSpecDesc"]
+      .setValue<RelationalNodeTable::columnTypes::folderChannelTableName>
+      ( newSpecDesc );
+    updateData["nodeId"].
+      setValue<RelationalNodeTable::columnTypes::nodeId>
+      ( nodeId );
+    std::string setClause = columnName + "=:payloadSpecDesc";
+    std::string whereClause = 
+      RelationalNodeTable::columnNames::nodeId + "=:nodeId";
+    unsigned int expectedRows = 1;
+    if ( ! db().queryMgr().updateTableRows
+         ( db().nodeTableName(), setClause, whereClause, 
+           updateData, expectedRows ) ) 
+    {
+      log() << coral::Error 
+            << "Failed to set value to in column '" << columnName 
+            << "' of table '" << db().nodeTableName() << "'" << coral::MessageStream::endmsg;
+      throw RelationalException
+        ( "Schema evolution failed", "RalSchemaEvolution" );
+    }
+    log() << coral::Info 
+          << "Updating folder payload specification "
+          << " in node table (130->200)... DONE!" << coral::MessageStream::endmsg;
+  }
+}
+
+//-----------------------------------------------------------------------------
+
+const RecordSpecification
+RalSchemaEvolution::decodeRecordSpecification130
+( const std::string& encodedEALS )
+{
+  RecordSpecification recordSpec;
+  if ( !encodedEALS.empty() ) {
+    std::string::size_type pos = 0;
+    while ( pos != encodedEALS.npos ) {
+      std::string::size_type newpos = encodedEALS.find( ',', pos );
+      std::string item_str;
+      if ( newpos != encodedEALS.npos )
+        item_str = encodedEALS.substr(pos,newpos-pos);
+      else
+        item_str = encodedEALS.substr(pos);
+      std::string::size_type separator_pos = item_str.find(':');
+      if ( separator_pos == item_str.npos )
+        throw RelationalException
+          ( std::string 
+            ( "Bad format, ':' not found in encoded EALSpecification '" )
+            + encodedEALS + "'", "RalSchemaEvolution" );      
+      recordSpec.extend
+        ( item_str.substr( 0, separator_pos ),
+          RalSchemaEvolution::storageType130
+          ( item_str.substr( separator_pos+1 ) ) );
+      pos = ( newpos != encodedEALS.npos ) ? newpos+1 : newpos;
+    }
+  }
+  return recordSpec;
+}
+
+//-----------------------------------------------------------------------------
+
+const StorageType& 
+RalSchemaEvolution::storageType130( const std::string& name ) 
+{
+  if ( name == "bool:DEF" )
+    return StorageType::storageType( StorageType::Bool );
+  //if ( name == "..." )
+  //  return StorageType::storageType( StorageType::Char ); // NOT IN 2.0.0
+  if ( name == "unsigned char:DEF" )
+    return StorageType::storageType( StorageType::UChar );
+  if ( name == "short:DEF" )
+    return StorageType::storageType( StorageType::Int16 );
+  if ( name == "unsigned short:DEF" )
+    return StorageType::storageType( StorageType::UInt16 );
+  if ( name == "int:DEF" )
+    return StorageType::storageType( StorageType::Int32 );
+  if ( name == "long:DEF" )
+    return StorageType::storageType( StorageType::Int32 ); // ONLY IN 1.3.0
+  if ( name == "unsigned int:DEF" )
+    return StorageType::storageType( StorageType::UInt32 );
+  if ( name == "unsigned long:DEF" )
+    return StorageType::storageType( StorageType::UInt32 ); // ONLY IN 1.3.0
+  if ( name == "unsigned long long:uInt63" )
+    return StorageType::storageType( StorageType::UInt63 );
+  //if ( name == "..." )
+  //  return StorageType::storageType( StorageType::Int64 ); // NEW IN 2.0.0!
+  //if ( name == "..." )
+  //  return StorageType::storageType( StorageType::UInt64 ); // NOT IN 2.0.0
+  if ( name == "float:DEF" )
+    return StorageType::storageType( StorageType::Float );
+  if ( name == "double:DEF" )
+    return StorageType::storageType( StorageType::Double );
+  if ( name == "string:255" )
+    return StorageType::storageType( StorageType::String255 );
+  if ( name == "string:4000" )
+    return StorageType::storageType( StorageType::String4k );
+  if ( name == "string:64K" )
+    return StorageType::storageType( StorageType::String64k );
+  if ( name == "string:16M" )
+    return StorageType::storageType( StorageType::String16M );
+  //if ( name == "..." )
+  //  return StorageType::storageType( StorageType::Blob64k ); // NEW IN 2.2.0!
+  //if ( name == "..." )
+  //  return StorageType::storageType( StorageType::Blob16M ); // NEW IN 2.2.0!
+  throw RelationalException
+    ( "PANIC! No 200 StorageType corresponds to 130 encoded type " + name, 
+      "RalSchemaEvolution" );
+}
+
+//-----------------------------------------------------------------------------
+
+const std::vector<ChannelId>
+RalSchemaEvolution::listChannels( const std::string& objectTableName ) const
+{  
+  RecordSpecification rsetSpec;
+  std::string channelIdLabel = std::string( "DISTINCT " ) + 
+    RelationalObjectTable::columnNames::channelId();
+  rsetSpec.extend
+    ( channelIdLabel, RelationalObjectTable::columnTypeIds::channelId );
+  std::string whereClause;
+  coral::AttributeList whereData;
+  std::vector<std::string> orderBy;
+  orderBy.push_back
+    ( RelationalObjectTable::columnNames::channelId() + " ASC" );
+  std::vector<RelationalTableRow> rows = 
+    db().queryMgr().fetchOrderedRowsFromTables
+    ( RelationalQueryMgr::tableList( objectTableName ), 
+      RelationalQueryMgr::columnList( rsetSpec ),
+      whereClause, whereData, orderBy, "" );
+  std::vector<ChannelId> channels;
+  for ( std::vector<RelationalTableRow>::const_iterator
+        row = rows.begin(); row != rows.end(); ++row ) {
+    ChannelId channel = 
+      ( *row )[ channelIdLabel ]
+      .data<ChannelId>(); // PORT: possibly <unsigned int> needed here instead
+    channels.push_back( channel );
+  }  
+  return channels;
+}
+
+//-----------------------------------------------------------------------------
+
+RelationalObjectTableRow
+RalSchemaEvolution::fetchLastRow( const std::string& objectTableName,
+                                  const ChannelId& channelId )
+{
+  // The "last object" inserted in each channel of a SV folder is retrieved
+  // as the object with the highest objectId in that channel (two possible
+  // alternatives could be to use the highest iovSince or iovUntil).
+  // The present algorithm uses two queries:
+  // 1. First, select max(objectId) in the given channel
+  // 2. Then, retrieve the full row for the object wih id=maxId
+  
+  // QUERY 1: select max(objectId) for the given channel
+  std::string maxObjectIdName =
+  std::string("MAX(") + RelationalObjectTable::columnNames::objectId() + ")";
+  
+  RecordSpecification spec;
+  spec.extend( maxObjectIdName,
+               RelationalObjectTable::columnTypeIds::objectId );
+  coral::AttributeList whereData;
+  whereData.extend
+    ( "channel", 
+      typeIdToCoralType(RelationalObjectTable::columnTypeIds::channelId) );
+  whereData["channel"]
+    .data<RelationalObjectTable::columnTypes::channelId>() = channelId;
+  std::string whereClause = RelationalObjectTable::columnNames::channelId();
+  whereClause += "= :channel";
+  
+  // Delegate the query to the RalQueryMgr
+  ObjectId maxObjectId;
+  try {
+    std::string desc = "";
+    RelationalTableRow maxObjectIdRow = db().queryMgr().fetchRowFromTables
+      ( RelationalQueryMgr::tableList( objectTableName ), 
+        RelationalQueryMgr::columnList( spec ), 
+        whereClause, whereData, desc );
+    maxObjectId = maxObjectIdRow[ maxObjectIdName ].data<ObjectId>();
+  } catch( NoRowsFound& ) {
+    throw ObjectNotFound
+    ( "max(objectId)", objectTableName, "RalSchemaEvolution" );
+  }
+  
+  // QUERY 2: select * for objectId = max(objectId)
+  return
+    fetchRowForId( objectTableName, maxObjectId );
+  
+}
+
+//---------------------------------------------------------------------------
+
+void RalSchemaEvolution::i_alterSqlTypes_130_to_200()
+{
+  log() << coral::Info 
+        << "Alter SQL types (130->200)... START" << coral::MessageStream::endmsg;
+
+  // Schema evolution of SQL types is only needed for MySQL and SQLite
+  std::string tech = db().sessionMgr()->databaseTechnology();
+  if ( tech == "Oracle" ) 
+  {
+    log() << coral::Info
+          << "Schema evolution of SQL types is NOT needed for technology '" 
+          << tech << "'" << coral::MessageStream::endmsg;
+  }
+  else if ( tech == "frontier" ) 
+  {
+    log() << coral::Error 
+          << "Schema evolution is not possible for read/only technology '" 
+          << tech << "'" << coral::MessageStream::endmsg;
+    throw RelationalException
+      ( "Schema evolution failed", "RalSchemaEvolution" );
+  }
+  else if ( tech != "MySQL" && tech != "SQLite" ) 
+  {
+    log() << coral::Error 
+          << "Unknown technology '" << tech << "'" << coral::MessageStream::endmsg;
+    throw RelationalException
+      ( "Schema evolution failed", "RalSchemaEvolution" );
+  }
+  else 
+  {
+    log() << coral::Info
+          << "Schema evolution of SQL types is needed for technology '" 
+          << tech << "'" << coral::MessageStream::endmsg;
+    const std::vector<std::string> tables = db().__listAllTables();
+    std::vector<std::string>::const_iterator iTable;
+    for ( iTable = tables.begin(); iTable != tables.end(); iTable++ ) 
+    {
+      std::string tableName = *iTable;
+      log() << coral::Info
+            << "Scan columns of table '" << tableName << "'" << coral::MessageStream::endmsg;
+      coral::ITable& table = db().sessionMgr()->session()
+        .nominalSchema().tableHandle( tableName );
+      int nCol = table.description().numberOfColumns();
+      for ( int iCol = 0; iCol < nCol; iCol++ ) 
+      {
+        const coral::IColumn& column = 
+          table.description().columnDescription(iCol);
+        //log() << coral::Verbose
+        //      << "--> Column '" << column.name() << "'" 
+        //      << ", type '" << column.type() << "'"
+        //      << ", size=" << column.size()
+        //      << ", isSizeFixed '" << column.isSizeFixed() << "'"
+        //      << coral::MessageStream::endmsg;
+        const std::string name = column.name();
+        std::string type = column.type();
+        long size = column.size();
+        const bool isSizeFixed = column.isSizeFixed();
+        if ( ( tech=="SQLite" && ( type=="long" || type=="unsigned long" ) ) ||
+             ( tech=="MySQL" && ( type=="string" && size==255 ) ) )
+           //( tech=="MySQL" && ( type=="string" ) ) ) // disable TEXT BINARY
+        {
+          log() << coral::Info
+                << "Alter SQL type of column '" << name << "'" 
+                << " (type " << type << ", size " << size << ")"
+                << " in table '" << tableName << "'" << coral::MessageStream::endmsg;
+          if ( tech=="SQLite" && type=="long" ) type="int";
+          if ( tech=="SQLite" && type=="unsigned long" ) type="unsigned int";
+          table.schemaEditor().changeColumnType
+            ( name, type, size, isSizeFixed );
+        }
+      }
+    }    
+  }
+  
+  // Success
+  log() << coral::Info 
+        << "Alter SQL types (130->200)... DONE" << coral::MessageStream::endmsg;
+}  
+
+//-----------------------------------------------------------------------------
+
+const RelationalObjectTableRow
+RalSchemaEvolution::fetchRowForId( const std::string& objectTableName,
+                                   const unsigned int objectId ) const
+{
+  // Define the WHERE clause for the selection using bind variables
+  coral::AttributeList whereData;
+  whereData.extend
+    ( "objectId",
+      typeIdToCoralType(RelationalObjectTable::columnTypeIds::objectId) );
+  whereData["objectId"].setValue( objectId );
+  std::string whereClause = RelationalObjectTable::columnNames::objectId();
+  whereClause += "= :objectId";
+  
+  // Delegate the query to the RelationalQueryMgr
+  try {
+    std::string desc = "";
+    // Fetch only the IOV metadata, not the payload
+    return RelationalObjectTableRow
+      ( db().queryMgr().fetchRowFromTables
+        ( RelationalQueryMgr::tableList( objectTableName ), 
+          RelationalQueryMgr::columnList
+          ( RelationalObjectTable::defaultSpecification() ),
+          whereClause, whereData, desc ) );
+  } catch( NoRowsFound& ) {
+    std::stringstream s;
+    s << "object_id: " << objectId;
+    throw ObjectNotFound
+      ( s.str(), objectTableName, "RalSchemaEvolution" );
+  }
+}
+
+//---------------------------------------------------------------------------
+
+void RalSchemaEvolution::insertChannelTableRow
+( const std::string& channelTableName,
+  const ChannelId& channelId,
+  const unsigned int lastObjectId,
+  const bool hasNewData,
+  const std::string& channelName,
+  const std::string& description ) const
+{
+  coral::AttributeList data =
+  Record( RelationalChannelTable::tableSpecification() ).attributeList();
+  data[RelationalChannelTable::columnNames::channelId()].setValue
+    ( channelId );
+  data[RelationalChannelTable::columnNames::lastObjectId()].setValue
+    ( lastObjectId );
+  data[RelationalChannelTable::columnNames::hasNewData()].setValue
+    ( hasNewData );
+  if ( channelName != "" )
+    data[RelationalChannelTable::columnNames::channelName()].setValue
+      ( channelName );
+  else
+    data[RelationalChannelTable::columnNames::channelName()].setNull();
+  data[RelationalChannelTable::columnNames::description()].setValue
+    ( description );
+  db().queryMgr().insertTableRow( channelTableName, data );
+}
+
+//-----------------------------------------------------------------------------
+
+void RalSchemaEvolution::evolveDatabase_200_to_220() 
+{
+  log() << coral::Info 
+        << "Evolve database schema (200->220)..." << coral::MessageStream::endmsg;
+
+  // -------------------------------------------------------------------
+  // Alter selected SQL types of columns in all existing tables:
+  // ( 1) Alter MySQL "VARCHAR(255)" into "VARCHAR(255) BINARY"
+  // -------------------------------------------------------------------
+
+  i_alterSqlTypes_200_to_220();
+
+  // -------------------------------------------------------------------
+  // Evolve each folder from 200 to 220
+  // ( 1) Fill the channels tables of all MV folders
+  // (2a) Create the 5-column index for user tags (task #4381) if needed
+  // (2b) Add FK constraints (on channelId) to each IOV table
+  // ( 3) Update the node table with new folder schema versions '2.0.1'
+  // -------------------------------------------------------------------
+
+  i_evolveNodes_200_to_220();
+
+  // Success
+  log() << coral::Info 
+        << "Evolve database schema (200->220)... DONE!" << coral::MessageStream::endmsg;
+}
+
+//-----------------------------------------------------------------------------
+
+void RalSchemaEvolution::i_alterSqlTypes_200_to_220()
+{
+  log() << coral::Info 
+        << "Alter SQL types (200->220)... START" << coral::MessageStream::endmsg;
+
+  // Schema evolution of SQL types is only needed for MySQL
+  std::string tech = db().sessionMgr()->databaseTechnology();
+  if ( tech == "Oracle" || tech == "SQLite") 
+  {
+    log() << coral::Info
+          << "Schema evolution of SQL types is NOT needed for technology '" 
+          << tech << "'" << coral::MessageStream::endmsg;
+  }
+  else if ( tech == "frontier" ) 
+  {
+    log() << coral::Error 
+          << "Schema evolution is not possible for read/only technology '" 
+          << tech << "'" << coral::MessageStream::endmsg;
+    throw RelationalException
+      ( "Schema evolution failed", "RalSchemaEvolution" );
+  }
+  else if ( tech != "MySQL" ) 
+  {
+    log() << coral::Error 
+          << "Unknown technology '" << tech << "'" << coral::MessageStream::endmsg;
+    throw RelationalException
+      ( "Schema evolution failed", "RalSchemaEvolution" );
+  }
+  else 
+  {
+    log() << coral::Info
+          << "Schema evolution of SQL types is needed for technology '" 
+          << tech << "'" << coral::MessageStream::endmsg;
+    const std::vector<std::string> tables = db().__listAllTables();
+    std::vector<std::string>::const_iterator iTable;
+    for ( iTable = tables.begin(); iTable != tables.end(); iTable++ ) 
+    {
+      std::string tableName = *iTable;
+      log() << coral::Info
+            << "Scan columns of table '" << tableName << "'" << coral::MessageStream::endmsg;
+      coral::ITable& table = db().sessionMgr()->session()
+        .nominalSchema().tableHandle( tableName );
+      int nCol = table.description().numberOfColumns();
+      for ( int iCol = 0; iCol < nCol; iCol++ ) 
+      {
+        const coral::IColumn& column = 
+          table.description().columnDescription(iCol);
+        //log() << coral::Verbose
+        //      << "--> Column '" << column.name() << "'" 
+        //      << ", type '" << column.type() << "'"
+        //      << ", size=" << column.size()
+        //      << ", isSizeFixed '" << column.isSizeFixed() << "'"
+        //      << coral::MessageStream::endmsg;
+        const std::string name = column.name();
+        std::string type = column.type();
+        long size = column.size();
+        const bool isSizeFixed = column.isSizeFixed();
+        if ( ( tech=="MySQL" && ( type=="string" && size==255 ) ) )
+        {
+          log() << coral::Info
+                << "Alter SQL type of column '" << name << "'" 
+                << " (type " << type << ", size " << size << ")"
+                << " in table '" << tableName << "'" << coral::MessageStream::endmsg;
+          if ( tech=="SQLite" && type=="long" ) type="int";
+          if ( tech=="SQLite" && type=="unsigned long" ) type="unsigned int";
+          table.schemaEditor().changeColumnType
+            ( name, type, size, isSizeFixed );
+        }
+      }
+    }    
+  }
+  
+  // Success
+  log() << coral::Info 
+        << "Alter SQL types (200->220)... DONE" << coral::MessageStream::endmsg;
+}  
+
+//-----------------------------------------------------------------------------
+
+void RalSchemaEvolution::i_evolveNodes_200_to_220() 
+{
+  log() << coral::Info 
+        << "Evolve individual nodes (200->220) if needed..." << coral::MessageStream::endmsg;
+  
+  {    
+    // List all folders ordered by nodeId
+    coral::AttributeList whereData;
+    whereData.extend
+      ( "isLeaf", 
+        typeIdToCoralType(RelationalNodeTable::columnTypeIds::nodeIsLeaf) );
+    whereData["isLeaf"].setValue
+      ( true ); // select folders only
+    std::string whereClause = RelationalNodeTable::columnNames::nodeIsLeaf;
+    whereClause += "= :isLeaf";
+    std::vector<std::string> orderBy;
+    std::string orderClause = RelationalNodeTable::columnNames::nodeId;
+    orderClause += " ASC";
+    orderBy.push_back( orderClause );
+    std::vector<RelationalTableRow> rows =
+      db().queryMgr().fetchOrderedRowsFromTables
+      ( RelationalQueryMgr::tableList( db().nodeTableName() ), 
+        RelationalQueryMgr::columnList
+        ( RelationalNodeTable::tableSpecification
+          ( VersionNumber( "2.0.0" ) ) ),
+        whereClause, whereData, orderBy, "" );
+    // Evolve all folders one by one
+    bool evolveNone = true;
+    for ( std::vector<RelationalTableRow>::const_iterator
+          row = rows.begin(); row != rows.end(); ++row ) 
+    {
+      std::string fullPath = 
+        (*row)[RelationalNodeTable::columnNames::nodeFullPath]
+        .data<std::string>();
+      std::string nodeSchemaVersion = 
+        (*row)[RelationalNodeTable::columnNames::nodeSchemaVersion]
+        .data<std::string>();
+      if ( nodeSchemaVersion != 
+           std::string( RelationalFolder::folderSchemaVersion() ) )
+      {
+        evolveNone = false;
+        log() << coral::Info 
+              << "Folder '" << fullPath << "' needs schema evolution"
+              << " from schema version '" << nodeSchemaVersion
+              << "' to '" << RelationalFolder::folderSchemaVersion()
+              << "'" << coral::MessageStream::endmsg;
+        i_fillChannelsTableMV_200_to_220( *row );
+        i_evolveIovTable_200_to_220( *row );    
+        i_updateNodeTable_200_to_220( *row );
+      }
+      else 
+      {
+        log() << coral::Verbose 
+              << "Folder '" << fullPath << "' is already schema version '"
+              << RelationalFolder::folderSchemaVersion()
+              << "' and needs no schema evolution" << coral::MessageStream::endmsg;
+      }
+    }
+    if ( evolveNone )
+      log() << coral::Info
+            << "All folders are already schema version '"
+            << RelationalFolder::folderSchemaVersion()
+            << "' and need no schema evolution" << coral::MessageStream::endmsg;
+  }
+  
+  // Success
+  log() << coral::Info 
+        << "Evolve individual nodes (200->220) if needed... DONE!" 
+        << coral::MessageStream::endmsg;
+}
+
+//-----------------------------------------------------------------------------
+
+void RalSchemaEvolution::i_fillChannelsTableMV_200_to_220
+( const RelationalTableRow& row )
+{
+  int folderVersioningMode = 
+    row[RelationalNodeTable::columnNames::folderVersioningMode].data<int>();
+  
+  // Only MV folders need to be updated
+  if ( folderVersioningMode != FolderVersioning::MULTI_VERSION ) return;
+  
+  unsigned int nodeId =
+    row[RelationalNodeTable::columnNames::nodeId].data<unsigned int>();
+  std::string channelTableName =
+    RelationalChannelTable::defaultTableName
+    ( db().defaultTablePrefix(), nodeId );
+  log() << coral::Info 
+        << "Fill the MV channels table " << channelTableName 
+        << " (200->220)..." << coral::MessageStream::endmsg;
+  
+  std::string objectTableName = 
+    row[RelationalNodeTable::columnNames::folderObjectTableName]
+    .data<std::string>();
+  std::vector<ChannelId> channels = listChannels( objectTableName );
+
+  for ( std::vector<ChannelId>::const_iterator
+          ch = channels.begin(); ch != channels.end(); ++ch ) 
+  {
+    log() << coral::Verbose 
+          << "Fill the MV channels table " << channelTableName 
+          << " (200->220)..."
+          << " Insert channel: " << *ch << coral::MessageStream::endmsg;
+    RelationalObjectTableRow objRow = fetchLastRow( objectTableName, *ch );
+    bool hasNewData = false;
+    std::string channelName = "";
+    std::string description = "";
+    // Avoid CORAL error messages by changing the output level
+    coral::MsgLevel outputLevel = coral::MessageStream::msgVerbosity();
+    try 
+    {
+      //coral::MessageStream::setMsgVerbosity( coral::Fatal );
+      insertChannelTableRow( channelTableName,
+                             *ch,
+                             objRow.objectId(),
+                             hasNewData,
+                             channelName,
+                             description );
+      coral::MessageStream::setMsgVerbosity( outputLevel );
+    }
+    // Ignore any rows already present in the channels table (fix bug #30361)
+    catch ( coral::DuplicateEntryInUniqueKeyException& )
+    {
+      coral::MessageStream::setMsgVerbosity( outputLevel ); // OK?
+      log() << coral::Warning
+            << "Fill the MV channels table " << channelTableName
+            << " (200->220)..." 
+            << " channel " << *ch << " already exists" << coral::MessageStream::endmsg;
+    }
+    // Debug printout for bug #45716
+    catch ( std::exception& e )
+    {
+      coral::MessageStream::setMsgVerbosity( outputLevel ); // OK?
+      log() << coral::Warning
+            << "Fill the MV channels table " << channelTableName
+            << " (200->220)..." 
+            << " Exception caught while inserting channel " << *ch 
+            << ": " << e.what() << coral::MessageStream::endmsg;
+      log() << coral::Warning
+            << "Exception will be rethrown" << coral::MessageStream::endmsg;
+      throw;
+    }
+  }
+    
+  log() << coral::Info 
+        << "Fill the MV channels table " << channelTableName 
+        << " (200->220)... DONE!" << coral::MessageStream::endmsg;
+}
+
+//-----------------------------------------------------------------------------
+
+void RalSchemaEvolution::i_evolveIovTable_200_to_220
+( const RelationalTableRow& row )
+{
+  log() << coral::Info 
+        << "Evolve IOV table schema (200->220)... START" << coral::MessageStream::endmsg;
+  std::string fullPath = 
+    row[RelationalNodeTable::columnNames::nodeFullPath]
+    .data<std::string>();
+  std::string objectTableName = 
+    row[RelationalNodeTable::columnNames::folderObjectTableName]
+    .data<std::string>();
+  std::string channelTableName = 
+    row[RelationalNodeTable::columnNames::folderChannelTableName]
+    .data<std::string>();
+  
+  // 1. Add the 5-column index for user tags (task #4381) if needed
+  {
+    std::string indexName = objectTableName + "_UTAG_5INDX";
+    log() << coral::Info 
+          << "Folder '" << fullPath << "' needs schema evolution"
+          << ": add index '" << indexName 
+          << "' to table '" << objectTableName
+          << "' if needed" << coral::MessageStream::endmsg;
+    try 
+    {
+      coral::ITable& objectTable = db().sessionMgr()->session()
+        .nominalSchema().tableHandle( objectTableName );
+      const coral::ITableDescription& description = objectTable.description();
+      unsigned int nInd = description.numberOfIndices();
+      bool indexExists = false;
+      for ( unsigned iInd = 0; iInd < nInd; iInd++ )
+      {
+        if ( description.index( iInd ).name() == indexName )
+          indexExists = true;        
+      }
+      if ( !indexExists ) 
+      {
+        coral::ITableSchemaEditor& editor = objectTable.schemaEditor();
+        std::vector<std::string> indColumns;
+        indColumns.push_back
+          ( RelationalObjectTable::columnNames::userTagId() );
+        indColumns.push_back
+          ( RelationalObjectTable::columnNames::newHeadId() );
+        indColumns.push_back
+          ( RelationalObjectTable::columnNames::channelId() );
+        indColumns.push_back
+          ( RelationalObjectTable::columnNames::iovSince() );
+        indColumns.push_back
+          ( RelationalObjectTable::columnNames::iovUntil() );
+        bool unique = true;
+        editor.createIndex( indexName, indColumns, unique );
+      }
+      else 
+      {
+        log() << coral::Info
+              << "Index '" << indexName << "' already exists in table '" 
+              << objectTableName << coral::MessageStream::endmsg;
+      } 
+    } 
+    catch ( std::exception& e ) 
+    {
+      log() << coral::Error 
+            << "Exception caught: '" << e.what() << "'" << coral::MessageStream::endmsg;
+      log() << coral::Error 
+            << "Failed add index '" << indexName 
+            << "' to table '" << objectTableName << coral::MessageStream::endmsg;
+      throw RelationalException
+        ( "Schema evolution failed", "RalSchemaEvolution" );
+    }    
+  }
+    
+  // 2. Add the FK constraint from the object table to the channel table
+  {
+    log() << coral::Info 
+          << "Folder '" << fullPath << "' needs schema evolution"
+          << ": create FK reference from channels"
+          << " in table '" << objectTableName
+          << "' to channels"
+          << " in table '" << channelTableName << "'" << coral::MessageStream::endmsg;
+    try 
+    {
+      db().schemaMgr().createObjectChannelFK
+        ( objectTableName, channelTableName );
+    } 
+    catch ( std::exception& e ) 
+    {
+      log() << coral::Error 
+            << "Exception caught: '" << e.what() << "'" << coral::MessageStream::endmsg;
+      log() << coral::Error 
+            << "Failed to create FK reference from channels"
+            << " in table '" << objectTableName
+            << "' to channels"
+            << " in table '" << channelTableName << "'" << coral::MessageStream::endmsg;
+      throw RelationalException
+        ( "Schema evolution failed", "RalSchemaEvolution" );
+    }    
+  }
+  
+  // Success
+  log() << coral::Info 
+        << "Evolve IOV table schema (200->220)... DONE!" << coral::MessageStream::endmsg;
+}
+
+//-----------------------------------------------------------------------------
+
+void RalSchemaEvolution::i_updateNodeTable_200_to_220
+( const RelationalTableRow& row )
+{ 
+  unsigned int nodeId =
+    row[RelationalNodeTable::columnNames::nodeId].data<unsigned int>();
+  
+  // 1. Update NODE_SCHEMA_VERSION
+  {
+    log() << coral::Info 
+          << "Updating folder schema version " 
+          << RelationalFolder::folderSchemaVersion()
+          << " in node table (200->220)..." << coral::MessageStream::endmsg;
+    std::string columnName = 
+      RelationalNodeTable::columnNames::nodeSchemaVersion;
+    const StorageType::TypeId columnTypeId = 
+      RelationalNodeTable::columnTypeIds::nodeSchemaVersion;
+    const cool::StorageType& columnType = 
+      StorageType::storageType( columnTypeId );
+    coral::AttributeList updateData;
+    updateData.extend
+      ( "nodeSchemaVersion", columnType.cppType() );
+    updateData.extend
+      ( "nodeId", 
+        StorageType::storageType
+        ( RelationalNodeTable::columnTypeIds::nodeId ).cppType() );
+    updateData["nodeSchemaVersion"]
+      .setValue<RelationalNodeTable::columnTypes::folderChannelTableName>
+      ( RelationalFolder::folderSchemaVersion() );
+    updateData["nodeId"].
+      setValue<RelationalNodeTable::columnTypes::nodeId>
+      ( nodeId );
+    std::string setClause = columnName + "=:nodeSchemaVersion";
+    std::string whereClause = 
+      RelationalNodeTable::columnNames::nodeId + "=:nodeId";
+    unsigned int expectedRows = 1;
+    if ( ! db().queryMgr().updateTableRows
+         ( db().nodeTableName(), setClause, whereClause, 
+           updateData, expectedRows ) ) 
+    {
+      log() << coral::Error 
+            << "Failed to set value to in column '" << columnName 
+            << "' of table '" << db().nodeTableName() << "'" << coral::MessageStream::endmsg;
+      throw RelationalException
+        ( "Schema evolution failed", "RalSchemaEvolution" );
+    }
+    log() << coral::Info 
+          << "Updating folder schema version " 
+          << RelationalFolder::folderSchemaVersion()
+          << " in node table (200->220)... DONE!" << coral::MessageStream::endmsg;
+  }
+}
+
+//-----------------------------------------------------------------------------
+
diff --git a/RelationalCool/utilities/coolEvolveSchema/RalSchemaEvolution.h b/RelationalCool/utilities/coolEvolveSchema/RalSchemaEvolution.h
new file mode 100644
index 000000000..e22c8e8f8
--- /dev/null
+++ b/RelationalCool/utilities/coolEvolveSchema/RalSchemaEvolution.h
@@ -0,0 +1,162 @@
+// $Id: RalSchemaEvolution.h,v 1.32 2008-04-10 15:31:15 avalassi Exp $
+#ifndef RELATIONALCOOL_RALSCHEMAEVOLUTION_H 
+#define RELATIONALCOOL_RALSCHEMAEVOLUTION_H 1
+
+// Include files
+#include <boost/shared_ptr.hpp>
+#include "CoolKernel/DatabaseId.h"
+#include "CoolKernel/RecordSpecification.h"
+#include "CoralBase/MessageStream.h"
+#include "RelationalAccess/IConnectionService.h"
+
+// Local include files
+#include "../../src/CoralConnectionServiceProxy.h"
+
+namespace cool 
+{
+
+  // Forward declarations
+  class RalDatabase;
+  class RelationalObjectTableRow;
+  class RelationalTableRow;
+
+  /** @class RalSchemaEvolution RalSchemaEvolution.h
+   *  
+   *  Private utility class to implement COOL relational schema evolution.
+   *
+   *  @author Andrea Valassi
+   *  @date   2006-03-15
+   */
+
+  class RalSchemaEvolution 
+  {
+    
+  public:
+    
+    /// Constructor
+    RalSchemaEvolution( CoralConnectionServiceProxyPtr ppConnSvc,
+                        const DatabaseId& dbId );
+    
+    /// Destructor
+    virtual ~RalSchemaEvolution();    
+    
+    /// Evolve the schema of the full database to version 220.
+    /// Encapsulate schema evolution in a single transaction.
+    void evolveDatabase();
+
+  protected:
+    
+    /// Get a CORAL MessageStream
+    coral::MessageStream& log();
+
+    /// Get the RalDatabase reference
+    const RalDatabase& db() const { return *m_db; }
+
+    /// --- SCHEMA EVOLUTION FROM COOL_1_3_0 TO COOL_2_0_0
+
+    /// Evolve the schema of the full database (130->200).
+    void evolveDatabase_130_to_200();
+    
+    /// Evolve the schema of the node table (130->200).
+    void i_evolveNodeTable_130_200();
+
+    /// Evolve the schema of the global tag table (130->200).
+    void i_evolveGlobalTagTable_130_200();
+
+    /// Evolve the schema of the tag2tag table (130->200).
+    void i_evolveTag2TagTable_130_200();
+
+    /// Create the tag shared sequence (130->200).
+    void i_createTagSharedSequence_130_200();
+
+    /// Create the IOV shared sequence (130->200).
+    void i_createIovSharedSequence_130_200();
+
+    /// Evolve the IOV table schema for a given folder (130->200).
+    void i_evolveIovTable_130_to_200( const RelationalTableRow& row );
+    
+    /// Create the channels table for a given folder (130->200).
+    void i_createChannelsTable_130_to_200( const RelationalTableRow& row );
+
+    /// Fill the channels tables for a given SV folder (130->200).
+    void i_fillChannelsTableSV_130_to_200( const RelationalTableRow& row );
+    
+    /// Update node table with updated values for a given folder (130->200).
+    void i_updateNodeTable_130_to_200( const RelationalTableRow& row );
+
+    /// Evolve the schema and contents of the main table (130->200).
+    void i_evolveMainTable_130_to_200();
+
+    /// Alter selected SQL types in all tables (130->200, MySQL/sqlite only).
+    void i_alterSqlTypes_130_to_200();
+
+    /// Decode a 200 RecordSpecification from a 130 encoded 'extended' EALS
+    static const RecordSpecification
+    decodeRecordSpecification130( const std::string& encodedEALS );
+    
+    /// Decode a 200 StorageType from a 130 encoded type specification
+    static const StorageType& 
+    storageType130( const std::string& encodedType );
+    
+    const std::vector<ChannelId> 
+    listChannels( const std::string& objectTableName ) const;
+    
+    RelationalObjectTableRow
+    fetchLastRow( const std::string& objectTableName,
+                  const ChannelId& channelId );
+    
+    const RelationalObjectTableRow
+    fetchRowForId( const std::string& objectTableName,
+                   const unsigned int objectId ) const;
+    
+    void insertChannelTableRow( const std::string& channelTableName,
+                                const ChannelId& channelId,
+                                const unsigned int lastObjectId,
+                                const bool hasNewData,
+                                const std::string& channelName,
+                                const std::string& description ) const;
+      
+    /// --- SCHEMA EVOLUTION FROM COOL_2_0_0 TO COOL_2_2_0
+
+    /// Evolve SQL types and the schema of individual nodes (200->220).
+    void evolveDatabase_200_to_220();
+    
+    /// Alter selected SQL types in all tables (200->220, MySQL only).
+    void i_alterSqlTypes_200_to_220();
+
+    /// Evolve the schema of individual nodes (200->220).
+    void i_evolveNodes_200_to_220();
+    
+    /// Fill the channels tables for a given MV folder (200->220).
+    void i_fillChannelsTableMV_200_to_220( const RelationalTableRow& row );
+    
+    /// Evolve the IOV table schema for a given folder (200->220).
+    void i_evolveIovTable_200_to_220( const RelationalTableRow& row );
+    
+    /// Update node table with updated values for a given folder (200->220).
+    void i_updateNodeTable_200_to_220( const RelationalTableRow& row );
+
+  private:
+
+    /// Standard constructor is private
+    RalSchemaEvolution(); 
+
+    /// Copy constructor is private
+    RalSchemaEvolution( const RalSchemaEvolution& rhs ); 
+
+    /// Assignment operator is private
+    RalSchemaEvolution& operator=( const RalSchemaEvolution& rhs ); 
+   
+  private:
+
+    /// RalDatabase pointer
+    RalDatabase* m_db;    
+
+    /// CORAL MessageStream
+    std::auto_ptr<coral::MessageStream> m_log;
+
+  };
+
+}
+
+#endif // RELATIONALCOOL_RALSCHEMAEVOLUTION_H
diff --git a/RelationalCool/utilities/coolEvolveSchema/coolEvolveSchema.cpp b/RelationalCool/utilities/coolEvolveSchema/coolEvolveSchema.cpp
new file mode 100644
index 000000000..f26a8ed7a
--- /dev/null
+++ b/RelationalCool/utilities/coolEvolveSchema/coolEvolveSchema.cpp
@@ -0,0 +1,96 @@
+// $Id: coolEvolveSchema.cpp,v 1.15 2008-04-10 15:31:15 avalassi Exp $
+
+// Include files
+#include <iostream>
+#include "CoolKernel/IDatabase.h"
+#include "CoolKernel/IDatabaseSvc.h"
+#include "RelationalAccess/IConnectionService.h"
+#include "RelationalAccess/IConnectionServiceConfiguration.h"
+
+// Local include files
+#include "RalSchemaEvolution.h"
+#include "../../src/CoralApplication.h"
+#include "../../src/CoralConnectionServiceProxy.h"
+#include "../../src/RalDatabase.h"
+#include "../../src/VersionInfo.h"
+
+// Namespace
+using namespace cool;
+
+// Message output
+#define LOG std::cout
+
+//-----------------------------------------------------------------------------
+
+int main( int argc, char** argv )
+{
+
+  try {
+    
+    // Get the command line arguments
+    std::string dbId;
+    if ( argc != 2 ) {
+      LOG << "Usage: " << argv[0] << " dbId" << std:: endl;
+      std::string dbIdOra = 
+        "oracle://SERVER;schema=USER1;dbname=DB;user=USER1";
+      LOG << "Example: " << argv[0] << " '" << dbIdOra << "'\n" << std::endl;
+      return 1;
+    }
+    else {
+      dbId = argv[1];
+    } 
+  
+    // Instantiate a COOL Application
+    CoralApplication app;
+    
+    // If we can access a LFC and the user is not explicitely forbidding it,
+    // we try to use CORAL LFCReplicaService
+    if ( ::getenv("COOL_IGNORE_LFC") == NULL &&
+         ::getenv("LFC_HOST") != NULL ) 
+    {
+      // try to load CORAL LFCReplicaService
+      coral::IConnectionServiceConfiguration &connSvcConf =
+            app.connectionSvc().configuration();
+      connSvcConf.setAuthenticationService("CORAL/Services/LFCReplicaService");
+      connSvcConf.setLookupService("CORAL/Services/LFCReplicaService");
+    }
+
+    // Create a schema evolution manager
+    cool::CoralConnectionServiceProxyPtr ppConnSvc
+      ( new cool::CoralConnectionServiceProxy( &app.connectionSvc() ) );
+    RalSchemaEvolution se( ppConnSvc, dbId );
+
+    // Evolve the schema of the whole database
+    se.evolveDatabase();
+
+    // Close the session manager access to the CORAL connection service
+    ppConnSvc->purgeConnectionPool();
+    ppConnSvc->resetICS();
+
+  }
+  
+  catch( cool::Exception& e ) 
+  {
+    LOG << "ERROR! Cool Exception: '" << e.what() << "'" << std::endl;
+    return 1;
+  }
+
+  catch( std::exception& e )
+  {
+    LOG << "ERROR! Standard C++ exception: '" << e.what() << "'" << std::endl;
+    return 1;
+  }
+
+  catch( ... ) 
+  {
+    LOG << "ERROR! Unknown exception caught" << std::endl;
+    return 1;
+  }
+
+  // Successful program termination
+  LOG << "Schema evolution successfully completed" << std::endl;
+  return 0;
+  
+}
+
+//-----------------------------------------------------------------------------
diff --git a/RelationalCool/utilities/coolPrivileges/RalPrivilegeManager.cpp b/RelationalCool/utilities/coolPrivileges/RalPrivilegeManager.cpp
new file mode 100644
index 000000000..85ed7f90e
--- /dev/null
+++ b/RelationalCool/utilities/coolPrivileges/RalPrivilegeManager.cpp
@@ -0,0 +1,510 @@
+// $Id: RalPrivilegeManager.cpp,v 1.12 2009-01-06 11:52:12 avalassi Exp $
+
+// Include files
+#include "RelationalAccess/ISchema.h"
+#include "RelationalAccess/ITable.h"
+
+// Local include files
+// [NB Weird: a transaction is needed to avoid OCI_INVALID_HANDLE...]
+// [See http://dbforums.com/t394084.html]
+#include "RalPrivilegeManager.h"
+#include "../../src/RalDatabase.h"
+#include "../../src/RelationalException.h"
+#include "../../src/RelationalFolder.h"
+#include "../../src/RelationalFolderSet.h"
+#include "../../src/RelationalNodeTable.h"
+#include "../../src/RelationalObjectTable.h"
+#include "../../src/RelationalTagSequence.h"
+#include "../../src/RelationalTagTable.h"
+#include "../../src/RelationalTag2TagTable.h"
+#include "../../src/RelationalTransaction.h"
+
+// Workaround for Windows (win32_vc9_dbg)
+// DELETE seems to be defined in a Windows VC9 header
+// See also CoolKernel/CoolKernel/MessageLevels.h
+// See also RelationalCool/src/CoralApplication.cpp
+#ifdef WIN32
+#ifdef DELETE
+#undef DELETE
+#pragma message ("WARN!NG: in coolPrivileges/RalPrivilegeManager.cpp")
+#pragma message ("WARN!NG: 'DELETE' was defined and has been undefined")
+#endif
+#endif
+
+// Namespace
+using namespace cool;
+
+//-----------------------------------------------------------------------------
+
+RalPrivilegeManager::RalPrivilegeManager( RalDatabase* db ) 
+  : m_db( db )
+  , m_log( new coral::MessageStream
+           ( "RalPrivilegeManager" ) )
+{
+  log() << coral::Debug << "Instantiate a RalPrivilegeManager for '" 
+        << m_db->databaseId() << "'" << coral::MessageStream::endmsg;
+  m_fourPrivs.push_back( SELECT );
+  m_fourPrivs.push_back( INSERT );
+  m_fourPrivs.push_back( UPDATE );
+  m_fourPrivs.push_back( DELETE );
+  // This class can only be used with "oracle" database technology
+  if ( m_db->sessionMgr()->databaseTechnology() != "Oracle" ) {
+    throw RelationalException
+      ( "Unsupported technology '" + m_db->sessionMgr()->databaseTechnology() + 
+        "' for database privilege management ", "RalPrivilegeManager" );
+  }  
+}
+
+//-----------------------------------------------------------------------------
+
+RalPrivilegeManager::~RalPrivilegeManager() 
+{
+  log() << coral::Debug << "Delete the RalPrivilegeManager for '" 
+        << m_db->databaseId() << "'" << coral::MessageStream::endmsg;
+}
+ 
+//-----------------------------------------------------------------------------
+
+coral::MessageStream& RalPrivilegeManager::log() {
+  *m_log << coral::Verbose;
+  return *m_log;
+}
+
+//-----------------------------------------------------------------------------
+
+std::vector< std::string > 
+RalPrivilegeManager::i_listReaderTables( const Privilege& priv ) 
+{
+  std::vector< std::string > tables;
+
+  // Tables with SELECT privileges
+  if ( priv == SELECT ) {
+
+    // Main table
+    tables.push_back
+      ( m_db->mainTableName() );
+    
+    // Node table and sequence
+    tables.push_back
+      ( m_db->nodeTableName() );
+    tables.push_back
+      ( RelationalNodeTable::sequenceName( m_db->nodeTableName() ) );
+    
+    // Global tag table
+    tables.push_back
+      ( m_db->globalTagTableName() );
+    
+    // Tag2tag table and sequence
+    tables.push_back
+      ( m_db->tag2TagTableName() );
+    tables.push_back
+      ( RelationalTag2TagTable::sequenceName( m_db->tag2TagTableName() ) );
+    
+    // Tag shared sequence
+    tables.push_back
+      ( m_db->tagSharedSequenceName() );
+    
+    // Object shared sequence
+    tables.push_back
+      ( m_db->iovSharedSequenceName() );
+    
+    // Loop over all nodes in the database
+    std::vector<std::string> nodes( m_db->listAllNodes( false ) );
+    std::vector<std::string>::const_iterator node;
+    for ( node = nodes.begin(); node != nodes.end(); node++ ) {
+      // Process folders
+      try {
+        IFolderPtr folder = m_db->getFolder( *node );
+        RelationalFolder* relFolder = 
+          dynamic_cast<RelationalFolder*>( folder.get() );
+        // Object table and sequence
+        tables.push_back
+          ( relFolder->objectTableName() );
+        tables.push_back
+          ( RelationalObjectTable::sequenceName 
+            ( relFolder->objectTableName() ) );
+        // Channel table 
+        tables.push_back
+          ( relFolder->channelTableName() );
+        // Tag table and sequence and object2tag table (MV only)
+        if ( relFolder->versioningMode() == FolderVersioning::MULTI_VERSION ) {
+          tables.push_back
+            ( relFolder->tagTableName() );
+          tables.push_back
+            ( RelationalTagSequence::sequenceName
+              ( m_db->defaultTablePrefix(), relFolder->id() ) );
+          tables.push_back
+            ( relFolder->object2TagTableName() );
+        }
+      }
+      catch ( FolderNotFound& e ) {
+        if ( ! e.isFolderSet() ) throw;
+      }  
+      // Process folder sets
+      try {
+        IFolderSetPtr folderSet = m_db->getFolderSet( *node );
+        RelationalFolderSet* relFolderSet = 
+          dynamic_cast<RelationalFolderSet*>( folderSet.get() );
+        if ( priv == SELECT ) {
+          // Local tag sequence
+          tables.push_back
+            ( RelationalTagSequence::sequenceName
+              ( m_db->defaultTablePrefix(), relFolderSet->id() ) );
+        }        
+      }
+      catch ( FolderSetNotFound& e ) {
+        if ( ! e.isFolder() ) throw;
+      }  
+    }  
+  }
+  
+  // Tables with INSERT or UPDATE or DELETE privileges
+  else if ( priv == INSERT || priv == UPDATE || priv == DELETE ) {
+    // No tables!
+  }
+  
+  // Unknown privilege
+  else {
+    throw RelationalException
+      ( "PANIC! Unknown privilege", "RalPrivilegeManager" );
+  }  
+
+  return tables;
+
+}
+
+//-----------------------------------------------------------------------------
+
+std::vector< std::string > 
+RalPrivilegeManager::i_listWriterTables( const Privilege& priv ) 
+{
+  std::vector< std::string > tables;
+
+  // Tables with SELECT privileges
+  if ( priv == SELECT ) {
+    // No tables! Reader privileges must be granted explcitly!
+    //tables = i_listReaderTables( SELECT );
+  }
+
+  // Tables with INSERT or UPDATE privileges
+  else if ( priv == INSERT || priv == UPDATE ) {
+
+    if ( priv == UPDATE ) {
+      // UPDATE: object shared sequence
+      tables.push_back
+        ( m_db->iovSharedSequenceName() );
+    }
+
+    // Loop over all nodes in the database
+    std::vector<std::string> nodes( m_db->listAllNodes( false ) );
+    std::vector<std::string>::const_iterator node;
+    for ( node = nodes.begin(); node != nodes.end(); node++ ) {
+      try {
+        IFolderPtr folder = m_db->getFolder( *node );
+        RelationalFolder* relFolder = 
+          dynamic_cast<RelationalFolder*>( folder.get() );
+        if ( priv == INSERT ) {
+          // INSERT: object table, channel table
+          tables.push_back
+            ( relFolder->objectTableName() );
+          tables.push_back
+            ( relFolder->channelTableName() );
+        } else {
+          // UPDATE: object table and sequence, channel table
+          tables.push_back
+            ( relFolder->objectTableName() );
+          tables.push_back
+            ( RelationalObjectTable::sequenceName 
+            ( relFolder->objectTableName() ) );
+          tables.push_back
+            ( relFolder->channelTableName() );
+        }        
+      }
+      catch ( FolderNotFound& e ) {
+        if ( ! e.isFolderSet() ) throw;
+      }  
+    }  
+  }
+  
+  // Tables with DELETE privileges
+  else if ( priv == DELETE ) {
+    // No tables!
+  }
+
+  // Unknown privilege
+  else {
+    throw RelationalException
+      ( "PANIC! Unknown privilege", "RalPrivilegeManager" );
+  }  
+
+  return tables;
+
+}
+
+//-----------------------------------------------------------------------------
+
+std::vector< std::string > 
+RalPrivilegeManager::i_listTaggerTables( const Privilege& priv,
+                                         const bool retag ) 
+{
+  std::vector< std::string > tables;
+
+  // Tables with SELECT privileges
+  if ( priv == SELECT ) {
+    // No tables! Reader privileges must be granted explcitly!
+    //tables = i_listReaderTables( SELECT );
+  }
+
+  // Tables with INSERT or UPDATE or DELETE privileges
+  else if ( priv == INSERT || priv == UPDATE || priv == DELETE ) {
+
+    if ( priv == INSERT ) {
+      // INSERT: global tag and tag2tag tables
+      tables.push_back
+        ( m_db->globalTagTableName() );
+      tables.push_back
+        ( m_db->tag2TagTableName() );
+    } else if ( priv == UPDATE ) {
+      // UPDATE: tag shared sequence and tag2tag sequence
+      tables.push_back
+        ( m_db->tagSharedSequenceName() );
+      tables.push_back
+        ( RelationalTag2TagTable::sequenceName( m_db->tag2TagTableName() ) );
+    } else {
+      // DELETE: global tag and tag2tag table (only for retagging)
+      if ( retag ) {
+        tables.push_back
+          ( m_db->globalTagTableName() );
+        tables.push_back
+          ( m_db->tag2TagTableName() );
+      }
+    }        
+
+    // Loop over all nodes in the database
+    std::vector<std::string> nodes( m_db->listAllNodes( false ) );
+    std::vector<std::string>::const_iterator node;
+    for ( node = nodes.begin(); node != nodes.end(); node++ ) {
+      // Process folders
+      try {
+        IFolderPtr folder = m_db->getFolder( *node );
+        RelationalFolder* relFolder = 
+          dynamic_cast<RelationalFolder*>( folder.get() );
+        // MV folders only
+        if ( relFolder->versioningMode() == FolderVersioning::MULTI_VERSION ) {
+          if ( priv == INSERT ) {
+            // INSERT: local tag and object2tag table
+            tables.push_back
+              ( relFolder->tagTableName() );
+            tables.push_back
+              ( relFolder->object2TagTableName() );
+          } else if ( priv == UPDATE ) {
+            // UPDATE: local tag sequence
+            tables.push_back
+              ( RelationalTagSequence::sequenceName
+                ( m_db->defaultTablePrefix(), relFolder->id() ) );
+          } else {
+            // DELETE: local tag and object2tag table (only for retagging)
+            if ( retag ) {
+              tables.push_back
+                ( relFolder->tagTableName() );
+              tables.push_back
+                ( relFolder->object2TagTableName() );
+            }
+          }        
+        }
+      }
+      catch ( FolderNotFound& e ) {
+        if ( ! e.isFolderSet() ) throw;
+      }  
+      // Process folder sets
+      try {
+        IFolderSetPtr folderSet = m_db->getFolderSet( *node );
+        RelationalFolderSet* relFolderSet = 
+          dynamic_cast<RelationalFolderSet*>( folderSet.get() );
+        if ( priv == UPDATE ) {
+          // UPDATE: local tag sequence
+          tables.push_back
+            ( RelationalTagSequence::sequenceName
+              ( m_db->defaultTablePrefix(), relFolderSet->id() ) );
+        }        
+      }
+      catch ( FolderSetNotFound& e ) {
+        if ( ! e.isFolder() ) throw;
+      }  
+    }  
+  }
+  
+  // Unknown privilege
+  else {
+    throw RelationalException
+      ( "PANIC! Unknown privilege", "RalPrivilegeManager" );
+  }  
+
+  return tables;
+
+}
+
+//-----------------------------------------------------------------------------
+
+coral::ITablePrivilegeManager&
+RalPrivilegeManager::i_tablePrivMgr( const std::string& tableName )
+{
+  coral::ITable& tableHandle =
+    m_db->session().nominalSchema().tableHandle( tableName );
+  return tableHandle.privilegeManager();
+}
+
+//-----------------------------------------------------------------------------
+
+void RalPrivilegeManager::i_grantPrivilege( const Privilege& priv, 
+                                            const std::string& table,
+                                            const std::string& user )
+{
+  coral::ITablePrivilegeManager::Privilege ralPriv;
+  if ( priv == SELECT ) 
+    ralPriv = coral::ITablePrivilegeManager::Select;
+  else if ( priv == INSERT ) 
+    ralPriv = coral::ITablePrivilegeManager::Insert;
+  else if ( priv == UPDATE ) 
+    ralPriv = coral::ITablePrivilegeManager::Update;
+  else if ( priv == DELETE ) 
+    ralPriv = coral::ITablePrivilegeManager::Delete;
+  else 
+    throw RelationalException
+      ( "PANIC! Unknown privilege", "RalPrivilegeManager" );
+  i_tablePrivMgr( table ).grantToUser( user, ralPriv );
+}
+
+//-----------------------------------------------------------------------------
+
+void RalPrivilegeManager::i_revokePrivilege( const Privilege& priv, 
+                                             const std::string& table,
+                                             const std::string& user )
+{
+  coral::ITablePrivilegeManager::Privilege ralPriv;
+  if ( priv == SELECT ) 
+    ralPriv = coral::ITablePrivilegeManager::Select;
+  else if ( priv == INSERT ) 
+    ralPriv = coral::ITablePrivilegeManager::Insert;
+  else if ( priv == UPDATE ) 
+    ralPriv = coral::ITablePrivilegeManager::Update;
+  else if ( priv == DELETE ) 
+    ralPriv = coral::ITablePrivilegeManager::Delete;
+  else 
+    throw RelationalException
+      ( "PANIC! Unknown privilege", "RalPrivilegeManager" );
+  i_tablePrivMgr( table ).revokeFromUser( user, ralPriv );
+}
+
+//-----------------------------------------------------------------------------
+
+void RalPrivilegeManager::grantReaderPrivileges( const std::string& user )
+{
+  log() << "Grant reader role privileges to user '" << user << "'" 
+        << coral::MessageStream::endmsg;
+  std::vector<Privilege>::const_iterator priv;
+  for ( priv = m_fourPrivs.begin(); priv != m_fourPrivs.end(); priv++ ) {
+    std::vector<std::string> tables( i_listReaderTables( *priv ) );
+    std::vector<std::string>::const_iterator table;
+    RelationalTransaction transaction( m_db->transactionMgr() ); // read-write
+    for ( table = tables.begin(); table != tables.end(); table++ ) {
+      i_grantPrivilege( *priv, *table, user );
+    }
+    transaction.commit();
+  }
+}
+
+//-----------------------------------------------------------------------------
+
+void RalPrivilegeManager::revokeReaderPrivileges( const std::string& user )
+{
+  log() << "Revoke reader role privileges from user '" << user << "'" 
+        << coral::MessageStream::endmsg;
+  std::vector<Privilege>::const_iterator priv;
+  for ( priv = m_fourPrivs.begin(); priv != m_fourPrivs.end(); priv++ ) {
+    std::vector<std::string> tables( i_listReaderTables( *priv ) );
+    std::vector<std::string>::const_iterator table;
+    RelationalTransaction transaction( m_db->transactionMgr() ); // read-write
+    for ( table = tables.begin(); table != tables.end(); table++ ) {
+      i_revokePrivilege( *priv, *table, user );
+    }
+    transaction.commit();
+  }
+}
+
+//-----------------------------------------------------------------------------
+
+void RalPrivilegeManager::grantWriterPrivileges( const std::string& user )
+{
+  log() << "Grant writer role privileges to user '" << user << "'" 
+        << coral::MessageStream::endmsg;
+  std::vector<Privilege>::const_iterator priv;
+  for ( priv = m_fourPrivs.begin(); priv != m_fourPrivs.end(); priv++ ) {
+    std::vector<std::string> tables( i_listWriterTables( *priv ) );
+    std::vector<std::string>::const_iterator table;
+    RelationalTransaction transaction( m_db->transactionMgr() ); // read-write
+    for ( table = tables.begin(); table != tables.end(); table++ ) {
+      i_grantPrivilege( *priv, *table, user );
+    }
+    transaction.commit();
+  }
+}
+
+//-----------------------------------------------------------------------------
+
+void RalPrivilegeManager::revokeWriterPrivileges( const std::string& user )
+{
+  log() << "Revoke writer role privileges from user '" << user << "'" 
+        << coral::MessageStream::endmsg;
+  std::vector<Privilege>::const_iterator priv;
+  for ( priv = m_fourPrivs.begin(); priv != m_fourPrivs.end(); priv++ ) {
+    std::vector<std::string> tables( i_listWriterTables( *priv ) );
+    std::vector<std::string>::const_iterator table;
+    RelationalTransaction transaction( m_db->transactionMgr() ); // read-write
+    for ( table = tables.begin(); table != tables.end(); table++ ) {
+      i_revokePrivilege( *priv, *table, user );
+    }
+    transaction.commit();
+  }
+}
+
+//-----------------------------------------------------------------------------
+
+void RalPrivilegeManager::grantTaggerPrivileges( const std::string& user,
+                                                 const bool retag )
+{
+  log() << "Grant tagger role privileges to user '" << user << "'" 
+        << coral::MessageStream::endmsg;
+  std::vector<Privilege>::const_iterator priv;
+  for ( priv = m_fourPrivs.begin(); priv != m_fourPrivs.end(); priv++ ) {
+    std::vector<std::string> tables( i_listTaggerTables( *priv, retag ) );
+    std::vector<std::string>::const_iterator table;
+    RelationalTransaction transaction( m_db->transactionMgr() ); // read-write
+    for ( table = tables.begin(); table != tables.end(); table++ ) {
+      i_grantPrivilege( *priv, *table, user );
+    }
+    transaction.commit();
+  }
+}
+
+//-----------------------------------------------------------------------------
+
+void RalPrivilegeManager::revokeTaggerPrivileges( const std::string& user )
+{
+  bool retag = true; // Revoke retag privileges
+  log() << "Revoke tagger role privileges from user '" << user << "'" 
+        << coral::MessageStream::endmsg;
+  std::vector<Privilege>::const_iterator priv;
+  for ( priv = m_fourPrivs.begin(); priv != m_fourPrivs.end(); priv++ ) {
+    std::vector<std::string> tables( i_listTaggerTables( *priv, retag ) );
+    std::vector<std::string>::const_iterator table;
+    RelationalTransaction transaction( m_db->transactionMgr() ); // read-write
+    for ( table = tables.begin(); table != tables.end(); table++ ) {
+      i_revokePrivilege( *priv, *table, user );
+    }
+    transaction.commit();
+  }
+}
+
+//-----------------------------------------------------------------------------
+
diff --git a/RelationalCool/utilities/coolPrivileges/RalPrivilegeManager.h b/RelationalCool/utilities/coolPrivileges/RalPrivilegeManager.h
new file mode 100644
index 000000000..00e2a3dc2
--- /dev/null
+++ b/RelationalCool/utilities/coolPrivileges/RalPrivilegeManager.h
@@ -0,0 +1,121 @@
+// $Id: RalPrivilegeManager.h,v 1.3 2008-10-29 09:11:31 avalassi Exp $
+#ifndef RELATIONALCOOL_RALPRIVILEGEMANAGER_H 
+#define RELATIONALCOOL_RALPRIVILEGEMANAGER_H 1
+
+// Include files
+#include <memory>
+#include "CoralBase/MessageStream.h"
+#include "RelationalAccess/ITablePrivilegeManager.h"
+
+namespace cool 
+{
+
+  // Forward declarations
+  class RalDatabase;
+
+  /** @class RalPrivilegeManager RalPrivilegeManager.h
+   *  
+   *  Private utility class to grant/revoke table-level object privileges 
+   *  on COOL schema objects to other users in the same server.
+   *
+   *  For the moment, this does not implement any public API: the
+   *  functionality is offered to users only via pre-built executables.
+   *
+   *  This class can only be used with "oracle" database technology.
+   *
+   *  @author Andrea Valassi and Sven A. Schmidt
+   *  @date   2005-07-05
+   */
+
+  class RalPrivilegeManager 
+  {
+    
+    /// Adopt the same Privilege list as RAL (SELECT, UPDATE, INSERT, DELETE)
+    typedef enum { SELECT, INSERT, UPDATE, DELETE } Privilege;
+
+  public:
+    
+    /// Constructor from a RalDatabase pointer
+    RalPrivilegeManager( RalDatabase* db );
+    
+    /// Destructor
+    virtual ~RalPrivilegeManager();    
+    
+    /// Grant privileges to read all data in the COOL database
+    void grantReaderPrivileges( const std::string& user );    
+
+    /// Revoke privileges to read all data in the COOL database
+    void revokeReaderPrivileges( const std::string& user );    
+
+    /// Grant privileges to insert new IOVs into the COOL database
+    /// [NB: reader privileges are also needed and must be granted explicitly]
+    void grantWriterPrivileges( const std::string& user );    
+
+    /// Revoke privileges to insert new IOVs into the COOL database
+    void revokeWriterPrivileges( const std::string& user );    
+
+    /// Grant privileges to tag (optionally retag) IOVs in the COOL database
+    /// [NB: reader privileges are also needed and must be granted explicitly]
+    void grantTaggerPrivileges( const std::string& user,
+                                const bool retag );    
+
+    /// Revoke privileges to tag and/or retag IOVs in the COOL database
+    void revokeTaggerPrivileges( const std::string& user );
+
+  protected:
+    
+    /// Get a CORAL MessageStream
+    coral::MessageStream& log();
+
+    /// List all tables that a READER must be allowed to have privileges on
+    /// [For SELECT privileges these are ALL the tables in the COOL database]
+    std::vector< std::string > i_listReaderTables( const Privilege& priv );
+
+    /// List all tables that a WRITER must be allowed to have privileges on
+    std::vector< std::string > i_listWriterTables( const Privilege& priv );
+
+    /// List all tables that a TAGGER must be allowed to have privileges on
+    std::vector< std::string > i_listTaggerTables( const Privilege& priv,
+                                                   const bool retag );
+
+    /// Get the coral::ITablePrivilegeManager for a given table
+    coral::ITablePrivilegeManager& 
+    i_tablePrivMgr( const std::string& table );
+
+    /// Grant a given privilege on a given table to a given user
+    void i_grantPrivilege( const Privilege& priv,
+                           const std::string& table, 
+                           const std::string& user );
+
+    /// Revoke a given privilege on a given table to a given user
+    void i_revokePrivilege( const Privilege& priv,
+                            const std::string& table, 
+                            const std::string& user );
+
+  private:
+
+    /// Standard constructor is private
+    RalPrivilegeManager(); 
+
+    /// Copy constructor is private
+    RalPrivilegeManager( const RalPrivilegeManager& rhs ); 
+
+    /// Assignment operator is private
+    RalPrivilegeManager& operator=( const RalPrivilegeManager& rhs ); 
+   
+  private:
+
+    /// RalDatabase pointer
+    RalDatabase* m_db;    
+
+    /// CORAL MessageStream
+    std::auto_ptr<coral::MessageStream> m_log;
+
+    /// Vector of four basic privileges
+    std::vector<Privilege> m_fourPrivs;    
+
+  };
+
+}
+
+#endif // RELATIONALCOOL_RALPRIVILEGEMANAGER_H
diff --git a/RelationalCool/utilities/coolPrivileges/coolPrivileges.cpp b/RelationalCool/utilities/coolPrivileges/coolPrivileges.cpp
new file mode 100644
index 000000000..3047bbc78
--- /dev/null
+++ b/RelationalCool/utilities/coolPrivileges/coolPrivileges.cpp
@@ -0,0 +1,156 @@
+// $Id: coolPrivileges.cpp,v 1.10 2008-04-10 08:32:53 avalassi Exp $
+
+// Include files
+#include <iostream>
+#include "CoolKernel/IDatabase.h"
+#include "CoolKernel/IDatabaseSvc.h"
+#include "CoralBase/Exception.h"
+#include "RelationalAccess/IConnectionService.h"
+#include "RelationalAccess/IConnectionServiceConfiguration.h"
+
+// Local include files
+#include "RalPrivilegeManager.h"
+#include "../../src/CoralApplication.h"
+#include "../../src/RalDatabase.h"
+
+// Namespace
+using namespace cool;
+
+// Message output
+#define LOG std::cout
+
+//-----------------------------------------------------------------------------
+
+int main( int argc, char** argv )
+{
+
+  try {
+    
+    // Get the command line arguments
+    bool ok = true;
+    std::string dbId;
+    std::string comm;
+    std::string role;
+    std::string user;
+    if ( argc != 5 )
+      ok = false;
+    else {
+      dbId = argv[1];
+      comm = argv[2];
+      role = argv[3];
+      user = argv[4];
+      if ( comm != "GRANT" && 
+           comm != "REVOKE" ) 
+        ok = false;
+      if ( role != "READER" && 
+           role != "WRITER" && 
+           role != "TAGGER" &&
+           role != "ALL" ) 
+        ok = false;
+    } 
+    if ( !ok ) {
+      LOG << "Usage: " << argv[0] 
+          << " dbId {GRANT|REVOKE} {READER|WRITER|TAGGER|ALL} user" 
+          << std:: endl;
+      std::string dbId = 
+        "oracle://SERVER;schema=USER1;dbname=DB;user=USER1";
+      std::string dbId2 = 
+        "ServerAlias(owner)/DBNAME";
+      LOG << "Example: " << argv[0] << " '" << dbId 
+          << "' GRANT READER USER2" << std::endl;
+      LOG << "Example: " << argv[0] << " '" << dbId2 
+          << "' GRANT READER USER2" << std::endl;
+      return 1;
+    }
+  
+    // Instantiate a COOL Application
+    CoralApplication app;
+    
+    // If we can access a LFC and the user is not explicitely forbidding it,
+    // we try to use CORAL LFCReplicaService
+    if ( ::getenv("COOL_IGNORE_LFC") == NULL &&
+         ::getenv("LFC_HOST") != NULL ) {
+      // try to load CORAL LFCReplicaService
+      coral::IConnectionServiceConfiguration &connSvcConf =
+            app.connectionSvc().configuration();
+      connSvcConf.setAuthenticationService("CORAL/Services/LFCReplicaService");
+      connSvcConf.setLookupService("CORAL/Services/LFCReplicaService");
+    }
+    
+    // Open the database
+    IDatabaseSvc& dbSvc = app.databaseService();
+    IDatabasePtr db = dbSvc.openDatabase( dbId, false ); // open for update
+    RalDatabase* ralDb = dynamic_cast<RalDatabase*>( db.get() );
+    RalPrivilegeManager prMgr( ralDb );
+
+    // Grant/Revoke role to/from user
+    if ( comm == "GRANT" ) {
+      LOG << "GRANT '" << role 
+          << "' privileges to user " << user << std::endl;
+      if ( role == "READER" ) {
+        prMgr.grantReaderPrivileges( user );
+      } else if ( role == "WRITER" ) {
+        prMgr.grantReaderPrivileges( user );
+        prMgr.grantWriterPrivileges( user );
+      } else if ( role == "TAGGER" ) {
+        bool retag = true;
+        prMgr.grantReaderPrivileges( user );
+        prMgr.grantTaggerPrivileges( user, retag );
+      } else if ( role == "ALL" ) {
+        bool retag = true;
+        prMgr.grantReaderPrivileges( user );
+        prMgr.grantWriterPrivileges( user );
+        prMgr.grantTaggerPrivileges( user, retag );
+      } else {
+        LOG << "Unknown privileges '" << role << "'" << std::endl;
+      }
+    }
+    else {
+      LOG << "REVOKE '" << role 
+          << "' privileges from user " << user << std::endl;
+      if ( role == "READER" ) {
+        prMgr.revokeReaderPrivileges( user );
+      } else if ( role == "WRITER" ) {
+        prMgr.revokeWriterPrivileges( user );
+      } else if ( role == "TAGGER" ) {
+        prMgr.revokeTaggerPrivileges( user );
+      } else if ( role == "ALL" ) {
+        prMgr.revokeTaggerPrivileges( user );
+        prMgr.revokeWriterPrivileges( user );
+        prMgr.revokeReaderPrivileges( user );
+      } else {
+        LOG << "Unknown privileges '" << role << "'" << std::endl;
+      }
+    }
+  }
+  
+  catch( cool::Exception& e ) 
+  {
+    LOG << "ERROR! Cool Exception: '" << e.what() << "'" << std::endl;
+    return 1;
+  }
+
+  catch( coral::Exception& e ) 
+  {
+    LOG << "ERROR! Coral Exception: '" << e.what() << "'" << std::endl;
+    return 1;
+  }
+
+  catch( std::exception& e )
+  {
+    LOG << "ERROR! Standard C++ exception: '" << e.what() << "'" << std::endl;
+    return 1;
+  }
+
+  catch( ... ) 
+  {
+    LOG << "ERROR! Unknown exception caught" << std::endl;
+    return 1;
+  }
+
+  // Successful program termination
+  return 0;
+  
+}
+
+//-----------------------------------------------------------------------------
diff --git a/RelationalCool/utilities/coolPrivileges/logs/grantAll-details.txt b/RelationalCool/utilities/coolPrivileges/logs/grantAll-details.txt
new file mode 100644
index 000000000..a7880bbb4
--- /dev/null
+++ b/RelationalCool/utilities/coolPrivileges/logs/grantAll-details.txt
@@ -0,0 +1,91 @@
+* READER privileges
+
+GRANT SELECT ON LCG_COOL.COOLTEST_DB_ATTRIBUTES TO PUBLIC
+GRANT SELECT ON LCG_COOL.COOLTEST_NODES TO PUBLIC
+GRANT SELECT ON LCG_COOL.COOLTEST_NODES_SEQ TO PUBLIC
+GRANT SELECT ON LCG_COOL.COOLTEST_TAGS TO PUBLIC
+GRANT SELECT ON LCG_COOL.COOLTEST_TAG2TAG TO PUBLIC
+GRANT SELECT ON LCG_COOL.COOLTEST_TAG2TAG_SEQ TO PUBLIC
+GRANT SELECT ON LCG_COOL.COOLTEST_TAGS_SEQ TO PUBLIC
+GRANT SELECT ON LCG_COOL.COOLTEST_IOVS_SEQ TO PUBLIC
+GRANT SELECT ON LCG_COOL.COOLTEST_F0010_IOVS TO PUBLIC
+GRANT SELECT ON LCG_COOL.COOLTEST_F0010_IOVS_SEQ TO PUBLIC
+GRANT SELECT ON LCG_COOL.COOLTEST_F0010_CHANNELS TO PUBLIC
+GRANT SELECT ON LCG_COOL.COOLTEST_F0005_TAGS_SEQ TO PUBLIC
+GRANT SELECT ON LCG_COOL.COOLTEST_F0007_IOVS TO PUBLIC
+GRANT SELECT ON LCG_COOL.COOLTEST_F0007_IOVS_SEQ TO PUBLIC
+GRANT SELECT ON LCG_COOL.COOLTEST_F0007_CHANNELS TO PUBLIC
+GRANT SELECT ON LCG_COOL.COOLTEST_F0003_TAGS_SEQ TO PUBLIC
+GRANT SELECT ON LCG_COOL.COOLTEST_F0009_IOVS TO PUBLIC
+GRANT SELECT ON LCG_COOL.COOLTEST_F0009_IOVS_SEQ TO PUBLIC
+GRANT SELECT ON LCG_COOL.COOLTEST_F0009_CHANNELS TO PUBLIC
+GRANT SELECT ON LCG_COOL.COOLTEST_F0009_TAGS TO PUBLIC
+GRANT SELECT ON LCG_COOL.COOLTEST_F0009_TAGS_SEQ TO PUBLIC
+GRANT SELECT ON LCG_COOL.COOLTEST_F0009_IOV2TAG TO PUBLIC
+GRANT SELECT ON LCG_COOL.COOLTEST_F0008_IOVS TO PUBLIC
+GRANT SELECT ON LCG_COOL.COOLTEST_F0008_IOVS_SEQ TO PUBLIC
+GRANT SELECT ON LCG_COOL.COOLTEST_F0008_CHANNELS TO PUBLIC
+GRANT SELECT ON LCG_COOL.COOLTEST_F0008_TAGS TO PUBLIC
+GRANT SELECT ON LCG_COOL.COOLTEST_F0008_TAGS_SEQ TO PUBLIC
+GRANT SELECT ON LCG_COOL.COOLTEST_F0008_IOV2TAG TO PUBLIC
+GRANT SELECT ON LCG_COOL.COOLTEST_F0004_TAGS_SEQ TO PUBLIC
+GRANT SELECT ON LCG_COOL.COOLTEST_F0002_TAGS_SEQ TO PUBLIC
+GRANT SELECT ON LCG_COOL.COOLTEST_F0006_IOVS TO PUBLIC
+GRANT SELECT ON LCG_COOL.COOLTEST_F0006_IOVS_SEQ TO PUBLIC
+GRANT SELECT ON LCG_COOL.COOLTEST_F0006_CHANNELS TO PUBLIC
+GRANT SELECT ON LCG_COOL.COOLTEST_F0001_TAGS_SEQ TO PUBLIC
+GRANT SELECT ON LCG_COOL.COOLTEST_F0000_TAGS_SEQ TO PUBLIC
+
+* WRITER privileges
+
+GRANT INSERT ON LCG_COOL.COOLTEST_F0010_IOVS TO PUBLIC
+GRANT INSERT ON LCG_COOL.COOLTEST_F0010_CHANNELS TO PUBLIC
+GRANT INSERT ON LCG_COOL.COOLTEST_F0007_IOVS TO PUBLIC
+GRANT INSERT ON LCG_COOL.COOLTEST_F0007_CHANNELS TO PUBLIC
+GRANT INSERT ON LCG_COOL.COOLTEST_F0009_IOVS TO PUBLIC
+GRANT INSERT ON LCG_COOL.COOLTEST_F0009_CHANNELS TO PUBLIC
+GRANT INSERT ON LCG_COOL.COOLTEST_F0008_IOVS TO PUBLIC
+GRANT INSERT ON LCG_COOL.COOLTEST_F0008_CHANNELS TO PUBLIC
+GRANT INSERT ON LCG_COOL.COOLTEST_F0006_IOVS TO PUBLIC
+GRANT INSERT ON LCG_COOL.COOLTEST_F0006_CHANNELS TO PUBLIC
+GRANT UPDATE ON LCG_COOL.COOLTEST_IOVS_SEQ TO PUBLIC
+GRANT UPDATE ON LCG_COOL.COOLTEST_F0010_IOVS TO PUBLIC
+GRANT UPDATE ON LCG_COOL.COOLTEST_F0010_IOVS_SEQ TO PUBLIC
+GRANT UPDATE ON LCG_COOL.COOLTEST_F0010_CHANNELS TO PUBLIC
+GRANT UPDATE ON LCG_COOL.COOLTEST_F0007_IOVS TO PUBLIC
+GRANT UPDATE ON LCG_COOL.COOLTEST_F0007_IOVS_SEQ TO PUBLIC
+GRANT UPDATE ON LCG_COOL.COOLTEST_F0007_CHANNELS TO PUBLIC
+GRANT UPDATE ON LCG_COOL.COOLTEST_F0009_IOVS TO PUBLIC
+GRANT UPDATE ON LCG_COOL.COOLTEST_F0009_IOVS_SEQ TO PUBLIC
+GRANT UPDATE ON LCG_COOL.COOLTEST_F0009_CHANNELS TO PUBLIC
+GRANT UPDATE ON LCG_COOL.COOLTEST_F0008_IOVS TO PUBLIC
+GRANT UPDATE ON LCG_COOL.COOLTEST_F0008_IOVS_SEQ TO PUBLIC
+GRANT UPDATE ON LCG_COOL.COOLTEST_F0008_CHANNELS TO PUBLIC
+GRANT UPDATE ON LCG_COOL.COOLTEST_F0006_IOVS TO PUBLIC
+GRANT UPDATE ON LCG_COOL.COOLTEST_F0006_IOVS_SEQ TO PUBLIC
+GRANT UPDATE ON LCG_COOL.COOLTEST_F0006_CHANNELS TO PUBLIC
+
+* TAGGER privileges
+
+GRANT INSERT ON LCG_COOL.COOLTEST_TAGS TO PUBLIC
+GRANT INSERT ON LCG_COOL.COOLTEST_TAG2TAG TO PUBLIC
+GRANT INSERT ON LCG_COOL.COOLTEST_F0009_TAGS TO PUBLIC
+GRANT INSERT ON LCG_COOL.COOLTEST_F0009_IOV2TAG TO PUBLIC
+GRANT INSERT ON LCG_COOL.COOLTEST_F0008_TAGS TO PUBLIC
+GRANT INSERT ON LCG_COOL.COOLTEST_F0008_IOV2TAG TO PUBLIC
+GRANT UPDATE ON LCG_COOL.COOLTEST_TAGS_SEQ TO PUBLIC
+GRANT UPDATE ON LCG_COOL.COOLTEST_TAG2TAG_SEQ TO PUBLIC
+GRANT UPDATE ON LCG_COOL.COOLTEST_F0005_TAGS_SEQ TO PUBLIC
+GRANT UPDATE ON LCG_COOL.COOLTEST_F0003_TAGS_SEQ TO PUBLIC
+GRANT UPDATE ON LCG_COOL.COOLTEST_F0009_TAGS_SEQ TO PUBLIC
+GRANT UPDATE ON LCG_COOL.COOLTEST_F0008_TAGS_SEQ TO PUBLIC
+GRANT UPDATE ON LCG_COOL.COOLTEST_F0004_TAGS_SEQ TO PUBLIC
+GRANT UPDATE ON LCG_COOL.COOLTEST_F0002_TAGS_SEQ TO PUBLIC
+GRANT UPDATE ON LCG_COOL.COOLTEST_F0001_TAGS_SEQ TO PUBLIC
+GRANT UPDATE ON LCG_COOL.COOLTEST_F0000_TAGS_SEQ TO PUBLIC
+GRANT DELETE ON LCG_COOL.COOLTEST_TAGS TO PUBLIC
+GRANT DELETE ON LCG_COOL.COOLTEST_TAG2TAG TO PUBLIC
+GRANT DELETE ON LCG_COOL.COOLTEST_F0009_TAGS TO PUBLIC
+GRANT DELETE ON LCG_COOL.COOLTEST_F0009_IOV2TAG TO PUBLIC
+GRANT DELETE ON LCG_COOL.COOLTEST_F0008_TAGS TO PUBLIC
+GRANT DELETE ON LCG_COOL.COOLTEST_F0008_IOV2TAG TO PUBLIC
diff --git a/RelationalCool/utilities/coolPrivileges/logs/grantAll.txt b/RelationalCool/utilities/coolPrivileges/logs/grantAll.txt
new file mode 100644
index 000000000..10946df27
--- /dev/null
+++ b/RelationalCool/utilities/coolPrivileges/logs/grantAll.txt
@@ -0,0 +1,616 @@
+CoralApplication                     Info     Create a cool::CoralApplication...
+CoralApplication                     Info     Enable the COOL signal handler
+CoralApplication                     Info     Create a new own CORAL connection service
+CoralApplication                     Info     Create the COOL database service
+RalDatabaseSvc                       Info     Instantiate the RalDatabaseSvc
+CoralApplication                     Info     Create a cool::CoralApplication... DONE
+RelationalDatabase                   Debug    Instantiate a RelationalDatabase for 'oracle://lcg_cool_nightly;schema=lcg_cool;dbname=COOLTEST'
+RalSessionMgr                        Info     Instantiate a R/W RalSessionMgr for 'oracle://lcg_cool_nightly;schema=lcg_cool;dbname=COOLTEST'
+RalSessionMgr                        Info     Connect to the database server
+PluginManager                        Info     PluginManager creating CORAL/Services/ConnectionService component
+PluginManager                        Info     PluginMaager needs to load CORAL/Services/ConnectionService component
+PluginManager                        Info     PluginManager loaded ConnectionService library
+CORAL/Services/ConnectionService     Info     Loading default plugin for coral::IRelationalService: CORAL/Services/RelationalService
+PluginManager                        Info     PluginManager creating CORAL/Services/RelationalService component
+PluginManager                        Info     PluginMaager needs to load CORAL/Services/RelationalService component
+PluginManager                        Info     PluginManager loaded RelationalService library
+CORAL/Services/RelationalService     Info     Found plugin for RDBMS technology "coral" with native implementation
+CORAL/Services/RelationalService     Info     Found plugin for RDBMS technology "frontier" with native implementation
+CORAL/Services/RelationalService     Info     Found plugin for RDBMS technology "mysql" with native implementation
+CORAL/Services/RelationalService     Info     Found plugin for RDBMS technology "oracle" with native implementation
+CORAL/Services/RelationalService     Info     Found plugin for RDBMS technology "sqlite" with native implementation
+CORAL/Services/RelationalService     Info     Default implementation for RDBMS technology "coral" is native
+CORAL/Services/RelationalService     Info     Default implementation for RDBMS technology "frontier" is native
+CORAL/Services/RelationalService     Info     Default implementation for RDBMS technology "mysql" is native
+CORAL/Services/RelationalService     Info     Default implementation for RDBMS technology "oracle" is native
+CORAL/Services/RelationalService     Info     Default implementation for RDBMS technology "sqlite" is native
+PluginManager                        Info     PluginManager creating CORAL/RelationalPlugins/oracle component
+PluginManager                        Info     PluginMaager needs to load CORAL/RelationalPlugins/oracle component
+PluginManager                        Info     PluginManager loaded OracleAccess library
+CORAL/Services/ConnectionService     Info     Loading default plugin for coral::IAuthenticationService: CORAL/Services/XMLAuthenticationService
+PluginManager                        Info     PluginManager creating CORAL/Services/XMLAuthenticationService component
+PluginManager                        Info     PluginMaager needs to load CORAL/Services/XMLAuthenticationService component
+PluginManager                        Info     PluginManager loaded XMLAuthenticationService library
+CORAL/Services/XMLAuthenticationS... Info     Authentication using /afs/cern.ch/user/a/avalassi/private/authentication.xml file
+CORAL/Services/ConnectionService     Debug    No valid connection for string "oracle://lcg_cool_nightly/lcg_cool" found in the pool. Creating a new connection.
+CORAL/Services/ConnectionService     Debug    Trying to get a new update session on "oracle://lcg_cool_nightly/lcg_cool"
+CORAL/Services/ConnectionService     Debug    Connection parameters are: Retry-Period=10sec, Retry-Timeout=60sec, Connection-Timeout=0sec.
+CORAL/Services/ConnectionService     Info      Connection to service "lcg_cool_nightly" established. Id=c183a350-8418-11dd-870d-001617c3b642
+CORAL/Services/ConnectionService     Info     New session on connection to service "lcg_cool_nightly" started for user "lcg_cool". Connection Id=c183a350-8418-11dd-870d-001617c3b642
+CORAL/Services/ConnectionService     Debug     A New connection to service "lcg_cool_nightly" has been added in the active list. Id=c183a350-8418-11dd-870d-001617c3b642
+RelationalDatabase                   Info     Instantiate a R/W RalDatabase for 'oracle://lcg_cool_nightly;schema=lcg_cool;dbname=COOLTEST'
+RelationalQueryMgr                   Debug    Instantiate a RelationalQueryMgr
+RelationalQueryMgr                   Debug    Instantiate a RalQueryMgr
+RelationalSequenceMgr                Debug    Instantiate a RelationalSequenceMgr
+RelationalSequenceMgr                Debug    Instantiate a RalSequenceMgr
+RelationalSchemaMgr                  Debug    Instantiate a RelationalSchemaMgr
+RelationalSchemaMgr                  Debug    Instantiate a RalSchemaMgr
+RelationalNodeMgr                    Debug    Instantiate a RelationalNodeMgr
+RelationalTagMgr                     Debug    Instantiate a RelationalTagMgr
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "DB_ATTRIBUTE_NAME", "DB_ATTRIBUTE_VALUE" FROM LCG_COOL."COOLTEST_DB_ATTRIBUTES" "COOLTEST_DB_ATTRIBUTES""
+RelationalQueryMgr                   Debug    Successfully fetched 10 table rows
+RelationalDatabase                   Debug    Release number match: database with CURRENT release number 2.6.0 will be opened using CURRENT client release number 2.6.0
+RalPrivilegeManager                  Debug    Instantiate a RalPrivilegeManager for 'oracle://lcg_cool_nightly;schema=lcg_cool;dbname=COOLTEST'
+GRANT 'ALL' privileges to user PUBLIC
+RelationalNodeMgr                    Debug    Fetch all nodes in the database
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" ORDER BY "NODE_FULLPATH" DESC"
+RelationalQueryMgr                   Debug    Successfully fetched 11 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/UcharSpec/uc
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolder                     Debug    Instantiate a RelationalFolder for '/UcharSpec/uc'
+RelationalFolder                     Debug    Delete the RelationalFolder for '/UcharSpec/uc'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/UcharSpec/uc
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/UcharSpec
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/UcharSpec
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolderSet                  Debug    Instantiate a RelationalFolderSet for '/UcharSpec'
+RelationalFolderSet                  Debug    Delete the RelationalFolderSet for '/UcharSpec'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/SV/sv1
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolder                     Debug    Instantiate a RelationalFolder for '/SimpleSpec/SV/sv1'
+RelationalFolder                     Debug    Delete the RelationalFolder for '/SimpleSpec/SV/sv1'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/SV/sv1
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/SV
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/SV
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolderSet                  Debug    Instantiate a RelationalFolderSet for '/SimpleSpec/SV'
+RelationalFolderSet                  Debug    Delete the RelationalFolderSet for '/SimpleSpec/SV'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/MV/mv2
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolder                     Debug    Instantiate a RelationalFolder for '/SimpleSpec/MV/mv2'
+RelationalFolder                     Debug    Delete the RelationalFolder for '/SimpleSpec/MV/mv2'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/MV/mv2
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/MV/mv1
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolder                     Debug    Instantiate a RelationalFolder for '/SimpleSpec/MV/mv1'
+RelationalFolder                     Debug    Delete the RelationalFolder for '/SimpleSpec/MV/mv1'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/MV/mv1
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/MV
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/MV
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolderSet                  Debug    Instantiate a RelationalFolderSet for '/SimpleSpec/MV'
+RelationalFolderSet                  Debug    Delete the RelationalFolderSet for '/SimpleSpec/MV'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolderSet                  Debug    Instantiate a RelationalFolderSet for '/SimpleSpec'
+RelationalFolderSet                  Debug    Delete the RelationalFolderSet for '/SimpleSpec'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/ReferenceSpec/ref
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolder                     Debug    Instantiate a RelationalFolder for '/ReferenceSpec/ref'
+RelationalFolder                     Debug    Delete the RelationalFolder for '/ReferenceSpec/ref'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/ReferenceSpec/ref
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/ReferenceSpec
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/ReferenceSpec
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolderSet                  Debug    Instantiate a RelationalFolderSet for '/ReferenceSpec'
+RelationalFolderSet                  Debug    Delete the RelationalFolderSet for '/ReferenceSpec'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolderSet                  Debug    Instantiate a RelationalFolderSet for '/'
+RelationalFolderSet                  Debug    Delete the RelationalFolderSet for '/'
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT SELECT ON LCG_COOL."COOLTEST_DB_ATTRIBUTES" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT SELECT ON LCG_COOL."COOLTEST_NODES" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT SELECT ON LCG_COOL."COOLTEST_NODES_SEQ" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT SELECT ON LCG_COOL."COOLTEST_TAGS" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT SELECT ON LCG_COOL."COOLTEST_TAG2TAG" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT SELECT ON LCG_COOL."COOLTEST_TAG2TAG_SEQ" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT SELECT ON LCG_COOL."COOLTEST_TAGS_SEQ" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT SELECT ON LCG_COOL."COOLTEST_IOVS_SEQ" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT SELECT ON LCG_COOL."COOLTEST_F0010_IOVS" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT SELECT ON LCG_COOL."COOLTEST_F0010_IOVS_SEQ" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT SELECT ON LCG_COOL."COOLTEST_F0010_CHANNELS" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT SELECT ON LCG_COOL."COOLTEST_F0005_TAGS_SEQ" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT SELECT ON LCG_COOL."COOLTEST_F0007_IOVS" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT SELECT ON LCG_COOL."COOLTEST_F0007_IOVS_SEQ" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT SELECT ON LCG_COOL."COOLTEST_F0007_CHANNELS" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT SELECT ON LCG_COOL."COOLTEST_F0003_TAGS_SEQ" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT SELECT ON LCG_COOL."COOLTEST_F0009_IOVS" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT SELECT ON LCG_COOL."COOLTEST_F0009_IOVS_SEQ" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT SELECT ON LCG_COOL."COOLTEST_F0009_CHANNELS" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT SELECT ON LCG_COOL."COOLTEST_F0009_TAGS" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT SELECT ON LCG_COOL."COOLTEST_F0009_TAGS_SEQ" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT SELECT ON LCG_COOL."COOLTEST_F0009_IOV2TAG" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT SELECT ON LCG_COOL."COOLTEST_F0008_IOVS" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT SELECT ON LCG_COOL."COOLTEST_F0008_IOVS_SEQ" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT SELECT ON LCG_COOL."COOLTEST_F0008_CHANNELS" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT SELECT ON LCG_COOL."COOLTEST_F0008_TAGS" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT SELECT ON LCG_COOL."COOLTEST_F0008_TAGS_SEQ" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT SELECT ON LCG_COOL."COOLTEST_F0008_IOV2TAG" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT SELECT ON LCG_COOL."COOLTEST_F0004_TAGS_SEQ" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT SELECT ON LCG_COOL."COOLTEST_F0002_TAGS_SEQ" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT SELECT ON LCG_COOL."COOLTEST_F0006_IOVS" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT SELECT ON LCG_COOL."COOLTEST_F0006_IOVS_SEQ" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT SELECT ON LCG_COOL."COOLTEST_F0006_CHANNELS" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT SELECT ON LCG_COOL."COOLTEST_F0001_TAGS_SEQ" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT SELECT ON LCG_COOL."COOLTEST_F0000_TAGS_SEQ" TO PUBLIC"
+RelationalNodeMgr                    Debug    Fetch all nodes in the database
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" ORDER BY "NODE_FULLPATH" DESC"
+RelationalQueryMgr                   Debug    Successfully fetched 11 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/UcharSpec/uc
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolder                     Debug    Instantiate a RelationalFolder for '/UcharSpec/uc'
+RelationalFolder                     Debug    Delete the RelationalFolder for '/UcharSpec/uc'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/UcharSpec
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/SV/sv1
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolder                     Debug    Instantiate a RelationalFolder for '/SimpleSpec/SV/sv1'
+RelationalFolder                     Debug    Delete the RelationalFolder for '/SimpleSpec/SV/sv1'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/SV
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/MV/mv2
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolder                     Debug    Instantiate a RelationalFolder for '/SimpleSpec/MV/mv2'
+RelationalFolder                     Debug    Delete the RelationalFolder for '/SimpleSpec/MV/mv2'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/MV/mv1
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolder                     Debug    Instantiate a RelationalFolder for '/SimpleSpec/MV/mv1'
+RelationalFolder                     Debug    Delete the RelationalFolder for '/SimpleSpec/MV/mv1'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/MV
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/ReferenceSpec/ref
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolder                     Debug    Instantiate a RelationalFolder for '/ReferenceSpec/ref'
+RelationalFolder                     Debug    Delete the RelationalFolder for '/ReferenceSpec/ref'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/ReferenceSpec
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT INSERT ON LCG_COOL."COOLTEST_F0010_IOVS" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT INSERT ON LCG_COOL."COOLTEST_F0010_CHANNELS" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT INSERT ON LCG_COOL."COOLTEST_F0007_IOVS" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT INSERT ON LCG_COOL."COOLTEST_F0007_CHANNELS" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT INSERT ON LCG_COOL."COOLTEST_F0009_IOVS" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT INSERT ON LCG_COOL."COOLTEST_F0009_CHANNELS" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT INSERT ON LCG_COOL."COOLTEST_F0008_IOVS" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT INSERT ON LCG_COOL."COOLTEST_F0008_CHANNELS" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT INSERT ON LCG_COOL."COOLTEST_F0006_IOVS" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT INSERT ON LCG_COOL."COOLTEST_F0006_CHANNELS" TO PUBLIC"
+RelationalNodeMgr                    Debug    Fetch all nodes in the database
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" ORDER BY "NODE_FULLPATH" DESC"
+RelationalQueryMgr                   Debug    Successfully fetched 11 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/UcharSpec/uc
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolder                     Debug    Instantiate a RelationalFolder for '/UcharSpec/uc'
+RelationalFolder                     Debug    Delete the RelationalFolder for '/UcharSpec/uc'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/UcharSpec
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/SV/sv1
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolder                     Debug    Instantiate a RelationalFolder for '/SimpleSpec/SV/sv1'
+RelationalFolder                     Debug    Delete the RelationalFolder for '/SimpleSpec/SV/sv1'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/SV
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/MV/mv2
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolder                     Debug    Instantiate a RelationalFolder for '/SimpleSpec/MV/mv2'
+RelationalFolder                     Debug    Delete the RelationalFolder for '/SimpleSpec/MV/mv2'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/MV/mv1
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolder                     Debug    Instantiate a RelationalFolder for '/SimpleSpec/MV/mv1'
+RelationalFolder                     Debug    Delete the RelationalFolder for '/SimpleSpec/MV/mv1'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/MV
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/ReferenceSpec/ref
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolder                     Debug    Instantiate a RelationalFolder for '/ReferenceSpec/ref'
+RelationalFolder                     Debug    Delete the RelationalFolder for '/ReferenceSpec/ref'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/ReferenceSpec
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT UPDATE ON LCG_COOL."COOLTEST_IOVS_SEQ" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT UPDATE ON LCG_COOL."COOLTEST_F0010_IOVS" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT UPDATE ON LCG_COOL."COOLTEST_F0010_IOVS_SEQ" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT UPDATE ON LCG_COOL."COOLTEST_F0010_CHANNELS" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT UPDATE ON LCG_COOL."COOLTEST_F0007_IOVS" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT UPDATE ON LCG_COOL."COOLTEST_F0007_IOVS_SEQ" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT UPDATE ON LCG_COOL."COOLTEST_F0007_CHANNELS" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT UPDATE ON LCG_COOL."COOLTEST_F0009_IOVS" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT UPDATE ON LCG_COOL."COOLTEST_F0009_IOVS_SEQ" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT UPDATE ON LCG_COOL."COOLTEST_F0009_CHANNELS" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT UPDATE ON LCG_COOL."COOLTEST_F0008_IOVS" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT UPDATE ON LCG_COOL."COOLTEST_F0008_IOVS_SEQ" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT UPDATE ON LCG_COOL."COOLTEST_F0008_CHANNELS" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT UPDATE ON LCG_COOL."COOLTEST_F0006_IOVS" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT UPDATE ON LCG_COOL."COOLTEST_F0006_IOVS_SEQ" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT UPDATE ON LCG_COOL."COOLTEST_F0006_CHANNELS" TO PUBLIC"
+RelationalNodeMgr                    Debug    Fetch all nodes in the database
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" ORDER BY "NODE_FULLPATH" DESC"
+RelationalQueryMgr                   Debug    Successfully fetched 11 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/UcharSpec/uc
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolder                     Debug    Instantiate a RelationalFolder for '/UcharSpec/uc'
+RelationalFolder                     Debug    Delete the RelationalFolder for '/UcharSpec/uc'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/UcharSpec/uc
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/UcharSpec
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/UcharSpec
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolderSet                  Debug    Instantiate a RelationalFolderSet for '/UcharSpec'
+RelationalFolderSet                  Debug    Delete the RelationalFolderSet for '/UcharSpec'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/SV/sv1
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolder                     Debug    Instantiate a RelationalFolder for '/SimpleSpec/SV/sv1'
+RelationalFolder                     Debug    Delete the RelationalFolder for '/SimpleSpec/SV/sv1'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/SV/sv1
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/SV
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/SV
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolderSet                  Debug    Instantiate a RelationalFolderSet for '/SimpleSpec/SV'
+RelationalFolderSet                  Debug    Delete the RelationalFolderSet for '/SimpleSpec/SV'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/MV/mv2
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolder                     Debug    Instantiate a RelationalFolder for '/SimpleSpec/MV/mv2'
+RelationalFolder                     Debug    Delete the RelationalFolder for '/SimpleSpec/MV/mv2'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/MV/mv2
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/MV/mv1
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolder                     Debug    Instantiate a RelationalFolder for '/SimpleSpec/MV/mv1'
+RelationalFolder                     Debug    Delete the RelationalFolder for '/SimpleSpec/MV/mv1'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/MV/mv1
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/MV
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/MV
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolderSet                  Debug    Instantiate a RelationalFolderSet for '/SimpleSpec/MV'
+RelationalFolderSet                  Debug    Delete the RelationalFolderSet for '/SimpleSpec/MV'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolderSet                  Debug    Instantiate a RelationalFolderSet for '/SimpleSpec'
+RelationalFolderSet                  Debug    Delete the RelationalFolderSet for '/SimpleSpec'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/ReferenceSpec/ref
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolder                     Debug    Instantiate a RelationalFolder for '/ReferenceSpec/ref'
+RelationalFolder                     Debug    Delete the RelationalFolder for '/ReferenceSpec/ref'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/ReferenceSpec/ref
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/ReferenceSpec
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/ReferenceSpec
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolderSet                  Debug    Instantiate a RelationalFolderSet for '/ReferenceSpec'
+RelationalFolderSet                  Debug    Delete the RelationalFolderSet for '/ReferenceSpec'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolderSet                  Debug    Instantiate a RelationalFolderSet for '/'
+RelationalFolderSet                  Debug    Delete the RelationalFolderSet for '/'
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT INSERT ON LCG_COOL."COOLTEST_TAGS" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT INSERT ON LCG_COOL."COOLTEST_TAG2TAG" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT INSERT ON LCG_COOL."COOLTEST_F0009_TAGS" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT INSERT ON LCG_COOL."COOLTEST_F0009_IOV2TAG" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT INSERT ON LCG_COOL."COOLTEST_F0008_TAGS" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT INSERT ON LCG_COOL."COOLTEST_F0008_IOV2TAG" TO PUBLIC"
+RelationalNodeMgr                    Debug    Fetch all nodes in the database
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" ORDER BY "NODE_FULLPATH" DESC"
+RelationalQueryMgr                   Debug    Successfully fetched 11 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/UcharSpec/uc
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolder                     Debug    Instantiate a RelationalFolder for '/UcharSpec/uc'
+RelationalFolder                     Debug    Delete the RelationalFolder for '/UcharSpec/uc'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/UcharSpec/uc
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/UcharSpec
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/UcharSpec
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolderSet                  Debug    Instantiate a RelationalFolderSet for '/UcharSpec'
+RelationalFolderSet                  Debug    Delete the RelationalFolderSet for '/UcharSpec'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/SV/sv1
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolder                     Debug    Instantiate a RelationalFolder for '/SimpleSpec/SV/sv1'
+RelationalFolder                     Debug    Delete the RelationalFolder for '/SimpleSpec/SV/sv1'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/SV/sv1
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/SV
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/SV
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolderSet                  Debug    Instantiate a RelationalFolderSet for '/SimpleSpec/SV'
+RelationalFolderSet                  Debug    Delete the RelationalFolderSet for '/SimpleSpec/SV'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/MV/mv2
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolder                     Debug    Instantiate a RelationalFolder for '/SimpleSpec/MV/mv2'
+RelationalFolder                     Debug    Delete the RelationalFolder for '/SimpleSpec/MV/mv2'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/MV/mv2
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/MV/mv1
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolder                     Debug    Instantiate a RelationalFolder for '/SimpleSpec/MV/mv1'
+RelationalFolder                     Debug    Delete the RelationalFolder for '/SimpleSpec/MV/mv1'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/MV/mv1
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/MV
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/MV
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolderSet                  Debug    Instantiate a RelationalFolderSet for '/SimpleSpec/MV'
+RelationalFolderSet                  Debug    Delete the RelationalFolderSet for '/SimpleSpec/MV'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolderSet                  Debug    Instantiate a RelationalFolderSet for '/SimpleSpec'
+RelationalFolderSet                  Debug    Delete the RelationalFolderSet for '/SimpleSpec'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/ReferenceSpec/ref
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolder                     Debug    Instantiate a RelationalFolder for '/ReferenceSpec/ref'
+RelationalFolder                     Debug    Delete the RelationalFolder for '/ReferenceSpec/ref'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/ReferenceSpec/ref
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/ReferenceSpec
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/ReferenceSpec
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolderSet                  Debug    Instantiate a RelationalFolderSet for '/ReferenceSpec'
+RelationalFolderSet                  Debug    Delete the RelationalFolderSet for '/ReferenceSpec'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolderSet                  Debug    Instantiate a RelationalFolderSet for '/'
+RelationalFolderSet                  Debug    Delete the RelationalFolderSet for '/'
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT UPDATE ON LCG_COOL."COOLTEST_TAGS_SEQ" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT UPDATE ON LCG_COOL."COOLTEST_TAG2TAG_SEQ" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT UPDATE ON LCG_COOL."COOLTEST_F0005_TAGS_SEQ" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT UPDATE ON LCG_COOL."COOLTEST_F0003_TAGS_SEQ" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT UPDATE ON LCG_COOL."COOLTEST_F0009_TAGS_SEQ" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT UPDATE ON LCG_COOL."COOLTEST_F0008_TAGS_SEQ" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT UPDATE ON LCG_COOL."COOLTEST_F0004_TAGS_SEQ" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT UPDATE ON LCG_COOL."COOLTEST_F0002_TAGS_SEQ" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT UPDATE ON LCG_COOL."COOLTEST_F0001_TAGS_SEQ" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT UPDATE ON LCG_COOL."COOLTEST_F0000_TAGS_SEQ" TO PUBLIC"
+RelationalNodeMgr                    Debug    Fetch all nodes in the database
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" ORDER BY "NODE_FULLPATH" DESC"
+RelationalQueryMgr                   Debug    Successfully fetched 11 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/UcharSpec/uc
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolder                     Debug    Instantiate a RelationalFolder for '/UcharSpec/uc'
+RelationalFolder                     Debug    Delete the RelationalFolder for '/UcharSpec/uc'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/UcharSpec/uc
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/UcharSpec
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/UcharSpec
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolderSet                  Debug    Instantiate a RelationalFolderSet for '/UcharSpec'
+RelationalFolderSet                  Debug    Delete the RelationalFolderSet for '/UcharSpec'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/SV/sv1
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolder                     Debug    Instantiate a RelationalFolder for '/SimpleSpec/SV/sv1'
+RelationalFolder                     Debug    Delete the RelationalFolder for '/SimpleSpec/SV/sv1'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/SV/sv1
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/SV
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/SV
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolderSet                  Debug    Instantiate a RelationalFolderSet for '/SimpleSpec/SV'
+RelationalFolderSet                  Debug    Delete the RelationalFolderSet for '/SimpleSpec/SV'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/MV/mv2
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolder                     Debug    Instantiate a RelationalFolder for '/SimpleSpec/MV/mv2'
+RelationalFolder                     Debug    Delete the RelationalFolder for '/SimpleSpec/MV/mv2'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/MV/mv2
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/MV/mv1
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolder                     Debug    Instantiate a RelationalFolder for '/SimpleSpec/MV/mv1'
+RelationalFolder                     Debug    Delete the RelationalFolder for '/SimpleSpec/MV/mv1'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/MV/mv1
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/MV
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/MV
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolderSet                  Debug    Instantiate a RelationalFolderSet for '/SimpleSpec/MV'
+RelationalFolderSet                  Debug    Delete the RelationalFolderSet for '/SimpleSpec/MV'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolderSet                  Debug    Instantiate a RelationalFolderSet for '/SimpleSpec'
+RelationalFolderSet                  Debug    Delete the RelationalFolderSet for '/SimpleSpec'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/ReferenceSpec/ref
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolder                     Debug    Instantiate a RelationalFolder for '/ReferenceSpec/ref'
+RelationalFolder                     Debug    Delete the RelationalFolder for '/ReferenceSpec/ref'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/ReferenceSpec/ref
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/ReferenceSpec
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/ReferenceSpec
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolderSet                  Debug    Instantiate a RelationalFolderSet for '/ReferenceSpec'
+RelationalFolderSet                  Debug    Delete the RelationalFolderSet for '/ReferenceSpec'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolderSet                  Debug    Instantiate a RelationalFolderSet for '/'
+RelationalFolderSet                  Debug    Delete the RelationalFolderSet for '/'
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT DELETE ON LCG_COOL."COOLTEST_TAGS" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT DELETE ON LCG_COOL."COOLTEST_TAG2TAG" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT DELETE ON LCG_COOL."COOLTEST_F0009_TAGS" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT DELETE ON LCG_COOL."COOLTEST_F0009_IOV2TAG" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT DELETE ON LCG_COOL."COOLTEST_F0008_TAGS" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT DELETE ON LCG_COOL."COOLTEST_F0008_IOV2TAG" TO PUBLIC"
+RalPrivilegeManager                  Debug    Delete the RalPrivilegeManager for 'oracle://lcg_cool_nightly;schema=lcg_cool;dbname=COOLTEST'
+RelationalDatabase                   Info     Delete the RalDatabase for 'oracle://lcg_cool_nightly;schema=lcg_cool;dbname=COOLTEST'
+RelationalDatabase                   Debug    Delete the RelationalDatabase for 'oracle://lcg_cool_nightly;schema=lcg_cool;dbname=COOLTEST'
+RelationalTagMgr                     Debug    Delete the RelationalTagMgr
+RelationalNodeMgr                    Debug    Delete the RelationalNodeMgr
+RelationalSchemaMgr                  Debug    Delete the RalSchemaMgr
+RelationalSchemaMgr                  Debug    Delete the RelationalSchemaMgr
+RelationalQueryMgr                   Debug    Delete the RalQueryMgr
+RelationalSequenceMgr                Debug    Delete the RalSequenceMgr
+RelationalSequenceMgr                Debug    Delete the RelationalSequenceMgr
+RalSessionMgr                        Info     Delete the RalSessionMgr for 'oracle://lcg_cool_nightly;schema=lcg_cool;dbname=COOLTEST'
+RalSessionMgr                        Info     Disconnect from the database server
+CORAL/Services/ConnectionService     Debug    Connection id=c183a350-8418-11dd-870d-001617c3b642 to service "lcg_cool_nightly" has 0 session(s) opended.
+CORAL/Services/ConnectionService     Debug    The active connection id=c183a350-8418-11dd-870d-001617c3b642 to service "lcg_cool_nightly" has been removed from the active list.
+RelationalQueryMgr                   Debug    Delete the RelationalQueryMgr
+CoralApplication                     Info     Delete the COOL CoralApplication...
+CoralApplication                     Info     Delete the COOL database service
+RalDatabaseSvc                       Info     Delete the RalDatabaseSvc...
+RalDatabaseSvc                       Info     Purge the connection pool
+RalDatabaseSvc                       Info     Reset the ICS pointer
+RalDatabaseSvc                       Info     Delete the RalDatabaseSvc... DONE
+CoralApplication                     Info     Delete the CORAL connection service
+CoralApplication                     Info     Delete the COOL CoralApplication... DONE
diff --git a/RelationalCool/utilities/coolPrivileges/logs/grantReader.txt b/RelationalCool/utilities/coolPrivileges/logs/grantReader.txt
new file mode 100644
index 000000000..6b33cb6f2
--- /dev/null
+++ b/RelationalCool/utilities/coolPrivileges/logs/grantReader.txt
@@ -0,0 +1,203 @@
+CoralApplication                     Info     Create a cool::CoralApplication...
+CoralApplication                     Info     Enable the COOL signal handler
+CoralApplication                     Info     Create a new own CORAL connection service
+CoralApplication                     Info     Create the COOL database service
+RalDatabaseSvc                       Info     Instantiate the RalDatabaseSvc
+CoralApplication                     Info     Create a cool::CoralApplication... DONE
+RelationalDatabase                   Debug    Instantiate a RelationalDatabase for 'oracle://lcg_cool_nightly;schema=lcg_cool;dbname=COOLTEST'
+RalSessionMgr                        Info     Instantiate a R/W RalSessionMgr for 'oracle://lcg_cool_nightly;schema=lcg_cool;dbname=COOLTEST'
+RalSessionMgr                        Info     Connect to the database server
+PluginManager                        Info     PluginManager creating CORAL/Services/ConnectionService component
+PluginManager                        Info     PluginMaager needs to load CORAL/Services/ConnectionService component
+PluginManager                        Info     PluginManager loaded ConnectionService library
+CORAL/Services/ConnectionService     Info     Loading default plugin for coral::IRelationalService: CORAL/Services/RelationalService
+PluginManager                        Info     PluginManager creating CORAL/Services/RelationalService component
+PluginManager                        Info     PluginMaager needs to load CORAL/Services/RelationalService component
+PluginManager                        Info     PluginManager loaded RelationalService library
+CORAL/Services/RelationalService     Info     Found plugin for RDBMS technology "coral" with native implementation
+CORAL/Services/RelationalService     Info     Found plugin for RDBMS technology "frontier" with native implementation
+CORAL/Services/RelationalService     Info     Found plugin for RDBMS technology "mysql" with native implementation
+CORAL/Services/RelationalService     Info     Found plugin for RDBMS technology "oracle" with native implementation
+CORAL/Services/RelationalService     Info     Found plugin for RDBMS technology "sqlite" with native implementation
+CORAL/Services/RelationalService     Info     Default implementation for RDBMS technology "coral" is native
+CORAL/Services/RelationalService     Info     Default implementation for RDBMS technology "frontier" is native
+CORAL/Services/RelationalService     Info     Default implementation for RDBMS technology "mysql" is native
+CORAL/Services/RelationalService     Info     Default implementation for RDBMS technology "oracle" is native
+CORAL/Services/RelationalService     Info     Default implementation for RDBMS technology "sqlite" is native
+PluginManager                        Info     PluginManager creating CORAL/RelationalPlugins/oracle component
+PluginManager                        Info     PluginMaager needs to load CORAL/RelationalPlugins/oracle component
+PluginManager                        Info     PluginManager loaded OracleAccess library
+CORAL/Services/ConnectionService     Info     Loading default plugin for coral::IAuthenticationService: CORAL/Services/XMLAuthenticationService
+PluginManager                        Info     PluginManager creating CORAL/Services/XMLAuthenticationService component
+PluginManager                        Info     PluginMaager needs to load CORAL/Services/XMLAuthenticationService component
+PluginManager                        Info     PluginManager loaded XMLAuthenticationService library
+CORAL/Services/XMLAuthenticationS... Info     Authentication using /afs/cern.ch/user/a/avalassi/private/authentication.xml file
+CORAL/Services/ConnectionService     Debug    No valid connection for string "oracle://lcg_cool_nightly/lcg_cool" found in the pool. Creating a new connection.
+CORAL/Services/ConnectionService     Debug    Trying to get a new update session on "oracle://lcg_cool_nightly/lcg_cool"
+CORAL/Services/ConnectionService     Debug    Connection parameters are: Retry-Period=10sec, Retry-Timeout=60sec, Connection-Timeout=0sec.
+CORAL/Services/ConnectionService     Info      Connection to service "lcg_cool_nightly" established. Id=b1e038fa-8418-11dd-a887-001617c3b642
+CORAL/Services/ConnectionService     Info     New session on connection to service "lcg_cool_nightly" started for user "lcg_cool". Connection Id=b1e038fa-8418-11dd-a887-001617c3b642
+CORAL/Services/ConnectionService     Debug     A New connection to service "lcg_cool_nightly" has been added in the active list. Id=b1e038fa-8418-11dd-a887-001617c3b642
+RelationalDatabase                   Info     Instantiate a R/W RalDatabase for 'oracle://lcg_cool_nightly;schema=lcg_cool;dbname=COOLTEST'
+RelationalQueryMgr                   Debug    Instantiate a RelationalQueryMgr
+RelationalQueryMgr                   Debug    Instantiate a RalQueryMgr
+RelationalSequenceMgr                Debug    Instantiate a RelationalSequenceMgr
+RelationalSequenceMgr                Debug    Instantiate a RalSequenceMgr
+RelationalSchemaMgr                  Debug    Instantiate a RelationalSchemaMgr
+RelationalSchemaMgr                  Debug    Instantiate a RalSchemaMgr
+RelationalNodeMgr                    Debug    Instantiate a RelationalNodeMgr
+RelationalTagMgr                     Debug    Instantiate a RelationalTagMgr
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "DB_ATTRIBUTE_NAME", "DB_ATTRIBUTE_VALUE" FROM LCG_COOL."COOLTEST_DB_ATTRIBUTES" "COOLTEST_DB_ATTRIBUTES""
+RelationalQueryMgr                   Debug    Successfully fetched 10 table rows
+RelationalDatabase                   Debug    Release number match: database with CURRENT release number 2.6.0 will be opened using CURRENT client release number 2.6.0
+RalPrivilegeManager                  Debug    Instantiate a RalPrivilegeManager for 'oracle://lcg_cool_nightly;schema=lcg_cool;dbname=COOLTEST'
+GRANT 'READER' privileges to user PUBLIC
+RelationalNodeMgr                    Debug    Fetch all nodes in the database
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" ORDER BY "NODE_FULLPATH" DESC"
+RelationalQueryMgr                   Debug    Successfully fetched 11 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/UcharSpec/uc
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolder                     Debug    Instantiate a RelationalFolder for '/UcharSpec/uc'
+RelationalFolder                     Debug    Delete the RelationalFolder for '/UcharSpec/uc'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/UcharSpec/uc
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/UcharSpec
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/UcharSpec
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolderSet                  Debug    Instantiate a RelationalFolderSet for '/UcharSpec'
+RelationalFolderSet                  Debug    Delete the RelationalFolderSet for '/UcharSpec'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/SV/sv1
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolder                     Debug    Instantiate a RelationalFolder for '/SimpleSpec/SV/sv1'
+RelationalFolder                     Debug    Delete the RelationalFolder for '/SimpleSpec/SV/sv1'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/SV/sv1
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/SV
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/SV
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolderSet                  Debug    Instantiate a RelationalFolderSet for '/SimpleSpec/SV'
+RelationalFolderSet                  Debug    Delete the RelationalFolderSet for '/SimpleSpec/SV'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/MV/mv2
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolder                     Debug    Instantiate a RelationalFolder for '/SimpleSpec/MV/mv2'
+RelationalFolder                     Debug    Delete the RelationalFolder for '/SimpleSpec/MV/mv2'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/MV/mv2
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/MV/mv1
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolder                     Debug    Instantiate a RelationalFolder for '/SimpleSpec/MV/mv1'
+RelationalFolder                     Debug    Delete the RelationalFolder for '/SimpleSpec/MV/mv1'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/MV/mv1
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/MV
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/MV
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolderSet                  Debug    Instantiate a RelationalFolderSet for '/SimpleSpec/MV'
+RelationalFolderSet                  Debug    Delete the RelationalFolderSet for '/SimpleSpec/MV'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolderSet                  Debug    Instantiate a RelationalFolderSet for '/SimpleSpec'
+RelationalFolderSet                  Debug    Delete the RelationalFolderSet for '/SimpleSpec'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/ReferenceSpec/ref
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolder                     Debug    Instantiate a RelationalFolder for '/ReferenceSpec/ref'
+RelationalFolder                     Debug    Delete the RelationalFolder for '/ReferenceSpec/ref'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/ReferenceSpec/ref
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/ReferenceSpec
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/ReferenceSpec
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolderSet                  Debug    Instantiate a RelationalFolderSet for '/ReferenceSpec'
+RelationalFolderSet                  Debug    Delete the RelationalFolderSet for '/ReferenceSpec'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolderSet                  Debug    Instantiate a RelationalFolderSet for '/'
+RelationalFolderSet                  Debug    Delete the RelationalFolderSet for '/'
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT SELECT ON LCG_COOL."COOLTEST_DB_ATTRIBUTES" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT SELECT ON LCG_COOL."COOLTEST_NODES" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT SELECT ON LCG_COOL."COOLTEST_NODES_SEQ" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT SELECT ON LCG_COOL."COOLTEST_TAGS" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT SELECT ON LCG_COOL."COOLTEST_TAG2TAG" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT SELECT ON LCG_COOL."COOLTEST_TAG2TAG_SEQ" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT SELECT ON LCG_COOL."COOLTEST_TAGS_SEQ" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT SELECT ON LCG_COOL."COOLTEST_IOVS_SEQ" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT SELECT ON LCG_COOL."COOLTEST_F0010_IOVS" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT SELECT ON LCG_COOL."COOLTEST_F0010_IOVS_SEQ" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT SELECT ON LCG_COOL."COOLTEST_F0010_CHANNELS" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT SELECT ON LCG_COOL."COOLTEST_F0005_TAGS_SEQ" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT SELECT ON LCG_COOL."COOLTEST_F0007_IOVS" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT SELECT ON LCG_COOL."COOLTEST_F0007_IOVS_SEQ" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT SELECT ON LCG_COOL."COOLTEST_F0007_CHANNELS" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT SELECT ON LCG_COOL."COOLTEST_F0003_TAGS_SEQ" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT SELECT ON LCG_COOL."COOLTEST_F0009_IOVS" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT SELECT ON LCG_COOL."COOLTEST_F0009_IOVS_SEQ" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT SELECT ON LCG_COOL."COOLTEST_F0009_CHANNELS" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT SELECT ON LCG_COOL."COOLTEST_F0009_TAGS" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT SELECT ON LCG_COOL."COOLTEST_F0009_TAGS_SEQ" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT SELECT ON LCG_COOL."COOLTEST_F0009_IOV2TAG" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT SELECT ON LCG_COOL."COOLTEST_F0008_IOVS" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT SELECT ON LCG_COOL."COOLTEST_F0008_IOVS_SEQ" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT SELECT ON LCG_COOL."COOLTEST_F0008_CHANNELS" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT SELECT ON LCG_COOL."COOLTEST_F0008_TAGS" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT SELECT ON LCG_COOL."COOLTEST_F0008_TAGS_SEQ" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT SELECT ON LCG_COOL."COOLTEST_F0008_IOV2TAG" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT SELECT ON LCG_COOL."COOLTEST_F0004_TAGS_SEQ" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT SELECT ON LCG_COOL."COOLTEST_F0002_TAGS_SEQ" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT SELECT ON LCG_COOL."COOLTEST_F0006_IOVS" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT SELECT ON LCG_COOL."COOLTEST_F0006_IOVS_SEQ" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT SELECT ON LCG_COOL."COOLTEST_F0006_CHANNELS" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT SELECT ON LCG_COOL."COOLTEST_F0001_TAGS_SEQ" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT SELECT ON LCG_COOL."COOLTEST_F0000_TAGS_SEQ" TO PUBLIC"
+RalPrivilegeManager                  Debug    Delete the RalPrivilegeManager for 'oracle://lcg_cool_nightly;schema=lcg_cool;dbname=COOLTEST'
+RelationalDatabase                   Info     Delete the RalDatabase for 'oracle://lcg_cool_nightly;schema=lcg_cool;dbname=COOLTEST'
+RelationalDatabase                   Debug    Delete the RelationalDatabase for 'oracle://lcg_cool_nightly;schema=lcg_cool;dbname=COOLTEST'
+RelationalTagMgr                     Debug    Delete the RelationalTagMgr
+RelationalNodeMgr                    Debug    Delete the RelationalNodeMgr
+RelationalSchemaMgr                  Debug    Delete the RalSchemaMgr
+RelationalSchemaMgr                  Debug    Delete the RelationalSchemaMgr
+RelationalQueryMgr                   Debug    Delete the RalQueryMgr
+RelationalSequenceMgr                Debug    Delete the RalSequenceMgr
+RelationalSequenceMgr                Debug    Delete the RelationalSequenceMgr
+RalSessionMgr                        Info     Delete the RalSessionMgr for 'oracle://lcg_cool_nightly;schema=lcg_cool;dbname=COOLTEST'
+RalSessionMgr                        Info     Disconnect from the database server
+CORAL/Services/ConnectionService     Debug    Connection id=b1e038fa-8418-11dd-a887-001617c3b642 to service "lcg_cool_nightly" has 0 session(s) opended.
+CORAL/Services/ConnectionService     Debug    The active connection id=b1e038fa-8418-11dd-a887-001617c3b642 to service "lcg_cool_nightly" has been removed from the active list.
+RelationalQueryMgr                   Debug    Delete the RelationalQueryMgr
+CoralApplication                     Info     Delete the COOL CoralApplication...
+CoralApplication                     Info     Delete the COOL database service
+RalDatabaseSvc                       Info     Delete the RalDatabaseSvc...
+RalDatabaseSvc                       Info     Purge the connection pool
+RalDatabaseSvc                       Info     Reset the ICS pointer
+RalDatabaseSvc                       Info     Delete the RalDatabaseSvc... DONE
+CoralApplication                     Info     Delete the CORAL connection service
+CoralApplication                     Info     Delete the COOL CoralApplication... DONE
diff --git a/RelationalCool/utilities/coolPrivileges/logs/grantTagger.txt b/RelationalCool/utilities/coolPrivileges/logs/grantTagger.txt
new file mode 100644
index 000000000..fe58d0214
--- /dev/null
+++ b/RelationalCool/utilities/coolPrivileges/logs/grantTagger.txt
@@ -0,0 +1,498 @@
+CoralApplication                     Info     Create a cool::CoralApplication...
+CoralApplication                     Info     Enable the COOL signal handler
+CoralApplication                     Info     Create a new own CORAL connection service
+CoralApplication                     Info     Create the COOL database service
+RalDatabaseSvc                       Info     Instantiate the RalDatabaseSvc
+CoralApplication                     Info     Create a cool::CoralApplication... DONE
+RelationalDatabase                   Debug    Instantiate a RelationalDatabase for 'oracle://lcg_cool_nightly;schema=lcg_cool;dbname=COOLTEST'
+RalSessionMgr                        Info     Instantiate a R/W RalSessionMgr for 'oracle://lcg_cool_nightly;schema=lcg_cool;dbname=COOLTEST'
+RalSessionMgr                        Info     Connect to the database server
+PluginManager                        Info     PluginManager creating CORAL/Services/ConnectionService component
+PluginManager                        Info     PluginMaager needs to load CORAL/Services/ConnectionService component
+PluginManager                        Info     PluginManager loaded ConnectionService library
+CORAL/Services/ConnectionService     Info     Loading default plugin for coral::IRelationalService: CORAL/Services/RelationalService
+PluginManager                        Info     PluginManager creating CORAL/Services/RelationalService component
+PluginManager                        Info     PluginMaager needs to load CORAL/Services/RelationalService component
+PluginManager                        Info     PluginManager loaded RelationalService library
+CORAL/Services/RelationalService     Info     Found plugin for RDBMS technology "coral" with native implementation
+CORAL/Services/RelationalService     Info     Found plugin for RDBMS technology "frontier" with native implementation
+CORAL/Services/RelationalService     Info     Found plugin for RDBMS technology "mysql" with native implementation
+CORAL/Services/RelationalService     Info     Found plugin for RDBMS technology "oracle" with native implementation
+CORAL/Services/RelationalService     Info     Found plugin for RDBMS technology "sqlite" with native implementation
+CORAL/Services/RelationalService     Info     Default implementation for RDBMS technology "coral" is native
+CORAL/Services/RelationalService     Info     Default implementation for RDBMS technology "frontier" is native
+CORAL/Services/RelationalService     Info     Default implementation for RDBMS technology "mysql" is native
+CORAL/Services/RelationalService     Info     Default implementation for RDBMS technology "oracle" is native
+CORAL/Services/RelationalService     Info     Default implementation for RDBMS technology "sqlite" is native
+PluginManager                        Info     PluginManager creating CORAL/RelationalPlugins/oracle component
+PluginManager                        Info     PluginMaager needs to load CORAL/RelationalPlugins/oracle component
+PluginManager                        Info     PluginManager loaded OracleAccess library
+CORAL/Services/ConnectionService     Info     Loading default plugin for coral::IAuthenticationService: CORAL/Services/XMLAuthenticationService
+PluginManager                        Info     PluginManager creating CORAL/Services/XMLAuthenticationService component
+PluginManager                        Info     PluginMaager needs to load CORAL/Services/XMLAuthenticationService component
+PluginManager                        Info     PluginManager loaded XMLAuthenticationService library
+CORAL/Services/XMLAuthenticationS... Info     Authentication using /afs/cern.ch/user/a/avalassi/private/authentication.xml file
+CORAL/Services/ConnectionService     Debug    No valid connection for string "oracle://lcg_cool_nightly/lcg_cool" found in the pool. Creating a new connection.
+CORAL/Services/ConnectionService     Debug    Trying to get a new update session on "oracle://lcg_cool_nightly/lcg_cool"
+CORAL/Services/ConnectionService     Debug    Connection parameters are: Retry-Period=10sec, Retry-Timeout=60sec, Connection-Timeout=0sec.
+CORAL/Services/ConnectionService     Info      Connection to service "lcg_cool_nightly" established. Id=b91266d4-8418-11dd-ba29-001617c3b642
+CORAL/Services/ConnectionService     Info     New session on connection to service "lcg_cool_nightly" started for user "lcg_cool". Connection Id=b91266d4-8418-11dd-ba29-001617c3b642
+CORAL/Services/ConnectionService     Debug     A New connection to service "lcg_cool_nightly" has been added in the active list. Id=b91266d4-8418-11dd-ba29-001617c3b642
+RelationalDatabase                   Info     Instantiate a R/W RalDatabase for 'oracle://lcg_cool_nightly;schema=lcg_cool;dbname=COOLTEST'
+RelationalQueryMgr                   Debug    Instantiate a RelationalQueryMgr
+RelationalQueryMgr                   Debug    Instantiate a RalQueryMgr
+RelationalSequenceMgr                Debug    Instantiate a RelationalSequenceMgr
+RelationalSequenceMgr                Debug    Instantiate a RalSequenceMgr
+RelationalSchemaMgr                  Debug    Instantiate a RelationalSchemaMgr
+RelationalSchemaMgr                  Debug    Instantiate a RalSchemaMgr
+RelationalNodeMgr                    Debug    Instantiate a RelationalNodeMgr
+RelationalTagMgr                     Debug    Instantiate a RelationalTagMgr
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "DB_ATTRIBUTE_NAME", "DB_ATTRIBUTE_VALUE" FROM LCG_COOL."COOLTEST_DB_ATTRIBUTES" "COOLTEST_DB_ATTRIBUTES""
+RelationalQueryMgr                   Debug    Successfully fetched 10 table rows
+RelationalDatabase                   Debug    Release number match: database with CURRENT release number 2.6.0 will be opened using CURRENT client release number 2.6.0
+RalPrivilegeManager                  Debug    Instantiate a RalPrivilegeManager for 'oracle://lcg_cool_nightly;schema=lcg_cool;dbname=COOLTEST'
+GRANT 'TAGGER' privileges to user PUBLIC
+RelationalNodeMgr                    Debug    Fetch all nodes in the database
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" ORDER BY "NODE_FULLPATH" DESC"
+RelationalQueryMgr                   Debug    Successfully fetched 11 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/UcharSpec/uc
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolder                     Debug    Instantiate a RelationalFolder for '/UcharSpec/uc'
+RelationalFolder                     Debug    Delete the RelationalFolder for '/UcharSpec/uc'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/UcharSpec/uc
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/UcharSpec
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/UcharSpec
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolderSet                  Debug    Instantiate a RelationalFolderSet for '/UcharSpec'
+RelationalFolderSet                  Debug    Delete the RelationalFolderSet for '/UcharSpec'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/SV/sv1
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolder                     Debug    Instantiate a RelationalFolder for '/SimpleSpec/SV/sv1'
+RelationalFolder                     Debug    Delete the RelationalFolder for '/SimpleSpec/SV/sv1'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/SV/sv1
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/SV
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/SV
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolderSet                  Debug    Instantiate a RelationalFolderSet for '/SimpleSpec/SV'
+RelationalFolderSet                  Debug    Delete the RelationalFolderSet for '/SimpleSpec/SV'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/MV/mv2
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolder                     Debug    Instantiate a RelationalFolder for '/SimpleSpec/MV/mv2'
+RelationalFolder                     Debug    Delete the RelationalFolder for '/SimpleSpec/MV/mv2'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/MV/mv2
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/MV/mv1
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolder                     Debug    Instantiate a RelationalFolder for '/SimpleSpec/MV/mv1'
+RelationalFolder                     Debug    Delete the RelationalFolder for '/SimpleSpec/MV/mv1'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/MV/mv1
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/MV
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/MV
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolderSet                  Debug    Instantiate a RelationalFolderSet for '/SimpleSpec/MV'
+RelationalFolderSet                  Debug    Delete the RelationalFolderSet for '/SimpleSpec/MV'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolderSet                  Debug    Instantiate a RelationalFolderSet for '/SimpleSpec'
+RelationalFolderSet                  Debug    Delete the RelationalFolderSet for '/SimpleSpec'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/ReferenceSpec/ref
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolder                     Debug    Instantiate a RelationalFolder for '/ReferenceSpec/ref'
+RelationalFolder                     Debug    Delete the RelationalFolder for '/ReferenceSpec/ref'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/ReferenceSpec/ref
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/ReferenceSpec
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/ReferenceSpec
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolderSet                  Debug    Instantiate a RelationalFolderSet for '/ReferenceSpec'
+RelationalFolderSet                  Debug    Delete the RelationalFolderSet for '/ReferenceSpec'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolderSet                  Debug    Instantiate a RelationalFolderSet for '/'
+RelationalFolderSet                  Debug    Delete the RelationalFolderSet for '/'
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT SELECT ON LCG_COOL."COOLTEST_DB_ATTRIBUTES" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT SELECT ON LCG_COOL."COOLTEST_NODES" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT SELECT ON LCG_COOL."COOLTEST_NODES_SEQ" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT SELECT ON LCG_COOL."COOLTEST_TAGS" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT SELECT ON LCG_COOL."COOLTEST_TAG2TAG" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT SELECT ON LCG_COOL."COOLTEST_TAG2TAG_SEQ" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT SELECT ON LCG_COOL."COOLTEST_TAGS_SEQ" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT SELECT ON LCG_COOL."COOLTEST_IOVS_SEQ" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT SELECT ON LCG_COOL."COOLTEST_F0010_IOVS" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT SELECT ON LCG_COOL."COOLTEST_F0010_IOVS_SEQ" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT SELECT ON LCG_COOL."COOLTEST_F0010_CHANNELS" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT SELECT ON LCG_COOL."COOLTEST_F0005_TAGS_SEQ" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT SELECT ON LCG_COOL."COOLTEST_F0007_IOVS" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT SELECT ON LCG_COOL."COOLTEST_F0007_IOVS_SEQ" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT SELECT ON LCG_COOL."COOLTEST_F0007_CHANNELS" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT SELECT ON LCG_COOL."COOLTEST_F0003_TAGS_SEQ" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT SELECT ON LCG_COOL."COOLTEST_F0009_IOVS" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT SELECT ON LCG_COOL."COOLTEST_F0009_IOVS_SEQ" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT SELECT ON LCG_COOL."COOLTEST_F0009_CHANNELS" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT SELECT ON LCG_COOL."COOLTEST_F0009_TAGS" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT SELECT ON LCG_COOL."COOLTEST_F0009_TAGS_SEQ" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT SELECT ON LCG_COOL."COOLTEST_F0009_IOV2TAG" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT SELECT ON LCG_COOL."COOLTEST_F0008_IOVS" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT SELECT ON LCG_COOL."COOLTEST_F0008_IOVS_SEQ" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT SELECT ON LCG_COOL."COOLTEST_F0008_CHANNELS" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT SELECT ON LCG_COOL."COOLTEST_F0008_TAGS" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT SELECT ON LCG_COOL."COOLTEST_F0008_TAGS_SEQ" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT SELECT ON LCG_COOL."COOLTEST_F0008_IOV2TAG" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT SELECT ON LCG_COOL."COOLTEST_F0004_TAGS_SEQ" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT SELECT ON LCG_COOL."COOLTEST_F0002_TAGS_SEQ" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT SELECT ON LCG_COOL."COOLTEST_F0006_IOVS" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT SELECT ON LCG_COOL."COOLTEST_F0006_IOVS_SEQ" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT SELECT ON LCG_COOL."COOLTEST_F0006_CHANNELS" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT SELECT ON LCG_COOL."COOLTEST_F0001_TAGS_SEQ" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT SELECT ON LCG_COOL."COOLTEST_F0000_TAGS_SEQ" TO PUBLIC"
+RelationalNodeMgr                    Debug    Fetch all nodes in the database
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" ORDER BY "NODE_FULLPATH" DESC"
+RelationalQueryMgr                   Debug    Successfully fetched 11 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/UcharSpec/uc
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolder                     Debug    Instantiate a RelationalFolder for '/UcharSpec/uc'
+RelationalFolder                     Debug    Delete the RelationalFolder for '/UcharSpec/uc'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/UcharSpec/uc
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/UcharSpec
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/UcharSpec
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolderSet                  Debug    Instantiate a RelationalFolderSet for '/UcharSpec'
+RelationalFolderSet                  Debug    Delete the RelationalFolderSet for '/UcharSpec'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/SV/sv1
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolder                     Debug    Instantiate a RelationalFolder for '/SimpleSpec/SV/sv1'
+RelationalFolder                     Debug    Delete the RelationalFolder for '/SimpleSpec/SV/sv1'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/SV/sv1
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/SV
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/SV
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolderSet                  Debug    Instantiate a RelationalFolderSet for '/SimpleSpec/SV'
+RelationalFolderSet                  Debug    Delete the RelationalFolderSet for '/SimpleSpec/SV'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/MV/mv2
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolder                     Debug    Instantiate a RelationalFolder for '/SimpleSpec/MV/mv2'
+RelationalFolder                     Debug    Delete the RelationalFolder for '/SimpleSpec/MV/mv2'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/MV/mv2
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/MV/mv1
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolder                     Debug    Instantiate a RelationalFolder for '/SimpleSpec/MV/mv1'
+RelationalFolder                     Debug    Delete the RelationalFolder for '/SimpleSpec/MV/mv1'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/MV/mv1
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/MV
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/MV
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolderSet                  Debug    Instantiate a RelationalFolderSet for '/SimpleSpec/MV'
+RelationalFolderSet                  Debug    Delete the RelationalFolderSet for '/SimpleSpec/MV'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolderSet                  Debug    Instantiate a RelationalFolderSet for '/SimpleSpec'
+RelationalFolderSet                  Debug    Delete the RelationalFolderSet for '/SimpleSpec'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/ReferenceSpec/ref
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolder                     Debug    Instantiate a RelationalFolder for '/ReferenceSpec/ref'
+RelationalFolder                     Debug    Delete the RelationalFolder for '/ReferenceSpec/ref'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/ReferenceSpec/ref
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/ReferenceSpec
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/ReferenceSpec
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolderSet                  Debug    Instantiate a RelationalFolderSet for '/ReferenceSpec'
+RelationalFolderSet                  Debug    Delete the RelationalFolderSet for '/ReferenceSpec'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolderSet                  Debug    Instantiate a RelationalFolderSet for '/'
+RelationalFolderSet                  Debug    Delete the RelationalFolderSet for '/'
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT INSERT ON LCG_COOL."COOLTEST_TAGS" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT INSERT ON LCG_COOL."COOLTEST_TAG2TAG" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT INSERT ON LCG_COOL."COOLTEST_F0009_TAGS" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT INSERT ON LCG_COOL."COOLTEST_F0009_IOV2TAG" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT INSERT ON LCG_COOL."COOLTEST_F0008_TAGS" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT INSERT ON LCG_COOL."COOLTEST_F0008_IOV2TAG" TO PUBLIC"
+RelationalNodeMgr                    Debug    Fetch all nodes in the database
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" ORDER BY "NODE_FULLPATH" DESC"
+RelationalQueryMgr                   Debug    Successfully fetched 11 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/UcharSpec/uc
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolder                     Debug    Instantiate a RelationalFolder for '/UcharSpec/uc'
+RelationalFolder                     Debug    Delete the RelationalFolder for '/UcharSpec/uc'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/UcharSpec/uc
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/UcharSpec
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/UcharSpec
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolderSet                  Debug    Instantiate a RelationalFolderSet for '/UcharSpec'
+RelationalFolderSet                  Debug    Delete the RelationalFolderSet for '/UcharSpec'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/SV/sv1
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolder                     Debug    Instantiate a RelationalFolder for '/SimpleSpec/SV/sv1'
+RelationalFolder                     Debug    Delete the RelationalFolder for '/SimpleSpec/SV/sv1'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/SV/sv1
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/SV
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/SV
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolderSet                  Debug    Instantiate a RelationalFolderSet for '/SimpleSpec/SV'
+RelationalFolderSet                  Debug    Delete the RelationalFolderSet for '/SimpleSpec/SV'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/MV/mv2
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolder                     Debug    Instantiate a RelationalFolder for '/SimpleSpec/MV/mv2'
+RelationalFolder                     Debug    Delete the RelationalFolder for '/SimpleSpec/MV/mv2'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/MV/mv2
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/MV/mv1
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolder                     Debug    Instantiate a RelationalFolder for '/SimpleSpec/MV/mv1'
+RelationalFolder                     Debug    Delete the RelationalFolder for '/SimpleSpec/MV/mv1'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/MV/mv1
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/MV
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/MV
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolderSet                  Debug    Instantiate a RelationalFolderSet for '/SimpleSpec/MV'
+RelationalFolderSet                  Debug    Delete the RelationalFolderSet for '/SimpleSpec/MV'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolderSet                  Debug    Instantiate a RelationalFolderSet for '/SimpleSpec'
+RelationalFolderSet                  Debug    Delete the RelationalFolderSet for '/SimpleSpec'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/ReferenceSpec/ref
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolder                     Debug    Instantiate a RelationalFolder for '/ReferenceSpec/ref'
+RelationalFolder                     Debug    Delete the RelationalFolder for '/ReferenceSpec/ref'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/ReferenceSpec/ref
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/ReferenceSpec
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/ReferenceSpec
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolderSet                  Debug    Instantiate a RelationalFolderSet for '/ReferenceSpec'
+RelationalFolderSet                  Debug    Delete the RelationalFolderSet for '/ReferenceSpec'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolderSet                  Debug    Instantiate a RelationalFolderSet for '/'
+RelationalFolderSet                  Debug    Delete the RelationalFolderSet for '/'
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT UPDATE ON LCG_COOL."COOLTEST_TAGS_SEQ" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT UPDATE ON LCG_COOL."COOLTEST_TAG2TAG_SEQ" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT UPDATE ON LCG_COOL."COOLTEST_F0005_TAGS_SEQ" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT UPDATE ON LCG_COOL."COOLTEST_F0003_TAGS_SEQ" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT UPDATE ON LCG_COOL."COOLTEST_F0009_TAGS_SEQ" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT UPDATE ON LCG_COOL."COOLTEST_F0008_TAGS_SEQ" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT UPDATE ON LCG_COOL."COOLTEST_F0004_TAGS_SEQ" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT UPDATE ON LCG_COOL."COOLTEST_F0002_TAGS_SEQ" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT UPDATE ON LCG_COOL."COOLTEST_F0001_TAGS_SEQ" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT UPDATE ON LCG_COOL."COOLTEST_F0000_TAGS_SEQ" TO PUBLIC"
+RelationalNodeMgr                    Debug    Fetch all nodes in the database
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" ORDER BY "NODE_FULLPATH" DESC"
+RelationalQueryMgr                   Debug    Successfully fetched 11 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/UcharSpec/uc
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolder                     Debug    Instantiate a RelationalFolder for '/UcharSpec/uc'
+RelationalFolder                     Debug    Delete the RelationalFolder for '/UcharSpec/uc'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/UcharSpec/uc
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/UcharSpec
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/UcharSpec
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolderSet                  Debug    Instantiate a RelationalFolderSet for '/UcharSpec'
+RelationalFolderSet                  Debug    Delete the RelationalFolderSet for '/UcharSpec'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/SV/sv1
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolder                     Debug    Instantiate a RelationalFolder for '/SimpleSpec/SV/sv1'
+RelationalFolder                     Debug    Delete the RelationalFolder for '/SimpleSpec/SV/sv1'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/SV/sv1
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/SV
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/SV
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolderSet                  Debug    Instantiate a RelationalFolderSet for '/SimpleSpec/SV'
+RelationalFolderSet                  Debug    Delete the RelationalFolderSet for '/SimpleSpec/SV'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/MV/mv2
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolder                     Debug    Instantiate a RelationalFolder for '/SimpleSpec/MV/mv2'
+RelationalFolder                     Debug    Delete the RelationalFolder for '/SimpleSpec/MV/mv2'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/MV/mv2
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/MV/mv1
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolder                     Debug    Instantiate a RelationalFolder for '/SimpleSpec/MV/mv1'
+RelationalFolder                     Debug    Delete the RelationalFolder for '/SimpleSpec/MV/mv1'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/MV/mv1
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/MV
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/MV
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolderSet                  Debug    Instantiate a RelationalFolderSet for '/SimpleSpec/MV'
+RelationalFolderSet                  Debug    Delete the RelationalFolderSet for '/SimpleSpec/MV'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolderSet                  Debug    Instantiate a RelationalFolderSet for '/SimpleSpec'
+RelationalFolderSet                  Debug    Delete the RelationalFolderSet for '/SimpleSpec'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/ReferenceSpec/ref
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolder                     Debug    Instantiate a RelationalFolder for '/ReferenceSpec/ref'
+RelationalFolder                     Debug    Delete the RelationalFolder for '/ReferenceSpec/ref'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/ReferenceSpec/ref
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/ReferenceSpec
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/ReferenceSpec
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolderSet                  Debug    Instantiate a RelationalFolderSet for '/ReferenceSpec'
+RelationalFolderSet                  Debug    Delete the RelationalFolderSet for '/ReferenceSpec'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolderSet                  Debug    Instantiate a RelationalFolderSet for '/'
+RelationalFolderSet                  Debug    Delete the RelationalFolderSet for '/'
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT DELETE ON LCG_COOL."COOLTEST_TAGS" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT DELETE ON LCG_COOL."COOLTEST_TAG2TAG" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT DELETE ON LCG_COOL."COOLTEST_F0009_TAGS" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT DELETE ON LCG_COOL."COOLTEST_F0009_IOV2TAG" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT DELETE ON LCG_COOL."COOLTEST_F0008_TAGS" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT DELETE ON LCG_COOL."COOLTEST_F0008_IOV2TAG" TO PUBLIC"
+RalPrivilegeManager                  Debug    Delete the RalPrivilegeManager for 'oracle://lcg_cool_nightly;schema=lcg_cool;dbname=COOLTEST'
+RelationalDatabase                   Info     Delete the RalDatabase for 'oracle://lcg_cool_nightly;schema=lcg_cool;dbname=COOLTEST'
+RelationalDatabase                   Debug    Delete the RelationalDatabase for 'oracle://lcg_cool_nightly;schema=lcg_cool;dbname=COOLTEST'
+RelationalTagMgr                     Debug    Delete the RelationalTagMgr
+RelationalNodeMgr                    Debug    Delete the RelationalNodeMgr
+RelationalSchemaMgr                  Debug    Delete the RalSchemaMgr
+RelationalSchemaMgr                  Debug    Delete the RelationalSchemaMgr
+RelationalQueryMgr                   Debug    Delete the RalQueryMgr
+RelationalSequenceMgr                Debug    Delete the RalSequenceMgr
+RelationalSequenceMgr                Debug    Delete the RelationalSequenceMgr
+RalSessionMgr                        Info     Delete the RalSessionMgr for 'oracle://lcg_cool_nightly;schema=lcg_cool;dbname=COOLTEST'
+RalSessionMgr                        Info     Disconnect from the database server
+CORAL/Services/ConnectionService     Debug    Connection id=b91266d4-8418-11dd-ba29-001617c3b642 to service "lcg_cool_nightly" has 0 session(s) opended.
+CORAL/Services/ConnectionService     Debug    The active connection id=b91266d4-8418-11dd-ba29-001617c3b642 to service "lcg_cool_nightly" has been removed from the active list.
+RelationalQueryMgr                   Debug    Delete the RelationalQueryMgr
+CoralApplication                     Info     Delete the COOL CoralApplication...
+CoralApplication                     Info     Delete the COOL database service
+RalDatabaseSvc                       Info     Delete the RalDatabaseSvc...
+RalDatabaseSvc                       Info     Purge the connection pool
+RalDatabaseSvc                       Info     Reset the ICS pointer
+RalDatabaseSvc                       Info     Delete the RalDatabaseSvc... DONE
+CoralApplication                     Info     Delete the CORAL connection service
+CoralApplication                     Info     Delete the COOL CoralApplication... DONE
diff --git a/RelationalCool/utilities/coolPrivileges/logs/grantWriter.txt b/RelationalCool/utilities/coolPrivileges/logs/grantWriter.txt
new file mode 100644
index 000000000..8d7527b79
--- /dev/null
+++ b/RelationalCool/utilities/coolPrivileges/logs/grantWriter.txt
@@ -0,0 +1,321 @@
+CoralApplication                     Info     Create a cool::CoralApplication...
+CoralApplication                     Info     Enable the COOL signal handler
+CoralApplication                     Info     Create a new own CORAL connection service
+CoralApplication                     Info     Create the COOL database service
+RalDatabaseSvc                       Info     Instantiate the RalDatabaseSvc
+CoralApplication                     Info     Create a cool::CoralApplication... DONE
+RelationalDatabase                   Debug    Instantiate a RelationalDatabase for 'oracle://lcg_cool_nightly;schema=lcg_cool;dbname=COOLTEST'
+RalSessionMgr                        Info     Instantiate a R/W RalSessionMgr for 'oracle://lcg_cool_nightly;schema=lcg_cool;dbname=COOLTEST'
+RalSessionMgr                        Info     Connect to the database server
+PluginManager                        Info     PluginManager creating CORAL/Services/ConnectionService component
+PluginManager                        Info     PluginMaager needs to load CORAL/Services/ConnectionService component
+PluginManager                        Info     PluginManager loaded ConnectionService library
+CORAL/Services/ConnectionService     Info     Loading default plugin for coral::IRelationalService: CORAL/Services/RelationalService
+PluginManager                        Info     PluginManager creating CORAL/Services/RelationalService component
+PluginManager                        Info     PluginMaager needs to load CORAL/Services/RelationalService component
+PluginManager                        Info     PluginManager loaded RelationalService library
+CORAL/Services/RelationalService     Info     Found plugin for RDBMS technology "coral" with native implementation
+CORAL/Services/RelationalService     Info     Found plugin for RDBMS technology "frontier" with native implementation
+CORAL/Services/RelationalService     Info     Found plugin for RDBMS technology "mysql" with native implementation
+CORAL/Services/RelationalService     Info     Found plugin for RDBMS technology "oracle" with native implementation
+CORAL/Services/RelationalService     Info     Found plugin for RDBMS technology "sqlite" with native implementation
+CORAL/Services/RelationalService     Info     Default implementation for RDBMS technology "coral" is native
+CORAL/Services/RelationalService     Info     Default implementation for RDBMS technology "frontier" is native
+CORAL/Services/RelationalService     Info     Default implementation for RDBMS technology "mysql" is native
+CORAL/Services/RelationalService     Info     Default implementation for RDBMS technology "oracle" is native
+CORAL/Services/RelationalService     Info     Default implementation for RDBMS technology "sqlite" is native
+PluginManager                        Info     PluginManager creating CORAL/RelationalPlugins/oracle component
+PluginManager                        Info     PluginMaager needs to load CORAL/RelationalPlugins/oracle component
+PluginManager                        Info     PluginManager loaded OracleAccess library
+CORAL/Services/ConnectionService     Info     Loading default plugin for coral::IAuthenticationService: CORAL/Services/XMLAuthenticationService
+PluginManager                        Info     PluginManager creating CORAL/Services/XMLAuthenticationService component
+PluginManager                        Info     PluginMaager needs to load CORAL/Services/XMLAuthenticationService component
+PluginManager                        Info     PluginManager loaded XMLAuthenticationService library
+CORAL/Services/XMLAuthenticationS... Info     Authentication using /afs/cern.ch/user/a/avalassi/private/authentication.xml file
+CORAL/Services/ConnectionService     Debug    No valid connection for string "oracle://lcg_cool_nightly/lcg_cool" found in the pool. Creating a new connection.
+CORAL/Services/ConnectionService     Debug    Trying to get a new update session on "oracle://lcg_cool_nightly/lcg_cool"
+CORAL/Services/ConnectionService     Debug    Connection parameters are: Retry-Period=10sec, Retry-Timeout=60sec, Connection-Timeout=0sec.
+CORAL/Services/ConnectionService     Info      Connection to service "lcg_cool_nightly" established. Id=b49e1daa-8418-11dd-b331-001617c3b642
+CORAL/Services/ConnectionService     Info     New session on connection to service "lcg_cool_nightly" started for user "lcg_cool". Connection Id=b49e1daa-8418-11dd-b331-001617c3b642
+CORAL/Services/ConnectionService     Debug     A New connection to service "lcg_cool_nightly" has been added in the active list. Id=b49e1daa-8418-11dd-b331-001617c3b642
+RelationalDatabase                   Info     Instantiate a R/W RalDatabase for 'oracle://lcg_cool_nightly;schema=lcg_cool;dbname=COOLTEST'
+RelationalQueryMgr                   Debug    Instantiate a RelationalQueryMgr
+RelationalQueryMgr                   Debug    Instantiate a RalQueryMgr
+RelationalSequenceMgr                Debug    Instantiate a RelationalSequenceMgr
+RelationalSequenceMgr                Debug    Instantiate a RalSequenceMgr
+RelationalSchemaMgr                  Debug    Instantiate a RelationalSchemaMgr
+RelationalSchemaMgr                  Debug    Instantiate a RalSchemaMgr
+RelationalNodeMgr                    Debug    Instantiate a RelationalNodeMgr
+RelationalTagMgr                     Debug    Instantiate a RelationalTagMgr
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "DB_ATTRIBUTE_NAME", "DB_ATTRIBUTE_VALUE" FROM LCG_COOL."COOLTEST_DB_ATTRIBUTES" "COOLTEST_DB_ATTRIBUTES""
+RelationalQueryMgr                   Debug    Successfully fetched 10 table rows
+RelationalDatabase                   Debug    Release number match: database with CURRENT release number 2.6.0 will be opened using CURRENT client release number 2.6.0
+RalPrivilegeManager                  Debug    Instantiate a RalPrivilegeManager for 'oracle://lcg_cool_nightly;schema=lcg_cool;dbname=COOLTEST'
+GRANT 'WRITER' privileges to user PUBLIC
+RelationalNodeMgr                    Debug    Fetch all nodes in the database
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" ORDER BY "NODE_FULLPATH" DESC"
+RelationalQueryMgr                   Debug    Successfully fetched 11 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/UcharSpec/uc
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolder                     Debug    Instantiate a RelationalFolder for '/UcharSpec/uc'
+RelationalFolder                     Debug    Delete the RelationalFolder for '/UcharSpec/uc'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/UcharSpec/uc
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/UcharSpec
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/UcharSpec
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolderSet                  Debug    Instantiate a RelationalFolderSet for '/UcharSpec'
+RelationalFolderSet                  Debug    Delete the RelationalFolderSet for '/UcharSpec'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/SV/sv1
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolder                     Debug    Instantiate a RelationalFolder for '/SimpleSpec/SV/sv1'
+RelationalFolder                     Debug    Delete the RelationalFolder for '/SimpleSpec/SV/sv1'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/SV/sv1
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/SV
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/SV
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolderSet                  Debug    Instantiate a RelationalFolderSet for '/SimpleSpec/SV'
+RelationalFolderSet                  Debug    Delete the RelationalFolderSet for '/SimpleSpec/SV'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/MV/mv2
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolder                     Debug    Instantiate a RelationalFolder for '/SimpleSpec/MV/mv2'
+RelationalFolder                     Debug    Delete the RelationalFolder for '/SimpleSpec/MV/mv2'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/MV/mv2
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/MV/mv1
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolder                     Debug    Instantiate a RelationalFolder for '/SimpleSpec/MV/mv1'
+RelationalFolder                     Debug    Delete the RelationalFolder for '/SimpleSpec/MV/mv1'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/MV/mv1
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/MV
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/MV
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolderSet                  Debug    Instantiate a RelationalFolderSet for '/SimpleSpec/MV'
+RelationalFolderSet                  Debug    Delete the RelationalFolderSet for '/SimpleSpec/MV'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolderSet                  Debug    Instantiate a RelationalFolderSet for '/SimpleSpec'
+RelationalFolderSet                  Debug    Delete the RelationalFolderSet for '/SimpleSpec'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/ReferenceSpec/ref
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolder                     Debug    Instantiate a RelationalFolder for '/ReferenceSpec/ref'
+RelationalFolder                     Debug    Delete the RelationalFolder for '/ReferenceSpec/ref'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/ReferenceSpec/ref
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/ReferenceSpec
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/ReferenceSpec
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolderSet                  Debug    Instantiate a RelationalFolderSet for '/ReferenceSpec'
+RelationalFolderSet                  Debug    Delete the RelationalFolderSet for '/ReferenceSpec'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolderSet                  Debug    Instantiate a RelationalFolderSet for '/'
+RelationalFolderSet                  Debug    Delete the RelationalFolderSet for '/'
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT SELECT ON LCG_COOL."COOLTEST_DB_ATTRIBUTES" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT SELECT ON LCG_COOL."COOLTEST_NODES" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT SELECT ON LCG_COOL."COOLTEST_NODES_SEQ" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT SELECT ON LCG_COOL."COOLTEST_TAGS" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT SELECT ON LCG_COOL."COOLTEST_TAG2TAG" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT SELECT ON LCG_COOL."COOLTEST_TAG2TAG_SEQ" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT SELECT ON LCG_COOL."COOLTEST_TAGS_SEQ" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT SELECT ON LCG_COOL."COOLTEST_IOVS_SEQ" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT SELECT ON LCG_COOL."COOLTEST_F0010_IOVS" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT SELECT ON LCG_COOL."COOLTEST_F0010_IOVS_SEQ" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT SELECT ON LCG_COOL."COOLTEST_F0010_CHANNELS" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT SELECT ON LCG_COOL."COOLTEST_F0005_TAGS_SEQ" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT SELECT ON LCG_COOL."COOLTEST_F0007_IOVS" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT SELECT ON LCG_COOL."COOLTEST_F0007_IOVS_SEQ" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT SELECT ON LCG_COOL."COOLTEST_F0007_CHANNELS" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT SELECT ON LCG_COOL."COOLTEST_F0003_TAGS_SEQ" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT SELECT ON LCG_COOL."COOLTEST_F0009_IOVS" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT SELECT ON LCG_COOL."COOLTEST_F0009_IOVS_SEQ" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT SELECT ON LCG_COOL."COOLTEST_F0009_CHANNELS" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT SELECT ON LCG_COOL."COOLTEST_F0009_TAGS" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT SELECT ON LCG_COOL."COOLTEST_F0009_TAGS_SEQ" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT SELECT ON LCG_COOL."COOLTEST_F0009_IOV2TAG" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT SELECT ON LCG_COOL."COOLTEST_F0008_IOVS" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT SELECT ON LCG_COOL."COOLTEST_F0008_IOVS_SEQ" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT SELECT ON LCG_COOL."COOLTEST_F0008_CHANNELS" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT SELECT ON LCG_COOL."COOLTEST_F0008_TAGS" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT SELECT ON LCG_COOL."COOLTEST_F0008_TAGS_SEQ" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT SELECT ON LCG_COOL."COOLTEST_F0008_IOV2TAG" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT SELECT ON LCG_COOL."COOLTEST_F0004_TAGS_SEQ" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT SELECT ON LCG_COOL."COOLTEST_F0002_TAGS_SEQ" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT SELECT ON LCG_COOL."COOLTEST_F0006_IOVS" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT SELECT ON LCG_COOL."COOLTEST_F0006_IOVS_SEQ" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT SELECT ON LCG_COOL."COOLTEST_F0006_CHANNELS" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT SELECT ON LCG_COOL."COOLTEST_F0001_TAGS_SEQ" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT SELECT ON LCG_COOL."COOLTEST_F0000_TAGS_SEQ" TO PUBLIC"
+RelationalNodeMgr                    Debug    Fetch all nodes in the database
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" ORDER BY "NODE_FULLPATH" DESC"
+RelationalQueryMgr                   Debug    Successfully fetched 11 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/UcharSpec/uc
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolder                     Debug    Instantiate a RelationalFolder for '/UcharSpec/uc'
+RelationalFolder                     Debug    Delete the RelationalFolder for '/UcharSpec/uc'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/UcharSpec
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/SV/sv1
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolder                     Debug    Instantiate a RelationalFolder for '/SimpleSpec/SV/sv1'
+RelationalFolder                     Debug    Delete the RelationalFolder for '/SimpleSpec/SV/sv1'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/SV
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/MV/mv2
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolder                     Debug    Instantiate a RelationalFolder for '/SimpleSpec/MV/mv2'
+RelationalFolder                     Debug    Delete the RelationalFolder for '/SimpleSpec/MV/mv2'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/MV/mv1
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolder                     Debug    Instantiate a RelationalFolder for '/SimpleSpec/MV/mv1'
+RelationalFolder                     Debug    Delete the RelationalFolder for '/SimpleSpec/MV/mv1'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/MV
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/ReferenceSpec/ref
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolder                     Debug    Instantiate a RelationalFolder for '/ReferenceSpec/ref'
+RelationalFolder                     Debug    Delete the RelationalFolder for '/ReferenceSpec/ref'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/ReferenceSpec
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT INSERT ON LCG_COOL."COOLTEST_F0010_IOVS" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT INSERT ON LCG_COOL."COOLTEST_F0010_CHANNELS" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT INSERT ON LCG_COOL."COOLTEST_F0007_IOVS" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT INSERT ON LCG_COOL."COOLTEST_F0007_CHANNELS" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT INSERT ON LCG_COOL."COOLTEST_F0009_IOVS" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT INSERT ON LCG_COOL."COOLTEST_F0009_CHANNELS" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT INSERT ON LCG_COOL."COOLTEST_F0008_IOVS" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT INSERT ON LCG_COOL."COOLTEST_F0008_CHANNELS" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT INSERT ON LCG_COOL."COOLTEST_F0006_IOVS" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT INSERT ON LCG_COOL."COOLTEST_F0006_CHANNELS" TO PUBLIC"
+RelationalNodeMgr                    Debug    Fetch all nodes in the database
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" ORDER BY "NODE_FULLPATH" DESC"
+RelationalQueryMgr                   Debug    Successfully fetched 11 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/UcharSpec/uc
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolder                     Debug    Instantiate a RelationalFolder for '/UcharSpec/uc'
+RelationalFolder                     Debug    Delete the RelationalFolder for '/UcharSpec/uc'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/UcharSpec
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/SV/sv1
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolder                     Debug    Instantiate a RelationalFolder for '/SimpleSpec/SV/sv1'
+RelationalFolder                     Debug    Delete the RelationalFolder for '/SimpleSpec/SV/sv1'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/SV
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/MV/mv2
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolder                     Debug    Instantiate a RelationalFolder for '/SimpleSpec/MV/mv2'
+RelationalFolder                     Debug    Delete the RelationalFolder for '/SimpleSpec/MV/mv2'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/MV/mv1
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolder                     Debug    Instantiate a RelationalFolder for '/SimpleSpec/MV/mv1'
+RelationalFolder                     Debug    Delete the RelationalFolder for '/SimpleSpec/MV/mv1'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/MV
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/ReferenceSpec/ref
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolder                     Debug    Instantiate a RelationalFolder for '/ReferenceSpec/ref'
+RelationalFolder                     Debug    Delete the RelationalFolder for '/ReferenceSpec/ref'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/ReferenceSpec
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT UPDATE ON LCG_COOL."COOLTEST_IOVS_SEQ" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT UPDATE ON LCG_COOL."COOLTEST_F0010_IOVS" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT UPDATE ON LCG_COOL."COOLTEST_F0010_IOVS_SEQ" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT UPDATE ON LCG_COOL."COOLTEST_F0010_CHANNELS" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT UPDATE ON LCG_COOL."COOLTEST_F0007_IOVS" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT UPDATE ON LCG_COOL."COOLTEST_F0007_IOVS_SEQ" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT UPDATE ON LCG_COOL."COOLTEST_F0007_CHANNELS" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT UPDATE ON LCG_COOL."COOLTEST_F0009_IOVS" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT UPDATE ON LCG_COOL."COOLTEST_F0009_IOVS_SEQ" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT UPDATE ON LCG_COOL."COOLTEST_F0009_CHANNELS" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT UPDATE ON LCG_COOL."COOLTEST_F0008_IOVS" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT UPDATE ON LCG_COOL."COOLTEST_F0008_IOVS_SEQ" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT UPDATE ON LCG_COOL."COOLTEST_F0008_CHANNELS" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT UPDATE ON LCG_COOL."COOLTEST_F0006_IOVS" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT UPDATE ON LCG_COOL."COOLTEST_F0006_IOVS_SEQ" TO PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "GRANT UPDATE ON LCG_COOL."COOLTEST_F0006_CHANNELS" TO PUBLIC"
+RalPrivilegeManager                  Debug    Delete the RalPrivilegeManager for 'oracle://lcg_cool_nightly;schema=lcg_cool;dbname=COOLTEST'
+RelationalDatabase                   Info     Delete the RalDatabase for 'oracle://lcg_cool_nightly;schema=lcg_cool;dbname=COOLTEST'
+RelationalDatabase                   Debug    Delete the RelationalDatabase for 'oracle://lcg_cool_nightly;schema=lcg_cool;dbname=COOLTEST'
+RelationalTagMgr                     Debug    Delete the RelationalTagMgr
+RelationalNodeMgr                    Debug    Delete the RelationalNodeMgr
+RelationalSchemaMgr                  Debug    Delete the RalSchemaMgr
+RelationalSchemaMgr                  Debug    Delete the RelationalSchemaMgr
+RelationalQueryMgr                   Debug    Delete the RalQueryMgr
+RelationalSequenceMgr                Debug    Delete the RalSequenceMgr
+RelationalSequenceMgr                Debug    Delete the RelationalSequenceMgr
+RalSessionMgr                        Info     Delete the RalSessionMgr for 'oracle://lcg_cool_nightly;schema=lcg_cool;dbname=COOLTEST'
+RalSessionMgr                        Info     Disconnect from the database server
+CORAL/Services/ConnectionService     Debug    Connection id=b49e1daa-8418-11dd-b331-001617c3b642 to service "lcg_cool_nightly" has 0 session(s) opended.
+CORAL/Services/ConnectionService     Debug    The active connection id=b49e1daa-8418-11dd-b331-001617c3b642 to service "lcg_cool_nightly" has been removed from the active list.
+RelationalQueryMgr                   Debug    Delete the RelationalQueryMgr
+CoralApplication                     Info     Delete the COOL CoralApplication...
+CoralApplication                     Info     Delete the COOL database service
+RalDatabaseSvc                       Info     Delete the RalDatabaseSvc...
+RalDatabaseSvc                       Info     Purge the connection pool
+RalDatabaseSvc                       Info     Reset the ICS pointer
+RalDatabaseSvc                       Info     Delete the RalDatabaseSvc... DONE
+CoralApplication                     Info     Delete the CORAL connection service
+CoralApplication                     Info     Delete the COOL CoralApplication... DONE
diff --git a/RelationalCool/utilities/coolPrivileges/logs/revokeAll.txt b/RelationalCool/utilities/coolPrivileges/logs/revokeAll.txt
new file mode 100644
index 000000000..1373d4c06
--- /dev/null
+++ b/RelationalCool/utilities/coolPrivileges/logs/revokeAll.txt
@@ -0,0 +1,616 @@
+CoralApplication                     Info     Create a cool::CoralApplication...
+CoralApplication                     Info     Enable the COOL signal handler
+CoralApplication                     Info     Create a new own CORAL connection service
+CoralApplication                     Info     Create the COOL database service
+RalDatabaseSvc                       Info     Instantiate the RalDatabaseSvc
+CoralApplication                     Info     Create a cool::CoralApplication... DONE
+RelationalDatabase                   Debug    Instantiate a RelationalDatabase for 'oracle://lcg_cool_nightly;schema=lcg_cool;dbname=COOLTEST'
+RalSessionMgr                        Info     Instantiate a R/W RalSessionMgr for 'oracle://lcg_cool_nightly;schema=lcg_cool;dbname=COOLTEST'
+RalSessionMgr                        Info     Connect to the database server
+PluginManager                        Info     PluginManager creating CORAL/Services/ConnectionService component
+PluginManager                        Info     PluginMaager needs to load CORAL/Services/ConnectionService component
+PluginManager                        Info     PluginManager loaded ConnectionService library
+CORAL/Services/ConnectionService     Info     Loading default plugin for coral::IRelationalService: CORAL/Services/RelationalService
+PluginManager                        Info     PluginManager creating CORAL/Services/RelationalService component
+PluginManager                        Info     PluginMaager needs to load CORAL/Services/RelationalService component
+PluginManager                        Info     PluginManager loaded RelationalService library
+CORAL/Services/RelationalService     Info     Found plugin for RDBMS technology "coral" with native implementation
+CORAL/Services/RelationalService     Info     Found plugin for RDBMS technology "frontier" with native implementation
+CORAL/Services/RelationalService     Info     Found plugin for RDBMS technology "mysql" with native implementation
+CORAL/Services/RelationalService     Info     Found plugin for RDBMS technology "oracle" with native implementation
+CORAL/Services/RelationalService     Info     Found plugin for RDBMS technology "sqlite" with native implementation
+CORAL/Services/RelationalService     Info     Default implementation for RDBMS technology "coral" is native
+CORAL/Services/RelationalService     Info     Default implementation for RDBMS technology "frontier" is native
+CORAL/Services/RelationalService     Info     Default implementation for RDBMS technology "mysql" is native
+CORAL/Services/RelationalService     Info     Default implementation for RDBMS technology "oracle" is native
+CORAL/Services/RelationalService     Info     Default implementation for RDBMS technology "sqlite" is native
+PluginManager                        Info     PluginManager creating CORAL/RelationalPlugins/oracle component
+PluginManager                        Info     PluginMaager needs to load CORAL/RelationalPlugins/oracle component
+PluginManager                        Info     PluginManager loaded OracleAccess library
+CORAL/Services/ConnectionService     Info     Loading default plugin for coral::IAuthenticationService: CORAL/Services/XMLAuthenticationService
+PluginManager                        Info     PluginManager creating CORAL/Services/XMLAuthenticationService component
+PluginManager                        Info     PluginMaager needs to load CORAL/Services/XMLAuthenticationService component
+PluginManager                        Info     PluginManager loaded XMLAuthenticationService library
+CORAL/Services/XMLAuthenticationS... Info     Authentication using /afs/cern.ch/user/a/avalassi/private/authentication.xml file
+CORAL/Services/ConnectionService     Debug    No valid connection for string "oracle://lcg_cool_nightly/lcg_cool" found in the pool. Creating a new connection.
+CORAL/Services/ConnectionService     Debug    Trying to get a new update session on "oracle://lcg_cool_nightly/lcg_cool"
+CORAL/Services/ConnectionService     Debug    Connection parameters are: Retry-Period=10sec, Retry-Timeout=60sec, Connection-Timeout=0sec.
+CORAL/Services/ConnectionService     Info      Connection to service "lcg_cool_nightly" established. Id=c6ce484c-8418-11dd-80c3-001617c3b642
+CORAL/Services/ConnectionService     Info     New session on connection to service "lcg_cool_nightly" started for user "lcg_cool". Connection Id=c6ce484c-8418-11dd-80c3-001617c3b642
+CORAL/Services/ConnectionService     Debug     A New connection to service "lcg_cool_nightly" has been added in the active list. Id=c6ce484c-8418-11dd-80c3-001617c3b642
+RelationalDatabase                   Info     Instantiate a R/W RalDatabase for 'oracle://lcg_cool_nightly;schema=lcg_cool;dbname=COOLTEST'
+RelationalQueryMgr                   Debug    Instantiate a RelationalQueryMgr
+RelationalQueryMgr                   Debug    Instantiate a RalQueryMgr
+RelationalSequenceMgr                Debug    Instantiate a RelationalSequenceMgr
+RelationalSequenceMgr                Debug    Instantiate a RalSequenceMgr
+RelationalSchemaMgr                  Debug    Instantiate a RelationalSchemaMgr
+RelationalSchemaMgr                  Debug    Instantiate a RalSchemaMgr
+RelationalNodeMgr                    Debug    Instantiate a RelationalNodeMgr
+RelationalTagMgr                     Debug    Instantiate a RelationalTagMgr
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "DB_ATTRIBUTE_NAME", "DB_ATTRIBUTE_VALUE" FROM LCG_COOL."COOLTEST_DB_ATTRIBUTES" "COOLTEST_DB_ATTRIBUTES""
+RelationalQueryMgr                   Debug    Successfully fetched 10 table rows
+RelationalDatabase                   Debug    Release number match: database with CURRENT release number 2.6.0 will be opened using CURRENT client release number 2.6.0
+RalPrivilegeManager                  Debug    Instantiate a RalPrivilegeManager for 'oracle://lcg_cool_nightly;schema=lcg_cool;dbname=COOLTEST'
+REVOKE 'ALL' privileges from user PUBLIC
+RelationalNodeMgr                    Debug    Fetch all nodes in the database
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" ORDER BY "NODE_FULLPATH" DESC"
+RelationalQueryMgr                   Debug    Successfully fetched 11 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/UcharSpec/uc
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolder                     Debug    Instantiate a RelationalFolder for '/UcharSpec/uc'
+RelationalFolder                     Debug    Delete the RelationalFolder for '/UcharSpec/uc'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/UcharSpec/uc
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/UcharSpec
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/UcharSpec
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolderSet                  Debug    Instantiate a RelationalFolderSet for '/UcharSpec'
+RelationalFolderSet                  Debug    Delete the RelationalFolderSet for '/UcharSpec'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/SV/sv1
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolder                     Debug    Instantiate a RelationalFolder for '/SimpleSpec/SV/sv1'
+RelationalFolder                     Debug    Delete the RelationalFolder for '/SimpleSpec/SV/sv1'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/SV/sv1
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/SV
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/SV
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolderSet                  Debug    Instantiate a RelationalFolderSet for '/SimpleSpec/SV'
+RelationalFolderSet                  Debug    Delete the RelationalFolderSet for '/SimpleSpec/SV'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/MV/mv2
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolder                     Debug    Instantiate a RelationalFolder for '/SimpleSpec/MV/mv2'
+RelationalFolder                     Debug    Delete the RelationalFolder for '/SimpleSpec/MV/mv2'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/MV/mv2
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/MV/mv1
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolder                     Debug    Instantiate a RelationalFolder for '/SimpleSpec/MV/mv1'
+RelationalFolder                     Debug    Delete the RelationalFolder for '/SimpleSpec/MV/mv1'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/MV/mv1
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/MV
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/MV
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolderSet                  Debug    Instantiate a RelationalFolderSet for '/SimpleSpec/MV'
+RelationalFolderSet                  Debug    Delete the RelationalFolderSet for '/SimpleSpec/MV'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolderSet                  Debug    Instantiate a RelationalFolderSet for '/SimpleSpec'
+RelationalFolderSet                  Debug    Delete the RelationalFolderSet for '/SimpleSpec'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/ReferenceSpec/ref
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolder                     Debug    Instantiate a RelationalFolder for '/ReferenceSpec/ref'
+RelationalFolder                     Debug    Delete the RelationalFolder for '/ReferenceSpec/ref'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/ReferenceSpec/ref
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/ReferenceSpec
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/ReferenceSpec
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolderSet                  Debug    Instantiate a RelationalFolderSet for '/ReferenceSpec'
+RelationalFolderSet                  Debug    Delete the RelationalFolderSet for '/ReferenceSpec'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolderSet                  Debug    Instantiate a RelationalFolderSet for '/'
+RelationalFolderSet                  Debug    Delete the RelationalFolderSet for '/'
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "REVOKE INSERT ON LCG_COOL."COOLTEST_TAGS" FROM PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "REVOKE INSERT ON LCG_COOL."COOLTEST_TAG2TAG" FROM PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "REVOKE INSERT ON LCG_COOL."COOLTEST_F0009_TAGS" FROM PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "REVOKE INSERT ON LCG_COOL."COOLTEST_F0009_IOV2TAG" FROM PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "REVOKE INSERT ON LCG_COOL."COOLTEST_F0008_TAGS" FROM PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "REVOKE INSERT ON LCG_COOL."COOLTEST_F0008_IOV2TAG" FROM PUBLIC"
+RelationalNodeMgr                    Debug    Fetch all nodes in the database
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" ORDER BY "NODE_FULLPATH" DESC"
+RelationalQueryMgr                   Debug    Successfully fetched 11 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/UcharSpec/uc
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolder                     Debug    Instantiate a RelationalFolder for '/UcharSpec/uc'
+RelationalFolder                     Debug    Delete the RelationalFolder for '/UcharSpec/uc'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/UcharSpec/uc
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/UcharSpec
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/UcharSpec
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolderSet                  Debug    Instantiate a RelationalFolderSet for '/UcharSpec'
+RelationalFolderSet                  Debug    Delete the RelationalFolderSet for '/UcharSpec'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/SV/sv1
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolder                     Debug    Instantiate a RelationalFolder for '/SimpleSpec/SV/sv1'
+RelationalFolder                     Debug    Delete the RelationalFolder for '/SimpleSpec/SV/sv1'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/SV/sv1
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/SV
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/SV
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolderSet                  Debug    Instantiate a RelationalFolderSet for '/SimpleSpec/SV'
+RelationalFolderSet                  Debug    Delete the RelationalFolderSet for '/SimpleSpec/SV'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/MV/mv2
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolder                     Debug    Instantiate a RelationalFolder for '/SimpleSpec/MV/mv2'
+RelationalFolder                     Debug    Delete the RelationalFolder for '/SimpleSpec/MV/mv2'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/MV/mv2
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/MV/mv1
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolder                     Debug    Instantiate a RelationalFolder for '/SimpleSpec/MV/mv1'
+RelationalFolder                     Debug    Delete the RelationalFolder for '/SimpleSpec/MV/mv1'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/MV/mv1
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/MV
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/MV
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolderSet                  Debug    Instantiate a RelationalFolderSet for '/SimpleSpec/MV'
+RelationalFolderSet                  Debug    Delete the RelationalFolderSet for '/SimpleSpec/MV'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolderSet                  Debug    Instantiate a RelationalFolderSet for '/SimpleSpec'
+RelationalFolderSet                  Debug    Delete the RelationalFolderSet for '/SimpleSpec'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/ReferenceSpec/ref
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolder                     Debug    Instantiate a RelationalFolder for '/ReferenceSpec/ref'
+RelationalFolder                     Debug    Delete the RelationalFolder for '/ReferenceSpec/ref'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/ReferenceSpec/ref
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/ReferenceSpec
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/ReferenceSpec
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolderSet                  Debug    Instantiate a RelationalFolderSet for '/ReferenceSpec'
+RelationalFolderSet                  Debug    Delete the RelationalFolderSet for '/ReferenceSpec'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolderSet                  Debug    Instantiate a RelationalFolderSet for '/'
+RelationalFolderSet                  Debug    Delete the RelationalFolderSet for '/'
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "REVOKE UPDATE ON LCG_COOL."COOLTEST_TAGS_SEQ" FROM PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "REVOKE UPDATE ON LCG_COOL."COOLTEST_TAG2TAG_SEQ" FROM PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "REVOKE UPDATE ON LCG_COOL."COOLTEST_F0005_TAGS_SEQ" FROM PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "REVOKE UPDATE ON LCG_COOL."COOLTEST_F0003_TAGS_SEQ" FROM PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "REVOKE UPDATE ON LCG_COOL."COOLTEST_F0009_TAGS_SEQ" FROM PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "REVOKE UPDATE ON LCG_COOL."COOLTEST_F0008_TAGS_SEQ" FROM PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "REVOKE UPDATE ON LCG_COOL."COOLTEST_F0004_TAGS_SEQ" FROM PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "REVOKE UPDATE ON LCG_COOL."COOLTEST_F0002_TAGS_SEQ" FROM PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "REVOKE UPDATE ON LCG_COOL."COOLTEST_F0001_TAGS_SEQ" FROM PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "REVOKE UPDATE ON LCG_COOL."COOLTEST_F0000_TAGS_SEQ" FROM PUBLIC"
+RelationalNodeMgr                    Debug    Fetch all nodes in the database
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" ORDER BY "NODE_FULLPATH" DESC"
+RelationalQueryMgr                   Debug    Successfully fetched 11 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/UcharSpec/uc
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolder                     Debug    Instantiate a RelationalFolder for '/UcharSpec/uc'
+RelationalFolder                     Debug    Delete the RelationalFolder for '/UcharSpec/uc'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/UcharSpec/uc
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/UcharSpec
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/UcharSpec
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolderSet                  Debug    Instantiate a RelationalFolderSet for '/UcharSpec'
+RelationalFolderSet                  Debug    Delete the RelationalFolderSet for '/UcharSpec'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/SV/sv1
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolder                     Debug    Instantiate a RelationalFolder for '/SimpleSpec/SV/sv1'
+RelationalFolder                     Debug    Delete the RelationalFolder for '/SimpleSpec/SV/sv1'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/SV/sv1
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/SV
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/SV
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolderSet                  Debug    Instantiate a RelationalFolderSet for '/SimpleSpec/SV'
+RelationalFolderSet                  Debug    Delete the RelationalFolderSet for '/SimpleSpec/SV'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/MV/mv2
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolder                     Debug    Instantiate a RelationalFolder for '/SimpleSpec/MV/mv2'
+RelationalFolder                     Debug    Delete the RelationalFolder for '/SimpleSpec/MV/mv2'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/MV/mv2
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/MV/mv1
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolder                     Debug    Instantiate a RelationalFolder for '/SimpleSpec/MV/mv1'
+RelationalFolder                     Debug    Delete the RelationalFolder for '/SimpleSpec/MV/mv1'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/MV/mv1
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/MV
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/MV
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolderSet                  Debug    Instantiate a RelationalFolderSet for '/SimpleSpec/MV'
+RelationalFolderSet                  Debug    Delete the RelationalFolderSet for '/SimpleSpec/MV'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolderSet                  Debug    Instantiate a RelationalFolderSet for '/SimpleSpec'
+RelationalFolderSet                  Debug    Delete the RelationalFolderSet for '/SimpleSpec'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/ReferenceSpec/ref
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolder                     Debug    Instantiate a RelationalFolder for '/ReferenceSpec/ref'
+RelationalFolder                     Debug    Delete the RelationalFolder for '/ReferenceSpec/ref'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/ReferenceSpec/ref
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/ReferenceSpec
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/ReferenceSpec
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolderSet                  Debug    Instantiate a RelationalFolderSet for '/ReferenceSpec'
+RelationalFolderSet                  Debug    Delete the RelationalFolderSet for '/ReferenceSpec'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolderSet                  Debug    Instantiate a RelationalFolderSet for '/'
+RelationalFolderSet                  Debug    Delete the RelationalFolderSet for '/'
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "REVOKE DELETE ON LCG_COOL."COOLTEST_TAGS" FROM PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "REVOKE DELETE ON LCG_COOL."COOLTEST_TAG2TAG" FROM PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "REVOKE DELETE ON LCG_COOL."COOLTEST_F0009_TAGS" FROM PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "REVOKE DELETE ON LCG_COOL."COOLTEST_F0009_IOV2TAG" FROM PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "REVOKE DELETE ON LCG_COOL."COOLTEST_F0008_TAGS" FROM PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "REVOKE DELETE ON LCG_COOL."COOLTEST_F0008_IOV2TAG" FROM PUBLIC"
+RelationalNodeMgr                    Debug    Fetch all nodes in the database
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" ORDER BY "NODE_FULLPATH" DESC"
+RelationalQueryMgr                   Debug    Successfully fetched 11 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/UcharSpec/uc
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolder                     Debug    Instantiate a RelationalFolder for '/UcharSpec/uc'
+RelationalFolder                     Debug    Delete the RelationalFolder for '/UcharSpec/uc'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/UcharSpec
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/SV/sv1
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolder                     Debug    Instantiate a RelationalFolder for '/SimpleSpec/SV/sv1'
+RelationalFolder                     Debug    Delete the RelationalFolder for '/SimpleSpec/SV/sv1'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/SV
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/MV/mv2
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolder                     Debug    Instantiate a RelationalFolder for '/SimpleSpec/MV/mv2'
+RelationalFolder                     Debug    Delete the RelationalFolder for '/SimpleSpec/MV/mv2'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/MV/mv1
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolder                     Debug    Instantiate a RelationalFolder for '/SimpleSpec/MV/mv1'
+RelationalFolder                     Debug    Delete the RelationalFolder for '/SimpleSpec/MV/mv1'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/MV
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/ReferenceSpec/ref
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolder                     Debug    Instantiate a RelationalFolder for '/ReferenceSpec/ref'
+RelationalFolder                     Debug    Delete the RelationalFolder for '/ReferenceSpec/ref'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/ReferenceSpec
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "REVOKE INSERT ON LCG_COOL."COOLTEST_F0010_IOVS" FROM PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "REVOKE INSERT ON LCG_COOL."COOLTEST_F0010_CHANNELS" FROM PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "REVOKE INSERT ON LCG_COOL."COOLTEST_F0007_IOVS" FROM PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "REVOKE INSERT ON LCG_COOL."COOLTEST_F0007_CHANNELS" FROM PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "REVOKE INSERT ON LCG_COOL."COOLTEST_F0009_IOVS" FROM PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "REVOKE INSERT ON LCG_COOL."COOLTEST_F0009_CHANNELS" FROM PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "REVOKE INSERT ON LCG_COOL."COOLTEST_F0008_IOVS" FROM PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "REVOKE INSERT ON LCG_COOL."COOLTEST_F0008_CHANNELS" FROM PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "REVOKE INSERT ON LCG_COOL."COOLTEST_F0006_IOVS" FROM PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "REVOKE INSERT ON LCG_COOL."COOLTEST_F0006_CHANNELS" FROM PUBLIC"
+RelationalNodeMgr                    Debug    Fetch all nodes in the database
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" ORDER BY "NODE_FULLPATH" DESC"
+RelationalQueryMgr                   Debug    Successfully fetched 11 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/UcharSpec/uc
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolder                     Debug    Instantiate a RelationalFolder for '/UcharSpec/uc'
+RelationalFolder                     Debug    Delete the RelationalFolder for '/UcharSpec/uc'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/UcharSpec
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/SV/sv1
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolder                     Debug    Instantiate a RelationalFolder for '/SimpleSpec/SV/sv1'
+RelationalFolder                     Debug    Delete the RelationalFolder for '/SimpleSpec/SV/sv1'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/SV
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/MV/mv2
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolder                     Debug    Instantiate a RelationalFolder for '/SimpleSpec/MV/mv2'
+RelationalFolder                     Debug    Delete the RelationalFolder for '/SimpleSpec/MV/mv2'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/MV/mv1
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolder                     Debug    Instantiate a RelationalFolder for '/SimpleSpec/MV/mv1'
+RelationalFolder                     Debug    Delete the RelationalFolder for '/SimpleSpec/MV/mv1'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/MV
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/ReferenceSpec/ref
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolder                     Debug    Instantiate a RelationalFolder for '/ReferenceSpec/ref'
+RelationalFolder                     Debug    Delete the RelationalFolder for '/ReferenceSpec/ref'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/ReferenceSpec
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "REVOKE UPDATE ON LCG_COOL."COOLTEST_IOVS_SEQ" FROM PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "REVOKE UPDATE ON LCG_COOL."COOLTEST_F0010_IOVS" FROM PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "REVOKE UPDATE ON LCG_COOL."COOLTEST_F0010_IOVS_SEQ" FROM PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "REVOKE UPDATE ON LCG_COOL."COOLTEST_F0010_CHANNELS" FROM PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "REVOKE UPDATE ON LCG_COOL."COOLTEST_F0007_IOVS" FROM PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "REVOKE UPDATE ON LCG_COOL."COOLTEST_F0007_IOVS_SEQ" FROM PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "REVOKE UPDATE ON LCG_COOL."COOLTEST_F0007_CHANNELS" FROM PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "REVOKE UPDATE ON LCG_COOL."COOLTEST_F0009_IOVS" FROM PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "REVOKE UPDATE ON LCG_COOL."COOLTEST_F0009_IOVS_SEQ" FROM PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "REVOKE UPDATE ON LCG_COOL."COOLTEST_F0009_CHANNELS" FROM PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "REVOKE UPDATE ON LCG_COOL."COOLTEST_F0008_IOVS" FROM PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "REVOKE UPDATE ON LCG_COOL."COOLTEST_F0008_IOVS_SEQ" FROM PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "REVOKE UPDATE ON LCG_COOL."COOLTEST_F0008_CHANNELS" FROM PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "REVOKE UPDATE ON LCG_COOL."COOLTEST_F0006_IOVS" FROM PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "REVOKE UPDATE ON LCG_COOL."COOLTEST_F0006_IOVS_SEQ" FROM PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "REVOKE UPDATE ON LCG_COOL."COOLTEST_F0006_CHANNELS" FROM PUBLIC"
+RelationalNodeMgr                    Debug    Fetch all nodes in the database
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" ORDER BY "NODE_FULLPATH" DESC"
+RelationalQueryMgr                   Debug    Successfully fetched 11 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/UcharSpec/uc
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolder                     Debug    Instantiate a RelationalFolder for '/UcharSpec/uc'
+RelationalFolder                     Debug    Delete the RelationalFolder for '/UcharSpec/uc'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/UcharSpec/uc
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/UcharSpec
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/UcharSpec
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolderSet                  Debug    Instantiate a RelationalFolderSet for '/UcharSpec'
+RelationalFolderSet                  Debug    Delete the RelationalFolderSet for '/UcharSpec'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/SV/sv1
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolder                     Debug    Instantiate a RelationalFolder for '/SimpleSpec/SV/sv1'
+RelationalFolder                     Debug    Delete the RelationalFolder for '/SimpleSpec/SV/sv1'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/SV/sv1
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/SV
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/SV
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolderSet                  Debug    Instantiate a RelationalFolderSet for '/SimpleSpec/SV'
+RelationalFolderSet                  Debug    Delete the RelationalFolderSet for '/SimpleSpec/SV'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/MV/mv2
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolder                     Debug    Instantiate a RelationalFolder for '/SimpleSpec/MV/mv2'
+RelationalFolder                     Debug    Delete the RelationalFolder for '/SimpleSpec/MV/mv2'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/MV/mv2
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/MV/mv1
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolder                     Debug    Instantiate a RelationalFolder for '/SimpleSpec/MV/mv1'
+RelationalFolder                     Debug    Delete the RelationalFolder for '/SimpleSpec/MV/mv1'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/MV/mv1
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/MV
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/MV
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolderSet                  Debug    Instantiate a RelationalFolderSet for '/SimpleSpec/MV'
+RelationalFolderSet                  Debug    Delete the RelationalFolderSet for '/SimpleSpec/MV'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolderSet                  Debug    Instantiate a RelationalFolderSet for '/SimpleSpec'
+RelationalFolderSet                  Debug    Delete the RelationalFolderSet for '/SimpleSpec'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/ReferenceSpec/ref
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolder                     Debug    Instantiate a RelationalFolder for '/ReferenceSpec/ref'
+RelationalFolder                     Debug    Delete the RelationalFolder for '/ReferenceSpec/ref'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/ReferenceSpec/ref
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/ReferenceSpec
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/ReferenceSpec
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolderSet                  Debug    Instantiate a RelationalFolderSet for '/ReferenceSpec'
+RelationalFolderSet                  Debug    Delete the RelationalFolderSet for '/ReferenceSpec'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolderSet                  Debug    Instantiate a RelationalFolderSet for '/'
+RelationalFolderSet                  Debug    Delete the RelationalFolderSet for '/'
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "REVOKE SELECT ON LCG_COOL."COOLTEST_DB_ATTRIBUTES" FROM PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "REVOKE SELECT ON LCG_COOL."COOLTEST_NODES" FROM PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "REVOKE SELECT ON LCG_COOL."COOLTEST_NODES_SEQ" FROM PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "REVOKE SELECT ON LCG_COOL."COOLTEST_TAGS" FROM PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "REVOKE SELECT ON LCG_COOL."COOLTEST_TAG2TAG" FROM PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "REVOKE SELECT ON LCG_COOL."COOLTEST_TAG2TAG_SEQ" FROM PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "REVOKE SELECT ON LCG_COOL."COOLTEST_TAGS_SEQ" FROM PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "REVOKE SELECT ON LCG_COOL."COOLTEST_IOVS_SEQ" FROM PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "REVOKE SELECT ON LCG_COOL."COOLTEST_F0010_IOVS" FROM PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "REVOKE SELECT ON LCG_COOL."COOLTEST_F0010_IOVS_SEQ" FROM PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "REVOKE SELECT ON LCG_COOL."COOLTEST_F0010_CHANNELS" FROM PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "REVOKE SELECT ON LCG_COOL."COOLTEST_F0005_TAGS_SEQ" FROM PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "REVOKE SELECT ON LCG_COOL."COOLTEST_F0007_IOVS" FROM PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "REVOKE SELECT ON LCG_COOL."COOLTEST_F0007_IOVS_SEQ" FROM PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "REVOKE SELECT ON LCG_COOL."COOLTEST_F0007_CHANNELS" FROM PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "REVOKE SELECT ON LCG_COOL."COOLTEST_F0003_TAGS_SEQ" FROM PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "REVOKE SELECT ON LCG_COOL."COOLTEST_F0009_IOVS" FROM PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "REVOKE SELECT ON LCG_COOL."COOLTEST_F0009_IOVS_SEQ" FROM PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "REVOKE SELECT ON LCG_COOL."COOLTEST_F0009_CHANNELS" FROM PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "REVOKE SELECT ON LCG_COOL."COOLTEST_F0009_TAGS" FROM PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "REVOKE SELECT ON LCG_COOL."COOLTEST_F0009_TAGS_SEQ" FROM PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "REVOKE SELECT ON LCG_COOL."COOLTEST_F0009_IOV2TAG" FROM PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "REVOKE SELECT ON LCG_COOL."COOLTEST_F0008_IOVS" FROM PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "REVOKE SELECT ON LCG_COOL."COOLTEST_F0008_IOVS_SEQ" FROM PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "REVOKE SELECT ON LCG_COOL."COOLTEST_F0008_CHANNELS" FROM PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "REVOKE SELECT ON LCG_COOL."COOLTEST_F0008_TAGS" FROM PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "REVOKE SELECT ON LCG_COOL."COOLTEST_F0008_TAGS_SEQ" FROM PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "REVOKE SELECT ON LCG_COOL."COOLTEST_F0008_IOV2TAG" FROM PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "REVOKE SELECT ON LCG_COOL."COOLTEST_F0004_TAGS_SEQ" FROM PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "REVOKE SELECT ON LCG_COOL."COOLTEST_F0002_TAGS_SEQ" FROM PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "REVOKE SELECT ON LCG_COOL."COOLTEST_F0006_IOVS" FROM PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "REVOKE SELECT ON LCG_COOL."COOLTEST_F0006_IOVS_SEQ" FROM PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "REVOKE SELECT ON LCG_COOL."COOLTEST_F0006_CHANNELS" FROM PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "REVOKE SELECT ON LCG_COOL."COOLTEST_F0001_TAGS_SEQ" FROM PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "REVOKE SELECT ON LCG_COOL."COOLTEST_F0000_TAGS_SEQ" FROM PUBLIC"
+RalPrivilegeManager                  Debug    Delete the RalPrivilegeManager for 'oracle://lcg_cool_nightly;schema=lcg_cool;dbname=COOLTEST'
+RelationalDatabase                   Info     Delete the RalDatabase for 'oracle://lcg_cool_nightly;schema=lcg_cool;dbname=COOLTEST'
+RelationalDatabase                   Debug    Delete the RelationalDatabase for 'oracle://lcg_cool_nightly;schema=lcg_cool;dbname=COOLTEST'
+RelationalTagMgr                     Debug    Delete the RelationalTagMgr
+RelationalNodeMgr                    Debug    Delete the RelationalNodeMgr
+RelationalSchemaMgr                  Debug    Delete the RalSchemaMgr
+RelationalSchemaMgr                  Debug    Delete the RelationalSchemaMgr
+RelationalQueryMgr                   Debug    Delete the RalQueryMgr
+RelationalSequenceMgr                Debug    Delete the RalSequenceMgr
+RelationalSequenceMgr                Debug    Delete the RelationalSequenceMgr
+RalSessionMgr                        Info     Delete the RalSessionMgr for 'oracle://lcg_cool_nightly;schema=lcg_cool;dbname=COOLTEST'
+RalSessionMgr                        Info     Disconnect from the database server
+CORAL/Services/ConnectionService     Debug    Connection id=c6ce484c-8418-11dd-80c3-001617c3b642 to service "lcg_cool_nightly" has 0 session(s) opended.
+CORAL/Services/ConnectionService     Debug    The active connection id=c6ce484c-8418-11dd-80c3-001617c3b642 to service "lcg_cool_nightly" has been removed from the active list.
+RelationalQueryMgr                   Debug    Delete the RelationalQueryMgr
+CoralApplication                     Info     Delete the COOL CoralApplication...
+CoralApplication                     Info     Delete the COOL database service
+RalDatabaseSvc                       Info     Delete the RalDatabaseSvc...
+RalDatabaseSvc                       Info     Purge the connection pool
+RalDatabaseSvc                       Info     Reset the ICS pointer
+RalDatabaseSvc                       Info     Delete the RalDatabaseSvc... DONE
+CoralApplication                     Info     Delete the CORAL connection service
+CoralApplication                     Info     Delete the COOL CoralApplication... DONE
diff --git a/RelationalCool/utilities/coolPrivileges/logs/revokeReader.txt b/RelationalCool/utilities/coolPrivileges/logs/revokeReader.txt
new file mode 100644
index 000000000..25655d9f0
--- /dev/null
+++ b/RelationalCool/utilities/coolPrivileges/logs/revokeReader.txt
@@ -0,0 +1,202 @@
+CoralApplication                     Info     Create a cool::CoralApplication...
+CoralApplication                     Info     Enable the COOL signal handler
+CoralApplication                     Info     Create a new own CORAL connection service
+CoralApplication                     Info     Create the COOL database service
+RalDatabaseSvc                       Info     Instantiate the RalDatabaseSvc
+CoralApplication                     Info     Create a cool::CoralApplication... DONE
+RelationalDatabase                   Debug    Instantiate a RelationalDatabase for 'oracle://lcg_cool_nightly;schema=lcg_cool;dbname=COOLTEST'
+RalSessionMgr                        Info     Instantiate a R/W RalSessionMgr for 'oracle://lcg_cool_nightly;schema=lcg_cool;dbname=COOLTEST'
+RalSessionMgr                        Info     Connect to the database server
+PluginManager                        Info     PluginManager creating CORAL/Services/ConnectionService component
+PluginManager                        Info     PluginMaager needs to load CORAL/Services/ConnectionService component
+PluginManager                        Info     PluginManager loaded ConnectionService library
+CORAL/Services/ConnectionService     Info     Loading default plugin for coral::IRelationalService: CORAL/Services/RelationalService
+PluginManager                        Info     PluginManager creating CORAL/Services/RelationalService component
+PluginManager                        Info     PluginMaager needs to load CORAL/Services/RelationalService component
+PluginManager                        Info     PluginManager loaded RelationalService library
+CORAL/Services/RelationalService     Info     Found plugin for RDBMS technology "coral" with native implementation
+CORAL/Services/RelationalService     Info     Found plugin for RDBMS technology "frontier" with native implementation
+CORAL/Services/RelationalService     Info     Found plugin for RDBMS technology "mysql" with native implementation
+CORAL/Services/RelationalService     Info     Found plugin for RDBMS technology "oracle" with native implementation
+CORAL/Services/RelationalService     Info     Found plugin for RDBMS technology "sqlite" with native implementation
+CORAL/Services/RelationalService     Info     Default implementation for RDBMS technology "coral" is native
+CORAL/Services/RelationalService     Info     Default implementation for RDBMS technology "frontier" is native
+CORAL/Services/RelationalService     Info     Default implementation for RDBMS technology "mysql" is native
+CORAL/Services/RelationalService     Info     Default implementation for RDBMS technology "oracle" is native
+CORAL/Services/RelationalService     Info     Default implementation for RDBMS technology "sqlite" is native
+PluginManager                        Info     PluginManager creating CORAL/RelationalPlugins/oracle component
+PluginManager                        Info     PluginMaager needs to load CORAL/RelationalPlugins/oracle component
+PluginManager                        Info     PluginManager loaded OracleAccess library
+CORAL/Services/ConnectionService     Info     Loading default plugin for coral::IAuthenticationService: CORAL/Services/XMLAuthenticationService
+PluginManager                        Info     PluginManager creating CORAL/Services/XMLAuthenticationService component
+PluginManager                        Info     PluginMaager needs to load CORAL/Services/XMLAuthenticationService component
+PluginManager                        Info     PluginManager loaded XMLAuthenticationService library
+CORAL/Services/XMLAuthenticationS... Info     Authentication using /afs/cern.ch/user/a/avalassi/private/authentication.xml file
+CORAL/Services/ConnectionService     Debug    No valid connection for string "oracle://lcg_cool_nightly/lcg_cool" found in the pool. Creating a new connection.
+CORAL/Services/ConnectionService     Debug    Trying to get a new update session on "oracle://lcg_cool_nightly/lcg_cool"
+CORAL/Services/ConnectionService     Debug    Connection parameters are: Retry-Period=10sec, Retry-Timeout=60sec, Connection-Timeout=0sec.
+CORAL/Services/ConnectionService     Info      Connection to service "lcg_cool_nightly" established. Id=1a8d4df4-8417-11dd-ac95-001617c3b642
+CORAL/Services/ConnectionService     Info     New session on connection to service "lcg_cool_nightly" started for user "lcg_cool". Connection Id=1a8d4df4-8417-11dd-ac95-001617c3b642
+CORAL/Services/ConnectionService     Debug     A New connection to service "lcg_cool_nightly" has been added in the active list. Id=1a8d4df4-8417-11dd-ac95-001617c3b642
+RelationalDatabase                   Info     Instantiate a R/W RalDatabase for 'oracle://lcg_cool_nightly;schema=lcg_cool;dbname=COOLTEST'
+RelationalQueryMgr                   Debug    Instantiate a RelationalQueryMgr
+RelationalQueryMgr                   Debug    Instantiate a RalQueryMgr
+RelationalSequenceMgr                Debug    Instantiate a RelationalSequenceMgr
+RelationalSequenceMgr                Debug    Instantiate a RalSequenceMgr
+RelationalSchemaMgr                  Debug    Instantiate a RelationalSchemaMgr
+RelationalSchemaMgr                  Debug    Instantiate a RalSchemaMgr
+RelationalNodeMgr                    Debug    Instantiate a RelationalNodeMgr
+RelationalTagMgr                     Debug    Instantiate a RelationalTagMgr
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "DB_ATTRIBUTE_NAME", "DB_ATTRIBUTE_VALUE" FROM LCG_COOL."COOLTEST_DB_ATTRIBUTES" "COOLTEST_DB_ATTRIBUTES""
+RelationalQueryMgr                   Debug    Successfully fetched 10 table rows
+RelationalDatabase                   Debug    Release number match: database with CURRENT release number 2.6.0 will be opened using CURRENT client release number 2.6.0
+RalPrivilegeManager                  Debug    Instantiate a RalPrivilegeManager for 'oracle://lcg_cool_nightly;schema=lcg_cool;dbname=COOLTEST'
+REVOKE 'READER' privileges from user PUBLIC
+RelationalNodeMgr                    Debug    Fetch all nodes in the database
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" ORDER BY "NODE_FULLPATH" DESC"
+RelationalQueryMgr                   Debug    Successfully fetched 11 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/UcharSpec/uc
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolder                     Debug    Instantiate a RelationalFolder for '/UcharSpec/uc'
+RelationalFolder                     Debug    Delete the RelationalFolder for '/UcharSpec/uc'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/UcharSpec/uc
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/UcharSpec
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/UcharSpec
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolderSet                  Debug    Instantiate a RelationalFolderSet for '/UcharSpec'
+RelationalFolderSet                  Debug    Delete the RelationalFolderSet for '/UcharSpec'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/SV/sv1
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolder                     Debug    Instantiate a RelationalFolder for '/SimpleSpec/SV/sv1'
+RelationalFolder                     Debug    Delete the RelationalFolder for '/SimpleSpec/SV/sv1'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/SV/sv1
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/SV
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/SV
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolderSet                  Debug    Instantiate a RelationalFolderSet for '/SimpleSpec/SV'
+RelationalFolderSet                  Debug    Delete the RelationalFolderSet for '/SimpleSpec/SV'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/MV/mv2
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolder                     Debug    Instantiate a RelationalFolder for '/SimpleSpec/MV/mv2'
+RelationalFolder                     Debug    Delete the RelationalFolder for '/SimpleSpec/MV/mv2'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/MV/mv2
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/MV/mv1
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolder                     Debug    Instantiate a RelationalFolder for '/SimpleSpec/MV/mv1'
+RelationalFolder                     Debug    Delete the RelationalFolder for '/SimpleSpec/MV/mv1'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/MV/mv1
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/MV
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/MV
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolderSet                  Debug    Instantiate a RelationalFolderSet for '/SimpleSpec/MV'
+RelationalFolderSet                  Debug    Delete the RelationalFolderSet for '/SimpleSpec/MV'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolderSet                  Debug    Instantiate a RelationalFolderSet for '/SimpleSpec'
+RelationalFolderSet                  Debug    Delete the RelationalFolderSet for '/SimpleSpec'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/ReferenceSpec/ref
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolder                     Debug    Instantiate a RelationalFolder for '/ReferenceSpec/ref'
+RelationalFolder                     Debug    Delete the RelationalFolder for '/ReferenceSpec/ref'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/ReferenceSpec/ref
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/ReferenceSpec
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/ReferenceSpec
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolderSet                  Debug    Instantiate a RelationalFolderSet for '/ReferenceSpec'
+RelationalFolderSet                  Debug    Delete the RelationalFolderSet for '/ReferenceSpec'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolderSet                  Debug    Instantiate a RelationalFolderSet for '/'
+RelationalFolderSet                  Debug    Delete the RelationalFolderSet for '/'
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "REVOKE SELECT ON LCG_COOL."COOLTEST_DB_ATTRIBUTES" FROM PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "REVOKE SELECT ON LCG_COOL."COOLTEST_NODES" FROM PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "REVOKE SELECT ON LCG_COOL."COOLTEST_NODES_SEQ" FROM PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "REVOKE SELECT ON LCG_COOL."COOLTEST_TAGS" FROM PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "REVOKE SELECT ON LCG_COOL."COOLTEST_TAG2TAG" FROM PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "REVOKE SELECT ON LCG_COOL."COOLTEST_TAGS_SEQ" FROM PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "REVOKE SELECT ON LCG_COOL."COOLTEST_IOVS_SEQ" FROM PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "REVOKE SELECT ON LCG_COOL."COOLTEST_F0010_IOVS" FROM PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "REVOKE SELECT ON LCG_COOL."COOLTEST_F0010_IOVS_SEQ" FROM PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "REVOKE SELECT ON LCG_COOL."COOLTEST_F0010_CHANNELS" FROM PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "REVOKE SELECT ON LCG_COOL."COOLTEST_F0005_TAGS_SEQ" FROM PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "REVOKE SELECT ON LCG_COOL."COOLTEST_F0007_IOVS" FROM PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "REVOKE SELECT ON LCG_COOL."COOLTEST_F0007_IOVS_SEQ" FROM PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "REVOKE SELECT ON LCG_COOL."COOLTEST_F0007_CHANNELS" FROM PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "REVOKE SELECT ON LCG_COOL."COOLTEST_F0003_TAGS_SEQ" FROM PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "REVOKE SELECT ON LCG_COOL."COOLTEST_F0009_IOVS" FROM PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "REVOKE SELECT ON LCG_COOL."COOLTEST_F0009_IOVS_SEQ" FROM PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "REVOKE SELECT ON LCG_COOL."COOLTEST_F0009_CHANNELS" FROM PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "REVOKE SELECT ON LCG_COOL."COOLTEST_F0009_TAGS" FROM PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "REVOKE SELECT ON LCG_COOL."COOLTEST_F0009_TAGS_SEQ" FROM PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "REVOKE SELECT ON LCG_COOL."COOLTEST_F0009_IOV2TAG" FROM PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "REVOKE SELECT ON LCG_COOL."COOLTEST_F0008_IOVS" FROM PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "REVOKE SELECT ON LCG_COOL."COOLTEST_F0008_IOVS_SEQ" FROM PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "REVOKE SELECT ON LCG_COOL."COOLTEST_F0008_CHANNELS" FROM PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "REVOKE SELECT ON LCG_COOL."COOLTEST_F0008_TAGS" FROM PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "REVOKE SELECT ON LCG_COOL."COOLTEST_F0008_TAGS_SEQ" FROM PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "REVOKE SELECT ON LCG_COOL."COOLTEST_F0008_IOV2TAG" FROM PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "REVOKE SELECT ON LCG_COOL."COOLTEST_F0004_TAGS_SEQ" FROM PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "REVOKE SELECT ON LCG_COOL."COOLTEST_F0002_TAGS_SEQ" FROM PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "REVOKE SELECT ON LCG_COOL."COOLTEST_F0006_IOVS" FROM PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "REVOKE SELECT ON LCG_COOL."COOLTEST_F0006_IOVS_SEQ" FROM PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "REVOKE SELECT ON LCG_COOL."COOLTEST_F0006_CHANNELS" FROM PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "REVOKE SELECT ON LCG_COOL."COOLTEST_F0001_TAGS_SEQ" FROM PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "REVOKE SELECT ON LCG_COOL."COOLTEST_F0000_TAGS_SEQ" FROM PUBLIC"
+RalPrivilegeManager                  Debug    Delete the RalPrivilegeManager for 'oracle://lcg_cool_nightly;schema=lcg_cool;dbname=COOLTEST'
+RelationalDatabase                   Info     Delete the RalDatabase for 'oracle://lcg_cool_nightly;schema=lcg_cool;dbname=COOLTEST'
+RelationalDatabase                   Debug    Delete the RelationalDatabase for 'oracle://lcg_cool_nightly;schema=lcg_cool;dbname=COOLTEST'
+RelationalTagMgr                     Debug    Delete the RelationalTagMgr
+RelationalNodeMgr                    Debug    Delete the RelationalNodeMgr
+RelationalSchemaMgr                  Debug    Delete the RalSchemaMgr
+RelationalSchemaMgr                  Debug    Delete the RelationalSchemaMgr
+RelationalQueryMgr                   Debug    Delete the RalQueryMgr
+RelationalSequenceMgr                Debug    Delete the RalSequenceMgr
+RelationalSequenceMgr                Debug    Delete the RelationalSequenceMgr
+RalSessionMgr                        Info     Delete the RalSessionMgr for 'oracle://lcg_cool_nightly;schema=lcg_cool;dbname=COOLTEST'
+RalSessionMgr                        Info     Disconnect from the database server
+CORAL/Services/ConnectionService     Debug    Connection id=1a8d4df4-8417-11dd-ac95-001617c3b642 to service "lcg_cool_nightly" has 0 session(s) opended.
+CORAL/Services/ConnectionService     Debug    The active connection id=1a8d4df4-8417-11dd-ac95-001617c3b642 to service "lcg_cool_nightly" has been removed from the active list.
+RelationalQueryMgr                   Debug    Delete the RelationalQueryMgr
+CoralApplication                     Info     Delete the COOL CoralApplication...
+CoralApplication                     Info     Delete the COOL database service
+RalDatabaseSvc                       Info     Delete the RalDatabaseSvc...
+RalDatabaseSvc                       Info     Purge the connection pool
+RalDatabaseSvc                       Info     Reset the ICS pointer
+RalDatabaseSvc                       Info     Delete the RalDatabaseSvc... DONE
+CoralApplication                     Info     Delete the CORAL connection service
+CoralApplication                     Info     Delete the COOL CoralApplication... DONE
diff --git a/RelationalCool/utilities/coolPrivileges/logs/revokeTagger.txt b/RelationalCool/utilities/coolPrivileges/logs/revokeTagger.txt
new file mode 100644
index 000000000..f63948853
--- /dev/null
+++ b/RelationalCool/utilities/coolPrivileges/logs/revokeTagger.txt
@@ -0,0 +1,372 @@
+CoralApplication                     Info     Create a cool::CoralApplication...
+CoralApplication                     Info     Enable the COOL signal handler
+CoralApplication                     Info     Create a new own CORAL connection service
+CoralApplication                     Info     Create the COOL database service
+RalDatabaseSvc                       Info     Instantiate the RalDatabaseSvc
+CoralApplication                     Info     Create a cool::CoralApplication... DONE
+RelationalDatabase                   Debug    Instantiate a RelationalDatabase for 'oracle://lcg_cool_nightly;schema=lcg_cool;dbname=COOLTEST'
+RalSessionMgr                        Info     Instantiate a R/W RalSessionMgr for 'oracle://lcg_cool_nightly;schema=lcg_cool;dbname=COOLTEST'
+RalSessionMgr                        Info     Connect to the database server
+PluginManager                        Info     PluginManager creating CORAL/Services/ConnectionService component
+PluginManager                        Info     PluginMaager needs to load CORAL/Services/ConnectionService component
+PluginManager                        Info     PluginManager loaded ConnectionService library
+CORAL/Services/ConnectionService     Info     Loading default plugin for coral::IRelationalService: CORAL/Services/RelationalService
+PluginManager                        Info     PluginManager creating CORAL/Services/RelationalService component
+PluginManager                        Info     PluginMaager needs to load CORAL/Services/RelationalService component
+PluginManager                        Info     PluginManager loaded RelationalService library
+CORAL/Services/RelationalService     Info     Found plugin for RDBMS technology "coral" with native implementation
+CORAL/Services/RelationalService     Info     Found plugin for RDBMS technology "frontier" with native implementation
+CORAL/Services/RelationalService     Info     Found plugin for RDBMS technology "mysql" with native implementation
+CORAL/Services/RelationalService     Info     Found plugin for RDBMS technology "oracle" with native implementation
+CORAL/Services/RelationalService     Info     Found plugin for RDBMS technology "sqlite" with native implementation
+CORAL/Services/RelationalService     Info     Default implementation for RDBMS technology "coral" is native
+CORAL/Services/RelationalService     Info     Default implementation for RDBMS technology "frontier" is native
+CORAL/Services/RelationalService     Info     Default implementation for RDBMS technology "mysql" is native
+CORAL/Services/RelationalService     Info     Default implementation for RDBMS technology "oracle" is native
+CORAL/Services/RelationalService     Info     Default implementation for RDBMS technology "sqlite" is native
+PluginManager                        Info     PluginManager creating CORAL/RelationalPlugins/oracle component
+PluginManager                        Info     PluginMaager needs to load CORAL/RelationalPlugins/oracle component
+PluginManager                        Info     PluginManager loaded OracleAccess library
+CORAL/Services/ConnectionService     Info     Loading default plugin for coral::IAuthenticationService: CORAL/Services/XMLAuthenticationService
+PluginManager                        Info     PluginManager creating CORAL/Services/XMLAuthenticationService component
+PluginManager                        Info     PluginMaager needs to load CORAL/Services/XMLAuthenticationService component
+PluginManager                        Info     PluginManager loaded XMLAuthenticationService library
+CORAL/Services/XMLAuthenticationS... Info     Authentication using /afs/cern.ch/user/a/avalassi/private/authentication.xml file
+CORAL/Services/ConnectionService     Debug    No valid connection for string "oracle://lcg_cool_nightly/lcg_cool" found in the pool. Creating a new connection.
+CORAL/Services/ConnectionService     Debug    Trying to get a new update session on "oracle://lcg_cool_nightly/lcg_cool"
+CORAL/Services/ConnectionService     Debug    Connection parameters are: Retry-Period=10sec, Retry-Timeout=60sec, Connection-Timeout=0sec.
+CORAL/Services/ConnectionService     Info      Connection to service "lcg_cool_nightly" established. Id=baab43e4-8418-11dd-8d94-001617c3b642
+CORAL/Services/ConnectionService     Info     New session on connection to service "lcg_cool_nightly" started for user "lcg_cool". Connection Id=baab43e4-8418-11dd-8d94-001617c3b642
+CORAL/Services/ConnectionService     Debug     A New connection to service "lcg_cool_nightly" has been added in the active list. Id=baab43e4-8418-11dd-8d94-001617c3b642
+RelationalDatabase                   Info     Instantiate a R/W RalDatabase for 'oracle://lcg_cool_nightly;schema=lcg_cool;dbname=COOLTEST'
+RelationalQueryMgr                   Debug    Instantiate a RelationalQueryMgr
+RelationalQueryMgr                   Debug    Instantiate a RalQueryMgr
+RelationalSequenceMgr                Debug    Instantiate a RelationalSequenceMgr
+RelationalSequenceMgr                Debug    Instantiate a RalSequenceMgr
+RelationalSchemaMgr                  Debug    Instantiate a RelationalSchemaMgr
+RelationalSchemaMgr                  Debug    Instantiate a RalSchemaMgr
+RelationalNodeMgr                    Debug    Instantiate a RelationalNodeMgr
+RelationalTagMgr                     Debug    Instantiate a RelationalTagMgr
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "DB_ATTRIBUTE_NAME", "DB_ATTRIBUTE_VALUE" FROM LCG_COOL."COOLTEST_DB_ATTRIBUTES" "COOLTEST_DB_ATTRIBUTES""
+RelationalQueryMgr                   Debug    Successfully fetched 10 table rows
+RelationalDatabase                   Debug    Release number match: database with CURRENT release number 2.6.0 will be opened using CURRENT client release number 2.6.0
+RalPrivilegeManager                  Debug    Instantiate a RalPrivilegeManager for 'oracle://lcg_cool_nightly;schema=lcg_cool;dbname=COOLTEST'
+REVOKE 'TAGGER' privileges from user PUBLIC
+RelationalNodeMgr                    Debug    Fetch all nodes in the database
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" ORDER BY "NODE_FULLPATH" DESC"
+RelationalQueryMgr                   Debug    Successfully fetched 11 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/UcharSpec/uc
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolder                     Debug    Instantiate a RelationalFolder for '/UcharSpec/uc'
+RelationalFolder                     Debug    Delete the RelationalFolder for '/UcharSpec/uc'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/UcharSpec/uc
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/UcharSpec
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/UcharSpec
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolderSet                  Debug    Instantiate a RelationalFolderSet for '/UcharSpec'
+RelationalFolderSet                  Debug    Delete the RelationalFolderSet for '/UcharSpec'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/SV/sv1
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolder                     Debug    Instantiate a RelationalFolder for '/SimpleSpec/SV/sv1'
+RelationalFolder                     Debug    Delete the RelationalFolder for '/SimpleSpec/SV/sv1'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/SV/sv1
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/SV
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/SV
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolderSet                  Debug    Instantiate a RelationalFolderSet for '/SimpleSpec/SV'
+RelationalFolderSet                  Debug    Delete the RelationalFolderSet for '/SimpleSpec/SV'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/MV/mv2
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolder                     Debug    Instantiate a RelationalFolder for '/SimpleSpec/MV/mv2'
+RelationalFolder                     Debug    Delete the RelationalFolder for '/SimpleSpec/MV/mv2'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/MV/mv2
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/MV/mv1
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolder                     Debug    Instantiate a RelationalFolder for '/SimpleSpec/MV/mv1'
+RelationalFolder                     Debug    Delete the RelationalFolder for '/SimpleSpec/MV/mv1'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/MV/mv1
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/MV
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/MV
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolderSet                  Debug    Instantiate a RelationalFolderSet for '/SimpleSpec/MV'
+RelationalFolderSet                  Debug    Delete the RelationalFolderSet for '/SimpleSpec/MV'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolderSet                  Debug    Instantiate a RelationalFolderSet for '/SimpleSpec'
+RelationalFolderSet                  Debug    Delete the RelationalFolderSet for '/SimpleSpec'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/ReferenceSpec/ref
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolder                     Debug    Instantiate a RelationalFolder for '/ReferenceSpec/ref'
+RelationalFolder                     Debug    Delete the RelationalFolder for '/ReferenceSpec/ref'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/ReferenceSpec/ref
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/ReferenceSpec
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/ReferenceSpec
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolderSet                  Debug    Instantiate a RelationalFolderSet for '/ReferenceSpec'
+RelationalFolderSet                  Debug    Delete the RelationalFolderSet for '/ReferenceSpec'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolderSet                  Debug    Instantiate a RelationalFolderSet for '/'
+RelationalFolderSet                  Debug    Delete the RelationalFolderSet for '/'
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "REVOKE INSERT ON LCG_COOL."COOLTEST_TAGS" FROM PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "REVOKE INSERT ON LCG_COOL."COOLTEST_TAG2TAG" FROM PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "REVOKE INSERT ON LCG_COOL."COOLTEST_F0009_TAGS" FROM PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "REVOKE INSERT ON LCG_COOL."COOLTEST_F0009_IOV2TAG" FROM PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "REVOKE INSERT ON LCG_COOL."COOLTEST_F0008_TAGS" FROM PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "REVOKE INSERT ON LCG_COOL."COOLTEST_F0008_IOV2TAG" FROM PUBLIC"
+RelationalNodeMgr                    Debug    Fetch all nodes in the database
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" ORDER BY "NODE_FULLPATH" DESC"
+RelationalQueryMgr                   Debug    Successfully fetched 11 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/UcharSpec/uc
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolder                     Debug    Instantiate a RelationalFolder for '/UcharSpec/uc'
+RelationalFolder                     Debug    Delete the RelationalFolder for '/UcharSpec/uc'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/UcharSpec/uc
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/UcharSpec
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/UcharSpec
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolderSet                  Debug    Instantiate a RelationalFolderSet for '/UcharSpec'
+RelationalFolderSet                  Debug    Delete the RelationalFolderSet for '/UcharSpec'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/SV/sv1
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolder                     Debug    Instantiate a RelationalFolder for '/SimpleSpec/SV/sv1'
+RelationalFolder                     Debug    Delete the RelationalFolder for '/SimpleSpec/SV/sv1'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/SV/sv1
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/SV
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/SV
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolderSet                  Debug    Instantiate a RelationalFolderSet for '/SimpleSpec/SV'
+RelationalFolderSet                  Debug    Delete the RelationalFolderSet for '/SimpleSpec/SV'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/MV/mv2
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolder                     Debug    Instantiate a RelationalFolder for '/SimpleSpec/MV/mv2'
+RelationalFolder                     Debug    Delete the RelationalFolder for '/SimpleSpec/MV/mv2'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/MV/mv2
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/MV/mv1
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolder                     Debug    Instantiate a RelationalFolder for '/SimpleSpec/MV/mv1'
+RelationalFolder                     Debug    Delete the RelationalFolder for '/SimpleSpec/MV/mv1'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/MV/mv1
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/MV
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/MV
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolderSet                  Debug    Instantiate a RelationalFolderSet for '/SimpleSpec/MV'
+RelationalFolderSet                  Debug    Delete the RelationalFolderSet for '/SimpleSpec/MV'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolderSet                  Debug    Instantiate a RelationalFolderSet for '/SimpleSpec'
+RelationalFolderSet                  Debug    Delete the RelationalFolderSet for '/SimpleSpec'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/ReferenceSpec/ref
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolder                     Debug    Instantiate a RelationalFolder for '/ReferenceSpec/ref'
+RelationalFolder                     Debug    Delete the RelationalFolder for '/ReferenceSpec/ref'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/ReferenceSpec/ref
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/ReferenceSpec
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/ReferenceSpec
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolderSet                  Debug    Instantiate a RelationalFolderSet for '/ReferenceSpec'
+RelationalFolderSet                  Debug    Delete the RelationalFolderSet for '/ReferenceSpec'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolderSet                  Debug    Instantiate a RelationalFolderSet for '/'
+RelationalFolderSet                  Debug    Delete the RelationalFolderSet for '/'
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "REVOKE UPDATE ON LCG_COOL."COOLTEST_TAGS_SEQ" FROM PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "REVOKE UPDATE ON LCG_COOL."COOLTEST_TAG2TAG_SEQ" FROM PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "REVOKE UPDATE ON LCG_COOL."COOLTEST_F0005_TAGS_SEQ" FROM PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "REVOKE UPDATE ON LCG_COOL."COOLTEST_F0003_TAGS_SEQ" FROM PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "REVOKE UPDATE ON LCG_COOL."COOLTEST_F0009_TAGS_SEQ" FROM PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "REVOKE UPDATE ON LCG_COOL."COOLTEST_F0008_TAGS_SEQ" FROM PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "REVOKE UPDATE ON LCG_COOL."COOLTEST_F0004_TAGS_SEQ" FROM PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "REVOKE UPDATE ON LCG_COOL."COOLTEST_F0002_TAGS_SEQ" FROM PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "REVOKE UPDATE ON LCG_COOL."COOLTEST_F0001_TAGS_SEQ" FROM PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "REVOKE UPDATE ON LCG_COOL."COOLTEST_F0000_TAGS_SEQ" FROM PUBLIC"
+RelationalNodeMgr                    Debug    Fetch all nodes in the database
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" ORDER BY "NODE_FULLPATH" DESC"
+RelationalQueryMgr                   Debug    Successfully fetched 11 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/UcharSpec/uc
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolder                     Debug    Instantiate a RelationalFolder for '/UcharSpec/uc'
+RelationalFolder                     Debug    Delete the RelationalFolder for '/UcharSpec/uc'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/UcharSpec/uc
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/UcharSpec
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/UcharSpec
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolderSet                  Debug    Instantiate a RelationalFolderSet for '/UcharSpec'
+RelationalFolderSet                  Debug    Delete the RelationalFolderSet for '/UcharSpec'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/SV/sv1
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolder                     Debug    Instantiate a RelationalFolder for '/SimpleSpec/SV/sv1'
+RelationalFolder                     Debug    Delete the RelationalFolder for '/SimpleSpec/SV/sv1'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/SV/sv1
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/SV
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/SV
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolderSet                  Debug    Instantiate a RelationalFolderSet for '/SimpleSpec/SV'
+RelationalFolderSet                  Debug    Delete the RelationalFolderSet for '/SimpleSpec/SV'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/MV/mv2
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolder                     Debug    Instantiate a RelationalFolder for '/SimpleSpec/MV/mv2'
+RelationalFolder                     Debug    Delete the RelationalFolder for '/SimpleSpec/MV/mv2'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/MV/mv2
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/MV/mv1
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolder                     Debug    Instantiate a RelationalFolder for '/SimpleSpec/MV/mv1'
+RelationalFolder                     Debug    Delete the RelationalFolder for '/SimpleSpec/MV/mv1'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/MV/mv1
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/MV
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/MV
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolderSet                  Debug    Instantiate a RelationalFolderSet for '/SimpleSpec/MV'
+RelationalFolderSet                  Debug    Delete the RelationalFolderSet for '/SimpleSpec/MV'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolderSet                  Debug    Instantiate a RelationalFolderSet for '/SimpleSpec'
+RelationalFolderSet                  Debug    Delete the RelationalFolderSet for '/SimpleSpec'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/ReferenceSpec/ref
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolder                     Debug    Instantiate a RelationalFolder for '/ReferenceSpec/ref'
+RelationalFolder                     Debug    Delete the RelationalFolder for '/ReferenceSpec/ref'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/ReferenceSpec/ref
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/ReferenceSpec
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/ReferenceSpec
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolderSet                  Debug    Instantiate a RelationalFolderSet for '/ReferenceSpec'
+RelationalFolderSet                  Debug    Delete the RelationalFolderSet for '/ReferenceSpec'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolderSet                  Debug    Instantiate a RelationalFolderSet for '/'
+RelationalFolderSet                  Debug    Delete the RelationalFolderSet for '/'
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "REVOKE DELETE ON LCG_COOL."COOLTEST_TAGS" FROM PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "REVOKE DELETE ON LCG_COOL."COOLTEST_TAG2TAG" FROM PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "REVOKE DELETE ON LCG_COOL."COOLTEST_F0009_TAGS" FROM PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "REVOKE DELETE ON LCG_COOL."COOLTEST_F0009_IOV2TAG" FROM PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "REVOKE DELETE ON LCG_COOL."COOLTEST_F0008_TAGS" FROM PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "REVOKE DELETE ON LCG_COOL."COOLTEST_F0008_IOV2TAG" FROM PUBLIC"
+RalPrivilegeManager                  Debug    Delete the RalPrivilegeManager for 'oracle://lcg_cool_nightly;schema=lcg_cool;dbname=COOLTEST'
+RelationalDatabase                   Info     Delete the RalDatabase for 'oracle://lcg_cool_nightly;schema=lcg_cool;dbname=COOLTEST'
+RelationalDatabase                   Debug    Delete the RelationalDatabase for 'oracle://lcg_cool_nightly;schema=lcg_cool;dbname=COOLTEST'
+RelationalTagMgr                     Debug    Delete the RelationalTagMgr
+RelationalNodeMgr                    Debug    Delete the RelationalNodeMgr
+RelationalSchemaMgr                  Debug    Delete the RalSchemaMgr
+RelationalSchemaMgr                  Debug    Delete the RelationalSchemaMgr
+RelationalQueryMgr                   Debug    Delete the RalQueryMgr
+RelationalSequenceMgr                Debug    Delete the RalSequenceMgr
+RelationalSequenceMgr                Debug    Delete the RelationalSequenceMgr
+RalSessionMgr                        Info     Delete the RalSessionMgr for 'oracle://lcg_cool_nightly;schema=lcg_cool;dbname=COOLTEST'
+RalSessionMgr                        Info     Disconnect from the database server
+CORAL/Services/ConnectionService     Debug    Connection id=baab43e4-8418-11dd-8d94-001617c3b642 to service "lcg_cool_nightly" has 0 session(s) opended.
+CORAL/Services/ConnectionService     Debug    The active connection id=baab43e4-8418-11dd-8d94-001617c3b642 to service "lcg_cool_nightly" has been removed from the active list.
+RelationalQueryMgr                   Debug    Delete the RelationalQueryMgr
+CoralApplication                     Info     Delete the COOL CoralApplication...
+CoralApplication                     Info     Delete the COOL database service
+RalDatabaseSvc                       Info     Delete the RalDatabaseSvc...
+RalDatabaseSvc                       Info     Purge the connection pool
+RalDatabaseSvc                       Info     Reset the ICS pointer
+RalDatabaseSvc                       Info     Delete the RalDatabaseSvc... DONE
+CoralApplication                     Info     Delete the CORAL connection service
+CoralApplication                     Info     Delete the COOL CoralApplication... DONE
diff --git a/RelationalCool/utilities/coolPrivileges/logs/revokeWriter.txt b/RelationalCool/utilities/coolPrivileges/logs/revokeWriter.txt
new file mode 100644
index 000000000..8f8b66c0b
--- /dev/null
+++ b/RelationalCool/utilities/coolPrivileges/logs/revokeWriter.txt
@@ -0,0 +1,195 @@
+CoralApplication                     Info     Create a cool::CoralApplication...
+CoralApplication                     Info     Enable the COOL signal handler
+CoralApplication                     Info     Create a new own CORAL connection service
+CoralApplication                     Info     Create the COOL database service
+RalDatabaseSvc                       Info     Instantiate the RalDatabaseSvc
+CoralApplication                     Info     Create a cool::CoralApplication... DONE
+RelationalDatabase                   Debug    Instantiate a RelationalDatabase for 'oracle://lcg_cool_nightly;schema=lcg_cool;dbname=COOLTEST'
+RalSessionMgr                        Info     Instantiate a R/W RalSessionMgr for 'oracle://lcg_cool_nightly;schema=lcg_cool;dbname=COOLTEST'
+RalSessionMgr                        Info     Connect to the database server
+PluginManager                        Info     PluginManager creating CORAL/Services/ConnectionService component
+PluginManager                        Info     PluginMaager needs to load CORAL/Services/ConnectionService component
+PluginManager                        Info     PluginManager loaded ConnectionService library
+CORAL/Services/ConnectionService     Info     Loading default plugin for coral::IRelationalService: CORAL/Services/RelationalService
+PluginManager                        Info     PluginManager creating CORAL/Services/RelationalService component
+PluginManager                        Info     PluginMaager needs to load CORAL/Services/RelationalService component
+PluginManager                        Info     PluginManager loaded RelationalService library
+CORAL/Services/RelationalService     Info     Found plugin for RDBMS technology "coral" with native implementation
+CORAL/Services/RelationalService     Info     Found plugin for RDBMS technology "frontier" with native implementation
+CORAL/Services/RelationalService     Info     Found plugin for RDBMS technology "mysql" with native implementation
+CORAL/Services/RelationalService     Info     Found plugin for RDBMS technology "oracle" with native implementation
+CORAL/Services/RelationalService     Info     Found plugin for RDBMS technology "sqlite" with native implementation
+CORAL/Services/RelationalService     Info     Default implementation for RDBMS technology "coral" is native
+CORAL/Services/RelationalService     Info     Default implementation for RDBMS technology "frontier" is native
+CORAL/Services/RelationalService     Info     Default implementation for RDBMS technology "mysql" is native
+CORAL/Services/RelationalService     Info     Default implementation for RDBMS technology "oracle" is native
+CORAL/Services/RelationalService     Info     Default implementation for RDBMS technology "sqlite" is native
+PluginManager                        Info     PluginManager creating CORAL/RelationalPlugins/oracle component
+PluginManager                        Info     PluginMaager needs to load CORAL/RelationalPlugins/oracle component
+PluginManager                        Info     PluginManager loaded OracleAccess library
+CORAL/Services/ConnectionService     Info     Loading default plugin for coral::IAuthenticationService: CORAL/Services/XMLAuthenticationService
+PluginManager                        Info     PluginManager creating CORAL/Services/XMLAuthenticationService component
+PluginManager                        Info     PluginMaager needs to load CORAL/Services/XMLAuthenticationService component
+PluginManager                        Info     PluginManager loaded XMLAuthenticationService library
+CORAL/Services/XMLAuthenticationS... Info     Authentication using /afs/cern.ch/user/a/avalassi/private/authentication.xml file
+CORAL/Services/ConnectionService     Debug    No valid connection for string "oracle://lcg_cool_nightly/lcg_cool" found in the pool. Creating a new connection.
+CORAL/Services/ConnectionService     Debug    Trying to get a new update session on "oracle://lcg_cool_nightly/lcg_cool"
+CORAL/Services/ConnectionService     Debug    Connection parameters are: Retry-Period=10sec, Retry-Timeout=60sec, Connection-Timeout=0sec.
+CORAL/Services/ConnectionService     Info      Connection to service "lcg_cool_nightly" established. Id=bcec47ac-8418-11dd-8186-001617c3b642
+CORAL/Services/ConnectionService     Info     New session on connection to service "lcg_cool_nightly" started for user "lcg_cool". Connection Id=bcec47ac-8418-11dd-8186-001617c3b642
+CORAL/Services/ConnectionService     Debug     A New connection to service "lcg_cool_nightly" has been added in the active list. Id=bcec47ac-8418-11dd-8186-001617c3b642
+RelationalDatabase                   Info     Instantiate a R/W RalDatabase for 'oracle://lcg_cool_nightly;schema=lcg_cool;dbname=COOLTEST'
+RelationalQueryMgr                   Debug    Instantiate a RelationalQueryMgr
+RelationalQueryMgr                   Debug    Instantiate a RalQueryMgr
+RelationalSequenceMgr                Debug    Instantiate a RelationalSequenceMgr
+RelationalSequenceMgr                Debug    Instantiate a RalSequenceMgr
+RelationalSchemaMgr                  Debug    Instantiate a RelationalSchemaMgr
+RelationalSchemaMgr                  Debug    Instantiate a RalSchemaMgr
+RelationalNodeMgr                    Debug    Instantiate a RelationalNodeMgr
+RelationalTagMgr                     Debug    Instantiate a RelationalTagMgr
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "DB_ATTRIBUTE_NAME", "DB_ATTRIBUTE_VALUE" FROM LCG_COOL."COOLTEST_DB_ATTRIBUTES" "COOLTEST_DB_ATTRIBUTES""
+RelationalQueryMgr                   Debug    Successfully fetched 10 table rows
+RelationalDatabase                   Debug    Release number match: database with CURRENT release number 2.6.0 will be opened using CURRENT client release number 2.6.0
+RalPrivilegeManager                  Debug    Instantiate a RalPrivilegeManager for 'oracle://lcg_cool_nightly;schema=lcg_cool;dbname=COOLTEST'
+REVOKE 'WRITER' privileges from user PUBLIC
+RelationalNodeMgr                    Debug    Fetch all nodes in the database
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" ORDER BY "NODE_FULLPATH" DESC"
+RelationalQueryMgr                   Debug    Successfully fetched 11 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/UcharSpec/uc
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolder                     Debug    Instantiate a RelationalFolder for '/UcharSpec/uc'
+RelationalFolder                     Debug    Delete the RelationalFolder for '/UcharSpec/uc'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/UcharSpec
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/SV/sv1
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolder                     Debug    Instantiate a RelationalFolder for '/SimpleSpec/SV/sv1'
+RelationalFolder                     Debug    Delete the RelationalFolder for '/SimpleSpec/SV/sv1'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/SV
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/MV/mv2
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolder                     Debug    Instantiate a RelationalFolder for '/SimpleSpec/MV/mv2'
+RelationalFolder                     Debug    Delete the RelationalFolder for '/SimpleSpec/MV/mv2'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/MV/mv1
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolder                     Debug    Instantiate a RelationalFolder for '/SimpleSpec/MV/mv1'
+RelationalFolder                     Debug    Delete the RelationalFolder for '/SimpleSpec/MV/mv1'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/MV
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/ReferenceSpec/ref
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolder                     Debug    Instantiate a RelationalFolder for '/ReferenceSpec/ref'
+RelationalFolder                     Debug    Delete the RelationalFolder for '/ReferenceSpec/ref'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/ReferenceSpec
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "REVOKE INSERT ON LCG_COOL."COOLTEST_F0010_IOVS" FROM PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "REVOKE INSERT ON LCG_COOL."COOLTEST_F0010_CHANNELS" FROM PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "REVOKE INSERT ON LCG_COOL."COOLTEST_F0007_IOVS" FROM PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "REVOKE INSERT ON LCG_COOL."COOLTEST_F0007_CHANNELS" FROM PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "REVOKE INSERT ON LCG_COOL."COOLTEST_F0009_IOVS" FROM PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "REVOKE INSERT ON LCG_COOL."COOLTEST_F0009_CHANNELS" FROM PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "REVOKE INSERT ON LCG_COOL."COOLTEST_F0008_IOVS" FROM PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "REVOKE INSERT ON LCG_COOL."COOLTEST_F0008_CHANNELS" FROM PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "REVOKE INSERT ON LCG_COOL."COOLTEST_F0006_IOVS" FROM PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "REVOKE INSERT ON LCG_COOL."COOLTEST_F0006_CHANNELS" FROM PUBLIC"
+RelationalNodeMgr                    Debug    Fetch all nodes in the database
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" ORDER BY "NODE_FULLPATH" DESC"
+RelationalQueryMgr                   Debug    Successfully fetched 11 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/UcharSpec/uc
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolder                     Debug    Instantiate a RelationalFolder for '/UcharSpec/uc'
+RelationalFolder                     Debug    Delete the RelationalFolder for '/UcharSpec/uc'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/UcharSpec
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/SV/sv1
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolder                     Debug    Instantiate a RelationalFolder for '/SimpleSpec/SV/sv1'
+RelationalFolder                     Debug    Delete the RelationalFolder for '/SimpleSpec/SV/sv1'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/SV
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/MV/mv2
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolder                     Debug    Instantiate a RelationalFolder for '/SimpleSpec/MV/mv2'
+RelationalFolder                     Debug    Delete the RelationalFolder for '/SimpleSpec/MV/mv2'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/MV/mv1
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolder                     Debug    Instantiate a RelationalFolder for '/SimpleSpec/MV/mv1'
+RelationalFolder                     Debug    Delete the RelationalFolder for '/SimpleSpec/MV/mv1'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec/MV
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/SimpleSpec
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/ReferenceSpec/ref
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalFolder                     Debug    Instantiate a RelationalFolder for '/ReferenceSpec/ref'
+RelationalFolder                     Debug    Delete the RelationalFolder for '/ReferenceSpec/ref'
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/ReferenceSpec
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+RelationalNodeMgr                    Debug    Fetch table row for folder[set] with fullPath=/
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "SELECT "NODE_ID", "NODE_PARENTID", "NODE_NAME", "NODE_FULLPATH", "NODE_DESCRIPTION", "NODE_ISLEAF", "NODE_SCHEMA_VERSION", "NODE_INSTIME", "LASTMOD_DATE", "FOLDER_VERSIONING", "FOLDER_PAYLOADSPEC", "FOLDER_PAYLOAD_INLINE", "FOLDER_PAYLOAD_EXTREF", "FOLDER_CHANNELSPEC", "FOLDER_CHANNEL_EXTREF", "FOLDER_IOVTABLENAME", "FOLDER_TAGTABLENAME", "FOLDER_IOV2TAGTABLENAME", "FOLDER_CHANNELTABLENAME" FROM LCG_COOL."COOLTEST_NODES" "COOLTEST_NODES" WHERE "NODE_FULLPATH"= :"fullName""
+RelationalQueryMgr                   Debug    Successfully fetched 1 table rows
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "REVOKE UPDATE ON LCG_COOL."COOLTEST_IOVS_SEQ" FROM PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "REVOKE UPDATE ON LCG_COOL."COOLTEST_F0010_IOVS" FROM PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "REVOKE UPDATE ON LCG_COOL."COOLTEST_F0010_IOVS_SEQ" FROM PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "REVOKE UPDATE ON LCG_COOL."COOLTEST_F0010_CHANNELS" FROM PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "REVOKE UPDATE ON LCG_COOL."COOLTEST_F0007_IOVS" FROM PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "REVOKE UPDATE ON LCG_COOL."COOLTEST_F0007_IOVS_SEQ" FROM PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "REVOKE UPDATE ON LCG_COOL."COOLTEST_F0007_CHANNELS" FROM PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "REVOKE UPDATE ON LCG_COOL."COOLTEST_F0009_IOVS" FROM PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "REVOKE UPDATE ON LCG_COOL."COOLTEST_F0009_IOVS_SEQ" FROM PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "REVOKE UPDATE ON LCG_COOL."COOLTEST_F0009_CHANNELS" FROM PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "REVOKE UPDATE ON LCG_COOL."COOLTEST_F0008_IOVS" FROM PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "REVOKE UPDATE ON LCG_COOL."COOLTEST_F0008_IOVS_SEQ" FROM PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "REVOKE UPDATE ON LCG_COOL."COOLTEST_F0008_CHANNELS" FROM PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "REVOKE UPDATE ON LCG_COOL."COOLTEST_F0006_IOVS" FROM PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "REVOKE UPDATE ON LCG_COOL."COOLTEST_F0006_IOVS_SEQ" FROM PUBLIC"
+CORAL/RelationalPlugins/oracle       Debug    Prepared statement : "REVOKE UPDATE ON LCG_COOL."COOLTEST_F0006_CHANNELS" FROM PUBLIC"
+RalPrivilegeManager                  Debug    Delete the RalPrivilegeManager for 'oracle://lcg_cool_nightly;schema=lcg_cool;dbname=COOLTEST'
+RelationalDatabase                   Info     Delete the RalDatabase for 'oracle://lcg_cool_nightly;schema=lcg_cool;dbname=COOLTEST'
+RelationalDatabase                   Debug    Delete the RelationalDatabase for 'oracle://lcg_cool_nightly;schema=lcg_cool;dbname=COOLTEST'
+RelationalTagMgr                     Debug    Delete the RelationalTagMgr
+RelationalNodeMgr                    Debug    Delete the RelationalNodeMgr
+RelationalSchemaMgr                  Debug    Delete the RalSchemaMgr
+RelationalSchemaMgr                  Debug    Delete the RelationalSchemaMgr
+RelationalQueryMgr                   Debug    Delete the RalQueryMgr
+RelationalSequenceMgr                Debug    Delete the RalSequenceMgr
+RelationalSequenceMgr                Debug    Delete the RelationalSequenceMgr
+RalSessionMgr                        Info     Delete the RalSessionMgr for 'oracle://lcg_cool_nightly;schema=lcg_cool;dbname=COOLTEST'
+RalSessionMgr                        Info     Disconnect from the database server
+CORAL/Services/ConnectionService     Debug    Connection id=bcec47ac-8418-11dd-8186-001617c3b642 to service "lcg_cool_nightly" has 0 session(s) opended.
+CORAL/Services/ConnectionService     Debug    The active connection id=bcec47ac-8418-11dd-8186-001617c3b642 to service "lcg_cool_nightly" has been removed from the active list.
+RelationalQueryMgr                   Debug    Delete the RelationalQueryMgr
+CoralApplication                     Info     Delete the COOL CoralApplication...
+CoralApplication                     Info     Delete the COOL database service
+RalDatabaseSvc                       Info     Delete the RalDatabaseSvc...
+RalDatabaseSvc                       Info     Purge the connection pool
+RalDatabaseSvc                       Info     Reset the ICS pointer
+RalDatabaseSvc                       Info     Delete the RalDatabaseSvc... DONE
+CoralApplication                     Info     Delete the CORAL connection service
+CoralApplication                     Info     Delete the COOL CoralApplication... DONE
diff --git a/RelationalCool/utilities/coolPrivileges/logs/showTables.txt b/RelationalCool/utilities/coolPrivileges/logs/showTables.txt
new file mode 100644
index 000000000..9ac1e0572
--- /dev/null
+++ b/RelationalCool/utilities/coolPrivileges/logs/showTables.txt
@@ -0,0 +1,35 @@
+COOLTEST_TAGS_SEQ
+COOLTEST_TAGS
+COOLTEST_TAG2TAG_SEQ
+COOLTEST_TAG2TAG
+COOLTEST_NODES_SEQ
+COOLTEST_NODES
+COOLTEST_IOVS_SEQ
+COOLTEST_F0010_IOVS_SEQ
+COOLTEST_F0010_IOVS
+COOLTEST_F0010_CHANNELS
+COOLTEST_F0009_TAGS_SEQ
+COOLTEST_F0009_TAGS
+COOLTEST_F0009_IOVS_SEQ
+COOLTEST_F0009_IOVS
+COOLTEST_F0009_IOV2TAG
+COOLTEST_F0009_CHANNELS
+COOLTEST_F0008_TAGS_SEQ
+COOLTEST_F0008_TAGS
+COOLTEST_F0008_IOVS_SEQ
+COOLTEST_F0008_IOVS
+COOLTEST_F0008_IOV2TAG
+COOLTEST_F0008_CHANNELS
+COOLTEST_F0007_IOVS_SEQ
+COOLTEST_F0007_IOVS
+COOLTEST_F0007_CHANNELS
+COOLTEST_F0006_IOVS_SEQ
+COOLTEST_F0006_IOVS
+COOLTEST_F0006_CHANNELS
+COOLTEST_F0005_TAGS_SEQ
+COOLTEST_F0004_TAGS_SEQ
+COOLTEST_F0003_TAGS_SEQ
+COOLTEST_F0002_TAGS_SEQ
+COOLTEST_F0001_TAGS_SEQ
+COOLTEST_F0000_TAGS_SEQ
+COOLTEST_DB_ATTRIBUTES
diff --git a/RelationalCool/utilities/coolReplicateDB/Replication.cpp b/RelationalCool/utilities/coolReplicateDB/Replication.cpp
new file mode 100644
index 000000000..767c10ec7
--- /dev/null
+++ b/RelationalCool/utilities/coolReplicateDB/Replication.cpp
@@ -0,0 +1,1038 @@
+// $Id: Replication.cpp,v 1.42 2008-09-01 16:38:12 avalassi Exp $
+
+// Include files 
+#include <iostream>
+#include "CoralBase/Attribute.h"
+#include "CoralBase/AttributeList.h"
+#include "CoralBase/AttributeListException.h"
+#include "CoolKernel/Exception.h"
+#include "CoolKernel/IDatabaseSvc.h"
+#include "CoolKernel/Record.h"
+#include "RelationalAccess/IBulkOperation.h"
+#include "RelationalAccess/IConnectionServiceConfiguration.h"
+#include "RelationalAccess/IColumn.h"
+#include "RelationalAccess/IQuery.h"
+#include "RelationalAccess/ISchema.h"
+#include "RelationalAccess/ISessionProxy.h"
+#include "RelationalAccess/ITable.h"
+#include "RelationalAccess/ITableDataEditor.h"
+#include "RelationalAccess/ITableDescription.h"
+#include "RelationalAccess/TableDescription.h"
+#include "RelationalAccess/ITransaction.h"
+
+// Local include files
+#include "Replication.h"
+#include "../../src/RalDatabase.h"
+#include "../../src/RalQueryMgr.h"
+#include "../../src/RelationalChannelTable.h"
+#include "../../src/RelationalDatabaseTable.h"
+#include "../../src/RelationalFolder.h"
+#include "../../src/RelationalGlobalTagTable.h"
+#include "../../src/RelationalNodeMgr.h"
+#include "../../src/RelationalNodeTable.h"
+#include "../../src/RelationalObject2TagTable.h"
+#include "../../src/RelationalObjectMgr.h"
+#include "../../src/RelationalObjectTable.h"
+#include "../../src/RelationalObjectTableRow.h"
+#include "../../src/RelationalQueryMgr.h"
+#include "../../src/RelationalSequence.h"
+#include "../../src/RelationalSequenceMgr.h"
+#include "../../src/RelationalSchemaMgr.h"
+#include "../../src/RelationalTag2TagTable.h"
+#include "../../src/RelationalTagTable.h"
+#include "../../src/RelationalTransaction.h"
+#include "../../src/sleep.h"
+
+using namespace cool;
+
+// Message output
+#define LOG std::cout
+
+// Local type definitions
+typedef boost::shared_ptr<RelationalSequence> RelationalSequencePtr;
+
+//---------------------------------------------------------------------------
+
+Replication::Replication()
+  : CoralApplication() 
+{
+  
+  // Disable CORAL automatic pool clean up thread 
+  coral::IConnectionServiceConfiguration &connSvcConf =
+    connectionSvc().configuration();
+  
+  // If we can access a LFC and the user is not explicitely forbidding it,
+  // we try to use CORAL LFCReplicaService
+  if ( ::getenv("COOL_IGNORE_LFC") == NULL &&
+       ::getenv("LFC_HOST") != NULL ) {
+    // use CORAL LFCReplicaService
+    connSvcConf.setAuthenticationService("CORAL/Services/LFCReplicaService");
+    connSvcConf.setLookupService("CORAL/Services/LFCReplicaService");
+  }
+    
+  connSvcConf.disablePoolAutomaticCleanUp();
+  connSvcConf.setConnectionTimeOut( 0 );
+     
+}
+
+//---------------------------------------------------------------------------
+
+std::vector<RelationalTableRow> 
+Replication::newNodeTableRows( const RalDatabase& db, 
+                               const std::string& lastUpdate ) 
+{
+  coral::AttributeList whereData;
+  whereData.extend
+    ( "lastUpdate",
+      typeIdToCoralType
+      ( RelationalNodeTable::columnTypeIds::nodeInsertionTime ) );
+  whereData["lastUpdate"].setValue( lastUpdate );
+  std::string whereClause = 
+  RelationalNodeTable::columnNames::nodeInsertionTime + " > :lastUpdate";
+  
+  std::vector<std::string> orderBy;
+  std::string orderClause = RelationalNodeTable::columnNames::nodeId;
+  orderBy.push_back( orderClause );
+  std::string desc = "";
+
+  std::vector<RelationalTableRow> rows =
+    db.queryMgr().fetchOrderedRowsFromTables
+    ( RelationalQueryMgr::tableList( db.nodeTableName() ), 
+      RelationalQueryMgr::columnList
+      ( RelationalNodeTable::tableSpecification() ),
+      whereClause, whereData, orderBy, desc );
+  
+  return rows;
+}
+
+//---------------------------------------------------------------------------
+
+std::vector<RelationalTableRow> 
+Replication::modifiedNodeTableRows( const RalDatabase& db, 
+                                    const std::string& lastUpdate ) 
+{
+  coral::AttributeList whereData;
+  whereData.extend
+    ( "lastUpdate",
+      typeIdToCoralType
+      ( RelationalNodeTable::columnTypeIds::lastModDate ) );
+  whereData["lastUpdate"].setValue( lastUpdate );
+  std::string whereClause = 
+    RelationalNodeTable::columnNames::lastModDate + " > :lastUpdate"
+    + " and "
+    + RelationalNodeTable::columnNames::lastModDate + " > "
+    + RelationalNodeTable::columnNames::nodeInsertionTime;
+  
+  std::vector<std::string> orderBy;
+  std::string orderClause = RelationalNodeTable::columnNames::nodeId;
+  orderBy.push_back( orderClause );
+  std::string desc = "";
+  
+  std::vector<RelationalTableRow> rows =
+    db.queryMgr().fetchOrderedRowsFromTables
+    ( RelationalQueryMgr::tableList( db.nodeTableName() ), 
+      RelationalQueryMgr::columnList
+      ( RelationalNodeTable::tableSpecification() ),
+      whereClause, whereData, orderBy, desc );
+  
+  return rows;
+}
+
+//---------------------------------------------------------------------------
+
+std::vector<RelationalTableRow> 
+Replication::fetchNodeTableRows( const RalDatabase& db, bool isLeaf ) 
+{
+  coral::AttributeList whereData;
+  whereData.extend
+    ( "isLeaf",
+      typeIdToCoralType
+      ( RelationalNodeTable::columnTypeIds::nodeIsLeaf ) );
+  whereData["isLeaf"].setValue( isLeaf );
+  std::string whereClause = 
+    RelationalNodeTable::columnNames::nodeIsLeaf + " = :isLeaf";
+  
+  std::vector<std::string> orderBy;
+  std::string orderClause = RelationalNodeTable::columnNames::nodeId;
+  orderBy.push_back( orderClause );
+  std::string desc = "";
+  
+  std::vector<RelationalTableRow> rows =
+    db.queryMgr().fetchOrderedRowsFromTables
+    ( RelationalQueryMgr::tableList( db.nodeTableName() ), 
+      RelationalQueryMgr::columnList
+      ( RelationalNodeTable::tableSpecification() ),
+      whereClause, whereData, orderBy, desc );
+  
+  return rows;
+}
+
+//---------------------------------------------------------------------------
+
+boost::shared_ptr<CursorHandle> 
+Replication::newObjectTableRows( const RalDatabase& db,
+                                 const RelationalFolder& folder, 
+                                 const std::string& lastUpdate ) 
+{
+  coral::AttributeList whereData;
+  whereData.extend
+    ( "lastUpdate",
+      typeIdToCoralType
+      ( RelationalObjectTable::columnTypeIds::sysInsTime ) );
+  whereData["lastUpdate"].setValue( lastUpdate );
+  std::string whereClause = 
+    RelationalObjectTable::columnNames::sysInsTime() + " > :lastUpdate";
+  
+  std::vector<std::string> orderBy;
+  std::string orderClause = RelationalObjectTable::columnNames::objectId();
+  orderBy.push_back( orderClause );
+  
+  std::auto_ptr<RalQueryMgr> queryMgr( new RalQueryMgr( db.sessionMgr() ) );
+  boost::shared_ptr<coral::AttributeList> dataBuffer;
+  std::auto_ptr<coral::IQuery> query =
+    queryMgr->prepareQuery
+    ( RelationalQueryMgr::tableList( folder.objectTableName() ),
+      RelationalQueryMgr::columnList
+      ( RelationalObjectTable::tableSpecification
+        ( folder.payloadSpecification() ) ),
+      whereClause, whereData, orderBy, dataBuffer );
+  return boost::shared_ptr<CursorHandle>( new CursorHandle( query,
+                                                            dataBuffer ) );
+}
+
+//---------------------------------------------------------------------------
+
+boost::shared_ptr<CursorHandle> 
+Replication::modifiedObjectTableRows( const RalDatabase& db,
+                                      const RelationalFolder& folder, 
+                                      const std::string& lastUpdate ) 
+{
+  coral::AttributeList whereData;
+  whereData.extend
+    ( "lastUpdate",
+      typeIdToCoralType
+      ( RelationalObjectTable::columnTypeIds::lastModDate ) );
+  whereData["lastUpdate"].setValue( lastUpdate );
+  std::string whereClause = 
+    RelationalObjectTable::columnNames::lastModDate() + " > :lastUpdate"
+    + " and "
+    + RelationalObjectTable::columnNames::lastModDate() + " > "
+    + RelationalObjectTable::columnNames::sysInsTime();
+  
+  std::vector<std::string> orderBy;
+  std::string orderClause = RelationalObjectTable::columnNames::objectId();
+  orderBy.push_back( orderClause );
+
+  std::auto_ptr<RalQueryMgr> queryMgr( new RalQueryMgr( db.sessionMgr() ) );
+  boost::shared_ptr<coral::AttributeList> dataBuffer;
+  std::auto_ptr<coral::IQuery> query =
+    queryMgr->prepareQuery
+    ( RelationalQueryMgr::tableList( folder.objectTableName() ),
+      RelationalQueryMgr::columnList
+      ( RelationalObjectTable::tableSpecification
+        ( folder.payloadSpecification() ) ),
+      whereClause, whereData, orderBy, dataBuffer );
+  return boost::shared_ptr<CursorHandle>( new CursorHandle( query,
+                                                            dataBuffer ) );
+}
+
+//---------------------------------------------------------------------------
+
+std::vector<RelationalTableRow> 
+Replication::localTagTableRows( const RalDatabase& db,
+                                const RelationalFolder& folder ) 
+{
+  coral::AttributeList whereData;
+  std::string whereClause = "";
+  
+  std::vector<std::string> orderBy;
+  std::string orderClause = RelationalTagTable::columnNames::tagId;
+  orderBy.push_back( orderClause );
+  std::string desc = "";
+  
+  std::vector<RelationalTableRow> rows =
+    db.queryMgr().fetchOrderedRowsFromTables
+    ( RelationalQueryMgr::tableList( folder.tagTableName() ), 
+      RelationalQueryMgr::columnList
+      ( RelationalTagTable::tableSpecification() ),
+      whereClause, whereData, orderBy, desc );
+  
+  return rows;
+}
+
+//---------------------------------------------------------------------------
+
+std::vector<RelationalTableRow> 
+Replication::object2TagTableRows( const RalDatabase& db,
+                                  const RelationalFolder& folder ) 
+{
+  coral::AttributeList whereData;
+  std::string whereClause = "";
+  
+  std::vector<std::string> orderBy;
+  std::string desc = "";
+  
+  std::vector<RelationalTableRow> rows =
+    db.queryMgr().fetchOrderedRowsFromTables
+    ( RelationalQueryMgr::tableList( folder.object2TagTableName() ), 
+      RelationalQueryMgr::columnList
+      ( RelationalObject2TagTable::tableSpecification() ),
+      whereClause, whereData, orderBy, desc );
+  
+  return rows;
+}
+
+//---------------------------------------------------------------------------
+
+std::vector<RelationalTableRow> 
+Replication::globalTagTableRows( const RalDatabase& db ) 
+{
+  coral::AttributeList whereData;
+  std::string whereClause = "";
+  
+  std::vector<std::string> orderBy;
+  std::string desc = "";
+  
+  std::vector<RelationalTableRow> rows =
+    db.queryMgr().fetchOrderedRowsFromTables
+    ( RelationalQueryMgr::tableList( db.globalTagTableName() ), 
+      RelationalQueryMgr::columnList
+      ( RelationalGlobalTagTable::tableSpecification() ),
+      whereClause, whereData, orderBy, desc );
+  
+  return rows;
+}
+
+//---------------------------------------------------------------------------
+
+std::vector<RelationalTableRow> 
+Replication::tag2TagTableRows( const RalDatabase& db ) 
+{
+  coral::AttributeList whereData;
+  std::string whereClause = "";
+  
+  std::vector<std::string> orderBy;
+  std::string desc = "";
+  
+  std::vector<RelationalTableRow> rows =
+    db.queryMgr().fetchOrderedRowsFromTables
+    ( RelationalQueryMgr::tableList( db.tag2TagTableName() ), 
+      RelationalQueryMgr::columnList
+      ( RelationalTag2TagTable::tableSpecification() ),
+      whereClause, whereData, orderBy, desc );
+  
+  return rows;
+}
+
+//---------------------------------------------------------------------------
+
+std::vector<RelationalTableRow> 
+Replication::channelTableRows( const RalDatabase& db,
+                               const RelationalFolder& folder ) 
+{
+  coral::AttributeList whereData;
+  std::string whereClause = "";
+  
+  std::vector<std::string> orderBy;
+  std::string desc = "";
+  
+  std::vector<RelationalTableRow> rows =
+    db.queryMgr().fetchOrderedRowsFromTables
+    ( RelationalQueryMgr::tableList( folder.channelTableName() ), 
+      RelationalQueryMgr::columnList
+      ( RelationalChannelTable::tableSpecification() ),
+      whereClause, whereData, orderBy, desc );
+  
+  return rows;
+}
+
+//---------------------------------------------------------------------------
+
+unsigned int 
+Replication::bulkInsert( const RalDatabase& db,
+                         const std::string& tableName,
+                         boost::shared_ptr<CursorHandle>& cursorHandle ) 
+{
+  if ( ! cursorHandle->cursor().next() ) return 0;
+  
+  coral::ITable&
+  objectTable = db.session().nominalSchema().tableHandle( tableName );
+  coral::AttributeList data( cursorHandle->cursor().currentRow() );
+  //coral::AttributeList data( rows[0].data() );
+  int rowCacheSize = 100;
+  std::auto_ptr<coral::IBulkOperation> 
+  bulkInserter( objectTable.dataEditor().bulkInsert( data, rowCacheSize ) );
+
+  int rowCount = 0;
+  do {
+    data.fastCopyData( cursorHandle->cursor().currentRow() );
+    bulkInserter->processNextIteration();
+    ++rowCount;
+  } while ( cursorHandle->cursor().next() );
+  
+  bulkInserter->flush();
+    
+  return rowCount;
+}
+
+//---------------------------------------------------------------------------
+
+unsigned int 
+Replication::bulkInsert( const RalDatabase& db,
+                         const std::string& tableName,
+                         const std::vector<RelationalTableRow>& rows ) 
+{
+  if ( rows.empty() ) return 0;
+  
+  coral::ITable&
+  objectTable = db.session().nominalSchema().tableHandle( tableName );
+  coral::AttributeList data( rows[0].data() );
+  int rowCacheSize = 100;
+  std::auto_ptr<coral::IBulkOperation> 
+    bulkInserter( objectTable.dataEditor().bulkInsert( data, rowCacheSize ) );
+  
+  for ( std::vector<RelationalTableRow>::const_iterator 
+        row = rows.begin(); row != rows.end(); ++row ) {
+    data.fastCopyData( row->data() );
+    bulkInserter->processNextIteration();
+  }
+  
+  bulkInserter->flush();
+  
+  return rows.size();
+}
+
+//---------------------------------------------------------------------------
+
+void 
+Replication::bulkUpdateObjectTableRows
+( const RalDatabase& db,
+  const std::string& tableName,
+  boost::shared_ptr<CursorHandle>& cursorHandle ) 
+{
+  if ( ! cursorHandle->cursor().next() ) return;
+  
+  coral::AttributeList updateData( cursorHandle->cursor().currentRow() );
+
+  std::string setClause = "";
+  bool first = true;
+  for ( coral::AttributeList::const_iterator
+        i = updateData.begin(); i != updateData.end(); ++i ) {
+    if ( first ) {
+      first = false;
+    } else {
+      setClause += ", ";
+    }
+    setClause += i->specification().name() + " = :" + 
+      i->specification().name();
+  }
+  
+  std::string whereClause = RelationalObjectTable::columnNames::objectId();
+  whereClause += "= :" + RelationalObjectTable::columnNames::objectId();
+  
+  coral::ITable&
+  objectTable = db.session().nominalSchema().tableHandle( tableName );
+  
+  int dataCacheSize = 100; // rows
+  std::auto_ptr<coral::IBulkOperation> 
+    query( objectTable.dataEditor().bulkUpdateRows( setClause,
+                                                    whereClause,
+                                                    updateData,
+                                                    dataCacheSize ) );
+  
+  do {
+    updateData.fastCopyData( cursorHandle->cursor().currentRow() );
+    query->processNextIteration();
+  } while ( cursorHandle->cursor().next() );
+  
+  query->flush();
+}
+
+//---------------------------------------------------------------------------
+
+void 
+Replication::bulkUpdateNodeTableDescriptions
+( const RalDatabase& db,
+  const std::vector<RelationalTableRow>& rows ) 
+{
+  if ( rows.empty() ) return;
+  
+  coral::AttributeList updateData;
+  updateData.extend
+    ( "description",
+      typeIdToCoralType
+      ( RelationalNodeTable::columnTypeIds::nodeDescription ) );
+  updateData.extend
+    ( "nodeId",
+      typeIdToCoralType
+      ( RelationalNodeTable::columnTypeIds::nodeId ) );
+  
+  std::string setClause =
+    RelationalNodeTable::columnNames::nodeDescription + " = :description";
+  
+  std::string whereClause = 
+    RelationalNodeTable::columnNames::nodeId + " = :nodeId";
+  
+  coral::ITable&
+    table = db.session().nominalSchema().tableHandle( db.nodeTableName() );
+  
+  int dataCacheSize = 100; // rows
+  std::auto_ptr<coral::IBulkOperation> 
+    query( table.dataEditor().bulkUpdateRows( setClause,
+                                              whereClause,
+                                              updateData,
+                                              dataCacheSize ) );
+  
+  for ( std::vector<RelationalTableRow>::const_iterator 
+        row = rows.begin(); row != rows.end(); ++row ) {
+    updateData["description"].setValue
+    ( row->data()[RelationalNodeTable::columnNames::nodeDescription].
+      data<std::string>() );
+    updateData["nodeId"].setValue
+      ( row->data()[RelationalNodeTable::columnNames::nodeId].
+        data<unsigned int>() );
+    query->processNextIteration();
+  }
+  
+  query->flush();
+}
+
+//---------------------------------------------------------------------------
+
+std::string Replication::serverTime( const RalDatabase& db ) 
+{
+  std::string serverTimeClause = db.queryMgr().serverTimeClause();
+  coral::AttributeList data;
+  data.extend( serverTimeClause, 
+               typeIdToCoralType( StorageType::String255 ) );
+  
+  std::auto_ptr<coral::IQuery> 
+    query( db.session().nominalSchema().newQuery() );
+  query->addToTableList( db.mainTableName() );
+  query->addToOutputList( serverTimeClause );
+  query->defineOutput( data );
+  
+  coral::ICursor& cursor = query->execute();
+  cursor.next();
+  return cursor.currentRow()[serverTimeClause].data<std::string>();
+}
+
+//---------------------------------------------------------------------------
+
+void Replication::updateLastReplication( const RalDatabase& db,
+                                         const std::string& lastReplication ) 
+{
+  LOG << "Setting time of replication in target" << std::endl;
+  
+  coral::AttributeList updateData;
+  updateData.extend
+    ( "lastReplication",
+      typeIdToCoralType
+      (RelationalDatabaseTable::columnTypeIds::attributeValue) );
+  updateData["lastReplication"].setValue( lastReplication );
+  std::string setClause = 
+    RelationalDatabaseTable::columnNames::attributeValue;
+  setClause += "= :lastReplication";
+  std::string whereClause =
+    RelationalDatabaseTable::columnNames::attributeName
+    + " = '" + RelationalDatabaseTable::attributeNames::lastReplication + "'";
+  
+  // Execute the update
+  UInt32 updatedRows = db.queryMgr().updateTableRows
+    ( db.mainTableName(), setClause, whereClause, updateData );
+  
+  if ( updatedRows == 0 ) {
+    // it's a new attribute
+    coral::AttributeList data =
+      Record( RelationalDatabaseTable::tableSpecification() ).attributeList();
+    data[RelationalDatabaseTable::columnNames::attributeName].setValue
+      ( RelationalDatabaseTable::attributeNames::lastReplication );
+    data[RelationalDatabaseTable::columnNames::attributeValue].setValue
+      ( lastReplication );
+    db.queryMgr().insertTableRow( db.mainTableName(), data );
+  } else if ( updatedRows != 1 ) {
+    throw Exception
+    ( "Could not update a row of the main table", "Replication" );
+  }
+}
+
+//---------------------------------------------------------------------------
+
+void Replication::updateLastReplicationSource( const RalDatabase& db,
+                                               const std::string& sourceUrl ) 
+{
+  LOG << "Setting replication source in target" << std::endl;
+  
+  coral::AttributeList updateData;
+  updateData.extend
+    ( "sourceUrl",
+      typeIdToCoralType
+      (RelationalDatabaseTable::columnTypeIds::attributeValue) );
+  updateData["sourceUrl"].setValue( sourceUrl );
+  std::string setClause = 
+    RelationalDatabaseTable::columnNames::attributeValue;
+  setClause += "= :sourceUrl";
+  std::string whereClause =
+    RelationalDatabaseTable::columnNames::attributeName
+    + " = '" 
+    + RelationalDatabaseTable::attributeNames::lastReplicationSource + "'";
+  
+  // Execute the update
+  UInt32 updatedRows = db.queryMgr().updateTableRows
+    ( db.mainTableName(), setClause, whereClause, updateData );
+  
+  if ( updatedRows == 0 ) {
+    // it's a new attribute
+    coral::AttributeList data =
+      Record( RelationalDatabaseTable::tableSpecification() ).attributeList();
+    data[RelationalDatabaseTable::columnNames::attributeName].setValue
+      ( RelationalDatabaseTable::attributeNames::lastReplicationSource );
+    data[RelationalDatabaseTable::columnNames::attributeValue].setValue
+      ( sourceUrl );
+    db.queryMgr().insertTableRow( db.mainTableName(), data );
+  } else if ( updatedRows != 1 ) {
+    throw Exception
+    ( "Could not update a row of the main table", "Replication" );
+  }
+}
+
+//---------------------------------------------------------------------------
+
+void Replication::setSourceDb( const std::string& url ) 
+{
+  std::cout << "opening source: " << url << std::endl;
+  try {
+    bool readOnly = true;
+    m_sourceDb = databaseService().openDatabase( url, readOnly );
+  } catch ( Exception& e ) {
+    std::cerr << "Exception: " << e.what() << std::endl;
+    std::cerr << "while opening " << url << std::endl;
+    throw e;
+  }
+  if ( m_sourceDb.get() == 0 ) throw Exception( "source db is null",
+                                                "Replication" );
+  m_sourceRalDb = dynamic_cast<RalDatabase*>( m_sourceDb.get() );
+  if ( m_sourceRalDb == 0 ) throw Exception( "source db is null",
+                                             "Replication" );
+}
+
+//---------------------------------------------------------------------------
+
+void Replication::setTargetDb( const std::string& url ) 
+{
+  std::cout << "opening target: " << url << std::endl;
+  try {
+    bool readOnly = false;
+    m_targetDb = databaseService().openDatabase( url, readOnly );
+  } catch ( DatabaseDoesNotExist& ) {
+    m_targetDb = databaseService().createDatabase( url );
+  }
+  if ( m_targetDb.get() == 0 ) throw Exception( "target db is null",
+                                                "Replication" );
+  m_targetRalDb = dynamic_cast<RalDatabase*>( m_targetDb.get() );
+  if ( m_targetRalDb == 0 ) throw Exception( "target db is null",
+                                             "Replication" );
+}
+
+//---------------------------------------------------------------------------
+
+std::string Replication::getLastUpdate() 
+{
+  std::string lastUpdate = "0000-00-00_00:00:00.000000000 GMT";
+  coral::AttributeList targetDbAttributes = 
+    targetDb().databaseAttributes().attributeList();
+  try {
+    lastUpdate = targetDbAttributes
+      [RelationalDatabaseTable::attributeNames::lastReplication]
+      .data<std::string>();
+  } 
+  catch ( coral::AttributeListException& ) {}
+  return lastUpdate;
+}
+
+//---------------------------------------------------------------------------
+
+bool Replication::checkSchemaCompliance( const RalDatabase& source,
+                                         const RalDatabase& target ) 
+{
+  coral::AttributeList sourceDbAttributes = 
+    source.databaseAttributes().attributeList();
+  coral::AttributeList targetDbAttributes = 
+    target.databaseAttributes().attributeList();
+  return 
+    sourceDbAttributes[RelationalDatabaseTable::attributeNames::schemaVersion]
+    ==
+    targetDbAttributes[RelationalDatabaseTable::attributeNames::schemaVersion];
+}
+
+//---------------------------------------------------------------------------
+
+void Replication::replicateNodeTable( const std::string& lastUpdate ) 
+{
+  LOG << "Replicating node table" << std::endl;
+  // check for dropped nodes
+  {
+    // Fetch nodes in reverse order so that dropping nodes will start with the
+    // deepest node.
+    bool ascending = false;
+    // Use node mgr directly to prevent opening of a new transaction.
+    std::vector<std::string> sourceNodes = 
+    sourceDb().nodeMgr().listAllNodes( ascending );
+    std::vector<std::string> targetNodes = 
+    targetDb().nodeMgr().listAllNodes( ascending );
+    // Find dropped nodes
+    for ( std::vector<std::string>::const_iterator
+          n = targetNodes.begin(); n != targetNodes.end(); ++n ) {
+      if ( find( sourceNodes.begin(), sourceNodes.end(), *n ) 
+           == sourceNodes.end() ) {
+        // Node does not exist in source -- drop it
+        targetDb().__dropNode( *n );
+      }
+    }
+  }
+  std::vector<RelationalTableRow> rows = newNodeTableRows( sourceDb(),
+                                                           lastUpdate );
+   
+  std::string nodeSeqName =
+  RelationalNodeTable::sequenceName( targetDb().nodeTableName() );
+  RelationalSequencePtr nodeSeq
+  ( targetDb().queryMgr().sequenceMgr().getSequence( nodeSeqName ) );
+  unsigned int previousNodeId = nodeSeq->currVal();
+
+  for ( std::vector<RelationalTableRow>::const_iterator
+        i = rows.begin(); i != rows.end(); ++i ) {
+    unsigned int nodeId =
+    i->data()[RelationalNodeTable::columnNames::nodeId]
+    .data<unsigned int>();
+    bool nodeIsLeaf =
+      i->data()[RelationalNodeTable::columnNames::nodeIsLeaf]
+      .data<bool>();
+    std::string nodeFullPath =
+      i->data()[RelationalNodeTable::columnNames::nodeFullPath]
+      .data<std::string>();
+    std::string nodeDescription =
+      i->data()[RelationalNodeTable::columnNames::nodeDescription]
+      .data<std::string>();
+    std::string folderPayloadSpecDesc =
+      i->data()[RelationalNodeTable::columnNames::folderPayloadSpecDesc]
+      .data<std::string>();
+    FolderVersioning::Mode folderVersioningMode =
+      FolderVersioning::Mode
+      ( i->data()[RelationalNodeTable::columnNames::folderVersioningMode]
+        .data<int>() );
+    
+    // Skip the root folder set if present, because even if it shows up
+    // in the selection (when a db has never been replicated) it will already
+    // exists on the target after database bootstrapping. In other words
+    // it then is already replicated through bootstrapping.
+    if ( nodeFullPath == "/" ) continue;
+    
+    // fix for bug #30578
+    unsigned int gap = nodeId - previousNodeId;
+    // start counting from 1, because a gap of 1 is expected -- we only
+    // want to increment the node sequence for gaps larger than one
+    for ( unsigned int i = 1; i < gap; ++i ) {
+      nodeSeq->nextVal();
+    }
+    previousNodeId = nodeId;
+    
+    // Check if the node exists on the target. If so, it was dropped and
+    // recreated in the meantime. Therefore we drop and recreate it as well.
+    if ( targetDb().nodeMgr().existsNode( nodeFullPath ) )
+      targetDb().__dropNode( nodeFullPath );
+    
+    bool createParents = false;
+    
+    LOG << "\tReplicating " << nodeFullPath << " ... ";
+    
+    if ( nodeIsLeaf ) {
+      RecordSpecification spec =
+      RelationalDatabase::decodeRecordSpecification
+      ( folderPayloadSpecDesc );
+      targetDb().__createFolder( nodeFullPath,
+                                 spec,
+                                 nodeDescription,
+                                 folderVersioningMode,
+                                 createParents );
+    } else {
+      targetDb().__createFolderSet( nodeFullPath,
+                                    nodeDescription,
+                                    createParents );
+    }       
+    LOG << "done" << std::endl;
+  }
+  // update modified node descriptions
+  {
+    std::vector<RelationalTableRow> rows = 
+    modifiedNodeTableRows( sourceDb(),
+                           lastUpdate );
+    bulkUpdateNodeTableDescriptions( targetDb(), rows );
+  }
+  // identify renamed/extended payload specifications
+  updatePayloadSpecifications();
+}
+
+//---------------------------------------------------------------------------
+
+void Replication::updatePayloadSpecifications() {
+  bool isLeaf = true;
+  std::vector<RelationalTableRow> sourceNodes
+  = fetchNodeTableRows( sourceDb(), isLeaf );
+  std::vector<RelationalTableRow> targetNodes
+  = fetchNodeTableRows( targetDb(), isLeaf );
+  if ( ! sourceNodes.size() == targetNodes.size() ) {
+    throw Exception( "Unexpected size mismatch between source and target "
+                    "node counts.", "Replication" );
+  }
+  
+  std::vector<RelationalTableRow>::const_iterator s, t;
+  for ( s = sourceNodes.begin(), t = targetNodes.begin();
+       s != sourceNodes.end();
+       ++s, ++t ) {
+    std::string sourceFullPath =
+    s->data()[RelationalNodeTable::columnNames::nodeFullPath]
+    .data<std::string>();
+    std::string targetFullPath =
+    t->data()[RelationalNodeTable::columnNames::nodeFullPath]
+    .data<std::string>();
+    if ( sourceFullPath != targetFullPath ) {
+      throw Exception( "Unexpected node path mismatch between source "
+                      "and target.", "Replication" );
+    }
+
+    // Get the folders and specs of source and target
+    IFolderPtr sourceFolder = sourceDb().__getFolder( sourceFullPath );
+    IFolderPtr targetFolder = targetDb().__getFolder( targetFullPath );
+    const IRecordSpecification& 
+      sourceSpec = sourceFolder->payloadSpecification();
+    const IRecordSpecification& 
+      targetSpec = targetFolder->payloadSpecification();
+    
+    if ( sourceSpec != targetSpec ) {
+      // Obtain a RelationalFolder pointer to call the interal API
+      RelationalFolder* relTargetFolder
+        = dynamic_cast<RelationalFolder*>(targetFolder.get());
+      
+      // The source spec is at least as long as the target spec. We check the
+      // fields up to the target's size for name changes. Any extra fields in
+      // the source must be additional fields which we add.
+      UInt32 index = 0;
+      for ( ; index < targetSpec.size(); ++index ) {
+        if ( sourceSpec[index].name() != targetSpec[index].name() ) {
+          relTargetFolder->__renamePayload( targetSpec[index].name(),
+                                            sourceSpec[index].name() );
+        }
+      }
+      
+      // We continue to use 'index' to loop over the potential extra fields
+      // in sourceSpec
+      for ( ; index < sourceSpec.size(); ++index ) {
+        // Prepare the new specification
+        // (we need to get the target spec from the folder each time,
+        // because it changes as we loop)
+        RecordSpecification newRecordSpecification;
+        newRecordSpecification.extend( sourceSpec[index] );
+        Record newRecord( newRecordSpecification );
+        relTargetFolder->__extendPayloadSpecification( newRecord );
+      }
+    }
+  }
+}  
+      
+
+//---------------------------------------------------------------------------
+
+void Replication::replicateNodes( const std::string& lastUpdate ) 
+{
+  LOG << "Replicating nodes" << std::endl;
+  replicateFolderSets( lastUpdate );
+  replicateFolders( lastUpdate );
+}
+
+//---------------------------------------------------------------------------
+
+void Replication::replicateFolderSets( const std::string& /*lastUpdate*/ ) 
+{
+  //LOG << "Replicating folder sets" << std::endl;
+  // only table is xxx_TAGS_SEQ which we don't replicate for the read-only
+  // target
+}
+
+//---------------------------------------------------------------------------
+
+void Replication::replicateFolders( const std::string& lastUpdate ) 
+{
+  LOG << "Replicating folders" << std::endl;
+  bool isLeaf = true;
+  std::vector<RelationalTableRow> nodes = fetchNodeTableRows( sourceDb(),
+                                                              isLeaf );
+
+  for ( std::vector<RelationalTableRow>::const_iterator
+        n = nodes.begin(); n != nodes.end(); ++n ) {
+    RelationalFolder sourceFolder( sourceDb().relationalDbPtr(), n->data() );
+    RelationalTableRow targetNode = 
+      targetDb().nodeMgr().fetchNodeTableRow( sourceFolder.fullPath() );
+    RelationalFolder targetFolder( targetDb().relationalDbPtr(), 
+                                   targetNode.data() );
+    LOG << "\tReplicating " << sourceFolder.fullPath() << " ... ";
+    replicateFolder( sourceFolder, targetFolder, lastUpdate );
+    LOG << " done" << std::endl;
+  }
+}
+
+//---------------------------------------------------------------------------
+
+void Replication::replicateFolder( const RelationalFolder& sourceFolder,
+                                   const RelationalFolder& targetFolder,
+                                   const std::string& lastUpdate ) 
+{
+  // replicate channels (drop the FK to the channel table, 
+  // delete all channels, recreate all channels, recreate the FK)
+  {
+    targetDb().schemaMgr().dropObjectChannelFK
+      ( targetFolder.objectTableName() );
+    std::vector<RelationalTableRow> rows = 
+      channelTableRows( sourceDb(), sourceFolder );
+    std::string whereClause = "";
+    coral::AttributeList whereData;
+    targetDb().queryMgr().deleteTableRows
+      ( targetFolder.channelTableName(), whereClause, whereData );
+    bulkInsert( targetDb(), targetFolder.channelTableName(), rows );
+    targetDb().schemaMgr().createObjectChannelFK
+      ( targetFolder.objectTableName(),
+        targetFolder.channelTableName() );
+  }
+  // update modified iovs
+  {
+    boost::shared_ptr<CursorHandle>
+    cursorHandle = modifiedObjectTableRows( sourceDb(),
+                                            sourceFolder, 
+                                            lastUpdate );
+    bulkUpdateObjectTableRows( targetDb(), 
+                               targetFolder.objectTableName(), 
+                               cursorHandle );
+  }
+  // replicate new iovs
+  {
+    boost::shared_ptr<CursorHandle> 
+    cursorHandle = newObjectTableRows( sourceDb(),
+                                       sourceFolder, 
+                                       lastUpdate );
+    bulkInsert( targetDb(), targetFolder.objectTableName(), cursorHandle );
+  }
+  if ( sourceFolder.versioningMode() == FolderVersioning::MULTI_VERSION ) {
+    // clear target's tag related tables
+    // (do object2tag first, because of integrity constraints)
+    std::string whereClause = "";
+    coral::AttributeList whereData;
+    targetDb().queryMgr().deleteTableRows( targetFolder.object2TagTableName(),
+                                           whereClause, 
+                                           whereData );
+    targetDb().queryMgr().deleteTableRows( targetFolder.tagTableName(),
+                                           whereClause, 
+                                           whereData );
+    // replicate local tags
+    {
+      std::vector<RelationalTableRow> rows = localTagTableRows( sourceDb(),
+                                                                sourceFolder );
+      bulkInsert( targetDb(), targetFolder.tagTableName(), rows );
+    }
+    // replicate tag to iov relations
+    {
+      std::vector<RelationalTableRow> rows = 
+        object2TagTableRows( sourceDb(), sourceFolder );
+      bulkInsert( targetDb(), targetFolder.object2TagTableName(), rows );
+    }
+  }
+}
+
+//---------------------------------------------------------------------------
+
+void Replication::replicateTags() 
+{
+  LOG << "Replicating tags" << std::endl;
+  // remove integrity constraint on target tag2tag table
+  targetDb().schemaMgr().dropTag2TagFKs( targetDb().tag2TagTableName() );
+  // replicate global tag table
+  {    
+    std::vector<RelationalTableRow> rows = globalTagTableRows( sourceDb() );
+    std::string whereClause = "";
+    coral::AttributeList whereData;
+    targetDb().queryMgr().deleteTableRows( targetDb().globalTagTableName(),
+                                           whereClause, 
+                                           whereData );
+    bulkInsert( targetDb(), targetDb().globalTagTableName(), rows );
+  }
+  // reenable integrity constraint on target tag2tag table
+  targetDb().schemaMgr().createTag2TagFKs( targetDb().tag2TagTableName(),
+                                           targetDb().globalTagTableName() );
+  // replicate tag to tag tabel
+  {
+    // delete all target rows 
+    std::string whereClause = "";
+    coral::AttributeList whereData;
+    targetDb().queryMgr().deleteTableRows( targetDb().tag2TagTableName(),
+                                           whereClause, 
+                                           whereData );
+    
+    // fetch and insert source rows into target table
+    std::vector<RelationalTableRow> rows = tag2TagTableRows( sourceDb() );
+    bulkInsert( targetDb(), targetDb().tag2TagTableName(), rows );
+  }
+}
+
+//---------------------------------------------------------------------------
+
+int Replication::replicate( const std::string& sourceUrl,
+                            const std::string& targetUrl ) 
+{
+  
+  setSourceDb( sourceUrl );
+  setTargetDb( targetUrl );
+  
+  if ( ! checkSchemaCompliance( sourceDb(), targetDb() ) ) {
+    throw Exception( "schemas are incompatible for replication",
+                     "Replication" );
+  }
+  
+  std::string lastUpdate = getLastUpdate();
+  
+  {
+    bool readOnly = true;
+    RelationalTransaction sourceTransaction( sourceDb().transactionMgr(),
+                                             readOnly );
+    readOnly = false;
+    RelationalTransaction targetTransaction( targetDb().transactionMgr(),
+                                             readOnly );
+
+    std::string timeOfReplication = serverTime( sourceDb() );
+    LOG << "Time of last update: " << lastUpdate << std::endl;
+    LOG << "Time of replication: " << timeOfReplication << std::endl;
+
+    // This timeout variable exists purely for concurrency testing purposes.
+    // The intention is to allow the replciation transaction to start
+    // and leave time for concurrent processes to access the database
+    // before the actual replication starts in order to investigate how
+    // the replication behaves under these circumstances.
+    if ( getenv( "COOLREPLICATION_TIMEOUT" ) ) {
+      int timeout = atoi( getenv( "COOLREPLICATION_TIMEOUT" ) );
+      cool::sleep( timeout );
+    }
+    
+    replicateNodeTable( lastUpdate );
+    replicateNodes( lastUpdate );
+    replicateTags();
+    
+    updateLastReplication( targetDb(), timeOfReplication );
+    updateLastReplicationSource( targetDb(), sourceUrl );
+    
+    sourceTransaction.commit();
+    targetTransaction.commit();
+  }
+   
+  LOG << "Done." << std::endl;
+  
+  return 0;
+}
+
+//---------------------------------------------------------------------------
diff --git a/RelationalCool/utilities/coolReplicateDB/Replication.h b/RelationalCool/utilities/coolReplicateDB/Replication.h
new file mode 100644
index 000000000..5084baf62
--- /dev/null
+++ b/RelationalCool/utilities/coolReplicateDB/Replication.h
@@ -0,0 +1,190 @@
+// $Id: Replication.h,v 1.16 2008-10-30 16:10:26 avalassi Exp $
+
+// Include files 
+#include "CoolKernel/pointers.h"
+#include "RelationalAccess/ICursor.h"
+#include "RelationalAccess/IQuery.h"
+
+// Local include files
+#include "../../src/CoralApplication.h"
+#include "../../src/RelationalTableRow.h"
+
+namespace cool {
+  
+  class IRecordSpecification;
+  class RalDatabase;
+  class RelationalFolder;
+
+  class CursorHandle {
+
+  public:
+    CursorHandle( std::auto_ptr<coral::IQuery>& query,
+                  boost::shared_ptr<coral::AttributeList>& dataBuffer )
+    : m_query( query )
+    // AFAIK, execution order is not guaranteed, meaning
+    // m_query->execute() could be called before m_query is assigned. However,
+    // using query->execute() won't work either, because assigning query
+    // to m_query (which is highly likely to happen before in the current
+    // initialization order) invalidates query.
+    // The ternary operator is there to ensure we use the right IQuery pointer.
+    , m_cursor( m_query.get() != NULL ? m_query->execute() 
+                                      : query->execute() )
+    , m_dataBuffer( dataBuffer ) {}
+    coral::ICursor& cursor() {
+      return m_cursor;
+    }
+  private:
+    std::auto_ptr<coral::IQuery> m_query;
+    coral::ICursor& m_cursor;
+    boost::shared_ptr<coral::AttributeList> m_dataBuffer;
+  };
+  
+  
+  class Replication : public CoralApplication {
+  
+  public:
+    
+    Replication();
+    
+    /// Replicate the source to the target database as specified by the urls.
+    int replicate( const std::string& sourceUrl,
+                   const std::string& targetUrl );
+    
+  private:
+  
+    /// Replicates all new rows in the node table since 'lastUpdate'.
+    void replicateNodeTable( const std::string& lastUpdate );
+    
+    /// Replicates data in all nodes since 'lastUpdate'.
+    void replicateNodes( const std::string& lastUpdate );
+    
+    /// Replicates data in all folder sets since 'lastUpdate'.
+    void replicateFolderSets( const std::string& lastUpdate );
+        
+    /// Replicates data in all folders since 'lastUpdate'.
+    void replicateFolders( const std::string& lastUpdate );
+    
+    /// Replicates the 'source' to the 'target' folder.
+    void replicateFolder( const RelationalFolder& sourceFolder,
+                          const RelationalFolder& targetFolder,
+                          const std::string& lastUpdate );
+
+    /// Replicates the global tag table.
+    void replicateTags();
+
+    /// Inserts the given rows into 'tableName' in 'db' in bulk.
+    /// Returns the number of inserted rows.
+    unsigned int bulkInsert( const RalDatabase& db,
+                             const std::string& tableName,
+                             boost::shared_ptr<CursorHandle>& cursorHandle );        
+    
+    /// Inserts the given rows into 'tableName' in 'db' in bulk.
+    /// Returns the number of inserted rows.
+    unsigned int bulkInsert( const RalDatabase& db,
+                             const std::string& tableName,
+                             const std::vector<RelationalTableRow>& rows );        
+    
+    /// Updates the given rows of object table 'tableName' in 'db' in bulk.
+    void bulkUpdateObjectTableRows( const RalDatabase& db,
+                                    const std::string& tableName,
+                                    boost::shared_ptr<CursorHandle>& cursorHandle );        
+
+    /// Updates the given descriptions of the node table in 'db' in bulk.
+    void bulkUpdateNodeTableDescriptions( const RalDatabase& db,
+                                          const std::vector<RelationalTableRow>& rows );
+        
+    /// Returns the current server time.
+    std::string serverTime( const RalDatabase& db );
+    
+    /// Updates the main LAST_REPLICATION field of db's main table.
+    void updateLastReplication( const RalDatabase& db,
+                                const std::string& lastUpdate );
+
+    /// Updates the main LAST_REPLICATION_SOURCE field of db's main table.
+    void updateLastReplicationSource( const RalDatabase& db,
+                                      const std::string& sourceUrl );
+    
+    /// Sets the source database member variables. This implies opening the
+    /// the database.
+    void setSourceDb( const std::string& url );
+    
+    /// Returns the source database handle.
+    RalDatabase& sourceDb() { return *m_sourceRalDb; }
+    
+    /// Sets the target database member variables. This implies opening the
+    /// the database.
+    void setTargetDb( const std::string& url );
+
+    /// Returns the target database handle.
+    RalDatabase& targetDb() { return *m_targetRalDb; }
+    
+    /// Fetched the time of the target's last update for the database.
+    std::string getLastUpdate();
+
+    /// Checks if the two schemas are compatible for replication
+    bool checkSchemaCompliance( const RalDatabase& source,
+                                const RalDatabase& target );
+    
+    /// Fetch node table rows inserted after 'lastUpdate'.
+    std::vector<RelationalTableRow> 
+      newNodeTableRows( const RalDatabase& db, 
+                        const std::string& lastUpdate );
+
+    /// Fetch node table rows modified after 'lastUpdate'.
+    std::vector<RelationalTableRow> 
+      modifiedNodeTableRows( const RalDatabase& db, 
+                             const std::string& lastUpdate );
+        
+    /// Fetch node table rows with the given 'isLeaf' flag.
+    std::vector<RelationalTableRow> 
+      fetchNodeTableRows( const RalDatabase& db, bool isLeaf );
+    
+    /// Fetch object table rows inserted after 'lastUpdate'.
+    boost::shared_ptr<CursorHandle> 
+      newObjectTableRows( const RalDatabase& db,
+                          const RelationalFolder& folder, 
+                          const std::string& lastUpdate );
+    
+    /// Fetch object table rows modified after 'lastUpdate'.
+    boost::shared_ptr<CursorHandle>
+      modifiedObjectTableRows( const RalDatabase& db,
+                               const RelationalFolder& folder, 
+                               const std::string& lastUpdate );
+    
+    /// Fetch all local tag table rows
+    std::vector<RelationalTableRow> 
+      localTagTableRows( const RalDatabase& db,
+                         const RelationalFolder& folder );
+    
+    /// Fetch all iov to tag table rows
+    std::vector<RelationalTableRow> 
+      object2TagTableRows( const RalDatabase& db,
+                           const RelationalFolder& folder );
+    
+    /// Fetch all global tag table rows
+    std::vector<RelationalTableRow> 
+      globalTagTableRows( const RalDatabase& db );
+        
+    /// Fetch all tag to tag table rows
+    std::vector<RelationalTableRow> 
+      tag2TagTableRows( const RalDatabase& db );
+    
+    /// Fetch all channel table rows.
+    std::vector<RelationalTableRow> 
+      channelTableRows( const RalDatabase& db,
+                        const RelationalFolder& folder );
+    
+    /// Update payload specifications (payload name changes, extensions)
+    /// on the target.
+    void updatePayloadSpecifications();
+    
+    IDatabasePtr m_sourceDb;
+    IDatabasePtr m_targetDb;
+    RalDatabase* m_sourceRalDb;
+    RalDatabase* m_targetRalDb;
+    std::auto_ptr<CursorHandle> m_cursor;
+    
+  };
+  
+} // namespace
+
diff --git a/RelationalCool/utilities/coolReplicateDB/coolReplicateDb.cpp b/RelationalCool/utilities/coolReplicateDB/coolReplicateDb.cpp
new file mode 100644
index 000000000..969f11515
--- /dev/null
+++ b/RelationalCool/utilities/coolReplicateDB/coolReplicateDb.cpp
@@ -0,0 +1,73 @@
+// $Id: coolReplicateDb.cpp,v 1.5 2007-06-18 09:28:58 sas Exp $
+
+#include <iostream>
+#include "Replication.h"
+#include "CoolKernel/Exception.h"
+
+int main( int argc, char** argv ) {
+  
+  std::string sourceConnectString;
+  std::string targetConnectString;
+  
+  if ( argc == 3 ) {
+    sourceConnectString = argv[1];
+    targetConnectString = argv[2];
+  } else {
+    std::cout << "Usage: " << argv[0] << " <source> <target>" << std::endl;
+    return -1;
+  }
+  
+  try {
+  
+    cool::Replication replicator;
+    return replicator.replicate( sourceConnectString, targetConnectString );
+
+  } catch ( std::exception& e ) {
+    std::cout << "Exception: " << e.what() << std::endl;
+    return -2;
+  } catch ( ... ) {
+    std::cout << "failure" << std::endl;
+    return -2;
+  }
+    
+}
+
+/*! \page replicatedb Dynamic Replication Tool
+
+The COOL Dynamic Replication Tool 'coolReplicateDB' allows replication of
+COOL databases. It differs from the PyCoolCopy tool in the ability to
+continuously update a replication target with the changes since the last
+replication instead of requiring a completely new copy of all data.
+
+Calling the tool without parameters will give the following brief help:
+
+\code
+%> coolReplicateDB 
+Usage: coolReplicateDB <source> <target>
+\endcode
+
+The expected parameters are a source and a target URL provided with the normal
+COOL database URL syntax. Replication between different technologies is 
+possible.
+
+\section replication_limitations Limitations
+
+There are two limitations regarding the replication tool:
+
+- The replica is a read-only database. It would be impossible for the tool
+to merge replication changes with direct changes to the replica. Therefore,
+the replica is flagged as read-only and cannot be used for writing by any
+software based on the public COOL API. In order to make replication more
+manageable and performant, some of the COOL 'infrastructure' information 
+(like the seqence tables) is not replicated, making updates through the public
+API impossible.
+
+- Only the Oracle backend supports replication while clients are actively 
+writing on the source database. SQLite only supports single client access and
+therefore prevents concurrent access by default. Tests with MySQL have exposed
+problems that lead to the conclusion that the replication tool <em>must not</em>
+be run while there are active clients (writers) on the source database. It is
+advised to restart the database with restricted access to safely run the
+replication on MySQL.
+
+*/
diff --git a/RelationalCool/utilities/coolStat/coolStat.cpp b/RelationalCool/utilities/coolStat/coolStat.cpp
new file mode 100644
index 000000000..66d75d0b9
--- /dev/null
+++ b/RelationalCool/utilities/coolStat/coolStat.cpp
@@ -0,0 +1,57 @@
+// $Id: coolStat.cpp,v 1.1 2006-03-15 09:53:30 avalassi Exp $
+
+// Include files
+#include <iostream>
+#include <sys/stat.h>
+#include <cerrno>
+//#include "SealBase/Filename.h"
+
+// Message output
+#define LOG std::cout
+
+//-----------------------------------------------------------------------------
+
+int main( int argc, char** argv )
+{
+
+  try {
+    
+    if ( argc != 2 ) {
+      LOG << "Usage: " << argv[0] << " filename" << std:: endl;
+      return 1;
+    }
+
+    std::string file = argv[1];
+    struct stat	statbuf;
+    //seal::Filename filename( file );
+    //int status = stat( filename, &statbuf );
+    int status = stat( file.c_str(), &statbuf );
+
+    if (status == -1)
+    {
+      LOG << "stat() failed with error " << errno << std::endl;
+      return 1;
+    }
+
+    LOG << "File: " << file.c_str() << std::endl;
+    LOG << "Last modification time: " << statbuf.st_mtime << std::endl;
+
+  }
+  
+  catch( std::exception& e )
+  {
+    LOG << "ERROR! Standard C++ exception: '" << e.what() << "'" << std::endl;
+    return 1;
+  }
+  
+  catch( ... ) 
+  {
+    LOG << "ERROR! Unknown exception caught" << std::endl;
+    return 1;
+  }
+
+  return 0;
+  
+}
+
+//-----------------------------------------------------------------------------
diff --git a/RelationalCool/utilities/coolStat/coolStat.py b/RelationalCool/utilities/coolStat/coolStat.py
new file mode 100644
index 000000000..073bc36cb
--- /dev/null
+++ b/RelationalCool/utilities/coolStat/coolStat.py
@@ -0,0 +1,41 @@
+#!/usr/bin/env python
+import os, sys
+
+def coolStat( file, newTZ="ignore" ) :
+
+    tz='TZ'
+
+    if newTZ == "none" :
+        if tz in os.environ:
+            #del os.environ[tz]
+            print "ERROR! Cannot unset",tz,": please unset it and start again"
+            sys.exit(1)
+    elif newTZ != "ignore" :
+        os.environ[tz] = newTZ
+
+    if tz in os.environ:
+        print 'TZ =', os.environ[tz]
+    else :
+        print 'TZ = [none]'
+
+    cmd = 'coolStat ' + file
+    status = os.system(cmd)
+    if status>0 : print 'Status =', status
+    return status
+
+#######################################################################
+
+if __name__ == '__main__':
+
+    if ( len(sys.argv) == 3 ) :
+        file = sys.argv[1]
+        newTZ = sys.argv[2]
+    elif ( len(sys.argv) == 2 ) :
+        file = sys.argv[1]
+        newTZ = "ignore"
+    else :
+        print 'Usage:', sys.argv[0], '<fileName> [<newTZ> | none]'
+        sys.exit(1)
+
+    status = coolStat( file, newTZ )
+    sys.exit(status>0)
diff --git a/RelationalCool/utilities/coolStat/testBug30859.py b/RelationalCool/utilities/coolStat/testBug30859.py
new file mode 100644
index 000000000..e8599f015
--- /dev/null
+++ b/RelationalCool/utilities/coolStat/testBug30859.py
@@ -0,0 +1,19 @@
+#!/usr/bin/env python
+import os
+from coolStat import coolStat
+if __name__ == '__main__':
+    key='OSTYPE'
+    if key in os.environ and os.environ[key] == "linux" :
+        file="/afs/cern.ch/sw/lcg/app/releases/SEAL/SEAL_1_9_3/win32_vc71_dbg/lib/modules/lcg_SealServices.reg"
+        ###file="/afs/cern.ch/sw/lcg/app/releases/COOL/internal/avalassi/COOL_HEAD/win32_vc71_dbg/lib/modules/lcg_RelationalCool.reg"
+    else :
+        file="\\\\afs\\all\\cern.ch\\sw\\lcg\\app\\releases\\SEAL\\SEAL_1_9_3\\win32_vc71_dbg\\lib\\modules\\lcg_SealServices.reg"
+        ###file="\\\\afs\\all\\cern.ch\\sw\\lcg\\app\\releases\\COOL\\internal\\avalassi\\COOL_HEAD\\win32_vc71_dbg\\lib\\modules\\lcg_RelationalCool.reg"
+    print "File =", file
+    coolStat(file,"none")
+    coolStat(file,"CEST")
+    coolStat(file,"CET")
+    coolStat(file,"UTC")
+
+
+    
diff --git a/RelationalCool/utilities/coolValidateSchema/RalSchemaValidation.cpp b/RelationalCool/utilities/coolValidateSchema/RalSchemaValidation.cpp
new file mode 100644
index 000000000..0586d1d6e
--- /dev/null
+++ b/RelationalCool/utilities/coolValidateSchema/RalSchemaValidation.cpp
@@ -0,0 +1,512 @@
+// $Id: RalSchemaValidation.cpp,v 1.11 2008-09-11 06:31:05 avalassi Exp $
+
+// Include files
+#include "CoolKernel/Record.h"
+#include "CoolKernel/FolderVersioning.h"
+#include "CoralBase/Attribute.h"
+
+// Local include files
+#include "RalSchemaValidation.h"
+#include "../../src/HvsPathHandler.h"
+#include "../../src/HvsPathHandlerException.h"
+#include "../../src/RalDatabase.h"
+#include "../../src/RelationalChannelTable.h"
+#include "../../src/RelationalDatabaseTable.h"
+#include "../../src/RelationalException.h"
+#include "../../src/RelationalFolder.h"
+#include "../../src/RelationalNodeTable.h"
+#include "../../src/RelationalObjectTable.h"
+#include "../../src/RelationalQueryDefinition.h"
+#include "../../src/RelationalQueryMgr.h"
+#include "../../src/RelationalTableRow.h"
+#include "../../src/RelationalTagSequence.h"
+#include "../../src/RelationalTransaction.h"
+#include "../../src/RelationalSequenceTable.h"
+
+// Namespace
+using namespace cool;
+
+//-----------------------------------------------------------------------------
+
+RalSchemaValidation::RalSchemaValidation( RalDatabase* db ) 
+  : m_db( db )
+  , m_log( new coral::MessageStream
+           ( "RalSchemaValidation" ) )
+  , m_fatal( false )
+{
+  log() << coral::Info 
+        << "Instantiate a RalSchemaValidation manager for '" 
+        << m_db->databaseId() << "'" << coral::MessageStream::endmsg;
+}
+
+//-----------------------------------------------------------------------------
+
+RalSchemaValidation::~RalSchemaValidation() 
+{
+  log() << coral::Info
+        << "Delete the RalSchemaValidation manager for '" 
+        << m_db->databaseId() << "'" << coral::MessageStream::endmsg;
+  if ( ! m_fatal ) 
+  {
+    if ( m_errors.size() == 0 && m_warnings.size() == 0 )
+    {
+      std::cout << "All seems ok - no errors and no warnings" << std::endl;
+    }
+    else 
+    {
+      unsigned ierr = 0;
+      for ( std::vector<std::string>::const_iterator
+              err = m_errors.begin(); err != m_errors.end(); ++err ) 
+      {
+        ierr++;
+        std::cout << "ERROR (" << ierr << "/" << m_errors.size()
+                  << "): " << *err << std::endl;
+      }
+      unsigned iwarn = 0;
+      for ( std::vector<std::string>::const_iterator
+              warn = m_warnings.begin(); warn != m_warnings.end(); ++warn ) 
+      {
+        iwarn++;
+        std::cout << "WARNING (" << iwarn << "/" << m_warnings.size()
+                  << "): " << *warn << std::endl;
+      }
+    }
+  }
+}
+ 
+//-----------------------------------------------------------------------------
+
+coral::MessageStream& RalSchemaValidation::log() 
+{
+  *m_log << coral::Verbose;
+  return *m_log;
+}
+
+//-----------------------------------------------------------------------------
+
+void RalSchemaValidation::validateDatabase() 
+{
+  // WELCOME
+  log() << coral::Info 
+        << "Validate database schema... START" << coral::MessageStream::endmsg;
+  RelationalTransaction transaction( db().transactionMgr(), true ); // r/o
+
+  // Can the schema of this database be validated?
+  const Record& dbAttr = db().databaseAttributes();
+  std::string releaseNumber =
+    dbAttr[RelationalDatabaseTable::attributeNames::release]
+    .data<std::string>();
+  std::string schemaVersion =
+    dbAttr[RelationalDatabaseTable::attributeNames::schemaVersion].
+    data<std::string>();
+  log() << coral::Info
+        << "Database release number: " << releaseNumber
+        << coral::MessageStream::endmsg;
+  log() << coral::Info
+        << "Database schema version: " << schemaVersion 
+        << coral::MessageStream::endmsg;
+
+  // VALIDATE THE DATABASE SCHEMA
+  validateDatabase_22x();
+
+  // GOODBYE
+  transaction.commit();
+  log() << coral::Info 
+        << "Validate database schema... DONE!" << coral::MessageStream::endmsg;
+}
+
+//-----------------------------------------------------------------------------
+
+void RalSchemaValidation::validateDatabase_22x() 
+{
+  log() << coral::Info 
+        << "Validate database schema (22x)..." << coral::MessageStream::endmsg;
+
+  // -------------------------------------------------------------------
+  // Check SQL types of columns in all existing tables (220):
+  // (..) ..to be implemented..
+  // -------------------------------------------------------------------
+
+  //i_checkSqlTypes_220();
+
+  // -------------------------------------------------------------------
+  // Check all nodes (220):
+  // ( 1) Check the existence of the tag sequence table of each node
+  // ( 2) Check the existence of the channels table of each folder
+  // -------------------------------------------------------------------
+
+  i_checkNodeTables_220();
+
+  // -------------------------------------------------------------------
+  // Check all folders (220):
+  // ( 3) Check the schema of the channels table of each folder
+  // -------------------------------------------------------------------
+
+  i_checkFolders_220();  
+
+  // -------------------------------------------------------------------
+  // Check all nodes (222):
+  // ( 4) Check the name of each node
+  // -------------------------------------------------------------------
+
+  i_checkNodeNames_222();
+
+  // Success
+  log() << coral::Info 
+        << "Validate database schema (22x)... DONE!" 
+        << coral::MessageStream::endmsg;
+}
+
+//-----------------------------------------------------------------------------
+
+/*
+void RalSchemaValidation::i_checkSqlTypes_220()
+{
+  log() << coral::Info 
+        << "Check SQL types (220)... START" << coral::MessageStream::endmsg;
+  
+  // Success
+  log() << coral::Info 
+        << "Check SQL types (220)... DONE" << coral::MessageStream::endmsg;
+}  
+*/
+
+//-----------------------------------------------------------------------------
+
+void RalSchemaValidation::i_checkFolders_220() 
+{
+  log() << coral::Info 
+        << "Check individual nodes (220)..." << coral::MessageStream::endmsg;
+  
+  {    
+    // List all folders ordered by nodeId
+    coral::AttributeList whereData;
+    whereData.extend
+      ( "isLeaf", 
+        typeIdToCoralType(RelationalNodeTable::columnTypeIds::nodeIsLeaf) );
+    whereData["isLeaf"].setValue
+      ( true ); // select folders only
+    std::string whereClause = RelationalNodeTable::columnNames::nodeIsLeaf;
+    whereClause += "= :isLeaf";
+    std::vector<std::string> orderBy;
+    std::string orderClause = RelationalNodeTable::columnNames::nodeId;
+    orderClause += " ASC";
+    orderBy.push_back( orderClause );
+    std::vector<RelationalTableRow> rows =
+      db().queryMgr().fetchOrderedRowsFromTables
+      ( RelationalQueryMgr::tableList( db().nodeTableName() ), 
+        RelationalQueryMgr::columnList
+        ( RelationalNodeTable::tableSpecification
+          ( VersionNumber( "2.0.0" ) ) ),
+        whereClause, whereData, orderBy, "" );
+    // Check all folders one by one
+    bool evolveNone = true;
+    for ( std::vector<RelationalTableRow>::const_iterator
+          row = rows.begin(); row != rows.end(); ++row ) 
+    {
+      std::string fullPath = 
+        (*row)[RelationalNodeTable::columnNames::nodeFullPath]
+        .data<std::string>();
+      VersionNumber nodeSchemaVersion = 
+        (*row)[RelationalNodeTable::columnNames::nodeSchemaVersion]
+        .data<std::string>();
+      VersionNumber version201( "2.0.1" );
+      if ( version201 != 
+           std::string( RelationalFolder::folderSchemaVersion() ) )
+      {
+        std::stringstream msg;
+        msg << "PANIC! Folder schema version for this software release is '"
+            << RelationalFolder::folderSchemaVersion()
+            << "' (expected: '" << version201 << "'):"
+            << " please update the schemaValidation tool" << std::endl;
+        log() << coral::Fatal << msg.str() << coral::MessageStream::endmsg;
+        m_fatal = true;
+        throw RelationalException( msg.str(), "RalSchemaValidation" );
+      }      
+      if ( nodeSchemaVersion < 
+           std::string( RelationalFolder::folderSchemaVersion() ) )
+      {
+        evolveNone = false;
+        std::stringstream msg;
+        msg << "Folder '" << fullPath << "' needs schema evolution"
+            << " from schema version '" << nodeSchemaVersion
+            << "' to '" << RelationalFolder::folderSchemaVersion() << "'";
+        log() << coral::Warning << msg.str() << coral::MessageStream::endmsg;
+        // No need to fail: just warn that this folder must be updated.
+        // No need to check FKs either: they were not there before 2.0.1.
+        m_warnings.push_back( msg.str() );        
+      }
+      else if ( nodeSchemaVersion ==
+                std::string( RelationalFolder::folderSchemaVersion() ) )
+      {
+        log() << coral::Verbose 
+              << "Folder '" << fullPath << "' is already schema version '"
+              << RelationalFolder::folderSchemaVersion()
+              << "' and needs no schema evolution" 
+              << coral::MessageStream::endmsg;
+        i_checkChannelsTable_220( *row );
+      }
+      else 
+      {
+        std::stringstream msg;
+        msg << "PANIC! Folder " << fullPath 
+            << " has schema version " << nodeSchemaVersion 
+            << " that is newer than that supported by this release ("
+            << RelationalFolder::folderSchemaVersion() << ")";
+        log() << coral::Fatal << msg.str() << coral::MessageStream::endmsg;
+        m_fatal = true;
+        throw RelationalException( msg.str(), "RalSchemaValidation" );        
+      }      
+    }
+    if ( evolveNone )
+      log() << coral::Info
+            << "All folders are already schema version '"
+            << RelationalFolder::folderSchemaVersion()
+            << "' and need no schema evolution" 
+            << coral::MessageStream::endmsg;
+  }
+  
+  // Success
+  log() << coral::Info 
+        << "Check individual nodes (220)... DONE!" 
+        << coral::MessageStream::endmsg;
+}
+
+//-----------------------------------------------------------------------------
+
+void RalSchemaValidation::i_checkChannelsTable_220
+( const RelationalTableRow& row )
+{
+  int folderVersioningMode = 
+    row[RelationalNodeTable::columnNames::folderVersioningMode].data<int>();
+  std::string svOrMv = "SV";
+  if ( folderVersioningMode == FolderVersioning::MULTI_VERSION ) svOrMv = "MV";
+  std::string fullPath =
+    row[RelationalNodeTable::columnNames::nodeFullPath]
+    .data<std::string>();
+  std::string channelTableName = 
+    row[RelationalNodeTable::columnNames::folderChannelTableName]
+    .data<std::string>();
+  std::string objectTableName = 
+    row[RelationalNodeTable::columnNames::folderObjectTableName]
+    .data<std::string>();
+  log() << coral::Info 
+        << "Check the " << svOrMv << " channels table " << channelTableName 
+        << " of folder " << fullPath << " (220)..." 
+        << coral::MessageStream::endmsg;
+
+  // List all channels in the IOV table
+  std::vector<RelationalTableRow> iovTableChannels;
+  try
+  {
+    RelationalQueryDefinition def;
+    def.addSelectItem
+      ( "DISTINCT " + RelationalObjectTable::columnNames::channelId() );
+    def.addFromItem( objectTableName );
+    def.addOrderItem
+      ( RelationalObjectTable::columnNames::channelId() + " ASC" );
+    RecordSpecification spec;    
+    spec.extend( RelationalObjectTable::columnNames::channelId(),
+                 RelationalObjectTable::columnTypeIds::channelId );
+    def.setResultSetSpecification( spec );
+    iovTableChannels = db().queryMgr().fetchOrderedRows( def );
+  }
+  catch( RelationalException& e ) 
+  {
+    std::stringstream msg;
+    msg << "Error checking iov table of folder '" << fullPath 
+        << "'. Caught exception: '" << e.what() << "'. Skipping this table.";
+    m_errors.push_back( msg.str() );
+    return;
+  }
+  
+  // List all channels in the channels table
+  std::vector<RelationalTableRow> chTableChannels;
+  try 
+  {
+    RelationalQueryDefinition def;
+    def.addSelectItem( RelationalChannelTable::columnNames::channelId() );
+    def.addFromItem( channelTableName );
+    def.addOrderItem
+      ( RelationalChannelTable::columnNames::channelId() + " ASC" );
+    RecordSpecification spec;    
+    spec.extend( RelationalChannelTable::columnNames::channelId(),
+                 RelationalChannelTable::columnTypeIds::channelId );
+    def.setResultSetSpecification( spec );
+    chTableChannels = db().queryMgr().fetchOrderedRows( def );
+  }
+  catch( RelationalException& e ) 
+  {
+    std::stringstream msg;
+    msg << "Error checking channels table of folder '" << fullPath 
+        << "'. Caught exception: '" << e.what() << "'. Skipping this table.";
+    m_errors.push_back(msg.str());
+    return;
+  }  
+  
+  // Check that all IOV table channels are present in the channels table
+  for ( std::vector<RelationalTableRow>::const_iterator ch = 
+          iovTableChannels.begin(); ch != iovTableChannels.end(); ++ch ) 
+  {
+    ChannelId chId = 
+      (*ch)[RelationalObjectTable::columnNames::channelId()].data<ChannelId>();
+    bool found = false;
+    //std::cout << "Channel in IOV table: " << chId << std::endl;
+    for ( std::vector<RelationalTableRow>::const_iterator ch2 = 
+            chTableChannels.begin(); ch2 != chTableChannels.end(); ++ch2 ) 
+    {
+      ChannelId chId2 =
+        (*ch2)[RelationalChannelTable::columnNames::channelId()]
+        .data<ChannelId>();
+      //std::cout << "Channel in channels table: " << chId2 << std::endl;
+      if ( chId2 == chId )
+      {
+        //std::cout << "Channel found in both tables: " << chId << std::endl;
+        found = true;
+        break;
+      }
+    }
+    if ( !found ) 
+    {
+      std::stringstream msg;
+      msg << "Channel #" << chId << " in the IOV table " << objectTableName 
+          << " does not reference an entry in the channels table "
+          << channelTableName << " of folder " << fullPath;
+      m_fatal = true;
+      throw RelationalException( msg.str(), "RalSchemaValidation" );
+    }    
+  }
+  log() << coral::Info 
+        << "Check the " << svOrMv << " channels table " << channelTableName 
+        << " of folder " << fullPath << " (220)... DONE!" 
+        << coral::MessageStream::endmsg;
+}
+
+//-----------------------------------------------------------------------------
+
+void RalSchemaValidation::i_checkNodeNames_222() 
+{
+  log() << coral::Info 
+        << "Check node names (222)..." << coral::MessageStream::endmsg;
+  
+  {    
+    // List all nodes ordered by nodeId
+    coral::AttributeList whereData;
+    std::string whereClause;
+    std::vector<std::string> orderBy;
+    std::string orderClause = RelationalNodeTable::columnNames::nodeId;
+    orderClause += " ASC";
+    orderBy.push_back( orderClause );
+    std::vector<RelationalTableRow> rows =
+      db().queryMgr().fetchOrderedRowsFromTables
+      ( RelationalQueryMgr::tableList( db().nodeTableName() ), 
+        RelationalQueryMgr::columnList
+        ( RelationalNodeTable::tableSpecification
+          ( VersionNumber( "2.0.0" ) ) ),
+        whereClause, whereData, orderBy, "" );
+    // Check all nodes one by one
+    for ( std::vector<RelationalTableRow>::const_iterator
+          row = rows.begin(); row != rows.end(); ++row ) 
+    {
+      std::string fullPath = 
+        (*row)[RelationalNodeTable::columnNames::nodeFullPath]
+        .data<std::string>();
+      HvsPathHandler pathHandler;
+      try 
+      {
+        if ( fullPath != pathHandler.rootFullPath() )
+          pathHandler.splitFullPath( fullPath );
+      } 
+      catch ( HvsPathHandlerException& e ) 
+      {
+        log() << coral::Warning << e.what() << coral::MessageStream::endmsg;
+        m_warnings.push_back( e.what() );        
+      }
+    }
+  }
+  
+  // Success
+  log() << coral::Info 
+        << "Check node names (222)... DONE!" 
+        << coral::MessageStream::endmsg;
+}
+
+//-----------------------------------------------------------------------------
+
+void RalSchemaValidation::i_checkNodeTables_220() 
+{
+
+  // List all nodes ordered by nodeId
+  std::vector<RelationalTableRow> rows;
+  {
+    coral::AttributeList whereData;
+    std::string whereClause = "";
+    std::vector<std::string> orderBy;
+    std::string orderClause = RelationalNodeTable::columnNames::nodeId;
+    orderClause += " ASC";
+    orderBy.push_back( orderClause );
+    rows = db().queryMgr().fetchOrderedRowsFromTables
+      ( RelationalQueryMgr::tableList( db().nodeTableName() ), 
+        RelationalQueryMgr::columnList
+        ( RelationalNodeTable::tableSpecification
+          ( VersionNumber( "2.0.0" ) ) ),
+        whereClause, whereData, orderBy, "" );
+  }
+  
+  // Check all nodes one by one
+  for ( std::vector<RelationalTableRow>::const_iterator
+          row = rows.begin(); row != rows.end(); ++row ) 
+  {
+    UInt32 nodeId = 
+      (*row)[RelationalNodeTable::columnNames::nodeId]
+      .data<UInt32>();
+    std::string nodeFullPath = 
+      (*row)[RelationalNodeTable::columnNames::nodeFullPath]
+      .data<cool::String255>();
+    Int32 folderVersioningMode = 
+      (*row)[RelationalNodeTable::columnNames::folderVersioningMode]
+      .data<Int32>();
+    std::string tagSequenceName = 
+      RelationalTagSequence::sequenceName
+      ( db().defaultTablePrefix(), nodeId );
+    std::string channelTableName = 
+      RelationalChannelTable::defaultTableName
+      ( db().defaultTablePrefix(), nodeId ); 
+    try 
+    {
+      coral::AttributeList whereData;
+      std::string whereClause = "";
+      std::vector<std::string> orderBy;
+      if ( folderVersioningMode != FolderVersioning::SINGLE_VERSION )
+      {
+        // single version folder don't have a tag sequence table
+        db().queryMgr().fetchOrderedRowsFromTables
+          ( RelationalQueryMgr::tableList( tagSequenceName ),
+            RelationalQueryMgr::columnList
+            ( RelationalSequenceTable::tableSpecification() ),
+            whereClause, whereData, orderBy, "" );
+      }
+      if ( folderVersioningMode != FolderVersioning::NONE ) 
+      {
+        // check for channels table if the node is not a folder set
+        db().queryMgr().fetchOrderedRowsFromTables
+          ( RelationalQueryMgr::tableList( channelTableName ),
+            RelationalQueryMgr::columnList
+            ( RelationalChannelTable::tableSpecification() ),
+            whereClause, whereData, orderBy, "");
+      }
+    }
+    catch ( RelationalException& e )
+    {
+      std::stringstream msg;
+      msg << "Corrupt or missing table for ";
+      if ( folderVersioningMode != FolderVersioning::NONE ) msg << "folder ";
+      else msg << "folder set ";
+      msg << "'" << nodeFullPath << "'. Error Message: '"<< e.what() << "'"; 
+      m_errors.push_back( msg.str() );
+    } 
+  }
+}
+
+//-----------------------------------------------------------------------------
+
diff --git a/RelationalCool/utilities/coolValidateSchema/RalSchemaValidation.h b/RelationalCool/utilities/coolValidateSchema/RalSchemaValidation.h
new file mode 100644
index 000000000..55975cef7
--- /dev/null
+++ b/RelationalCool/utilities/coolValidateSchema/RalSchemaValidation.h
@@ -0,0 +1,101 @@
+// $Id: RalSchemaValidation.h,v 1.8 2008-10-29 09:11:31 avalassi Exp $
+#ifndef RELATIONALCOOL_RALSCHEMAVALIDATION_H 
+#define RELATIONALCOOL_RALSCHEMAVALIDATION_H 1
+
+// Include files
+#include <memory>
+#include "CoolKernel/DatabaseId.h"
+#include "CoolKernel/RecordSpecification.h"
+#include "CoralBase/MessageStream.h"
+
+namespace cool 
+{
+
+  // Forward declarations
+  class RalDatabase;
+  class RelationalObjectTableRow;
+  class RelationalTableRow;
+
+  /** @class RalSchemaValidation RalSchemaValidation.h
+   *  
+   *  Private utility class to implement COOL relational schema validation.
+   *
+   *  @author Andrea Valassi
+   *  @date   2007-10-22
+   */
+
+  class RalSchemaValidation 
+  {
+    
+  public:
+    
+    /// Constructor from a RalDatabase pointer (see RalPrivilegeManager)
+    RalSchemaValidation( RalDatabase* db );
+    
+    /// Destructor
+    virtual ~RalSchemaValidation();    
+    
+    /// Validate the schema of the full database.
+    void validateDatabase();
+
+  protected:
+    
+    /// Get a CORAL MessageStream
+    coral::MessageStream& log();
+
+    /// Get the RalDatabase reference
+    const RalDatabase& db() const { return *m_db; }
+      
+    /// --- SCHEMA VALIDATION FOR COOL_2_2_0
+
+    /// Validate the schema of the full database (22x).
+    void validateDatabase_22x();
+    
+    /// Check SQL types in all tables (220).
+    //void i_checkSqlTypes_220();
+
+    /// Check that channels and tag sequence tables exist for all nodes (220).
+    void i_checkNodeTables_220();
+
+    /// Check the schemas of all folders (220).
+    void i_checkFolders_220();
+    
+    /// Check the schema of the channels table of a folder (220).
+    void i_checkChannelsTable_220( const RelationalTableRow& row );
+    
+    /// Check the names of all nodes (222).
+    void i_checkNodeNames_222();
+    
+  private:
+
+    /// Standard constructor is private
+    RalSchemaValidation(); 
+
+    /// Copy constructor is private
+    RalSchemaValidation( const RalSchemaValidation& rhs ); 
+
+    /// Assignment operator is private
+    RalSchemaValidation& operator=( const RalSchemaValidation& rhs ); 
+   
+  private:
+
+    /// RalDatabase pointer
+    RalDatabase* m_db;    
+
+    /// CORAL MessageStream
+    std::auto_ptr<coral::MessageStream> m_log;
+
+    /// Fatal errors received during schema validation
+    bool m_fatal;
+    
+    /// Errors received during schema validation
+    std::vector<std::string> m_errors;
+    
+    /// Warnings received during schema validation
+    std::vector<std::string> m_warnings;
+    
+  };
+
+}
+
+#endif // RELATIONALCOOL_RALSCHEMAVALIDATION_H
diff --git a/RelationalCool/utilities/coolValidateSchema/coolValidateSchema.cpp b/RelationalCool/utilities/coolValidateSchema/coolValidateSchema.cpp
new file mode 100644
index 000000000..34399b251
--- /dev/null
+++ b/RelationalCool/utilities/coolValidateSchema/coolValidateSchema.cpp
@@ -0,0 +1,95 @@
+// $Id: coolValidateSchema.cpp,v 1.5 2008-04-10 08:32:54 avalassi Exp $
+
+// Include files
+#include <iostream>
+#include "CoolKernel/IDatabase.h"
+#include "CoolKernel/IDatabaseSvc.h"
+#include "RelationalAccess/IConnectionService.h"
+#include "RelationalAccess/IConnectionServiceConfiguration.h"
+
+// Local include files
+#include "RalSchemaValidation.h"
+#include "../../src/CoralApplication.h"
+#include "../../src/RalDatabase.h"
+#include "../../src/VersionInfo.h"
+
+// Namespace
+using namespace cool;
+
+// Message output
+#define LOG  std::cout
+#define ENDL std::endl
+
+//-----------------------------------------------------------------------------
+
+int main( int argc, char** argv )
+{
+
+  LOG << "Schema validation starting" << ENDL;
+
+  try {
+    
+    // Get the command line arguments
+    std::string dbId;
+    if ( argc != 2 ) {
+      LOG << "Usage: " << argv[0] << " dbId" << ENDL;
+      std::string dbIdOra = 
+        "oracle://SERVER;schema=USER1;dbname=DB;user=USER1";
+      LOG << "Example: " << argv[0] << " '" << dbIdOra << "'\n" << ENDL;
+      return 1;
+    }
+    else {
+      dbId = argv[1];
+    } 
+  
+    // Instantiate a COOL Application
+    CoralApplication app;
+    
+    // If we can access a LFC and the user is not explicitely forbidding it,
+    // we try to use CORAL LFCReplicaService
+    if ( ::getenv("COOL_IGNORE_LFC") == NULL &&
+         ::getenv("LFC_HOST") != NULL ) 
+    {
+      // try to load CORAL LFCReplicaService
+      coral::IConnectionServiceConfiguration& connSvcConf =
+        app.connectionSvc().configuration();
+      connSvcConf.setAuthenticationService("CORAL/Services/LFCReplicaService");
+      connSvcConf.setLookupService("CORAL/Services/LFCReplicaService");
+    }
+
+    // Open the database and create a schema validation manager
+    IDatabaseSvc& dbSvc = app.databaseService();
+    IDatabasePtr db = dbSvc.openDatabase( dbId ); // open in readOnly mode
+    RalDatabase* ralDb = dynamic_cast<RalDatabase*>( db.get() );
+    RalSchemaValidation sv( ralDb );
+
+    // Validate the schema of the whole database
+    sv.validateDatabase();
+
+  }
+  
+  catch( cool::Exception& e ) 
+  {
+    LOG << "ERROR! Cool Exception: '" << e.what() << "'" << ENDL;
+    return 1;
+  }
+
+  catch( std::exception& e )
+  {
+    LOG << "ERROR! Standard C++ exception: '" << e.what() << "'" << ENDL;
+    return 1;
+  }
+
+  catch( ... ) 
+  {
+    LOG << "ERROR! Unknown exception caught" << ENDL;
+    return 1;
+  }
+
+  // Successful program termination
+  LOG << "Schema validation successfully completed" << ENDL;
+  return 0;
+  
+}
+
+//-----------------------------------------------------------------------------
diff --git a/RelationalCool/utilities/coolValidateSchema/test_missingTables.py b/RelationalCool/utilities/coolValidateSchema/test_missingTables.py
new file mode 100644
index 000000000..579f69c87
--- /dev/null
+++ b/RelationalCool/utilities/coolValidateSchema/test_missingTables.py
@@ -0,0 +1,73 @@
+#!/usr/bin/env python
+
+#
+# Martin's test for missing tables in coolValidateSchema (task #7691)
+# With Andrea's modifications - drop a table by brute force instead...
+#
+
+from PyCool import cool
+import os, sys, re
+
+# connect string for the schema owner
+connectString = 'Oracle-avalassi/COOLTEST'
+
+app = cool.Application()
+dbSvc = app.databaseService()
+svcVersion = dbSvc.serviceVersion()
+
+spec = cool.RecordSpecification()
+spec.extend( "I", cool.StorageType.Int32 )
+
+def checkValidateOutput(line) :
+        p = re.compile('.*Corrupt or missing table for folder \'([^\']*)\'.*');
+        m=p.match(line)
+        if ( m ) :
+                print "Found corrupt folder " , m.group(1)
+                return m.group(1)
+        return ""
+
+if (1):
+        # recreate the database and create folders
+        print "Drop the test database"
+        dbSvc.dropDatabase( connectString )
+        print "Create the test database as the owner"
+        db = dbSvc.createDatabase( connectString )
+        db.createFolderSet('/f1',"test folder set");
+        db.createFolder( '/f2', spec, "MV folder", \
+                         cool.FolderVersioning.MULTI_VERSION )
+        db.createFolder( '/f3', spec, "SV folder", \
+                         cool.FolderVersioning.SINGLE_VERSION )
+        db.closeDatabase()
+
+        # drop table in /f1 by brute force
+        err = os.system( "coolExecuteSql.csh %s -e 'DROP TABLE %s;'" % \
+                         ( connectString, "COOLTEST_F0001_TAGS_SEQ" ) );
+        if ( err != 0 ) :
+                print "Error: could not drop table COOLTEST_F0001_TAGS_SEQ"
+                sys.exit(err);
+
+        # drop table in /f2 by brute force
+        err = os.system( "coolExecuteSql.csh %s -e 'DROP TABLE %s;'" % \
+                         ( connectString, "COOLTEST_F0002_TAGS_SEQ" ) );
+        if ( err != 0 ) :
+                print "Error: could not drop table COOLTEST_F0002_TAGS_SEQ"
+                sys.exit(err);
+
+        # run coolValidateSchema on test database
+        print "Validate the schema using:\n",\
+              "coolValidateSchema %s" % connectString;
+        f = os.popen("coolValidateSchema %s" % connectString);
+        corruptFolders=[];
+        for line in f:
+               ret = checkValidateOutput(line);
+               if (ret != "") :
+                        corruptFolders.append(ret);
+
+        # check that coolValidateSchema reported the errors
+        expectedCorruptFolders =['/f1','/f2'] 
+        if (corruptFolders != expectedCorruptFolders) :
+                print "Error: expected ", expectedCorruptFolders,\
+                      " but found: ", corruptFolders
+                sys.exit(255)                
+        print "Test OK" 
+        sys.exit(0);
diff --git a/RelationalCool/utilities/coolValidateSchema/test_missingTables_roles.py b/RelationalCool/utilities/coolValidateSchema/test_missingTables_roles.py
new file mode 100644
index 000000000..18444357e
--- /dev/null
+++ b/RelationalCool/utilities/coolValidateSchema/test_missingTables_roles.py
@@ -0,0 +1,119 @@
+#!/usr/bin/env python
+
+#
+# Martin's test for missing tables in coolValidateSchema (task #7691)
+#
+
+from PyCool import cool
+import os, sys, re
+
+# connect string for the schema owner
+connectString = 'Oracle-avalassi/COOLTEST'
+# connect string for a writer 
+connectStringWriter = 'Oracle-avalassi(writer)/COOLTEST'
+
+# user name to whom writer privileges will be granted
+# (should be the one used in connectStringWriter)
+writerUser = 'lcg_cool_w'
+
+app = cool.Application()
+dbSvc = app.databaseService()
+svcVersion = dbSvc.serviceVersion()
+outLvl = app.outputLevel()
+
+spec = cool.RecordSpecification()
+spec.extend( "I", cool.StorageType.Int32 )
+
+def checkValidateOutput(line) :
+        p = re.compile('.*Corrupt or missing table for folder \'([^\']*)\'.*');
+        m=p.match(line)
+        if ( m ) :
+                print "Found corrupt folder " , m.group(1)
+                return m.group(1)
+        return ""
+
+if (1):
+        # recreate the database
+        print "Drop the test database"
+        dbSvc.dropDatabase( connectString )
+        print "Create the test database as the owner"
+        db = dbSvc.createDatabase( connectString )
+        db.closeDatabase()
+
+        # grant writer privileges to writerUser
+        print "Grant WRITER privileges"
+        err = os.system( "coolPrivileges %s GRANT WRITER %s" % \
+                         ( connectString, writerUser ) );
+        if ( err != 0 ) :
+                print "Error: could not grant writer privileges to '%s'" % \
+                      writerUser
+                sys.exit(err);
+       
+        # try to create folders with the writer user
+        # (this fails and is expected to corrupt the database)
+        print "Reopen the database as a writer\n"
+        ok=1; 
+        db = dbSvc.openDatabase( connectStringWriter, False )
+        app.setOutputLevel( 1 )
+
+       # try to create /f1
+        print "Try to create /f1"
+        try:
+                db.createFolderSet('/f1',"test folder set");
+                print "Error: 'createFolderSet()' did not throw... \n";
+                ok=0;
+        except RuntimeError:
+                print "Failed as expected\n";
+
+        # try to create /f2
+        print "Try to create /f2"
+        try:
+                db.createFolder( '/f2', spec, "MV folder", \
+                                 cool.FolderVersioning.MULTI_VERSION )
+                print "Error: creating multi version folder",\
+                      "with 'createFolder()' did not throw... \n";
+                ok=0;
+        #except RuntimeError:
+        #        print "Failed as expected\n";
+        except TypeError:
+                print "Failed as expected\n";
+
+        # try to create /f3
+        print "Try to create /f3"
+        try:
+                db.createFolder( '/f3', spec, "SV folder", \
+                                 cool.FolderVersioning.SINGLE_VERSION )
+                print "Error: creating single verstion folder",\
+                      "with 'createFolder()' did not throw... \n";
+                ok=0;
+        #except RuntimeError:
+        #        print "Failed as expected\n";
+        except TypeError:
+                print "Failed as expected\n";
+
+        # check that all failed
+        app.setOutputLevel( outLvl )
+        if ( ok == 0 ) :
+                print "Error: Some or all folder creation calls"\
+                      "did not fail as expected."
+                print "Error: Could not set up test database."
+                sys.exit(255);
+
+        # run coolValidateSchema on test database
+        print "Validate the schema using:\n",\
+              "coolValidateSchema %s" % connectString;
+        f = os.popen("coolValidateSchema %s" % connectString);
+        corruptFolders=[];
+        for line in f:
+               ret = checkValidateOutput(line);
+               if (ret != "") :
+                        corruptFolders.append(ret);
+
+        # check that coolValidateSchema reported the errors
+        expectedCorruptFolders =['/f1','/f2','/f3'] 
+        if (corruptFolders != expectedCorruptFolders) :
+                print "Error: expected ", expectedCorruptFolders,\
+                      " but found: ", corruptFolders
+                sys.exit(255)                
+        print "Passed test." 
+        sys.exit(0);
-- 
GitLab