From c2619d8040a15dabd9ee71dfa16f1b726b701c8d Mon Sep 17 00:00:00 2001
From: Peter Van Gemmeren <peter.van.gemmeren@cern.ch>
Date: Wed, 11 May 2016 17:10:35 +0200
Subject: [PATCH] Adjust AthenaPoolCnvSvc to changes to AthenaSharedMemoryTool
 implementation (AthenaPoolCnvSvc-00-28-20)

2016-05-11  Peter van Gemmeren <gemmeren@anl.gov>
	* src/AthenaPoolCnvSvc.cxx: Adjust to changes to
	AthenaSharedMemoryTool implementation.
	* tag AthenaPoolCnvSvc-00-28-20

2016-04-14  Peter van Gemmeren <gemmeren@anl.gov>
	* src/AthenaPoolCnvSvc.cxx: Adjust to changes to IAthenaIPCTool inface.
	* tag AthenaPoolCnvSvc-00-28-18

2016-04-06  Peter van Gemmeren <gemmeren@anl.gov>
	* AthenaPoolCnvSvc: Get Placement from Athena (PersistentDataModel).
	* tag AthenaPoolCnvSvc-00-28-17

2016-04-05 Attila Krasznahorkay <Attila.Krasznahorkay@cern.ch>
	* Added a hand-written CMakeLists.txt file to make sure that the
	  package's tests are executed correctly.
	* Removed the executable flag from the source files of the package.
	* Removed the empty cmt/fragments directory.
	* Tagging as AthenaPoolCnvSvc-00-28-15

...
(Long ChangeLog diff - truncated)
---
 .../AthenaPoolCnvTPExtension.h                |   0
 .../AthenaPoolCnvSvc/AthenaPoolConverter.h    |  30 +-
 .../AthenaPoolTopLevelTPCnvBase.h             |   0
 .../AthenaPoolTopLevelTPConverter.h           |   0
 .../AthenaPoolCnvSvc/IAthenaPoolCleanUp.h     |   0
 .../AthenaPoolCnvSvc/IAthenaPoolCleanUpSvc.h  |   0
 .../AthenaPoolCnvSvc/IAthenaPoolCnvSvc.h      |  18 +-
 .../AthenaPoolCnvSvc/ITPConverter.h           |   0
 .../AthenaPoolCnvSvc/TPCnvElt.h               | 167 +++++++++++
 .../AthenaPoolCnvSvc/TPCnvElt.icc             | 142 +++++++++
 .../AthenaPoolCnvSvc/TPCnvList.h              | 127 +++++++++
 .../AthenaPoolCnvSvc/TPCnvList.icc            | 136 +++++++++
 .../T_AthenaPoolAuxContainerCnv.h             |  88 ++++++
 .../T_AthenaPoolAuxContainerCnv.icc           |  64 +++++
 .../AthenaPoolCnvSvc/T_AthenaPoolCnv.h        |  40 +--
 .../AthenaPoolCnvSvc/T_AthenaPoolCnvBase.h    |  54 ++++
 ...enaPoolCnv.icc => T_AthenaPoolCnvBase.icc} |  58 ++--
 .../T_AthenaPoolCoolMultChanCnv.h             |   0
 .../T_AthenaPoolCoolMultChanCnv.icc           |  14 +-
 .../AthenaPoolCnvSvc/T_AthenaPoolCustCnv.h    |  11 +-
 .../AthenaPoolCnvSvc/T_AthenaPoolCustCnv.icc  |  96 ++-----
 .../AthenaPoolCnvSvc/T_AthenaPoolCustomCnv.h  |   2 +-
 .../T_AthenaPoolCustomCnv.icc                 |  72 +----
 .../T_AthenaPoolExtendingCnv.h                |   0
 .../T_AthenaPoolExtendingCnv.icc              |   4 +-
 .../AthenaPoolCnvSvc/T_AthenaPoolTPCnvCnv.h   |  92 ++++++
 .../AthenaPoolCnvSvc/T_AthenaPoolTPCnvCnv.icc |  65 +++++
 .../T_AthenaPoolTPConverter.h                 |   0
 .../T_AthenaPoolViewVectorCnv.h               |  93 ++++++
 .../T_AthenaPoolViewVectorCnv.icc             | 118 ++++++++
 .../AthenaPoolCnvSvc/T_AthenaPoolxAODCnv.h    | 104 +++++++
 .../AthenaPoolCnvSvc/T_AthenaPoolxAODCnv.icc  |  90 ++++++
 .../AthenaPoolCnvSvc/exceptions.h             |  84 ++++++
 .../AthenaPoolCnvSvc/selection_test.xml       |  29 ++
 .../AthenaPoolCnvSvc/CMakeLists.txt           | 105 +++++++
 .../AthenaPoolCnvSvc/cmt/requirements         |  26 +-
 .../AthenaPoolCnvSvc/doc/MainPage.h           |   0
 .../AthenaPoolCnvSvc/python/AthenaPool.py     |   0
 .../AthenaPoolCnvSvc/python/ReadAthenaPool.py |  15 +
 .../python/WriteAthenaPool.py                 |   0
 .../AthenaPoolCnvSvc/python/__init__.py       |   0
 .../share/AthenaPoolCnvSvc_jobOptions.py      |   0
 .../share/AthenaPool_jobOptions.py            |   0
 .../share/ReadAthenaPool_jobOptions.py        |   0
 .../AthenaPoolCnvSvc/share/TPCnvElt_test.ref  |   2 +
 .../AthenaPoolCnvSvc/share/TPCnvList_test.ref |   1 +
 .../T_AthenaPoolAuxContainerCnv_test.ref      |  20 ++
 .../share/T_AthenaPoolTPCnvCnv_test.ref       |  20 ++
 .../share/T_AthenaPoolViewVectorCnv_test.ref  |  20 ++
 .../share/T_AthenaPoolxAODCnv_test.ref        |  19 ++
 .../share/WriteAthenaPool_jobOptions.py       |   0
 .../share/exceptions_test.ref                 |   3 +
 .../AthenaPoolCnvSvc/share/test.txt           |   1 +
 .../src/AthenaAttributeListCnv.cxx            |   0
 .../src/AthenaAttributeListCnv.h              |   0
 .../AthenaPoolCnvSvc/src/AthenaPoolCnvSvc.cxx | 269 ++++++++++++++----
 .../AthenaPoolCnvSvc/src/AthenaPoolCnvSvc.h   |  27 +-
 .../src/AthenaPoolConverter.cxx               |  72 ++---
 .../src/AthenaPoolTopLevelTPCnvBase.cxx       |   0
 .../src/AthenaRootSerializeSvc.cxx            |  79 +++++
 .../src/AthenaRootSerializeSvc.h              |  41 +++
 .../src/CondAttrListCollCnv.cxx               |   0
 .../src/CondAttrListCollCnv.h                 |   0
 .../src/CondAttrListVecCnv.cxx                |   0
 .../AthenaPoolCnvSvc/src/CondAttrListVecCnv.h |   0
 .../AthenaPoolCnvSvc/src/TPCnvElt.cxx         |  36 +++
 .../components/AthenaPoolCnvSvc_entries.cxx   |   3 +
 .../src/components/AthenaPoolCnvSvc_load.cxx  |   0
 .../AthenaPoolCnvSvc/src/exceptions.cxx       |  92 ++++++
 .../test/AthenaPoolCnvSvc.xml                 |  15 +
 .../test/AthenaPoolCnvSvcTestDict.h           | 115 ++++++++
 .../AthenaPoolCnvSvc/test/TPCnvElt_test.cxx   | 113 ++++++++
 .../AthenaPoolCnvSvc/test/TPCnvList_test.cxx  | 129 +++++++++
 .../test/T_AthenaPoolAuxContainerCnv_test.cxx | 269 ++++++++++++++++++
 .../test/T_AthenaPoolTPCnvCnv_test.cxx        | 227 +++++++++++++++
 .../test/T_AthenaPoolViewVectorCnv_test.cxx   | 186 ++++++++++++
 .../test/T_AthenaPoolxAODCnv_test.cxx         | 161 +++++++++++
 .../AthenaPoolCnvSvc/test/TestCnvSvcBase.icc  | 145 ++++++++++
 .../AthenaPoolCnvSvc/test/TestThinningSvc.icc | 138 +++++++++
 .../AthenaPoolCnvSvc/test/exceptions_test.cxx |  35 +++
 80 files changed, 3831 insertions(+), 351 deletions(-)
 mode change 100755 => 100644 Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/AthenaPoolCnvTPExtension.h
 mode change 100755 => 100644 Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/AthenaPoolConverter.h
 mode change 100755 => 100644 Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/AthenaPoolTopLevelTPCnvBase.h
 mode change 100755 => 100644 Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/AthenaPoolTopLevelTPConverter.h
 mode change 100755 => 100644 Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/IAthenaPoolCleanUp.h
 mode change 100755 => 100644 Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/IAthenaPoolCleanUpSvc.h
 mode change 100755 => 100644 Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/IAthenaPoolCnvSvc.h
 mode change 100755 => 100644 Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/ITPConverter.h
 create mode 100644 Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/TPCnvElt.h
 create mode 100644 Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/TPCnvElt.icc
 create mode 100644 Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/TPCnvList.h
 create mode 100644 Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/TPCnvList.icc
 create mode 100644 Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolAuxContainerCnv.h
 create mode 100644 Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolAuxContainerCnv.icc
 mode change 100755 => 100644 Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolCnv.h
 create mode 100644 Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolCnvBase.h
 rename Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/{T_AthenaPoolCnv.icc => T_AthenaPoolCnvBase.icc} (53%)
 mode change 100755 => 100644
 mode change 100755 => 100644 Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolCoolMultChanCnv.h
 mode change 100755 => 100644 Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolCoolMultChanCnv.icc
 mode change 100755 => 100644 Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolCustCnv.h
 mode change 100755 => 100644 Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolCustCnv.icc
 mode change 100755 => 100644 Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolCustomCnv.h
 mode change 100755 => 100644 Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolCustomCnv.icc
 mode change 100755 => 100644 Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolExtendingCnv.h
 mode change 100755 => 100644 Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolExtendingCnv.icc
 create mode 100644 Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolTPCnvCnv.h
 create mode 100644 Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolTPCnvCnv.icc
 mode change 100755 => 100644 Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolTPConverter.h
 create mode 100644 Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolViewVectorCnv.h
 create mode 100644 Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolViewVectorCnv.icc
 create mode 100644 Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolxAODCnv.h
 create mode 100644 Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolxAODCnv.icc
 create mode 100644 Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/exceptions.h
 create mode 100644 Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/selection_test.xml
 create mode 100644 Database/AthenaPOOL/AthenaPoolCnvSvc/CMakeLists.txt
 mode change 100755 => 100644 Database/AthenaPOOL/AthenaPoolCnvSvc/cmt/requirements
 mode change 100755 => 100644 Database/AthenaPOOL/AthenaPoolCnvSvc/doc/MainPage.h
 mode change 100755 => 100644 Database/AthenaPOOL/AthenaPoolCnvSvc/python/AthenaPool.py
 mode change 100755 => 100644 Database/AthenaPOOL/AthenaPoolCnvSvc/python/ReadAthenaPool.py
 mode change 100755 => 100644 Database/AthenaPOOL/AthenaPoolCnvSvc/python/WriteAthenaPool.py
 mode change 100755 => 100644 Database/AthenaPOOL/AthenaPoolCnvSvc/python/__init__.py
 mode change 100755 => 100644 Database/AthenaPOOL/AthenaPoolCnvSvc/share/AthenaPoolCnvSvc_jobOptions.py
 mode change 100755 => 100644 Database/AthenaPOOL/AthenaPoolCnvSvc/share/AthenaPool_jobOptions.py
 mode change 100755 => 100644 Database/AthenaPOOL/AthenaPoolCnvSvc/share/ReadAthenaPool_jobOptions.py
 create mode 100644 Database/AthenaPOOL/AthenaPoolCnvSvc/share/TPCnvElt_test.ref
 create mode 100644 Database/AthenaPOOL/AthenaPoolCnvSvc/share/TPCnvList_test.ref
 create mode 100644 Database/AthenaPOOL/AthenaPoolCnvSvc/share/T_AthenaPoolAuxContainerCnv_test.ref
 create mode 100644 Database/AthenaPOOL/AthenaPoolCnvSvc/share/T_AthenaPoolTPCnvCnv_test.ref
 create mode 100644 Database/AthenaPOOL/AthenaPoolCnvSvc/share/T_AthenaPoolViewVectorCnv_test.ref
 create mode 100644 Database/AthenaPOOL/AthenaPoolCnvSvc/share/T_AthenaPoolxAODCnv_test.ref
 mode change 100755 => 100644 Database/AthenaPOOL/AthenaPoolCnvSvc/share/WriteAthenaPool_jobOptions.py
 create mode 100644 Database/AthenaPOOL/AthenaPoolCnvSvc/share/exceptions_test.ref
 create mode 100644 Database/AthenaPOOL/AthenaPoolCnvSvc/share/test.txt
 mode change 100755 => 100644 Database/AthenaPOOL/AthenaPoolCnvSvc/src/AthenaAttributeListCnv.cxx
 mode change 100755 => 100644 Database/AthenaPOOL/AthenaPoolCnvSvc/src/AthenaAttributeListCnv.h
 mode change 100755 => 100644 Database/AthenaPOOL/AthenaPoolCnvSvc/src/AthenaPoolCnvSvc.cxx
 mode change 100755 => 100644 Database/AthenaPOOL/AthenaPoolCnvSvc/src/AthenaPoolCnvSvc.h
 mode change 100755 => 100644 Database/AthenaPOOL/AthenaPoolCnvSvc/src/AthenaPoolConverter.cxx
 mode change 100755 => 100644 Database/AthenaPOOL/AthenaPoolCnvSvc/src/AthenaPoolTopLevelTPCnvBase.cxx
 create mode 100644 Database/AthenaPOOL/AthenaPoolCnvSvc/src/AthenaRootSerializeSvc.cxx
 create mode 100644 Database/AthenaPOOL/AthenaPoolCnvSvc/src/AthenaRootSerializeSvc.h
 mode change 100755 => 100644 Database/AthenaPOOL/AthenaPoolCnvSvc/src/CondAttrListCollCnv.cxx
 mode change 100755 => 100644 Database/AthenaPOOL/AthenaPoolCnvSvc/src/CondAttrListCollCnv.h
 mode change 100755 => 100644 Database/AthenaPOOL/AthenaPoolCnvSvc/src/CondAttrListVecCnv.cxx
 mode change 100755 => 100644 Database/AthenaPOOL/AthenaPoolCnvSvc/src/CondAttrListVecCnv.h
 create mode 100644 Database/AthenaPOOL/AthenaPoolCnvSvc/src/TPCnvElt.cxx
 mode change 100755 => 100644 Database/AthenaPOOL/AthenaPoolCnvSvc/src/components/AthenaPoolCnvSvc_entries.cxx
 mode change 100755 => 100644 Database/AthenaPOOL/AthenaPoolCnvSvc/src/components/AthenaPoolCnvSvc_load.cxx
 create mode 100644 Database/AthenaPOOL/AthenaPoolCnvSvc/src/exceptions.cxx
 create mode 100644 Database/AthenaPOOL/AthenaPoolCnvSvc/test/AthenaPoolCnvSvc.xml
 create mode 100644 Database/AthenaPOOL/AthenaPoolCnvSvc/test/AthenaPoolCnvSvcTestDict.h
 create mode 100644 Database/AthenaPOOL/AthenaPoolCnvSvc/test/TPCnvElt_test.cxx
 create mode 100644 Database/AthenaPOOL/AthenaPoolCnvSvc/test/TPCnvList_test.cxx
 create mode 100644 Database/AthenaPOOL/AthenaPoolCnvSvc/test/T_AthenaPoolAuxContainerCnv_test.cxx
 create mode 100644 Database/AthenaPOOL/AthenaPoolCnvSvc/test/T_AthenaPoolTPCnvCnv_test.cxx
 create mode 100644 Database/AthenaPOOL/AthenaPoolCnvSvc/test/T_AthenaPoolViewVectorCnv_test.cxx
 create mode 100644 Database/AthenaPOOL/AthenaPoolCnvSvc/test/T_AthenaPoolxAODCnv_test.cxx
 create mode 100644 Database/AthenaPOOL/AthenaPoolCnvSvc/test/TestCnvSvcBase.icc
 create mode 100644 Database/AthenaPOOL/AthenaPoolCnvSvc/test/TestThinningSvc.icc
 create mode 100644 Database/AthenaPOOL/AthenaPoolCnvSvc/test/exceptions_test.cxx

diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/AthenaPoolCnvTPExtension.h b/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/AthenaPoolCnvTPExtension.h
old mode 100755
new mode 100644
diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/AthenaPoolConverter.h b/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/AthenaPoolConverter.h
old mode 100755
new mode 100644
index dc964f0f52e..07c813b577f
--- a/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/AthenaPoolConverter.h
+++ b/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/AthenaPoolConverter.h
@@ -20,14 +20,12 @@
 #include <string>
 #include <map>
 
-namespace pool {
-   class Placement;
-}
 class IOpaqueAddress;
 class DataObject;
 class StatusCode;
 class IAthenaPoolCnvSvc;
 class Guid;
+class Placement;
 class Token;
 
 /// Abstract factory to create the converter
@@ -80,7 +78,8 @@ protected:
    /// Read an object from POOL.
    /// @param pObj [OUT] pointer to the transient object.
    /// @param token [IN] POOL token of the persistent representation.
-   virtual StatusCode PoolToDataObject(DataObject*& pObj, const std::string& token) = 0;
+   //virtual StatusCode PoolToDataObject(DataObject*& pObj, const std::string& token) = 0;
+   virtual StatusCode PoolToDataObject(DataObject*& pObj, const Token* token) = 0;
 
    /// Set POOL placement hint for a given type.
    /// @param tname [IN] type name.
@@ -90,32 +89,27 @@ protected:
    virtual void setPlacement(const std::string& key = "") = 0;
 
    /// @return data object from the converter.
-   virtual DataObject* getDataObject() const;
-   /// Set data object of the converter.
-   /// @param pObj [IN] data object pointer to be used by converter.
-   virtual void setDataObject(DataObject* pObj);
+   virtual const DataObject* getDataObject() const;
 
    bool compareClassGuid(const Guid &guid) const;
 
 protected: // data
    ServiceHandle<IAthenaPoolCnvSvc> m_athenaPoolCnvSvc;
-   pool::Placement*            m_placement;
-   RootType                    m_classDesc;
-   bool                        m_dictionaryOkRead;
-   bool                        m_dictionaryOkWrite;
+   Placement*            m_placement;
+   RootType              m_classDesc;
 
    typedef std::map<std::string, std::string>         StringMap;
    typedef StringMap::const_iterator                  StringMapIt;
-   StringMap                   m_placementHints;
+   StringMap             m_placementHints;
 
    typedef std::map<std::string, RootType>            ClassMap;
    typedef ClassMap::const_iterator                   ClassMapIt;
-   std::string                 m_className;
-   ClassMap                    m_classDescs;
+   std::string           m_className;
+   ClassMap              m_classDescs;
 
-   mutable std::string         m_token;
-   DataObject*                 m_dataObject;
-   mutable const Token*        m_poolToken;
+   DataObject*           m_dataObject;
+   const Token*          m_i_poolToken;
+   const Token*          m_o_poolToken;
 };
 
 #endif
diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/AthenaPoolTopLevelTPCnvBase.h b/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/AthenaPoolTopLevelTPCnvBase.h
old mode 100755
new mode 100644
diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/AthenaPoolTopLevelTPConverter.h b/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/AthenaPoolTopLevelTPConverter.h
old mode 100755
new mode 100644
diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/IAthenaPoolCleanUp.h b/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/IAthenaPoolCleanUp.h
old mode 100755
new mode 100644
diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/IAthenaPoolCleanUpSvc.h b/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/IAthenaPoolCleanUpSvc.h
old mode 100755
new mode 100644
diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/IAthenaPoolCnvSvc.h b/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/IAthenaPoolCnvSvc.h
old mode 100755
new mode 100644
index 1cb0174297b..849819fc75e
--- a/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/IAthenaPoolCnvSvc.h
+++ b/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/IAthenaPoolCnvSvc.h
@@ -12,6 +12,7 @@
 
 #include "AthenaPoolCnvSvc/IAthenaPoolCleanUpSvc.h"
 #include "GaudiKernel/IConversionSvc.h"
+#include "AthenaKernel/IDataShare.h"
 #include "DataModelRoot/RootType.h"
 
 #include <string>
@@ -19,11 +20,10 @@
 // Forward declarations
 class IOpaqueAddress;
 class IPoolSvc;
+class Placement;
 class Token;
 
-
 namespace pool {
-   class Placement;
    class DbType;
 }
 
@@ -33,7 +33,7 @@ static const InterfaceID IID_IAthenaPoolCnvSvc ("IAthenaPoolCnvSvc", 1 , 0);
 /** @class IAthenaPoolCnvSvc
  *  @brief This class provides the interface between Athena and PoolSvc.
  **/
