diff --git a/28PATCHES2013/CoolKernel/CoolKernel/NEW/IField.h b/28PATCHES2013/CoolKernel/CoolKernel/NEW/IField.h
new file mode 100644
index 0000000000000000000000000000000000000000..a04c397b2cd2386f3f6f7d8f09b96f65a5486cf2
--- /dev/null
+++ b/28PATCHES2013/CoolKernel/CoolKernel/NEW/IField.h
@@ -0,0 +1,271 @@
+#ifndef COOLKERNEL_IFIELD_H
+#define COOLKERNEL_IFIELD_H 1
+
+// First of all, enable or disable the COOL290 API extensions (see bug #92204)
+#include "CoolKernel/VersionInfo.h"
+
+// Include files
+#include "CoolKernel/IFieldSpecification.h"
+#include "CoolKernel/RecordException.h"
+
+// Forward declarations
+namespace coral 
+{
+  class Attribute;
+}
+
+namespace cool
+{
+
+  //--------------------------------------------------------------------------
+
+  /** @class IField IField.h
+   *
+   *  Abstract interface to a data field of user-defined name and storage type.
+   *
+   *  A field is a transient data value that can be made persistent.
+   *  Its StorageType specification defines constraints on its allowed
+   *  data values (e.g. strings of less than 256 characters), to ensure
+   *  portability across different platforms and persistent backends.
+   *  While each StorageType is associated to a platform-dependent transient
+   *  C++ type and to a backend-dependent persistent (e.g. SQL) data type,
+   *  the StorageType class allows users to write their code to define and
+   *  handles records and fields in a platform- and backend-independent way.
+   *
+   *  All methods of the IField interface are const except for the two
+   *  methods (setValue and setNull) that allow changes to the data values.
+   *  Implementations of IField are responsible for enforcing the
+   *  StorageType constraints on the data values in these two and all other
+   *  non-const methods, as well as at construction and assignment time.
+   *  The use of const_cast on any const method is highly discouraged
+   *  as it may lead to data corruption inside the IField instance.
+   *
+   *  The data values at construction time are defined in the concrete
+   *  implementations of the IField interface: default C++ values are
+   *  recommended over nulls for all storage types (0 for numbers and
+   *  chars, false for bool, "" for strings, empty blob for blobs).
+   *  The value of a field is either null or a well-defined true type.
+   *  Once the field has been set to null, its previous true type value
+   *  is lost and the field can only be set again to non-null by setting
+   *  it equal to a true type value using the setValue method: there is no
+   *  such thing as a setNull(false) method to recover the previous value.
+   *
+   *  Note the special semantics of null values for string variables only.
+   *  For strings, setNull() is now considered equivalent to setValue(""):
+   *  after such calls, isNull() returns false, and data() returns "".
+   *  This has been introduced to avoid inconsistencies for Oracle databases
+   *  (where empty strings are treated as SQL NULL values - see bug #22381).
+   *  **WARNING**: CORAL Attribute's are different from COOL Field's in the
+   *  management of null values. IField::data<T>() throws if IField::isNull()
+   *  returns true, while coral::Attribute::data<T>() does not throw and
+   *  returns an undefined value if coral::Attribute::isNull() returns true.
+   *  Note also that IField::isNull() is always false for strings.
+   *
+   *  It is not possible to change the name or storage types of a field
+   *  via the IField interface: if necessary, this is the responsibility
+   *  of the concrete classes implementing IField or IFieldSpecification.
+   *
+   *  Implementations of the IField interface may or may not be based on
+   *  the coral::Attribute class. To simplify the port of user code to the
+   *  new API, an attribute() method is provided to retrieve the contents
+   *  of the IField as a (read-only) constant Attribute reference.
+   *  This is DEPRECATED and may be removed in a future COOL release.
+   *  **WARNING**: in line with was explained above about CORAL Attribute's
+   *  being different from COOL Field's in the management of null values, the
+   *  Attribute reference returned by the attribute() method will behave as
+   *  follows: for all types except strings, isNull() and attribute().isNull(),
+   *  as well as data() and attribute().data(), always return the same value;
+   *  for strings, isNull() always returns false, while data() returns ""
+   *  if either of attribute().isNull() or attribute.data<std::string>()==""
+   *  are true, but it is not guaranteed that both these conditions are true.
+   *
+   *  @author Andrea Valassi and Marco Clemencic
+   *  @date   2006-09-28
+   */
+
+  class IField 
+  {
+
+  public:
+
+    virtual ~IField() {}
+
+    /// Return the specification of this field.
+    virtual const IFieldSpecification& specification() const = 0;
+
+    /// Return the name of this field (from the spec).
+    const std::string& name() const;
+
+    /// Return the storage type of this field (from the spec).
+    const StorageType& storageType() const;
+
+    /// Is the value of this field null?
+    /// For strings, this is always false.
+    virtual bool isNull() const = 0;
+
+    /// Return the data value of this field (as true type).
+    /// Throw FieldWrongCppType if the field C++ type is not T.
+    /// Throw FieldIsNull the field is null, i.e. if isNull() is true.
+    /// For strings, return "" if setNull() was called.
+    template<typename T> const T& data() const;
+
+    /// Return the address of the true-type data value of this field.
+    /// Throw FieldIsNull the field is null, i.e. if isNull() is true.
+    /// For strings, return a pointer to "" if setNull() was called.
+    virtual const void* addressOfData() const = 0;
+
+    /// Set the value of this field to null: any previous value is lost.
+    /// For strings, setNull() is equivalent to setValue(""): data() and
+    /// addressOfData() will return "" and a pointer to "" after setNull().
+    virtual void setNull() = 0;
+
+    /// Set the value of this field to a well defined (non null) true-type.
+    /// Throw FieldWrongCppType if the field C++ type is not T.
+    /// For strings, setNull() is equivalent to setValue("").
+    template<typename T> void setValue( const T& value );
+
+    /// Set the value of this field equal to the value of another field
+    /// (with the same StorageType, but not necessarily the same name).
+    /// Throw FieldSpecificationWrongStorageType if field has the wrong type.
+    void setValue( const IField& field );
+
+    /// Compare the names, types and values of this and another field.
+    virtual bool operator== ( const IField& rhs ) const;
+
+    /// Compare the names, types and values of this and another field.
+    virtual bool operator!= ( const IField& rhs ) const;
+
+    /// Print the name, storage type and data value of this field.
+    virtual std::ostream& print( std::ostream& os ) const;
+
+    /// Print the data value of this field.
+    /// Print "NULL" if the field is null (print "" for null strings).
+    virtual std::ostream& printValue( std::ostream& os ) const = 0;
+
+    /// DEPRECATED - added for easier compatibility with COOL 1.3
+    /// (this is likely to be removed in a future COOL release).
+    /// Explicit conversion to a constant coral Attribute reference.
+    virtual const coral::Attribute& attribute() const = 0;
+
+#ifdef COOL290
+  protected:
+
+    /// Standard constructor is protected (see bug #95823)
+    IField() {}
+#endif
+
+  private:
+
+#ifdef COOL290
+    /// Copy constructor is private (see bug #95823)
+    IField( const IField& rhs );
+
+    /// Assignment operator is private (see bug #95823)
+    IField& operator=( const IField& rhs );
+#endif
+
+    /// Compare the values of this and another field.
+    /// The values of two fields are equal either if they are both non null
+    /// and their true type values are equal, or if they are both null.
+    /// Private method - this does not check that fields have the same type.
+    virtual bool compareValue( const IField& rhs ) const = 0;
+
+    /// Set the value of this field to a well defined (non null) true-type.
+    /// For strings, setNull() is equivalent to setValue("").
+    /// Throw FieldWrongCppType if the field C++ type is not cppType.
+    /// Private method - this will crash if the address is not of cppType type.
+    virtual void setValue( const std::type_info& cppType,
+                           const void* externalAddress ) = 0;
+
+  };
+
+  /// Print the name, storage type and data value of a field.
+  std::ostream& operator<<( std::ostream& s, const IField& field );
+
+  //--------------------------------------------------------------------------
+
+  inline const std::string& IField::name() const
+  {
+    return specification().name();
+  }
+
+  //--------------------------------------------------------------------------
+
+  inline const StorageType& IField::storageType() const
+  {
+    return specification().storageType();
+  }
+
+  //--------------------------------------------------------------------------
+
+  template<typename T>
+  inline const T& IField::data() const
+  {
+    if ( this->storageType().cppType() != typeid(T) )
+      throw FieldWrongCppType
+        ( this->name(), this->storageType(), typeid(T), "IField" );
+    if ( this->isNull() )
+      throw FieldIsNull
+        ( this->name(), this->storageType(), "IField" );
+    return *( static_cast< const T* >( this->addressOfData() ) );
+  }
+
+  //--------------------------------------------------------------------------
+
+  template<typename T>
+  inline void IField::setValue( const T& value )
+  {
+    this->setValue( typeid(T), &value );
+  }
+
+  //--------------------------------------------------------------------------
+
+  /// Set value to null if the other field is null, else set value from C++
+  /// address of the other field's value (as in coral::Attribute::fastCopy).
+  inline void IField::setValue( const IField& field )
+  {
+    if ( this->storageType() != field.storageType() )
+      throw FieldSpecificationWrongStorageType
+        ( this->name(), this->storageType(), field.storageType(), "IField" );
+    if ( field.isNull() )
+      this->setNull();
+    else
+      this->setValue( this->storageType().cppType(), field.addressOfData() );
+  }
+
+  //--------------------------------------------------------------------------
+
+  inline bool IField::operator==( const IField& rhs ) const
+  {
+    // Compare names, storage types and values
+    // (NB coral::Attribute::operator== does NOT compare names)
+    return ( this->specification() == rhs.specification() )
+      && this->compareValue( rhs );
+  }
+
+  //--------------------------------------------------------------------------
+
+  inline bool IField::operator!=( const IField& rhs ) const
+  {
+    return ( ! ( *this == rhs ) );
+  }
+
+  //--------------------------------------------------------------------------
+
+  inline std::ostream& IField::print( std::ostream& s ) const
+  {
+    s << name() << " (" << storageType().name() << ") : ";
+    return this->printValue( s );
+  }
+
+  //--------------------------------------------------------------------------
+
+  inline std::ostream& operator<<( std::ostream& s, const IField& field )
+  {
+    return field.print( s );
+  }
+
+  //--------------------------------------------------------------------------
+
+}
+#endif // COOLKERNEL_IFIELD_H
diff --git a/28PATCHES2013/CoolKernel/CoolKernel/NEW/IFieldSpecification.h b/28PATCHES2013/CoolKernel/CoolKernel/NEW/IFieldSpecification.h
new file mode 100644
index 0000000000000000000000000000000000000000..12ea493e2f65ea0b54d08e00c9ada4d15e3b570b
--- /dev/null
+++ b/28PATCHES2013/CoolKernel/CoolKernel/NEW/IFieldSpecification.h
@@ -0,0 +1,117 @@
+#ifndef COOLKERNEL_IFIELDSPECIFICATION_H
+#define COOLKERNEL_IFIELDSPECIFICATION_H 1
+
+// First of all, enable or disable the COOL290 API extensions (see bug #92204)
+#include "CoolKernel/VersionInfo.h"
+
+// Include files
+#include "CoolKernel/StorageType.h"
+
+// Forward declarations
+namespace coral
+{
+  class Attribute;
+}
+
+namespace cool
+{
+
+  // Forward declarations
+  class IField;
+
+  /** @class IFieldSpecification IFieldSpecification.h
+   *
+   *  Abstract interface to the specification of a data field
+   *  of user-defined name and storage type.
+   *
+   *  A field is a transient data value that can be made persistent.
+   *  Its StorageType specification defines constraints on its allowed
+   *  data values (e.g. strings of less than 256 characters), to ensure
+   *  portability across different platforms and persistent backends.
+   *  While each StorageType is associated to a platform-dependent transient
+   *  C++ type and to a backend-dependent persistent (e.g. SQL) data type,
+   *  the StorageType class allows users to write their code to define and
+   *  handles records and fields in a platform- and backend-independent way.
+   *
+   *  The IFieldSpecification interface only allows read-only access to
+   *  the specification of a record: appropriate methods to change the name
+   *  or storage type of a field are meant to be defined and implemented in
+   *  the concrete classes derived from it, if at all necessary.
+   *
+   *  Implementations of IField and IRecord are responsible for enforcing
+   *  the StorageType constraints on the data values in all of their
+   *  non-const methods, as well as at construction and assignment time.
+   *  The IFieldSpecification interface provides a validate() method to
+   *  check if the data offered by a IField complies to the specification.
+   *
+   *  Implementations of the IField interface may or may not be based
+   *  on the coral::Attribute class. For internal COOL usage, another
+   *  signature of the validate() method is provided to check if the
+   *  data in an Attribue complies to the field specification.
+   *  This is DEPRECATED and may be removed in a future COOL release.
+
+   *  @author Andrea Valassi and Marco Clemencic
+   *  @date   2006-09-22
+   */
+
+  class IFieldSpecification 
+  {
+
+  public:
+
+    virtual ~IFieldSpecification() {}
+
+    /// Return the name of this field.
+    virtual const std::string& name() const = 0;
+
+    /// Return the storage type of this field.
+    virtual const StorageType& storageType() const = 0;
+
+    /// Compare the names and storage types of this and another field.
+    virtual bool operator==( const IFieldSpecification& rhs ) const = 0;
+
+    /// Compare the names and storage types of this and another field.
+    virtual bool operator!=( const IFieldSpecification& rhs ) const = 0;
+
+    /// Check that a given field is compatible with this specification.
+    /// The field must have the same transient C++ type and a value
+    /// compatible with the persistent storage type of the 'reference' field.
+    /// If checkName is true, the field (as well as the attribute accessible
+    /// via the field) must also have the same name as the reference field (*).
+    /// Throw FieldSpecificationWrongName if field/attribute name is wrong (*).
+    /// Throw FieldSpecificationWrongStorageType if field has the wrong type.
+    /// Throw StorageTypeInvalidValue for values outside the allowed range.
+    virtual void validate( const IField& field,
+                           bool checkName = true ) const = 0;
+
+    /// DEPRECATED - added for easier compatibility with COOL 1.3
+    /// (this is likely to be removed in a future COOL release).
+    /// Check that a given attribute is compatible with this specification.
+    /// The attribute must have the same transient C++ type and a value
+    /// compatible with the persistent storage type of the 'reference' field.
+    /// If checkName is true, the attribute must also have the same name (*).
+    /// Throw FieldSpecificationWrongName if attribute name is wrong (*).
+    /// Throw StorageTypeWrongCppType if the attribute has the wrong C++ type.
+    /// Throw StorageTypeInvalidValue for values outside the allowed range.
+    virtual void validate( const coral::Attribute& attribute,
+                           bool checkName = true ) const = 0;
+
+#ifdef COOL290
+  protected:
+
+    /// Standard constructor is protected (see bug #95823)
+    IFieldSpecification() {}
+
+    /// Copy constructor is protected (see bug #95823)
+    IFieldSpecification( const IFieldSpecification& ) {}
+
+  private:
+
+    /// Assignment operator is private (see bug #95823)
+    IFieldSpecification& operator=( const IFieldSpecification& rhs );
+#endif
+
+  };
+
+}
+#endif // COOLKERNEL_IFIELDSPECIFICATION_H
diff --git a/28PATCHES2013/CoolKernel/CoolKernel/NEW/IFolderSpecification.h b/28PATCHES2013/CoolKernel/CoolKernel/NEW/IFolderSpecification.h
new file mode 100644
index 0000000000000000000000000000000000000000..90828057dcd6f9e7b376cb8fb25f12b081687d0a
--- /dev/null
+++ b/28PATCHES2013/CoolKernel/CoolKernel/NEW/IFolderSpecification.h
@@ -0,0 +1,108 @@
+#ifndef COOLKERNEL_IFOLDERSPECIFICATION_H
+#define COOLKERNEL_IFOLDERSPECIFICATION_H 1
+
+// First of all, enable or disable the COOL290 API extensions (see bug #92204)
+#include "CoolKernel/VersionInfo.h"
+
+// Include files
+#include "CoolKernel/IRecordSpecification.h"
+#include "CoolKernel/FolderVersioning.h"
+#ifdef COOL290
+#include "CoolKernel/PayloadMode.h"
+#endif
+
+namespace cool
+{
+
+  //--------------------------------------------------------------------------
+
+  /** @class IFolderSpecification IFolderSpecification.h
+   *
+   *  Abstract interface to the specification of a COOL "folder".
+   *
+   *  This includes the payload specification and the versioning mode.
+   *  The description is not included as it is a generic "HVS node"
+   *  property (it applies to folder sets as well as to folders).
+   *
+   *  This class only provides const access to the specification.
+   *  Creating or modifying it is the task of concrete derived classes.
+   *
+   *  @author Andrea Valassi and Marco Clemencic
+   *  @date   2006-09-22
+   */
+
+  class IFolderSpecification
+  {
+
+  public:
+
+    virtual ~IFolderSpecification() {}
+
+    /// Get the versioning mode (const).
+    virtual const FolderVersioning::Mode& versioningMode() const = 0;
+
+    /// Get the payload specification (const).
+    virtual const IRecordSpecification& payloadSpecification() const = 0;
+
+    /*
+    /// Get the channel specification (const).
+    virtual const IRecordSpecification& channelSpecification() const = 0;
+    */
+
+    /// Get the payload table flag (const).
+    /// DEPRECATED!! This data member will be removed in COOL290!!
+    virtual const bool& hasPayloadTable() const = 0;
+
+#ifdef COOL290
+    /// Get the payload mode (const).
+    virtual const PayloadMode::Mode& payloadMode() const = 0;
+#endif
+
+    /// Comparison operator.
+    bool operator==( const IFolderSpecification& rhs ) const;
+
+    /// Comparison operator.
+    bool operator!=( const IFolderSpecification& rhs ) const;
+
+#ifdef COOL290
+  protected:
+
+    /// Standard constructor is protected (see bug #95823)
+    IFolderSpecification() {}
+
+  private:
+
+    /// Copy constructor is private (see bug #95823)
+    IFolderSpecification( const IFolderSpecification& rhs );
+
+    /// Assignment operator is private (see bug #95823)
+    IFolderSpecification& operator=( const IFolderSpecification& rhs );
+#endif
+
+  };
+
+  //--------------------------------------------------------------------------
+
+  inline bool
+  IFolderSpecification::operator==( const IFolderSpecification& rhs ) const
+  {
+    if ( versioningMode() != rhs.versioningMode() ) return false;
+    if ( payloadSpecification() != rhs.payloadSpecification() ) return false;
+    //if ( channelSpecification() != rhs.channelSpecification() ) return false;
+    if ( hasPayloadTable() != rhs.hasPayloadTable() ) return false;
+    return true;
+  }
+
+  //--------------------------------------------------------------------------
+
+  inline bool
+  IFolderSpecification::operator!=( const IFolderSpecification& rhs ) const
+  {
+    return ( ! ( *this == rhs ) );
+  }
+
+  //--------------------------------------------------------------------------
+
+}
+
+#endif // COOLKERNEL_IFOLDERSPECIFICATION_H
diff --git a/28PATCHES2013/CoolKernel/CoolKernel/NEW/IRecord.h b/28PATCHES2013/CoolKernel/CoolKernel/NEW/IRecord.h
new file mode 100644
index 0000000000000000000000000000000000000000..7869e9a284d934977815d229bf4ebd62208fec94
--- /dev/null
+++ b/28PATCHES2013/CoolKernel/CoolKernel/NEW/IRecord.h
@@ -0,0 +1,221 @@
+#ifndef COOLKERNEL_IRECORD_H
+#define COOLKERNEL_IRECORD_H 1
+
+// First of all, enable or disable the COOL290 API extensions (see bug #92204)
+#include "CoolKernel/VersionInfo.h"
+
+// Include files
+#include <sstream>
+#include "CoolKernel/IField.h"
+#include "CoolKernel/IRecordSpecification.h"
+
+// Forward declarations
+namespace coral
+{
+  class AttributeList;
+}
+
+namespace cool
+{
+
+  //--------------------------------------------------------------------------
+
+  class IRecord
+  {
+
+    /** @class IRecord IRecord.h
+     *
+     *  Abstract interface to a data record: an ordered collection
+     *  of data fields of user-defined names and storage types.
+     *
+     *  A field is a transient data value that can be made persistent.
+     *  Its StorageType specification defines constraints on its allowed
+     *  data values (e.g. strings of less than 256 characters), to ensure
+     *  portability across different platforms and persistent backends.
+     *  While each StorageType is associated to a platform-dependent transient
+     *  C++ type and to a backend-dependent persistent (e.g. SQL) data type,
+     *  the StorageType class allows users to write their code to define and
+     *  handles records and fields in a platform- and backend-independent way.
+     *
+     *  All public methods of the IRecord interface are const: this is in
+     *  practice a read-only interface. The only non-const methods are those
+     *  that allow non-const access to the IField interfaces of its fields:
+     *  these are protected, to be used or implemented in derived classes.
+     *  Implementations of IField and IRecord are responsible for enforcing
+     *  the StorageType constraints on the data values in all of their
+     *  non-const methods, as well as at construction and assignment time.
+     *  The use of const_cast on any const method is highly discouraged
+     *  as it may lead to data corruption inside the IRecord instance.
+     *
+     *  It is not possible to add, remove, rename or change the types of fields
+     *  via the IRecord interface: if necessary, this is the responsibility
+     *  of the concrete classes implementing IRecord or IRecordSpecification.
+     *
+     *  Field names are a property of fields and their specifications: record
+     *  specifications only define which fields exist and in which order.
+     *  The IRecord base class manages field names and indexes according
+     *  to its record specification. The implementation of size, index and
+     *  operator[] is inlined and delegated to IRecordSpecification, while
+     *  the concrete derived classes must only implement the field() method.
+     *
+     *  Implementations of the IRecord interface may or may not be based on
+     *  the coral::AttributeList class. To simplify the port of user code,
+     *  an attributeList() method is provided to retrieve the contents of
+     *  the IRecord as a (read-only) constant AttributeList reference.
+     *  This is DEPRECATED and may be removed in a future COOL release.
+     *
+     *  @author Andrea Valassi and Marco Clemencic
+     *  @date   2006-09-28
+     */
+
+  public:
+
+    virtual ~IRecord() {}
+
+    /// Return the specification of this record.
+    virtual const IRecordSpecification& specification() const = 0;
+
+    /// Return the number of fields in this record (from the spec).
+    UInt32 size() const;
+
+    /// Return the index of a field in this record by its name (from the spec).
+    UInt32 index( const std::string& name ) const;
+
+    /// Return a field in this record by its name (const).
+    const IField& operator[] ( const std::string& name ) const;
+
+    /// Return a field in this record by its index in [0, N-1] (const).
+    const IField& operator[] ( UInt32 index ) const;
+
+    /// Comparison operator. Two records are equal if they have the same
+    /// fields (each with the same name, type and value), in the same order.
+    virtual bool operator== ( const IRecord& rhs ) const;
+
+    /// Comparison operator. Two records are equal if they have the same
+    /// fields (each with the same name, type and value), in the same order.
+    virtual bool operator!= ( const IRecord& rhs ) const;
+
+    /// Print the names, types and data values of all fields in this record.
+    virtual std::ostream& print( std::ostream& os ) const;
+
+    /// DEPRECATED - added for easier compatibility with COOL 1.3
+    /// (this is likely to be removed in a future COOL release).
+    /// Explicit conversion to a constant coral AttributeList reference.
+    virtual const coral::AttributeList& attributeList() const = 0;
+
+  protected:
+
+    /// Return a field in this record by its name (non-const).
+    IField& operator[] ( const std::string& name );
+
+    /// Return a field in this record by its index in [0, N-1] (non-const).
+    IField& operator[] ( UInt32 index );
+
+#ifdef COOL290
+    /// Standard constructor is protected (see bug #95823)
+    IRecord() {}
+
+    /// Copy constructor is protected (fix bug #95823)
+    IRecord( const IRecord& ) {}
+#endif
+
+  private:
+
+#ifdef COOL290
+    /// Assignment operator is private (fix bug #95823)
+    IRecord& operator=( const IRecord& rhs );
+#endif
+
+    /// Return a field in this record by its index in [0, N-1] (const).
+    virtual const IField& field( UInt32 index ) const = 0;
+
+    /// Return a field in this record by its index in [0, N-1] (non-const).
+    virtual IField& field( UInt32 index ) = 0;
+
+  };
+
+  /// Print the names, types and data values of all fields in a record.
+  std::ostream& operator<<( std::ostream& s, const IRecord& record );
+
+  //--------------------------------------------------------------------------
+
+  inline UInt32 IRecord::size() const
+  {
+    return specification().size();
+  }
+
+  //--------------------------------------------------------------------------
+
+  inline UInt32 IRecord::index( const std::string& name ) const
+  {
+    return specification().index( name );
+  }
+
+  //--------------------------------------------------------------------------
+
+  inline const IField& IRecord::operator[] ( const std::string& name ) const
+  {
+    return field( index( name ) );
+  }
+
+  //--------------------------------------------------------------------------
+
+  inline IField& IRecord::operator[] ( const std::string& name )
+  {
+    return field( index( name ) );
+  }
+
+  //--------------------------------------------------------------------------
+
+  inline const IField& IRecord::operator[] ( UInt32 index ) const
+  {
+    return field( index );
+  }
+
+  //--------------------------------------------------------------------------
+
+  inline IField& IRecord::operator[] ( UInt32 index )
+  {
+    return field( index );
+  }
+
+  //--------------------------------------------------------------------------
+
+  inline bool IRecord::operator==( const IRecord& rhs ) const
+  {
+    if ( this->specification() != rhs.specification() ) return false;
+    for ( UInt32 i = 0; i < this->size(); ++i )
+      if ( (*this)[i] != rhs[i] ) return false;
+    return true;
+  }
+
+  //--------------------------------------------------------------------------
+
+  inline bool IRecord::operator!=( const IRecord& rhs ) const
+  {
+    return ( ! ( *this == rhs ) );
+  }
+
+  //--------------------------------------------------------------------------
+
+  inline std::ostream& IRecord::print( std::ostream& os ) const
+  {
+    for ( UInt32 i = 0; i < this->size(); ++i )
+    {
+      if ( i > 0 ) os << ", ";
+      os << "[" << (*this)[i] << "]";
+    }
+    return os;
+  }
+
+  //--------------------------------------------------------------------------
+
+  inline std::ostream& operator<<( std::ostream& s, const IRecord& record )
+  {
+    return record.print( s );
+  }
+
+  //--------------------------------------------------------------------------
+
+}
+#endif // COOLKERNEL_IRECORD_H
diff --git a/28PATCHES2013/CoolKernel/CoolKernel/NEW/IRecordSelection.h b/28PATCHES2013/CoolKernel/CoolKernel/NEW/IRecordSelection.h
new file mode 100644
index 0000000000000000000000000000000000000000..689a4ea5face73d6de32e1062db7bcd5f2e1a465
--- /dev/null
+++ b/28PATCHES2013/CoolKernel/CoolKernel/NEW/IRecordSelection.h
@@ -0,0 +1,84 @@
+#ifndef COOLKERNEL_IRECORDSELECTION_H
+#define COOLKERNEL_IRECORDSELECTION_H 1
+
+// First of all, enable or disable the COOL290 API extensions (see bug #92204)
+#include "CoolKernel/VersionInfo.h"
+
+// Include files
+#include "CoolKernel/Record.h"
+
+namespace cool
+{
+
+  //--------------------------------------------------------------------------
+
+  /** @class IRecordSelection IRecordSelection.h
+   *
+   *  Abstract interface to a data record selection.
+   *  Inspired by the HARP IEventSelection interface.
+   *
+   *  This interface is designed to define a user 'payload query cut' which
+   *  can be passed as the last argument to the IFolder::browseObjects method.
+   *  Payload query cuts are meant to be applied after a preselection on tag,
+   *  channel and IOV range is executed on the server using optimized SQL.
+   *  Payload queries thus consist in a scan of individual preselected IOVs,
+   *  which can be applied either in the C++ client after downloading all
+   *  preselected IOVs, or directly on the database server (e.g. by appending
+   *  a final SQL selection fragment to the WHERE clause of an RDBMS query).
+   *
+   *  The 'describe' method is meant to provide an SQL-like (or ROOT-like)
+   *  translation of payload query cuts that can be directly appended to
+   *  the database server query. In the relational implementation of COOL,
+   *  this approach is followed for all 'trusted' concrete implementations
+   *  of IRecordSelection defined in the CoolKernel API.
+   *
+   *  By default, the 'select' method can also be used to apply payload
+   *  query cuts on preselected IOVs in the C++ client. In the relational
+   *  implementation of COOL, this is the default approach for executing
+   *  arbitrary payload queries from user-defined implementation classes.
+   *
+   *  @author Andrea Valassi
+   *  @date   2008-07-05
+   */
+
+  class IRecordSelection
+  {
+
+  public:
+
+    virtual ~IRecordSelection() {}
+
+    /// Can the selection be applied to a record with the given specification?
+    virtual bool canSelect( const IRecordSpecification& spec ) const = 0;
+
+    /// Apply the selection to the given record.
+    virtual bool select( const IRecord& record ) const = 0;
+
+    /// Describe the selection (with or without bind variables)
+    //virtual const std::string& describe( bool useBindVar = false ) const = 0;
+
+    /// Get the bind variables for the selection.
+    //virtual const IRecord& bindVariables() const = 0;
+
+    /// Clone the record selection (and any objects referenced therein).
+    virtual IRecordSelection* clone() const = 0;
+
+#ifdef COOL290
+  protected:
+
+    /// Standard constructor is protected (see bug #95823)
+    IRecordSelection() {}
+
+    /// Copy constructor is protected (see bug #95823)
+    IRecordSelection( const IRecordSelection& ) {}
+
+  private:
+
+    /// Assignment operator is private (see bug #95823)
+    IRecordSelection& operator=( const IRecordSelection& rhs );
+#endif
+
+  };
+
+}
+#endif // COOLKERNEL_IRECORDSELECTION_H
diff --git a/28PATCHES2013/CoolKernel/CoolKernel/NEW/IRecordSpecification.h b/28PATCHES2013/CoolKernel/CoolKernel/NEW/IRecordSpecification.h
new file mode 100644
index 0000000000000000000000000000000000000000..c7c7471e3f4ebb6f747fb63f4566c1f1ffa1d95f
--- /dev/null
+++ b/28PATCHES2013/CoolKernel/CoolKernel/NEW/IRecordSpecification.h
@@ -0,0 +1,151 @@
+#ifndef COOLKERNEL_IRECORDSPECIFICATION_H
+#define COOLKERNEL_IRECORDSPECIFICATION_H 1
+
+// First of all, enable or disable the COOL290 API extensions (see bug #92204)
+#include "CoolKernel/VersionInfo.h"
+
+// Include files
+#include "CoolKernel/IFieldSpecification.h"
+#include "CoolKernel/types.h"
+
+// Forward declarations
+namespace coral
+{
+  class AttributeList;
+}
+
+namespace cool
+{
+
+  // Forward declarations
+  class IRecord;
+
+  /** @class IRecordSpecification IRecordSpecification.h
+   *
+   *  Abstract interface to the specification of a data record: an ordered
+   *  collection of data fields of user-defined names and storage types.
+   *
+   *  A field is a transient data value that can be made persistent.
+   *  Its StorageType specification defines constraints on its allowed
+   *  data values (e.g. strings of less than 256 characters), to ensure
+   *  portability across different platforms and persistent backends.
+   *  While each StorageType is associated to a platform-dependent transient
+   *  C++ type and to a backend-dependent persistent (e.g. SQL) data type,
+   *  the StorageType class allows users to write their code to define and
+   *  handles records and fields in a platform- and backend-independent way.
+   *
+   *  The IRecordSpecification interface only allows read-only access to
+   *  the specification of a record: appropriate methods to add, remove
+   *  or change the names and storage types of fields are meant to be
+   *  defined and implemented in the concrete classes derived from it.
+   *
+   *  Field names are a property of fields and their specifications: record
+   *  specifications only define which fields exist and in which order.
+   *
+   *  Implementations of IField and IRecord are responsible for enforcing
+   *  the StorageType constraints on the data values in all of their
+   *  non-const methods, as well as at construction and assignment time.
+   *  The IRecordSpecification interface provides a validate() method to
+   *  check if the data offered by a IRecord complies to the specification.
+   *
+   *  Implementations of the IRecord interface may or may not be based on
+   *  the coral::AttributeList class. For internal COOL usage, another
+   *  signature of the validate() method is provided to check if the data
+   *  in an AttribueList complies to the record specification.
+   *  This is DEPRECATED and may be removed in a future COOL release.
+
+   *  @author Andrea Valassi and Marco Clemencic
+   *  @date   2006-09-22
+   */
+
+  class IRecordSpecification
+  {
+
+  public:
+
+    virtual ~IRecordSpecification() {}
+
+    /// Return the number of fields in this record specification.
+    virtual UInt32 size() const = 0;
+
+    /// Comparison operator. Two record specifications are equal if they have
+    /// the same fields (each with the same name and type), in the same order.
+    virtual bool operator==( const IRecordSpecification& rhs ) const = 0;
+
+    /// Comparison operator. Two record specifications are equal if they have
+    /// the same fields (each with the same name and type), in the same order.
+    virtual bool operator!=( const IRecordSpecification& rhs ) const = 0;
+
+    /// Does a field with this name exist?
+    virtual bool exists( const std::string& name ) const = 0;
+
+    /// Return a field given its index.
+    /// Throws RecordSpecificationUnknownField if no such field exists.
+    virtual const
+    IFieldSpecification& operator[] ( UInt32 index ) const = 0;
+
+    /// Return a field given its name.
+    /// Throws RecordSpecificationUnknownField if no such field exists.
+    virtual const
+    IFieldSpecification& operator[] ( const std::string& name ) const = 0;
+
+    /// Return the index of a field given its name.
+    /// Throws RecordSpecificationUnknownField if no such field exists.
+    virtual UInt32 index( const std::string& name ) const = 0;
+
+    /// Check that a given record is compatible with this specification.
+    /// For every 'reference' field in this specification, the record must
+    /// contain (in any order) one field with the name, the persistent storage
+    /// type and a value compatible with the storage type of that field.
+    /// If checkSize is true, the record must not contain any other fields (*).
+    /// Throw RecordSpecificationUnknownField if no field with a given name
+    /// exists (do not check that the attribute has the same name too).
+    /// Throw FieldSpecificationWrongStorageType if a field has the wrong type.
+    /// Throw StorageTypeInvalidValue for values outside the allowed range.
+    /// Throw RecordSpecificationWrongSize if record has too many fields (*).
+    virtual void validate( const IRecord& record,
+                           bool checkSize = true ) const = 0;
+
+    /// DEPRECATED - added for easier compatibility with COOL 1.3
+    /// (this is likely to be removed in a future COOL release).
+    /// Check that an attribute list is compatible with this specification.
+    /// For every 'reference' field in this specification, the list must
+    /// contain (in any order) one field with the name, the transient C++ type
+    /// and a value compatible with the persistent storage type of that field.
+    /// If checkSize is true, the list must not contain any other fields (*).
+    /// Throw coral::AttributeListException if an attribute does not exist.
+    /// Throw StorageTypeWrongCppType if an attribute has the wrong C++ type.
+    /// Throw StorageTypeInvalidValue for values outside the allowed range.
+    /// Throw RecordSpecificationWrongSize if list has too many attributes (*).
+    virtual void validate( const coral::AttributeList& attributeList,
+                           bool checkSize = true ) const = 0;
+
+    /*
+    /// DEPRECATED - added for easier compatibility with COOL 1.3
+    /// (this is likely to be removed in a future COOL release).
+    /// Explicit conversion to a coral AttributeListSpecification reference.
+    /// This makes it possible to construct a coral::AttributeList from
+    /// a cool::IRecordSpecification, "coral::AttributeList aList( spec );".
+    virtual const
+    coral::AttributeListSpecification& attributeListSpecification() const = 0;
+    */
+
+#ifdef COOL290
+  protected:
+
+    /// Standard constructor is protected (see bug #95823)
+    IRecordSpecification() {}
+
+    /// Copy constructor is protected (see bug #95823)
+    IRecordSpecification( const IRecordSpecification& ) {}
+
+  private:
+
+    /// Assignment operator is private (see bug #95823)
+    IRecordSpecification& operator=( const IRecordSpecification& rhs );
+#endif
+
+  };
+
+}
+#endif // COOLKERNEL_IRECORDSPECIFICATION_H
diff --git a/28PATCHES2013/CoolKernel/CoolKernel/NEW/ITime.h b/28PATCHES2013/CoolKernel/CoolKernel/NEW/ITime.h
new file mode 100644
index 0000000000000000000000000000000000000000..a17665acae7cc950104d1112e6038fa5bb40c2f0
--- /dev/null
+++ b/28PATCHES2013/CoolKernel/CoolKernel/NEW/ITime.h
@@ -0,0 +1,131 @@
+#ifndef COOLKERNEL_ITIME_H
+#define COOLKERNEL_ITIME_H 1
+
+// First of all, enable or disable the COOL290 API extensions (see bug #92204)
+#include "CoolKernel/VersionInfo.h"
+
+// Include files
+#include <ostream>
+
+namespace cool
+{
+
+  /** @class ITime ITime.h
+   *
+   *  Abstract interface to a generic COOL time class.
+   *
+   *  The implementation details are hidden from the public API.
+   *
+   *  @author Andrea Valassi
+   *  @date   2007-01-17
+   */
+
+  class ITime
+  {
+
+  public:
+
+    /// Destructor.
+    virtual ~ITime() {}
+
+    /// Returns the year.
+    virtual int year() const = 0;
+
+    /// Returns the month [1-12].
+    virtual int month() const = 0;
+
+    /// Returns the day [1-31].
+    virtual int day() const = 0;
+
+    /// Returns the hour [0-23].
+    virtual int hour() const = 0;
+
+    /// Returns the minute [0-59].
+    virtual int minute() const = 0;
+
+    /// Returns the second [0-59].
+    virtual int second() const = 0;
+
+    /// Returns the nanosecond [0-999999999].
+    virtual long nanosecond() const = 0;
+
+    /// Print to an output stream.
+    virtual std::ostream& print( std::ostream& os ) const = 0;
+
+    /// Comparison operator.
+    virtual bool operator==( const ITime& rhs ) const = 0;
+
+    /// Comparison operator.
+    virtual bool operator>( const ITime& rhs ) const = 0;
+
+    /// Comparison operator.
+    bool operator>=( const ITime& rhs ) const;
+
+    /// Comparison operator.
+    bool operator<( const ITime& rhs ) const;
+
+    /// Comparison operator.
+    bool operator<=( const ITime& rhs ) const;
+
+    /// Comparison operator.
+    bool operator!=( const ITime& rhs ) const;
+
+#ifdef COOL290
+  protected:
+
+    /// Standard constructor is protected (see bug #95823)
+    ITime() {}
+
+    /// Copy constructor is protected (see bug #95823)
+    ITime( const ITime& ) {}
+
+  private:
+
+    /// Assignment operator is private (see bug #95823)
+    ITime& operator=( const ITime& rhs );
+#endif
+
+  };
+
+  /// Print to an output stream.
+  std::ostream& operator<<( std::ostream& s, const ITime& time );
+
+  //--------------------------------------------------------------------------
+
+  inline bool ITime::operator>=( const ITime& rhs ) const
+  {
+    return ( (*this) > rhs || (*this) == rhs );
+  }
+
+  //--------------------------------------------------------------------------
+
+  inline bool ITime::operator<( const ITime& rhs ) const
+  {
+    return !( (*this) >= rhs );
+  }
+
+  //--------------------------------------------------------------------------
+
+  inline bool ITime::operator<=( const ITime& rhs ) const
+  {
+    return !( (*this) > rhs );
+  }
+
+  //--------------------------------------------------------------------------
+
+  inline bool ITime::operator!=( const ITime& rhs ) const
+  {
+    return !( (*this) == rhs );
+  }
+
+  //--------------------------------------------------------------------------
+
+  inline std::ostream& operator<<( std::ostream& s, const ITime& time )
+  {
+    return time.print( s );
+  }
+
+  //--------------------------------------------------------------------------
+
+}
+#endif // COOLKERNEL_ITIME_H
diff --git a/28PATCHES2013/RelationalCool/src/ISessionMgr.h.NEW.20120208 b/28PATCHES2013/RelationalCool/src/ISessionMgr.h.NEW.20120208
new file mode 100644
index 0000000000000000000000000000000000000000..b9849f0951f774f430517041f6f63cc053fcdb04
--- /dev/null
+++ b/28PATCHES2013/RelationalCool/src/ISessionMgr.h.NEW.20120208
@@ -0,0 +1,100 @@
+// $Id: ISessionMgr.h,v 1.1 2012/01/30 17:06:03 avalassi Exp $
+#ifndef RELATIONALCOOL_ISESSIONMGR_H
+#define RELATIONALCOOL_ISESSIONMGR_H
+
+// Include files
+#include "CoralBase/MessageStream.h"
+#include "RelationalAccess/ISessionProxy.h"
+
+// Local include files
+
+namespace cool 
+{
+
+  /** @class ISessionMgr ISessionMgr.h
+   *
+   *  Pure virtual interface to a manager of a relational database session.
+   *  
+   *  This interface knows nothing about tables specific to COOL.
+   *  It is only concerned with generic relational databases functionalities
+   *  (like those available through CORAL, which has no predefined schema).
+   *
+   *  This interface was first added as part of the patch for task #6154.
+   *
+   *  @author Martin Wache
+   *  @date   2010-11-26
+   */
+
+  class ISessionMgr 
+  {
+
+    friend class RalDatabase;
+    friend class RalQueryMgr;
+    friend class RalSchemaMgr;
+    friend class RalSequenceMgr;
+    friend class RalTransactionMgr;
+
+  public:
+
+    /// The destructor automatically disconnects from the database.
+    virtual ~ISessionMgr() {}
+
+    /// 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
+    virtual const std::string databaseTechnology() const = 0;
+
+    /// 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
+    virtual const std::string serverVersion() const = 0;
+
+    /// Return the schema name for the current connection.
+    virtual const std::string schemaName() const = 0;
+
+    /// Return the connection state of the database.
+    /// [Note that this is subtly different from RelationalDatabase::isOpen!]
+    virtual bool isConnected() const = 0;
+
+    /// (Re)connect to the database.
+    virtual void connect() = 0;
+
+    /// Close the database connection.
+    virtual void disconnect() = 0;
+
+    /// Required access mode to the database.
+    virtual bool isReadOnly() const = 0;
+    
+    /// Required access mode to the database.
+    virtual bool isReadOnlyManyTx() const = 0;
+    
+    /// Sleep to work around ORA-01466 if needed (bug #87935)
+    /// This can also be called by RalDatabase for RO single tx sessions
+    virtual void sleepFor01466() const = 0;
+
+    /// Get a CORAL MessageStream
+    virtual coral::MessageStream& log() const = 0;
+
+  protected:
+
+    /// Get a reference to the RAL database session.
+    /// Throw an exception if there is no connection to the database.
+    virtual coral::ISessionProxy& session() const = 0;
+
+  };
+
+}
+
+#endif 
diff --git a/28PATCHES2013/RelationalCool/src/NEW/RalDatabase.cpp b/28PATCHES2013/RelationalCool/src/NEW/RalDatabase.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..ec7711928a7a724a3c20639970f3dea6b47bf005
--- /dev/null
+++ b/28PATCHES2013/RelationalCool/src/NEW/RalDatabase.cpp
@@ -0,0 +1,1882 @@
+
+// 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 "RelationalPayloadTable.h"
+#include "RelationalQueryDefinition.h"
+#include "RelationalSequence.h"
+#include "RelationalSequenceMgr.h"
+#include "RelationalTableRow.h"
+#include "RelationalTagMgr.h"
+#include "RelationalTagSequence.h"
+#include "RelationalTagTable.h"
+#include "RelationalTag2TagTable.h"
+#include "SimpleObject.h"
+#include "TimingReportMgr.h"
+#include "TransRelFolder.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:  $";
+    const std::string cvsCheckin = "$Id: RalDatabase.cpp,v 1.649 2012/01/27 16:23:30 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 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 (unless in 
+  // 'manytx mode): all other clients use a dummy transaction manager!
+  //if ( !readOnly )
+  if ( !readOnly || sessionMgr()->isReadOnlyManyTx() )
+  {
+    setTransactionMgr( boost::shared_ptr<IRelationalTransactionMgr>
+                       ( new RalTransactionMgr( sessionMgr() ) ) );
+  }
+  else
+  {
+    setTransactionMgr( boost::shared_ptr<IRelationalTransactionMgr>
+                       ( new DummyTransactionMgr() ) );
+  }
+
+  // Initialize timing reports
+  if ( TimingReport::enabled() )
+  {
+    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.
+
+  // Do NOT check that DB is open: it is not! (bug #87090)
+  //checkDbOpenTransaction( "RalDatabase::refreshNode", cool::ReadWrite );
+
+  // Check ONLY that RW transaction is active (is this needed/ok?)
+  if ( !transactionMgr()->isActive() )
+    throw RelationalException( "Transaction is not active", 
+                               "RalDatabase::refreshNode" );
+  //if ( transactionMgr()->isReadOnly() )
+  //  throw RelationalException( "Transaction is read only", 
+  //                             "RalDatabase::refreshNode" );
+
+  // 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 );
+
+  // 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).
+
+  // Check that DB is open and RW transaction is active (is this needed/ok?)
+  checkDbOpenTransaction( "RalDatabase::refreshNode", cool::ReadWrite );
+
+  // 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;
+      if ( ! schemaMgr().dropTable( tableName ) ) status = false;
+    }
+
+    // Drop the tag shared sequence
+    {
+      std::string tableName = tagSharedSequenceName();
+      log() << coral::Debug << "Drop table " << tableName
+            << coral::MessageStream::endmsg;
+      if ( ! schemaMgr().dropTable( tableName ) ) status = false;
+    }
+
+    // Drop the sequence associated to the tag2tag table
+    {
+      std::string seqName =
+        RelationalTag2TagTable::sequenceName( tag2TagTableName() );
+      log() << coral::Debug << "Drop sequence " << seqName
+            << coral::MessageStream::endmsg;
+      if ( ! queryMgr().sequenceMgr().existsSequence( seqName ) )
+      {
+        status = false;
+      }
+      else
+      {
+        queryMgr().sequenceMgr().dropSequence( seqName );
+      }
+    }
+
+    // Drop the tag2tag table
+    {
+      std::string tableName = tag2TagTableName();
+      log() << coral::Debug << "Drop table " << tableName
+            << coral::MessageStream::endmsg;
+      if ( ! schemaMgr().dropTable( tableName ) ) status = false;
+    }
+
+    /*
+    // *** 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;
+      if ( ! schemaMgr().dropTable( tableName ) ) status = false;
+    }
+
+    // Drop the global head tag table
+    {
+      std::string tableName = globalHeadTagTableName();
+      log() << coral::Debug << "Drop table " << tableName
+            << coral::MessageStream::endmsg;
+      if ( ! schemaMgr().dropTable( tableName ) ) status = false;
+    }
+    // **** 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;
+      if ( ! schemaMgr().dropTable( tableName ) ) status = false;
+    }
+
+    // Drop the sequence associated to the node table
+    {
+      std::string seqName =
+        RelationalNodeTable::sequenceName( nodeTableName() );
+      log() << coral::Debug << "Drop sequence " << seqName
+            << coral::MessageStream::endmsg;
+      if ( ! queryMgr().sequenceMgr().existsSequence( seqName ) )
+      {
+        status = false;
+      }
+      else
+      {
+        queryMgr().sequenceMgr().dropSequence( seqName );
+      }
+    }
+
+    // Drop the node table
+    {
+      std::string tableName = nodeTableName();
+      log() << coral::Debug << "Drop table " << tableName
+            << coral::MessageStream::endmsg;
+      if ( ! schemaMgr().dropTable( tableName ) ) status = false;
+    }
+
+    /*
+    // *** 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;
+      //if ( ! schemaMgr().dropTable( tableName ) ) status = false;
+    }
+
+    // Drop the iovTables table
+    {
+      std::string tableName = iovTablesTableName();
+      //log() << coral::Debug << "Drop table " << tableName
+      //      << coral::MessageStream::endmsg;
+      //if ( ! schemaMgr().dropTable( tableName ) ) status = false;
+    }
+    // **** 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;
+      if ( ! schemaMgr().dropTable( tableName ) ) status = false;
+    }
+
+  }
+  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;
+}
+
+//-----------------------------------------------------------------------------
+
+void RalDatabase::refreshDatabase( bool keepNodes )
+{
+  log() << coral::Info << "Refresh database"
+        << ( keepNodes ? " (refresh nodes)" : " (drop nodes)" )
+        << "..." << coral::MessageStream::endmsg;
+
+  // Check that DB is open and RW transaction is active (is this needed/ok?)
+  checkDbOpenTransaction( "RalDatabase::refreshNode", cool::ReadWrite );
+
+  // Enclose the implementation in a try-catch block anyway,
+  // just to be able to print some debug messages on failures.
+  try
+  {
+
+    if ( !keepNodes )
+      // For each node, drop IOV table and sequence and delete the node row.
+      // Also delete any tags associated to the node from the global tag table
+      // and from the tag2tag table (otherwise FK constraints may be violated)
+      // Throw an Exception if the schema of any 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)!
+      dropAllNodes( true );  // keep the root node
+    else
+      refreshAllNodes();
+
+    // Delete all rows from the IOV shared sequence
+    {
+      std::string tableName = iovSharedSequenceName();
+      log() << coral::Debug << "Refresh table " << tableName
+            << coral::MessageStream::endmsg;
+      queryMgr().deleteAllTableRows( tableName );
+      // No need to init() or nextVal(): see RalSchemaMgr::createSharedSequence
+    }
+
+    // Delete all rows from the tag shared sequence
+    {
+      std::string tableName = tagSharedSequenceName();
+      log() << coral::Debug << "Refresh table " << tableName
+            << coral::MessageStream::endmsg;
+      queryMgr().deleteAllTableRows( tableName );
+      // No need to init() or nextVal(): see RalSchemaMgr::createSharedSequence
+    }
+
+    // Delete all rows from the sequence associated to the tag2tag table
+    {
+      std::string seqName =
+        RelationalTag2TagTable::sequenceName( tag2TagTableName() );
+      log() << coral::Debug << "Refresh sequence " << seqName
+            << coral::MessageStream::endmsg;
+      queryMgr().deleteAllTableRows( seqName );
+      queryMgr().sequenceMgr().initSequence( seqName );
+      // No need to nextVal(): see RalSchemaMgr::createTag2TagTable
+    }
+
+    // Delete all rows from the tag2tag table
+    {
+      std::string tableName = tag2TagTableName();
+      log() << coral::Debug << "Refresh table " << tableName
+            << coral::MessageStream::endmsg;
+      queryMgr().deleteAllTableRows( tableName );
+    }
+
+    /*
+    // *** START *** 3.0.0 schema extensions (task #4396)
+    // Delete all rows from the global user tag table
+    {
+      std::string tableName = globalUserTagTableName();
+      log() << coral::Debug << "Refresh table " << tableName
+            << coral::MessageStream::endmsg;
+      queryMgr().deleteAllTableRows( tableName );
+    }
+
+    // Delete all rows from the global head tag table
+    {
+      std::string tableName = globalHeadTagTableName();
+      log() << coral::Debug << "Refresh table " << tableName
+            << coral::MessageStream::endmsg;
+      queryMgr().deleteAllTableRows( tableName );
+    }
+    // **** END **** 3.0.0 schema extensions (task #4396)
+    */
+
+    // Delete all rows from the global tag table
+    {
+      std::string tableName = globalTagTableName();
+      log() << coral::Debug << "Refresh table " << tableName
+            << coral::MessageStream::endmsg;
+      queryMgr().deleteAllTableRows( tableName );
+    }
+
+    // Delete all rows from the sequence associated to the node table
+    // (NB call nextVal: see RalSchemaMgr::createNodeTable)
+    if ( !keepNodes )
+    {
+      std::string seqName =
+        RelationalNodeTable::sequenceName( nodeTableName() );
+      log() << coral::Debug << "Refresh sequence " << seqName
+            << coral::MessageStream::endmsg;
+      queryMgr().deleteAllTableRows( seqName );
+      queryMgr().sequenceMgr().initSequence( seqName );
+      queryMgr().sequenceMgr().getSequence( seqName )->nextVal(); // root node!
+    }
+
+    // Do nothing about the node table
+    // (could delete all rows except root, but we already dropped all nodes)
+    {
+      std::string tableName = nodeTableName();
+      log() << coral::Debug << "Refresh table " << tableName
+            << coral::MessageStream::endmsg;
+    }
+
+    /*
+    // *** START *** 3.0.0 schema extensions (task #4307)
+    // Delete all rows from the channelTables table
+    {
+      std::string tableName = channelTablesTableName();
+      //log() << coral::Debug << "Refresh table " << tableName
+      //      << coral::MessageStream::endmsg;
+      //queryMgr().deleteAllTableRows( tableName );
+    }
+
+    // Delete all rows from the iovTables table
+    {
+      std::string tableName = iovTablesTableName();
+      //log() << coral::Debug << "Refresh table " << tableName
+      //      << coral::MessageStream::endmsg;
+      //queryMgr().deleteAllTableRows( tableName );
+    }
+    // **** END **** 3.0.0 schema extensions (task #4307)
+    */
+
+    // Do nothing about the main table
+    {
+      std::string tableName = mainTableName();
+      log() << coral::Debug << "Refresh table " << tableName
+            << coral::MessageStream::endmsg;
+    }
+
+  }
+  catch ( std::exception& e )
+  {
+    log() << coral::Warning << "Exception caught in refreshDatabase(): "
+          << e.what() << coral::MessageStream::endmsg;
+    throw;
+  }
+
+  // Success: the database has been refreshed
+  log() << coral::Info << "Refresh database"
+        << ( keepNodes ? " (refresh nodes)" : " (drop nodes)" )
+        << "... DONE" << coral::MessageStream::endmsg;
+}
+
+//-----------------------------------------------------------------------------
+
+void RalDatabase::refreshAllNodes()
+{
+  log() << coral::Info << "Refresh all nodes..."
+        << coral::MessageStream::endmsg;
+
+  // Listing the nodes in reverse order may be better
+  std::vector<std::string> nodes( listAllNodes( false ) );
+  std::vector<std::string>::const_iterator node;
+  for ( node = nodes.begin(); node != nodes.end(); node++ )
+    refreshNode( *node );
+
+  // Success: the nodes have been been refreshed
+  log() << coral::Info << "Refresh all nodes... DONE"
+        << coral::MessageStream::endmsg;
+}
+
+//-----------------------------------------------------------------------------
+
+void RalDatabase::refreshNode( const std::string& fullPath )
+{
+  log() << coral::Debug << "Refresh node '" << fullPath << "' ..."
+        << coral::MessageStream::endmsg;
+  checkDbOpenTransaction("RalDatabase::refreshNode", cool::ReadWrite );
+
+  // 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::Error << "Node '" << fullPath
+          << "' cannot be refreshed (node not found)"
+          << coral::MessageStream::endmsg;
+    throw;
+  } 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::Error << "The node table cannot be queried: '"
+          << e.what() << coral::MessageStream::endmsg;
+    throw;
+  }
+  bool isLeaf =
+    nodeRow[RelationalNodeTable::columnNames::nodeIsLeaf].data<bool>();
+  unsigned int nodeId =
+    nodeRow[RelationalNodeTable::columnNames::nodeId].data<unsigned int>();
+
+  // 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 refresh 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 refresh 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" );
+  }
+
+  // TRY block
+  try
+  {
+
+    // Folder: refresh folder-specific tables and sequences
+    if ( isLeaf )
+    {
+      std::string objectTableName =
+        RelationalFolder::objectTableName( nodeRow.data() );
+      std::string payloadTableName =
+        RelationalFolder::payloadTableName( 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;
+      // Refresh tables for MV folders
+      if ( versioningMode == FolderVersioning::MULTI_VERSION )
+      {
+        // Refresh iov2tag table first (it has FK constraints on other tables)
+        tableName = object2TagTableName;
+        log() << "Refresh table " << tableName << coral::MessageStream::endmsg;
+        queryMgr().deleteAllTableRows( tableName );
+        // Refresh local tag table
+        tableName = tagTableName;
+        log() << "Refresh table " << tableName << coral::MessageStream::endmsg;
+        queryMgr().deleteAllTableRows( tableName );
+        // Refresh local tag sequence
+        // (NB call nextVal: see RalSchemaMgr::createTagSequence)
+        seqName = tagSequenceName;
+        log() << "Refresh sequence " << seqName
+              << coral::MessageStream::endmsg;
+        queryMgr().deleteAllTableRows( seqName );
+        queryMgr().sequenceMgr().initSequence( seqName );
+        queryMgr().sequenceMgr().getSequence( seqName )->nextVal();
+      }
+      // vector  payload table
+      tableName = payloadTableName;
+      if ( RelationalFolder::payloadMode( nodeRow.data() ) == 
+           PayloadMode::VECTORPAYLOAD )  
+      {
+        log() << "Refresh table " << tableName << coral::MessageStream::endmsg;
+        queryMgr().deleteAllTableRows( tableName );
+        // Refresh payload sequence
+        // (NB call nextVal: see RalSchemaMgr::createPayloadTable)
+      };
+      // Refresh iov table
+      tableName = objectTableName;
+      log() << "Refresh table " << tableName << coral::MessageStream::endmsg;
+      queryMgr().deleteAllTableRows( tableName );
+      // Refresh iov sequence
+      // (NB call nextVal: see RalSchemaMgr::createObjectTable)
+      seqName = RelationalObjectTable::sequenceName( objectTableName );
+      log() << "Refresh sequence " << seqName << coral::MessageStream::endmsg;
+      queryMgr().deleteAllTableRows( seqName );
+      queryMgr().sequenceMgr().initSequence( seqName );
+      queryMgr().sequenceMgr().getSequence( seqName )->nextVal();
+      // Refresh payload table if it exists
+      tableName = payloadTableName;
+      if ( RelationalFolder::payloadMode( nodeRow.data() ) == 
+           PayloadMode::SEPARATEPAYLOAD )  
+      {
+        log() << "Refresh table " << tableName << coral::MessageStream::endmsg;
+        queryMgr().deleteAllTableRows( tableName );
+        // Refresh payload sequence
+        // (NB call nextVal: see RalSchemaMgr::createPayloadTable)
+        seqName = RelationalPayloadTable::sequenceName( payloadTableName );
+        log() << "Refresh sequence " << seqName
+              << coral::MessageStream::endmsg;
+        queryMgr().deleteAllTableRows( seqName );
+        queryMgr().sequenceMgr().initSequence( seqName );
+        queryMgr().sequenceMgr().getSequence( seqName )->nextVal();
+      };
+      // Refresh channel table last (it is referenced by FKs in the IOV table)
+      tableName = RelationalChannelTable::defaultTableName
+        ( defaultTablePrefix(), nodeId );
+      log() << "Refresh table " << tableName << coral::MessageStream::endmsg;
+      queryMgr().deleteAllTableRows( tableName );
+    }
+
+    // Folder set
+    else
+    {
+      // Refresh local tag sequence
+      // (NB call nextVal: see RalSchemaMgr::createTagSequence)
+      std::string tagSequenceName = RelationalTagSequence::sequenceName
+        ( defaultTablePrefix(), nodeId );
+      std::string seqName = tagSequenceName;
+      log() << "Refresh sequence " << seqName << coral::MessageStream::endmsg;
+      queryMgr().deleteAllTableRows( seqName );
+      queryMgr().sequenceMgr().initSequence( seqName );
+      queryMgr().sequenceMgr().getSequence( seqName )->nextVal();
+    }
+  }
+
+  // CATCH block
+  catch ( std::exception& e )
+  {
+    log() << coral::Fatal << "Exception caught in refreshNode(): '"
+          << e.what() << "'" << std::endl;
+  }
+
+  // Return
+  log() << coral::Debug << "Refresh node '" << fullPath << "' ... DONE"
+        << coral::MessageStream::endmsg;
+}
+
+//-----------------------------------------------------------------------------
+
+UInt32 RalDatabase::insertNodeTableRow
+( const std::string& fullPath,
+  const std::string& description,
+  bool createParents,
+  bool isLeaf,
+  const std::string& payloadSpecDesc,
+  FolderVersioning::Mode versioningMode,
+  PayloadMode::Mode payloadMode )
+{
+  checkDbOpenTransaction( "RalDatabase::insertNodeTableRow", cool::ReadWrite );
+
+  // 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 isParentLeaf =
+      row[RelationalNodeTable::columnNames::nodeIsLeaf].data<bool>();
+    if ( isParentLeaf ) {
+      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(); // nextVal -> recent!
+
+  // 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();
+  Record data( nodeTableSpec );
+  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
+                     ( payloadMode ) ) );
+  }
+  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::folderVersioningMode].setValue
+      ( (int)versioningMode );
+    data[RelationalNodeTable::columnNames::folderPayloadSpecDesc].setValue
+      ( payloadSpecDesc );
+    data[RelationalNodeTable::columnNames::folderPayloadInline].setValue
+      ( RelationalFolder::folderSchemaPayloadMode( payloadMode ) );
+    if ( payloadMode != PayloadMode::INLINEPAYLOAD )
+      data[RelationalNodeTable::columnNames::folderPayloadExtRef].setValue
+        ( RelationalPayloadTable::defaultTableName
+          ( defaultTablePrefix(), nodeId ) );
+    else
+      data[RelationalNodeTable::columnNames::folderPayloadExtRef].setValue
+        ( std::string( "" ) );
+    data[RelationalNodeTable::columnNames::folderChannelSpecDesc].setValue
+      ( std::string( "" ) );
+    data[RelationalNodeTable::columnNames::folderChannelExtRef].setValue
+      ( std::string( "" ) );
+    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 default values for folder sets
+    data[RelationalNodeTable::columnNames::folderVersioningMode].setValue
+      ( (int)FolderVersioning::NONE ); // default for folder sets
+    data[RelationalNodeTable::columnNames::folderPayloadSpecDesc].setValue
+      ( std::string( "" ) );
+    data[RelationalNodeTable::columnNames::folderPayloadInline].setValue
+      ( RelationalFolderSet::folderSetSchemaPayloadMode() ); // default (0)
+    data[RelationalNodeTable::columnNames::folderPayloadExtRef].setValue
+      ( std::string( "" ) );
+    data[RelationalNodeTable::columnNames::folderChannelSpecDesc].setValue
+      ( std::string( "" ) );
+    data[RelationalNodeTable::columnNames::folderChannelExtRef].setValue
+      ( std::string( "" ) );
+    data[RelationalNodeTable::columnNames::folderObjectTableName].setValue
+      ( std::string( "" ) );
+    data[RelationalNodeTable::columnNames::folderTagTableName].setValue
+      ( std::string( "" ) );
+    data[RelationalNodeTable::columnNames::folderObject2TagTableName].setValue
+      ( std::string( "" ) );
+    data[RelationalNodeTable::columnNames::folderChannelTableName].setValue
+      ( std::string( "" ) );
+  }
+
+  /*
+  // Check that all column values are within their allowed range.
+  // REMOVE? This is already done by the IField::setValue calls above.
+  nodeTableSpec.validate( data.attributeList() );
+  */
+
+  // Perform the actual db update
+  queryMgr().insertTableRow( nodeTableName(), data );
+  return nodeId;
+}
+
+//-----------------------------------------------------------------------------
+
+IFolderSetPtr RalDatabase::createFolderSet( const std::string& fullPath,
+                                            const std::string& description,
+                                            bool createParents )
+{
+  log() << coral::Verbose
+        << "Create folder set " << fullPath << coral::MessageStream::endmsg;
+
+  if ( ! transactionMgr()->autoTransactions() ) {
+    throw RelationalException("Cannot create folder set in manual "
+                              "transaction mode", "RalDatabase");
+  }
+ 
+  // Cross-check that the database is open
+  checkDbOpenTransaction( "RalDatabase::createFolderSet", cool::ReadWrite );
+
+  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");
+  }
+  IFolderPtr folder =
+    createFolder( fullPath, payloadSpec, description,
+                    versioningMode, createParents, PayloadMode::INLINEPAYLOAD );
+  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");
+  }
+  FolderVersioning::Mode versioningMode = folderSpec.versioningMode();
+  const IRecordSpecification& payloadSpec = folderSpec.payloadSpecification();
+  IFolderPtr folder =
+#ifdef COOL290
+    createFolder( fullPath, payloadSpec, description,
+                  versioningMode, createParents, folderSpec.payloadMode() );
+#else
+    createFolder( fullPath, payloadSpec, description,
+                  versioningMode, createParents, 
+                  ( folderSpec.hasPayloadTable() ? 
+                    PayloadMode::SEPARATEPAYLOAD :
+                    PayloadMode::INLINEPAYLOAD )
+                );
+#endif
+  return folder;
+}
+
+//-----------------------------------------------------------------------------
+
+IFolderPtr RalDatabase::createFolder
+( const std::string& fullPath,
+  const IRecordSpecification& payloadSpec,
+  const std::string& description,
+  FolderVersioning::Mode versioningMode,
+  bool createParents,
+  PayloadMode::Mode payloadMode )
+{
+  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, payloadMode );
+
+
+  // Create the IOV table for the folder
+  std::string objectTableName = RelationalObjectTable::defaultTableName
+    ( defaultTablePrefix(), nodeId );
+  std::string payloadTableName = "";
+  if ( payloadMode != PayloadMode::INLINEPAYLOAD )   
+    payloadTableName = RelationalPayloadTable::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 );
+
+    if ( payloadMode == PayloadMode::SEPARATEPAYLOAD ) {
+      schemaMgr().createPayloadTable( payloadTableName,
+                                      objectTableName,
+                                      payloadSpec,
+                                      payloadMode );
+      schemaMgr().createObjectTable
+        ( objectTableName, channelTableName,
+          RelationalPayloadTable::defaultSpecification( payloadMode ),
+          versioningMode, payloadTableName, payloadMode );
+    }
+    else  if ( payloadMode == PayloadMode::VECTORPAYLOAD) 
+    {
+      //std::cout << "creating vector folder " << std::endl;
+      schemaMgr().createObjectTable
+        ( objectTableName, channelTableName,
+          RecordSpecification(),
+          versioningMode, payloadTableName, payloadMode );
+
+      schemaMgr().createPayloadTable( payloadTableName,
+                                      objectTableName,
+                                      payloadSpec,
+                                      payloadMode );
+    }
+    else 
+    { 
+      // inline payload
+      schemaMgr().createObjectTable
+        ( objectTableName, channelTableName, payloadSpec,
+          versioningMode, "", payloadMode );
+    }
+
+    if ( versioningMode == FolderVersioning::MULTI_VERSION ) {
+      schemaMgr().createTagSequence( tagSequenceName );
+      schemaMgr().createTagTable( tagTableName );
+      schemaMgr().createObject2TagTable( obj2tagTableName, 
+                                         objectTableName, 
+                                         tagTableName, 
+                                         payloadTableName,
+                                         payloadMode );
+    }
+
+  } 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;
+
+  checkDbOpenTransaction( "updateNodeTableDescription", cool::ReadWrite );
+
+  // Define the SET and WHERE clauses for the update using bind variables
+  RecordSpecification updateDataSpec;
+  updateDataSpec.extend( "desc",
+                         RelationalNodeTable::columnTypeIds::nodeDescription );
+  updateDataSpec.extend( "path",
+                         RelationalNodeTable::columnTypeIds::nodeFullPath );
+  Record updateData( updateDataSpec );
+  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" );
+
+}
+
+//-----------------------------------------------------------------------------
+
+IFolderPtr RalDatabase::getFolder( const std::string& fullPath )
+{
+  if ( TimingReportMgr::isActive() )
+    TimingReportMgr::startTimer( "cool::RalDatabase::getFolder()" );
+
+  checkDbOpenTransaction( "RalDatabase::getFolder", cool::ReadOnly );
+
+  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 )
+{
+  log() << "Get folderset with name " << fullPath
+        << coral::MessageStream::endmsg;
+  checkDbOpenTransaction( "RalDatabase::getFolderSet", cool::ReadOnly );
+
+  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( bool keepRoot )
+{
+  log() << coral::Info << "Drop all nodes ("
+        << ( keepRoot ? "" : "do not" )
+        << "keep root)..." << 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;
+
+  // Reinitialise the node sequence if keepRoot is true (for tests only!)
+  std::string nodeSqNm = RelationalNodeTable::sequenceName( nodeTableName() );
+  unsigned int nodeSqCurr = 0; // Get the real value in the RO transaction
+
+  // 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)!
+  {
+
+    // Iterate over all folders and folder sets and compare schema versions
+    // to a well-defined hardcoded list supported by this s/w release
+    RelationalQueryDefinition queryDef;
+    queryDef.addFromItem( nodeTableName() );
+    queryDef.addSelectItems( RelationalNodeTable::tableSpecification() );
+    std::vector<RelationalTableRow> rows =
+      queryMgr().fetchOrderedRows( queryDef ); // no WHERE or ORDER clause
+    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" );
+      }
+    }
+
+    // Get the current value of the node sequence (only needed if keepRoot)
+    // NB: disable the for update clause (it needs a R/W transaction)
+    if ( keepRoot )
+    {
+      bool forUpdate = false;
+      nodeSqCurr =
+        queryMgr().sequenceMgr().getSequence( nodeSqNm )->currVal( forUpdate );
+    }
+
+  }
+
+  // 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;
+  HvsPathHandler handler;
+  for ( node = nodes.begin(); node != nodes.end(); node++ )
+  {
+    if ( !keepRoot || *node != handler.rootFullPath() )
+    {
+      log() << coral::Debug << "Will drop '" << *node << "'"
+            << coral::MessageStream::endmsg;
+    }
+  }
+  for ( node = nodes.begin(); node != nodes.end(); node++ )
+  {
+    if ( !keepRoot || *node != handler.rootFullPath() )
+    {
+      log() << coral::Debug << "Now drop '" << *node << "'"
+            << coral::MessageStream::endmsg;
+      if ( ! dropNode( *node ) ) status = false;
+    }
+  }
+
+  // If you keep the root node, this is only used for tests:
+  // reinitialise the sequence associated to the node table.
+  if ( keepRoot && nodeSqCurr > 0 )
+  {
+    log() << coral::Debug << "Refresh sequence " << nodeSqNm
+          << coral::MessageStream::endmsg;
+    queryMgr().deleteAllTableRows( nodeSqNm );
+    queryMgr().sequenceMgr().initSequence( nodeSqNm );
+    queryMgr().sequenceMgr().getSequence( nodeSqNm )->nextVal(); // root node!
+  }
+
+  // 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 ("
+        << ( keepRoot ? "" : "do not " )
+        << "keep root)... DONE" << coral::MessageStream::endmsg;
+  return status;
+
+}
+
+//-----------------------------------------------------------------------------
+
+bool RalDatabase::dropNode( const std::string& fullPath )
+{
+  log() << "Drop node with full path " << fullPath
+        << coral::MessageStream::endmsg;
+  checkDbOpenTransaction( "RalDatabase::dropNode", cool::ReadWrite );
+
+  // 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 payloadTableName =
+      RelationalFolder::payloadTableName( 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 );
+      }
+    }
+    // for vector payload folders, drop payload table before iov table
+    if ( RelationalFolder::payloadMode( nodeRow.data() ) == 
+         PayloadMode::VECTORPAYLOAD ) 
+    {
+      tableName = payloadTableName;
+      if ( ! schemaMgr().dropTable( tableName ) ) status = false;
+    }
+    // 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 );
+    }
+    // if exists, drop payload table
+    tableName = payloadTableName;
+    if ( RelationalFolder::payloadMode( nodeRow.data() ) ==
+         PayloadMode::SEPARATEPAYLOAD ) 
+    {
+      if ( ! schemaMgr().dropTable( tableName ) ) status = false;
+      // Drop payload sequence
+      seqName = RelationalPayloadTable::sequenceName( payloadTableName );
+      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
+  RecordSpecification whereDataSpec;
+  whereDataSpec.extend( "fullName",
+                        RelationalNodeTable::columnTypeIds::nodeFullPath );
+  Record whereData( whereDataSpec );
+  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 COOL400
+ITransactionPtr RalDatabase::startTransaction()
+{
+  transactionMgr()->setAutoTransactions( false );
+  return ITransactionPtr( new ManualTransaction( transactionMgr() ) );
+}
+#endif
+
+//-----------------------------------------------------------------------------
diff --git a/28PATCHES2013/RelationalCool/src/NEW/RalDatabase.h b/28PATCHES2013/RelationalCool/src/NEW/RalDatabase.h
new file mode 100644
index 0000000000000000000000000000000000000000..ba16ce761692c9a0fd77863b7963d8e98e5d1845
--- /dev/null
+++ b/28PATCHES2013/RelationalCool/src/NEW/RalDatabase.h
@@ -0,0 +1,290 @@
+#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"
+
+// Disable icc warning 444: boost::enable_shared_from_this has non virtual dtor
+#ifdef __ICC
+#pragma warning (push)
+#pragma warning (disable: 444)
+#endif
+
+namespace cool
+{
+
+  // Forward declarations
+  class RalDatabase;
+  class RalObjectMgr;
+  class RelationalObjectTableRow;
+  class RelationalSequence;
+  class RelationalTableRow;
+  class SimpleObject;
+  class TransRalDatabase;
+
+  // 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 wrapper needs to be able to create databases
+    friend class TransRalDatabase;
+
+    // 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;
+
+    /// Get the RelationalQueryMgr
+    const RelationalQueryMgr& queryMgr() const
+    {
+      return sessionMgr()->queryMgr();
+    }
+
+    /// 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 );
+
+    /// Retrieve an existing folderset and return the corresponding manager
+    /// Throw an exception if the folderset does not exist
+    IFolderSetPtr getFolderSet( const std::string& fullPath );
+
+    /// Return the folderset manager for a given row
+    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
+    IFolderPtr createFolder
+    ( const std::string& fullPath,
+      const IRecordSpecification& payloadSpec,
+      const std::string& description,
+      FolderVersioning::Mode mode,
+      bool createParents,
+      PayloadMode::Mode payloadMode );
+
+    /// Retrieve an existing folder and return the corresponding manager
+    /// Throw an exception if the folder does not exist
+    IFolderPtr getFolder( const std::string& fullPath );
+
+    /// Return the folder manager for a given row
+    IFolderPtr getFolder( const RelationalTableRow& row );
+
+    /// Retrieve all existing folders and folder sets
+    /// (preload the cache - used for ReadOnly connections only)
+    void preloadAllNodes();
+
+    /// Drop an existing node.
+    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 COOL400
+    /// Start a new transaction and enter manual transaction mode
+    virtual ITransactionPtr startTransaction();
+#endif
+
+    /// Refresh the database
+    /// Keep and refresh nodes if the flag is true, else drop them
+    void refreshDatabase( bool keepNodes = false );
+
+    /// Refresh all nodes.
+    void refreshAllNodes();
+
+    /// Refresh an existing node.
+    void refreshNode( const std::string& fullPath );
+
+    /// Drops all nodes (keep the root node if required)
+    bool dropAllNodes( bool keepRoot=false );
+
+  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;
+
+    /// 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,
+      PayloadMode::Mode payloadMode = PayloadMode::INLINEPAYLOAD );
+
+    /// 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;
+
+  };
+
+}
+
+// Reenable icc warning 444
+#ifdef __ICC
+#pragma warning (pop)
+#endif
+
+#endif // RELATIONALCOOL_RALDATABASE_H
diff --git a/28PATCHES2013/RelationalCool/src/NEW/RalQueryMgr.h b/28PATCHES2013/RelationalCool/src/NEW/RalQueryMgr.h
new file mode 100644
index 0000000000000000000000000000000000000000..90b067bf6304206bc3e1d10b04f6176214269c96
--- /dev/null
+++ b/28PATCHES2013/RelationalCool/src/NEW/RalQueryMgr.h
@@ -0,0 +1,175 @@
+#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;
+
+    /// 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 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;
+
+    /// 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 Record& dataBuffer,
+                         int rowCacheSize ) const;
+
+    /// Insert one row into one table.
+    void insertTableRow( const std::string& tableName,
+                         const Record& 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 Record& dataBuffer,
+                         int rowCacheSize ) const;
+
+    /// 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 Record& 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 Record& whereData,
+      UInt32 nExp = 0 ) const;
+
+    /// Delete all rows from one table (truncate the table).
+    /// Implements RelationalQueryMgr pure abstract virtual method.
+    void deleteAllTableRows
+    ( const std::string& tableName ) 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 server technology version for the current connection.
+    /// This ultimately corresponds to coral::IConnection::serverVersion().
+    const std::string serverVersion() 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/28PATCHES2013/RelationalCool/src/NEW/RalSessionMgr.cpp b/28PATCHES2013/RelationalCool/src/NEW/RalSessionMgr.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..8616f1460f0f790955c9ec9b94aa726687e2b542
--- /dev/null
+++ b/28PATCHES2013/RelationalCool/src/NEW/RalSessionMgr.cpp
@@ -0,0 +1,414 @@
+
+// Include files
+#include <cstdlib>
+#include <iostream>
+#include "RelationalAccess/IConnectionServiceConfiguration.h"
+#include "RelationalAccess/IRelationalDomain.h"
+#include "RelationalAccess/IRelationalService.h"
+#include "RelationalAccess/ITransaction.h"
+
+// Local include files
+#include "RalQueryMgr.h"
+#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_queryMgr( *this ),
+{
+  std::string ro;
+  if ( !readOnly )
+  {
+    m_sessionMode = Update;
+    ro = "R/W";
+  }
+  else if ( getenv( "COOL_READONLYSESSION_MANYTRANSACTIONS" ) )
+  {
+    m_sessionMode = ReadOnlyManyTx;
+    ro = "R/O (many tx)";
+  }
+  else
+  {
+    m_sessionMode = ReadOnly;
+    ro = "R/O";
+  }
+  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 CORAL connection pool automatic cleanup if requested
+  // Disable CORAL connection sharing if requested
+  static bool first = true;
+  if ( first )
+  {
+    first = false;
+    if ( getenv( "COOL_DISABLE_CORALCONNECTIONPOOLCLEANUP" ) )
+    {
+      log() << coral::Warning << "Use COOL_DISABLE_CORALCONNECTIONPOOLCLEANUP"
+            << coral::MessageStream::endmsg; // Use log, not cout (bug #75501)
+      m_ppConnSvc->configuration().disablePoolAutomaticCleanUp();
+      m_ppConnSvc->configuration().setConnectionTimeOut( 0 );
+    }
+    if ( getenv( "COOL_DISABLE_CORALCONNECTIONSHARING" ) )
+    {
+      log() << coral::Warning << "Use COOL_DISABLE_CORALCONNECTIONSHARING"
+            << coral::MessageStream::endmsg; // Use log, not cout (bug #75501)
+      m_ppConnSvc->configuration().disableConnectionSharing();
+    }
+  }
+  // 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 ( TimingReport::enabled() )
+    {
+      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; // need 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;
+      }
+    }
+
+    // Set the CORAL/Services/EnvironmentAuthenticationService
+    if ( environmentAuthenticationUsed )
+    {
+      connectionSvc().configuration().
+        setAuthenticationService
+        ( "CORAL/Services/EnvironmentAuthenticationService" );
+    }
+
+    // Get the session proxy
+    coral::AccessMode accessMode;
+    if ( isReadOnly() ) 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 );
+    }
+
+    // Clean up environment variables
+    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", "" );
+      }
+    }
+
+    // Was a connection established successfully?
+    if ( !m_session )
+    {
+      throw RelationalException( "Failed to connect to the server",
+                                 "RalSessionMgr::connect" );
+    }
+    log() << "Connection established successfully"
+          << coral::MessageStream::endmsg;
+
+    // In ReadOnly mode start a single transaction for the duration of
+    // the session (all other clients use a dummy transaction manager).
+    //if ( m_sessionMode==ReadOnly || m_sessionMode==ReadOnlyManyTx )
+    if ( m_sessionMode == ReadOnly ) // NB: m_sessionMode != ReadOnlyManyTx
+    {
+      log() << coral::Info
+            << "Start a read-only transaction active"
+            << " for the duration of the database connection"
+            << coral::MessageStream::endmsg;
+      session().transaction().start( true ); // R/O transaction
+    }
+
+    if ( TimingReportMgr::isActive() )
+    {
+      TimingReportMgr::stopTimer( "EXTRA cool::RalSessionMgr::connect()" );
+      TimingReportMgr::finalize();
+    }
+
+  }
+}
+
+//-----------------------------------------------------------------------------
+
+void RalSessionMgr::disconnect()
+{
+  if ( TimingReport::enabled() )
+  {
+    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 transaction, and in that case rollback
+    // (do not rollback all the time, else CORAL will issue a warning!).
+    if ( m_sessionMode == Update )
+    {
+      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 ReadOnlyManyTx 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 transaction, and in that case rollback
+    // (do not rollback all the time, else CORAL will issue a warning!).
+    else if ( m_sessionMode == ReadOnlyManyTx ) // fix bug #90949
+    {
+      if ( session().transaction().isActive() )
+      {
+        log() << coral::Warning
+              << "Active transactions found while disconnecting from a"
+              << " ReadOnly (many transactions) session will be rolled back"
+              << coral::MessageStream::endmsg;
+        session().transaction().rollback();
+      }
+    }
+    // In ReadOnly 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 (single transaction) 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() const
+{
+  *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/28PATCHES2013/RelationalCool/src/NEW/RalSessionMgr.h b/28PATCHES2013/RelationalCool/src/NEW/RalSessionMgr.h
new file mode 100644
index 0000000000000000000000000000000000000000..e5c484367a0c56fb28ec69f2f62c8a9f12c0cf9f
--- /dev/null
+++ b/28PATCHES2013/RelationalCool/src/NEW/RalSessionMgr.h
@@ -0,0 +1,161 @@
+#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 "RalQueryMgr.h"
+#include "RelationalDatabaseId.h"
+
+// Disable icc warning 444: boost::enable_shared_from_this has non virtual dtor
+#ifdef __ICC
+#pragma warning (push)
+#pragma warning (disable: 444)
+#endif
+
+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 boost::enable_shared_from_this<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() const;
+
+    /// Get the RelationalQueryMgr
+    const RelationalQueryMgr& queryMgr() const
+    {
+      return m_queryMgr;
+    }
+
+    /// Required access mode to the database.
+    bool isReadOnly() const
+    {
+      return ( m_sessionMode==ReadOnly || m_sessionMode==ReadOnlyManyTx );
+    }
+
+    /// Required access mode to the database.
+    bool isReadOnlyManyTx() const
+    {
+      return ( m_sessionMode==ReadOnlyManyTx );
+    }
+
+  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;
+
+    /// RelationalQueryMgr (owned by this instance)
+    RalQueryMgr m_queryMgr;
+
+    /// Session access mode (see bug #90949)
+    typedef enum { ReadOnly, Update, ReadOnlyManyTx } SessionMode;
+
+    /// Required access mode to the database
+    SessionMode m_sessionMode;
+
+  };
+
+}
+
+#endif // RELATIONALCOOL_RALSESSIONMGR_H
diff --git a/28PATCHES2013/RelationalCool/src/NEW/RelationalDatabase.cpp b/28PATCHES2013/RelationalCool/src/NEW/RelationalDatabase.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..37510cc5629914a3d55278ce06cb55ad1f665eb8
--- /dev/null
+++ b/28PATCHES2013/RelationalCool/src/NEW/RelationalDatabase.cpp
@@ -0,0 +1,1287 @@
+
+// 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 "RelationalQueryDefinition.h"
+#include "RelationalSchemaMgr.h"
+#include "RelationalTableRow.h"
+#include "RelationalTag2TagTable.h"
+#include "RelationalTagSequence.h"
+#include "RelationalTagSharedSequenceTable.h"
+#include "RelationalTagTable.h"
+#include "RelationalTagMgr.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_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;
+}
+
+//-----------------------------------------------------------------------------
+
+void RelationalDatabase::checkDbOpenTransaction( const std::string& domain,
+                                                 cool::AccessMode mode ) const
+{
+  if ( !isOpen() ) 
+    throw DatabaseNotOpen( domain );
+  if ( mode == cool::ReadWrite && isReadOnly() )
+    throw DatabaseOpenInReadOnlyMode( domain );
+  if ( !transactionMgr()->isActive() )
+    throw RelationalException( "Transaction is not active", domain );
+//  if ( mode == cool::ReadWrite && transactionMgr()->isReadOnly() )
+//    throw cool::Exception( "Transaction is read only", domain );
+}
+
+//-----------------------------------------------------------------------------
+
+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;
+  m_dbAttr = fetchDatabaseAttributes();
+  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 )
+  {
+    if ( 
+#ifdef COOL290
+    // This release (2.9.0) can read 2.9.0
+         ( db_rel_version == "2.9.0" ) ||
+#endif
+    // This release (2.8.13) can read 2.8.x
+    // This release (2.8.13) can read 2.7.0
+    // This release (2.8.13) can read 2.6.0
+    // This release (2.8.13) can read 2.5.0
+    // This release (2.8.13) can read 2.4.0
+    // This release (2.8.13) can read 2.3.x (including the unreleased 2.3.1)
+    // This release (2.8.13) can read 2.2.x
+    // This release (2.8.13) can read 2.1.x
+    // This release (2.8.13) can read 2.0.0
+         ( db_rel_version >= "2.8.0" && db_rel_version <= "2.8.13" ) ||
+         ( db_rel_version == "2.7.0" ) ||
+         ( 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::Info
+            << "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;
+    }
+    // This release (2.8.13) needs schema evolution before it can read 1.3.x
+    else 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;
+    }
+    // This release (2.8.13) needs schema evolution before it can read 1.2.x
+    else 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.8.13) 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;
+}
+
+//-----------------------------------------------------------------------------
+
+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::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
+  RecordSpecification whereDataSpec;
+  whereDataSpec.extend( "tagName", 
+                        RelationalTagTable::columnTypeIds::tagName );
+  Record whereData( whereDataSpec );
+  whereData["tagName"].setValue( tagName );
+  std::string whereClause = RelationalTagTable::columnNames::tagName;
+  whereClause += "= :tagName";
+
+  // Delegate the query to the RelationalQueryMgr
+  RelationalQueryDefinition queryDef;
+  queryDef.addFromItem( tagTableName );
+  queryDef.addSelectItems( RelationalTagTable::tableSpecification() );
+  queryDef.setWhereClause( whereClause );
+  queryDef.setBindVariables( whereData );
+  try 
+  {
+    return queryMgr().fetchOrderedRows( queryDef, "", 1 )[0]; // expect 1 row
+  } 
+  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 
+  {
+    RelationalQueryDefinition queryDef;
+    queryDef.addFromItem( mainTableName() );
+    queryDef.addSelectItems( RelationalDatabaseTable::tableSpecification() );
+    rows = queryMgr().fetchOrderedRows( queryDef ); // no WHERE or ORDER clause
+  } 
+  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,
+  PayloadMode::Mode pMode )
+{
+  // Define the WHERE clause for the selection using bind variables
+  RecordSpecification whereDataSpec;
+  whereDataSpec.extend( "tagId", 
+                        RelationalObject2TagTable::columnTypeIds::tagId );
+  whereDataSpec.extend( "objectId", 
+                        RelationalObject2TagTable::columnTypeIds::objectId );
+  Record whereData( whereDataSpec );
+  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
+  RelationalQueryDefinition queryDef;
+  queryDef.addFromItem( object2TagTableName );
+  queryDef.addSelectItems
+    ( RelationalObject2TagTable::tableSpecification( pMode ) );
+  queryDef.setWhereClause( whereClause );
+  queryDef.setBindVariables( whereData );
+  std::stringstream s;
+  s << "Query object2Tag table row with tag_id=" << tagId
+    << " and object_id=" << objectId;
+  return queryMgr().fetchOrderedRows( queryDef, s.str(), 1 )[0]; // expct 1 row
+}
+
+//-----------------------------------------------------------------------------
+
+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 Record& 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
+  checkDbOpenTransaction( "RelationalDatabase::listFolders",
+                               cool::ReadOnly );
+
+  bool isLeaf = true;
+  std::vector<std::string>
+    nodes( listNodes( folderset->id(), isLeaf, ascending ) );
+
+  return nodes;
+}
+
+//-----------------------------------------------------------------------------
+
+const std::vector<std::string>
+RelationalDatabase::listFolderSets( const RelationalFolderSet* folderset,
+                                    bool ascending ) const
+{
+  // Cross-check that the database is open
+  checkDbOpenTransaction( "RelationalDatabase::listFolderSets",
+                               cool::ReadOnly );
+
+  bool isLeaf = false;
+  std::vector<std::string>
+    nodes( listNodes( folderset->id(), isLeaf, ascending ) );
+
+  return nodes;
+}
+
+//-----------------------------------------------------------------------------
+
+const std::vector<std::string>
+RelationalDatabase::listAllNodes( bool ascending )
+{
+  // Cross-check that the database is open
+  checkDbOpenTransaction( "RelationalDatabase::listAllNodes",
+                               cool::ReadOnly );
+
+  // Delegate to the node manager
+  std::vector<std::string> nodeList = nodeMgr().listAllNodes( ascending );
+
+  // 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
+{
+  checkDbOpenTransaction( "RelationalDatabase::listAllTables",
+                               cool::ReadOnly );
+  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
+  RelationalQueryDefinition queryDef;
+  queryDef.addFromItem( nodeTableName() );
+  queryDef.addSelectItems( RelationalNodeTable::tableSpecification( VersionNumber( dbSchemaVersion ) ) );
+  std::vector<RelationalTableRow> nodes =
+    queryMgr().fetchOrderedRows( queryDef );
+  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/28PATCHES2013/RelationalCool/src/NEW/RelationalDatabase.h b/28PATCHES2013/RelationalCool/src/NEW/RelationalDatabase.h
new file mode 100644
index 0000000000000000000000000000000000000000..e68708e7d09b8a8527e393bae9b12e7d78c97162
--- /dev/null
+++ b/28PATCHES2013/RelationalCool/src/NEW/RelationalDatabase.h
@@ -0,0 +1,527 @@
+#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/PayloadMode.h"
+#include "PayloadMode.h" // TEMPORARY
+#include "CoolKernel/IDatabase.h"
+#ifdef COOL400
+#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;
+
+  /**
+   * FIXME move somewhere else?
+   *
+   * Enumeration for AccessMode
+   *
+   * To be used in parameter list, to avoid
+   * boolean parameters.
+   */
+
+  enum AccessMode { ReadWrite, ReadOnly };
+
+  /** @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;
+
+    /// Helper methods, does the ususal checks if
+    /// database is open, rw/ro, a transaction active, etc
+    /// Throws exceptions if the
+    void checkDbOpenTransaction( const std::string& domain,
+                                 cool::AccessMode mode ) 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 COOL400
+    /// 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
+    /// PURE VIRTUAL method implemented in subclasses.
+    virtual const RelationalQueryMgr& queryMgr() const = 0;
+
+    /// 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 Record& 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: USED ONLY IN TESTS! (AV)
+    /// Fetch the object2Tag table row for the given tagId, objectId
+    RelationalTableRow
+    fetchObject2TagTableRow( const std::string& tagTableName,
+                             unsigned int tagId,
+                             unsigned int objectId,
+                             PayloadMode::Mode pMode );
+
+    /// 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 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;
+
+    /// 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/28PATCHES2013/RelationalCool/src/README.txt b/28PATCHES2013/RelationalCool/src/README.txt
new file mode 100644
index 0000000000000000000000000000000000000000..5a180dbe2e04f82eedbe685cc1e00b6b6fd8ec8b
--- /dev/null
+++ b/28PATCHES2013/RelationalCool/src/README.txt
@@ -0,0 +1,44 @@
+I screwed up all of the Ral/Rel stuff by committing the ISessionMgr.
+The name was totally misleading. It is a RalSessionMgr, I do not understand
+why MW decided to use an interface there.
+
+Note that if everyone gets screwed up,me included, it means that this is
+totally unmaintainable as it is. The class structure of COOL is crap.
+
+My specific problem here is
+- I want a shared ptr to a singel instance and this is the ISessionMgr
+- However I cannot easily have a shared ptr to ISessionMgr and RalSessionMgr
+  mixed, in some cases I only need RalSessionMgr
+
+Short term may be to use private coral ISessionProxy inside
+and declare that only some classes (eg RalQueryMgr) see it?
+Or I should have used shared from this?
+
+How much is the extr acomplication I put in each time
+to artificially maintain this separation anyway?!
+
+Honestly, it would all be much simpler and understandable
+if yo decide COOL uses CORAL and full stop!
+eg remove the RalCursor and RalBulkOperation wrappers..
+
+Eventually (soon??!) get rid of class duplication?
+Or otherwise find a better structure.
+
+Start by keeping only ONE version of each class:
+- already no RelationalBulkOperation, good
+- already no RelationalCursor, good
+- what to do with RelationalDatabase?
+- already no RelationalDatabaseSvc, good
+- drop RelationalQueryMgr (easy)
+- already not RelationalSchemaMgr, good
+- drop RelationalSequenceMgr (easy)
+- already no RelationalSessionMgr, good
+- already no RelationalTransactionMgr, good
+Then rename the Ral as Coral
+And keep the Coral as friends in SessionMgr (cheap but effective)
+
+Can do it in several times
+- First get a single class per name
+- Eventually remove all the hassle? (maybe not, if just friendsis what remains)
+
+Eventually should actually review WHOLE class structure...
\ No newline at end of file
diff --git a/cmt/USERCONTEXT/avalassi/CMT_userenv.csh b/cmt/USERCONTEXT/avalassi/CMT_userenv.csh
new file mode 100644
index 0000000000000000000000000000000000000000..41e99bda17c56dea3fbb8ba2185ec38bb20b402e
--- /dev/null
+++ b/cmt/USERCONTEXT/avalassi/CMT_userenv.csh
@@ -0,0 +1,24 @@
+# $Id: CMT_userenv.csh,v 1.16 2013/05/15 12:03:19 avalassi Exp $
+
+# Add LCGCMT patches from /home/avalassi/releases (e.g. if absent on cvmfs)
+###setenv CMTPROJECTPATH /home/avalassi/releases:${CMTPROJECTPATH}
+
+# Special settings for the CORAL3/COOL3 preview branches
+# Use a private copy of the latest ROOT6 nightlies
+#if ( "$HOST" == "aicoral61.cern.ch" ) then
+#  setenv CMTPROJECTPATH /home/avalassi/nightlies/dev4/20140610Tue
+#else
+#  echo "ERROR! Invalid host for this USERCONTEXT"
+#endif
+
+# Use the nightlies to debug dev2/dev4 issues on the default gcc48 platform
+# Use the nightlies to work around "wrong option -std=c++11" on gcc47
+# Use the nightlies to work around issues with icc13 buids in LCGCMT_68_root6
+#if ( "$HOST" == "aicoral61.cern.ch" ) then
+#  ###setenv CMTPROJECTPATH /home/avalassi/nightlies/dev2/20140610Tue
+#  setenv CMTPROJECTPATH /home/avalassi/nightlies/dev4/20140610Tue
+#  if ( "$CMTCONFIG" == "x86_64-slc6-icc13-dbg" || \
+#       "$CMTCONFIG" == "x86_64-slc6-gcc47-opt" ) then
+#    setenv CMTPROJECTPATH /home/avalassi/nightlies/dev2/Tue
+#  endif
+#endif
diff --git a/cmt/USERCONTEXT/avalassi/CMT_userenv.sh b/cmt/USERCONTEXT/avalassi/CMT_userenv.sh
new file mode 100644
index 0000000000000000000000000000000000000000..a2f9d903e948fd0ad84bcbd270888385608443c6
--- /dev/null
+++ b/cmt/USERCONTEXT/avalassi/CMT_userenv.sh
@@ -0,0 +1,6 @@
+# $Id: CMT_userenv.sh,v 1.15 2013/05/15 12:03:19 avalassi Exp $
+
+###unset CMTPROJECTPATH; echo CMTPROJECTPATH=$CMTPROJECTPATH
+cmtUserContext=`dirname $BASH_SOURCE`
+export CMTPROJECTPATH=`tcsh -f -c "source $cmtUserContext/CMT_userenv.csh; echo \\$CMTPROJECTPATH"`
+###echo CMTPROJECTPATH=$CMTPROJECTPATH
diff --git a/cmt/USERCONTEXT/avalassi/requirements b/cmt/USERCONTEXT/avalassi/requirements
new file mode 100644
index 0000000000000000000000000000000000000000..c4fc0630576df4969471dc0f176afe582639035d
--- /dev/null
+++ b/cmt/USERCONTEXT/avalassi/requirements
@@ -0,0 +1,218 @@
+#============================================================================
+# Package CMTUSERCONTEXT - private CMT config for user avalassi
+#============================================================================
+
+# LCG AA nightly build area base.
+###macro lcgaa_nightlies_base $(SITEROOT)/sw/lcg/app/nightlies
+
+# Internal COOL area with private installations of externals.
+# Do not use "/afs/cern.ch/sw/lcg/app/releases/COOL/internal" because pattern
+# "path_remove /COOL/" would remove the paths to any external installed there.
+###macro cool_internal /afs/cern.ch/sw/lcg/app/cool/internal
+
+# Internal COOL area with private installations of externals for avalassi.
+###macro av_internal $(cool_internal)/avalassi
+
+# Private local directory for user avalassi
+macro av_home /home/avalassi
+
+# Linux system type (32/64 bit) from fs sysname
+###macro fs_sysname 'i386_linux26' host-x86_64 'amd64_linux26'
+
+#----------------------------------------------------------------------------
+
+# LCG AA nightly build area.
+###macro lcgaa_nightlies $(lcgaa_nightlies_base)/dev/Wed
+
+# Private copy of the LCG AA nightly build area.
+###macro av_nightlies_dev4 /home/avalassi/nightlies/dev4/20141003Fri
+
+#----------------------------------------------------------------------------
+# "COOL400" API extensions
+#----------------------------------------------------------------------------
+
+# Test the COOL400 API extensions only on selected platforms
+###macro_append use_cppflags           '' \
+###             x86_64-slc6-gcc48-dbg  ' -DCOOL400'
+###macro_append gccxmlopts             '' \
+###             x86_64-slc6-gcc48-dbg  ' -DCOOL400'
+
+#----------------------------------------------------------------------------
+# LCGCMT and LCG_releases
+#----------------------------------------------------------------------------
+
+# *** REMINDER ********************************************
+# Remember to set CMTPROJECTPATH in CMT_userenv.bat/csh/sh 
+# if you want to take LCGCMT from a copy of the nightlies!
+# *** REMINDER ********************************************
+
+# If you change CMTPROJECTPATH to take LCGCMT from the nightlies or from a 
+# copy of the nightlies, you must reset LCG_releases to use externals on AFS
+# (in the nightlies LCG_releases points to externals in /build/nightlies...).
+# If you use a copy of the nightlies, reset LCG_releases here (user context).
+# If you use the nightlies directly, consider CMTEXTRATAGS=LCG_NIGHTLIES.
+
+# General macros after the changes in LCG_Settings (LCG_home no longer exists)
+# [e.g. ROOT >=5.34.00 is on lcg/app/releases for both AFS and CVMFS]
+# *** NB (APR 2014): THESE MACROS ARE OBSOLETE AND MAY NOT WORK ON >=LCG68! ***
+###macro LCG_releases $(SITEROOT)/sw/lcg/app/releases \
+###      LOCAL        $(SITEROOT)/lcg/app/releases
+###macro LCG_external $(SITEROOT)/sw/lcg/external \
+###      LOCAL        $(SITEROOT)/lcg/external
+###macro LCG_external $(SITEROOT)/sw/lcg/experimental \
+###      LOCAL        $(SITEROOT)/lcg/external
+
+# Use AFS instead of CVMFS for icc13
+###macro LCG_external $(LCG_external) \
+###      target-icc13 /afs/cern.ch/sw/lcg/external
+
+# Extra tags for root6 (extends LCG_Platforms, needed for LCG_system macro)
+###tag x86_64-slc6-gcc48-dbg-root6-dev2 x86_64-slc6-gcc48-dbg-root
+###tag x86_64-slc6-gcc48-dbg-root6-test x86_64-slc6-gcc48-dbg-root
+###tag x86_64-slc6-gcc48-dbg-root6 x86_64-slc6-gcc48-dbg ROOT_GE_6_00
+
+# Experimental setup for new and test platforms
+###macro LCG_external $(LCG_external) \
+###      LOCAL&x86_64-slc6-gcc48-dbg-root6 $(SITEROOT)/lcg/external \
+###      x86_64-slc6-gcc48-dbg-root6 $(SITEROOT)/sw/lcg/experimental
+
+#----------------------------------------------------------------------------
+# CORAL (for COOL tests inside private COOL builds)
+#----------------------------------------------------------------------------
+# NB: redefining CORAL_config_version and CORAL_base is harmless within
+# private CORAL builds; CORAL_home however is defined by cmt/project.cmt.
+
+# Use another CORAL version in the default LCG release area.
+###macro CORAL_config_version CORAL_2_4_0
+
+# Use a private CORAL build
+# NB: the "/CORAL/" path must always be present to allow CMT path cleanup.
+###macro CORAL_config_version CORAL_HEAD
+macro CORAL_config_version CORAL_23x
+macro CORAL_base $(av_home)/CORAL/$(CORAL_config_version)
+macro CORAL_home $(CORAL_home)
+macro CORAL_include $(CORAL_home)/include
+
+# Use (a copy of) the CORAL nightlies.
+# NB: the "/CORAL/" path must always be present to allow CMT path cleanup.
+###macro CORAL_config_version CORAL-preview
+###macro CORAL_base $(av_nightlies_dev2)/CORAL/$(CORAL_config_version)
+###macro CORAL_home $(CORAL_base)/$(LCG_basesystem)-dbg
+
+# Use the CORAL nightlies directly.
+# NB: the "/CORAL/" path must always be present to allow CMT path cleanup.
+###macro CORAL_config_version CORAL-preview
+###macro CORAL_base $(lcgaa_nightlies)/CORAL/$(CORAL_config_version)
+
+# Use opt version of CORAL for dbg builds on cvmfs (dbg is missing on cvmfs)
+###macro CORAL_home $(CORAL_home) \
+###      LOCAL&target-dbg $(CORAL_base)/$(LCG_basesystem)-opt
+
+#----------------------------------------------------------------------------
+# ROOT (for COOL tests inside private COOL builds)
+#----------------------------------------------------------------------------
+# NB: redefining ROOT macros is harmless within private CORAL builds.
+
+# Use another ROOT version in the default LCG release area.
+###macro ROOT_config_version 5.34.13
+
+# Use the ROOT nightlies directly.
+# NB: the "/ROOT/" path must always be present to allow CMT path cleanup.
+###macro ROOT_config_version ROOT_today
+###macro ROOT_base $(lcgaa_nightlies)/ROOT/$(ROOT_config_version)
+
+# Use ROOT6 beta2 from AFS.
+# NB: the "/ROOT/" path must always be present to allow CMT path cleanup.
+###macro ROOT_config_version 5.99.05
+###macro ROOT_base /afs/cern.ch/sw/lcg/app/releases/ROOT/$(ROOT_config_version)
+
+# Use (a copy of) the ROOT6 nightlies.
+# NB: the "/ROOT/" path must always be present to allow CMT path cleanup.
+###macro ROOT_config_version 6.02.00
+###macro ROOT_base $(av_nightlies_dev4)/ROOT/$(ROOT_config_version)
+###macro ROOT_home $(ROOT_base)/$(LCG_basesystem)-dbg/root
+
+# Use opt version of ROOT for dbg builds where dbg is missing (e.g. cvmfs)
+###macro ROOT_home $(ROOT_home) \
+###    LOCAL&target-dbg $(ROOT_base)/$(LCG_basesystem)-opt/root
+
+#----------------------------------------------------------------------------
+# COOL (for CORAL_SERVER tests inside private CORAL builds)
+#----------------------------------------------------------------------------
+# NB: redefining COOL_config_version and COOL_base is harmless within
+# private COOL builds; COOL_home however is defined by cmt/project.cmt.
+
+# Use a private COOL installation.
+# NB: the "/COOL/" path must always be present to allow CMT path cleanup
+# (OK as this is /afs/cern.ch/sw/lcg/app/releases/COOL/internal/avalassi)
+macro COOL_config_version COOL_28x
+macro COOL_base $(av_home)/$(COOL_config_version)
+
+#----------------------------------------------------------------------------
+# Oracle 12c tests
+#----------------------------------------------------------------------------
+
+# Use 12.1.0.1.0 on AFS
+###macro oracle_config_version $(oracle_config_version) target-linux 12.1.0.1.0
+###macro oracle_home $(oracle_home) target-linux /afs/cern.ch/sw/lcg/external/oracle/$(oracle_native_version)/$(LCG_system)
+
+#----------------------------------------------------------------------------
+# Frontier client for CORAL3 (SPI-561) and on mac (SPI-439)
+#----------------------------------------------------------------------------
+
+# Upgrade Frontier client to 2.8.10 as this is needed by CORAL3 (SPI-561)
+###macro Frontier_Client_config_version 2.8.10
+###macro Frontier_Client_home /afs/cern.ch/sw/lcg/external/frontier_client/$(Frontier_Client_native_version)/$(LCG_system)
+
+# Downgrade Frontier client to 2.8.7 on mac
+# NB: CORAL3 requires Frontier client 2.8.10!
+###macro Frontier_Client_config_version $(Frontier_Client_config_version) \
+###  target-mac 2.8.7
+
+# Use the mac106 version on mac108 for gcc42
+###macro Frontier_Client_home $(Frontier_Client_home) \
+###  target-mac&target-gcc $(LCG_external)/frontier_client/$(Frontier_Client_native_version)/x86_64-mac106-gcc42-opt 
+
+#----------------------------------------------------------------------------
+# MySQL client on mac (SPI-440)
+#----------------------------------------------------------------------------
+
+# Downgrade mysql from 5.5.27 while using LCGCMT from the nightlies
+###macro mysql_native_version 5.5.14
+
+# Use the clang42 version for llvm42
+###macro mysql_home $(mysql_home) \
+###  target-mac&target-llvm $(LCG_external)/mysql/$(mysql_native_version)/x86_64-mac108-clang42-opt 
+
+#----------------------------------------------------------------------------
+# Boost on mac (SPI-441)
+#----------------------------------------------------------------------------
+
+# Use the clang42 version for llvm42
+###macro Boost_home $(Boost_home) \
+###  target-mac&target-llvm $(LCG_external)/Boost/$(Boost_native_version)/x86_64-mac108-clang42-opt 
+
+# Fix gcc2icc
+###macro gcc2icc $(gcc2icc) target-icc13 gcc48
+
+#----------------------------------------------------------------------------
+# QMtest on mac (SPI-442)
+#----------------------------------------------------------------------------
+
+# Use the clang42 version for gcc42 and llvm42
+###macro QMtest_home $(QMtest_home) \
+###  target-mac&target-gcc $(LCG_external)/QMtest/$(QMtest_native_version)/x86_64-mac108-clang42-opt \
+###  target-mac&target-llvm $(LCG_external)/QMtest/$(QMtest_native_version)/x86_64-mac108-clang42-opt 
+
+# Use the mac106 version on mac108
+###macro QMtest_home $(QMtest_home) \
+###  target-mac $(LCG_external)/QMtest/$(QMtest_native_version)/x86_64-mac106-gcc42-opt
+
+#----------------------------------------------------------------------------
+# Python
+#----------------------------------------------------------------------------
+
+# Downgrade python from 2.7.6 while using LCGCMT from the nightlies
+###macro Python_native_version 2.7.4
+
+#----------------------------------------------------------------------------