diff --git a/Database/AthenaPOOL/EventSelectorAthenaPool/src/EventSelectorAthenaPool.cxx b/Database/AthenaPOOL/EventSelectorAthenaPool/src/EventSelectorAthenaPool.cxx
index 1dee033d4801d1fab959f52dc0d8f67b9a5069b2..10f8fca96d89143196b1d768f68a6bc4ef88106b 100755
--- a/Database/AthenaPOOL/EventSelectorAthenaPool/src/EventSelectorAthenaPool.cxx
+++ b/Database/AthenaPOOL/EventSelectorAthenaPool/src/EventSelectorAthenaPool.cxx
@@ -429,7 +429,7 @@ void EventSelectorAthenaPool::fireEndFileIncidents(bool isLastFile, bool fireEnd
             // Assume that the end of collection file indicates the end of payload file.
             if (m_guid != Guid::null()) {
                // Fire EndInputFile incident
-               FileIncident endInputFileIncident(name(), "EndInputFile", "FID:" + m_guid.toString());
+               FileIncident endInputFileIncident(name(), "EndInputFile", "FID:" + m_guid.toString(), m_guid.toString());
                m_incidentSvc->fireIncident(endInputFileIncident);
             }
             // Fire EndTagFile incident if not out of files (maybe we should make it fire then as well?)
@@ -1088,7 +1088,7 @@ PoolCollectionConverter* EventSelectorAthenaPool::getCollectionCnv(bool throwInc
             if (throwIncidents && m_processMetadata.value()) {
                FileIncident beginInputFileIncident(name(), "BeginInputFile", *m_inputCollectionsIterator);
                m_incidentSvc->fireIncident(beginInputFileIncident);
-               FileIncident endInputFileIncident(name(), "EndInputFile", "eventless " + *m_inputCollectionsIterator);
+               FileIncident endInputFileIncident(name(), "EndInputFile", "eventless " + *m_inputCollectionsIterator, m_guid.toString() );
                m_incidentSvc->fireIncident(endInputFileIncident);
             }
             m_athenaPoolCnvSvc->getPoolSvc()->disconnectDb(*m_inputCollectionsIterator, IPoolSvc::kInputStream).ignore();
diff --git a/Database/PersistentDataModel/PersistentDataModel/DataHeader.h b/Database/PersistentDataModel/PersistentDataModel/DataHeader.h
index 920a47d0d273ec41a92afc47b6d87dd9ad4ffd51..83a68f2b20b9f90d23ea05e5a7eecab0a5094a25 100755
--- a/Database/PersistentDataModel/PersistentDataModel/DataHeader.h
+++ b/Database/PersistentDataModel/PersistentDataModel/DataHeader.h
@@ -75,11 +75,13 @@ public: // Non-static members
    /// Add new entry to hash map
    void addHash(IStringPool* pool);
 
+   void dump(std::ostream& ostr) const;
+  
 private:
    friend class DataHeaderElementCnv_p3;
    friend class DataHeaderElementCnv_p4;
    friend class DataHeaderElementCnv_p5;
-   friend class DataHeaderElementCnv_p6;
+   friend class DataHeaderCnv_p6;
 
    /// primary ClassID.
    CLID m_pClid;
@@ -165,6 +167,8 @@ public: // Non-static members
    void setEvtRefTokenStr(const std::string& tokenStr);
    const std::string& getEvtRefTokenStr();
 
+   void dump(std::ostream& ostr) const;
+  
 private:
    friend class DataHeaderCnv_p3;
    friend class DataHeaderCnv_p4;
diff --git a/Database/PersistentDataModel/src/DataHeader.cxx b/Database/PersistentDataModel/src/DataHeader.cxx
index 2bb1bd87ebc4f6bad2a84e25a50651defe87a9be..0268fd9c1f56e2d002920cc4659d2fca371230da 100755
--- a/Database/PersistentDataModel/src/DataHeader.cxx
+++ b/Database/PersistentDataModel/src/DataHeader.cxx
@@ -142,6 +142,34 @@ SG::TransientAddress* DataHeaderElement::getAddress(const std::string& key,
    sgAddress->setAlias(m_alias);
    return(sgAddress);
 }
+//______________________________________________________________________________
+void DataHeaderElement::dump(std::ostream& ostr) const
+{
+   using namespace std;
+   ostr << "SGKey: " << getKey() << endl;
+   ostr << "CLID: " << getPrimaryClassID();
+   if( getClassIDs().size() > 1 ) {
+      ostr << " ||";
+      for( auto& c : getClassIDs() ) ostr << " " << c;
+   }
+   ostr << std::endl;
+   if( getAlias().size() > 0 ) {
+      ostr << "Alias: ";
+      for( auto& a : getAlias() ) ostr << " " << a;
+      ostr << endl;
+   }
+   if( m_token ) {
+      ostr << "Token: " << m_token->toString();
+      if( m_ownToken ) ostr << " owned";
+      ostr << endl;
+   }
+   if( m_hashes.size() ) {
+      ostr << "Hashes:";
+      for( auto h : m_hashes ) ostr <<  " " << h;
+      ostr << endl;
+   }
+}
+
 //______________________________________________________________________________
 //______________________________________________________________________________
 DataHeader::DataHeader() : m_dataHeader(),
@@ -263,3 +291,24 @@ void DataHeader::setEvtRefTokenStr(const std::string& tokenStr) {
 const std::string& DataHeader::getEvtRefTokenStr() {
    return(m_evtRefTokenStr);
 }
+//______________________________________________________________________________
+#include "CoralBase/AttributeList.h"
+#include "CoralBase/Attribute.h"
+
+void DataHeader::dump(std::ostream& ostr) const
+{
+   using namespace std;
+   ostr << "--- DataHeader Dump ---" << endl;
+   for( auto& el : m_dataHeader ) {
+      el.dump(ostr);
+   }
+   for( auto& el : m_inputDataHeader ) {
+      el.dump(ostr);
+   }
+   ostr << "Status: " << m_status << endl;
+   ostr << "Proc tag: " << m_processTag << endl;
+   ostr << "evtRef: " << m_evtRefTokenStr << endl;
+   ostr << "attrListPtr: " << m_attrList << endl;
+   if( m_attrList ) ostr << "attrListSize: " << m_attrList->size() << endl;
+   ostr << "--- DataHeader End ---" << endl;   
+}
diff --git a/Database/PersistentDataModelAthenaPool/src/DataHeaderCnv.cxx b/Database/PersistentDataModelAthenaPool/src/DataHeaderCnv.cxx
index a4af8370fc17238e83511df7d053f552ae89eec4..9a002b043b5a67a76aef40c5a1287646ef596be8 100755
--- a/Database/PersistentDataModelAthenaPool/src/DataHeaderCnv.cxx
+++ b/Database/PersistentDataModelAthenaPool/src/DataHeaderCnv.cxx
@@ -1,11 +1,10 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
 */
 
 /** @file DataHeaderCnv.cxx
  *  @brief This file contains the implementation for the DataHeaderCnv class.
  *  @author Peter van Gemmeren <gemmeren@anl.gov>
- *  $Id: DataHeaderCnv.cxx,v 1.15 2009-04-21 22:04:51 gemmeren Exp $
  **/
 
 #include "DataHeaderCnv.h"
@@ -14,10 +13,15 @@
 #include "PersistentDataModel/Token.h"
 #include "PersistentDataModelTPCnv/DataHeaderCnv_p3.h"
 #include "PersistentDataModelTPCnv/DataHeaderCnv_p4.h"
+#include "PersistentDataModelTPCnv/DataHeader_p6.h"
 
 #include "CoralBase/AttributeList.h"
 #include "CoralBase/Attribute.h"
 
+#include "GaudiKernel/IIncidentSvc.h"
+#include "GaudiKernel/FileIncident.h"
+#include "AthenaBaseComps/AthCheckMacros.h"
+
 #include <memory>
 #include <stdexcept>
 
@@ -27,8 +31,47 @@ DataHeaderCnv::DataHeaderCnv(ISvcLocator* svcloc) :
 	m_dhFormMdx(),
 	m_dhForm(0) {
 }
-DataHeaderCnv::~DataHeaderCnv() {
-   delete m_dhForm ; m_dhForm = 0;
+//______________________________________________________________________________
+DataHeaderCnv::~DataHeaderCnv()
+{
+   // Remove itself from the IncidentSvc - if it is still around
+   ServiceHandle<IIncidentSvc> incSvc("IncidentSvc", "DataHeaderCnv");
+   if( incSvc.retrieve().isSuccess() ) {
+      incSvc->removeListener(this, IncidentType::EndInputFile);
+   }
+   delete m_dhForm ; m_dhForm = nullptr;
+   for( auto& item : m_persFormMap ) {
+      delete item.second;
+   } 
+}
+//______________________________________________________________________________
+StatusCode DataHeaderCnv::initialize()
+{
+   // listen to EndFile incidents to clear old DataHeaderForms from the cache
+   //Get IncidentSvc
+   ServiceHandle<IIncidentSvc> incSvc("IncidentSvc", "DataHeaderCnv");
+   ATH_CHECK( incSvc.retrieve() );
+   incSvc->addListener(this, IncidentType::EndInputFile, 0);
+   return DataHeaderCnvBase::initialize();
+}
+
+//______________________________________________________________________________
+void DataHeaderCnv::handle(const Incident& incident)
+{
+   if( incident.type() == IncidentType::EndInputFile ) {
+      // remove cached DHForms that came from the file that is now being closed
+      const std::string& guid = static_cast<const FileIncident&>(incident).fileGuid(); 
+      auto iter = m_persFormMap.begin();
+      while( iter != m_persFormMap.end() ) {
+         size_t dbpos = iter->first.find("[DB=");
+         if( dbpos != std::string::npos && iter->first.substr(dbpos+4, dbpos+36) == guid ) {
+            delete iter->second;
+            iter = m_persFormMap.erase( iter );
+         } else {
+            iter++;
+         }
+      }
+   }
 }
 
 //______________________________________________________________________________
@@ -143,6 +186,8 @@ StatusCode DataHeaderCnv::DataObjectToPool(DataObject* pObj, const std::string&
    this->m_o_poolToken = dh_token; // return to converter
    return(StatusCode::SUCCESS);
 }
+#include <sstream>
+using namespace std;
 //______________________________________________________________________________
 DataHeader_p5* DataHeaderCnv::poolReadObject_p5() {
    DataHeader_p5* pObj = 0;
@@ -189,6 +234,37 @@ DataHeader_p5* DataHeaderCnv::poolReadObject_p5() {
    }
    return(pObj);
 }
+
+//______________________________________________________________________________
+// Read the persistent rep of DataHeader_p6 and also DataHeaderForm_p6 if necessary
+// Set dh_form pointer to the correct DataHeaderForm, either from file or cache
+DataHeader_p6* DataHeaderCnv::poolReadObject_p6( DataHeaderForm_p6* &dh_form )
+{
+   void* voidPtr1 = nullptr;
+   m_athenaPoolCnvSvc->setObjPtr(voidPtr1, m_i_poolToken);
+   if (voidPtr1 == nullptr) {
+      throw std::runtime_error("Could not get object for token = " + m_i_poolToken->toString());
+   }
+   DataHeader_p6* pObj = reinterpret_cast<DataHeader_p6*>(voidPtr1);
+      
+   // see if the DataHeaderForm is already cached
+   dh_form = m_persFormMap[ pObj->dhFormToken() ];
+   if( !dh_form ) {
+      // we need to read a new DHF
+      void* voidPtr2 = nullptr;
+      Token mapToken;
+      mapToken.fromString(pObj->dhFormToken());
+      if (mapToken.classID() != Guid::null()) {
+         m_athenaPoolCnvSvc->setObjPtr(voidPtr2, &mapToken);
+         if (voidPtr2 == nullptr) {
+            throw std::runtime_error("Could not get object for token = " + mapToken.toString());
+         }
+      }
+      m_persFormMap[ pObj->dhFormToken() ] = dh_form = reinterpret_cast<DataHeaderForm_p6*>(voidPtr2);
+   }
+   return pObj;
+}
+
 //______________________________________________________________________________
 DataHeader_p5* DataHeaderCnv::createPersistent(DataHeader* transObj) {
    DataHeader_p5* persObj = m_TPconverter.createPersistent(transObj);
@@ -208,10 +284,17 @@ DataHeader* DataHeaderCnv::createTransient() {
       dh->insert(dhe);
       return(dh);
    }
+   static const pool::Guid p6_guid("4DDBD295-EFCE-472A-9EC8-15CD35A9EB8D");
    static const pool::Guid p5_guid("D82968A1-CF91-4320-B2DD-E0F739CBC7E6");
    static const pool::Guid p4_guid("9630EB7B-CCD7-47D9-A39B-CBBF4133CDF2");
    static const pool::Guid p3_guid("EC1318F0-8E28-45F8-9A2D-2597C1CC87A6");
-   if (this->compareClassGuid(p5_guid)) {
+   if( compareClassGuid(p6_guid) ) {
+      DataHeaderForm_p6* dh_form = nullptr;
+      std::auto_ptr<DataHeader_p6> obj( poolReadObject_p6( dh_form ) );
+      auto dh = m_tpInConverter_p6.createTransient( obj.get(), *dh_form );
+      // To dump DH:   ostringstream ss; dh->dump(ss); cout << ss.str() << endl;
+      return dh;
+   } else if (this->compareClassGuid(p5_guid)) {
       std::auto_ptr<DataHeader_p5> obj_p5(this->poolReadObject_p5());
       return(m_TPconverter.createTransient(obj_p5.get()));
    } else if (this->compareClassGuid(p4_guid)) {
diff --git a/Database/PersistentDataModelAthenaPool/src/DataHeaderCnv.h b/Database/PersistentDataModelAthenaPool/src/DataHeaderCnv.h
index 9dc3dce9cee5b6242fe77b0676d1bd21ad756724..d66ac98d124bd1466791e461f98499a1347193bd 100755
--- a/Database/PersistentDataModelAthenaPool/src/DataHeaderCnv.h
+++ b/Database/PersistentDataModelAthenaPool/src/DataHeaderCnv.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
 */
 
 #ifndef DATAHEADERCNV_H
@@ -9,35 +9,56 @@
  *  @file DataHeaderCnv.h
  *  @brief This file contains the class definition for the DataHeaderCnv class.
  *  @author Peter van Gemmeren <gemmeren@anl.gov>
- *  $Id: DataHeaderCnv.h,v 1.9 2009-04-21 22:04:51 gemmeren Exp $
  **/
 
 #include "AthenaPoolCnvSvc/T_AthenaPoolCustomCnv.h"
 #include "PersistentDataModel/DataHeader.h"
 #include "PersistentDataModelTPCnv/DataHeader_p5.h"
 #include "PersistentDataModelTPCnv/DataHeaderCnv_p5.h"
+#include "PersistentDataModelTPCnv/DataHeaderCnv_p6.h"
+
+#include "GaudiKernel/IIncidentListener.h"
+
+#include <map>
+
+class  DataHeaderForm_p6;
+
+typedef  T_AthenaPoolCustomCnv<DataHeader, DataHeader_p5>   DataHeaderCnvBase;
 
 /** @class DataHeaderCnv
  *  @brief This class provides the converter to customize the saving of DataHeader.
  **/
-class DataHeaderCnv : public T_AthenaPoolCustomCnv<DataHeader, DataHeader_p5> {
+class DataHeaderCnv : public DataHeaderCnvBase, virtual public IIncidentListener
+{
    friend class CnvFactory<DataHeaderCnv>;
 public:
    DataHeaderCnv(ISvcLocator* svcloc);
    ~DataHeaderCnv();
 
+   virtual StatusCode initialize() override;
+
    /// Extend base-class conversion methods
    virtual StatusCode updateRep(IOpaqueAddress* pAddress, DataObject* pObject);
    virtual StatusCode updateRepRefs(IOpaqueAddress* pAddress, DataObject* pObject);
 
    virtual StatusCode DataObjectToPool(DataObject* pObj, const std::string& tname);
 
-   virtual DataHeader_p5* poolReadObject_p5();
+   DataHeader_p5* poolReadObject_p5();
+   DataHeader_p6* poolReadObject_p6( DataHeaderForm_p6*& );
 
    virtual DataHeader_p5* createPersistent(DataHeader* transObj);
    virtual DataHeader* createTransient();
 
 private:
+   /// Incident service handle listening for EndFile.
+   virtual void handle(const Incident& incident) override;
+ 
+protected:
+   DataHeaderCnv_p6 m_tpInConverter_p6;
+  
+   /// Local DHForm cache indexed by filename or reference
+   std::map<std::string,  DataHeaderForm_p6*>    m_persFormMap;
+
    DataHeaderCnv_p5 m_TPconverter;
    RootType m_mapClassDesc;
    mutable std::string m_dhFormMdx;
diff --git a/Database/PersistentDataModelTPCnv/PersistentDataModelTPCnv/DataHeaderCnv_p6.h b/Database/PersistentDataModelTPCnv/PersistentDataModelTPCnv/DataHeaderCnv_p6.h
index 573dfeac2a46f6a1eddb7f15dd4402f470166f86..ba62c0075d738b7e1f572fc276d77b5ccf5db9ff 100755
--- a/Database/PersistentDataModelTPCnv/PersistentDataModelTPCnv/DataHeaderCnv_p6.h
+++ b/Database/PersistentDataModelTPCnv/PersistentDataModelTPCnv/DataHeaderCnv_p6.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
 */
 
 #ifndef PERSISTENTDATAMODELTPCNV_DATAHEADERCNV_P6_H
@@ -7,58 +7,33 @@
 
 /**
  *  @file DataHeaderCnv_p6.h
- *  @brief This file contains the class definition for the DataHeaderCnv_p6 and DataHeaderElementCnv_p6 classes.
+ *  @brief This file contains the class definition for DataHeaderCnv_p6 
  *  @author Peter van Gemmeren <gemmeren@anl.gov>
- *  $Id: DataHeaderCnv_p6.h,v 1.1 2009-04-21 21:48:34 gemmeren Exp $
  **/
 
-#include "PersistentDataModel/DataHeader.h"
-#include "PersistentDataModelTPCnv/DataHeader_p6.h"
-
-#include <map>
-
-/** @class DataHeaderElementCnv_p6
- *  @brief This class provides the converter to customize the saving of DataHeaderElement_p6.
- **/
-class DataHeaderElementCnv_p6 {
-public:
-   DataHeaderElementCnv_p6();
-   virtual ~DataHeaderElementCnv_p6();
-
-   void persToTrans(const DataHeaderElement_p6* pers, DataHeaderElement* trans, const DataHeaderForm_p6& form);
-   void transToPers(const DataHeaderElement* trans, DataHeaderElement_p6* pers, DataHeaderForm_p6& form);
-
-friend class DataHeaderCnv_p6;
-};
+class DataHeader;
+class DataHeader_p6;
+class DataHeaderForm_p6;
 
 /** @class DataHeaderCnv_p6
  *  @brief This class provides the converter to customize the saving of DataHeader_p6.
  **/
 class DataHeaderCnv_p6 {
 public:
-   DataHeaderCnv_p6();
-   virtual ~DataHeaderCnv_p6();
-
-   DataHeader* createTransient(const DataHeader_p6* persObj);
-   void persToTrans(const DataHeader_p6* pers, DataHeader* trans);
-   DataHeader_p6* createPersistent(const DataHeader* transObj);
-   void transToPers(const DataHeader* trans, DataHeader_p6* pers);
-
-   void insertDHRef(DataHeader_p6* pers, const std::string& key, const std::string& strToken);
-
-private:
-   DataHeaderElementCnv_p6 m_elemCnv;
+   DataHeaderCnv_p6() {}
+
+   DataHeader* createTransient(const DataHeader_p6* persObj, const DataHeaderForm_p6& form);
+   DataHeader_p6* createPersistent(const DataHeader* transObj, DataHeaderForm_p6& form);
+
+   /// convert single DH element to persistent represenation
+   void elemToPers(const DataHeaderElement* trans, DataHeader_p6* pers, DataHeaderForm_p6& form);
+   /// restore single DH element from persistent represenation
+   void persToElem(const DataHeader_p6* pers, unsigned p_idx, DataHeaderElement* trans,
+                   const DataHeaderForm_p6& form );
+  
+   void insertDHRef( DataHeader_p6* pers,
+                     const std::string& key, const std::string& strToken,
+                     DataHeaderForm_p6& form );
 };
 
-inline DataHeader* DataHeaderCnv_p6::createTransient(const DataHeader_p6* persObj) {
-   DataHeader* trans = new DataHeader();
-   persToTrans(persObj, trans);
-   return(trans);
-}
-inline DataHeader_p6* DataHeaderCnv_p6::createPersistent(const DataHeader* transObj){
-   DataHeader_p6* pers = new DataHeader_p6();
-   transToPers(transObj, pers);
-   return(pers);
-}
-
 #endif
diff --git a/Database/PersistentDataModelTPCnv/PersistentDataModelTPCnv/DataHeader_p6.h b/Database/PersistentDataModelTPCnv/PersistentDataModelTPCnv/DataHeader_p6.h
index 93493969b48fa442ba3cf105efb2ed85e0d1e29f..5f79bd12be8c204b1d04eb413a3f88833f474d21 100755
--- a/Database/PersistentDataModelTPCnv/PersistentDataModelTPCnv/DataHeader_p6.h
+++ b/Database/PersistentDataModelTPCnv/PersistentDataModelTPCnv/DataHeader_p6.h
@@ -1,15 +1,14 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
 */
 
 #ifndef PERSISTENTDATAMODELTPCNV_DATAHEADER_P6_H
 #define PERSISTENTDATAMODELTPCNV_DATAHEADER_P6_H
 
 /** @file DataHeader_p6.h
- *  @brief This file contains the class definition for the DataHeader_p6,
- *  DataHeaderForm_p6 and DataHeaderElement_p6 classes.
- *  @author Peter van Gemmeren <gemmeren@anl.gov>
- *  $Id: DataHeader_p6.h,v 1.1 2009-04-21 21:48:34 gemmeren Exp $
+ *  @brief This file contains the class definitions for the
+ *  DataHeader_p6 and DataHeaderForm_p6 
+ *  @author Peter van Gemmeren <gemmeren@anl.gov>, Marcin Nowak
  **/
 
 #include "PersistentDataModel/Guid.h"
@@ -18,46 +17,32 @@
 #include <set>
 #include <string>
 
-/** @class DataHeaderElement_p6
- *  @brief This class provides a persistent representation for the DataHeaderElement class.
- **/
-class DataHeaderElement_p6 {
-public: // Constructor and Destructor
-   DataHeaderElement_p6();
-   DataHeaderElement_p6(const DataHeaderElement_p6& rhs);
-   virtual ~DataHeaderElement_p6();
-
-   DataHeaderElement_p6& operator=(const DataHeaderElement_p6& rhs);
-
-friend class DataHeaderCnv_p6;
-friend class DataHeaderElementCnv_p6;
-
-   const std::string& token() const;
-   unsigned long long oid1() const;
-   unsigned long long oid2() const;
-   void overwriteOid2(unsigned long long oid2);
-
-private:
-   std::string m_token;
-   unsigned long long m_oid1;
-   unsigned long long m_oid2;
-
-   unsigned int m_dbIdx; // entry with GUID & technology
-   unsigned int m_objIdx; // Will get entry with ClassId and transient CLID/key, direct clid for now...
-};
+class Token;
 
 /** @class DataHeaderForm_p6
  *  @brief This class provides storage for the constant fields of the persistent DataHeader class.
  **/
 class  DataHeaderForm_p6 {
 public:
-   typedef std::pair<Guid, unsigned int> DbRecord;
-   typedef std::pair<std::string, unsigned int> SgRecord;
-   typedef std::pair<Guid, SgRecord> ObjRecord;
+  struct DbRecord {
+    Guid fid; unsigned tech;
+    DbRecord() {}
+    DbRecord( const Guid& f, unsigned t) : fid(f), tech(t) {}
+    bool operator==(const DbRecord& rhs) const { return fid==rhs.fid && tech==rhs.tech; }
+  };
+  struct ObjRecord {
+    Guid guid; std::string key; unsigned clid; long long oid1;
+    ObjRecord() {}
+    ObjRecord( const Guid& g, const std::string& k, unsigned id, long long o)
+      : guid(g), key(k), clid(id), oid1(o) {}
+    bool operator==(const ObjRecord& rhs) const
+      { return clid == rhs.clid && key == rhs.key && oid1 == rhs.oid1; }
+  };
+
 public: // Constructor and Destructor
-   DataHeaderForm_p6();
+   DataHeaderForm_p6() {}
    DataHeaderForm_p6(const DataHeaderForm_p6& rhs);
-   virtual ~DataHeaderForm_p6();
+   ~DataHeaderForm_p6();
 
    DataHeaderForm_p6& operator=(const DataHeaderForm_p6& rhs);
 
@@ -76,56 +61,72 @@ friend class DataHeaderCnv_p6;
    std::string getObjKey(unsigned int index) const;
    unsigned int getObjType(unsigned int index) const;
    Guid getObjClassId(unsigned int index) const;
+   long long getObjOid1(unsigned int index) const { return m_objRecords[index].oid1; }
    std::set<std::string> getObjAlias(unsigned int index) const;
    std::set<unsigned int> getObjSymLinks(unsigned int index) const;
    std::vector<unsigned int> getObjHashes(unsigned int index) const;
-
-   const std::vector<unsigned int>& params() const;
-   void insertParam(unsigned int param);
-
-   unsigned int entry() const;
-   void start() const;
-   void next() const;
-   unsigned int size() const;
+   std::string calculateMdx();
+   bool wasModified() const;
+   void clearModified();
+   void setToken(Token *tok);
+   Token* getToken() const;
    void resize(unsigned int size);
 
 private:
-   std::vector<std::vector<unsigned int> > m_uints;
    std::vector<DbRecord> m_dbRecords;
    std::vector<ObjRecord> m_objRecords;
    std::vector<std::vector<std::string> > m_objAlias;
    std::vector<std::vector<unsigned int> > m_objSymLinks;
    std::vector<std::vector<unsigned int> > m_objHashes;
-   mutable unsigned int m_entry;
+
+   /// In case we need ot handle encoding changes later
+   unsigned             m_version { 600 };
+  
+   // transient members
+   /// indicates that the last event was somehow different and a new DHForm needs to be written
+   bool                 m_modified { true };
+   /// Reference to self in the persistent storage
+   Token*               m_token { nullptr };
 };
 
+
 /** @class DataHeader_p6
  *  @brief This class provides a persistent representation for the DataHeader class.
- **/
-class  DataHeader_p6 {
-public: // Constructor and Destructor
-   DataHeader_p6();
-   DataHeader_p6(const DataHeader_p6& rhs);
-   virtual ~DataHeader_p6();
-
-   DataHeader_p6& operator=(const DataHeader_p6& rhs);
 
-friend class DataHeaderCnv_p6;
-
-   const std::vector<DataHeaderElement_p6>& elements() const;
-   const DataHeaderForm_p6& dhForm() const;
-   void setDhForm(const DataHeaderForm_p6& form);
+    Version P6 optimized FOR references pointing to the same OID2 in the same Database
+ **/
+class  DataHeader_p6
+{
+  friend class DataHeaderCnv_p6;
+
+public: 
+  struct FullElement {
+    FullElement() : oid2(0), dbIdx(0), objIdx(0) {}
+    FullElement(unsigned long long o2, unsigned db, unsigned obj) : oid2(o2), dbIdx(db), objIdx(obj) {}
+    unsigned long long oid2;
+    unsigned int dbIdx;  // index to DHForm entry with DB GUID & technology
+    unsigned int objIdx; // index to DHForm entry with object data
+  };
+
+   DataHeader_p6() {};
    const std::string& dhFormToken() const;
    void setDhFormToken(const std::string& formToken);
-   void calculateDhFormMdx();
-   const std::string& dhFormMdx() const;
-
+  
 private:
-   std::vector<DataHeaderElement_p6> m_dataHeader;
-   unsigned int m_provenanceSize;
-   DataHeaderForm_p6 m_dhForm;
-   std::string m_dhFormToken;
-   std::string m_dhFormMdx;
+   /// common DB entry index used by all short DH elements
+   unsigned                     m_commonDbIndex;
+   unsigned long long           m_commonOID2;
+  
+   std::vector<int>             m_shortElements;
+   std::vector<FullElement>     m_fullElements;
+   unsigned int                 m_provenanceSize;
+
+   std::string                  m_dhFormToken;
 };
 
 #endif
+
+
+
+
+
diff --git a/Database/PersistentDataModelTPCnv/PersistentDataModelTPCnv/PersistentDataModelTPCnvDict.h b/Database/PersistentDataModelTPCnv/PersistentDataModelTPCnv/PersistentDataModelTPCnvDict.h
index a400a019cfa9363b43347cb00582737645c12e43..16ab3cc1e07fd12865f0d0dfbda8c07eed142f4c 100755
--- a/Database/PersistentDataModelTPCnv/PersistentDataModelTPCnv/PersistentDataModelTPCnvDict.h
+++ b/Database/PersistentDataModelTPCnv/PersistentDataModelTPCnv/PersistentDataModelTPCnvDict.h
@@ -1,5 +1,5 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
 */
 
 #ifndef PERSISTENTDATAMODEL_PERSISTENTDATAMODELTPCNVDICT_H
@@ -12,14 +12,4 @@
 #include "PersistentDataModelTPCnv/DataHeaderCnv_p5.h"
 #include "PersistentDataModelTPCnv/DataHeaderCnv_p6.h"
 
-// Need to instantiate iterators
-namespace PersistentDataModelTPCnvDict {
-   // template instantiations
-   std::pair<Guid, unsigned int> dummy_dbRecord;
-   std::vector<std::pair<Guid, unsigned int> > dummy_dbRecords;
-   std::pair<std::string, unsigned int> dummy_sgRecord;
-   std::pair<Guid, std::pair<std::string, unsigned int> > dummy_objRecord;
-   std::vector<std::pair<Guid, std::pair<std::string, unsigned int> > >dummy_objRecords;
-}
-
 #endif
diff --git a/Database/PersistentDataModelTPCnv/PersistentDataModelTPCnv/selection.xml b/Database/PersistentDataModelTPCnv/PersistentDataModelTPCnv/selection.xml
index e7518182335dac25cc0625d3f0d6a9344d5051c1..5c14730f069383de120b130591614fae1a13d2bb 100755
--- a/Database/PersistentDataModelTPCnv/PersistentDataModelTPCnv/selection.xml
+++ b/Database/PersistentDataModelTPCnv/PersistentDataModelTPCnv/selection.xml
@@ -14,18 +14,19 @@
       <field name="m_entry" transient="true" />
    </class>
    <class name="DataHeaderCnv_p5"/>
+
    <class name="DataHeader_p6" id="4DDBD295-EFCE-472A-9EC8-15CD35A9EB8D">
-      <field name="m_dhForm" transient="true" />
    </class>
-   <class name="std::vector<DataHeaderElement_p6>" />
-   <class name="DataHeaderElement_p6" />
+   <class name="std::vector<DataHeader_p6::FullElement>" />
+   <class name="DataHeader_p6::FullElement" />
    <class name="DataHeaderForm_p6" id="7BE56CEF-C866-4BEE-9348-A5F34B5F1DAD">
-      <field name="m_entry" transient="true" />
+      <field name="m_modified" transient="true" />
+      <field name="m_token" transient="true" />
    </class>
-   <class name="std::vector<std::pair<Guid, unsigned int> >" />
-   <class name="std::pair<Guid, unsigned int>" />
+   <class name="DataHeaderForm_p6::DbRecord" />
+   <class name="DataHeaderForm_p6::ObjRecord" />
    <class name="Guid" />
-   <class name="std::vector<std::pair<Guid, std::pair<std::string, unsigned int> > >" />
-   <class name="std::pair<Guid, std::pair<std::string, unsigned int> >" />
+   <class name="std::vector<DataHeaderForm_p6::DbRecord>" />
+   <class name="std::vector<DataHeaderForm_p6::ObjRecord>" />
    <class name="DataHeaderCnv_p6"/>
 </lcgdict>
diff --git a/Database/PersistentDataModelTPCnv/src/DataHeaderCnv_p6.cxx b/Database/PersistentDataModelTPCnv/src/DataHeaderCnv_p6.cxx
index d4e737e255f54e424d615e371bceab2b0ec65dd2..f69fd3694f4f8df28c0423d90cc513e6433b89c7 100755
--- a/Database/PersistentDataModelTPCnv/src/DataHeaderCnv_p6.cxx
+++ b/Database/PersistentDataModelTPCnv/src/DataHeaderCnv_p6.cxx
@@ -1,106 +1,136 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
 */
 
 /** @file DataHeaderCnv_p6.cxx
  *  @brief This file contains the implementation for the DataHeaderCnv_p6 class.
  *  @author Peter van Gemmeren <gemmeren@anl.gov>
- *  $Id: DataHeaderCnv_p6.cxx,v 1.3.2.2 2009-05-22 19:26:54 gemmeren Exp $
  **/
 
 #include "PersistentDataModel/DataHeader.h"
+#include "PersistentDataModelTPCnv/DataHeader_p6.h"
 #include "PersistentDataModelTPCnv/DataHeaderCnv_p6.h"
+#include <climits>
 
-DataHeaderElementCnv_p6::DataHeaderElementCnv_p6() {}
-DataHeaderElementCnv_p6::~DataHeaderElementCnv_p6() {}
+using FullElement  = DataHeader_p6::FullElement;
 
 //______________________________________________________________________________
-void DataHeaderElementCnv_p6::persToTrans(const DataHeaderElement_p6* pers,
-	DataHeaderElement* trans,
-	const DataHeaderForm_p6& form) {
-   delete trans->m_token; trans->m_token = new Token;
-   Token* token = const_cast<Token*>(trans->m_token);
-// Append DbGuid
-   token->setDb(form.getDbGuid(pers->m_dbIdx));
-   token->setTechnology(form.getDbTech(pers->m_dbIdx));
-// Append ClassId
-   token->setClassID(form.getObjClassId(pers->m_objIdx));
-   token->setOid(Token::OID_t(pers->m_oid1, pers->m_oid2));
-// StoreGate
-   trans->m_key = form.getObjKey(pers->m_objIdx);
-   trans->m_alias = form.getObjAlias(pers->m_objIdx);
-   trans->m_pClid = form.getObjType(pers->m_objIdx);
-   trans->m_clids = form.getObjSymLinks(pers->m_objIdx);
-   trans->m_hashes = form.getObjHashes(pers->m_objIdx);
-}
-//______________________________________________________________________________
-void DataHeaderElementCnv_p6::transToPers(const DataHeaderElement* trans,
-	DataHeaderElement_p6* pers,
-	DataHeaderForm_p6& form) {
-// Translate PoolToken
-   if (trans->getToken() != 0) {
-// Database GUID & Technology
-      DataHeaderForm_p6::DbRecord transDb(trans->getToken()->dbID(), trans->getToken()->technology());
-      pers->m_dbIdx = form.insertDb(transDb);
-// StoreGate Type/Key & persistent Class GUID
-      DataHeaderForm_p6::SgRecord transSg(trans->m_key, trans->m_pClid);
-      DataHeaderForm_p6::ObjRecord transObj(trans->getToken()->classID(), transSg);
-      pers->m_objIdx = form.insertObj(transObj, trans->m_alias, trans->m_clids, trans->m_hashes);
-      pers->m_oid1 = trans->getToken()->oid().first;
-      pers->m_oid2 = trans->getToken()->oid().second;
+void DataHeaderCnv_p6::persToElem( const DataHeader_p6* pers, unsigned p_idx,
+                                    DataHeaderElement* trans, const DataHeaderForm_p6& form )
+{
+   delete trans->m_token;  trans->m_token = nullptr;
+   int obj_idx = pers->m_shortElements[p_idx];
+   if( obj_idx != INT32_MIN ) {
+      Token* token = new Token;
+      trans->m_token = token;
+      unsigned db_idx = 0;
+      unsigned long long oid2 = 0;
+      if( obj_idx >= 0 ) {
+         db_idx = pers->m_commonDbIndex;
+         oid2   = pers->m_commonOID2;
+      } else {
+         const FullElement &full_el = pers->m_fullElements[ -1 - obj_idx ];
+         db_idx = full_el.dbIdx;
+         obj_idx = full_el.objIdx;
+         oid2 = full_el.oid2;
+      }
+      // Append DbGuid
+      token->setDb(         form.getDbGuid(db_idx ) );
+      token->setTechnology( form.getDbTech(db_idx ) );
+      // Append ClassId
+      token->setClassID(    form.getObjClassId(obj_idx) );
+      token->setOid( Token::OID_t( form.getObjOid1(obj_idx), oid2) );
+      // StoreGate
+      trans->m_key = form.getObjKey( obj_idx );
+      trans->m_alias = form.getObjAlias( obj_idx );
+      trans->m_pClid = form.getObjType( obj_idx );
+      trans->m_clids = form.getObjSymLinks( obj_idx );
+      trans->m_hashes = form.getObjHashes( obj_idx );
    }
 }
+
 //______________________________________________________________________________
-//______________________________________________________________________________
-DataHeaderCnv_p6::DataHeaderCnv_p6() {}
-DataHeaderCnv_p6::~DataHeaderCnv_p6() {}
-//______________________________________________________________________________
-void DataHeaderCnv_p6::persToTrans(const DataHeader_p6* pers, DataHeader* trans) {
-   pers->m_dhForm.start();
+DataHeader* DataHeaderCnv_p6::createTransient(const DataHeader_p6* pers, const DataHeaderForm_p6& form)
+{
+   DataHeader* trans = new DataHeader();
    const unsigned int provSize = pers->m_provenanceSize;
    trans->m_inputDataHeader.resize(provSize);
-   std::vector<DataHeaderElement>::iterator it = trans->m_inputDataHeader.begin();
-   std::vector<DataHeaderElement_p6>::const_iterator pit = pers->m_dataHeader.begin();
-   for (unsigned int i = 0U; i < provSize; i++, it++, pit++) {
-      m_elemCnv.persToTrans(&(*pit), &(*it), pers->m_dhForm);
-      pers->m_dhForm.next();
+   trans->m_dataHeader.resize(pers->m_shortElements.size() - provSize);
+
+   unsigned i = 0;
+   for( auto& elem : trans->m_dataHeader ) {
+      persToElem( pers, i++, &elem, form );
    }
-   trans->m_dataHeader.resize(pers->m_dataHeader.size() - provSize);
-   it = trans->m_dataHeader.begin();
-   for (std::vector<DataHeaderElement_p6>::const_iterator last = pers->m_dataHeader.end();
-		   pit != last; it++, pit++) {
-      m_elemCnv.persToTrans(&(*pit), &(*it), pers->m_dhForm);
-      pers->m_dhForm.next();
+   for( auto& elem : trans->m_inputDataHeader ) {
+      persToElem( pers, i++, &elem, form );
    }
+   trans->setStatus(DataHeader::Input);
+   return trans;
 }
+
+
 //______________________________________________________________________________
-void DataHeaderCnv_p6::transToPers(const DataHeader* trans, DataHeader_p6* pers) {
+void DataHeaderCnv_p6::elemToPers(const DataHeaderElement* trans,
+                                  DataHeader_p6* pers,
+                                  DataHeaderForm_p6& form)
+{
+   // Translate PoolToken
+   const Token *token =  trans->getToken();
+   if( !token ) {
+      // store marker for NO Token
+      pers->m_shortElements.push_back( INT32_MIN );
+   } else {
+      // Database GUID & Technology
+      DataHeaderForm_p6::DbRecord  db_rec( token->dbID(), token->technology() );
+      unsigned db_idx = form.insertDb( db_rec );
+      // StoreGate Type/Key & persistent Class GUID
+      DataHeaderForm_p6::ObjRecord transObj( token->classID(), trans->m_key, trans->m_pClid, token->oid().first );
+      unsigned obj_idx = form.insertObj(transObj, trans->m_alias, trans->m_clids, trans->m_hashes);
+      unsigned long long oid2 = token->oid().second;
+
+      // first element sets the common DB
+      if( pers->m_shortElements.empty() ) {
+         // first element - set the common DB and OID2 values
+         pers->m_commonDbIndex = db_idx;
+         pers->m_commonOID2 = oid2;
+      }
+      if( db_idx == pers->m_commonDbIndex && oid2 == pers->m_commonOID2 ) {
+         // Can use short DH element
+         pers->m_shortElements.push_back( obj_idx );
+      } else {
+         // need to use full DH element
+         // store the index (as negative) to the full element in the short vector
+         pers->m_shortElements.push_back( -1 - pers->m_fullElements.size() );
+         pers->m_fullElements.push_back( FullElement(oid2, db_idx, obj_idx) );
+      }
+   }
+}
+
+//______________________________________________________________________________
+DataHeader_p6* DataHeaderCnv_p6::createPersistent(const DataHeader* trans, DataHeaderForm_p6& form)
+{
+   DataHeader_p6* pers = new DataHeader_p6();
    const unsigned int provSize = trans->m_inputDataHeader.size();
-   pers->m_dataHeader.resize(provSize + trans->m_dataHeader.size());
    pers->m_provenanceSize = provSize;
-   pers->m_dhForm.resize(provSize + trans->m_dataHeader.size() + 1);
-   pers->m_dhForm.start();
-   std::vector<DataHeaderElement_p6>::iterator pit = pers->m_dataHeader.begin();
-   for (std::vector<DataHeaderElement>::const_iterator it = trans->m_inputDataHeader.begin(),
-		   last = trans->m_inputDataHeader.end(); it != last; it++, pit++) {
-      m_elemCnv.transToPers(&(*it), &(*pit), pers->m_dhForm);
-      pers->m_dhForm.next();
+
+   pers->m_shortElements.reserve( provSize + trans->m_dataHeader.size() );
+   form.resize(provSize + trans->m_dataHeader.size() + 1);
+   for( const auto& transElem: trans->m_dataHeader ) {
+      elemToPers( &transElem, pers, form );
    }
-   for (std::vector<DataHeaderElement>::const_iterator it = trans->m_dataHeader.begin(),
-		   last = trans->m_dataHeader.end(); it != last; it++, pit++) {
-      m_elemCnv.transToPers(&(*it), &(*pit), pers->m_dhForm);
-      pers->m_dhForm.next();
+   for( const auto& transElem: trans->m_inputDataHeader ) {
+      elemToPers( &transElem, pers, form );
    }
+   return pers;
 }
+
 //______________________________________________________________________________
-void DataHeaderCnv_p6::insertDHRef(DataHeader_p6* pers,
-	const std::string& key,
-	const std::string& strToken) {
+void DataHeaderCnv_p6::insertDHRef( DataHeader_p6* pers,
+                                    const std::string& key, const std::string& strToken,
+                                    DataHeaderForm_p6& form )
+{
    Token* token = new Token;
    token->fromString(strToken);
    DataHeaderElement tEle(ClassID_traits<DataHeader>::ID(), key, token);
-   DataHeaderElement_p6 pEle;
-   pers->m_dhForm.next();
-   m_elemCnv.transToPers(&tEle, &pEle, pers->m_dhForm);
-   pers->m_dataHeader.push_back(pEle);
+   elemToPers( &tEle, pers, form );
 }
diff --git a/Database/PersistentDataModelTPCnv/src/DataHeader_p6.cxx b/Database/PersistentDataModelTPCnv/src/DataHeader_p6.cxx
index 554ecff84d0b62f2149d987eb22890e9b889113d..882f53a548afd8f4db55118550349a2424a604e6 100755
--- a/Database/PersistentDataModelTPCnv/src/DataHeader_p6.cxx
+++ b/Database/PersistentDataModelTPCnv/src/DataHeader_p6.cxx
@@ -1,71 +1,43 @@
 /*
-  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+  Copyright (C) 2002-2019 CERN for the benefit of the ATLAS collaboration
 */
 
 #include "PersistentDataModelTPCnv/DataHeader_p6.h"
+#include "PersistentDataModel/Token.h"
 
 #include "CxxUtils/MD5.h"
 
 #include <uuid/uuid.h>
-#include <sstream>
-
-DataHeaderElement_p6::DataHeaderElement_p6() :
-  m_token(),
-  m_oid1(0ULL),
-  m_oid2(0ULL),
-  m_dbIdx(0),
-  m_objIdx(0) {}
-DataHeaderElement_p6::DataHeaderElement_p6(const DataHeaderElement_p6& rhs) : m_token(rhs.m_token),
-	m_oid1(rhs.m_oid1),
-	m_oid2(rhs.m_oid2),
-	m_dbIdx(rhs.m_dbIdx),
-	m_objIdx(rhs.m_objIdx) {}
-DataHeaderElement_p6::~DataHeaderElement_p6() {}
-
-DataHeaderElement_p6& DataHeaderElement_p6::operator=(const DataHeaderElement_p6& rhs) {
-   if (this != &rhs) {
-      m_token = rhs.m_token;
-      m_oid1 = rhs.m_oid1;
-      m_oid2 = rhs.m_oid2;
-      m_dbIdx = rhs.m_dbIdx;
-      m_objIdx = rhs.m_objIdx;
-   }
-   return(*this);
-}
-
-const std::string& DataHeaderElement_p6::token() const {
-   return(m_token);
-}
-
-unsigned long long DataHeaderElement_p6::oid1() const {
-   return(m_oid1);
-}
 
-unsigned long long DataHeaderElement_p6::oid2() const {
-   return(m_oid2);
+DataHeaderForm_p6::DataHeaderForm_p6(const DataHeaderForm_p6& rhs) :
+      m_dbRecords(rhs.m_dbRecords), m_objRecords(rhs.m_objRecords),
+      m_objAlias(rhs.m_objAlias), m_objSymLinks(rhs.m_objSymLinks),
+      m_objHashes(rhs.m_objHashes), m_version(rhs.m_version),
+      m_modified(rhs.m_modified), m_token(nullptr)
+{
+   setToken(rhs.m_token);
 }
 
-void DataHeaderElement_p6::overwriteOid2(unsigned long long oid2) {
-   m_oid2 = oid2;
-}
-
-
-DataHeaderForm_p6::DataHeaderForm_p6() : m_uints(), m_dbRecords(), m_objRecords(), m_objAlias(), m_objSymLinks(), m_objHashes(), m_entry(0U) {}
-DataHeaderForm_p6::DataHeaderForm_p6(const DataHeaderForm_p6& rhs) : m_uints(rhs.m_uints), m_dbRecords(rhs.m_dbRecords), m_objRecords(rhs.m_objRecords), m_objAlias(rhs.m_objAlias), m_objSymLinks(rhs.m_objSymLinks), m_objHashes(rhs.m_objHashes), m_entry(0U) {}
-DataHeaderForm_p6::~DataHeaderForm_p6() {}
 DataHeaderForm_p6& DataHeaderForm_p6::operator=(const DataHeaderForm_p6& rhs) {
    if (&rhs != this) {
-      m_uints = rhs.m_uints;
       m_dbRecords = rhs.m_dbRecords;
       m_objRecords = rhs.m_objRecords;
       m_objAlias = rhs.m_objAlias;
       m_objSymLinks = rhs.m_objSymLinks;
       m_objHashes = rhs.m_objHashes;
-      m_entry = 0U;
+      m_version = rhs.m_version;
+      m_modified = rhs.m_modified;
+      setToken(rhs.m_token);
    }
    return(*this);
 }
 
+DataHeaderForm_p6::~DataHeaderForm_p6()
+{
+   if( m_token ) m_token->release();
+}
+
+
 unsigned int DataHeaderForm_p6::insertDb(const DbRecord& rec) {
    unsigned int index = 0U;
    for (std::vector<DbRecord>::const_iterator iter = m_dbRecords.begin(), last = m_dbRecords.end();
@@ -74,6 +46,7 @@ unsigned int DataHeaderForm_p6::insertDb(const DbRecord& rec) {
    }
    if (index == m_dbRecords.size()) {
       m_dbRecords.push_back(rec);
+      m_modified = true;
    }
    return(index);
 }
@@ -83,29 +56,48 @@ std::size_t DataHeaderForm_p6::sizeDb() const {
 }
 
 Guid DataHeaderForm_p6::getDbGuid(unsigned int index) const {
-   return(m_dbRecords[index].first);
+   return m_dbRecords[index].fid;
 }
 
 unsigned int DataHeaderForm_p6::getDbTech(unsigned int index) const {
-   return(m_dbRecords[index].second);
+   return m_dbRecords[index].tech;
 }
 
 unsigned int DataHeaderForm_p6::insertObj(const ObjRecord& rec,
 	const std::set<std::string>& alias,
 	const std::set<unsigned int>& symLinks,
-	const std::vector<unsigned int>& hashes) {
+	const std::vector<unsigned int>& hashes)
+{
    unsigned int index = 0U;
    for (std::vector<ObjRecord>::const_iterator iter = m_objRecords.begin(), last = m_objRecords.end();
            iter != last; iter++, index++) {
       if (*iter == rec) break;
    }
-   if (index == m_objRecords.size()) {
-      m_objRecords.push_back(rec);
-      m_objAlias.push_back(std::vector<std::string>(alias.begin(), alias.end()));
-      m_objSymLinks.push_back(std::vector<unsigned int>(symLinks.begin(), symLinks.end()));
-      m_objHashes.push_back(hashes);
+   std::vector<std::string>     aliases( alias.begin(), alias.end() );
+   std::vector<unsigned int>    symlinks( symLinks.begin(), symLinks.end() );
+   if (index != m_objRecords.size()) {
+      // found matching object record, check if all the info is the same
+      if( m_objAlias[index] != aliases ) {
+         m_objAlias[index] = std::move(aliases);
+         m_modified = true;
+      }
+      if( m_objSymLinks[index] != symlinks ) {
+         m_objSymLinks[index] = std::move(symlinks);
+         m_modified = true;
+      }
+      if( m_objHashes[index] != hashes ) {
+         m_objHashes[index] = hashes;
+         m_modified = true;
+      }
+      return index;
    }
-   return(index);
+   // enter a new record
+   m_objRecords.push_back( rec );
+   m_objAlias.push_back( std::move(aliases) );
+   m_objSymLinks.push_back( std::move(symlinks) );
+   m_objHashes.push_back( hashes );
+   m_modified = true;
+   return m_objRecords.size() - 1;
 }
 
 std::size_t DataHeaderForm_p6::sizeObj() const {
@@ -113,15 +105,15 @@ std::size_t DataHeaderForm_p6::sizeObj() const {
 }
 
 std::string DataHeaderForm_p6::getObjKey(unsigned int index) const {
-   return(m_objRecords[index].second.first);
+   return m_objRecords[index].key;
 }
 
 unsigned int DataHeaderForm_p6::getObjType(unsigned int index) const {
-   return(m_objRecords[index].second.second);
+   return m_objRecords[index].clid;
 }
 
 Guid DataHeaderForm_p6::getObjClassId(unsigned int index) const {
-   return(m_objRecords[index].first);
+   return m_objRecords[index].guid;
 }
 
 std::set<std::string> DataHeaderForm_p6::getObjAlias(unsigned int index) const {
@@ -137,67 +129,35 @@ std::vector<unsigned int> DataHeaderForm_p6::getObjHashes(unsigned int index) co
 }
 
 
-
-const std::vector<unsigned int>& DataHeaderForm_p6::params() const {
-   return(m_uints[m_entry]);
+bool DataHeaderForm_p6::wasModified() const {
+   return m_modified;
 }
 
-void DataHeaderForm_p6::insertParam(unsigned int param) {
-   m_uints[m_entry].push_back(param);
+void DataHeaderForm_p6::clearModified() {
+   m_modified = false;
 }
 
-unsigned int DataHeaderForm_p6::entry() const {
-   return(m_entry);
+void DataHeaderForm_p6::setToken( Token *tok )
+{
+   if( tok ) tok->addRef(); 
+   if( m_token ) m_token->release();
+   m_token = tok;
 }
 
-void DataHeaderForm_p6::start() const {
-   m_entry = 0;
-}
-
-void DataHeaderForm_p6::next() const {
-   m_entry++;
-}
-
-unsigned int DataHeaderForm_p6::size() const {
-   return(m_uints.size());
+Token* DataHeaderForm_p6::getToken() const {
+   return m_token;
 }
 
 void DataHeaderForm_p6::resize(unsigned int size) {
-   m_uints.resize(size);
-}
-
-
-DataHeader_p6::DataHeader_p6() : m_dataHeader(), m_provenanceSize(0U), m_dhForm(), m_dhFormToken(), m_dhFormMdx() {}
-DataHeader_p6::DataHeader_p6(const DataHeader_p6& rhs) :
-  m_dataHeader(rhs.m_dataHeader),
-  m_provenanceSize(rhs.m_provenanceSize),
-  m_dhForm(rhs.m_dhForm),
-  m_dhFormToken(rhs.m_dhFormToken),
-  m_dhFormMdx(rhs.m_dhFormMdx) {}
-DataHeader_p6::~DataHeader_p6() {}
-
-DataHeader_p6& DataHeader_p6::operator=(const DataHeader_p6& rhs) {
-   if (this != &rhs) {
-      m_dataHeader = rhs.m_dataHeader;
-      m_provenanceSize = rhs.m_provenanceSize;
-      m_dhForm = rhs.m_dhForm;
-      m_dhFormToken = rhs.m_dhFormToken;
-      m_dhFormMdx = rhs.m_dhFormMdx;
-   }
-   return(*this);
+   m_objRecords.reserve( size );
+   m_objAlias.reserve( size );
+   m_objSymLinks.reserve( size );
+   m_objHashes.reserve( size );
 }
 
-const std::vector<DataHeaderElement_p6>& DataHeader_p6::elements() const {
-   return(m_dataHeader);
-}
 
-const DataHeaderForm_p6& DataHeader_p6::dhForm() const {
-   return(m_dhForm);
-}
 
-void DataHeader_p6::setDhForm(const DataHeaderForm_p6& form) {
-   m_dhForm = form;
-}
+//---------------------------------------------------------------------
 
 const std::string& DataHeader_p6::dhFormToken() const {
    return(m_dhFormToken);
@@ -207,22 +167,3 @@ void DataHeader_p6::setDhFormToken(const std::string& formToken) {
    m_dhFormToken = formToken;
 }
 
-void DataHeader_p6::calculateDhFormMdx() {
-   std::ostringstream stream;
-   for (std::size_t iter = 0, last = m_dhForm.sizeDb(); iter != last; iter++) {
-	stream << m_dhForm.getDbGuid(iter) << "," << m_dhForm.getDbTech(iter) << "\n";
-   }
-   for (std::size_t iter = 0, last = m_dhForm.sizeObj(); iter != last; iter++) {
-	stream << m_dhForm.getObjKey(iter) << "," << m_dhForm.getObjType(iter) << "," << m_dhForm.getObjClassId(iter) << "\n";
-   }
-   MD5 checkSum((unsigned char*)stream.str().c_str(), stream.str().size());
-   uuid_t checkSumUuid;
-   checkSum.raw_digest((unsigned char*)(&checkSumUuid));
-   char text[37];
-   uuid_unparse_upper(checkSumUuid, text);
-   m_dhFormMdx = text;
-}
-
-const std::string& DataHeader_p6::dhFormMdx() const {
-   return(m_dhFormMdx);
-}