-class IAthenaPoolCnvSvc : virtual public IConversionSvc, public IAthenaPoolCleanUpSvc {
+class IAthenaPoolCnvSvc : virtual public IConversionSvc, public IDataShare, public IAthenaPoolCleanUpSvc {
 public:
    /// Retrieve interface ID
    static const InterfaceID& interfaceID() { return(IID_IAthenaPoolCnvSvc); }
@@ -60,7 +60,7 @@ public:
    /// @param placement [IN] pointer to the placement hint
    /// @param obj [IN] pointer to the Data Object to be written to Pool
    /// @param classDesc [IN] pointer to the Seal class description for the Data Object.
-   virtual const Token* registerForWrite(const pool::Placement* placement,
+   virtual const Token* registerForWrite(const Placement* placement,
 	   const void* obj,
 	   const RootType& classDesc) const = 0;
 
@@ -68,10 +68,6 @@ public:
    /// @param token [IN] string token of the Data Object for which a Pool Ref is filled.
    virtual void setObjPtr(void*& obj, const Token* token) const = 0;
 
-   /// Utility to test whether the dictionary knows about a given class.
-   /// @param className [IN] string containing the name of the class to be checked.
-   virtual bool testDictionary(const std::string& className) const = 0;
-
    /// @return a boolean for using detailed time and size statistics.
    virtual bool useDetailChronoStat() const = 0;
 
@@ -102,6 +98,12 @@ public:
    /// @param refAddress [OUT] converted string form.
    virtual StatusCode convertAddress(const IOpaqueAddress* pAddress, std::string& refAddress) = 0;
 
+   /// Make this a server.
+   virtual StatusCode makeServer(int num) = 0;
+
+   /// Make this a client.
+   virtual StatusCode makeClient(int num) = 0;
+
    /// Implement registerCleanUp to register a IAthenaPoolCleanUp to be called during cleanUp.
    virtual StatusCode registerCleanUp(IAthenaPoolCleanUp* cnv) = 0;
 
diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/ITPConverter.h b/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/ITPConverter.h
old mode 100755
new mode 100644
diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/TPCnvElt.h b/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/TPCnvElt.h
new file mode 100644
index 00000000000..7b82a2483cb
--- /dev/null
+++ b/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/TPCnvElt.h
@@ -0,0 +1,167 @@
+// This file's extension implies that it's C, but it's really -*- C++ -*-.
+
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// $Id$
+/**
+ * @file AthenaPoolCnvSvc/TPCnvElt.h
+ * @author scott snyder <snyder@bnl.gov>
+ * @date Jan, 2016
+ * @brief Helper for calling a TP converter from an Athena converter.
+ */
+
+
+#ifndef ATHENAPOOLCNVSVC_TPCNVELT_H
+#define ATHENAPOOLCNVSVC_TPCNVELT_H
+
+
+#include "PersistentDataModel/Guid.h"
+#include <typeinfo>
+#include <memory>
+class MsgStream;
+
+
+/**
+ * @brief Placeholder for the case where no conversion is to be done.
+ */
+template <class TRANS> class T_TPCnvNull
+{
+};
+
+
+namespace AthenaPoolCnvSvc {
+
+
+/**
+ * @brief Given a @c type_info, get the corresponding pool guid.
+ * @param ti @c type_info to look for.
+ *
+ * Throws an exception on errors.
+ */
+Guid guidFromTypeinfo (const std::type_info& ti);
+
+
+/**
+ * @brief Helper for calling a TP converter from an Athena converter.
+ *
+ * This is used to allow calling one out of a templated list of TP converters.
+ * The methods here test if the current guid matches the guid for this
+ * converter, and calls it if so.
+ *
+ * CNV is the top-level pool converter (that reads the persistent object).
+ * TPCNV is the TP converter class to be called.  For the case where no
+ * conversion is to be done, use T_TPCnvNull<TRANS> for the TP converter
+ * class.
+ */
+template <class CNV, class TPCNV>
+class TPCnvElt
+{
+public:
+  /// Make available the persistent and transient types.
+  typedef typename TPCNV::Trans_t Trans_t;
+  typedef typename TPCNV::Pers_t  Pers_t;
+
+  
+  /**
+   * @brief Constructor.
+   */
+  TPCnvElt();
+
+
+  /**
+   * @brief Read the persistent object and convert it to transient.
+   * @param parent The top-level pool converter object.
+   * @param msg MsgStream for error reporting.
+   *
+   * Returns a newly-allocated object.
+   * If the type of the persistent object on the file does not match the
+   * type that this converter handles, return nullptr.
+   * Other errors are reported by raising exceptions.
+   */
+  Trans_t* createTransient (CNV& parent, MsgStream& msg);
+
+
+  /**
+   * @brief Read the persistent object and convert it to transient.
+   * @param parent The top-level pool converter object.
+   * @param trans The transient object to modify.
+   * @param msg MsgStream for error reporting.
+   *
+   * Overwrites the provided transient object.
+   * If the type of the persistent object on the file does not match the
+   * type that this converter handles, returns false.
+   * Other errors are reported by raising exceptions.
+   */
+  bool persToTrans (CNV& parent, Trans_t* trans, MsgStream& msg);
+
+  
+private:
+  /// GUID for the persistent class we read.
+  Guid m_guid;
+
+  /// The underlying TP converter.
+  TPCNV m_cnv;
+};
+
+
+/**
+ * @brief Helper for calling a TP converter from an Athena converter.
+ *        Specialization for the case of no conversion.
+ */
+template <class CNV, class TRANS>
+class TPCnvElt<CNV, T_TPCnvNull<TRANS> >
+{
+public:
+  /// Make available the persistent and transient types.
+  typedef TRANS Trans_t;
+  typedef TRANS  Pers_t;
+
+  
+  /**
+   * @brief Constructor.
+   */
+  TPCnvElt();
+
+
+  /**
+   * @brief Read the persistent object and convert it to transient.
+   * @param parent The top-level pool converter object.
+   * @param msg MsgStream for error reporting.
+   *
+   * Returns a newly-allocated object.
+   * If the type of the persistent object on the file does not match the
+   * type that this converter handles, return nullptr.
+   * Other errors are reported by raising exceptions.
+   */
+  Trans_t* createTransient (CNV& parent, MsgStream& msg);
+
+
+  /**
+   * @brief Read the persistent object and convert it to transient.
+   * @param parent The top-level pool converter object.
+   * @param trans The transient object to modify.
+   * @param msg MsgStream for error reporting.
+   *
+   * Overwrites the provided transient object.
+   * If the type of the persistent object on the file does not match the
+   * type that this converter handles, returns false.
+   * Other errors are reported by raising exceptions.
+   */
+  bool persToTrans (CNV& parent, Trans_t* trans, MsgStream& msg);
+
+  
+private:
+  /// GUID for the persistent class we read.
+  Guid m_guid;
+};
+
+
+} // namespace AthenaPoolCnvSvc
+
+
+#include "AthenaPoolCnvSvc/TPCnvElt.icc"
+
+
+#endif // not ATHENAPOOLCNVSVC_TPCNVELT_H
diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/TPCnvElt.icc b/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/TPCnvElt.icc
new file mode 100644
index 00000000000..46ec8f189b2
--- /dev/null
+++ b/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/TPCnvElt.icc
@@ -0,0 +1,142 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// $Id$
+/**
+ * @file AthenaPoolCnvSvc/TPCnvElt.icc
+ * @author scott snyder <snyder@bnl.gov>
+ * @date Jan, 2016
+ * @brief Helper for calling a TP converter from an Athena converter.
+ */
+
+
+namespace AthenaPoolCnvSvc {
+
+
+/**
+ * @brief Constructor.
+ */
+template <class CNV, class TPCNV>
+TPCnvElt<CNV, TPCNV>::TPCnvElt()
+  // Remember the guid for our persistent type.
+  : m_guid (guidFromTypeinfo (typeid (Pers_t)))
+{
+}
+
+
+/**
+ * @brief Read the persistent object and convert it to transient.
+ * @param parent The top-level pool converter object.
+ * @param msg MsgStream for error reporting.
+ *
+ * Returns a newly-allocated object.
+ * If the type of the persistent object on the file does not match the
+ * type that this converter handles, return nullptr.
+ * Other errors are reported by raising exceptions.
+ */
+template <class CNV, class TPCNV>
+typename TPCnvElt<CNV, TPCNV>::Trans_t*
+TPCnvElt<CNV, TPCNV>::createTransient (CNV& parent, MsgStream& msg)
+{
+  if (!parent.compareClassGuid (m_guid))
+    return nullptr;
+
+  std::unique_ptr<Pers_t> old (parent.template poolReadObject<Pers_t>() );
+  return m_cnv.createTransient(old.get(), msg);
+}
+
+
+/**
+ * @brief Read the persistent object and convert it to transient.
+ * @param parent The top-level pool converter object.
+ * @param trans The transient object to modify.
+ * @param msg MsgStream for error reporting.
+ *
+ * Overwrites the provided transient object.
+ * If the type of the persistent object on the file does not match the
+ * type that this converter handles, returns false.
+ * Other errors are reported by raising exceptions.
+ */
+template <class CNV, class TPCNV>
+bool
+TPCnvElt<CNV, TPCNV>::persToTrans (CNV& parent, Trans_t* trans, MsgStream& msg)
+{
+  if (!parent.compareClassGuid (m_guid))
+    return false;
+
+  std::unique_ptr<Pers_t> old ( parent.template poolReadObject<Pers_t>() );
+  m_cnv.persToTrans (old.get(), trans, msg);
+  return true;
+}
+
+
+//*************************************************************************
+
+
+/**
+ * @brief Constructor.
+ *
+ * Specialization for the case of no conversion.
+ */
+template <class CNV, class TRANS>
+TPCnvElt<CNV, T_TPCnvNull<TRANS> >::TPCnvElt()
+  // Remember the guid for our persistent type.
+  : m_guid (guidFromTypeinfo (typeid (Pers_t)))
+{
+}
+
+
+/**
+ * @brief Read the persistent object and convert it to transient.
+ * @param parent The top-level pool converter object.
+ * @param msg MsgStream for error reporting.
+ *
+ * Specialization for the case of no conversion.
+ *
+ * Returns a newly-allocated object.
+ * If the type of the persistent object on the file does not match the
+ * type that this converter handles, return nullptr.
+ * Other errors are reported by raising exceptions.
+ */
+template <class CNV, class TRANS>
+typename TPCnvElt<CNV, T_TPCnvNull<TRANS> >::Trans_t*
+TPCnvElt<CNV, T_TPCnvNull<TRANS> >::createTransient (CNV& parent,
+                                                     MsgStream& /*msg*/)
+{
+  if (!parent.compareClassGuid (m_guid))
+    return nullptr;
+
+  return parent.template poolReadObject<Pers_t>();
+}
+
+
+/**
+ * @brief Read the persistent object and convert it to transient.
+ * @param parent The top-level pool converter object.
+ * @param trans The transient object to modify.
+ * @param msg MsgStream for error reporting.
+ *
+ * Specialization for the case of no conversion.
+ *
+ * Overwrites the provided transient object.
+ * If the type of the persistent object on the file does not match the
+ * type that this converter handles, returns false.
+ * Other errors are reported by raising exceptions.
+ */
+template <class CNV, class TRANS>
+bool
+TPCnvElt<CNV, T_TPCnvNull<TRANS> >::persToTrans (CNV& parent,
+                                                 Trans_t* trans,
+                                                 MsgStream& /*msg*/)
+{
+  if (!parent.compareClassGuid (m_guid))
+    return false;
+
+  std::unique_ptr<Pers_t> old ( parent.template poolReadObject<Pers_t>() );
+  *trans = *old;
+  return true;
+}
+
+
+} // namespace AthenaPoolCnvSvc
diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/TPCnvList.h b/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/TPCnvList.h
new file mode 100644
index 00000000000..92b0f0fa7b6
--- /dev/null
+++ b/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/TPCnvList.h
@@ -0,0 +1,127 @@
+// This file's extension implies that it's C, but it's really -*- C++ -*-.
+
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// $Id$
+/**
+ * @file AthenaPoolCnvSvc/TPCnvList.h
+ * @author scott snyder <snyder@bnl.gov>
+ * @date Jan, 2016
+ * @brief Helper for calling TP converters from an Athena converter.
+ */
+
+
+#ifndef ATHENAPOOLCNVSVC_TPCNVLIST_H
+#define ATHENAPOOLCNVSVC_TPCNVLIST_H
+
+
+#include "AthenaPoolCnvSvc/TPCnvElt.h"
+#include "boost/mpl/vector.hpp"
+#include "boost/mpl/transform.hpp"
+#include <boost/fusion/mpl.hpp>
+#include "boost/fusion/container/vector.hpp"
+#include "boost/fusion/container/vector/convert.hpp"
+#include "boost/fusion/algorithm/iteration/accumulate.hpp"
+
+
+namespace AthenaPoolCnvSvc {
+
+
+/**
+ * @brief Helper for calling TP converters from an Athena converter.
+ */
+template <class CNV, class TRANS, class ... TPCNVS>
+class TPCnvList
+{
+  /// Metafunction to wrap a TP converter in @c TPCnvElt.
+  template <class TPCNV>
+  struct wrap_tpcnv
+  {
+    typedef TPCnvElt<CNV, TPCNV> type;
+  };
+
+
+  /// Functional to iterate over TP converters and call @c createTransient
+  /// on each.  Stop once one succeeds.
+  struct do_create_transient
+  {
+    do_create_transient (CNV& parent, MsgStream& msg);
+  
+    template <class ELT>
+    typename ELT::Trans_t* operator() (typename ELT::Trans_t* p, ELT& elt);
+
+    CNV& m_parent;
+    MsgStream& m_msg;
+  };
+
+
+  /// Functional to iterate over TP converters and call @c persToTrans
+  /// on each.  Stop once one succeeds.
+  struct do_pers_to_trans
+  {
+    do_pers_to_trans (CNV& parent, TRANS* trans, MsgStream& msg);
+    
+    template <class ELT>
+    bool operator() (bool found, ELT& elt);
+
+    CNV& m_parent;
+    TRANS* m_trans;
+    MsgStream& m_msg;
+  };
+
+
+public:
+  // Convert the list of TP converters <T1, T2, ...> to a boost fusion vector
+  // of converters wrapped by TPCnvElt:
+  //   boost::fusion::vector<TPCnvElt<T1>, TPCnvElt<T2>, ...>
+  // We can create in instance of this vector to get an object that holds
+  // all the TP converter instances.
+  typedef boost::mpl::vector<TPCNVS...> vec_t;
+  typedef typename boost::mpl::transform<vec_t, wrap_tpcnv<boost::mpl::_1> >::type list_mpl_t;
+  typedef typename boost::fusion::result_of::as_vector<list_mpl_t>::type list_t;
+
+
+  /**
+   * @brief Read the persistent object and convert it to transient.
+   * @param parent The top-level pool converter object.
+   * @param msg MsgStream for error reporting.
+   *
+   * Returns a newly-allocated object.
+   * If the type of the persistent object on the file does not match the
+   * the type of any of our TP converters, return nullptr.
+   * Other errors are reported by raising exceptions.
+   */
+  TRANS* createTransient (CNV& parent, MsgStream& msg);
+
+  
+  /**
+   * @brief Read the persistent object and convert it to transient.
+   * @param parent The top-level pool converter object.
+   * @param trans The transient object to modify.
+   * @param msg MsgStream for error reporting.
+   *
+   * Overwrites the provided transient object.
+   * If the type of the persistent object on the file does not match the
+   * the type of any of our TP converters, return false.
+   * Other errors are reported by raising exceptions.
+   */
+  bool persToTrans (CNV& parent, TRANS* trans, MsgStream& msg);
+  
+
+private:
+  /// List of TP converter instances, wrapped by @c TPCnvElt.
+  list_t m_list;
+};
+
+
+} // namespace AthenaPoolCnvSvc
+
+
+#include "AthenaPoolCnvSvc/TPCnvList.icc"
+
+
+#endif // not ATHENAPOOLCNVSVC_TPCNVLIST_H
+
+
diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/TPCnvList.icc b/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/TPCnvList.icc
new file mode 100644
index 00000000000..129f8d67a52
--- /dev/null
+++ b/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/TPCnvList.icc
@@ -0,0 +1,136 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// $Id$
+/**
+ * @file AthenaPoolCnvSvc/TPCnvList.h
+ * @author scott snyder <snyder@bnl.gov>
+ * @date Jan, 2016
+ * @brief Helper for calling TP converters from an Athena converter.
+ */
+
+
+namespace AthenaPoolCnvSvc {
+
+
+/**
+ * @brief Constructor.
+ * @param parent The parent Athena pool converter.
+ * @param msg MsgStream for error reporting.
+ */
+template <class CNV, class TRANS, class ... TPCNVS>
+inline
+TPCnvList<CNV, TRANS, TPCNVS...>::do_create_transient::do_create_transient (CNV& parent, MsgStream& msg)
+  : m_parent (parent),
+    m_msg (msg)
+{
+}
+
+
+/**
+ * @brief Worker for loop over TP converters calling @c createTransient.
+ * @param p Result of the iteration (pointer to transient object).
+ * @param elt The TPCnvElt instance to call.
+ *
+ * This function gets called once for each TP converter instance.
+ * It gets as arguments the wrapped TP converter and the result @c p
+ * from the previous TP converter call.  If a previous TP converter
+ * has succeeded, then @c p will be non-null, so we just return it
+ * without calling anything.  Otherwise, we call the TP converter
+ * and return the result.
+ */
+template <class CNV, class TRANS, class ... TPCNVS>
+template <class ELT>
+inline
+typename ELT::Trans_t*
+TPCnvList<CNV, TRANS, TPCNVS...>::do_create_transient::operator()
+  (typename ELT::Trans_t* p, ELT& elt)
+{
+  if (p) return p;
+  return elt.createTransient (m_parent, m_msg);
+}
+
+
+/**
+ * @brief Constructor.
+ * @param parent The parent Athena pool converter.
+ * @param msg MsgStream for error reporting.
+ */
+template <class CNV, class TRANS, class ... TPCNVS>
+inline
+TPCnvList<CNV, TRANS, TPCNVS...>::do_pers_to_trans::do_pers_to_trans
+ (CNV& parent, TRANS* trans, MsgStream& msg)
+  : m_parent (parent),
+    m_trans (trans),
+    m_msg (msg)
+{
+}
+
+
+/**
+ * @brief Worker for loop over TP converters calling @c persToTrans.
+ * @param found Result of the iteration (has a converter succeeded?).
+ * @param elt The TPCnvElt instance to call.
+ *
+ * This function gets called once for each TP converter instance.
+ * It gets as arguments the wrapped TP converter and a flag @c found
+ * telling whether any TP converer has succeeded so far.  If one has,
+ * then we just return the flag again without calling anything.
+ * Otherwise, we call the TP converter and return the result.
+ */
+template <class CNV, class TRANS, class ... TPCNVS>
+template <class ELT>
+inline
+bool TPCnvList<CNV, TRANS, TPCNVS...>::do_pers_to_trans::operator()
+  (bool found, ELT& elt)
+{
+  if (found) return true;
+  return elt.persToTrans (m_parent, m_trans, m_msg);
+}
+
+
+/**
+ * @brief Read the persistent object and convert it to transient.
+ * @param parent The top-level pool converter object.
+ * @param msg MsgStream for error reporting.
+ *
+ * Returns a newly-allocated object.
+ * If the type of the persistent object on the file does not match the
+ * the type of any of our TP converters, return nullptr.
+ * Other errors are reported by raising exceptions.
+ */
+template <class CNV, class TRANS, class ... TPCNVS>
+TRANS* TPCnvList<CNV, TRANS, TPCNVS...>::createTransient (CNV& parent,
+                                                          MsgStream& msg)
+{
+  // Try createTransient on each TPCnv; stop when one succeeds.
+  TRANS* p = nullptr;
+  return boost::fusion::accumulate
+    (m_list, p, do_create_transient(parent, msg));
+}
+
+
+/**
+ * @brief Read the persistent object and convert it to transient.
+ * @param parent The top-level pool converter object.
+ * @param trans The transient object to modify.
+ * @param msg MsgStream for error reporting.
+ *
+ * Overwrites the provided transient object.
+ * If the type of the persistent object on the file does not match the
+ * the type of any of our TP converters, return false.
+ * Other errors are reported by raising exceptions.
+ */
+template <class CNV, class TRANS, class ... TPCNVS>
+bool TPCnvList<CNV, TRANS, TPCNVS...>::persToTrans (CNV& parent,
+                                                    TRANS* trans,
+                                                    MsgStream& msg)
+{
+  // Try persToTrans on each TPCnv; stop when one succeeds.
+  return boost::fusion::accumulate
+    (m_list, false, do_pers_to_trans(parent, trans, msg));
+}
+
+
+} // namespace AthenaPoolCnvSvc
diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolAuxContainerCnv.h b/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolAuxContainerCnv.h
new file mode 100644
index 00000000000..cb34231053c
--- /dev/null
+++ b/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolAuxContainerCnv.h
@@ -0,0 +1,88 @@
+// This file's extension implies that it's C, but it's really -*- C++ -*-.
+
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// $Id$
+/**
+ * @file AthenaPoolCnvSvc/T_AthenaPoolAuxContainerCnv.h
+ * @author scott snyder <snyder@bnl.gov>
+ * @date Jan, 2016
+ * @brief Athena pool converter for aux store classes.
+ */
+
+
+#ifndef ATHENAPOOLCNVSVC_T_ATHENAPOOLAUXCONTAINERCNV_H
+#define ATHENAPOOLCNVSVC_T_ATHENAPOOLAUXCONTAINERCNV_H
+
+
+#include "AthenaPoolCnvSvc/T_AthenaPoolCustomCnv.h"
+#include "AthenaPoolCnvSvc/TPCnvList.h"
+#include "AthenaPoolCnvSvc/exceptions.h"
+#include "AthContainers/tools/copyThinned.h"
+#include "AthenaKernel/IThinningSvc.h"
+
+
+/**
+ * @brief Athena pool converter for aux store classes.
+ *
+ * AUXSTORE is the class being read/written.
+ * TPCNVS is a list of TP converters to handle older versions of the class.
+ *
+ * On writing, the container is copied (and thinned if required).
+ * For reading, we read the object either directly
+ * or using one of the TP converters, depending on the saved GUID.
+ */
+template <class AUXSTORE, class ... TPCNVS>
+class T_AthenaPoolAuxContainerCnv
+  : public T_AthenaPoolCustomCnv<AUXSTORE, AUXSTORE>
+{
+  friend class CnvFactory< T_AthenaPoolAuxContainerCnv >;
+
+  template <class CNV, class TPCNV>
+  friend class AthenaPoolCnvSvc::TPCnvElt;
+
+public:
+  typedef T_AthenaPoolCustomCnv<AUXSTORE, AUXSTORE> Base;
+
+
+  /**
+   * @brief Constructor.
+   * @param svcLoc Gaudi service locator.
+   */
+  T_AthenaPoolAuxContainerCnv ( ISvcLocator* svcLoc );
+
+
+  /**
+   * @brief Convert a transient object to persistent form.
+   * @param trans The transient object to convert.
+   *
+   * Returns a newly-allocated persistent object.
+   */
+  virtual AUXSTORE* createPersistent( AUXSTORE* trans ) override;
+
+
+  /**
+   * @brief Read the persistent object and convert it to transient.
+   *
+   * Returns a newly-allocated transient object.
+   * Errors are reported by raising exceptions.
+   */
+  virtual AUXSTORE* createTransient() override;
+
+  
+private:
+  /// GUID of the object being read.
+  Guid m_guid;
+
+  /// List of TP converters.
+  AthenaPoolCnvSvc::TPCnvList<T_AthenaPoolAuxContainerCnv, AUXSTORE, TPCNVS...> m_tpcnvs;
+};
+
+
+#include "AthenaPoolCnvSvc/T_AthenaPoolAuxContainerCnv.icc"
+
+
+#endif // not ATHENAPOOLCNVSVC_T_ATHENAPOOLAUXCONTAINERCNV_H
+
diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolAuxContainerCnv.icc b/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolAuxContainerCnv.icc
new file mode 100644
index 00000000000..2c4993d7929
--- /dev/null
+++ b/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolAuxContainerCnv.icc
@@ -0,0 +1,64 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// $Id$
+/**
+ * @file AthenaPoolCnvSvc/T_AthenaPoolAuxContainerCnv.icc
+ * @author scott snyder <snyder@bnl.gov>
+ * @date Jan, 2016
+ * @brief Athena pool converter for aux store classes.
+ */
+
+
+/**
+ * @brief Constructor.
+ * @param svcLoc Gaudi service locator.
+ */
+template <class AUXSTORE, class ... TPCNVS>
+T_AthenaPoolAuxContainerCnv<AUXSTORE, TPCNVS...>::T_AthenaPoolAuxContainerCnv( ISvcLocator* svcLoc )
+  : Base( svcLoc )
+{
+  m_guid = AthenaPoolCnvSvc::guidFromTypeinfo (typeid (AUXSTORE));
+}
+
+
+/**
+ * @brief Convert a transient object to persistent form.
+ * @param trans The transient object to convert.
+ *
+ * Returns a newly-allocated persistent object.
+ */
+template <class AUXSTORE, class ... TPCNVS>
+AUXSTORE* T_AthenaPoolAuxContainerCnv<AUXSTORE, TPCNVS...>::createPersistent( AUXSTORE* trans )
+{
+  return SG::copyThinned (*trans, IThinningSvc::instance());
+}
+
+
+/**
+ * @brief Read the persistent object and convert it to transient.
+ *
+ * Returns a newly-allocated transient object.
+ * Errors are reported by raising exceptions.
+ */
+template <class AUXSTORE, class ... TPCNVS>
+AUXSTORE* T_AthenaPoolAuxContainerCnv<AUXSTORE, TPCNVS...>::createTransient()
+{
+  if ( this->compareClassGuid( m_guid ) ) {
+    // It's the latest version, read it directly:
+    return this->template poolReadObject< AUXSTORE >();
+  }
+
+  // Try a converter.
+  AUXSTORE* c = m_tpcnvs.createTransient (*this, this->msg());
+  if (c)
+    return c;
+
+  // Didn't recognize the GUID.
+  AthenaPoolCnvSvc::throwExcUnsupportedVersion (typeid(AUXSTORE),
+                                                this->m_i_poolToken->classID());
+  return 0;
+}
+
+
diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolCnv.h b/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolCnv.h
old mode 100755
new mode 100644
index 4d0b0abba1c..ab49ff44310
--- a/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolCnv.h
+++ b/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolCnv.h
@@ -10,12 +10,9 @@
  *  @author Peter van Gemmeren <gemmeren@anl.gov>
  **/
 
-#include "AthenaPoolCnvSvc/AthenaPoolConverter.h"
-
-#include <string>
-
-class DataObject;
-class StatusCode;
+#include "AthenaPoolCnvSvc/T_AthenaPoolCnvBase.h"
+#include "AthenaPoolCnvSvc/T_AthenaPoolViewVectorCnv.h"
+#include "AthContainers/ViewVector.h"
 
 /// Abstract factory to create the converter
 template <class TYPE> class CnvFactory;
@@ -24,33 +21,22 @@ template <class TYPE> class CnvFactory;
  *  @brief This templated class provides the converter to translate an object to/from its persistent POOL representation.
  **/
 template <class T>
-class T_AthenaPoolCnv : public AthenaPoolConverter {
+class T_AthenaPoolCnv : public T_AthenaPoolCnvBase<T> {
    friend class CnvFactory<T_AthenaPoolCnv<T> >;
 
 protected:
-   /// Constructor
-   T_AthenaPoolCnv(ISvcLocator* svcloc);
-
-   /// Gaudi Service Interface method implementations:
-   virtual StatusCode initialize();
-
-   /// Write an object into POOL.
-   /// @param pObj [IN] pointer to the transient object.
-   /// @param key [IN] StoreGate key (string) - placement hint to generate POOL container name
-   virtual StatusCode DataObjectToPool(DataObject* pObj, const std::string& key);
+   using T_AthenaPoolCnvBase<T>::T_AthenaPoolCnvBase;
+};
 
-   /// Read an object from POOL.
-   /// @param pObj [OUT] pointer to the transient object.
-   /// @param token [IN] POOL token of the persistent representation.
-   virtual StatusCode PoolToDataObject(DataObject*& pObj, const std::string& token);
 
-   /// Set POOL placement.
-   virtual void setPlacement(const std::string& key = "");
+template <class DV>
+class T_AthenaPoolCnv<ViewVector<DV> > : public T_AthenaPoolViewVectorCnv<DV>
+{
+   friend class CnvFactory<T_AthenaPoolCnv<ViewVector<DV> > >;
 
-public:
-   /// @return class ID.
-   static const CLID& classID();
+protected:
+   using T_AthenaPoolViewVectorCnv<DV>::T_AthenaPoolViewVectorCnv;
 };
 
-#include "AthenaPoolCnvSvc/T_AthenaPoolCnv.icc"
+
 #endif
diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolCnvBase.h b/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolCnvBase.h
new file mode 100644
index 00000000000..9db01715f53
--- /dev/null
+++ b/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolCnvBase.h
@@ -0,0 +1,54 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef ATHENAPOOLCNVSVC_T_ATHENAPOOLCNVBASE_H
+#define ATHENAPOOLCNVSVC_T_ATHENAPOOLCNVBASE_H
+
+/** @file T_AthenaPoolCnvBase.h
+ *  @brief his file contains the class definition for the templated T_AthenaPoolCnvBase class.
+ *  @author Peter van Gemmeren <gemmeren@anl.gov>
+ **/
+
+#include "AthenaPoolCnvSvc/AthenaPoolConverter.h"
+
+#include <string>
+
+class DataObject;
+class StatusCode;
+
+/** @class T_AthenaPoolCnvBase
+ *  @brief This templated class provides the converter to translate an object to/from its persistent POOL representation.
+ **/
+template <class T>
+class T_AthenaPoolCnvBase : public AthenaPoolConverter {
+
+protected:
+   /// Constructor
+   T_AthenaPoolCnvBase(ISvcLocator* svcloc);
+
+   /// Gaudi Service Interface method implementations:
+   virtual StatusCode initialize();
+
+   /// Write an object into POOL.
+   /// @param pObj [IN] pointer to the transient object.
+   /// @param key [IN] StoreGate key (string) - placement hint to generate POOL container name
+   virtual StatusCode DataObjectToPool(DataObject* pObj, const std::string& key);
+
+   /// Read an object from POOL.
+   /// @param pObj [OUT] pointer to the transient object.
+   /// @param token [IN] POOL token of the persistent representation.
+   virtual StatusCode PoolToDataObject(DataObject*& pObj, const Token* token);
+
+   /// Set POOL placement.
+   virtual void setPlacement(const std::string& key = "");
+
+public:
+   /// @return class ID.
+   static const CLID& classID();
+};
+
+
+#include "AthenaPoolCnvSvc/T_AthenaPoolCnvBase.icc"
+
+#endif
diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolCnv.icc b/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolCnvBase.icc
old mode 100755
new mode 100644
similarity index 53%
rename from Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolCnv.icc
rename to Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolCnvBase.icc
index c720e02b244..4ab4fba104b
--- a/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolCnv.icc
+++ b/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolCnvBase.icc
@@ -2,8 +2,8 @@
   Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
 */
 
-/** @file T_AthenaPoolCnv.icc
- *  @brief This file contains the implementation for the templated T_AthenaPoolCnv class.
+/** @file T_AthenaPoolCnvBase.icc
+ *  @brief This file contains the implementation for the templated T_AthenaPoolCnvBase class.
  *  @author Peter van Gemmeren <gemmeren@anl.gov>
  **/
 
@@ -18,17 +18,17 @@
 #include "DataModelRoot/RootType.h"
 
 #include "CLIDSvc/CLASS_DEF.h"
-#include "DataModel/ClassName.h"
+#include "SGTools/ClassName.h"
 #include "SGTools/StorableConversions.h"
 
 //__________________________________________________________________________
 template <class T>
-T_AthenaPoolCnv<T>::T_AthenaPoolCnv(ISvcLocator* svcloc) : AthenaPoolConverter(classID(), svcloc) {
+T_AthenaPoolCnvBase<T>::T_AthenaPoolCnvBase(ISvcLocator* svcloc) : AthenaPoolConverter(classID(), svcloc) {
 }
 //______________________________________________________________________________
 template <class T>
-StatusCode T_AthenaPoolCnv<T>::initialize() {
-   ATH_MSG_DEBUG("initialize() in T_AthenaPoolCnv " << classID());
+StatusCode T_AthenaPoolCnvBase<T>::initialize() {
+   ATH_MSG_DEBUG("initialize() in T_AthenaPoolCnvBase " << classID());
    if (!AthenaPoolConverter::initialize().isSuccess()) {
       ATH_MSG_FATAL("Failed to initialize AthenaPoolConverter base class.");
       return(StatusCode::FAILURE);
@@ -37,73 +37,53 @@ StatusCode T_AthenaPoolCnv<T>::initialize() {
 }
 //__________________________________________________________________________
 template <class T>
-const CLID& T_AthenaPoolCnv<T>::classID() {
+const CLID& T_AthenaPoolCnvBase<T>::classID() {
    return(ClassID_traits<T>::ID());
 }
 //__________________________________________________________________________
 template <class T>
-StatusCode T_AthenaPoolCnv<T>::DataObjectToPool(DataObject* /*pObj*/, const std::string& key) {
+StatusCode T_AthenaPoolCnvBase<T>::DataObjectToPool(DataObject* pObj, const std::string& key) {
    const std::string className = ClassName<T>::name();
-   if (!m_dictionaryOkWrite) {
-      m_dictionaryOkWrite = m_athenaPoolCnvSvc->testDictionary(className);
-   }
-   if (!m_dictionaryOkWrite) {
-      ATH_MSG_ERROR("There is no correct dictionary for class (type/key) " << className << "/" << getDataObject()->name());
-      return(StatusCode::FAILURE);
-   }
    if (!m_classDesc) {
-      ATH_MSG_DEBUG("Retrieve class description for class (type/key) " << className << "/" << getDataObject()->name());
+      ATH_MSG_DEBUG("Retrieve class description for class (type/key) " << className << "/" << pObj->name());
       m_classDesc = RootType( typeid(T) );
    }
-   if (this->getDataObject()->clID() == 1 && this->getDataObject()->registry()->address() != 0) {
+   if (pObj->clID() == 1 && pObj->registry()->address() != 0) {
       ATH_MSG_DEBUG("Failed to cast DataObject to transient type, doing pers to pers");
-      if (this->m_poolToken == 0) this->m_poolToken = new Token;
-      const_cast<Token*>(m_poolToken)->fromString(this->getDataObject()->registry()->address()->par()[0]); //FIXME: get TokenAddress?
-      DataObject* pObj = 0;
-      if (!PoolToDataObject(pObj, "").isSuccess()) {
-         delete this->m_poolToken; this->m_poolToken = 0;
+      if (!PoolToDataObject(pObj, this->m_i_poolToken).isSuccess()) {
          ATH_MSG_ERROR("Failed to read persistent DataType");
          return(StatusCode::FAILURE);
       }
-      delete this->m_poolToken; this->m_poolToken = 0;
    }
    T* obj = 0;
-   bool success = SG::fromStorable(getDataObject(), obj);
+   bool success = SG::fromStorable(pObj, obj);
    if (!success || obj == 0) {
-      ATH_MSG_ERROR("failed to cast to T for class (type/key) " << className << "/" << getDataObject()->name());
+      ATH_MSG_ERROR("failed to cast to T for class (type/key) " << className << "/" << pObj->name());
       return(StatusCode::FAILURE);
    }
    setPlacement(key);
-   this->m_poolToken = m_athenaPoolCnvSvc->registerForWrite(m_placement, obj, m_classDesc);
+   this->m_o_poolToken = m_athenaPoolCnvSvc->registerForWrite(m_placement, obj, m_classDesc);
    return(StatusCode::SUCCESS);
 }
 //__________________________________________________________________________
 template <class T>
-StatusCode T_AthenaPoolCnv<T>::PoolToDataObject(DataObject*& pObj, const std::string& /*token*/) {
+StatusCode T_AthenaPoolCnvBase<T>::PoolToDataObject(DataObject*& pObj, const Token* token) {
    const std::string className = ClassName<T>::name();
-   if (!m_dictionaryOkRead) {
-      m_dictionaryOkRead = m_athenaPoolCnvSvc->testDictionary(className);
-   }
-   if (!m_dictionaryOkRead) {
-      ATH_MSG_ERROR("There is no correct dictionary for class \"" << className << "\"");
-      return(StatusCode::FAILURE);
-   }
-   void* voidPtr;
+   void* voidPtr = 0;
    try {
-      m_athenaPoolCnvSvc->setObjPtr(voidPtr, this->m_poolToken);
+      m_athenaPoolCnvSvc->setObjPtr(voidPtr, token);
    } catch (std::exception &e) {
       std::string error = e.what();
       ATH_MSG_ERROR("poolToObject: caught error: " << error);
       return(StatusCode::FAILURE);
    }
    T* obj = reinterpret_cast<T*>(voidPtr);
-   this->setDataObject(SG::asStorable(obj));
-   pObj = this->getDataObject();
+   pObj = SG::asStorable(obj);
    return(StatusCode::SUCCESS);
 }
 //__________________________________________________________________________
 template <class T>
-void T_AthenaPoolCnv<T>::setPlacement(const std::string& key) {
+void T_AthenaPoolCnvBase<T>::setPlacement(const std::string& key) {
    const std::string typenm = ClassName<T>::name();
    setPlacementWithType(typenm, key);
 }
diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolCoolMultChanCnv.h b/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolCoolMultChanCnv.h
old mode 100755
new mode 100644
diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolCoolMultChanCnv.icc b/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolCoolMultChanCnv.icc
old mode 100755
new mode 100644
index 4f35581597d..382650ffb7b
--- a/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolCoolMultChanCnv.icc
+++ b/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolCoolMultChanCnv.icc
@@ -176,14 +176,6 @@ T_AthenaPoolCoolMultChanCnv<COLL_T, ELEM_T, ELEM_P>::objectToAttrListColl(COLL_T
 	ATH_MSG_DEBUG("Chan " << *itChan1);
     }
 
-    // We must check the class def for CondMultChanCollImpl at least
-    // once. To do so, we need to reset the dict check flag once since
-    // it was already after checking ELEM_T
-    static bool first = true;
-    if (first) {
-	this->m_dictionaryOkWrite = false;
-	first                     = false;
-    }
     StatusCode sc = this->objectToPool(impl, implToken);
     if (sc != StatusCode::SUCCESS || !implToken) {
 	ATH_MSG_ERROR("Unable to write out CondMultChanCollImpl");
@@ -310,7 +302,7 @@ T_AthenaPoolCoolMultChanCnv<COLL_T, ELEM_T, ELEM_P>::condMultChanCollImplToObjec
     // Read in the CondMultChanCollImpl
     CondMultChanCollImpl* impl = 0;
     this->setToken(collImplToken);
-    StatusCode sc = this->poolToObject(collImplToken, impl);
+    StatusCode sc = this->poolToObject(this->m_i_poolToken, impl);
     if (sc != StatusCode::SUCCESS) {
 	ATH_MSG_ERROR("Unable to read in CondMultChanCollImpl");
 	return(StatusCode::FAILURE);
@@ -376,7 +368,7 @@ template <class P>
 inline
 P* T_AthenaPoolCoolMultChanCnv<COLL_T, ELEM_T, ELEM_P>::poolReadObject() {
    P* persObj = 0;
-   if( this->poolToObject( this->m_poolToken != 0 ? this->m_poolToken->toString() : "", persObj ).isFailure() ) {
+   if( this->poolToObject( this->m_i_poolToken , persObj ).isFailure() ) {
       throw std::runtime_error("POOL read failed");
    }
    return(persObj);
@@ -389,7 +381,7 @@ template <class COLL_T, class ELEM_T, class ELEM_P>
 inline
 ELEM_T* T_AthenaPoolCoolMultChanCnv<COLL_T, ELEM_T, ELEM_P>::poolReadObject() {
    ELEM_T* persObj = 0;
-   if( this->poolToObject( this->m_poolToken != 0 ? this->m_poolToken->toString() : "", persObj ).isFailure() ) {
+   if( this->poolToObject( this->m_i_poolToken , persObj ).isFailure() ) {
       throw std::runtime_error("POOL read failed");
    }
    return(persObj);
diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolCustCnv.h b/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolCustCnv.h
old mode 100755
new mode 100644
index 3e05cffdb01..a9fe556da7b
--- a/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolCustCnv.h
+++ b/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolCustCnv.h
@@ -10,7 +10,7 @@
  *  @author Peter van Gemmeren <gemmeren@anl.gov>
  **/
 
-#include "AthenaPoolCnvSvc/T_AthenaPoolCnv.h"
+#include "AthenaPoolCnvSvc/T_AthenaPoolCnvBase.h"
 
 #include "PersistentDataModel/Token.h"
 #include "PersistentDataModel/Guid.h"
@@ -31,7 +31,7 @@ template <class TYPE> class CnvFactory;
  *  @brief This templated class provides the converter to translate an object to/from its persistent POOL representation.
  **/
 template <class TRANS, class PERS>
-class T_AthenaPoolCustCnv : public T_AthenaPoolCnv<TRANS> {
+class T_AthenaPoolCustCnv : public T_AthenaPoolCnvBase<TRANS> {
    friend class CnvFactory<T_AthenaPoolCustCnv<TRANS, PERS> >;
 
 protected:
@@ -53,7 +53,7 @@ protected:
    /// Read an object from POOL.
    /// @param pObj [OUT] pointer to the transient object.
    /// @param token [IN] POOL token of the persistent representation.
-   virtual StatusCode PoolToDataObject(DataObject*& pObj, const std::string& token);
+   virtual StatusCode PoolToDataObject(DataObject*& pObj, const Token* token);
 
    /// Write an object into POOL returning its token.
    /// @param pObj  [IN]  pointer to the object to be written.
@@ -66,7 +66,7 @@ protected:
    /// @param token [IN]  POOL token of the persistent representation.
    /// @param pObj  [OUT] pointer to the object read.
    template <class P>
-   StatusCode poolToObject(const std::string& token, P*& pObj);
+   StatusCode poolToObject(const Token*& token, P*& pObj);
 
    virtual StatusCode transToPers(TRANS* obj, PERS*& persObj) = 0;
    virtual StatusCode persToTrans(TRANS*& transObj, PERS* obj) = 0;
@@ -83,8 +83,7 @@ protected:
    virtual void setToken(const std::string& token);
  
    // the POOL class ID (GUID) of the object being read.
-   // Set by PoolToDataObject() (together with m_token)
-   // available in createTransient()
+   // Set by PoolToDataObject() available in createTransient()
    Guid m_classID;
 
 public:
diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolCustCnv.icc b/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolCustCnv.icc
old mode 100755
new mode 100644
index d77803888ff..03ad20bc0f4
--- a/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolCustCnv.icc
+++ b/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolCustCnv.icc
@@ -17,19 +17,19 @@
 #include "StorageSvc/DbReflex.h"
 
 #include "CLIDSvc/CLASS_DEF.h"
-#include "DataModel/ClassName.h"
+#include "SGTools/ClassName.h"
 #include "PersistentDataModel/Token.h"
 #include "SGTools/StorableConversions.h"
 
 //__________________________________________________________________________
 template <class TRANS, class PERS>
-T_AthenaPoolCustCnv<TRANS, PERS>::T_AthenaPoolCustCnv(ISvcLocator* pSvcLocator) : T_AthenaPoolCnv<TRANS>(pSvcLocator) {
+T_AthenaPoolCustCnv<TRANS, PERS>::T_AthenaPoolCustCnv(ISvcLocator* pSvcLocator) : T_AthenaPoolCnvBase<TRANS>(pSvcLocator) {
 }
 //______________________________________________________________________________
 template <class TRANS, class PERS>
 StatusCode T_AthenaPoolCustCnv<TRANS, PERS>::initialize() {
    ATH_MSG_DEBUG("initialize() in T_AthenaPoolCustCnv " << classID());
-   if (!T_AthenaPoolCnv<TRANS>::initialize().isSuccess()) {
+   if (!T_AthenaPoolCnvBase<TRANS>::initialize().isSuccess()) {
       ATH_MSG_FATAL("Failed to initialize AthenaPoolConverter base class.");
       return(StatusCode::FAILURE);
    }
@@ -53,13 +53,6 @@ template <class P>
 StatusCode T_AthenaPoolCustCnv<TRANS, PERS>::objectToPool(P* pObj, const Token*& token, const std::string& key) {
    const std::string className = ClassName<P>::name();
    // Check dictionary
-   if (!this->m_dictionaryOkWrite) {
-      this->m_dictionaryOkWrite = this->m_athenaPoolCnvSvc->testDictionary(className);
-   }
-   if (!this->m_dictionaryOkWrite) {
-      ATH_MSG_ERROR("There is no correct dictionary for class (type/key) " << className << "/" << key);
-      return(StatusCode::FAILURE);
-   }
    // Allow for multiple class names
    if (this->m_className != className) {
       this->m_className = className;
@@ -67,7 +60,6 @@ StatusCode T_AthenaPoolCustCnv<TRANS, PERS>::objectToPool(P* pObj, const Token*&
       auto itClass = this->m_classDescs.find(className);
       if (itClass == this->m_classDescs.end()) {
          // For new class names, check dictionary
-         this->m_dictionaryOkWrite = false;
          this->m_classDesc = RootType( typeid(P) );
          this->m_classDescs[className] = this->m_classDesc;
       } else {
@@ -82,100 +74,51 @@ StatusCode T_AthenaPoolCustCnv<TRANS, PERS>::objectToPool(P* pObj, const Token*&
 //__________________________________________________________________________
 template <class TRANS, class PERS>
 template <class P>
-StatusCode T_AthenaPoolCustCnv<TRANS, PERS>::poolToObject(const std::string& /*token*/, P*& pObj) {
+StatusCode T_AthenaPoolCustCnv<TRANS, PERS>::poolToObject(const Token*& token, P*& pObj) {
    pObj = 0;
    const std::string className = ClassName<P>::name();
-   if (!this->m_dictionaryOkRead) {
-      this->m_dictionaryOkRead = this->m_athenaPoolCnvSvc->testDictionary(className);
-   }
-   if (!this->m_dictionaryOkRead) {
-      ATH_MSG_ERROR("There is no correct dictionary for class \"" << className << "\"");
-      return(StatusCode::FAILURE);
-   }
    void* voidPtr = 0;
    try {
-      this->m_athenaPoolCnvSvc->setObjPtr(voidPtr, this->m_poolToken);
+      this->m_athenaPoolCnvSvc->setObjPtr(voidPtr, token);
    } catch (std::exception &e) {
       ATH_MSG_ERROR("poolToObject: caught error: " << e.what());
       return(StatusCode::FAILURE);
    }
    if (voidPtr == 0) {
-      ATH_MSG_ERROR("poolToObject: Could not get object for Token = " << (this->m_poolToken != 0 ? this->m_poolToken->toString() : ""));
+      ATH_MSG_ERROR("poolToObject: Could not get object for Token = " << (token != 0 ? token->toString() : ""));
       return(StatusCode::FAILURE);
    }
    pObj = reinterpret_cast<P*>(voidPtr);
    if (pObj == 0) {
-      ATH_MSG_ERROR("poolToObject: Failed to cast object for Token = " << (this->m_poolToken != 0 ? this->m_poolToken->toString() : ""));
+      ATH_MSG_ERROR("poolToObject: Failed to cast object for Token = " << (token != 0 ? token->toString() : ""));
       return(StatusCode::FAILURE);
    }
    return(StatusCode::SUCCESS);
 }
 //__________________________________________________________________________
 template <class TRANS, class PERS>
-StatusCode T_AthenaPoolCustCnv<TRANS, PERS>::DataObjectToPool(DataObject* /*pObj*/, const std::string& key) {
+StatusCode T_AthenaPoolCustCnv<TRANS, PERS>::DataObjectToPool(DataObject* pObj, const std::string& key) {
    const std::string className = ClassName<TRANS>::name();
-   bool skipDHE = false;
    TRANS* obj = 0;
    PERS* persObj = 0;
-   SG::fromStorable(this->getDataObject(), obj);
+   SG::fromStorable(pObj, obj);
    if (obj == 0) {
-      if (this->getDataObject()->clID() == 1) {
-         if (this->getDataObject()->registry() != 0 && this->getDataObject()->registry()->address() != 0) {
-            ATH_MSG_DEBUG("Failed to cast DataObject to transient type, doing pers to pers");
-            const std::string className = ClassName<PERS>::name();
-            if (this->m_className != className) {
-               this->m_className = className;
-               // Different class name - get description
-               auto itClass = this->m_classDescs.find(className);
-               if (itClass == this->m_classDescs.end()) {
-                  this->m_classDesc = RootType( typeid(PERS) );
-                  this->m_classDescs[className] = this->m_classDesc;
-               } else {
-                  // Set to correct class description
-                  this->m_classDesc = (*itClass).second;
-               }
-            }
-            this->setToken(this->getDataObject()->registry()->address()->par()[0]);
-            ATH_MSG_DEBUG("Failed to cast DataObject to transient type, doing pers to pers");
-            if (!this->compareClassGuid(pool::DbReflex::guid(this->m_classDesc))) {
-               ATH_MSG_ERROR("Can not evolve schema in pers to pers copy");
-               return(StatusCode::FAILURE);
-            }
-            if (!poolToObject<PERS>("", persObj).isSuccess()) {
-               ATH_MSG_ERROR("Failed to read persistent DataType");
-               return(StatusCode::FAILURE);
-            }
-         } else {
-            ATH_MSG_DEBUG("Failed to cast DataObject to transient type, using empty default");
-            skipDHE = true;
-            persObj = new PERS();
-         }
-      } else {
-         ATH_MSG_ERROR("failed to cast to T for class (type/key) " << className << "/" << this->getDataObject()->name());
-         return(StatusCode::FAILURE);
-      }
+      ATH_MSG_ERROR("failed to cast to T for class (type/key) " << className << "/" << pObj->name());
+      return(StatusCode::FAILURE);
    } else {
       if (!transToPers(obj, persObj).isSuccess()) {
-         ATH_MSG_ERROR("Failed to convert to persistent DataType for class (type/key) " << className << "/" << this->getDataObject()->name());
+         ATH_MSG_ERROR("Failed to convert to persistent DataType for class (type/key) " << className << "/" << pObj->name());
          return(StatusCode::FAILURE);
       }
    }
-   const Token* token = 0;
-   StatusCode status = objectToPool<PERS>(persObj, token, key);
-   if (skipDHE) {
-      delete token; token = 0;
-      this->setToken("\n");
-   } else {
-      this->m_poolToken = token; token = 0;
-   }
-   return(status);
+   return(objectToPool<PERS>(persObj, this->m_o_poolToken, key));
 }
 //__________________________________________________________________________
 template <class TRANS, class PERS>
-StatusCode T_AthenaPoolCustCnv<TRANS, PERS>::PoolToDataObject(DataObject*& pObj, const std::string& /*token*/) {
+StatusCode T_AthenaPoolCustCnv<TRANS, PERS>::PoolToDataObject(DataObject*& pObj, const Token* token) {
    TRANS* transObj = 0;
    PERS* obj = 0;
-   if (!poolToObject<PERS>("", obj).isSuccess()) {
+   if (!poolToObject<PERS>(token, obj).isSuccess()) {
       ATH_MSG_ERROR("Failed to read persistent DataType");
       return(StatusCode::FAILURE);
    }
@@ -186,8 +129,7 @@ StatusCode T_AthenaPoolCustCnv<TRANS, PERS>::PoolToDataObject(DataObject*& pObj,
       return(StatusCode::FAILURE);
    }
    delete obj; obj = 0;
-   this->setDataObject(SG::asStorable(transObj));
-   pObj = this->getDataObject();
+   pObj = SG::asStorable(transObj);
    return(StatusCode::SUCCESS);
 }
 //__________________________________________________________________________
@@ -195,9 +137,9 @@ StatusCode T_AthenaPoolCustCnv<TRANS, PERS>::PoolToDataObject(DataObject*& pObj,
 // the object that will be read next.  Required by compareClassGuid()
 template <class TRANS, class PERS>
 inline void T_AthenaPoolCustCnv<TRANS, PERS>::setToken(const std::string& token_str) {
-   if (this->m_poolToken == 0) this->m_poolToken = new Token;
-   const_cast<Token*>(this->m_poolToken)->fromString(token_str);
-   m_classID = this->m_poolToken != 0 ? this->m_poolToken->classID() : Guid::null();
+   if (this->m_i_poolToken == 0) this->m_i_poolToken = new Token;
+   const_cast<Token*>(this->m_i_poolToken)->fromString(token_str);
+   m_classID = this->m_i_poolToken != 0 ? this->m_i_poolToken->classID() : Guid::null();
 }
 //__________________________________________________________________________
 // Compare POOL class GUID with the one from object being read
diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolCustomCnv.h b/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolCustomCnv.h
old mode 100755
new mode 100644
index d7741852667..706a632f1b7
--- a/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolCustomCnv.h
+++ b/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolCustomCnv.h
@@ -91,7 +91,7 @@ protected:
    /// Read an object from POOL.
    /// @param pObj [OUT] pointer to the transient object.
    /// @param token [IN] POOL token of the persistent representation.
-   virtual StatusCode PoolToDataObject(DataObject*& pObj, const std::string& token);
+   virtual StatusCode PoolToDataObject(DataObject*& pObj, const Token* token);
 
    /// Callback from the CleanupSvc to delete persistent object in the local list
    virtual StatusCode cleanUp();
diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolCustomCnv.icc b/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolCustomCnv.icc
old mode 100755
new mode 100644
index 3459655dcdf..f05c6cd770a
--- a/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolCustomCnv.icc
+++ b/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolCustomCnv.icc
@@ -27,53 +27,14 @@ T_AthenaPoolCustomCnv<TRANS, PERS>::T_AthenaPoolCustomCnv(ISvcLocator* pSvcLocat
 }
 
 template <class TRANS, class PERS>
-StatusCode T_AthenaPoolCustomCnv<TRANS, PERS>::DataObjectToPool(DataObject* /*pObj*/, const std::string& key) {
-   ATH_MSG_VERBOSE("In DataObjectToPool() for key = " << this->getDataObject()->name());
-   bool skipDHE = false;
+StatusCode T_AthenaPoolCustomCnv<TRANS, PERS>::DataObjectToPool(DataObject* pObj, const std::string& key) {
+   ATH_MSG_VERBOSE("In DataObjectToPool() for key = " << pObj->name());
    TRANS* obj = 0;
    PERS* persObj = 0;
-   SG::fromStorable(this->getDataObject(), obj);
+   SG::fromStorable(pObj, obj);
    if (obj == 0) {
-      if (this->getDataObject()->clID() == 1) {
-         if (this->getDataObject()->registry() != 0 && this->getDataObject()->registry()->address() != 0) {
-            const std::string className = ClassName<PERS>::name();
-            if (this->m_className != className) {
-               this->m_className = className;
-               auto itClass = this->m_classDescs.find(className);
-               if (itClass == this->m_classDescs.end()) {
-                  this->m_classDesc = RootType( typeid(PERS) );
-                  this->m_classDescs[className] = this->m_classDesc;
-               } else {
-                  // Set to correct class description
-                  this->m_classDesc = (*itClass).second;
-               }
-            }
-            this->setToken(this->getDataObject()->registry()->address()->par()[0]);
-            ATH_MSG_DEBUG("Failed to cast DataObject to transient type, doing pers to pers");
-            if (!this->compareClassGuid(pool::DbReflex::guid(this->m_classDesc))) {
-               ATH_MSG_ERROR("Can not evolve schema in pers to pers copy");
-               return(StatusCode::FAILURE);
-            }
-            AthenaConverterTLPExtension *extCnv = dynamic_cast<AthenaConverterTLPExtension*>(this);
-            if (extCnv != 0) {
-               ATH_MSG_ERROR("Can not retrieve " << this->getDataObject()->name() << " in pers to pers copy");
-               return(StatusCode::FAILURE);
-            }
-            try {
-               persObj = this->poolReadObject<PERS>();
-            } catch (...) {
-               ATH_MSG_ERROR("Failed to read persistent DataType");
-               return(StatusCode::FAILURE);
-            }
-         } else {
-            ATH_MSG_DEBUG("Failed to cast DataObject to transient type, using empty default");
-            skipDHE = true;
-            persObj = new PERS();
-         }
-      } else {
-         ATH_MSG_ERROR("Failed to cast DataObject to transient type");
-         return(StatusCode::FAILURE);
-      }
+      ATH_MSG_ERROR("Failed to cast DataObject to transient type");
+      return(StatusCode::FAILURE);
    } else {
       try {
          persObj = createPersistent(obj);
@@ -93,21 +54,13 @@ StatusCode T_AthenaPoolCustomCnv<TRANS, PERS>::DataObjectToPool(DataObject* /*pO
       }
    }
    m_persObjList.push_back(persObj);
-   const Token* token = 0;
-   StatusCode status = this->objectToPool(persObj, token, key);
-   if (skipDHE) {
-      delete token; token = 0;
-      this->setToken("\n");
-   } else {
-      this->m_poolToken = token; token = 0;
-   }
-   return(status);
+   return(this->objectToPool(persObj, this->m_o_poolToken, key));
 }
 
 template <class TRANS, class PERS>
-StatusCode T_AthenaPoolCustomCnv<TRANS, PERS>::PoolToDataObject(DataObject*& pObj, const std::string& /*token_str*/) {
-   if (this->m_poolToken != 0) {
-      this->m_classID = this->m_poolToken->classID();
+StatusCode T_AthenaPoolCustomCnv<TRANS, PERS>::PoolToDataObject(DataObject*& pObj, const Token* token) {
+   if (token != 0) {
+      this->m_classID = token->classID();
    }
    TRANS* transObj = 0;
    AthenaConverterTLPExtension *extCnv = dynamic_cast<AthenaConverterTLPExtension*>(this);
@@ -128,8 +81,7 @@ StatusCode T_AthenaPoolCustomCnv<TRANS, PERS>::PoolToDataObject(DataObject*& pOb
    if (extCnv != 0) {
       extCnv->deletePersistentObjects();
    }
-   this->setDataObject(SG::asStorable(transObj));
-   pObj = this->getDataObject();
+   pObj = SG::asStorable(transObj);
    return(StatusCode::SUCCESS);
 }
 
@@ -139,9 +91,9 @@ template <class TRANS, class PERS>
 template <class P>
 inline P* T_AthenaPoolCustomCnv<TRANS, PERS>::poolReadObject() {
    P* persObj = 0;
-   if (this->poolToObject("", persObj).isFailure()) {
+   if (this->poolToObject(this->m_i_poolToken, persObj).isFailure()) {
       std::string error("POOL read failed. Token = ");
-      throw std::runtime_error(error + (this->m_poolToken != 0 ? this->m_poolToken->toString() : ""));
+      throw std::runtime_error(error + (this->m_i_poolToken != 0 ? this->m_i_poolToken->toString() : ""));
    }
    AthenaConverterTLPExtension *extCnv = dynamic_cast<AthenaConverterTLPExtension*>(this);
    if (extCnv != 0) {
diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolExtendingCnv.h b/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolExtendingCnv.h
old mode 100755
new mode 100644
diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolExtendingCnv.icc b/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolExtendingCnv.icc
old mode 100755
new mode 100644
index a971206011c..4f7695d349e
--- a/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolExtendingCnv.icc
+++ b/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolExtendingCnv.icc
@@ -38,7 +38,9 @@ wasClonedFrom( AthenaConverterTLPExtension *converter )
       m_originalExtendingCnv = dynamic_cast< BaseType* >(converter);
    } else {
       // in case of cloning a clone, get the real original converter
-      m_originalExtendingCnv = dynamic_cast< T_AthenaPoolExtendingCnv< TRANS, PERS >* >(converter)->baseAthenaPoolCnv();
+      auto* extcnv = dynamic_cast< T_AthenaPoolExtendingCnv< TRANS, PERS >* >(converter);
+      if (!extcnv) std::abort();
+      m_originalExtendingCnv = extcnv->baseAthenaPoolCnv();
    }
 //   std::cout << " TPCNVINFO:  Registering clone source " << (void*)m_originalExtendingCnv << std::endl;
 }
diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolTPCnvCnv.h b/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolTPCnvCnv.h
new file mode 100644
index 00000000000..e6dbe97fef8
--- /dev/null
+++ b/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolTPCnvCnv.h
@@ -0,0 +1,92 @@
+// This file's extension implies that it's C, but it's really -*- C++ -*-.
+
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// $Id$
+/**
+ * @file AthenaPoolCnvSvc/T_AthenaPoolTPCnvCnv.h
+ * @author scott snyder <snyder@bnl.gov>
+ * @date Jan, 2016
+ * @brief Athena pool converter for a class using TP separation.
+ */
+
+
+#ifndef ATHENAPOOLCNVSVC_T_ATHENAPOOLTPCNVCNV_H
+#define ATHENAPOOLCNVSVC_T_ATHENAPOOLTPCNVCNV_H
+
+
+#include "AthenaPoolCnvSvc/TPCnvList.h"
+#include "AthenaPoolCnvSvc/T_AthenaPoolCustomCnv.h"
+#include "AthenaPoolCnvSvc/exceptions.h"
+#include "SGTools/ClassName.h"
+#include <memory>
+
+
+/**
+ * @brief Athena pool converter for aux store classes.
+ *
+ * AUXSTORE is the class being read/written.
+ * TPCNVS is a list of TP converters to handle older versions of the class.
+ *
+ * On writing, the container is copied (and thinned if required).
+ * For reading, we read the object either directly
+ * or using one of the TP converters, depending on the saved GUID.
+ */
+template <class TRANS, class TPCNV_CUR, class ... TPCNVS>
+class T_AthenaPoolTPCnvCnv
+  : public T_AthenaPoolCustomCnv<TRANS, typename TPCNV_CUR::Pers_t>
+{
+  friend class CnvFactory< T_AthenaPoolTPCnvCnv >;
+
+  template <class CNV, class TPCNV>
+  friend class AthenaPoolCnvSvc::TPCnvElt;
+
+public:
+  typedef T_AthenaPoolCustomCnv<TRANS, typename TPCNV_CUR::Pers_t> Base;
+  typedef typename TPCNV_CUR::Pers_t Pers_t;
+
+  
+  /**
+   * @brief Constructor.
+   * @param svcLoc Gaudi service locator.
+   */
+  T_AthenaPoolTPCnvCnv ( ISvcLocator* svcLoc );
+
+  
+  /**
+   * @brief Convert a transient object to persistent form.
+   * @param trans The transient object to convert.
+   *
+   * Returns a newly-allocated persistent object.
+   */
+  virtual Pers_t* createPersistent( TRANS* trans ) override;
+
+
+  /**
+   * @brief Read the persistent object and convert it to transient.
+   *
+   * Returns a newly-allocated transient object.
+   * Errors are reported by raising exceptions.
+   */
+  virtual TRANS* createTransient() override;
+
+  
+private:
+  /// GUID of the object being read.
+  Guid m_guid;
+
+  /// TP converter for current persistent class version.
+  TPCNV_CUR m_tpcnv_cur;
+
+  /// List of TP converters for older versions.
+  AthenaPoolCnvSvc::TPCnvList<T_AthenaPoolTPCnvCnv, TRANS, TPCNVS...> m_tpcnvs;
+};
+
+
+#include "AthenaPoolCnvSvc/T_AthenaPoolTPCnvCnv.icc"
+
+
+#endif // not ATHENAPOOLCNVSVC_T_ATHENAPOOLTPCNVCNV_H
+
diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolTPCnvCnv.icc b/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolTPCnvCnv.icc
new file mode 100644
index 00000000000..662e5776cc2
--- /dev/null
+++ b/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolTPCnvCnv.icc
@@ -0,0 +1,65 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// $Id$
+/**
+ * @file AthenaPoolCnvSvc/T_AthenaPoolTPCnvCnv.icc
+ * @author scott snyder <snyder@bnl.gov>
+ * @date Jan, 2016
+ * @brief Athena pool converter for a class using TP separation.
+ */
+
+
+/**
+ * @brief Constructor.
+ * @param svcLoc Gaudi service locator.
+ */
+template <class TRANS, class TPCNV_CUR, class ... TPCNVS>
+T_AthenaPoolTPCnvCnv<TRANS, TPCNV_CUR, TPCNVS...>::T_AthenaPoolTPCnvCnv( ISvcLocator* svcLoc )
+  : Base( svcLoc )
+{
+  m_guid = AthenaPoolCnvSvc::guidFromTypeinfo (typeid (Pers_t));
+}
+
+
+/**
+ * @brief Convert a transient object to persistent form.
+ * @param trans The transient object to convert.
+ *
+ * Returns a newly-allocated persistent object.
+ */
+template <class TRANS, class TPCNV_CUR, class ... TPCNVS>
+typename T_AthenaPoolTPCnvCnv<TRANS, TPCNV_CUR, TPCNVS...>::Pers_t*
+T_AthenaPoolTPCnvCnv<TRANS, TPCNV_CUR, TPCNVS...>::createPersistent( TRANS* trans )
+{
+  return m_tpcnv_cur.createPersistent (trans, this->msg());
+}
+
+
+/**
+ * @brief Read the persistent object and convert it to transient.
+ *
+ * Returns a newly-allocated transient object.
+ * Errors are reported by raising exceptions.
+ */
+template <class TRANS, class TPCNV_CUR, class ... TPCNVS>
+TRANS*
+T_AthenaPoolTPCnvCnv<TRANS, TPCNV_CUR, TPCNVS...>::createTransient()
+{
+  if ( this->compareClassGuid( m_guid ) ) {
+    // It's the latest version.
+    std::unique_ptr<Pers_t> persObj( this->template poolReadObject<Pers_t>() );
+    return m_tpcnv_cur.createTransient( persObj.get(), this->msg() );
+  }
+
+  // Try a converter.
+  TRANS* c = m_tpcnvs.createTransient (*this, this->msg());
+  if (c)
+    return c;
+
+  // Didn't recognize the GUID.
+  AthenaPoolCnvSvc::throwExcUnsupportedVersion (typeid(TRANS),
+                                                this->m_i_poolToken->classID());
+  return 0;
+}
diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolTPConverter.h b/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolTPConverter.h
old mode 100755
new mode 100644
diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolViewVectorCnv.h b/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolViewVectorCnv.h
new file mode 100644
index 00000000000..5b533ccec24
--- /dev/null
+++ b/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolViewVectorCnv.h
@@ -0,0 +1,93 @@
+// This file's extension implies that it's C, but it's really -*- C++ -*-.
+
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// $Id$
+/**
+ * @file AthenaPoolCnvSvc/T_AthenaPoolViewVectorCnv.h
+ * @author scott snyder <snyder@bnl.gov>
+ * @date Jan, 2016
+ * @brief Athena pool converter for a ViewVector class.
+ */
+
+
+#ifndef ATHENAPOOLCNVSVC_T_ATHENAPOOLVIEWVECTORCNV_H
+#define ATHENAPOOLCNVSVC_T_ATHENAPOOLVIEWVECTORCNV_H
+
+
+#include "AthenaPoolCnvSvc/T_AthenaPoolCustomCnv.h"
+#include "AthenaPoolCnvSvc/exceptions.h"
+#include "StorageSvc/DbReflex.h"
+#include "AthContainers/ViewVector.h"
+#include "AthContainers/dataVectorAsELV.h"
+#include "AthContainers/ConstDataVector.h"
+#include "AthLinks/ElementLink.h"
+#include "AthenaKernel/errorcheck.h"
+#include "CxxUtils/make_unique.h"
+#include "CxxUtils/StrFormat.h"
+#include <vector>
+#include <cstdlib>
+
+
+/**
+ * @brief Athena pool converter for a ViewVector class.
+ *
+ * This pool converter converts between a transient ViewVector<DV> type
+ * and a persistent std::vector<ElementLink<DV> > type, where DV is
+ * a DataVector.
+ */
+template <class DV>
+class T_AthenaPoolViewVectorCnv
+  : public T_AthenaPoolCustomCnv<ViewVector<DV>,
+                                 std::vector<ElementLink<DV> > >
+{
+public:
+  /// The transient and persistent types.
+  typedef ViewVector<DV> trans_t;
+  typedef std::vector<ElementLink<DV> > pers_t;
+
+  /// Base class.
+  typedef T_AthenaPoolCustomCnv<trans_t, pers_t> Base;
+
+  
+  /**
+   * @brief Constructor.
+   * @param svcloc The Gaudi service locator.
+   */
+  T_AthenaPoolViewVectorCnv (ISvcLocator* svcloc);
+
+
+  /**
+   * @brief Standard Gaudi initialize method.
+   */
+  virtual StatusCode initialize() override;
+
+
+  /**
+   * @brief Convert a transient object to persistent form.
+   * @param trans The transient object to convert.
+   *
+   * Returns a newly-allocated persistent object.
+   */
+  virtual pers_t* createPersistent( trans_t* trans ) override;
+
+
+  /**
+   * @brief Read the persistent object and convert it to transient.
+   *
+   * Returns a newly-allocated transient object.
+   * Errors are reported by raising exceptions.
+   */
+  virtual trans_t* createTransient() override;
+
+private:
+  std::vector<pool::Guid> m_guids;
+};
+
+
+#include "AthenaPoolCnvSvc/T_AthenaPoolViewVectorCnv.icc"
+
+
+#endif // not ATHENAPOOLCNVSVC_T_ATHENAPOOLVIEWVECTORCNV_H
diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolViewVectorCnv.icc b/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolViewVectorCnv.icc
new file mode 100644
index 00000000000..c774ea3eac3
--- /dev/null
+++ b/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolViewVectorCnv.icc
@@ -0,0 +1,118 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// $Id$
+/**
+ * @file AthenaPoolCnvSvc/T_AthenaPoolViewVectorCnv.icc
+ * @author scott snyder <snyder@bnl.gov>
+ * @date Jan, 2016
+ * @brief Athena pool converter for a ViewVector class.
+ */
+
+
+/**
+ * @brief Constructor.
+ * @param svcloc The Gaudi service locator.
+ */
+template <class DV>
+T_AthenaPoolViewVectorCnv<DV>::T_AthenaPoolViewVectorCnv (ISvcLocator* svcloc)
+  : Base (svcloc)
+{
+}
+
+
+/**
+ * @brief Standard Gaudi initialize method.
+ */
+template <class DV>
+StatusCode
+T_AthenaPoolViewVectorCnv<DV>::initialize()
+{
+  CHECK( Base::initialize() );
+
+  // Make a list of all the guids that this converter can read.
+  // First, add the entry for pers_t.
+  pool::TypeH typ = pool::DbReflex::forTypeInfo (typeid(pers_t));
+  if (!typ)
+    AthenaPoolCnvSvc::throwExcNoDictForClass (typeid(pers_t));
+  m_guids.push_back (pool::DbReflex::guid (typ));
+
+  // Now look for entries for previous versions.
+  // Look for a version tag in the type name and try replacing it with
+  // previous versions.  Eg, if the name for pers_t contains `_v3',
+  // then we also look for guids for the same name with `_v3' replaced
+  // by `_v2' and `_v1'.
+
+  std::string name = typ.Name();
+  std::string::size_type vpos = 0;
+  while ((vpos = name.find ("_v", vpos)) != std::string::npos) {
+    vpos += 2;
+    std::string::size_type vpos2 = vpos;
+    if (isdigit (name[vpos2])) {
+      ++vpos2;
+      while (vpos2 < name.size() && isdigit (name[vpos2]))
+        ++vpos2;
+      if (vpos2 < name.size() && name[vpos2] == '>') {
+        int vers = atoi (name.substr (vpos, vpos2-vpos).c_str());
+        while (--vers > 0) {
+          std::string name2 = name.substr(0,vpos) + CxxUtils::strformat("%d", vers) + name.substr(vpos2,std::string::npos);
+          pool::TypeH typ2 = pool::DbReflex::forTypeName (name2);
+          if (typ2)
+            m_guids.push_back (pool::DbReflex::guid (typ2));
+        }
+      }
+    }
+  }
+  return StatusCode::SUCCESS;
+}
+
+
+/**
+ * @brief Convert a transient object to persistent form.
+ * @param trans The transient object to convert.
+ *
+ * Returns a newly-allocated persistent object.
+ */
+template <class DV>
+typename T_AthenaPoolViewVectorCnv<DV>::pers_t*
+T_AthenaPoolViewVectorCnv<DV>::createPersistent( trans_t* trans )
+{
+  // Convert to ElementLinks and apply thinning.
+  pers_t* pers =  new pers_t (SG::dataVectorAsELV (static_cast<const DV&>(*trans)));
+  for (ElementLink<DV>& el : *pers)
+    el.thin();
+  return pers;
+}
+
+
+/**
+ * @brief Read the persistent object and convert it to transient.
+ *
+ * Returns a newly-allocated transient object.
+ * Errors are reported by raising exceptions.
+ */
+template <class DV>
+typename T_AthenaPoolViewVectorCnv<DV>::trans_t*
+T_AthenaPoolViewVectorCnv<DV>::createTransient()
+{
+  // See if we're looking at one of the guids we can handle.
+  // FIXME: For old persistent versions, this works by essentially doing
+  // a reinterpret_cast from the version on the file to the current version.
+  // That works for current ElementLink classes, but it's not very nice.
+  for (const pool::Guid& guid : m_guids) {
+    if( this->compareClassGuid( guid ) ) {
+      std::unique_ptr<pers_t> v (this->template poolReadObject< pers_t >());
+      auto c = CxxUtils::make_unique<ConstDataVector<trans_t> > (*v);
+      // FIXME: To get rid of this @c const_cast, the converter interfaces
+      // need to be changed to allow returning a const pointer
+      // all the way back to StoreGate.
+      return const_cast<trans_t*>(c.release()->asDataVector());
+    }
+  }
+   
+  // Didn't recognize the ID.
+  AthenaPoolCnvSvc::throwExcUnsupportedVersion (typeid(pers_t),
+                                                this->m_i_poolToken->classID());
+  return 0;
+}
diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolxAODCnv.h b/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolxAODCnv.h
new file mode 100644
index 00000000000..482b20cdd51
--- /dev/null
+++ b/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolxAODCnv.h
@@ -0,0 +1,104 @@
+// This file's extension implies that it's C, but it's really -*- C++ -*-.
+
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// $Id$
+/**
+ * @file AthenaPoolCnvSvc/T_AthenaPoolxAODCnv.h
+ * @author scott snyder <snyder@bnl.gov>
+ * @date Jan, 2016
+ * @brief Athena pool converter for xAOD classes.
+ */
+
+
+#ifndef ATHENAPOOLCNVSVC_T_ATHENAPOOLXAODCNV_H
+#define ATHENAPOOLCNVSVC_T_ATHENAPOOLXAODCNV_H
+
+
+#include "AthenaPoolCnvSvc/T_AthenaPoolCustomCnv.h"
+#include "AthenaPoolCnvSvc/TPCnvList.h"
+#include "AthenaPoolCnvSvc/exceptions.h"
+#include "AthContainers/AuxVectorBase.h"
+#include "SGTools/ClassName.h"
+
+
+/**
+ * @brief Athena pool converter for xAOD classes.
+ *
+ * XAOD is the class being read/written.
+ * TPCNVS is a list of TP converters to handle older versions of the class.
+ *
+ * On writing, the container is simply copied (thinning is handled by the
+ * thinning service).  For reading, we read the object either directly
+ * or using one of the TP converters, depending on the saved GUID.
+ * The link to the aux store is then set based on the SG key.
+ */
+template <class XAOD, class ... TPCNVS>
+class T_AthenaPoolxAODCnv
+  : public T_AthenaPoolCustomCnv<XAOD, XAOD>
+{
+  friend class CnvFactory< T_AthenaPoolxAODCnv >;
+
+  template <class CNV, class TPCNV>
+  friend class AthenaPoolCnvSvc::TPCnvElt;
+
+public:
+  typedef T_AthenaPoolCustomCnv<XAOD, XAOD> Base;
+
+
+  /**
+   * @brief Constructor.
+   * @param svcLoc Gaudi service locator.
+   */
+  T_AthenaPoolxAODCnv ( ISvcLocator* svcLoc );
+
+
+  /**
+   * @brief Read an object from persistent storage.
+   * @param pAddr Address of the object to read.
+   * @param pObj[out] Pointer to the read object.
+   *
+   * This is overridden here in order to be able to pass the SG key
+   * from the address to @c createTransient.
+   */
+  virtual StatusCode createObj( IOpaqueAddress* pAddr,
+                                DataObject*& pObj ) override;
+
+
+  /**
+   * @brief Convert a transient object to persistent form.
+   * @param trans The transient object to convert.
+   *
+   * Returns a newly-allocated persistent object.
+   */
+  virtual XAOD* createPersistent( XAOD* trans ) override;
+
+
+  /**
+   * @brief Read the persistent object and convert it to transient.
+   *
+   * Returns a newly-allocated transient object.
+   * Errors are reported by raising exceptions.
+   */
+  virtual XAOD* createTransient() override;
+
+  
+private:
+  /// SG key for the object being read.
+  std::string m_key;
+
+  /// GUID of the object being read.
+  Guid m_guid;
+
+  /// List of TP converters.
+  AthenaPoolCnvSvc::TPCnvList<T_AthenaPoolxAODCnv, XAOD, TPCNVS...> m_tpcnvs;
+};
+
+
+#include "AthenaPoolCnvSvc/T_AthenaPoolxAODCnv.icc"
+
+
+#endif // not ATHENAPOOLCNVSVC_T_ATHENAPOOLXAODCNV_H
+
diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolxAODCnv.icc b/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolxAODCnv.icc
new file mode 100644
index 00000000000..d2953c029c8
--- /dev/null
+++ b/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/T_AthenaPoolxAODCnv.icc
@@ -0,0 +1,90 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// $Id$
+/**
+ * @file AthenaPoolCnvSvc/T_AthenaPoolxAODCnv.icc
+ * @author scott snyder <snyder@bnl.gov>
+ * @date Jan, 2016
+ * @brief Athena pool converter for xAOD classes.
+ */
+
+
+/**
+ * @brief Constructor.
+ * @param svcLoc Gaudi service locator.
+ */
+template <class XAOD, class ... TPCNVS>
+T_AthenaPoolxAODCnv<XAOD, TPCNVS...>::T_AthenaPoolxAODCnv( ISvcLocator* svcLoc )
+  : Base( svcLoc )
+{
+  m_guid = AthenaPoolCnvSvc::guidFromTypeinfo (typeid (XAOD));
+}
+
+
+/**
+ * @brief Read an object from persistent storage.
+ * @param pAddr Address of the object to read.
+ * @param pObj[out] Pointer to the read object.
+ *
+ * This is overridden here in order to be able to pass the SG key
+ * from the address to @c createTransient.
+ */
+template <class XAOD, class ... TPCNVS>
+StatusCode
+T_AthenaPoolxAODCnv<XAOD, TPCNVS...>::createObj( IOpaqueAddress* pAddr,
+                                                 DataObject*& pObj )
+{
+   // Get the key of the container that we'll be creating:
+   m_key = pAddr->par()[1];
+   ATH_MSG_VERBOSE( "Key of " << ClassName<XAOD>::name() << ": " << m_key );
+
+   // Let the base class do its thing now:
+   return AthenaPoolConverter::createObj( pAddr, pObj );
+}
+
+
+/**
+ * @brief Convert a transient object to persistent form.
+ * @param trans The transient object to convert.
+ *
+ * Returns a newly-allocated persistent object.
+ */
+template <class XAOD, class ... TPCNVS>
+XAOD* T_AthenaPoolxAODCnv<XAOD, TPCNVS...>::createPersistent( XAOD* trans )
+{
+  return new XAOD (trans->begin(), trans->end(), SG::VIEW_ELEMENTS);
+}
+
+
+/**
+ * @brief Read the persistent object and convert it to transient.
+ *
+ * Returns a newly-allocated transient object.
+ * Errors are reported by raising exceptions.
+ */
+template <class XAOD, class ... TPCNVS>
+XAOD* T_AthenaPoolxAODCnv<XAOD, TPCNVS...>::createTransient()
+{
+  XAOD* c = nullptr;
+
+  if ( this->compareClassGuid( m_guid ) ) {
+    // It's the latest version, read it directly:
+    c = this->template poolReadObject< XAOD >();
+  }
+  else {
+    // Try a converter.
+    c = m_tpcnvs.createTransient (*this, this->msg());
+  }
+
+  if (c) {
+    c->setStore( DataLink< SG::IConstAuxStore > (m_key + "Aux." ) );
+    return c;
+  }
+
+  // Didn't recognize the GUID.
+  AthenaPoolCnvSvc::throwExcUnsupportedVersion (typeid(XAOD),
+                                                this->m_i_poolToken->classID());
+  return 0;
+}
diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/exceptions.h b/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/exceptions.h
new file mode 100644
index 00000000000..18a6db845d1
--- /dev/null
+++ b/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/exceptions.h
@@ -0,0 +1,84 @@
+// This file's extension implies that it's C, but it's really -*- C++ -*-.
+
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// $Id$
+/**
+ * @file AthenaPoolCnvSvc/exceptions.h
+ * @author scott snyder <snyder@bnl.gov>
+ * @date Jan, 2016
+ * @brief Exceptions that can be thrown from AthenaPoolCnvSvc.
+ */
+
+
+#ifndef ATHENAPOOLCNVSVC_EXCEPTIONS_H
+#define ATHENAPOOLCNVSVC_EXCEPTIONS_H
+
+
+#include "PersistentDataModel/Guid.h"
+#include <stdexcept>
+#include <typeinfo>
+#include <string>
+
+
+namespace AthenaPoolCnvSvc {
+
+
+/**
+ * @brief Exception --- Can't find dictionary information for class.
+ *
+ * POOL was unable to find the dictionary information for a given class.
+ */
+class ExcNoDictForClass
+  : public std::runtime_error
+{
+public:
+  /**
+   * @brief Constructor.
+   * @param ti The requested class.
+   */
+  ExcNoDictForClass (const std::type_info& ti);
+};
+
+
+/**
+ * @brief Throw a AthenaPoolCnvSvc::ExcNoDictForClass exception.
+ * @param ti The requested class.
+ */
+[[noreturn]]
+void throwExcNoDictForClass (const std::type_info& ti);
+
+  
+/**
+ * @brief Exception --- Unsupported persistent version of CLASS found.
+ *
+ * The guid of the persistent class was not recognized.
+ */
+class ExcUnsupportedVersion
+  : public std::runtime_error
+{
+public:
+  /**
+   * @brief Constructor.
+   * @param ti The class being read.
+   * @param guid The GUID of the persistent class.
+   */
+  ExcUnsupportedVersion (const std::type_info& ti, const Guid& guid);
+};
+
+
+/**
+ * @brief Throw a AthenaPoolCnvSvc::ExcUnsupportedVersion exception.
+ * @param ti The class being read.
+ * @param guid The GUID of the persistent class.
+o */
+[[noreturn]]
+void throwExcUnsupportedVersion (const std::type_info& ti, const Guid& guid);
+
+  
+} // namespace AthenaPoolCnvSvc
+
+
+#endif // not EXCEPTIONS_H
diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/selection_test.xml b/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/selection_test.xml
new file mode 100644
index 00000000000..abb50d92f45
--- /dev/null
+++ b/Database/AthenaPOOL/AthenaPoolCnvSvc/AthenaPoolCnvSvc/selection_test.xml
@@ -0,0 +1,29 @@
+<lcgdict>
+  <class name="AthenaPoolCnvSvcTest::X"
+         id="CAE53A87-64AD-4576-A203-1A4142E1E10F" />
+  <class name="AthenaPoolCnvSvcTest::X_p1"
+         id="6AD63B61-BE75-40FC-B0C6-DD3C7801D871" />
+  <class name="AthenaPoolCnvSvcTest::X_p2"
+         id="0AAC9C99-726D-4CF4-B9F9-00B6674C57DD" />
+  <class name="AthenaPoolCnvSvcTest::Y_v1"/>
+  <class name="AthenaPoolCnvSvcTest::Y_v2"/>
+  <class name="AthenaPoolCnvSvcTest::YCont_v1_pers"
+         id="7E1826B9-3666-42B3-A2E7-C916BD10A5B8" />
+  <class name="AthenaPoolCnvSvcTest::YCont_v2_pers"
+         id="80C19103-FE9B-4227-8E48-8C0DB468F892" />
+  <class name="DataVector<AthenaPoolCnvSvcTest::Y_v1>"
+         id="05309E49-5567-4790-BE56-2E541E0B4B24" />
+  <class name="DataVector<AthenaPoolCnvSvcTest::Y_v2>"
+         id="0CC6B32E-6C95-4B0E-B97A-9B9040A8A9BE" />
+  <class name="AthenaPoolCnvSvcTest::YAuxCont_v1"
+         id="BEE3C14E-149E-4366-9E24-8A32C419A3B4" />
+  <class name="AthenaPoolCnvSvcTest::YAuxCont_v2"
+         id="170BFEE4-F6B2-4AF4-919B-7EB3986656FA" />
+
+  <class name="AthenaPoolCnvSvcTest::XCont"
+         id="6AEA6831-8777-4571-8595-95FFF40B171F" />
+  <class name="AthenaPoolCnvSvcTest::XCont_p1"
+         id="421C967C-CB57-4234-A33F-EBE4928036C2" />
+  <class name="AthenaPoolCnvSvcTest::XCont_p2"
+         id="F151C81D-869A-4585-8086-5F8835AB12E1" />
+</lcgdict>
diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/CMakeLists.txt b/Database/AthenaPOOL/AthenaPoolCnvSvc/CMakeLists.txt
new file mode 100644
index 00000000000..5a0eea9faa7
--- /dev/null
+++ b/Database/AthenaPOOL/AthenaPoolCnvSvc/CMakeLists.txt
@@ -0,0 +1,105 @@
+# $Id: CMakeLists.txt 733899 2016-04-05 07:43:22Z krasznaa $
+################################################################################
+# Package: AthenaPoolCnvSvc
+################################################################################
+
+# Declare the package name:
+atlas_subdir( AthenaPoolCnvSvc )
+
+# Declare the package's dependencies:
+atlas_depends_on_subdirs(
+   PUBLIC
+   Control/AthContainers
+   Control/AthLinks
+   Control/AthenaBaseComps
+   Control/AthenaKernel
+   Control/CLIDSvc
+   Control/CxxUtils
+   Control/DataModelRoot
+   Control/SGTools
+   Database/APR/CollectionBase
+   Database/APR/CollectionUtilities
+   Database/APR/POOLCore
+   Database/APR/PersistencySvc
+   Database/APR/StorageSvc
+   Database/AthenaPOOL/AthenaPoolUtilities
+   Database/AthenaPOOL/PoolSvc
+   Database/PersistentDataModel
+   Database/TPTools
+   GaudiKernel
+   PRIVATE
+   AtlasTest/TestTools
+   Control/StoreGate )
+
+# External dependencies:
+find_package( Boost )
+find_package( ROOT COMPONENTS Core )
+
+# Component(s) in the package:
+atlas_add_library( AthenaPoolCnvSvcLib
+   AthenaPoolCnvSvc/*.h AthenaPoolCnvSvc/*.icc src/*.cxx
+   PUBLIC_HEADERS AthenaPoolCnvSvc
+   INCLUDE_DIRS ${Boost_INCLUDE_DIRS}
+   PRIVATE_INCLUDE_DIRS ${ROOT_INCLUDE_DIRS}
+   LINK_LIBRARIES ${Boost_LIBRARIES} AthContainers AthLinks AthenaBaseComps
+   AthenaKernel CxxUtils DataModelRoot SGTools CollectionBase
+   CollectionUtilities POOLCore PersistencySvc StorageSvc AthenaPoolUtilities
+   PersistentDataModel TPTools GaudiKernel StoreGateLib
+   PRIVATE_LINK_LIBRARIES ${ROOT_LIBRARIES} )
+
+atlas_add_component( AthenaPoolCnvSvc
+   src/components/*.cxx
+   LINK_LIBRARIES AthenaPoolCnvSvcLib )
+
+atlas_add_dictionary( AthenaPoolCnvSvcTestDict
+   test/AthenaPoolCnvSvcTestDict.h
+   AthenaPoolCnvSvc/selection_test.xml
+   LINK_LIBRARIES AthenaPoolCnvSvcLib
+   NO_ROOTMAP_MERGE )
+
+# Test(s) in the package:
+atlas_add_test( exceptions_test
+   SOURCES test/exceptions_test.cxx
+   LINK_LIBRARIES AthenaPoolCnvSvcLib )
+
+atlas_add_test( TPCnvElt_test
+   SOURCES test/TPCnvElt_test.cxx
+   INCLUDE_DIRS ${ROOT_INCLUDE_DIRS}
+   LINK_LIBRARIES ${ROOT_LIBRARIES} GaudiKernel AthenaPoolCnvSvcLib )
+
+atlas_add_test( TPCnvList_test
+   SOURCES test/TPCnvList_test.cxx
+   INCLUDE_DIRS ${ROOT_INCLUDE_DIRS}
+   LINK_LIBRARIES ${ROOT_LIBRARIES} GaudiKernel AthenaPoolCnvSvcLib )
+
+atlas_add_test( T_AthenaPoolViewVectorCnv_test
+   SOURCES test/T_AthenaPoolViewVectorCnv_test.cxx
+   INCLUDE_DIRS ${ROOT_INCLUDE_DIRS}
+   LINK_LIBRARIES ${ROOT_LIBRARIES} AthContainers AthLinks SGTools GaudiKernel
+   TestTools AthenaPoolCnvSvcLib
+   ENVIRONMENT "JOBOPTSEARCHPATH=${CMAKE_CURRENT_SOURCE_DIR}/share" )
+
+atlas_add_test( T_AthenaPoolxAODCnv_test
+   SOURCES test/T_AthenaPoolxAODCnv_test.cxx
+   INCLUDE_DIRS ${ROOT_INCLUDE_DIRS}
+   LINK_LIBRARIES ${ROOT_LIBRARIES} PersistentDataModel SGTools TestTools
+   CxxUtils AthenaPoolCnvSvcLib
+   ENVIRONMENT "JOBOPTSEARCHPATH=${CMAKE_CURRENT_SOURCE_DIR}/share" )
+
+atlas_add_test( T_AthenaPoolAuxContainerCnv_test
+   SOURCES test/T_AthenaPoolAuxContainerCnv_test.cxx
+   INCLUDE_DIRS ${ROOT_INCLUDE_DIRS}
+   LINK_LIBRARIES ${ROOT_LIBRARIES} PersistentDataModel AthContainers SGTools
+   TestTools CxxUtils AthenaPoolCnvSvcLib
+   ENVIRONMENT "JOBOPTSEARCHPATH=${CMAKE_CURRENT_SOURCE_DIR}/share" )
+
+atlas_add_test( T_AthenaPoolTPCnvCnv_test
+   SOURCES test/T_AthenaPoolTPCnvCnv_test.cxx
+   INCLUDE_DIRS ${ROOT_INCLUDE_DIRS}
+   LINK_LIBRARIES ${ROOT_LIBRARIES} PersistentDataModel SGTools TestTools
+   CxxUtils AthenaPoolCnvSvcLib
+   ENVIRONMENT "JOBOPTSEARCHPATH=${CMAKE_CURRENT_SOURCE_DIR}/share" )
+
+# Install files from the package:
+atlas_install_python_modules( python/*.py )
+atlas_install_joboptions( share/*.py )
diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/cmt/requirements b/Database/AthenaPOOL/AthenaPoolCnvSvc/cmt/requirements
old mode 100755
new mode 100644
index f3814f75f43..5305d6ce6f8
--- a/Database/AthenaPOOL/AthenaPoolCnvSvc/cmt/requirements
+++ b/Database/AthenaPOOL/AthenaPoolCnvSvc/cmt/requirements
@@ -4,12 +4,17 @@ author Peter Van Gemmeren <gemmeren@bnl.gov>
 
 use AtlasPolicy           AtlasPolicy-*
 use AtlasPOOL             AtlasPOOL-*           External
+use AtlasROOT             AtlasROOT-*           External 
 use GaudiInterface        GaudiInterface-*      External
+use AtlasBoost            AtlasBoost-*          External
+use CxxUtils              CxxUtils-*            Control
 use AthenaBaseComps       AthenaBaseComps-*     Control
+use AthenaKernel          AthenaKernel-*        Control
 use CLIDSvc               CLIDSvc-*             Control
-use DataModel             DataModel-*           Control
 use DataModelRoot         DataModelRoot-*       Control
 use SGTools               SGTools-*             Control
+use AthContainers         AthContainers-*       Control
+use AthLinks              AthLinks-*            Control
 use PersistentDataModel   PersistentDataModel-* Database
 use AthenaPoolUtilities   AthenaPoolUtilities-* Database/AthenaPOOL
 use PoolSvc               PoolSvc-*             Database/AthenaPOOL
@@ -27,9 +32,26 @@ apply_pattern declare_python_modules files="*.py"
 set POOL_AUTH_PATH "${AthenaPoolCnvSvc_root}/share"
 
 private
-use AthenaKernel          AthenaKernel-*        Control
 use StoreGate             StoreGate-*           Control
 
 private
 apply_tag ROOTSTLDictLibs
 
+
+private 
+
+# Dictionary entries used by the unit tests.
+# Use no_rootmap so that they're not visible to other packages.
+use AtlasReflex  AtlasReflex-*  External  -no_auto_imports
+apply_tag no_rootmap
+apply_pattern lcgdict dict=AthenaPoolCnvSvcTest selectionfile=selection_test.xml\
+  headerfiles="../test/AthenaPoolCnvSvcTestDict.h"
+
+use TestTools      TestTools-*         AtlasTest 
+apply_pattern UnitTest_run unit_test=exceptions
+apply_pattern UnitTest_run unit_test=TPCnvElt
+apply_pattern UnitTest_run unit_test=TPCnvList
+apply_pattern UnitTest_run unit_test=T_AthenaPoolViewVectorCnv
+apply_pattern UnitTest_run unit_test=T_AthenaPoolxAODCnv
+apply_pattern UnitTest_run unit_test=T_AthenaPoolAuxContainerCnv
+apply_pattern UnitTest_run unit_test=T_AthenaPoolTPCnvCnv
diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/doc/MainPage.h b/Database/AthenaPOOL/AthenaPoolCnvSvc/doc/MainPage.h
old mode 100755
new mode 100644
diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/python/AthenaPool.py b/Database/AthenaPOOL/AthenaPoolCnvSvc/python/AthenaPool.py
old mode 100755
new mode 100644
diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/python/ReadAthenaPool.py b/Database/AthenaPOOL/AthenaPoolCnvSvc/python/ReadAthenaPool.py
old mode 100755
new mode 100644
index 20436037b4d..1f7f00c951f
--- a/Database/AthenaPOOL/AthenaPoolCnvSvc/python/ReadAthenaPool.py
+++ b/Database/AthenaPOOL/AthenaPoolCnvSvc/python/ReadAthenaPool.py
@@ -59,6 +59,21 @@ def _configureReadAthenaPool():
     theApp.EvtSel = _n
     del _n
 
+    # For Analysis release use DataHeader satellite and lower heartbeat
+    import os 
+    if "AthAnalysisBase" in os.environ.get('CMTEXTRATAGS',""): 
+        svcMgr.EventSelector.CollectionTree = "POOLContainer/basic"
+        # From Will Buttinger to suppress the event loop heartbeat as it is somewhat I/O hungry for 
+        # no real gain in analysis scenarii 
+        if not hasattr(svcMgr, theApp.EventLoop): 
+            svcMgr += getattr(CfgMgr, theApp.EventLoop)() 
+        evtloop = getattr(svcMgr, theApp.EventLoop) 
+        try: 
+            evtloop.EventPrintoutInterval = 10000 
+        except Exception, err: 
+            msg.info('failed suppressing event loop heartbeat. performances might be sub-par... sorry.') 
+            pass 
+
     # Add in AthenaPoolAddressProviderSvc
     if not hasattr (svcMgr, 'AthenaPoolAddressProviderSvc'):
         svcMgr += CfgMgr.AthenaPoolAddressProviderSvc ("AthenaPoolAddressProviderSvc")
diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/python/WriteAthenaPool.py b/Database/AthenaPOOL/AthenaPoolCnvSvc/python/WriteAthenaPool.py
old mode 100755
new mode 100644
diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/python/__init__.py b/Database/AthenaPOOL/AthenaPoolCnvSvc/python/__init__.py
old mode 100755
new mode 100644
diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/share/AthenaPoolCnvSvc_jobOptions.py b/Database/AthenaPOOL/AthenaPoolCnvSvc/share/AthenaPoolCnvSvc_jobOptions.py
old mode 100755
new mode 100644
diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/share/AthenaPool_jobOptions.py b/Database/AthenaPOOL/AthenaPoolCnvSvc/share/AthenaPool_jobOptions.py
old mode 100755
new mode 100644
diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/share/ReadAthenaPool_jobOptions.py b/Database/AthenaPOOL/AthenaPoolCnvSvc/share/ReadAthenaPool_jobOptions.py
old mode 100755
new mode 100644
diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/share/TPCnvElt_test.ref b/Database/AthenaPOOL/AthenaPoolCnvSvc/share/TPCnvElt_test.ref
new file mode 100644
index 00000000000..bae42c55f9e
--- /dev/null
+++ b/Database/AthenaPOOL/AthenaPoolCnvSvc/share/TPCnvElt_test.ref
@@ -0,0 +1,2 @@
+test1
+test2
diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/share/TPCnvList_test.ref b/Database/AthenaPOOL/AthenaPoolCnvSvc/share/TPCnvList_test.ref
new file mode 100644
index 00000000000..a5bce3fd256
--- /dev/null
+++ b/Database/AthenaPOOL/AthenaPoolCnvSvc/share/TPCnvList_test.ref
@@ -0,0 +1 @@
+test1
diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/share/T_AthenaPoolAuxContainerCnv_test.ref b/Database/AthenaPOOL/AthenaPoolCnvSvc/share/T_AthenaPoolAuxContainerCnv_test.ref
new file mode 100644
index 00000000000..3185ff4fc67
--- /dev/null
+++ b/Database/AthenaPOOL/AthenaPoolCnvSvc/share/T_AthenaPoolAuxContainerCnv_test.ref
@@ -0,0 +1,20 @@
+
+
+Initializing Gaudi ApplicationMgr using job opts ../share/test.txt
+JobOptionsSvc        INFO Job options successfully read in from ../share/test.txt
+ApplicationMgr    SUCCESS 
+====================================================================================================================================
+                                                   Welcome to ApplicationMgr (GaudiCoreSvc v999r999)
+                                          running on karma on Thu Jan 21 14:08:47 2016
+====================================================================================================================================
+ApplicationMgr       INFO Application Manager Configured successfully
+EventLoopMgr      WARNING Unable to locate service "EventSelector" 
+EventLoopMgr      WARNING No events will be processed from external input.
+HistogramPersis...WARNING Histograms saving not required.
+ApplicationMgr       INFO Application Manager Initialized successfully
+ApplicationMgr Ready
+test1
+test2
+AthenaPoolConve...  ERROR Failed to convert persistent object to transient: AthenaPoolCnvSvc::::ExcUnsupported version: Unsupported persistent version of AthenaPoolCnvSvcTest::YAuxCont_v2 found; guid: 8ACD1C53-D3C7-4FE5-9BC0-E388701DB8FA
+AthenaPoolConve...  ERROR createObj PoolToDataObject() failed, Token = [DB=00000000-0000-0000-0000-000000000000][CNT=][CLID=8ACD1C53-D3C7-4FE5-9BC0-E388701DB8FA][TECH=00000000][OID=FFFFFFFFFFFFFFFF-FFFFFFFFFFFFFFFF]
+AthenaPoolConve...  ERROR createObj failed to get DataObject, Token = [DB=00000000-0000-0000-0000-000000000000][CNT=][CLID=8ACD1C53-D3C7-4FE5-9BC0-E388701DB8FA][TECH=00000000][OID=FFFFFFFFFFFFFFFF-FFFFFFFFFFFFFFFF]
diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/share/T_AthenaPoolTPCnvCnv_test.ref b/Database/AthenaPOOL/AthenaPoolCnvSvc/share/T_AthenaPoolTPCnvCnv_test.ref
new file mode 100644
index 00000000000..cabfcb0f73c
--- /dev/null
+++ b/Database/AthenaPOOL/AthenaPoolCnvSvc/share/T_AthenaPoolTPCnvCnv_test.ref
@@ -0,0 +1,20 @@
+
+
+Initializing Gaudi ApplicationMgr using job opts ../share/test.txt
+JobOptionsSvc        INFO Job options successfully read in from ../share/test.txt
+ApplicationMgr    SUCCESS 
+====================================================================================================================================
+                                                   Welcome to ApplicationMgr (GaudiCoreSvc v999r999)
+                                          running on karma on Fri Jan 22 14:26:54 2016
+====================================================================================================================================
+ApplicationMgr       INFO Application Manager Configured successfully
+EventLoopMgr      WARNING Unable to locate service "EventSelector" 
+EventLoopMgr      WARNING No events will be processed from external input.
+HistogramPersis...WARNING Histograms saving not required.
+ApplicationMgr       INFO Application Manager Initialized successfully
+ApplicationMgr Ready
+test1
+test2
+AthenaPoolConve...  ERROR Failed to convert persistent object to transient: AthenaPoolCnvSvc::::ExcUnsupported version: Unsupported persistent version of DataVector<AthenaPoolCnvSvcTest::X,DataModel_detail::NoBase> found; guid: 8ACD1C53-D3C7-4FE5-9BC0-E388701DB8FA
+AthenaPoolConve...  ERROR createObj PoolToDataObject() failed, Token = [DB=00000000-0000-0000-0000-000000000000][CNT=][CLID=8ACD1C53-D3C7-4FE5-9BC0-E388701DB8FA][TECH=00000000][OID=FFFFFFFFFFFFFFFF-FFFFFFFFFFFFFFFF]
+AthenaPoolConve...  ERROR createObj failed to get DataObject, Token = [DB=00000000-0000-0000-0000-000000000000][CNT=][CLID=8ACD1C53-D3C7-4FE5-9BC0-E388701DB8FA][TECH=00000000][OID=FFFFFFFFFFFFFFFF-FFFFFFFFFFFFFFFF]
diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/share/T_AthenaPoolViewVectorCnv_test.ref b/Database/AthenaPOOL/AthenaPoolCnvSvc/share/T_AthenaPoolViewVectorCnv_test.ref
new file mode 100644
index 00000000000..f4f98f093a9
--- /dev/null
+++ b/Database/AthenaPOOL/AthenaPoolCnvSvc/share/T_AthenaPoolViewVectorCnv_test.ref
@@ -0,0 +1,20 @@
+
+
+Initializing Gaudi ApplicationMgr using job opts ../share/test.txt
+JobOptionsSvc        INFO Job options successfully read in from ../share/test.txt
+ApplicationMgr    SUCCESS 
+====================================================================================================================================
+                                                   Welcome to ApplicationMgr (GaudiCoreSvc v999r999)
+                                          running on karma on Wed Jan 20 12:20:45 2016
+====================================================================================================================================
+ApplicationMgr       INFO Application Manager Configured successfully
+EventLoopMgr      WARNING Unable to locate service "EventSelector" 
+EventLoopMgr      WARNING No events will be processed from external input.
+HistogramPersis...WARNING Histograms saving not required.
+ApplicationMgr       INFO Application Manager Initialized successfully
+ApplicationMgr Ready
+test1
+AthenaPoolConve...  ERROR Failed to convert persistent object to transient: AthenaPoolCnvSvc::::ExcUnsupported version: Unsupported persistent version of std::vector<ElementLink<DataVector<AthenaPoolCnvSvcTest::Y_v2,DataModel_detail::NoBase> >,std::allocator<ElementLink<DataVector<AthenaPoolCnvSvcTest::Y_v2,DataModel_detail::NoBase> > > > found; guid: 79E2478D-C17F-45E9-848D-278240C2FED3
+AthenaPoolConve...  ERROR createObj PoolToDataObject() failed, Token = [DB=00000000-0000-0000-0000-000000000000][CNT=][CLID=79E2478D-C17F-45E9-848D-278240C2FED3][TECH=00000000][OID=FFFFFFFFFFFFFFFF-FFFFFFFFFFFFFFFF]
+AthenaPoolConve...  ERROR createObj failed to get DataObject, Token = [DB=00000000-0000-0000-0000-000000000000][CNT=][CLID=79E2478D-C17F-45E9-848D-278240C2FED3][TECH=00000000][OID=FFFFFFFFFFFFFFFF-FFFFFFFFFFFFFFFF]
+test2
diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/share/T_AthenaPoolxAODCnv_test.ref b/Database/AthenaPOOL/AthenaPoolCnvSvc/share/T_AthenaPoolxAODCnv_test.ref
new file mode 100644
index 00000000000..eb58bc43dba
--- /dev/null
+++ b/Database/AthenaPOOL/AthenaPoolCnvSvc/share/T_AthenaPoolxAODCnv_test.ref
@@ -0,0 +1,19 @@
+
+
+Initializing Gaudi ApplicationMgr using job opts ../share/test.txt
+JobOptionsSvc        INFO Job options successfully read in from ../share/test.txt
+ApplicationMgr    SUCCESS 
+====================================================================================================================================
+                                                   Welcome to ApplicationMgr (GaudiCoreSvc v999r999)
+                                          running on karma on Wed Jan 20 17:09:50 2016
+====================================================================================================================================
+ApplicationMgr       INFO Application Manager Configured successfully
+EventLoopMgr      WARNING Unable to locate service "EventSelector" 
+EventLoopMgr      WARNING No events will be processed from external input.
+HistogramPersis...WARNING Histograms saving not required.
+ApplicationMgr       INFO Application Manager Initialized successfully
+ApplicationMgr Ready
+test1
+AthenaPoolConve...  ERROR Failed to convert persistent object to transient: AthenaPoolCnvSvc::::ExcUnsupported version: Unsupported persistent version of DataVector<AthenaPoolCnvSvcTest::Y_v2,DataModel_detail::NoBase> found; guid: 8ACD1C53-D3C7-4FE5-9BC0-E388701DB8FA
+AthenaPoolConve...  ERROR createObj PoolToDataObject() failed, Token = [DB=00000000-0000-0000-0000-000000000000][CNT=][CLID=8ACD1C53-D3C7-4FE5-9BC0-E388701DB8FA][TECH=00000000][OID=FFFFFFFFFFFFFFFF-FFFFFFFFFFFFFFFF]
+AthenaPoolConve...  ERROR createObj failed to get DataObject, Token = [DB=00000000-0000-0000-0000-000000000000][CNT=][CLID=8ACD1C53-D3C7-4FE5-9BC0-E388701DB8FA][TECH=00000000][OID=FFFFFFFFFFFFFFFF-FFFFFFFFFFFFFFFF]
diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/share/WriteAthenaPool_jobOptions.py b/Database/AthenaPOOL/AthenaPoolCnvSvc/share/WriteAthenaPool_jobOptions.py
old mode 100755
new mode 100644
diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/share/exceptions_test.ref b/Database/AthenaPOOL/AthenaPoolCnvSvc/share/exceptions_test.ref
new file mode 100644
index 00000000000..8809968d624
--- /dev/null
+++ b/Database/AthenaPOOL/AthenaPoolCnvSvc/share/exceptions_test.ref
@@ -0,0 +1,3 @@
+test1
+AthenaPoolCnvSvc::::ExcNoDictForClass: Can't find dictionary information for class: int
+AthenaPoolCnvSvc::::ExcUnsupported version: Unsupported persistent version of int found; guid: 336F636C-D414-4261-8286-37429F353F0A
diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/share/test.txt b/Database/AthenaPOOL/AthenaPoolCnvSvc/share/test.txt
new file mode 100644
index 00000000000..8b137891791
--- /dev/null
+++ b/Database/AthenaPOOL/AthenaPoolCnvSvc/share/test.txt
@@ -0,0 +1 @@
+
diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/src/AthenaAttributeListCnv.cxx b/Database/AthenaPOOL/AthenaPoolCnvSvc/src/AthenaAttributeListCnv.cxx
old mode 100755
new mode 100644
diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/src/AthenaAttributeListCnv.h b/Database/AthenaPOOL/AthenaPoolCnvSvc/src/AthenaAttributeListCnv.h
old mode 100755
new mode 100644
diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/src/AthenaPoolCnvSvc.cxx b/Database/AthenaPOOL/AthenaPoolCnvSvc/src/AthenaPoolCnvSvc.cxx
old mode 100755
new mode 100644
index 7a832a36cb9..459580fa1c3
--- a/Database/AthenaPOOL/AthenaPoolCnvSvc/src/AthenaPoolCnvSvc.cxx
+++ b/Database/AthenaPOOL/AthenaPoolCnvSvc/src/AthenaPoolCnvSvc.cxx
@@ -14,11 +14,13 @@
 #include "GaudiKernel/IOpaqueAddress.h"
 #include "GaudiKernel/IJobOptionsSvc.h"
 #include "GaudiKernel/IIncidentSvc.h"
-#include "GaudiKernel/Tokenizer.h"
+#include "GaudiKernel/AttribStringParser.h"
 
 #include "AthenaKernel/IAthenaIPCTool.h"
+#include "AthenaKernel/IAthenaSerializeSvc.h"
 #include "AthenaKernel/IClassIDSvc.h"
 #include "AthenaKernel/IAthenaOutputStreamTool.h"
+#include "PersistentDataModel/Placement.h"
 #include "PersistentDataModel/Token.h"
 #include "PersistentDataModel/TokenAddress.h"
 #include "PoolSvc/IPoolSvc.h"
@@ -64,10 +66,26 @@ StatusCode AthenaPoolCnvSvc::initialize() {
       ATH_MSG_FATAL("Cannot get ClassIDSvc.");
       return(StatusCode::FAILURE);
    }
-   // Retrieve DataStreamingTool (if configured)
-   if (!m_dataStreamingTool.empty() && !m_dataStreamingTool.retrieve().isSuccess()) {
-      ATH_MSG_FATAL("Cannot get AthenaIPCTool");
-      return(StatusCode::FAILURE);
+   // Retrieve InputStreamingTool (if configured)
+   if (!m_inputStreamingTool.empty()) {
+      if (!m_inputStreamingTool.retrieve().isSuccess()) {
+         ATH_MSG_FATAL("Cannot get Input AthenaIPCTool");
+         return(StatusCode::FAILURE);
+      }
+   }
+   // Retrieve OutputStreamingTool (if configured)
+   if (!m_outputStreamingTool.empty()) {
+      if (!m_outputStreamingTool.retrieve().isSuccess()) {
+         ATH_MSG_FATAL("Cannot get Output AthenaIPCTool");
+         return(StatusCode::FAILURE);
+      }
+   }
+   if (!m_inputStreamingTool.empty() || !m_outputStreamingTool.empty()) {
+      // Retrieve AthenaSerializeSvc
+      if (!m_serializeSvc.retrieve().isSuccess()) {
+         ATH_MSG_FATAL("Cannot get AthenaSerializeSvc.");
+         return(StatusCode::FAILURE);
+      }
    }
    // Extracting MaxFileSizes for global default and map by Database name.
    for (std::vector<std::string>::const_iterator iter = m_maxFileSizes.value().begin(),
@@ -113,9 +131,23 @@ StatusCode AthenaPoolCnvSvc::initialize() {
 }
 //______________________________________________________________________________
 StatusCode AthenaPoolCnvSvc::finalize() {
-   // Retrieve DataStreamingTool (if configured)
-   if (!m_dataStreamingTool.empty() && !m_dataStreamingTool.release().isSuccess()) {
-      ATH_MSG_WARNING("Cannot release AthenaIPCTool.");
+   // Release AthenaSerializeSvc
+   if (!m_serializeSvc.empty()) {
+      if (!m_serializeSvc.release().isSuccess()) {
+         ATH_MSG_WARNING("Cannot release AthenaSerializeSvc.");
+      }
+   }
+   // Release OutputStreamingTool (if configured)
+   if (!m_outputStreamingTool.empty()) {
+      if (!m_outputStreamingTool.release().isSuccess()) {
+         ATH_MSG_WARNING("Cannot release Output AthenaIPCTool.");
+      }
+   }
+   // Release InputStreamingTool (if configured)
+   if (!m_inputStreamingTool.empty()) {
+      if (!m_inputStreamingTool.release().isSuccess()) {
+         ATH_MSG_WARNING("Cannot release Input AthenaIPCTool.");
+      }
    }
    // Release ClassIDSvc
    if (!m_clidSvc.release().isSuccess()) {
@@ -147,6 +179,10 @@ StatusCode AthenaPoolCnvSvc::queryInterface(const InterfaceID& riid, void** ppvI
 }
 //______________________________________________________________________________
 StatusCode AthenaPoolCnvSvc::createObj(IOpaqueAddress* pAddress, DataObject*& refpObject) {
+#ifdef ATHENAHIVE  
+  std::lock_guard<CallMutex> lock(m_i_mut);
+#endif
+
    assert(pAddress);
    if (m_useDetailChronoStat.value() && m_doChronoStat) {
       std::string objName, keyName = "#" + *(pAddress->par() + 1);
@@ -175,6 +211,9 @@ StatusCode AthenaPoolCnvSvc::createObj(IOpaqueAddress* pAddress, DataObject*& re
 }
 //______________________________________________________________________________
 StatusCode AthenaPoolCnvSvc::createRep(DataObject* pObject, IOpaqueAddress*& refpAddress) {
+#ifdef ATHENAHIVE  
+  std::lock_guard<CallMutex> lock(m_o_mut);
+#endif
    assert(pObject);
    if (m_useDetailChronoStat.value() && m_doChronoStat) {
       std::string objName, keyName = "#" + pObject->registry()->name();
@@ -291,17 +330,14 @@ StatusCode AthenaPoolCnvSvc::connectOutput(const std::string& outputConnectionSp
    }
 
    // Extract the technology
-   StatusCode status = decodeOutputSpec(m_outputConnectionSpec, m_dbType);
-   if (!status.isSuccess()) {
+   if (!decodeOutputSpec(m_outputConnectionSpec, m_dbType).isSuccess()) {
       ATH_MSG_ERROR("connectOutput FAILED extract file name and technology.");
       return(StatusCode::FAILURE);
    }
-   status = processPoolAttributes(m_domainAttr, m_outputConnectionSpec, IPoolSvc::kOutputStream);
-   if (!status.isSuccess()) {
+   if (!processPoolAttributes(m_domainAttr, m_outputConnectionSpec, IPoolSvc::kOutputStream).isSuccess()) {
       ATH_MSG_DEBUG("connectOutput failed process POOL domain attributes.");
    }
-   status = processPoolAttributes(m_databaseAttr, m_outputConnectionSpec, IPoolSvc::kOutputStream);
-   if (!status.isSuccess()) {
+   if (!processPoolAttributes(m_databaseAttr, m_outputConnectionSpec, IPoolSvc::kOutputStream).isSuccess()) {
       ATH_MSG_DEBUG("connectOutput failed process POOL database attributes.");
    }
    return(StatusCode::SUCCESS);
@@ -312,16 +348,13 @@ StatusCode AthenaPoolCnvSvc::commitOutput(const std::string& /*outputConnectionS
    if (m_useDetailChronoStat.value()) {
       m_chronoStatSvc->chronoStart("commitOutput");
    }
-   StatusCode status = processPoolAttributes(m_domainAttr, m_outputConnectionSpec, IPoolSvc::kOutputStream);
-   if (!status.isSuccess()) {
+   if (!processPoolAttributes(m_domainAttr, m_outputConnectionSpec, IPoolSvc::kOutputStream).isSuccess()) {
       ATH_MSG_DEBUG("commitOutput failed process POOL domain attributes.");
    }
-   status = processPoolAttributes(m_databaseAttr, m_outputConnectionSpec, IPoolSvc::kOutputStream);
-   if (!status.isSuccess()) {
+   if (!processPoolAttributes(m_databaseAttr, m_outputConnectionSpec, IPoolSvc::kOutputStream).isSuccess()) {
       ATH_MSG_DEBUG("commitOutput failed process POOL database attributes.");
    }
-   status = processPoolAttributes(m_containerAttr, m_outputConnectionSpec, IPoolSvc::kOutputStream);
-   if (!status.isSuccess()) {
+   if (!processPoolAttributes(m_containerAttr, m_outputConnectionSpec, IPoolSvc::kOutputStream).isSuccess()) {
       ATH_MSG_DEBUG("commitOutput failed process POOL container attributes.");
    }
    static int commitCounter = 1;
@@ -429,7 +462,7 @@ IPoolSvc* AthenaPoolCnvSvc::getPoolSvc() {
    return(&*m_poolSvc);
 }
 //______________________________________________________________________________
-const Token* AthenaPoolCnvSvc::registerForWrite(const pool::Placement* placement,
+const Token* AthenaPoolCnvSvc::registerForWrite(const Placement* placement,
 	const void* obj,
 	const RootType& classDesc) const {
    if (m_useDetailChronoStat.value() && m_doChronoStat) {
@@ -446,21 +479,37 @@ void AthenaPoolCnvSvc::setObjPtr(void*& obj, const Token* token) const {
    if (m_useDetailChronoStat.value() && m_doChronoStat) {
       m_chronoStatSvc->chronoStart("cObjR_" + m_className.back());
    }
-   m_poolSvc->setObjPtr(obj, token, m_contextIds.back());
+   if (!m_inputStreamingTool.empty() && m_inputStreamingTool->isClient()) {
+      ATH_MSG_VERBOSE("Requesting object for: " << token->toString());
+      if (!m_inputStreamingTool->lockObject(token->toString().c_str()).isSuccess()) {
+         ATH_MSG_WARNING("Failed to lock Data for " << token->toString());
+         obj = 0;
+      } else {
+         void* buffer = 0;
+         size_t nbytes = 0;
+         StatusCode sc = m_inputStreamingTool->getObject(&buffer, nbytes);
+         while (sc.isRecoverable()) {
+            usleep(100);
+            sc = m_inputStreamingTool->getObject(&buffer, nbytes);
+         }
+         if (!sc.isSuccess()) {
+            ATH_MSG_WARNING("Failed to get Data for " << token->toString());
+            obj = 0;
+         } else {
+            obj = m_serializeSvc->deserialize(buffer, nbytes, token->classID());
+         }
+      }
+   } else if (!m_inputStreamingTool.empty() && m_inputStreamingTool->isServer()) {
+      // Reading in Server
+      m_poolSvc->setObjPtr(obj, token);
+   } else {
+      m_poolSvc->setObjPtr(obj, token, m_contextIds.back());
+   }
    if (m_useDetailChronoStat.value() && m_doChronoStat) {
       m_chronoStatSvc->chronoStop("cObjR_" + m_className.back());
    }
 }
 //______________________________________________________________________________
-bool AthenaPoolCnvSvc::testDictionary(const std::string& className) const {
-#if ROOT_VERSION_CODE < ROOT_VERSION(5,99,0)
-   return(m_poolSvc->testDictionary(className));
-#else
-   ATH_MSG_DEBUG("Skipping Dictionary check for: " << className);
-   return(true);
-#endif
-}
-//______________________________________________________________________________
 bool AthenaPoolCnvSvc::useDetailChronoStat() const {
    return(m_useDetailChronoStat.value());
 }
@@ -474,7 +523,36 @@ StatusCode AthenaPoolCnvSvc::createAddress(long svcType,
       ATH_MSG_ERROR("createAddress: svcType != POOL_StorageType " << svcType << " " << POOL_StorageType);
       return(StatusCode::FAILURE);
    }
-   Token* token = m_poolSvc->getToken(par[0], par[1], ip[0]);
+   Token* token = 0;
+   if (!m_inputStreamingTool.empty() && m_inputStreamingTool->isClient()) {
+      Token addressToken;
+      addressToken.setDb(par[0].substr(4));
+      addressToken.setCont(par[1]);
+      addressToken.setOid(Token::OID_t(ip[0], ip[1]));
+      if (!m_inputStreamingTool->lockObject(addressToken.toString().c_str()).isSuccess()) {
+         ATH_MSG_WARNING("Failed to lock Address Token: " << addressToken.toString());
+         return(StatusCode::FAILURE);
+      }
+      void* buffer = 0;
+      size_t nbytes = 0;
+      StatusCode sc = m_inputStreamingTool->getObject(&buffer, nbytes);
+      while (sc.isRecoverable()) {
+         usleep(100);
+         sc = m_inputStreamingTool->getObject(&buffer, nbytes);
+      }
+      if (!sc.isSuccess()) {
+         ATH_MSG_WARNING("Failed to get Address Token: " << addressToken.toString());
+         return(StatusCode::FAILURE);
+      } else {
+         token = new Token();
+         token->fromString((char*)buffer);
+         if (token->classID() == Guid::null()) {
+            delete token; token = 0;
+         }
+      }
+   } else {
+      token = m_poolSvc->getToken(par[0], par[1], ip[0]);
+   }
    if (token == 0) {
       return(StatusCode::RECOVERABLE);
    }
@@ -521,21 +599,106 @@ StatusCode AthenaPoolCnvSvc::cleanUp() {
 StatusCode AthenaPoolCnvSvc::setInputAttributes(const std::string& fileName) {
    // Set attributes for input file
    m_lastFileName = fileName; // Save file name for printing attributes per event
-   StatusCode status = processPoolAttributes(m_inputAttr, m_lastFileName, IPoolSvc::kInputStream, false, true, false);
-   if (!status.isSuccess()) {
+   if (!processPoolAttributes(m_inputAttr, m_lastFileName, IPoolSvc::kInputStream, false, true, false).isSuccess()) {
       ATH_MSG_DEBUG("setInputAttribute failed setting POOL database/container attributes.");
    }
-   status = processPoolAttributes(m_inputAttr, m_lastFileName, IPoolSvc::kInputStream, true, false);
-   if (!status.isSuccess()) {
+   if (!processPoolAttributes(m_inputAttr, m_lastFileName, IPoolSvc::kInputStream, true, false).isSuccess()) {
       ATH_MSG_DEBUG("setInputAttribute failed getting POOL database/container attributes.");
    }
    return(StatusCode::SUCCESS);
 }
 //______________________________________________________________________________
+StatusCode AthenaPoolCnvSvc::makeServer(int num) {
+   if (!m_outputStreamingTool.empty() && !m_outputStreamingTool->isServer()) {
+      ATH_MSG_DEBUG("makeServer: " << m_outputStreamingTool << " = " << num);
+      if (m_outputStreamingTool->makeServer(num).isFailure()) {
+         ATH_MSG_ERROR("makeServer: " << m_outputStreamingTool << " failed");
+         return(StatusCode::FAILURE);
+      }
+   }
+   if (m_inputStreamingTool.empty()) {
+      return(StatusCode::RECOVERABLE);
+   }
+   m_doChronoStat = false;
+   ATH_MSG_DEBUG("makeServer: " << m_inputStreamingTool << " = " << num);
+   return(m_inputStreamingTool->makeServer(num));
+}
+//________________________________________________________________________________
+StatusCode AthenaPoolCnvSvc::makeClient(int num) {
+   m_doChronoStat = false;
+   if (!m_outputStreamingTool.empty() && !m_outputStreamingTool->isClient() && num > 0) {
+      ATH_MSG_DEBUG("makeClient: " << m_outputStreamingTool << " = " << num);
+      if (m_outputStreamingTool->makeClient(num).isFailure()) {
+         ATH_MSG_ERROR("makeClient: " << m_outputStreamingTool << " failed");
+         return(StatusCode::FAILURE);
+      }
+   }
+   if (m_inputStreamingTool.empty()) {
+      return(StatusCode::RECOVERABLE);
+   }
+   ATH_MSG_DEBUG("makeClient: " << m_inputStreamingTool << " = " << num);
+   return(m_inputStreamingTool->makeClient(num));
+}
+//________________________________________________________________________________
+StatusCode AthenaPoolCnvSvc::readData() const {
+   if (m_inputStreamingTool.empty()) {
+      return(StatusCode::FAILURE);
+   }
+   char* tokenStr = 0;
+   int num = -1;
+   StatusCode sc = m_inputStreamingTool->clearObject(&tokenStr, num);
+   if (sc.isSuccess() && tokenStr != 0 && strlen(tokenStr) > 0 && num > 0) {
+      ATH_MSG_DEBUG("readData: " << tokenStr << ", for client: " << num);
+   } else {
+      delete tokenStr; tokenStr = 0;
+      return(sc);
+   }
+   // Read object instance via POOL/ROOT
+   void* instance = 0;
+   Token token;
+   token.fromString(tokenStr);
+   delete tokenStr; tokenStr = 0;
+   if (token.classID() != Guid::null()) {
+      this->setObjPtr(instance, &token);
+      // Serialize object via ROOT
+      void* buffer = 0;
+      size_t nbytes = 0;
+      buffer = m_serializeSvc->serialize(instance, token.classID(), nbytes);
+      // Share object
+      sc = m_inputStreamingTool->putObject(buffer, nbytes, num);
+      delete [] (char*)buffer; buffer = 0;
+      if (!sc.isSuccess()) {
+         ATH_MSG_ERROR("Could not share object for: " << token.toString());
+         return(StatusCode::FAILURE);
+      }
+   } else if (token.dbID() != Guid::null()) {
+      std::string returnToken;
+      const Token* metadataToken = m_poolSvc->getToken("FID:" + token.dbID().toString(), token.contID(), token.oid().first);
+      if (metadataToken != 0) {
+         returnToken = metadataToken->toString();
+      } else {
+         returnToken = token.toString();
+      }
+      delete metadataToken; metadataToken = 0;
+      // Share token
+      sc = m_inputStreamingTool->putObject(returnToken.c_str(), returnToken.size() + 1, num);
+      while (sc.isRecoverable()) {
+         usleep(100);
+         sc = m_inputStreamingTool->putObject(returnToken.c_str(), returnToken.size() + 1, num);
+      }
+      if (!sc.isSuccess()) {
+         ATH_MSG_ERROR("Could not share token for: " << token.toString());
+         return(StatusCode::FAILURE);
+      }
+   } else {
+      return(StatusCode::RECOVERABLE);
+   }
+   return(StatusCode::SUCCESS);
+}
+//______________________________________________________________________________
 void AthenaPoolCnvSvc::handle(const Incident& incident) {
    if (incident.type() == "EndEvent") {
-      StatusCode status = processPoolAttributes(m_inputAttrPerEvent, m_lastFileName, IPoolSvc::kInputStream);
-      if (!status.isSuccess()) {
+      if (!processPoolAttributes(m_inputAttrPerEvent, m_lastFileName, IPoolSvc::kInputStream).isSuccess()) {
          ATH_MSG_DEBUG("handle EndEvent failed process POOL database attributes.");
       }
    }
@@ -552,7 +715,9 @@ AthenaPoolCnvSvc::AthenaPoolCnvSvc(const std::string& name, ISvcLocator* pSvcLoc
 	m_poolSvc("PoolSvc", name),
 	m_chronoStatSvc("ChronoStatSvc", name),
 	m_clidSvc("ClassIDSvc", name),
-	m_dataStreamingTool("", this),
+	m_serializeSvc("AthenaRootSerializeSvc", name),
+	m_inputStreamingTool("", this),
+	m_outputStreamingTool("", this),
 	m_containerPrefix(),
 	m_containerNameHint(),
 	m_branchNameHint(),
@@ -568,6 +733,8 @@ AthenaPoolCnvSvc::AthenaPoolCnvSvc(const std::string& name, ISvcLocator* pSvcLoc
    declareProperty("MaxFileSizes", m_maxFileSizes);
    declareProperty("CommitInterval", m_commitInterval = 0);
    declareProperty("SkipFirstChronoCommit", m_skipFirstChronoCommit = false);
+   declareProperty("InputStreamingTool", m_inputStreamingTool);
+   declareProperty("OutputStreamingTool", m_outputStreamingTool);
 }
 //______________________________________________________________________________
 AthenaPoolCnvSvc::~AthenaPoolCnvSvc() {
@@ -592,22 +759,19 @@ void AthenaPoolCnvSvc::extractPoolAttributes(const StringArrayProperty& property
 	std::vector<std::vector<std::string> >* contAttr,
 	std::vector<std::vector<std::string> >* dbAttr,
 	std::vector<std::vector<std::string> >* domAttr) const {
-   Tokenizer tok;
    std::vector<std::string> opt;
    std::string attributeName, containerName, databaseName, valueString;
    for (std::vector<std::string>::const_iterator iter = property.value().begin(),
            last = property.value().end(); iter != last; iter++) {
-      tok.analyse(*iter, " ", "", "", "=", "'", "'");
       opt.clear();
       attributeName.clear();
       containerName.clear();
       databaseName.clear();
       valueString.clear();
-      for (Tokenizer::Items::iterator i = tok.items().begin(), iEnd = tok.items().end(); i != iEnd; i++) {
-         const size_t tagBegin = (*i).tag().find_first_not_of(" 	;");
-         const size_t tagEnd = (*i).tag().find_last_not_of(" 	;");
-         const std::string tag = (*i).tag().substr(tagBegin, tagEnd - tagBegin + 1);
-         const std::string val = (*i).value();
+      using Gaudi::Utils::AttribStringParser;
+      for (const AttribStringParser::Attrib& attrib : AttribStringParser (*iter)) {
+         const std::string tag = attrib.tag;
+         const std::string val = attrib.value;
          if (tag == "DatabaseName") {
             databaseName = val;
          } else if (tag == "ContainerName") {
@@ -654,6 +818,7 @@ StatusCode AthenaPoolCnvSvc::processPoolAttributes(std::vector<std::vector<std::
 	bool doSet,
 	bool doClear) const {
    bool retError = false;
+   if (!m_inputStreamingTool.empty() && m_inputStreamingTool->isClient()) doGet = false;
    for (std::vector<std::vector<std::string> >::iterator iter = attr.begin(), last = attr.end();
 		   iter != last; ++iter) {
       if (iter->size() == 2) {
@@ -661,15 +826,13 @@ StatusCode AthenaPoolCnvSvc::processPoolAttributes(std::vector<std::vector<std::
          std::string data = (*iter)[1];
          if (data == "int" || data == "DbLonglong" || data == "double" || data == "string") {
             if (doGet) {
-               StatusCode status = m_poolSvc->getAttribute(opt, data, m_dbType.type(), contextId);
-               if (!status.isSuccess()) {
+               if (!m_poolSvc->getAttribute(opt, data, m_dbType.type(), contextId).isSuccess()) {
                   ATH_MSG_DEBUG("getAttribute failed for domain attr " << opt);
                   retError = true;
                }
             }
          } else if (doSet) {
-            StatusCode status = m_poolSvc->setAttribute(opt, data, m_dbType.type(), contextId);
-            if (status.isSuccess()) {
+            if (m_poolSvc->setAttribute(opt, data, m_dbType.type(), contextId).isSuccess()) {
                ATH_MSG_DEBUG("setAttribute " << opt << " to " << data);
                if (doClear) {
                   iter->clear();
@@ -689,15 +852,13 @@ StatusCode AthenaPoolCnvSvc::processPoolAttributes(std::vector<std::vector<std::
 		         && file.find("," + fileName + ",") == std::string::npos))) {
             if (data == "int" || data == "DbLonglong" || data == "double" || data == "string") {
                if (doGet) {
-                  StatusCode status = m_poolSvc->getAttribute(opt, data, m_dbType.type(), fileName, cont, contextId);
-                  if (!status.isSuccess()) {
+                  if (!m_poolSvc->getAttribute(opt, data, m_dbType.type(), fileName, cont, contextId).isSuccess()) {
                      ATH_MSG_DEBUG("getAttribute failed for database/container attr " << opt);
                      retError = true;
                   }
                }
             } else if (doSet) {
-               StatusCode status = m_poolSvc->setAttribute(opt, data, m_dbType.type(), fileName, cont, contextId);
-               if (status.isSuccess()) {
+               if (m_poolSvc->setAttribute(opt, data, m_dbType.type(), fileName, cont, contextId).isSuccess()) {
                   ATH_MSG_DEBUG("setAttribute " << opt << " to " << data << " for db: " << fileName << " and cont: " << cont);
                   if (doClear) {
                      if (file.substr(0, 1) == "*") {
diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/src/AthenaPoolCnvSvc.h b/Database/AthenaPOOL/AthenaPoolCnvSvc/src/AthenaPoolCnvSvc.h
old mode 100755
new mode 100644
index 5b18c00f40e..97b0c566581
--- a/Database/AthenaPOOL/AthenaPoolCnvSvc/src/AthenaPoolCnvSvc.h
+++ b/Database/AthenaPOOL/AthenaPoolCnvSvc/src/AthenaPoolCnvSvc.h
@@ -20,9 +20,11 @@
 
 #include <vector>
 #include <map>
+#include <mutex>
 
 // Forward declarations
 class IAthenaIPCTool;
+class IAthenaSerializeSvc;
 class IChronoStatSvc;
 class IClassIDSvc;
 class IPoolSvc;
@@ -95,7 +97,7 @@ public:
    /// @param placement [IN] pointer to the placement hint
    /// @param obj [IN] pointer to the Data Object to be written to Pool
    /// @param classDesc [IN] pointer to the Seal class description for the Data Object.
-   const Token* registerForWrite(const pool::Placement* placement,
+   const Token* registerForWrite(const Placement* placement,
 	   const void* obj,
 	   const RootType& classDesc) const;
 
@@ -103,10 +105,6 @@ public:
    /// @param token [IN] string token of the Data Object for which a Pool Ref is filled.
    void setObjPtr(void*& obj, const Token* token) const;
 
-   /// Utility to test whether the dictionary knows about a given class.
-   /// @param className [IN] string containing the name of the class to be checked.
-   bool testDictionary(const std::string& className) const;
-
    /// @return a boolean for using detailed time and size statistics.
    bool useDetailChronoStat() const;
 
@@ -147,6 +145,15 @@ public:
    /// @param fileName [IN] name of the input file
    StatusCode setInputAttributes(const std::string& fileName);
 
+   /// Make this a server.
+   virtual StatusCode makeServer(int num);
+
+   /// Make this a client.
+   virtual StatusCode makeClient(int num);
+
+   /// Read the next data object
+   virtual StatusCode readData() const;
+
    /// Implementation of IIncidentListener: Handle for EndEvent incidence
    void handle(const Incident& incident);
 
@@ -185,7 +192,9 @@ private: // data
    ServiceHandle<IPoolSvc>       m_poolSvc;
    ServiceHandle<IChronoStatSvc> m_chronoStatSvc;
    ServiceHandle<IClassIDSvc>    m_clidSvc;
-   ToolHandle<IAthenaIPCTool>    m_dataStreamingTool;
+   ServiceHandle<IAthenaSerializeSvc> m_serializeSvc;
+   ToolHandle<IAthenaIPCTool>    m_inputStreamingTool;
+   ToolHandle<IAthenaIPCTool>    m_outputStreamingTool;
 
 private: // properties
    /// UseDetailChronoStat, enable detailed output for time and size statistics for AthenaPOOL:
@@ -231,6 +240,12 @@ private: // properties
 
    /// pool connection context
    std::vector<unsigned long> m_contextIds;
+
+#ifdef ATHENAHIVE
+  typedef std::recursive_mutex CallMutex;
+  mutable CallMutex m_i_mut;
+  mutable CallMutex m_o_mut;
+#endif
 };
 
 #endif
diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/src/AthenaPoolConverter.cxx b/Database/AthenaPOOL/AthenaPoolCnvSvc/src/AthenaPoolConverter.cxx
old mode 100755
new mode 100644
index ea9850e4175..68b75513f46
--- a/Database/AthenaPOOL/AthenaPoolCnvSvc/src/AthenaPoolConverter.cxx
+++ b/Database/AthenaPOOL/AthenaPoolCnvSvc/src/AthenaPoolConverter.cxx
@@ -12,11 +12,11 @@
 
 #include "SGTools/DataProxy.h"
 
-#include "PersistencySvc/Placement.h"
 #include "PersistentDataModel/Guid.h"
 namespace pool {
    typedef ::Guid Guid;
 }
+#include "PersistentDataModel/Placement.h"
 #include "PersistentDataModel/Token.h"
 #include "PersistentDataModel/TokenAddress.h"
 #include "StorageSvc/DbType.h"
@@ -24,6 +24,8 @@ namespace pool {
 //__________________________________________________________________________
 AthenaPoolConverter::~AthenaPoolConverter() {
    delete m_placement; m_placement = 0;
+   delete m_i_poolToken; m_i_poolToken = 0;
+   delete m_o_poolToken; m_o_poolToken = 0;
 }
 //__________________________________________________________________________
 StatusCode AthenaPoolConverter::initialize() {
@@ -54,44 +56,40 @@ long AthenaPoolConverter::repSvcType() const {
 StatusCode AthenaPoolConverter::createObj(IOpaqueAddress* pAddr, DataObject*& pObj) {
    TokenAddress* tokAddr = dynamic_cast<TokenAddress*>(pAddr);
    if (tokAddr == 0 || tokAddr->getToken() == 0) {
-      if (m_poolToken == 0) m_poolToken = new Token;
-      const_cast<Token*>(m_poolToken)->fromString(*(pAddr->par()));
+      if (m_i_poolToken == 0) m_i_poolToken = new Token;
+      const_cast<Token*>(m_i_poolToken)->fromString(*(pAddr->par()));
    } else {
-      m_poolToken = tokAddr->getToken();
-      m_token.clear();
+      m_i_poolToken = tokAddr->getToken();
    }
-   m_dataObject = 0;
    try {
-      if (!PoolToDataObject(pObj, "").isSuccess()) {
-         ATH_MSG_ERROR("createObj PoolToDataObject() failed, Token = " << (m_poolToken ? m_poolToken->toString() : m_token));
-         return(StatusCode::FAILURE);
+      if (!PoolToDataObject(pObj, m_i_poolToken).isSuccess()) {
+         ATH_MSG_ERROR("createObj PoolToDataObject() failed, Token = " << (m_i_poolToken ? m_i_poolToken->toString() : "NULL"));
+         pObj = 0;
       }
    } catch (std::exception& e) {
       ATH_MSG_ERROR("createObj - caught exception: " << e.what());
-      return(StatusCode::FAILURE);
+      pObj = 0;
    }
-   m_dataObject = pObj;
-   if (m_dataObject == 0) {
-      ATH_MSG_ERROR("createObj failed to get DataObject, Token = " << (m_poolToken ? m_poolToken->toString() : m_token));
-      return(StatusCode::FAILURE);
+   if (pObj == 0) {
+      ATH_MSG_ERROR("createObj failed to get DataObject, Token = " << (m_i_poolToken ? m_i_poolToken->toString() : "NULL"));
    }
    if (tokAddr == 0 || tokAddr->getToken() == 0) {
-      delete m_poolToken; m_poolToken = 0;
+      delete m_i_poolToken; m_i_poolToken = 0;
    } else {
-      m_poolToken = 0;
+      m_i_poolToken = 0;
+   }
+   if (pObj == 0) {
+      return(StatusCode::FAILURE);
    }
-   m_token.clear();
    return(StatusCode::SUCCESS);
 }
 //__________________________________________________________________________
 StatusCode AthenaPoolConverter::createRep(DataObject* pObj, IOpaqueAddress*& pAddr) {
    // Create a Pool object for DataObject
-   m_dataObject = pObj;
-   m_poolToken = 0;
-   m_token.clear();
+   m_o_poolToken = 0;
    try {
-      if (!DataObjectToPool(pObj, m_dataObject->registry()->name()).isSuccess()) {
-         ATH_MSG_ERROR("CreateRep failed, key = " << m_dataObject->registry()->name());
+      if (!DataObjectToPool(pObj, pObj->registry()->name()).isSuccess()) {
+         ATH_MSG_ERROR("CreateRep failed, key = " << pObj->registry()->name());
          return(StatusCode::FAILURE);
       }
    } catch (std::exception& e) {
@@ -99,22 +97,20 @@ StatusCode AthenaPoolConverter::createRep(DataObject* pObj, IOpaqueAddress*& pAd
       return(StatusCode::FAILURE);
    }
    // Null/empty token means ERROR
-   if ((m_poolToken == 0 || m_poolToken->classID() == Guid::null()) && m_token.empty()) {
-      ATH_MSG_ERROR("CreateRep failed to get Token, key = " << m_dataObject->registry()->name());
+   if ((m_o_poolToken == 0 || m_o_poolToken->classID() == Guid::null())) {
+      ATH_MSG_ERROR("CreateRep failed to get Token, key = " << pObj->registry()->name());
       return(StatusCode::FAILURE);
    }
    const SG::DataProxy* proxy = dynamic_cast<SG::DataProxy*>(pObj->registry());
    if (proxy == 0) {
       ATH_MSG_ERROR("AthenaPoolConverter CreateRep failed to cast DataProxy, key = "
-	      << m_dataObject->registry()->name());
+	      << pObj->registry()->name());
       return(StatusCode::FAILURE);
    }
    const CLID clid = proxy->clID();
    // Create a IOpaqueAddress for this object.
-   pAddr = new TokenAddress(POOL_StorageType, clid, "", "", 0, m_poolToken);
-   m_poolToken = 0; // Token will be inserted into DataHeader, which takes ownership
-   m_token.clear();
-   m_dataObject = 0;
+   pAddr = new TokenAddress(POOL_StorageType, clid, "", "", 0, m_o_poolToken);
+   m_o_poolToken = 0; // Token will be inserted into DataHeader, which takes ownership
    return(StatusCode::SUCCESS);
 }
 //__________________________________________________________________________
@@ -127,20 +123,18 @@ AthenaPoolConverter::AthenaPoolConverter(const CLID& myCLID, ISvcLocator* pSvcLo
 		::AthMessaging((pSvcLocator != 0 ? msgSvc() : 0), "AthenaPoolConverter"),
 	m_athenaPoolCnvSvc("AthenaPoolCnvSvc", "AthenaPoolConverter"),
 	m_placement(0),
-	m_dictionaryOkRead(false),
-	m_dictionaryOkWrite(false),
 	m_placementHints(),
 	m_className(),
 	m_classDescs(),
-	m_token(),
 	m_dataObject(0),
-	m_poolToken(0) {
+	m_i_poolToken(0),
+	m_o_poolToken(0) {
 }
 //__________________________________________________________________________
 void AthenaPoolConverter::setPlacementWithType(const std::string& tname, const std::string& key) {
    if (m_placement == 0) {
       // Create placement for this converter if needed
-      m_placement = new pool::Placement();
+      m_placement = new Placement();
    }
    // Use technology from AthenaPoolCnvSvc
    if (m_athenaPoolCnvSvc->technologyType().type() == 0) {
@@ -150,7 +144,7 @@ void AthenaPoolConverter::setPlacementWithType(const std::string& tname, const s
    m_placement->setTechnology(m_athenaPoolCnvSvc->technologyType().type());
    // Set DB and Container names
    const std::string fileName = m_athenaPoolCnvSvc->getOutputConnectionSpec();
-   m_placement->setDatabase(fileName, pool::DatabaseSpecification::PFN);
+   m_placement->setFileName(fileName);
    if (key.empty()) { // No key will result in a separate tree by type for the data object
       m_placement->setContainerName(m_athenaPoolCnvSvc->getOutputContainer(tname));
    } else if (m_placementHints.find(tname + key) != m_placementHints.end()) { // PlacementHint already generated?
@@ -163,16 +157,12 @@ void AthenaPoolConverter::setPlacementWithType(const std::string& tname, const s
    }
 }
 //__________________________________________________________________________
-DataObject* AthenaPoolConverter::getDataObject() const {
+const DataObject* AthenaPoolConverter::getDataObject() const {
    return(m_dataObject);
 }
 //__________________________________________________________________________
-void AthenaPoolConverter::setDataObject(DataObject* pObj) {
-   m_dataObject = pObj;
-}
-//__________________________________________________________________________
 bool AthenaPoolConverter::compareClassGuid(const Guid &guid) const {
-   return(m_poolToken ? (guid == m_poolToken->classID()) : false);
+   return(m_i_poolToken ? (guid == m_i_poolToken->classID()) : false);
 }
 //__________________________________________________________________________
 StatusCode AthenaPoolConverter::cleanUp() {
diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/src/AthenaPoolTopLevelTPCnvBase.cxx b/Database/AthenaPOOL/AthenaPoolCnvSvc/src/AthenaPoolTopLevelTPCnvBase.cxx
old mode 100755
new mode 100644
diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/src/AthenaRootSerializeSvc.cxx b/Database/AthenaPOOL/AthenaPoolCnvSvc/src/AthenaRootSerializeSvc.cxx
new file mode 100644
index 00000000000..c63de705889
--- /dev/null
+++ b/Database/AthenaPOOL/AthenaPoolCnvSvc/src/AthenaRootSerializeSvc.cxx
@@ -0,0 +1,79 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+/* file contains the implementation for the AthenaRootSerializeSvc class.
+ *  @author Peter van Gemmeren <gemmeren@anl.gov>
+ **/
+
+#include "AthenaRootSerializeSvc.h"
+#include "DataModelRoot/RootType.h"
+
+#include "StorageSvc/DbReflex.h"
+#include "TBufferFile.h"
+
+//___________________________________________________________________________
+AthenaRootSerializeSvc::AthenaRootSerializeSvc(const std::string& name,
+	ISvcLocator* pSvcLocator) : AthService(name, pSvcLocator) {
+}
+
+//___________________________________________________________________________
+AthenaRootSerializeSvc::~AthenaRootSerializeSvc() {
+}
+
+//___________________________________________________________________________
+StatusCode AthenaRootSerializeSvc::initialize() {
+   ATH_MSG_INFO("Initializing " << name() << " - package version " << PACKAGE_VERSION);
+   if (!::AthService::initialize().isSuccess()) {
+      ATH_MSG_FATAL("Cannot initialize AthService base class.");
+      return(StatusCode::FAILURE);
+   }
+   return(StatusCode::SUCCESS);
+}
+
+//___________________________________________________________________________
+StatusCode AthenaRootSerializeSvc::finalize() {
+   ATH_MSG_INFO("in finalize()");
+   return(::AthService::finalize());
+}
+
+//___________________________________________________________________________
+StatusCode AthenaRootSerializeSvc::queryInterface(const InterfaceID& riid, void** ppvInterface) {
+   if ( IAthenaSerializeSvc::interfaceID().versionMatch(riid) ) {
+      *ppvInterface = (IAthenaSerializeSvc*)this;
+   } else {
+      // Interface is not directly available: try out a base class
+      return(AthService::queryInterface(riid, ppvInterface));
+   }
+   addRef();
+   return(StatusCode::SUCCESS);
+}
+
+//___________________________________________________________________________
+void* AthenaRootSerializeSvc::serialize(const void* /*object*/, const std::string& /*name*/, size_t& /*nbytes*/) {
+   return(0);
+}
+
+//___________________________________________________________________________
+void* AthenaRootSerializeSvc::serialize(const void* object, const Guid& id, size_t& nbytes) {
+   RootType cltype(pool::DbReflex::forGuid(id));
+   TBufferFile writeBuffer(TBuffer::kWrite);
+   writeBuffer.WriteObjectAny(object, cltype);
+   void* buffer = writeBuffer.Buffer();
+   nbytes = writeBuffer.Length();
+   writeBuffer.ResetBit(TBuffer::kIsOwner); writeBuffer.SetBuffer(0);
+   return(buffer);
+}
+
+//___________________________________________________________________________
+void* AthenaRootSerializeSvc::deserialize(void* /*buffer*/, size_t /*nbytes*/, const std::string& /*name*/) {
+   return(0);
+}
+
+//___________________________________________________________________________
+void* AthenaRootSerializeSvc::deserialize(void* buffer, size_t nbytes, const Guid& id) {
+   RootType cltype(pool::DbReflex::forGuid(id));
+   TBufferFile readBuffer(TBuffer::kRead, nbytes, buffer, kTRUE);
+   void* obj = readBuffer.ReadObjectAny(cltype);
+   return(obj);
+}
diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/src/AthenaRootSerializeSvc.h b/Database/AthenaPOOL/AthenaPoolCnvSvc/src/AthenaRootSerializeSvc.h
new file mode 100644
index 00000000000..9eddf084377
--- /dev/null
+++ b/Database/AthenaPOOL/AthenaPoolCnvSvc/src/AthenaRootSerializeSvc.h
@@ -0,0 +1,41 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef ATHENAROOTSERIALIZESVC_H
+#define ATHENAROOTSERIALIZESVC_H
+
+/** @file AthenaRootSerializeSvc.h
+ *  @brief This file contains the class definition for the AthenaRootSerializeSvc class.
+ *  @author Peter van Gemmeren <gemmeren@anl.gov>
+ **/
+
+#include "AthenaBaseComps/AthService.h"
+#include "AthenaKernel/IAthenaSerializeSvc.h"
+
+/** @class AthenaRootSerializeSvc
+ *  @brief This class provides the AthenaSerializeSvc using ROOT
+ **/
+class AthenaRootSerializeSvc : public ::AthService, virtual public IAthenaSerializeSvc {
+   // Allow the factory class access to the constructor
+   friend class SvcFactory<AthenaRootSerializeSvc>;
+
+public: 
+   /// Standard Service Constructor
+   AthenaRootSerializeSvc(const std::string& name, ISvcLocator* pSvcLocator);
+   /// Destructor
+   virtual ~AthenaRootSerializeSvc();
+
+   /// Gaudi Service Interface method implementations:
+   StatusCode initialize();
+   StatusCode finalize();
+   StatusCode queryInterface(const InterfaceID& riid, void** ppvInterface);
+
+   void* serialize(const void* object, const std::string& name, size_t& nbytes);
+   void* serialize(const void* object, const Guid& id, size_t& nbytes);
+
+   void* deserialize(void* buffer, size_t nbytes, const std::string& name);
+   void* deserialize(void* buffer, size_t nbytes, const Guid& id);
+};
+
+#endif
diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/src/CondAttrListCollCnv.cxx b/Database/AthenaPOOL/AthenaPoolCnvSvc/src/CondAttrListCollCnv.cxx
old mode 100755
new mode 100644
diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/src/CondAttrListCollCnv.h b/Database/AthenaPOOL/AthenaPoolCnvSvc/src/CondAttrListCollCnv.h
old mode 100755
new mode 100644
diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/src/CondAttrListVecCnv.cxx b/Database/AthenaPOOL/AthenaPoolCnvSvc/src/CondAttrListVecCnv.cxx
old mode 100755
new mode 100644
diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/src/CondAttrListVecCnv.h b/Database/AthenaPOOL/AthenaPoolCnvSvc/src/CondAttrListVecCnv.h
old mode 100755
new mode 100644
diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/src/TPCnvElt.cxx b/Database/AthenaPOOL/AthenaPoolCnvSvc/src/TPCnvElt.cxx
new file mode 100644
index 00000000000..5bdf2bf5062
--- /dev/null
+++ b/Database/AthenaPOOL/AthenaPoolCnvSvc/src/TPCnvElt.cxx
@@ -0,0 +1,36 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// $Id$
+/**
+ * @file AthenaPoolCnvSvc/src/TPCnvElt.cxx
+ * @author scott snyder <snyder@bnl.gov>
+ * @date Jan, 2016
+ * @brief Helper for calling a TP converter from an Athena converter.
+ */
+
+
+#include "AthenaPoolCnvSvc/TPCnvElt.h"
+#include "AthenaPoolCnvSvc/exceptions.h"
+#include "StorageSvc/DbReflex.h"
+
+
+namespace AthenaPoolCnvSvc {
+
+
+/**
+ * @brief Given a @c type_info, get the corresponding pool guid.
+ * @param ti @c type_info to look for.
+ *
+ * Throws an exception on errors.
+ */
+Guid guidFromTypeinfo (const std::type_info& ti)
+{
+  pool::TypeH typ = pool::DbReflex::forTypeInfo (ti);
+  if (!typ) throwExcNoDictForClass (ti);
+  return pool::DbReflex::guid (typ);
+}
+
+
+} // namespace AthenaPoolCnvSvc
diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/src/components/AthenaPoolCnvSvc_entries.cxx b/Database/AthenaPOOL/AthenaPoolCnvSvc/src/components/AthenaPoolCnvSvc_entries.cxx
old mode 100755
new mode 100644
index 5f984412ec2..f5f46df7784
--- a/Database/AthenaPOOL/AthenaPoolCnvSvc/src/components/AthenaPoolCnvSvc_entries.cxx
+++ b/Database/AthenaPOOL/AthenaPoolCnvSvc/src/components/AthenaPoolCnvSvc_entries.cxx
@@ -7,17 +7,20 @@
 #include "GaudiKernel/DeclareFactoryEntries.h"
 
 #include "../AthenaPoolCnvSvc.h"
+#include "../AthenaRootSerializeSvc.h"
 #include "../AthenaAttributeListCnv.h"
 #include "../CondAttrListCollCnv.h"
 #include "../CondAttrListVecCnv.h"
 
 DECLARE_SERVICE_FACTORY(AthenaPoolCnvSvc)
+DECLARE_SERVICE_FACTORY(AthenaRootSerializeSvc)
 DECLARE_CONVERTER_FACTORY(AthenaAttributeListCnv)
 DECLARE_CONVERTER_FACTORY(CondAttrListCollCnv)
 DECLARE_CONVERTER_FACTORY(CondAttrListVecCnv)
 
 DECLARE_FACTORY_ENTRIES(AthenaPoolCnvSvc) {
    DECLARE_SERVICE(AthenaPoolCnvSvc);
+   DECLARE_SERVICE(AthenaRootSerializeSvc);
    DECLARE_CONVERTER(AthenaAttributeListCnv);
    DECLARE_CONVERTER(CondAttrListCollCnv);
    DECLARE_CONVERTER(CondAttrListVecCnv);
diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/src/components/AthenaPoolCnvSvc_load.cxx b/Database/AthenaPOOL/AthenaPoolCnvSvc/src/components/AthenaPoolCnvSvc_load.cxx
old mode 100755
new mode 100644
diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/src/exceptions.cxx b/Database/AthenaPOOL/AthenaPoolCnvSvc/src/exceptions.cxx
new file mode 100644
index 00000000000..7a46d489696
--- /dev/null
+++ b/Database/AthenaPOOL/AthenaPoolCnvSvc/src/exceptions.cxx
@@ -0,0 +1,92 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// $Id$
+/**
+ * @file AthenaPoolCnvSvc/src/exceptions.cxx
+ * @author scott snyder <snyder@bnl.gov>
+ * @date Jan, 2016
+ * @brief Exceptions that can be thrown from AthenaPoolCnvSvc.
+ */
+
+
+#include "AthenaPoolCnvSvc/exceptions.h"
+#include "GaudiKernel/System.h"
+#include <sstream>
+
+
+namespace AthenaPoolCnvSvc {
+
+
+/// Helper: format exception error string.
+std::string excNoDictForClass_format (const std::type_info& ti)
+{
+  std::ostringstream os;
+  os << "AthenaPoolCnvSvc::::ExcNoDictForClass: "
+     << "Can't find dictionary information for class: ";
+  os << System::typeinfoName(ti);
+  return os.str();
+}
+
+
+/**
+ * @brief Constructor.
+ * @param ti The requested class.
+ */
+ExcNoDictForClass::ExcNoDictForClass (const std::type_info& ti)
+  : std::runtime_error (excNoDictForClass_format (ti))
+{
+}
+
+
+/**
+ * @brief Throw a AthenaPoolCnvSvc::ExcNoDictForClass exception.
+ * @param ti The requested class.
+ */
+void throwExcNoDictForClass (const std::type_info& ti)
+{
+  throw ExcNoDictForClass (ti);
+}
+
+
+//*************************************************************************
+
+
+/// Helper: format exception error string.
+std::string excUnsupportedVersion_format (const std::type_info& ti,
+                                          const Guid& guid)
+{
+  std::ostringstream os;
+  os << "AthenaPoolCnvSvc::::ExcUnsupported version: "
+     << "Unsupported persistent version of "
+     << System::typeinfoName(ti)
+     << " found; guid: " << guid.toString();
+  return os.str();
+}
+
+
+/**
+ * @brief Constructor.
+ * @param ti The requested class.
+ * @param guid The GUID of the persistent class.
+ */
+ExcUnsupportedVersion::ExcUnsupportedVersion (const std::type_info& ti,
+                                              const Guid& guid)
+  : std::runtime_error (excUnsupportedVersion_format (ti, guid))
+{
+}
+
+
+/**
+ * @brief Throw a AthenaPoolCnvSvc::ExcUnsupportedVersion exception.
+ * @param ti The class being read.
+ * @param guid The GUID of the persistent class.
+ */
+void throwExcUnsupportedVersion (const std::type_info& ti, const Guid& guid)
+{
+  throw ExcUnsupportedVersion (ti, guid);
+}
+
+
+} // namespace AthenaPoolCnvSvc
diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/test/AthenaPoolCnvSvc.xml b/Database/AthenaPOOL/AthenaPoolCnvSvc/test/AthenaPoolCnvSvc.xml
new file mode 100644
index 00000000000..e685e3d92ea
--- /dev/null
+++ b/Database/AthenaPOOL/AthenaPoolCnvSvc/test/AthenaPoolCnvSvc.xml
@@ -0,0 +1,15 @@
+<?xml version="1.0"?>
+<atn>
+    <TEST name="AthenaPoolCnvSvcTest" type="makecheck" suite="Core">
+       <package>Database/AthenaPOOL/AthenaPoolCnvSvc</package>
+       <timelimit>10</timelimit>
+       <mailto> snyder@bnl.gov</mailto>
+       <expectations>
+          <errorMessage>Athena exited abnormally</errorMessage>
+          <errorMessage>differ</errorMessage>
+          <warningMessage> # WARNING_MESSAGE : post.sh> ERROR</warningMessage>
+          <successMessage>check ok</successMessage>
+          <returnValue>0</returnValue>
+       </expectations>
+    </TEST>
+</atn>
diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/test/AthenaPoolCnvSvcTestDict.h b/Database/AthenaPOOL/AthenaPoolCnvSvc/test/AthenaPoolCnvSvcTestDict.h
new file mode 100644
index 00000000000..7cda5404718
--- /dev/null
+++ b/Database/AthenaPOOL/AthenaPoolCnvSvc/test/AthenaPoolCnvSvcTestDict.h
@@ -0,0 +1,115 @@
+// This file's extension implies that it's C, but it's really -*- C++ -*-.
+
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// $Id$
+/**
+ * @file AthenaPoolCnvSvcTestDict.h
+ * @author scott snyder <snyder@bnl.gov>
+ * @date Jan, 2016
+ * @brief 
+ */
+
+
+#ifndef ATHENAPOOLCNVSVC_ATHENAPOOLCNVSVCTESTDICT_H
+#define ATHENAPOOLCNVSVC_ATHENAPOOLCNVSVCTESTDICT_H
+
+
+#include "AthContainers/DataVector.h"
+#include "AthContainers/ViewVector.h"
+#include "AthContainers/AuxElement.h"
+#include "AthContainers/AuxStoreInternal.h"
+#include "AthLinks/ElementLink.h"
+#include "SGTools/CLASS_DEF.h"
+#include <vector>
+
+
+namespace AthenaPoolCnvSvcTest {
+
+
+class X
+{
+public:
+  X(int a) : m_a(a) {}
+  int m_a;
+};
+typedef DataVector<X> XCont;
+
+class X_p1
+{
+public:
+  X_p1(int a) : m_a(a) {}
+  int m_a;
+};
+class XCont_p1
+{
+public:
+  std::vector<X_p1> m_v;
+};
+
+
+class X_p2
+{
+public:
+  X_p2(int a) : m_a(a) {}
+  int m_a;
+};
+class XCont_p2
+{
+public:
+  std::vector<X_p2> m_v;
+};
+
+
+struct Y_v1
+  : public SG::AuxElement
+{
+  Y_v1(int a) : m_a(a) {}
+  int m_a;
+};
+struct Y_v2
+  : public SG::AuxElement
+{
+  Y_v2(int a) : m_a(a) {}
+  int m_a;
+};
+
+
+struct YAuxCont_v1
+  : public SG::AuxStoreInternal
+{
+};
+
+
+struct YAuxCont_v2
+  : public SG::AuxStoreInternal
+{
+};
+
+
+} // namespace AthenaPoolCnvSvcTest
+
+
+CLASS_DEF(DataVector<AthenaPoolCnvSvcTest::Y_v1>, 524263040, 1)
+CLASS_DEF(DataVector<AthenaPoolCnvSvcTest::Y_v2>, 524263041, 1)
+CLASS_DEF(ViewVector<DataVector<AthenaPoolCnvSvcTest::Y_v1> >, 524263042, 1)
+CLASS_DEF(ViewVector<DataVector<AthenaPoolCnvSvcTest::Y_v2> >, 524263043, 1)
+CLASS_DEF(AthenaPoolCnvSvcTest::YAuxCont_v1, 524263044, 1)
+CLASS_DEF(AthenaPoolCnvSvcTest::YAuxCont_v2, 524263045, 1)
+CLASS_DEF(AthenaPoolCnvSvcTest::XCont, 524263046, 1)
+
+
+namespace AthenaPoolCnvSvcTest {
+
+
+typedef std::vector<ElementLink<DataVector<Y_v1> > > YCont_v1_pers;
+typedef std::vector<ElementLink<DataVector<Y_v2> > > YCont_v2_pers;
+
+
+
+} // namespace AthenaPoolCnvSvcTest
+
+
+#endif // not ATHENAPOOLCNVSVC_ATHENAPOOLCNVSVCTESTDICT_H
diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/test/TPCnvElt_test.cxx b/Database/AthenaPOOL/AthenaPoolCnvSvc/test/TPCnvElt_test.cxx
new file mode 100644
index 00000000000..173f5a0a13c
--- /dev/null
+++ b/Database/AthenaPOOL/AthenaPoolCnvSvc/test/TPCnvElt_test.cxx
@@ -0,0 +1,113 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// $Id$
+/**
+ * @file AthenaPoolCnvSvc/test/TPCnvElt_test.cxx
+ * @author scott snyder <snyder@bnl.gov>
+ * @date Jan, 2016
+ * @brief Tests for TPCnvElt.
+ */
+
+
+#undef NDEBUG
+#include "AthenaPoolCnvSvc/TPCnvElt.h"
+#include "AthenaPoolCnvSvcTestDict.h"
+#include "GaudiKernel/MsgStream.h"
+#include "TSystem.h"
+#include <iostream>
+#include <typeinfo>
+#include <cassert>
+
+
+using namespace AthenaPoolCnvSvcTest;
+
+
+class XCnv_p1
+{
+public:
+  typedef X Trans_t;
+  typedef X_p1 Pers_t;
+  
+  X* createTransient (const X_p1* pers, MsgStream&)
+  { return new X(pers->m_a*2); }
+
+  void persToTrans (const X_p1* pers, X* trans, MsgStream&)
+  {
+    trans->m_a = pers->m_a*2;
+  }
+};
+
+
+std::string X_guid = "CAE53A87-64AD-4576-A203-1A4142E1E10F";
+std::string X_p1_guid = "6AD63B61-BE75-40FC-B0C6-DD3C7801D871";
+
+
+class TestConverter
+{
+public:
+  TestConverter (const std::string& guid) : m_guid (guid) {}
+  
+  bool compareClassGuid (const Guid& guid)
+  { return guid == m_guid; }
+
+  template <class T>
+  T* poolReadObject() { return new T (10); }
+  
+
+private:
+  Guid m_guid;
+};
+
+
+void test1()
+{
+  std::cout << "test1\n";
+
+  assert (AthenaPoolCnvSvc::guidFromTypeinfo (typeid (X_p1)) == Guid (X_p1_guid));
+}
+
+
+void test2()
+{
+  std::cout << "test2\n";
+  MsgStream msg (nullptr, "");
+
+  AthenaPoolCnvSvc::TPCnvElt<TestConverter, XCnv_p1> tpcnv;
+
+  TestConverter cnv1 (X_p1_guid);
+  X* x = tpcnv.createTransient (cnv1, msg);
+  assert (x->m_a == 20);
+  delete x;
+
+  X x2 (0);
+  assert (tpcnv.persToTrans (cnv1, &x2, msg));
+  assert (x2.m_a == 20);
+  
+  TestConverter cnv2 ("8ADE9DD7-ED1F-447E-A096-0F8F786291CD");
+  assert (tpcnv.createTransient (cnv2, msg) == nullptr);
+  assert (!tpcnv.persToTrans (cnv2, &x2, msg));
+
+  AthenaPoolCnvSvc::TPCnvElt<TestConverter, T_TPCnvNull<X> > tpcnv_null;
+  TestConverter cnv3 (X_guid);
+  x = tpcnv_null.createTransient (cnv3, msg);
+  assert (x->m_a == 10);
+  delete x;
+  assert (tpcnv_null.createTransient (cnv1, msg) == nullptr);
+
+  assert (tpcnv_null.persToTrans (cnv3, &x2, msg));
+  assert (x2.m_a == 10);
+  assert (!tpcnv_null.persToTrans (cnv1, &x2, msg));
+}
+
+
+int main()
+{
+  gSystem->Load("libAthenaPoolCnvSvcTestDict");
+  test1();
+  test2();
+  return 0;
+}
+
+
diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/test/TPCnvList_test.cxx b/Database/AthenaPOOL/AthenaPoolCnvSvc/test/TPCnvList_test.cxx
new file mode 100644
index 00000000000..b1cc8a85973
--- /dev/null
+++ b/Database/AthenaPOOL/AthenaPoolCnvSvc/test/TPCnvList_test.cxx
@@ -0,0 +1,129 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// $Id$
+/**
+ * @file AthenaPoolCnvSvc/test/TPCnvList_test.cxx
+ * @author scott snyder <snyder@bnl.gov>
+ * @date Jan, 2016
+ * @brief Tests for TPCnvList.
+ */
+
+
+#undef NDEBUG
+#include "AthenaPoolCnvSvc/TPCnvList.h"
+#include "AthenaPoolCnvSvcTestDict.h"
+#include "GaudiKernel/MsgStream.h"
+#include "TSystem.h"
+#include <iostream>
+#include <typeinfo>
+#include <cassert>
+
+
+using namespace AthenaPoolCnvSvcTest;
+
+
+class XCnv_p1
+{
+public:
+  typedef X Trans_t;
+  typedef X_p1 Pers_t;
+  
+  X* createTransient (const X_p1* pers, MsgStream&)
+  { return new X(pers->m_a*2); }
+
+  void persToTrans (const X_p1* pers, X* trans, MsgStream&)
+  {
+    trans->m_a = pers->m_a*2;
+  }
+};
+
+
+class XCnv_p2
+{
+public:
+  typedef X Trans_t;
+  typedef X_p2 Pers_t;
+  
+  X* createTransient (const X_p2* pers, MsgStream&)
+  { return new X(pers->m_a*3); }
+
+  void persToTrans (const X_p2* pers, X* trans, MsgStream&)
+  {
+    trans->m_a = pers->m_a*3;
+  }
+};
+
+
+std::string X_guid = "CAE53A87-64AD-4576-A203-1A4142E1E10F";
+std::string X_p1_guid = "6AD63B61-BE75-40FC-B0C6-DD3C7801D871";
+std::string X_p2_guid = "0AAC9C99-726D-4CF4-B9F9-00B6674C57DD";
+
+
+class TestConverter
+{
+public:
+  TestConverter (const std::string& guid) : m_guid (guid) {}
+  
+  bool compareClassGuid (const Guid& guid)
+  { return guid == m_guid; }
+
+  template <class T>
+  T* poolReadObject() { return new T (10); }
+  
+
+private:
+  Guid m_guid;
+};
+
+
+void test1()
+{
+  std::cout << "test1\n";
+  MsgStream msg (nullptr, "");
+
+  AthenaPoolCnvSvc::TPCnvList<TestConverter, X,
+                              XCnv_p2,
+                              XCnv_p1,
+                              T_TPCnvNull<X> > tpcnv;
+
+  X* x = nullptr;
+  X x2(0);
+
+  TestConverter cnv1 (X_p1_guid);
+  x = tpcnv.createTransient (cnv1, msg);
+  assert (x->m_a == 20);
+  delete x;
+
+  assert (tpcnv.persToTrans (cnv1, &x2, msg));
+  assert (x2.m_a == 20);
+
+  TestConverter cnv2 (X_p2_guid);
+  x = tpcnv.createTransient (cnv2, msg);
+  assert (x->m_a == 30);
+  delete x;
+
+  assert (tpcnv.persToTrans (cnv2, &x2, msg));
+  assert (x2.m_a == 30);
+
+  TestConverter cnv0 (X_guid);
+  x = tpcnv.createTransient (cnv0, msg);
+  assert (x->m_a == 10);
+  delete x;
+
+  assert (tpcnv.persToTrans (cnv0, &x2, msg));
+  assert (x2.m_a == 10);
+
+  TestConverter cnvx ("B3FCEE90-66FC-4AE1-A81B-5257A0306EF8");
+  assert (tpcnv.createTransient (cnvx, msg) == nullptr);
+  assert (!tpcnv.persToTrans (cnvx, &x2, msg));
+}
+
+
+int main()
+{
+  gSystem->Load("libAthenaPoolCnvSvcTestDict");
+  test1();
+  return 0;
+}
diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/test/T_AthenaPoolAuxContainerCnv_test.cxx b/Database/AthenaPOOL/AthenaPoolCnvSvc/test/T_AthenaPoolAuxContainerCnv_test.cxx
new file mode 100644
index 00000000000..24605568a7d
--- /dev/null
+++ b/Database/AthenaPOOL/AthenaPoolCnvSvc/test/T_AthenaPoolAuxContainerCnv_test.cxx
@@ -0,0 +1,269 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// $Id$
+/**
+ * @file AthenaPoolCnvSvc/test/T_AthenaPoolAuxContainerCnv_test.cxx
+ * @author scott snyder <snyder@bnl.gov>
+ * @date Jan, 2016
+ * @brief Tests for T_AthenaPoolAuxContainerCnv_test.
+ */
+
+
+#undef NDEBUG
+#include "AthenaPoolCnvSvc/T_AthenaPoolAuxContainerCnv.h"
+#include "PersistentDataModel/TokenAddress.h"
+#include "AthContainers/AuxTypeRegistry.h"
+#include "SGTools/TestStore.h"
+#include "TestTools/initGaudi.h"
+#include "CxxUtils/make_unique.h"
+#include "TSystem.h"
+#include "AthenaPoolCnvSvcTestDict.h"
+#include "TestThinningSvc.icc"
+#include "TestCnvSvcBase.icc"
+#include <iostream>
+#include <cassert>
+#include <vector>
+
+
+using namespace AthenaPoolCnvSvcTest;
+
+
+std::string YAuxCont_v1_guid = "BEE3C14E-149E-4366-9E24-8A32C419A3B4";
+std::string YAuxCont_v2_guid = "170BFEE4-F6B2-4AF4-919B-7EB3986656FA";
+
+
+class TestCnvSvc
+  : public TestCnvSvcBase
+{
+public:
+  TestCnvSvc (const std::string& name, ISvcLocator* svcloc)
+    : TestCnvSvcBase (name, svcloc),
+      m_pers1 (nullptr),
+      m_pers2 (nullptr)
+  {}
+
+  virtual void setObjPtr(void*& obj, const Token* /*token*/) const override
+  {
+    if (m_pers2) {
+      obj = new YAuxCont_v2 (*m_pers2);
+    }
+    else if (m_pers1) {
+      obj = new YAuxCont_v1 (*m_pers1);
+    }
+    else
+      std::abort();
+  }
+
+  std::string m_name;
+  YAuxCont_v1* m_pers1;
+  YAuxCont_v2* m_pers2;
+};
+
+
+class YAuxContCnv_v1
+{
+public:
+  typedef YAuxCont_v2 Trans_t;
+  typedef YAuxCont_v1 Pers_t;
+  
+  Trans_t* createTransient (const Pers_t* pers, MsgStream& msg)
+  {
+    auto trans = CxxUtils::make_unique<Trans_t>();
+    persToTrans (pers, trans.get(), msg);
+    return trans.release();
+  }
+
+  void persToTrans (const Pers_t* pers, Trans_t* trans, MsgStream&)
+  {
+    typedef ElementLink<DataVector<Y_v2> > Link_t;
+    SG::AuxTypeRegistry& reg = SG::AuxTypeRegistry::instance();
+    SG::auxid_t x_auxid = reg.getAuxID<int> ("x");
+    SG::auxid_t l_auxid = reg.getAuxID<Link_t> ("l");
+
+    size_t sz = pers->size();
+
+    int* xt = reinterpret_cast<int*> (trans->getData (x_auxid, sz, sz));
+    Link_t* lt = reinterpret_cast<Link_t*> (trans->getData (l_auxid, sz, sz));
+
+    const int* xp = reinterpret_cast<const int*> (pers->getData (x_auxid));
+    const Link_t* lp = reinterpret_cast<const Link_t*> (pers->getData (l_auxid));
+
+    for (size_t i = 0; i < sz; i++) {
+      lt[i] = lp[i];
+      xt[i] = xp[i]*3;
+    }
+  }
+};
+
+
+// Writing
+void test1 (ISvcLocator* svcloc, TestCnvSvc& /*testsvc*/)
+{
+  std::cout << "test1\n";
+  const size_t N = 10;
+
+  DataVector<Y_v2>* vec = new DataVector<Y_v2>;
+  for (size_t i = 0; i < N; i++)
+    vec->push_back (new Y_v2(i));
+  SGTest::store.record (vec, "vec");
+
+  T_AthenaPoolAuxContainerCnv<YAuxCont_v2, YAuxContCnv_v1> cnv (svcloc);
+  assert (static_cast<AthenaPoolConverter&>(cnv).initialize().isSuccess());
+
+  typedef ElementLink<DataVector<Y_v2> > Link_t;
+  SG::AuxTypeRegistry& reg = SG::AuxTypeRegistry::instance();
+  SG::auxid_t x_auxid = reg.getAuxID<int> ("x");
+  SG::auxid_t l_auxid = reg.getAuxID<Link_t> ("l");
+  YAuxCont_v2* trans2 = new YAuxCont_v2;
+  int* x2 = reinterpret_cast<int*> (trans2->getData (x_auxid, N, N));
+  Link_t* l2 = reinterpret_cast<Link_t*> (trans2->getData (l_auxid, N, N));
+  for (size_t i = 0; i < N; i++) {
+    x2[i] = i*2;
+    l2[i] = Link_t ("vec", i);
+  }
+  SGTest::store.record (trans2, "store");
+
+  YAuxCont_v2* pers2a = cnv.createPersistent (trans2);
+  assert (pers2a->size() == trans2->size());
+  const int* x2a = reinterpret_cast<const int*> (pers2a->getData (x_auxid));
+  const Link_t* l2a = reinterpret_cast<const Link_t*> (pers2a->getData (l_auxid));
+  for (size_t i = 0; i < N; i++) {
+    assert (x2a[i] == static_cast<int>(i)*2);
+    assert (l2a[i].dataID() == "vec");
+    assert (l2a[i].index() == i);
+  }
+
+  TestThinningSvc thinsvc;
+  TestThinningSvc::instance (&thinsvc, true);
+  thinsvc.remap (vec, 5, IThinningSvc::RemovedIdx);
+  for (size_t i = 6; i < N; i++)
+    thinsvc.remap (vec, i, i-1);
+  thinsvc.remap (trans2, 7, IThinningSvc::RemovedIdx);
+
+  YAuxCont_v2* pers2b = cnv.createPersistent (trans2);
+  assert (pers2b->size() == trans2->size()-1);
+  const int* x2b = reinterpret_cast<const int*> (pers2b->getData (x_auxid));
+  const Link_t* l2b = reinterpret_cast<const Link_t*> (pers2b->getData (l_auxid));
+  for (size_t i = 0; i < N-1; i++) {
+    size_t ii = i;
+    if (i >= 7) ii = i+1;
+    assert (x2b[i] == static_cast<int>(ii)*2);
+    if (ii == 5) {
+      assert (l2b[i].key() == 0);
+      assert (l2b[i].index() == 0);
+    }
+    else {
+      assert (l2b[i].dataID() == "vec");
+      if (i < 5)
+        assert (l2b[i].index() == ii);
+      else
+        assert (l2b[i].index() == ii-1);
+    }
+  }
+
+  TestThinningSvc::instance (nullptr, true);
+  delete trans2;
+  delete pers2a;
+  delete pers2b;
+}
+
+
+// Reading
+void test2 (ISvcLocator* svcloc, TestCnvSvc& testsvc)
+{
+  std::cout << "test2\n";
+  const size_t N = 10;
+
+  T_AthenaPoolAuxContainerCnv<YAuxCont_v2, YAuxContCnv_v1> cnv (svcloc);
+  assert (static_cast<AthenaPoolConverter&>(cnv).initialize().isSuccess());
+
+  typedef ElementLink<DataVector<Y_v2> > Link_t;
+  SG::AuxTypeRegistry& reg = SG::AuxTypeRegistry::instance();
+  SG::auxid_t x_auxid = reg.getAuxID<int> ("x");
+  SG::auxid_t l_auxid = reg.getAuxID<Link_t> ("l");
+  YAuxCont_v2 pers2;
+  int* x2 = reinterpret_cast<int*> (pers2.getData (x_auxid, N, N));
+  Link_t* l2 = reinterpret_cast<Link_t*> (pers2.getData (l_auxid, N, N));
+  for (size_t i = 0; i < N; i++) {
+    x2[i] = i*2;
+    l2[i] = Link_t ("vec", i);
+  }
+
+  testsvc.m_pers2 = &pers2;
+  Token* token = new Token;
+  token->setClassID (Guid (YAuxCont_v2_guid));
+  TokenAddress taddr (0, 0, "", "", 0, token);
+
+  {
+    DataObject* pObj = nullptr;
+    assert (cnv.createObj (&taddr, pObj).isSuccess());
+    auto* trans = SG::Storable_cast<YAuxCont_v2> (pObj);
+    assert (trans->size() == pers2.size());
+    const int* xt = reinterpret_cast<const int*> (trans->getData (x_auxid));
+    const Link_t* lt = reinterpret_cast<const Link_t*> (trans->getData (l_auxid));
+    for (size_t i = 0; i < N; i++) {
+      assert (xt[i] == static_cast<int>(i)*2);
+      assert (lt[i].dataID() == "vec");
+      assert (lt[i].index() == i);
+    }
+
+    delete pObj;
+  }
+  testsvc.m_pers2 = nullptr;
+
+  YAuxCont_v1 pers1;
+  int* x1 = reinterpret_cast<int*> (pers1.getData (x_auxid, N, N));
+  Link_t* l1 = reinterpret_cast<Link_t*> (pers1.getData (l_auxid, N, N));
+  for (size_t i = 0; i < N; i++) {
+    x1[i] = i*4;
+    l1[i] = Link_t ("vec", i);
+  }
+
+  testsvc.m_pers1 = &pers1;
+  token->setClassID (Guid (YAuxCont_v1_guid));
+  {
+    DataObject* pObj = nullptr;
+    assert (cnv.createObj (&taddr, pObj).isSuccess());
+    auto* trans = SG::Storable_cast<YAuxCont_v2> (pObj);
+    assert (trans->size() == pers2.size());
+    const int* xt = reinterpret_cast<const int*> (trans->getData (x_auxid));
+    const Link_t* lt = reinterpret_cast<const Link_t*> (trans->getData (l_auxid));
+    for (size_t i = 0; i < N; i++) {
+      assert (xt[i] == static_cast<int>(i)*3*4);
+      assert (lt[i].dataID() == "vec");
+      assert (lt[i].index() == i);
+    }
+
+    delete pObj;
+  }
+
+  token->setClassID (Guid ("8ACD1C53-D3C7-4FE5-9BC0-E388701DB8FA"));
+  DataObject* pObj = nullptr;
+  assert (cnv.createObj (&taddr, pObj).isFailure());
+
+  testsvc.m_pers1 = nullptr;
+}
+
+
+int main()
+{
+  SGTest::initTestStore();
+  ISvcLocator* pSvcLoc = nullptr;
+  if (!Athena_test::initGaudi("test.txt", pSvcLoc)) {
+    std::cerr << "This test can not be run" << std::endl;
+    return 0;
+  }
+
+  TestCnvSvc* svc = new TestCnvSvc ("AthenaPoolCnvSvc", pSvcLoc);
+  ISvcManager* mgr = dynamic_cast<ISvcManager*> (pSvcLoc);
+  if (mgr->addService (svc).isFailure())
+    std::abort();
+  
+  gSystem->Load("libAthenaPoolCnvSvcTestDict");
+
+  test1 (pSvcLoc, *svc);
+  test2 (pSvcLoc, *svc);
+  return 0;
+}
diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/test/T_AthenaPoolTPCnvCnv_test.cxx b/Database/AthenaPOOL/AthenaPoolCnvSvc/test/T_AthenaPoolTPCnvCnv_test.cxx
new file mode 100644
index 00000000000..c31154526fa
--- /dev/null
+++ b/Database/AthenaPOOL/AthenaPoolCnvSvc/test/T_AthenaPoolTPCnvCnv_test.cxx
@@ -0,0 +1,227 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// $Id$
+/**
+ * @file AthenaPoolCnvSvc/test/T_AthenaPoolTPCnvCnv_test.cxx
+ * @author scott snyder <snyder@bnl.gov>
+ * @date Jan, 2016
+ * @brief Tests for T_AthenaPoolTPCnvCnv_test.
+ */
+
+
+#undef NDEBUG
+#include "AthenaPoolCnvSvc/T_AthenaPoolTPCnvCnv.h"
+#include "AthenaPoolCnvSvc/T_AthenaPoolTPConverter.h"
+#include "PersistentDataModel/TokenAddress.h"
+#include "SGTools/TestStore.h"
+#include "TestTools/initGaudi.h"
+#include "CxxUtils/make_unique.h"
+#include "TSystem.h"
+#include "AthenaPoolCnvSvcTestDict.h"
+#include "TestCnvSvcBase.icc"
+#include <iostream>
+#include <cassert>
+#include <vector>
+
+
+using namespace AthenaPoolCnvSvcTest;
+
+
+std::string XCont_guid    = "6AEA6831-8777-4571-8595-95FFF40B171F";
+std::string XCont_p1_guid = "421C967C-CB57-4234-A33F-EBE4928036C2";
+std::string XCont_p2_guid = "F151C81D-869A-4585-8086-5F8835AB12E1";
+
+
+class TestCnvSvc
+  : public TestCnvSvcBase
+{
+public:
+  TestCnvSvc (const std::string& name, ISvcLocator* svcloc)
+    : TestCnvSvcBase (name, svcloc),
+      m_pers0 (nullptr),
+      m_pers1 (nullptr),
+      m_pers2 (nullptr)
+  {}
+
+  virtual void setObjPtr(void*& obj, const Token* /*token*/) const override
+  {
+    if (m_pers2) {
+      obj = new XCont_p2 (*m_pers2);
+    }
+    else if (m_pers1) {
+      obj = new XCont_p1 (*m_pers1);
+    }
+    else if (m_pers0) {
+      obj = new XCont (*m_pers0);
+    }
+    else
+      std::abort();
+  }
+
+  std::string m_name;
+  XCont* m_pers0;
+  XCont_p1* m_pers1;
+  XCont_p2* m_pers2;
+};
+
+
+class XContCnv_p1
+  : public T_AthenaPoolTPCnvBase<XCont, XCont_p1>
+{
+public:
+  virtual
+  void persToTrans (const Pers_t* pers, Trans_t* trans, MsgStream&) override
+  {
+    trans->clear();
+    for (const X_p1& x : pers->m_v)
+      trans->push_back (new X (x.m_a / 20));
+  }
+
+  virtual
+  void transToPers (const Trans_t* trans, Pers_t* pers, MsgStream&) override
+  {
+    pers->m_v.clear();
+    for (const X* x : *trans)
+      pers->m_v.emplace_back (x->m_a * 20);
+  }
+};
+
+
+class XContCnv_p2
+  : public T_AthenaPoolTPCnvBase<XCont, XCont_p2>
+{
+public:
+  virtual
+  void persToTrans (const Pers_t* pers, Trans_t* trans, MsgStream&) override
+  {
+    trans->clear();
+    for (const X_p2& x : pers->m_v)
+      trans->push_back (new X (x.m_a / 10));
+  }
+
+  virtual
+  void transToPers (const Trans_t* trans, Pers_t* pers, MsgStream&) override
+  {
+    pers->m_v.clear();
+    for (const X* x : *trans)
+      pers->m_v.emplace_back (x->m_a * 10);
+  }
+};
+
+
+// Writing
+void test1 (ISvcLocator* svcloc, TestCnvSvc& /*testsvc*/)
+{
+  std::cout << "test1\n";
+  const size_t N = 10;
+
+  T_AthenaPoolTPCnvCnv<XCont, XContCnv_p2, XContCnv_p1, T_TPCnvNull<XCont> >
+    cnv (svcloc);
+  assert (static_cast<AthenaPoolConverter&>(cnv).initialize().isSuccess());
+
+  XCont trans;
+  for (size_t i = 0; i < N; i++)
+    trans.push_back (new X(i));
+
+  {
+    XCont_p2* pers2 = cnv.createPersistent (&trans);
+    assert (pers2->m_v.size() == N);
+    for (size_t i = 0; i < N; i++)
+      assert (pers2->m_v[i].m_a == static_cast<int>(i*10));
+    delete pers2;
+  }
+}
+
+
+// Reading
+void test2 (ISvcLocator* svcloc, TestCnvSvc& testsvc)
+{
+  std::cout << "test2\n";
+  const size_t N = 10;
+  T_AthenaPoolTPCnvCnv<XCont, XContCnv_p2, XContCnv_p1, T_TPCnvNull<XCont> >
+    cnv (svcloc);
+  assert (static_cast<AthenaPoolConverter&>(cnv).initialize().isSuccess());
+
+  XCont_p2 pers2;
+  for (size_t i = 0; i < N; i++)
+    pers2.m_v.push_back (X_p2 (i*50));
+
+  testsvc.m_pers2 = &pers2;
+  Token* token = new Token;
+  token->setClassID (Guid (XCont_p2_guid));
+  TokenAddress taddr (0, 0, "", "", 0, token);
+
+  {
+    DataObject* pObj = nullptr;
+    assert (cnv.createObj (&taddr, pObj).isSuccess());
+    auto* trans = SG::Storable_cast<XCont> (pObj);
+    assert (trans->size() == N);
+    for (size_t i = 0; i < N; i++)
+      assert ((*trans)[i]->m_a == static_cast<int>(i*5));
+    delete pObj;
+  }
+  testsvc.m_pers2 = nullptr;
+
+  XCont_p1 pers1;
+  for (size_t i = 0; i < N; i++)
+    pers1.m_v.push_back (X_p1 (i*80));
+
+  testsvc.m_pers1 = &pers1;
+  token->setClassID (Guid (XCont_p1_guid));
+  {
+    DataObject* pObj = nullptr;
+    assert (cnv.createObj (&taddr, pObj).isSuccess());
+    auto* trans = SG::Storable_cast<XCont> (pObj);
+    assert (trans->size() == N);
+    for (size_t i = 0; i < N; i++)
+      assert ((*trans)[i]->m_a == static_cast<int>(i*4));
+    delete pObj;
+  }
+  testsvc.m_pers1 = nullptr;
+
+  XCont pers0;
+  for (size_t i = 0; i < N; i++)
+    pers0.push_back (new X (i*11));
+
+  testsvc.m_pers0 = &pers0;
+  token->setClassID (Guid (XCont_guid));
+  {
+    DataObject* pObj = nullptr;
+    assert (cnv.createObj (&taddr, pObj).isSuccess());
+    auto* trans = SG::Storable_cast<XCont> (pObj);
+    assert (trans->size() == N);
+    for (size_t i = 0; i < N; i++)
+      assert ((*trans)[i]->m_a == static_cast<int>(i*11));
+    delete pObj;
+  }
+
+  token->setClassID (Guid ("8ACD1C53-D3C7-4FE5-9BC0-E388701DB8FA"));
+  DataObject* pObj = nullptr;
+  assert (cnv.createObj (&taddr, pObj).isFailure());
+
+  testsvc.m_pers1 = nullptr;
+}
+
+
+int main()
+{
+  SGTest::initTestStore();
+  ISvcLocator* pSvcLoc = nullptr;
+  if (!Athena_test::initGaudi("test.txt", pSvcLoc)) {
+    std::cerr << "This test can not be run" << std::endl;
+    return 0;
+  }
+
+  TestCnvSvc* svc = new TestCnvSvc ("AthenaPoolCnvSvc", pSvcLoc);
+  ISvcManager* mgr = dynamic_cast<ISvcManager*> (pSvcLoc);
+  if (mgr->addService (svc).isFailure())
+    std::abort();
+  
+  gSystem->Load("libAthenaPoolCnvSvcTestDict");
+
+  test1 (pSvcLoc, *svc);
+  test2 (pSvcLoc, *svc);
+  return 0;
+}
diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/test/T_AthenaPoolViewVectorCnv_test.cxx b/Database/AthenaPOOL/AthenaPoolCnvSvc/test/T_AthenaPoolViewVectorCnv_test.cxx
new file mode 100644
index 00000000000..bb4eb0acf78
--- /dev/null
+++ b/Database/AthenaPOOL/AthenaPoolCnvSvc/test/T_AthenaPoolViewVectorCnv_test.cxx
@@ -0,0 +1,186 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// $Id$
+/**
+ * @file AthenaPoolCnvSvc/test/T_AthenaPoolViewVectorCnv_test.cxx
+ * @author scott snyder <snyder@bnl.gov>
+ * @date Jan, 2016
+ * @brief Tests for T_AthenaPoolViewVectorCnv_test.
+ */
+
+
+#undef NDEBUG
+#include "AthenaPoolCnvSvc/T_AthenaPoolViewVectorCnv.h"
+#include "AthenaPoolCnvSvc/T_AthenaPoolCnv.h"
+#include "PersistentDataModel/TokenAddress.h"
+#include "AthContainers/DataVector.h"
+#include "AthLinks/ElementLink.h"
+#include "SGTools/TestStore.h"
+#include "SGTools/StorableConversions.h"
+#include "TestTools/initGaudi.h"
+#include "GaudiKernel/MsgStream.h"
+#include "TSystem.h"
+#include "AthenaPoolCnvSvcTestDict.h"
+#include "TestThinningSvc.icc"
+#include "TestCnvSvcBase.icc"
+#include <iostream>
+#include <cassert>
+#include <vector>
+
+
+using namespace AthenaPoolCnvSvcTest;
+
+
+std::string YCont_v1_guid = "7E1826B9-3666-42B3-A2E7-C916BD10A5B8";
+std::string YCont_v2_guid = "80C19103-FE9B-4227-8E48-8C0DB468F892";
+
+
+class TestCnvSvc
+  : public TestCnvSvcBase
+{
+public:
+  TestCnvSvc (const std::string& name, ISvcLocator* svcloc)
+    : TestCnvSvcBase (name, svcloc),
+      m_pers (nullptr)
+  {}
+
+  virtual void setObjPtr(void*& obj, const Token* /*token*/) const override
+  {
+    obj = new YCont_v2_pers (*m_pers);
+  }
+
+  std::string m_name;
+  YCont_v2_pers* m_pers;
+};
+
+
+void test1 (ISvcLocator* svcloc, TestCnvSvc& testsvc, DataVector<Y_v2>& vec)
+{
+  std::cout << "test1\n";
+
+  T_AthenaPoolCnv<ViewVector<DataVector<Y_v2> > > cnv (svcloc);
+  assert (cnv.initialize().isSuccess());
+
+  ViewVector<DataVector<Y_v2> > view (SG::VIEW_ELEMENTS);
+  size_t sz = vec.size();
+  for (size_t i = 0; i < sz; i++)
+    view.push_back (vec[sz-i-1]);
+
+  YCont_v2_pers* pers = cnv.createPersistent (&view);
+  assert (pers->size() == sz);
+  for (size_t i = 0; i < sz; i++) {
+    assert ((*pers)[i].dataID() == "vec");
+    assert ((*pers)[i].index() == sz-i-1);
+  }
+
+  testsvc.m_pers = pers;
+  Token* token = new Token;
+  token->setClassID (Guid (YCont_v2_guid));
+  TokenAddress taddr (0, 0, "", "", 0, token);
+
+  DataObject* pObj;
+  assert (cnv.createObj (&taddr, pObj).isSuccess());
+  auto* trans1 = SG::Storable_cast<ViewVector<DataVector<Y_v2> > > (pObj);
+  assert (trans1->size() == 10);
+  for (size_t i = 0; i < sz; i++)
+    assert ((*trans1)[i] == view[i]);
+  delete pObj;
+  pObj = nullptr;
+  delete pers;
+  testsvc.m_pers = nullptr;
+
+  YCont_v2_pers pers1;
+  size_t ii = 0;
+  for (size_t i = 0; i < sz; i++, ii+=2) {
+    if (ii >= sz) ii = 1;
+    pers1.emplace_back ("vec", ii);
+  }
+  testsvc.m_pers = &pers1;
+  token->setClassID (Guid (YCont_v1_guid));
+  assert (cnv.createObj (&taddr, pObj).isSuccess());
+  auto* trans2 = SG::Storable_cast<ViewVector<DataVector<Y_v2> > > (pObj);
+  assert (trans2->size() == 10);
+  ii = 0;
+  for (size_t i = 0; i < sz; i++, ii+=2) {
+    if (ii >= sz) ii = 1;
+    assert ((*trans2)[i] == vec[ii]);
+  }
+  delete trans2;
+
+  token->setClassID (Guid ("79E2478D-C17F-45E9-848D-278240C2FED3"));
+  assert (cnv.createObj (&taddr, pObj).isFailure());
+}
+
+
+// Test with thinning.
+void test2 (ISvcLocator* svcloc, TestCnvSvc& /*testsvc*/, DataVector<Y_v2>& vec)
+{
+  std::cout << "test2\n";
+  size_t sz = vec.size();
+
+  TestThinningSvc thinsvc;
+  TestThinningSvc::instance (&thinsvc, true);
+  thinsvc.remap (&vec, 5, IThinningSvc::RemovedIdx);
+  for (size_t i = 6; i < sz; i++)
+    thinsvc.remap (&vec, i, i-1);
+
+  T_AthenaPoolCnv<ViewVector<DataVector<Y_v2> > > cnv (svcloc);
+  assert (cnv.initialize().isSuccess());
+
+  ViewVector<DataVector<Y_v2> > view (SG::VIEW_ELEMENTS);
+  for (size_t i = 0; i < sz; i++)
+    view.push_back (vec[i]);
+
+  YCont_v2_pers* pers = cnv.createPersistent (&view);
+  assert (pers->size() == sz);
+  for (size_t i = 0; i < sz; i++) {
+    const ElementLink<DataVector<Y_v2> >& l = (*pers)[i];
+    if (i == 5) {
+      assert (l.key() == 0);
+      assert (l.index() == 0);
+    }
+    else {
+      assert (l.dataID() == "vec");
+      if (i < 5)
+        assert (l.index() == i);
+      else
+        assert (l.index() == i-1);
+    }
+  }
+  delete pers;
+}
+
+
+DataVector<Y_v2>& makeVecs()
+{
+  auto vec = CxxUtils::make_unique<DataVector<Y_v2> >();
+  for (size_t i = 0; i < 10; i++)
+    vec->push_back (new Y_v2(i));
+  DataVector<Y_v2>& ret = *vec.get();
+  SGTest::store.record (vec.release(), "vec");
+  return ret;
+}
+
+
+int main()
+{
+  SGTest::initTestStore();
+  ISvcLocator* pSvcLoc = nullptr;
+  if (!Athena_test::initGaudi("test.txt", pSvcLoc)) {
+    std::cerr << "This test can not be run" << std::endl;
+    return 0;
+  }
+
+  TestCnvSvc* svc = new TestCnvSvc ("AthenaPoolCnvSvc", pSvcLoc);
+  ISvcManager* mgr = dynamic_cast<ISvcManager*> (pSvcLoc);
+  if (mgr->addService (svc).isFailure())
+    std::abort();
+  
+  gSystem->Load("libAthenaPoolCnvSvcTestDict");
+  DataVector<Y_v2>& vec = makeVecs();
+  test1 (pSvcLoc, *svc, vec);
+  test2 (pSvcLoc, *svc, vec);
+}
+
diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/test/T_AthenaPoolxAODCnv_test.cxx b/Database/AthenaPOOL/AthenaPoolCnvSvc/test/T_AthenaPoolxAODCnv_test.cxx
new file mode 100644
index 00000000000..fd5216ce376
--- /dev/null
+++ b/Database/AthenaPOOL/AthenaPoolCnvSvc/test/T_AthenaPoolxAODCnv_test.cxx
@@ -0,0 +1,161 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// $Id$
+/**
+ * @file AthenaPoolCnvSvc/test/T_AthenaPoolxAODCnv_test.cxx
+ * @author scott snyder <snyder@bnl.gov>
+ * @date Jan, 2016
+ * @brief Tests for T_AthenaPoolxAODCnv_test.
+ */
+
+
+#undef NDEBUG
+#include "AthenaPoolCnvSvc/T_AthenaPoolxAODCnv.h"
+#include "PersistentDataModel/TokenAddress.h"
+#include "SGTools/TestStore.h"
+#include "TestTools/initGaudi.h"
+#include "CxxUtils/make_unique.h"
+#include "TSystem.h"
+#include "AthenaPoolCnvSvcTestDict.h"
+#include "TestCnvSvcBase.icc"
+#include <iostream>
+#include <cassert>
+#include <vector>
+
+
+using namespace AthenaPoolCnvSvcTest;
+
+
+std::string YCont_v1_guid = "05309E49-5567-4790-BE56-2E541E0B4B24";
+std::string YCont_v2_guid = "0CC6B32E-6C95-4B0E-B97A-9B9040A8A9BE";
+
+
+class TestCnvSvc
+  : public TestCnvSvcBase
+{
+public:
+  TestCnvSvc (const std::string& name, ISvcLocator* svcloc)
+    : TestCnvSvcBase (name, svcloc),
+      m_pers1 (nullptr),
+      m_pers2 (nullptr)
+  {}
+
+  virtual void setObjPtr(void*& obj, const Token* /*token*/) const override
+  {
+    if (m_pers2) {
+      DataVector<Y_v2>* v = new DataVector<Y_v2>;
+      for (const Y_v2* y : *m_pers2)
+        v->push_back (new Y_v2(*y));
+      obj = v;
+    }
+    else if (m_pers1) {
+      DataVector<Y_v1>* v = new DataVector<Y_v1>;
+      for (const Y_v1* y : *m_pers1)
+        v->push_back (new Y_v1(*y));
+      obj = v;
+    }
+    else
+      std::abort();
+  }
+
+  std::string m_name;
+  DataVector<Y_v1>* m_pers1;
+  DataVector<Y_v2>* m_pers2;
+};
+
+
+class YCnv_v1
+{
+public:
+  typedef DataVector<Y_v2> Trans_t;
+  typedef DataVector<Y_v1> Pers_t;
+  
+  DataVector<Y_v2>* createTransient (const DataVector<Y_v1>* pers, MsgStream& msg)
+  {
+    auto trans = CxxUtils::make_unique<DataVector<Y_v2> >();
+    persToTrans (pers, trans.get(), msg);
+    return trans.release();
+  }
+
+  void persToTrans (const DataVector<Y_v1>* pers, DataVector<Y_v2>* trans, MsgStream&)
+  {
+    for (const Y_v1* y : *pers)
+      trans->push_back (new Y_v2 (y->m_a * 3));
+  }
+};
+
+
+void test1 (ISvcLocator* svcloc, TestCnvSvc& testsvc)
+{
+  std::cout << "test1\n";
+  const size_t N = 10;
+
+  T_AthenaPoolxAODCnv<DataVector<Y_v2>, YCnv_v1> cnv (svcloc);
+  assert (static_cast<AthenaPoolConverter&>(cnv).initialize().isSuccess());
+
+  DataVector<Y_v2> trans1;
+  for (size_t i=0; i < N; i++)
+    trans1.push_back (new Y_v2(i));
+
+  DataVector<Y_v2>* pers1 = cnv.createPersistent (&trans1);
+  assert (pers1->size() == trans1.size());
+  for (size_t i = 0; i < N; i++)
+    assert ((*pers1)[i] == trans1[i]);
+
+  testsvc.m_pers2 = pers1;
+  Token* token = new Token;
+  token->setClassID (Guid (YCont_v2_guid));
+  TokenAddress taddr (0, 0, "xyz", "key", 0, token);
+
+  DataObject* pObj = nullptr;
+  assert (cnv.createObj (&taddr, pObj).isSuccess());
+  auto* trans2 = SG::Storable_cast<DataVector<Y_v2> > (pObj);
+  assert (trans2->size() == 10);
+  for (size_t i = 0; i < 10; i++)
+    assert ((*trans2)[i]->m_a == (int)i);
+  assert (trans2->getConstStoreLink().dataID() == "keyAux.");
+  delete pObj;
+  delete pers1;
+  testsvc.m_pers2 = nullptr;
+
+  DataVector<Y_v1> pers_old;
+  for (size_t i=0; i < N; i++)
+    pers_old.push_back (new Y_v1(i));
+  testsvc.m_pers1 = &pers_old;
+  token->setClassID (Guid (YCont_v1_guid));
+  pObj = nullptr;
+  assert (cnv.createObj (&taddr, pObj).isSuccess());
+  auto* trans3 = SG::Storable_cast<DataVector<Y_v2> > (pObj);
+  assert (trans3->size() == 10);
+  for (size_t i = 0; i < 10; i++)
+    assert ((*trans3)[i]->m_a == (int)i*3);
+  assert (trans3->getConstStoreLink().dataID() == "keyAux.");
+  delete pObj;
+
+  token->setClassID (Guid ("8ACD1C53-D3C7-4FE5-9BC0-E388701DB8FA"));
+  pObj = nullptr;
+  assert (cnv.createObj (&taddr, pObj).isFailure());
+}
+
+
+int main()
+{
+  SGTest::initTestStore();
+  ISvcLocator* pSvcLoc = nullptr;
+  if (!Athena_test::initGaudi("test.txt", pSvcLoc)) {
+    std::cerr << "This test can not be run" << std::endl;
+    return 0;
+  }
+
+  TestCnvSvc* svc = new TestCnvSvc ("AthenaPoolCnvSvc", pSvcLoc);
+  ISvcManager* mgr = dynamic_cast<ISvcManager*> (pSvcLoc);
+  if (mgr->addService (svc).isFailure())
+    std::abort();
+  
+  gSystem->Load("libAthenaPoolCnvSvcTestDict");
+
+  test1 (pSvcLoc, *svc);
+  return 0;
+}
diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/test/TestCnvSvcBase.icc b/Database/AthenaPOOL/AthenaPoolCnvSvc/test/TestCnvSvcBase.icc
new file mode 100644
index 00000000000..a245f02b89a
--- /dev/null
+++ b/Database/AthenaPOOL/AthenaPoolCnvSvc/test/TestCnvSvcBase.icc
@@ -0,0 +1,145 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// $Id$
+/**
+ * @file AthenaPoolCnvSvc/test/TestCnvSvcBase.icc
+ * @author scott snyder <snyder@bnl.gov>
+ * @date Jan, 2016
+ * @brief Helper for AthenaPoolCnvSvc unit tests.
+ */
+
+
+#include "AthenaPoolCnvSvc/IAthenaPoolCnvSvc.h"
+#include "AthenaBaseComps/AthService.h"
+#include "StorageSvc/DbType.h"
+
+
+class TestCnvSvcBase
+  : public IAthenaPoolCnvSvc, public AthService
+{
+public:
+  TestCnvSvcBase (const std::string& name, ISvcLocator* svcloc)
+    : AthService (name, svcloc),
+      m_name (name)
+  {}
+  
+  virtual StatusCode disconnectOutput() override
+  { std::abort(); }
+   virtual const std::string& getOutputConnectionSpec() const override
+  { std::abort(); }
+  virtual std::string getOutputContainer(const std::string& /*typeName*/,
+                                         const std::string& /*key*/ = "") const override
+  { std::abort(); }
+  virtual pool::DbType technologyType() const override
+  { std::abort(); }
+  virtual IPoolSvc* getPoolSvc() override
+  { std::abort(); }
+  virtual const Token* registerForWrite(const Placement* /*placement*/,
+                                        const void* /*obj*/,
+                                        const RootType& /*classDesc*/) const override
+  { std::abort(); }
+  virtual bool useDetailChronoStat() const override
+  { std::abort(); }
+  virtual StatusCode createAddress(long /*svcType*/,
+                                   const CLID& /*clid*/,
+                                   const std::string* /*par*/,
+                                   const unsigned long* /*ip*/,
+                                   IOpaqueAddress*& /*refpAddress*/) override
+  { std::abort(); }
+  virtual StatusCode createAddress(long /*svcType*/,
+                                   const CLID& /*clid*/,
+                                   const std::string& /*refAddress*/,
+                                   IOpaqueAddress*& /*refpAddress*/) override
+  { std::abort(); }
+  virtual StatusCode convertAddress(const IOpaqueAddress* /*pAddress*/,
+                                    std::string& /*refAddress*/) override
+  
+  { std::abort(); }
+  virtual StatusCode makeServer(int /*num*/) override
+  { std::abort(); }
+  virtual StatusCode makeClient(int /*num*/) override
+  { std::abort(); }
+  virtual StatusCode cleanUp() override
+  { std::abort(); }
+  virtual StatusCode setInputAttributes(const std::string& /*fileName*/) override
+  { std::abort(); }
+
+  virtual StatusCode initialize() override
+  { std::abort(); }
+  virtual StatusCode finalize() override
+  { std::abort(); }
+  virtual const CLID& objType() const override
+  { std::abort(); }
+  virtual long repSvcType() const override
+  { std::abort(); }
+  virtual StatusCode setDataProvider(IDataProviderSvc* /*pService*/) override
+  { std::abort(); }
+  virtual SmartIF<IDataProviderSvc>& dataProvider() const override
+  { std::abort(); }
+  virtual StatusCode setConversionSvc(IConversionSvc* /*pService*/) override
+  { std::abort(); }
+  virtual SmartIF<IConversionSvc>& conversionSvc()    const override
+  { std::abort(); }
+  virtual StatusCode setAddressCreator(IAddressCreator* /*creator*/) override
+  { std::abort(); }
+  virtual SmartIF<IAddressCreator>& addressCreator()    const override
+  { std::abort(); }
+  virtual StatusCode createObj(IOpaqueAddress* /*pAddress*/, DataObject*& /*refpObject*/) override
+  { std::abort(); }
+  virtual StatusCode fillObjRefs(IOpaqueAddress* /*pAddress*/, DataObject* /*pObject*/) override
+  { std::abort(); }
+  virtual StatusCode updateObj(IOpaqueAddress* /*pAddress*/, DataObject* /*refpObject*/) override
+  { std::abort(); }
+  virtual StatusCode updateObjRefs(IOpaqueAddress* /*pAddress*/, DataObject* /*pObject*/) override
+  { std::abort(); }
+  virtual StatusCode createRep(DataObject* /*pObject*/, IOpaqueAddress*& /*refpAddress*/) override
+  { std::abort(); }
+  virtual StatusCode fillRepRefs(IOpaqueAddress* /*pAddress*/, DataObject* /*pObject*/) override
+  { std::abort(); }
+  virtual StatusCode updateRep(IOpaqueAddress* /*pAddress*/, DataObject* /*pObject*/)  override
+  { std::abort(); }
+  virtual StatusCode updateRepRefs(IOpaqueAddress* /*pAddress*/, DataObject* /*pObject*/) override
+  { std::abort(); }
+  virtual StatusCode addConverter(const CLID& /*clid*/) override
+  { std::abort(); }
+  virtual StatusCode removeConverter(const CLID& /*clid*/) override
+  { std::abort(); }
+  virtual IConverter* converter(const CLID& /*clid*/) override
+  { std::abort(); }
+  virtual StatusCode connectOutput(const std::string& /*outputFile*/) override
+  { std::abort(); }
+  virtual StatusCode readData() const override
+  { std::abort(); }
+  virtual const std::string& name() const override
+  { return m_name; }
+  virtual StatusCode addConverter(IConverter* /*pConverter*/) override
+  { std::abort(); }
+  virtual StatusCode connectOutput(const std::string& /*outputFile*/,
+                                   const std::string& /*openMode*/) override
+  { std::abort(); }
+  virtual StatusCode commitOutput(const std::string& /*outputFile*/,
+                                  bool /*do_commit*/) override
+  { std::abort(); }
+
+
+  
+  virtual StatusCode queryInterface(const InterfaceID &ti, void** pp) override
+  {
+    if (ti == IID_IAthenaPoolCnvSvc) {
+      *pp = this;
+      return StatusCode::SUCCESS;
+    }
+    return Service::queryInterface (ti, pp);
+  }
+  
+  virtual StatusCode registerCleanUp(IAthenaPoolCleanUp* /*cnv*/) override
+  {
+    return StatusCode::SUCCESS;
+  }
+
+  std::string m_name;
+};
+
+
diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/test/TestThinningSvc.icc b/Database/AthenaPOOL/AthenaPoolCnvSvc/test/TestThinningSvc.icc
new file mode 100644
index 00000000000..1cc613c983d
--- /dev/null
+++ b/Database/AthenaPOOL/AthenaPoolCnvSvc/test/TestThinningSvc.icc
@@ -0,0 +1,138 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// $Id$
+/**
+ * @file TestThinningSvc.icc
+ * @author scott snyder <snyder@bnl.gov>
+ * @date Jul, 2014
+ * @brief Dummy thinning service, for regression tests.
+ */
+
+
+#include "SGTools/DataProxy.h"
+#include "SGTools/TestStore.h"
+#include "AthenaKernel/IThinningSvc.h"
+#include <map>
+
+
+class TestThinningSvc
+  : virtual public IThinningSvc, public SGTest::TestStore
+{
+public:
+  StatusCode sysInitialize() override
+  { std::cout << "sysInitialize\n"; std::abort(); }
+  StatusCode sysStart() override
+  { std::cout << "sysStart\n"; std::abort(); }
+  StatusCode sysStop() override
+  { std::cout << "sysStop\n"; std::abort(); }
+  StatusCode sysFinalize() override
+  { std::cout << "sysFinalize\n"; std::abort(); }
+  StatusCode sysReinitialize() override
+  { std::cout << "sysReinitialize\n"; std::abort(); }
+  StatusCode sysRestart() override
+  { std::cout << "sysRestart\n"; std::abort(); }
+  StatusCode configure() override
+  { std::cout << "configure\n"; std::abort(); }
+  StatusCode initialize() override
+  { std::cout << "initialize\n"; std::abort(); }
+  StatusCode start() override
+  { std::cout << "start\n"; std::abort(); }
+  StatusCode stop() override
+  { std::cout << "stop\n"; std::abort(); }
+  StatusCode finalize() override
+  { std::cout << "finalize\n"; std::abort(); }
+  StatusCode terminate() override
+  { std::cout << "terminate\n"; std::abort(); }
+  StatusCode reinitialize() override
+  { std::cout << "reinitialize\n"; std::abort(); }
+  StatusCode restart() override
+  { std::cout << "restart\n"; std::abort(); }
+  Gaudi::StateMachine::State FSMState() const override
+  { std::cout << "FSMState\n"; std::abort(); }
+  Gaudi::StateMachine::State targetFSMState() const override
+  { std::cout << "targetFSMState\n"; std::abort(); }
+  void setServiceManager (ISvcManager*) override
+  { std::cout << "setServiceManager\n"; std::abort(); }
+  StatusCode register_slimmer (Athena::ISlimmingHdlr */*handler*/) override
+  { std::cout << "register_slimmer\n"; std::abort(); }
+  virtual Athena::IThinningHdlr* handler( SG::DataProxy* /*proxy*/ ) override
+  { std::cout << "handler\n"; std::abort(); }
+  virtual StatusCode
+  filter_impl( Athena::IThinningHdlr* /*handler*/,
+               SG::DataProxy* /*proxy*/,
+               const Filter_t& /*filter*/,
+               const IThinningSvc::Operator::Type /*op*/ = Operator::And ) override
+  { std::cout << "filter_impl\n"; std::abort(); }
+  StatusCode commit() override
+  { std::cout << "commit\n"; std::abort(); }
+  StatusCode rollback() override
+  { std::cout << "rollback\n"; std::abort(); }
+  virtual
+  sgkey_t stringToKey (const std::string& /*str*/, CLID /*clid*/) override
+  { std::abort(); }
+  virtual
+  const std::string* keyToString (sgkey_t /*key*/) const override
+  { std::abort(); }
+  virtual
+  const std::string* keyToString (sgkey_t /*key*/,
+                                  CLID& /*clid*/) const override
+  { std::abort(); }
+  virtual
+  void registerKey (sgkey_t /*key*/,
+                    const std::string& /*str*/,
+                    CLID /*clid*/) override
+  { std::abort(); }
+
+  virtual
+  bool thinningOccurred() const override
+  {
+    return m_map.size() > 0;
+  }
+
+  virtual
+  bool is_thinned_impl(const SG::DataProxy* p) const override
+  {
+    proxymap_t::const_iterator i = m_map.find (p);
+    if (i != m_map.end())
+      return true;
+    return false;
+  }
+
+  using SGTest::TestStore::proxy;
+  virtual
+  SG::DataProxy* proxy(const void* const pTransient) const override
+  {
+    return SG::CurrentEventStore::store()->proxy (pTransient);
+  }
+
+  virtual
+  std::size_t index_impl( const SG::DataProxy* objProxy, 
+                          std::size_t idx ) const override
+  {
+    proxymap_t::const_iterator i = m_map.find (objProxy);
+    if (i != m_map.end()) {
+      map_t::const_iterator ii = i->second.find (idx);
+      if (ii != i->second.end())
+        return ii->second;
+    }
+    return idx;
+  }
+
+  void remap (const void* obj, size_t from, size_t to)
+  {
+    SG::DataProxy* proxy = SG::CurrentEventStore::store()->proxy (obj);
+    
+    if (!proxy) {
+      std::abort();
+    }
+
+    m_map[proxy][from] = to;
+  }
+
+  typedef std::map<size_t, size_t> map_t;
+
+  typedef std::map<const SG::DataProxy*, map_t> proxymap_t;
+  proxymap_t m_map;
+};
diff --git a/Database/AthenaPOOL/AthenaPoolCnvSvc/test/exceptions_test.cxx b/Database/AthenaPOOL/AthenaPoolCnvSvc/test/exceptions_test.cxx
new file mode 100644
index 00000000000..c72d18fa9ce
--- /dev/null
+++ b/Database/AthenaPOOL/AthenaPoolCnvSvc/test/exceptions_test.cxx
@@ -0,0 +1,35 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// $Id$
+/**
+ * @file AthenaPoolCnvSvc/test/exceptions_test.cxx
+ * @author scott snyder <snyder@bnl.gov>
+ * @date Jan, 2016
+ * @brief Tests for exceptions.
+ */
+
+
+#undef NDEBUG
+#include "AthenaPoolCnvSvc/exceptions.h"
+#include <iostream>
+#include <typeinfo>
+
+
+void test1()
+{
+  std::cout << "test1\n";
+
+  std::cout << AthenaPoolCnvSvc::ExcNoDictForClass (typeid(int)).what() << "\n";
+  std::cout << AthenaPoolCnvSvc::ExcUnsupportedVersion
+    ( typeid(int),
+      Guid("336F636C-D414-4261-8286-37429F353F0A") ).what() << "\n";
+}
+
+
+int main()
+{
+  test1();
+  return 0;
+}
-- 
GitLab