diff --git a/Control/DataModelTest/DataModelTestDataRead/DataModelTestDataRead/BDer.h b/Control/DataModelTest/DataModelTestDataRead/DataModelTestDataRead/BDer.h
new file mode 100644
index 0000000000000000000000000000000000000000..a05efbda5b2c61348639f0448a90a0b04bcdcffa
--- /dev/null
+++ b/Control/DataModelTest/DataModelTestDataRead/DataModelTestDataRead/BDer.h
@@ -0,0 +1,51 @@
+// 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: BDer.h,v 1.4 2007-10-17 01:01:47 ssnyder Exp $
+
+/**
+ * @file  DataModelTestDataRead/BVec.h
+ * @author snyder@bnl.gov
+ * @date Nov 2005
+ * @brief Class used for testing the new @c DataVector inheritance scheme.
+ *
+ *        This is a class deriving from a @c DataVector
+ *        containing the base class, @c B.
+ */
+
+
+#ifndef DATAMODELTESTDATAREAD_BDER_H
+#define DATAMODELTESTDATAREAD_BDER_H
+
+
+#include "DataModelTestDataRead/BVec.h"
+#include "AthLinks/ElementLink.h"
+#include "SGTools/BaseInfo.h"
+#include "CLIDSvc/CLASS_DEF.h"
+
+
+namespace DMTest {
+
+
+/**
+ * @brief A class deriving from @c DataVector containing the base class, @c B.
+ */
+struct BDer
+  : public BVec
+{
+private:
+  ElementLink<BVec> m_el;
+};
+
+
+}
+
+CLASS_DEF (DMTest::BDer, 9631, 1)
+
+// Tell StoreGate that BDer derives from BVec.
+SG_BASE(DMTest::BDer, DMTest::BVec);
+
+#endif // not DATAMODELTESTDATAREAD_BDER_H
diff --git a/Control/DataModelTest/DataModelTestDataRead/DataModelTestDataRead/BVec.h b/Control/DataModelTest/DataModelTestDataRead/DataModelTestDataRead/BVec.h
new file mode 100644
index 0000000000000000000000000000000000000000..ce3cb82806a4961b1355b5baa19c5d0f6dd5e505
--- /dev/null
+++ b/Control/DataModelTest/DataModelTestDataRead/DataModelTestDataRead/BVec.h
@@ -0,0 +1,44 @@
+// 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: BVec.h,v 1.3 2007-10-17 01:01:47 ssnyder Exp $
+
+/**
+ * @file  DataModelTestDataRead/BVec.h
+ * @author snyder@bnl.gov
+ * @date Nov 2005
+ * @brief Class used for testing the new @c DataVector inheritance scheme.
+ *
+ *        This is a @c DataVector containing the base class, @c B.
+ */
+
+#ifndef DATAMODELTESTDATAREAD_BVEC_H
+#define DATAMODELTESTDATAREAD_BVEC_H
+
+
+#include "DataModelTestDataCommon/B.h"
+#include "AthContainers/DataVector.h"
+#include "CLIDSvc/CLASS_DEF.h"
+
+
+namespace DMTest {
+
+
+/**
+ * @brief A @c DataVector containing the base class, @c B.
+ *
+ * The redundant DMTest:: is required by the stupid pooliohander machinery.
+ */
+typedef DataVector<DMTest::B> BVec;
+
+
+}
+
+
+CLASS_DEF (DataVector<DMTest::B>, 9633, 1)
+
+
+#endif // not DATAMODELTESTDATAREAD_BVEC_H
diff --git a/Control/DataModelTest/DataModelTestDataRead/DataModelTestDataRead/DDer.h b/Control/DataModelTest/DataModelTestDataRead/DataModelTestDataRead/DDer.h
new file mode 100644
index 0000000000000000000000000000000000000000..3c473eebdfb5480e5ff4f59b9a45c2bdd6600fa8
--- /dev/null
+++ b/Control/DataModelTest/DataModelTestDataRead/DataModelTestDataRead/DDer.h
@@ -0,0 +1,49 @@
+// 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: DDer.h,v 1.3 2007-01-31 03:12:39 ssnyder Exp $
+
+/**
+ * @file  DataModelTestDataRead/DDer.h
+ * @author snyder@bnl.gov
+ * @date Nov 2005
+ * @brief Class used for testing the new @c DataVector inheritance scheme.
+ *
+ *        This is a class deriving from a @c DataVector
+ *        containing the derived class, @c D.
+ */
+
+
+#ifndef DATAMODELTESTDATAREAD_DDER_H
+#define DATAMODELTESTDATAREAD_DDER_H
+
+
+#include "DataModelTestDataRead/DVec.h"
+#include "SGTools/BaseInfo.h"
+#include "CLIDSvc/CLASS_DEF.h"
+
+
+namespace DMTest {
+
+
+/**
+ * @brief A class deriving from @c DataVector
+ *        containing the derived class, @c D.
+ */
+struct DDer
+  : public DVec
+{
+};
+
+
+}
+
+CLASS_DEF (DMTest::DDer, 9632, 1)
+
+// Tell StoreGate that DDer derives from DVec.
+SG_BASE(DMTest::DDer, DMTest::DVec);
+
+#endif // not DATAMODELTESTDATAREAD_DDER_H
diff --git a/Control/DataModelTest/DataModelTestDataRead/DataModelTestDataRead/DVec.h b/Control/DataModelTest/DataModelTestDataRead/DataModelTestDataRead/DVec.h
new file mode 100644
index 0000000000000000000000000000000000000000..14db01b519828dc6ad0379a09526fbbbe576cedb
--- /dev/null
+++ b/Control/DataModelTest/DataModelTestDataRead/DataModelTestDataRead/DVec.h
@@ -0,0 +1,51 @@
+// 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: DVec.h,v 1.2 2007-01-31 03:12:39 ssnyder Exp $
+
+/**
+ * @file  DataModelTestDataRead/DVec.h
+ * @author snyder@bnl.gov
+ * @date Nov 2005
+ * @brief Class used for testing the new @c DataVector inheritance scheme.
+ *
+ *        This is a @c DataVector containing the derived class, @c D.
+ *        We set things up so that in this package, @c DVec derives
+ *        from @c BVec.
+ */
+
+#ifndef DATAMODELTESTDATAREAD_DVEC_H
+#define DATAMODELTESTDATAREAD_DVEC_H
+
+
+#include "DataModelTestDataCommon/D.h"
+// Next include needed here to make sure we get the CLID
+// for BVec.
+#include "DataModelTestDataRead/BVec.h"
+#include "AthContainers/DataVector.h"
+#include "CLIDSvc/CLASS_DEF.h"
+
+
+// Set up the inheritance relation between the @c DataVector classes.
+DATAVECTOR_VIRTBASES1 (DMTest::D, DMTest::B);
+
+
+namespace DMTest {
+
+
+/**
+ * @brief A @c DataVector containing the derived class, @c B.
+ */
+typedef DataVector<D> DVec;
+
+
+}
+
+
+CLASS_DEF (DataVector<DMTest::D>, 9634, 1)
+
+
+#endif // not DATAMODELTESTDATAREAD_DVEC_H
diff --git a/Control/DataModelTest/DataModelTestDataRead/DataModelTestDataRead/DataModelTestDataReadDict.h b/Control/DataModelTest/DataModelTestDataRead/DataModelTestDataRead/DataModelTestDataReadDict.h
new file mode 100644
index 0000000000000000000000000000000000000000..bbf9f2e29aaf2a986c7236869239f06e1b954626
--- /dev/null
+++ b/Control/DataModelTest/DataModelTestDataRead/DataModelTestDataRead/DataModelTestDataReadDict.h
@@ -0,0 +1,31 @@
+// 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: DataModelTestDataReadDict.h,v 1.3 2008-04-18 03:42:12 ssnyder Exp $
+
+/**
+ * @file  DataModelTestDataRead/DataModelTestDataReadDict.h
+ * @author snyder@bnl.gov
+ * @date Nov 2005
+ * @brief Dictionary generation header.
+ */
+
+#ifndef DATAMODELTESTDATAREADDICT_H
+#define DATAMODELTESTDATAREADDICT_H
+
+#include "DataModelTestDataRead/BVec.h"
+#include "DataModelTestDataRead/BDer.h"
+#include "DataModelTestDataRead/DVec.h"
+#include "DataModelTestDataRead/DDer.h"
+#include "DataModelTestDataRead/ELVec.h"
+
+struct dummy {
+  ElementLink<DMTest::BVec> m_dum1;
+  DataLink<DMTest::BVec> m_dum2;
+};
+
+#endif // not DATAMODELTESTDATAREADDICT_H
+
diff --git a/Control/DataModelTest/DataModelTestDataRead/DataModelTestDataRead/ELVec.h b/Control/DataModelTest/DataModelTestDataRead/DataModelTestDataRead/ELVec.h
new file mode 100644
index 0000000000000000000000000000000000000000..f7f1f3f011cbedf79e9ee1e9cdff3cf9f77f5d75
--- /dev/null
+++ b/Control/DataModelTest/DataModelTestDataRead/DataModelTestDataRead/ELVec.h
@@ -0,0 +1,59 @@
+// 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: ELVec.h,v 1.4 2008-11-21 06:29:05 ssnyder Exp $
+
+/**
+ * @file  DataModelTestDataRead/ELVec.h
+ * @author snyder@bnl.gov
+ * @date May 2007
+ * @brief Class used for testing new @c ElementLink.
+ */
+
+#ifndef DATAMODELTESTDATAREAD_ELVEC_H
+#define DATAMODELTESTDATAREAD_ELVEC_H
+
+
+#include "DataModelTestDataRead/BVec.h"
+#include "AthLinks/ElementLink.h"
+#include "AthLinks/ElementLinkVector.h"
+#include "AthLinks/DataLink.h"
+#include "DataModelAthenaPool/ElementLinkVector_p1.h"
+#include "DataModelAthenaPool/ElementLink_p3.h"
+#include "DataModelAthenaPool/DataLink_p1.h"
+#include "CLIDSvc/CLASS_DEF.h"
+
+
+namespace DMTest {
+
+
+/**
+ * @brief For testing @c ElementLink.
+ */
+struct ELVec
+{
+  std::vector<ElementLink<BVec> > m_el;
+  std::vector<DataLink<BVec> > m_dl;
+  ElementLinkVector<BVec> m_elv;
+
+  ElementLinkVector<BVec> m_elv2;    // Transient
+  ElementLinkIntVector_p1 m_elv2_p;
+
+  std::vector<ElementLink<BVec> > m_el2; // Transient
+  std::vector<ElementLinkInt_p3> m_el2_p;
+
+  std::vector<DataLink<BVec> > m_dl2; // Transient
+  std::vector<DataLink_p1> m_dl2_p;
+};
+
+
+}
+
+
+CLASS_DEF (DMTest::ELVec, 9639, 1)
+
+
+#endif // not DATAMODELTESTDATAREAD_ELVEC_H
diff --git a/Control/DataModelTest/DataModelTestDataRead/DataModelTestDataRead/selection.xml b/Control/DataModelTest/DataModelTestDataRead/DataModelTestDataRead/selection.xml
new file mode 100644
index 0000000000000000000000000000000000000000..0e9f90c54e14b78fa0a386631c0c2d3228a15fab
--- /dev/null
+++ b/Control/DataModelTest/DataModelTestDataRead/DataModelTestDataRead/selection.xml
@@ -0,0 +1,26 @@
+<!--
+  $Id: selection.xml,v 1.7 2008-11-21 06:29:05 ssnyder Exp $
+
+  File: DataModelTestDataRead/selection.xml
+  Author: snyder@bnl.gov
+  Date: Nov 2005
+  Purpose: LCG dictionary generation selection file.
+-->
+
+<lcgdict>
+
+  <class name="DMTest::BDer" id="F899E479-B507-44CD-B571-B3CD254D215D"/>
+  <class name="DMTest::DDer" id="BF1FF2FB-332A-497B-B55E-D704108C68D0"/>
+  <class name="std::vector<DMTest::B*>"/>
+  <class name="DataVector<DMTest::B>" id="726A6BED-3DD9-4AD9-9F5E-1DCBFA42EB75"/>
+  <class name="DataVector<DMTest::D>" id="14085919-C66D-45B2-A183-17D77986CACC"/>
+  <class name="DataVector_detail::VirtBases<DMTest::B>"/>
+
+  <class name="DMTest::ELVec" id="08A5FE26-1553-44E0-BFC4-196B96D3AD44">
+    <field name="m_elv2" transient="true"/>
+    <field name="m_el2" transient="true"/>
+    <field name="m_dl2" transient="true"/>
+  </class>
+
+  <class name="std::vector<ElementLink<DataVector<DMTest::B> > >"/>
+</lcgdict>
diff --git a/Control/DataModelTest/DataModelTestDataRead/cmt/requirements b/Control/DataModelTest/DataModelTestDataRead/cmt/requirements
new file mode 100644
index 0000000000000000000000000000000000000000..6dfe30fa45bb92e364aee4a77fa0fdc83cc481bf
--- /dev/null
+++ b/Control/DataModelTest/DataModelTestDataRead/cmt/requirements
@@ -0,0 +1,44 @@
+#
+# $Id: requirements,v 1.7 2008-06-12 05:25:52 ssnyder Exp $
+#
+# @file  cmt/requirements
+# @author snyder@bnl.gov
+# @date Nov 2005
+# @brief DataModelTestDataRead cmt requirements file.
+#
+
+package DataModelTestDataRead
+
+author scott snyder <snyder@bnl.gov>
+
+use AtlasPolicy             AtlasPolicy-*
+use AthContainers           AthContainers-*           Control
+use AthLinks                AthLinks-*                Control
+use DataModelAthenaPool     DataModelAthenaPool-*     Control
+use DataModelTestDataCommon DataModelTestDataCommon-* Control/DataModelTest
+use GaudiInterface          GaudiInterface-*          External
+use CLIDSvc                 CLIDSvc-*                 Control
+use SGTools                 SGTools-*                 Control
+
+
+private
+use CxxUtils                CxxUtils-*                Control
+use AthenaKernel            AthenaKernel-*            Control
+use StoreGate               StoreGate-*               Control
+use AthenaBaseComps         AthenaBaseComps-*         Control
+use xAODCore                xAODCore-*                Event/xAOD
+end_private
+
+apply_pattern component_library
+library DataModelTestDataRead *.cxx components/*.cxx
+
+private
+use AtlasReflex  AtlasReflex-*  External  -no_auto_imports
+
+macro elemLinks_DataModelTestDataRead "DataVector<DMTest::B>"
+
+apply_tag no_rootmap
+apply_pattern lcgdict dict=DataModelTestDataRead selectionfile=selection.xml\
+  headerfiles="../DataModelTestDataRead/DataModelTestDataReadDict.h" \
+  elementLinks="$(elemLinks_DataModelTestDataRead)"
+
diff --git a/Control/DataModelTest/DataModelTestDataRead/src/AuxDataTestClearDecor.cxx b/Control/DataModelTest/DataModelTestDataRead/src/AuxDataTestClearDecor.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..24473500c822733f1f5c68571418519041220f50
--- /dev/null
+++ b/Control/DataModelTest/DataModelTestDataRead/src/AuxDataTestClearDecor.cxx
@@ -0,0 +1,72 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// $Id$
+/**
+ * @file  src/AuxDataTestClearDecor.cxx
+ * @author snyder@bnl.gov
+ * @date May 2014
+ * @brief Algorithm to test clearing @c DataVector decorations.
+ */
+
+
+#include "AuxDataTestClearDecor.h"
+#include "DataModelTestDataCommon/BAux.h"
+#include "DataModelTestDataCommon/BAuxVec.h"
+#include "AthenaKernel/errorcheck.h"
+
+
+namespace DMTest {
+
+
+/**
+ * @brief Constructor.
+ * @param name The algorithm name.
+ * @param svc The service locator.
+ */
+AuxDataTestClearDecor::AuxDataTestClearDecor (const std::string &name,
+                                              ISvcLocator *pSvcLocator)
+  : AthAlgorithm (name, pSvcLocator)
+{
+  declareProperty ("ReadPrefix",  m_readPrefix);
+}
+  
+
+/**
+ * @brief Algorithm initialization; called at the beginning of the job.
+ */
+StatusCode AuxDataTestClearDecor::initialize()
+{
+  return StatusCode::SUCCESS;
+}
+
+
+/**
+ * @brief Algorithm event processing.
+ */
+StatusCode AuxDataTestClearDecor::execute()
+{
+  const BAuxVec* vec = 0;
+  CHECK( evtStore()->retrieve (vec, m_readPrefix + "bauxvec") );
+  vec->clearDecorations();
+
+  const BAux* b = 0;
+  CHECK( evtStore()->retrieve (b, m_readPrefix + "b") );
+  b->clearDecorations();
+
+  return StatusCode::SUCCESS;
+}
+
+
+/**
+ * @brief Algorithm finalization; called at the end of the job.
+ */
+StatusCode AuxDataTestClearDecor::finalize()
+{
+  return StatusCode::SUCCESS;
+}
+
+
+} // namespace DMTest
+
diff --git a/Control/DataModelTest/DataModelTestDataRead/src/AuxDataTestClearDecor.h b/Control/DataModelTest/DataModelTestDataRead/src/AuxDataTestClearDecor.h
new file mode 100644
index 0000000000000000000000000000000000000000..602161df36cefd634e3776447c7162f79eca84d2
--- /dev/null
+++ b/Control/DataModelTest/DataModelTestDataRead/src/AuxDataTestClearDecor.h
@@ -0,0 +1,69 @@
+// 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 src/AuxDataTestClearDecor.h
+ * @author scott snyder <snyder@bnl.gov>
+ * @date May, 2014
+ * @brief Algorithm to test clearing @c DataVector decorations.
+ */
+
+
+#ifndef DATAMODELTESTDATAREAD_AUXDATATESTCLEARDECOR_H
+#define DATAMODELTESTDATAREAD_AUXDATATESTCLEARDECOR_H
+
+
+#include "AthenaBaseComps/AthAlgorithm.h"
+
+
+namespace DMTest {
+
+
+/**
+ * @brief Algorithm to test adding decorations to a @c DataVector
+ *        with auxiliary data.
+ */
+class AuxDataTestClearDecor
+  : public AthAlgorithm
+{
+public:
+  /**
+   * @brief Constructor.
+   * @param name The algorithm name.
+   * @param svc The service locator.
+   */
+  AuxDataTestClearDecor (const std::string &name, ISvcLocator *pSvcLocator);
+  
+
+  /**
+   * @brief Algorithm initialization; called at the beginning of the job.
+   */
+  virtual StatusCode initialize();
+
+
+  /**
+   * @brief Algorithm event processing.
+   */
+  virtual StatusCode execute(); 
+
+
+  /**
+   * @brief Algorithm finalization; called at the end of the job.
+   */
+  virtual StatusCode finalize();
+
+
+private:
+  /// Parameter: Prefix for names read from SG.
+  std::string m_readPrefix;
+};
+
+
+} // namespace DMTest
+
+
+#endif // not DATAMODELTESTDATAREAD_AUXDATATESTCLEARDECOR_H
diff --git a/Control/DataModelTest/DataModelTestDataRead/src/AuxDataTestDecor.cxx b/Control/DataModelTest/DataModelTestDataRead/src/AuxDataTestDecor.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..671f6e22d93079a8adddae039839e60765931bdb
--- /dev/null
+++ b/Control/DataModelTest/DataModelTestDataRead/src/AuxDataTestDecor.cxx
@@ -0,0 +1,78 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// $Id$
+/**
+ * @file  src/AuxDataTestDecor.cxx
+ * @author snyder@bnl.gov
+ * @date May 2014
+ * @brief Algorithm to test adding decorations to a @c DataVector
+ *        with auxiliary data.
+ */
+
+
+#include "AuxDataTestDecor.h"
+#include "DataModelTestDataCommon/BAux.h"
+#include "DataModelTestDataCommon/BAuxVec.h"
+#include "AthenaKernel/errorcheck.h"
+
+
+namespace DMTest {
+
+
+/**
+ * @brief Constructor.
+ * @param name The algorithm name.
+ * @param svc The service locator.
+ */
+AuxDataTestDecor::AuxDataTestDecor (const std::string &name,
+                                    ISvcLocator *pSvcLocator)
+  : AthAlgorithm (name, pSvcLocator)
+{
+  declareProperty ("ReadPrefix",  m_readPrefix);
+  declareProperty ("DecorName",   m_decorName = "dInt1");
+  declareProperty ("Offset",      m_offset = 100);
+}
+  
+
+/**
+ * @brief Algorithm initialization; called at the beginning of the job.
+ */
+StatusCode AuxDataTestDecor::initialize()
+{
+  return StatusCode::SUCCESS;
+}
+
+
+/**
+ * @brief Algorithm event processing.
+ */
+StatusCode AuxDataTestDecor::execute()
+{
+  BAux::Decorator<int> dInt1 (m_decorName);
+
+  const BAuxVec* vec = 0;
+  CHECK( evtStore()->retrieve (vec, m_readPrefix + "bauxvec") );
+  for (const BAux* belt : *vec)
+    dInt1(*belt) = m_offset + belt->m_x;
+
+  const BAux* b = 0;
+  CHECK( evtStore()->retrieve (b, m_readPrefix + "b") );
+  dInt1(*b) = 400 + m_offset + b->m_x;
+
+  return StatusCode::SUCCESS;
+}
+
+
+/**
+ * @brief Algorithm finalization; called at the end of the job.
+ */
+StatusCode AuxDataTestDecor::finalize()
+{
+  return StatusCode::SUCCESS;
+}
+
+
+} // namespace DMTest
+
diff --git a/Control/DataModelTest/DataModelTestDataRead/src/AuxDataTestDecor.h b/Control/DataModelTest/DataModelTestDataRead/src/AuxDataTestDecor.h
new file mode 100644
index 0000000000000000000000000000000000000000..74c634b0a03dee5565d8830e864287fedab38935
--- /dev/null
+++ b/Control/DataModelTest/DataModelTestDataRead/src/AuxDataTestDecor.h
@@ -0,0 +1,76 @@
+// 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 src/AuxDataTestDecor.h
+ * @author scott snyder <snyder@bnl.gov>
+ * @date May, 2014
+ * @brief Algorithm to test adding decorations to a @c DataVector
+ *        with auxiliary data.
+ */
+
+
+#ifndef DATAMODELTESTDATAREAD_AUXDATATESTDECOR_H
+#define DATAMODELTESTDATAREAD_AUXDATATESTDECOR_H
+
+
+#include "AthenaBaseComps/AthAlgorithm.h"
+
+
+namespace DMTest {
+
+
+/**
+ * @brief Algorithm to test adding decorations to a @c DataVector
+ *        with auxiliary data.
+ */
+class AuxDataTestDecor
+  : public AthAlgorithm
+{
+public:
+  /**
+   * @brief Constructor.
+   * @param name The algorithm name.
+   * @param svc The service locator.
+   */
+  AuxDataTestDecor (const std::string &name, ISvcLocator *pSvcLocator);
+  
+
+  /**
+   * @brief Algorithm initialization; called at the beginning of the job.
+   */
+  virtual StatusCode initialize();
+
+
+  /**
+   * @brief Algorithm event processing.
+   */
+  virtual StatusCode execute(); 
+
+
+  /**
+   * @brief Algorithm finalization; called at the end of the job.
+   */
+  virtual StatusCode finalize();
+
+
+private:
+  /// Parameter: Prefix for names read from SG.
+  std::string m_readPrefix;
+
+  /// Parameter: Name of the decoration.
+  std::string m_decorName;
+
+  /// Parameter: Offset to be applied to decoration.
+  int m_offset;
+};
+
+
+} // namespace DMTest
+
+
+#endif // not DATAMODELTESTDATAREAD_AUXDATATESTDECOR_H
diff --git a/Control/DataModelTest/DataModelTestDataRead/src/AuxDataTestRead.cxx b/Control/DataModelTest/DataModelTestDataRead/src/AuxDataTestRead.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..9c31d6c2db9009a8ebd8c7bd2844591144c4a1e2
--- /dev/null
+++ b/Control/DataModelTest/DataModelTestDataRead/src/AuxDataTestRead.cxx
@@ -0,0 +1,141 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// $Id$
+/**
+ * @file  src/AuxDataTestRead.cxx
+ * @author snyder@bnl.gov
+ * @date May 2014
+ * @brief Algorithm to test reading @c DataVector with auxiliary data.
+ */
+
+
+#include "AuxDataTestRead.h"
+#include "DataModelTestDataCommon/B.h"
+#include "DataModelTestDataCommon/BAux.h"
+#include "DataModelTestDataCommon/BAuxStandalone.h"
+#include "DataModelTestDataCommon/BAuxVec.h"
+#include "AthContainers/AuxTypeRegistry.h"
+#include "AthContainers/AuxStoreInternal.h"
+#include "AthLinks/ElementLink.h"
+#include "AthenaKernel/errorcheck.h"
+#include "CxxUtils/StrFormat.h"
+#include <memory>
+
+
+namespace DMTest {
+
+
+/**
+ * @brief Constructor.
+ * @param name The algorithm name.
+ * @param svc The service locator.
+ */
+AuxDataTestRead::AuxDataTestRead (const std::string &name,
+                                  ISvcLocator *pSvcLocator)
+  : AthAlgorithm (name, pSvcLocator),
+    m_count(0)
+{
+  declareProperty ("ReadPrefix",  m_readPrefix);
+  declareProperty ("WritePrefix", m_writePrefix);
+}
+  
+
+/**
+ * @brief Algorithm initialization; called at the beginning of the job.
+ */
+StatusCode AuxDataTestRead::initialize()
+{
+  return StatusCode::SUCCESS;
+}
+
+
+/**
+ * @brief Algorithm event processing.
+ */
+StatusCode AuxDataTestRead::execute()
+{
+  ++m_count;
+  std::cout << m_count << "\n";
+
+  const SG::AuxTypeRegistry& r = SG::AuxTypeRegistry::instance();
+
+  static BAux::Accessor<int> anInt1 ("anInt1");
+  static BAux::Accessor<float> aFloat1 ("aFloat1");
+  static BAux::Accessor<ElementLink<BAuxVec> > anEL ("anEL");
+  static BAux::Accessor<DMTest::B> aB ("aB");
+  static BAux::Accessor<float> dFloat1 ("dFloat1");
+  static BAux::Accessor<int> dInt1 ("dInt1");
+  static BAux::Accessor<int> dInt2 ("dInt2");
+
+  const BAuxVec* vec = 0;
+  CHECK( evtStore()->retrieve (vec, m_readPrefix + "bauxvec") );
+
+  // Ordering of auxid is not reliable.  Sort by name.
+  std::vector<std::string> names;
+  for (SG::auxid_t auxid : vec->getAuxIDs())
+    names.push_back (r.getName(auxid));
+  std::sort (names.begin(), names.end());
+  for (const std::string& n : names)
+    std::cout << n << " ";
+  std::cout << "\n";
+  for (const BAux* belt : *vec) {
+    std::cout << " anInt1: " << anInt1(*belt)
+              << " aFloat1: " << aFloat1(*belt)
+              << " aB: " << aB(*belt).m_x
+              << " dFloat1: " << dFloat1(*belt);
+    if (dInt1.isAvailable(*belt))
+      std::cout << " dInt1: " << dInt1(*belt);
+    if (dInt2.isAvailable(*belt))
+      std::cout << " dInt2: " << dInt2(*belt);
+    std::cout << "\n";
+  }
+
+  const BAux* b = 0;
+  CHECK( evtStore()->retrieve (b, m_readPrefix + "b") );
+  std::cout << "b anInt1: " << anInt1(*b) 
+            << " aFloat1: " << CxxUtils::strformat ("%.1f", aFloat1(*b))
+            << " anEL: " << anEL(*b).dataID() << "[" << anEL(*b).index() << "]"
+            << " aB: " << aB(*b).m_x 
+            << " dFloat1: " << dFloat1(*b);
+  if (dInt1.isAvailable(*b))
+    std::cout << " dInt1: " << dInt1(*b);
+  if (dInt2.isAvailable(*b))
+    std::cout << " dInt2: " << dInt2(*b);
+  std::cout << "\n";
+    
+  if (!m_writePrefix.empty()) {
+    // Passing this as the third arg of record will make the object const.
+    bool LOCKED = false;
+
+    std::unique_ptr<BAuxVec> vecnew (new BAuxVec);
+    std::unique_ptr<SG::AuxStoreInternal> store (new SG::AuxStoreInternal);
+    vecnew->setStore (store.get());
+    for (size_t i = 0; i < vec->size(); i++) {
+      vecnew->push_back (new BAux);
+      *vecnew->back() = *(*vec)[i];
+    }
+    CHECK (evtStore()->record (std::move(vecnew), m_writePrefix + "bauxvec", LOCKED));
+    CHECK (evtStore()->record (std::move(store), m_writePrefix + "bauxvecAux.", LOCKED));
+
+    std::unique_ptr<BAuxStandalone> bnew (new BAuxStandalone);
+    bnew->makePrivateStore (*b);
+    CHECK (evtStore()->record (std::move(bnew), m_writePrefix + "b", LOCKED));
+  }
+
+  return StatusCode::SUCCESS;
+}
+
+
+/**
+ * @brief Algorithm finalization; called at the end of the job.
+ */
+StatusCode AuxDataTestRead::finalize()
+{
+  return StatusCode::SUCCESS;
+}
+
+
+} // namespace DMTest
+
diff --git a/Control/DataModelTest/DataModelTestDataRead/src/AuxDataTestRead.h b/Control/DataModelTest/DataModelTestDataRead/src/AuxDataTestRead.h
new file mode 100644
index 0000000000000000000000000000000000000000..97e28e22cc686a614b3d54068e69e3836b927af7
--- /dev/null
+++ b/Control/DataModelTest/DataModelTestDataRead/src/AuxDataTestRead.h
@@ -0,0 +1,74 @@
+// 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 src/AuxDataTestRead.h
+ * @author scott snyder <snyder@bnl.gov>
+ * @date May, 2014
+ * @brief Algorithm to test reading @c DataVector with auxiliary data.
+ */
+
+
+#ifndef DATAMODELTESTDATAREAD_AUXDATATESTREAD_H
+#define DATAMODELTESTDATAREAD_AUXDATATESTREAD_H
+
+
+#include "AthenaBaseComps/AthAlgorithm.h"
+
+
+namespace DMTest {
+
+
+/**
+ * @brief Algorithm for reading test aux data.
+ */
+class AuxDataTestRead
+  : public AthAlgorithm
+{
+public:
+  /**
+   * @brief Constructor.
+   * @param name The algorithm name.
+   * @param svc The service locator.
+   */
+  AuxDataTestRead (const std::string &name, ISvcLocator *pSvcLocator);
+  
+
+  /**
+   * @brief Algorithm initialization; called at the beginning of the job.
+   */
+  virtual StatusCode initialize();
+
+
+  /**
+   * @brief Algorithm event processing.
+   */
+  virtual StatusCode execute(); 
+
+
+  /**
+   * @brief Algorithm finalization; called at the end of the job.
+   */
+  virtual StatusCode finalize();
+
+
+private:
+  /// Parameter: Prefix for names read from SG.
+  std::string m_readPrefix;
+
+  /// Parameter: Prefix for names written to SG.  Null for no write.
+  std::string m_writePrefix;
+
+  /// Event counter.
+  int m_count;
+};
+
+
+} // namespace DMTest
+
+
+#endif // not DATAMODELTESTDATAREAD_AUXDATATESTREAD_H
diff --git a/Control/DataModelTest/DataModelTestDataRead/src/AuxDataTestTypelessRead.cxx b/Control/DataModelTest/DataModelTestDataRead/src/AuxDataTestTypelessRead.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..f4377b42603fe48ca212a1dd1d395bef85b318ef
--- /dev/null
+++ b/Control/DataModelTest/DataModelTestDataRead/src/AuxDataTestTypelessRead.cxx
@@ -0,0 +1,164 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// $Id$
+/**
+ * @file  src/AuxDataTestTypelessRead.cxx
+ * @author snyder@bnl.gov
+ * @date May 2014
+ * @brief Algorithm to test reading @c DataVector with auxiliary data,
+ *        without compile-time typing of aux data.
+ */
+
+
+#include "AuxDataTestTypelessRead.h"
+#include "DataModelTestDataCommon/B.h"
+#include "DataModelTestDataCommon/BAux.h"
+#include "DataModelTestDataCommon/BAuxStandalone.h"
+#include "DataModelTestDataCommon/BAuxVec.h"
+#include "AthContainers/AuxTypeRegistry.h"
+#include "AthContainers/AuxStoreInternal.h"
+#include "AthLinks/ElementLink.h"
+#include "AthenaKernel/errorcheck.h"
+#include "CxxUtils/StrFormat.h"
+#include "GaudiKernel/System.h"
+#include <map>
+#include <memory>
+
+
+namespace DMTest {
+
+
+/**
+ * @brief Constructor.
+ * @param name The algorithm name.
+ * @param svc The service locator.
+ */
+AuxDataTestTypelessRead::AuxDataTestTypelessRead (const std::string &name,
+                                                  ISvcLocator *pSvcLocator)
+  : AthAlgorithm (name, pSvcLocator),
+    m_count(0)
+{
+  declareProperty ("WritePrefix", m_writePrefix);
+}
+  
+
+/**
+ * @brief Algorithm initialization; called at the beginning of the job.
+ */
+StatusCode AuxDataTestTypelessRead::initialize()
+{
+  return StatusCode::SUCCESS;
+}
+
+
+namespace {
+
+
+void dumpAuxItem (SG::auxid_t auxid, const SG::AuxVectorData& c, size_t i)
+{
+  const SG::AuxTypeRegistry& r = SG::AuxTypeRegistry::instance();
+  const std::type_info* ti = r.getType(auxid);
+  std::cout << r.getName(auxid) << ": ";
+  if (ti == &typeid(int))
+    std::cout << c.getData<int> (auxid, i) << "; ";
+  else if (ti == &typeid(float))
+    std::cout << CxxUtils::strformat ("%.1f", c.getData<float> (auxid, i)) << "; ";
+  else if (ti == &typeid(ElementLink<DMTest::BAuxVec>)) {
+    const ElementLink<DMTest::BAuxVec>& el =
+      c.getData<ElementLink<DMTest::BAuxVec> > (auxid, i);
+    std::cout << el.dataID() << "[" << el.index() << "]; ";
+  }
+  else if (ti == &typeid(DMTest::B)) {
+    std::cout << c.getData<B>(auxid, i).m_x << "; ";
+  }
+  else
+    std::cout << "xxx; ";
+}
+
+
+} // anonymous namespace
+
+
+/**
+ * @brief Algorithm event processing.
+ */
+StatusCode AuxDataTestTypelessRead::execute()
+{
+  ++m_count;
+  std::cout << m_count << "\n";
+
+  const SG::AuxTypeRegistry& r = SG::AuxTypeRegistry::instance();
+
+  const BAuxVec* vec = 0;
+  CHECK( evtStore()->retrieve (vec, "bauxvec") );
+
+  // Sort auxids in name order.
+  std::map<std::string, SG::auxid_t> auxid_map;
+  for (SG::auxid_t auxid : vec->getAuxIDs())
+    auxid_map[r.getName(auxid)] = auxid;
+
+  std::cout << "bvec types: ";
+  for (const auto& m : auxid_map)
+    std::cout << r.getName(m.second) << "/" 
+              << System::typeinfoName (*r.getType(m.second)) << " ";
+  std::cout << "\n";
+  for (size_t i = 0; i < vec->size(); i++) {
+    std::cout << "  ";
+    for (const auto& m : auxid_map)
+      dumpAuxItem (m.second, *vec, i);
+    std::cout << "\n";
+  }
+
+  const BAux* b = 0;
+  CHECK( evtStore()->retrieve (b, "b") );
+  const SG::AuxVectorData* cont = b->container();
+
+  std::map<std::string, SG::auxid_t> bauxid_map;
+  for (SG::auxid_t auxid : cont->getAuxIDs())
+    bauxid_map[r.getName(auxid)] = auxid;
+
+  std::cout << "b types: ";
+  for (const auto& m : bauxid_map)
+    std::cout << r.getName(m.second) << "/" 
+              << System::typeinfoName (*r.getType(m.second)) << " ";
+  std::cout << "\n";
+  for (const auto& m : bauxid_map)
+    dumpAuxItem (m.second, *cont, 0);
+  std::cout << "\n";
+
+  if (!m_writePrefix.empty()) {
+    // Passing this as the third arg of record will make the object const.
+    bool LOCKED = false;
+
+    std::unique_ptr<BAuxVec> vecnew (new BAuxVec);
+    std::unique_ptr<SG::AuxStoreInternal> store (new SG::AuxStoreInternal);
+    vecnew->setStore (store.get());
+    for (size_t i = 0; i < vec->size(); i++) {
+      vecnew->push_back (new BAux);
+      *vecnew->back() = *(*vec)[i];
+    }
+    CHECK (evtStore()->record (std::move(vecnew), m_writePrefix + "bauxvec", LOCKED));
+    CHECK (evtStore()->record (std::move(store), m_writePrefix + "bauxvecAux.", LOCKED));
+
+    std::unique_ptr<BAuxStandalone> bnew (new BAuxStandalone);
+    bnew->makePrivateStore (*b);
+    CHECK (evtStore()->record (std::move(bnew), m_writePrefix + "b", LOCKED));
+  }
+
+  return StatusCode::SUCCESS;
+}
+
+
+/**
+ * @brief Algorithm finalization; called at the end of the job.
+ */
+StatusCode AuxDataTestTypelessRead::finalize()
+{
+  return StatusCode::SUCCESS;
+}
+
+
+} // namespace DMTest
+
diff --git a/Control/DataModelTest/DataModelTestDataRead/src/AuxDataTestTypelessRead.h b/Control/DataModelTest/DataModelTestDataRead/src/AuxDataTestTypelessRead.h
new file mode 100644
index 0000000000000000000000000000000000000000..90dc2751d7599a97ec2d0e8992c23fbf61ff88e5
--- /dev/null
+++ b/Control/DataModelTest/DataModelTestDataRead/src/AuxDataTestTypelessRead.h
@@ -0,0 +1,71 @@
+// 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 src/AuxDataTestTypelessRead.h
+ * @author scott snyder <snyder@bnl.gov>
+ * @date May, 2014
+ * @brief Algorithm to test reading @c DataVector with auxiliary data,
+ *        without compile-time typing of aux data.
+ */
+
+#ifndef DATAMODELTESTDATAREAD_AUXDATATESTTYPELESSREAD_H
+#define DATAMODELTESTDATAREAD_AUXDATATESTTYPELESSREAD_H
+
+
+#include "AthenaBaseComps/AthAlgorithm.h"
+
+
+namespace DMTest {
+
+
+/**
+ * @brief Algorithm for reading test aux data.
+ */
+class AuxDataTestTypelessRead
+  : public AthAlgorithm
+{
+public:
+  /**
+   * @brief Constructor.
+   * @param name The algorithm name.
+   * @param svc The service locator.
+   */
+  AuxDataTestTypelessRead (const std::string &name, ISvcLocator *pSvcLocator);
+  
+
+  /**
+   * @brief Algorithm initialization; called at the beginning of the job.
+   */
+  virtual StatusCode initialize();
+
+
+  /**
+   * @brief Algorithm event processing.
+   */
+  virtual StatusCode execute(); 
+
+
+  /**
+   * @brief Algorithm finalization; called at the end of the job.
+   */
+  virtual StatusCode finalize();
+
+
+private:
+  /// Parameter: Prefix for names written to SG.  Null for no write.
+  std::string m_writePrefix;
+
+  /// Event counter.
+  int m_count;
+};
+
+
+} // namespace DMTest
+
+
+#endif // not DATAMODELTESTDATAREAD_AUXDATATESTTYPELESSREAD_H
diff --git a/Control/DataModelTest/DataModelTestDataRead/src/DMTestRead.cxx b/Control/DataModelTest/DataModelTestDataRead/src/DMTestRead.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..ffa0b0478e46ea05c31fc472eec2209846b7831d
--- /dev/null
+++ b/Control/DataModelTest/DataModelTestDataRead/src/DMTestRead.cxx
@@ -0,0 +1,191 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// $Id: DMTestRead.cxx,v 1.6 2008-11-21 06:29:06 ssnyder Exp $
+/**
+ * @file  src/DMTestRead.cxx
+ * @author snyder@bnl.gov
+ * @date Nov 2005
+ * @brief Algorithm to test reading @c DataVector data.
+ *
+ *        We read information using all four types,
+ *        @c BVec, @c DVec, @c BDer, @c DDer.
+ *        When we run, we have the inheritance relationship set up
+ *        between @c BVec and @c DVec.
+ */
+
+#undef NDEBUG
+
+#include "DMTestRead.h"
+#include "DataModelAthenaPool/ElementLinkVectorCnv_p1.h"
+#include "DataModelAthenaPool/ElementLinkCnv_p3.h"
+#include "DataModelAthenaPool/DataLinkCnv_p1.h"
+#include "DataModelTestDataRead/BVec.h"
+#include "DataModelTestDataRead/BDer.h"
+#include "DataModelTestDataRead/DVec.h"
+#include "DataModelTestDataRead/DDer.h"
+#include "DataModelTestDataRead/ELVec.h"
+#include "AthContainers/ClassName.h"
+#include "StoreGate/StoreGateSvc.h"
+#include "GaudiKernel/MsgStream.h"
+#include "AthenaKernel/errorcheck.h"
+#include <iostream>
+#include <cassert>
+
+
+namespace DMTest {
+
+
+/**
+ * @brief Constructor.
+ * @param name The algorithm name.
+ * @param svc The service locator.
+ */
+DMTestRead::DMTestRead (const std::string& name, ISvcLocator* pSvcLocator)
+  : AthAlgorithm (name, pSvcLocator)
+{
+}
+
+
+/**
+ * @brief Algorithm initialization; called at the beginning of the job.
+ */
+StatusCode DMTestRead::initialize()
+{
+  return StatusCode::SUCCESS;
+}
+
+
+namespace {
+
+
+/**
+ * @brief Print out one of our test objects of type @c VEC from storegate.
+ * @param sg The @c StoreGateSvc object.
+ * @param key The storegate key to use.
+ */
+template <class VEC>
+StatusCode print_vec (StoreGateSvc* sg,
+                      const std::string& key,
+                      const std::string& context)
+{
+  if (!sg->contains<VEC> (key))
+  {
+    std::cout << key << " not in SG; ignored.\n";
+    return StatusCode::SUCCESS;
+  }
+
+  const VEC* vec;
+  CHECK_WITH_CONTEXT( sg->retrieve (vec, key), context );
+  std::cout << key << " as " << ClassName<VEC>::name() << ": ";
+  for (unsigned i=0; i < vec->size(); i++)
+    std::cout << (*vec)[i]->m_x << " ";
+  std::cout << "\n";
+
+  return StatusCode::SUCCESS;
+}
+
+
+StatusCode print_elvec (StoreGateSvc* sg,
+                        const std::string& key,
+                        const std::string& context)
+{
+  const ELVec* vec;
+  CHECK_WITH_CONTEXT( sg->retrieve (vec, key), context );
+  ELVec* mvec = const_cast<ELVec*> (vec);
+  std::cout << key << ": ";
+  for (size_t i = 0; i < vec->m_el.size(); i++) {
+    const DMTest::B* b = *vec->m_el[i];
+    mvec->m_el[i].toPersistent();
+    std::cout << b->m_x << " ";
+  }
+  std::cout << "\n";
+  return StatusCode::SUCCESS;
+}
+
+
+StatusCode remap_test (StoreGateSvc* sg, MsgStream& log)
+{
+  const ELVec* vec;
+  CHECK_WITH_CONTEXT( sg->retrieve (vec, "elv_remap"), "remap_test" );
+  ELVec* mvec = const_cast<ELVec*> (vec);
+
+  ElementLinkCnv_p3<ElementLink<BVec> > elcnv;
+  mvec->m_el2.resize (mvec->m_el2_p.size());
+  for (size_t i=0; i < mvec->m_el2_p.size(); i++)
+    elcnv.persToTrans (&mvec->m_el2_p[i], &mvec->m_el2[i], log);
+
+  std::cout << "elv_remap: ";
+  for (size_t i = 0; i < vec->m_el2.size(); i++) {
+    const DMTest::B* b = *vec->m_el2[i];
+    std::cout << b->m_x << " ";
+  }
+  std::cout << "\n";
+
+  ElementLinkVectorCnv_p1<ElementLinkVector<BVec> > elvcnv;
+  elvcnv.persToTrans (&vec->m_elv2_p, &const_cast<ELVec*>(vec)->m_elv2, log);
+
+  std::cout << "elv_remap v2: ";
+  for (size_t i = 0; i < vec->m_elv2.size(); i++) {
+    const DMTest::B* b = *vec->m_elv2[i];
+    std::cout << b->m_x << " ";
+  }
+  std::cout << "\n";
+
+  DataLinkCnv_p1<DataLink<BVec> > dlcnv;
+  mvec->m_dl2.resize (mvec->m_dl2_p.size());
+  for (size_t i=0; i < mvec->m_dl2_p.size(); i++)
+    dlcnv.persToTrans (&mvec->m_dl2_p[i], &mvec->m_dl2[i], log);
+
+  const BVec* b3;
+  CHECK_WITH_CONTEXT( sg->retrieve (b3, "b3"), "remap_test" );
+  assert (vec->m_dl2[0].cptr() == b3);
+  assert (vec->m_dl2[1].cptr() == b3);
+
+  return StatusCode::SUCCESS;
+}
+
+
+} // anonymous namespace
+
+
+/**
+ * @brief Algorithm event processing.
+ */
+StatusCode DMTestRead::execute()
+{
+  MsgStream log(msgSvc(), name());
+
+  StoreGateSvc* sg = &*evtStore();
+
+  // Test reading our four types.
+  CHECK( print_vec<BVec> (sg, "bvec", name()) );
+  CHECK( print_vec<BDer> (sg, "bder", name()) );
+  CHECK( print_vec<DVec> (sg, "dvec", name()) );
+  CHECK( print_vec<DDer> (sg, "dder", name()) );
+
+  // Test using implicit symlinks.
+  CHECK( print_vec<BVec> (sg, "bder", name()) );
+  CHECK( print_vec<BVec> (sg, "dvec", name()) );
+  CHECK( print_vec<BVec> (sg, "dder", name()) );
+  CHECK( print_vec<DVec> (sg, "dder", name()) );
+
+  CHECK( print_elvec (sg, "elvec", name()) );
+
+  CHECK( remap_test (sg, log) );
+
+  return StatusCode::SUCCESS;
+}
+
+
+/**
+ * @brief Algorithm finalization; called at the end of the job.
+ */
+StatusCode DMTestRead::finalize()
+{
+  return StatusCode::SUCCESS;
+}
+
+
+} // namespace DMTest
diff --git a/Control/DataModelTest/DataModelTestDataRead/src/DMTestRead.h b/Control/DataModelTest/DataModelTestDataRead/src/DMTestRead.h
new file mode 100644
index 0000000000000000000000000000000000000000..7eeb4eb968ff8e981231a425edc80a138c9d2d4e
--- /dev/null
+++ b/Control/DataModelTest/DataModelTestDataRead/src/DMTestRead.h
@@ -0,0 +1,69 @@
+// 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: DMTestRead.h,v 1.1 2005-12-01 19:11:57 ssnyder Exp $
+
+/**
+ * @file  DataModelTestDataRead/DMTestRead.h
+ * @author snyder@bnl.gov
+ * @date Nov 2005
+ * @brief Algorithm to test reading @c DataVector data.
+ *
+ *        We read information using all four types,
+ *        @c BVec, @c DVec, @c BDer, @c DDer.
+ *        When we run, we have the inheritance relationship set up
+ *        between @c BVec and @c DVec.
+ */
+
+#ifndef DATAMODELTESTDATAREAD_DMTESTREAD_H
+#define DATAMODELTESTDATAREAD_DMTESTREAD_H
+
+
+#include "AthenaBaseComps/AthAlgorithm.h"
+
+
+
+namespace DMTest {
+
+
+/**
+ * @brief Algorithm for printing test data.
+ */
+class DMTestRead
+  : public AthAlgorithm
+{
+public:
+  /**
+   * @brief Constructor.
+   * @param name The algorithm name.
+   * @param svc The service locator.
+   */
+  DMTestRead (const std::string &name,ISvcLocator *pSvcLocator);
+  
+
+  /**
+   * @brief Algorithm initialization; called at the beginning of the job.
+   */
+  virtual StatusCode initialize();
+
+
+  /**
+   * @brief Algorithm event processing.
+   */
+  virtual StatusCode execute(); 
+
+
+  /**
+   * @brief Algorithm finalization; called at the end of the job.
+   */
+  virtual StatusCode finalize();
+};
+
+
+} // namespace DMTest
+
+
+#endif // not DATAMODELTESTDATAREAD_DMTESTREAD_H
diff --git a/Control/DataModelTest/DataModelTestDataRead/src/components/DataModelTestDataRead_entries.cxx b/Control/DataModelTest/DataModelTestDataRead/src/components/DataModelTestDataRead_entries.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..78be43b1bb6d422e145f5b249aa6e6022116b428
--- /dev/null
+++ b/Control/DataModelTest/DataModelTestDataRead/src/components/DataModelTestDataRead_entries.cxx
@@ -0,0 +1,43 @@
+// $Id: DataModelTestDataRead_entries.cxx,v 1.2 2006-04-07 18:30:38 ssnyder Exp $
+/**
+ * @file  src/components/DataModelTestDataRead_entries.cxx
+ * @author snyder@bnl.gov
+ * @date Nov 2005
+ * @brief Gaudi algorithm factory declarations.
+ */
+
+#include "GaudiKernel/DeclareFactoryEntries.h"
+#include "../DMTestRead.h"
+#include "../AuxDataTestRead.h"
+#include "../AuxDataTestDecor.h"
+#include "../AuxDataTestClearDecor.h"
+#include "../AuxDataTestTypelessRead.h"
+#include "../xAODTestRead.h"
+#include "../xAODTestDecor.h"
+#include "../xAODTestClearDecor.h"
+#include "../xAODTestTypelessRead.h"
+#include "../xAODTestShallowCopy.h"
+
+DECLARE_NAMESPACE_ALGORITHM_FACTORY(DMTest, DMTestRead)
+DECLARE_NAMESPACE_ALGORITHM_FACTORY(DMTest, AuxDataTestRead)
+DECLARE_NAMESPACE_ALGORITHM_FACTORY(DMTest, AuxDataTestDecor)
+DECLARE_NAMESPACE_ALGORITHM_FACTORY(DMTest, AuxDataTestClearDecor)
+DECLARE_NAMESPACE_ALGORITHM_FACTORY(DMTest, AuxDataTestTypelessRead)
+DECLARE_NAMESPACE_ALGORITHM_FACTORY(DMTest, xAODTestRead)
+DECLARE_NAMESPACE_ALGORITHM_FACTORY(DMTest, xAODTestDecor)
+DECLARE_NAMESPACE_ALGORITHM_FACTORY(DMTest, xAODTestClearDecor)
+DECLARE_NAMESPACE_ALGORITHM_FACTORY(DMTest, xAODTestTypelessRead)
+DECLARE_NAMESPACE_ALGORITHM_FACTORY(DMTest, xAODTestShallowCopy)
+
+DECLARE_FACTORY_ENTRIES(DataModelTestDataRead) {
+  DECLARE_NAMESPACE_ALGORITHM(DMTest, DMTestRead);
+  DECLARE_NAMESPACE_ALGORITHM(DMTest, AuxDataTestRead);
+  DECLARE_NAMESPACE_ALGORITHM(DMTest, AuxDataTestDecor);
+  DECLARE_NAMESPACE_ALGORITHM(DMTest, AuxDataTestClearDecor);
+  DECLARE_NAMESPACE_ALGORITHM(DMTest, AuxDataTestTypelessRead);
+  DECLARE_NAMESPACE_ALGORITHM(DMTest, xAODTestRead);
+  DECLARE_NAMESPACE_ALGORITHM(DMTest, xAODTestDecor);
+  DECLARE_NAMESPACE_ALGORITHM(DMTest, xAODTestClearDecor);
+  DECLARE_NAMESPACE_ALGORITHM(DMTest, xAODTestTypelessRead);
+  DECLARE_NAMESPACE_ALGORITHM(DMTest, xAODTestShallowCopy);
+}
diff --git a/Control/DataModelTest/DataModelTestDataRead/src/components/DataModelTestDataRead_load.cxx b/Control/DataModelTest/DataModelTestDataRead/src/components/DataModelTestDataRead_load.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..e91c3b81190e26fd1a7acade5c85b217ec1b858c
--- /dev/null
+++ b/Control/DataModelTest/DataModelTestDataRead/src/components/DataModelTestDataRead_load.cxx
@@ -0,0 +1,11 @@
+// $Id: DataModelTestDataRead_load.cxx,v 1.1 2005-12-01 19:11:58 ssnyder Exp $
+/**
+ * @file  src/components/DataModelTestDataRead_load.cxx
+ * @author snyder@bnl.gov
+ * @date Nov 2005
+ * @brief Gaudi shared lib loading declaration.
+ */
+
+#include "GaudiKernel/LoadFactoryEntries.h"
+
+LOAD_FACTORY_ENTRIES( DataModelTestDataRead )
diff --git a/Control/DataModelTest/DataModelTestDataRead/src/xAODTestClearDecor.cxx b/Control/DataModelTest/DataModelTestDataRead/src/xAODTestClearDecor.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..ac9932eba7101dc2b6f63b24b925d4b053fb3f34
--- /dev/null
+++ b/Control/DataModelTest/DataModelTestDataRead/src/xAODTestClearDecor.cxx
@@ -0,0 +1,76 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// $Id$
+/**
+ * @file  src/xAODTestClearDecor.cxx
+ * @author snyder@bnl.gov
+ * @date May 2014
+ * @brief Algorithm to test clearing xAOD decorations.
+ */
+
+
+#include "xAODTestClearDecor.h"
+#include "DataModelTestDataCommon/C.h"
+#include "DataModelTestDataCommon/CVec.h"
+#include "AthenaKernel/errorcheck.h"
+
+
+namespace DMTest {
+
+
+/**
+ * @brief Constructor.
+ * @param name The algorithm name.
+ * @param svc The service locator.
+ */
+xAODTestClearDecor::xAODTestClearDecor (const std::string &name,
+                                        ISvcLocator *pSvcLocator)
+  : AthAlgorithm (name, pSvcLocator)
+{
+  declareProperty ("ReadPrefix",  m_readPrefix);
+}
+  
+
+/**
+ * @brief Algorithm initialization; called at the beginning of the job.
+ */
+StatusCode xAODTestClearDecor::initialize()
+{
+  return StatusCode::SUCCESS;
+}
+
+
+/**
+ * @brief Algorithm event processing.
+ */
+StatusCode xAODTestClearDecor::execute()
+{
+  const CVec* vec = 0;
+  CHECK( evtStore()->retrieve (vec, m_readPrefix + "cvec") );
+  vec->clearDecorations();
+
+  const C* c = 0;
+  CHECK( evtStore()->retrieve (c, m_readPrefix + "cinfo") );
+  c->clearDecorations();
+
+  const CVec* ctrig = 0;
+  CHECK( evtStore()->retrieve (ctrig, m_readPrefix + "ctrig") );
+  ctrig->clearDecorations();
+
+  return StatusCode::SUCCESS;
+}
+
+
+/**
+ * @brief Algorithm finalization; called at the end of the job.
+ */
+StatusCode xAODTestClearDecor::finalize()
+{
+  return StatusCode::SUCCESS;
+}
+
+
+} // namespace DMTest
+
diff --git a/Control/DataModelTest/DataModelTestDataRead/src/xAODTestClearDecor.h b/Control/DataModelTest/DataModelTestDataRead/src/xAODTestClearDecor.h
new file mode 100644
index 0000000000000000000000000000000000000000..951eb8efb3d8dd6a8b1e792e84715a973806477e
--- /dev/null
+++ b/Control/DataModelTest/DataModelTestDataRead/src/xAODTestClearDecor.h
@@ -0,0 +1,69 @@
+// 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 src/xAODTestClearDecor.h
+ * @author scott snyder <snyder@bnl.gov>
+ * @date May, 2014
+ * @brief Algorithm to test clearing xAOD decorations.
+ */
+
+
+#ifndef DATAMODELTESTDATAREAD_XAODTESTCLEARDECOR_H
+#define DATAMODELTESTDATAREAD_XAODTESTCLEARDECOR_H
+
+
+#include "AthenaBaseComps/AthAlgorithm.h"
+
+
+namespace DMTest {
+
+
+/**
+ * @brief Algorithm to test adding decorations to a @c DataVector
+ *        with auxiliary data.
+ */
+class xAODTestClearDecor
+  : public AthAlgorithm
+{
+public:
+  /**
+   * @brief Constructor.
+   * @param name The algorithm name.
+   * @param svc The service locator.
+   */
+  xAODTestClearDecor (const std::string &name, ISvcLocator *pSvcLocator);
+  
+
+  /**
+   * @brief Algorithm initialization; called at the beginning of the job.
+   */
+  virtual StatusCode initialize();
+
+
+  /**
+   * @brief Algorithm event processing.
+   */
+  virtual StatusCode execute(); 
+
+
+  /**
+   * @brief Algorithm finalization; called at the end of the job.
+   */
+  virtual StatusCode finalize();
+
+
+private:
+  /// Parameter: Prefix for names read from SG.
+  std::string m_readPrefix;
+};
+
+
+} // namespace DMTest
+
+
+#endif // not DATAMODELTESTDATAREAD_XAODTESTCLEARDECOR_H
diff --git a/Control/DataModelTest/DataModelTestDataRead/src/xAODTestDecor.cxx b/Control/DataModelTest/DataModelTestDataRead/src/xAODTestDecor.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..a37082354c811da174509c11eb2d5f8a5102aadc
--- /dev/null
+++ b/Control/DataModelTest/DataModelTestDataRead/src/xAODTestDecor.cxx
@@ -0,0 +1,82 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// $Id$
+/**
+ * @file  src/AuxDataTestDecor.cxx
+ * @author snyder@bnl.gov
+ * @date May 2014
+ * @brief Algorithm to test adding decorations to xAOD data.
+ */
+
+
+#include "xAODTestDecor.h"
+#include "DataModelTestDataCommon/C.h"
+#include "DataModelTestDataCommon/CVec.h"
+#include "AthenaKernel/errorcheck.h"
+
+
+namespace DMTest {
+
+
+/**
+ * @brief Constructor.
+ * @param name The algorithm name.
+ * @param svc The service locator.
+ */
+xAODTestDecor::xAODTestDecor (const std::string &name,
+                              ISvcLocator *pSvcLocator)
+  : AthAlgorithm (name, pSvcLocator)
+{
+  declareProperty ("ReadPrefix",  m_readPrefix);
+  declareProperty ("DecorName",   m_decorName = "dInt1");
+  declareProperty ("Offset",      m_offset = 100);
+}
+  
+
+/**
+ * @brief Algorithm initialization; called at the beginning of the job.
+ */
+StatusCode xAODTestDecor::initialize()
+{
+  return StatusCode::SUCCESS;
+}
+
+
+/**
+ * @brief Algorithm event processing.
+ */
+StatusCode xAODTestDecor::execute()
+{
+  C::Decorator<int> dInt1 (m_decorName);
+
+  const CVec* vec = 0;
+  CHECK( evtStore()->retrieve (vec, m_readPrefix + "cvec") );
+  for (const C* celt : *vec)
+    dInt1(*celt) = m_offset + celt->anInt();
+
+  const C* c = 0;
+  CHECK( evtStore()->retrieve (c, m_readPrefix + "cinfo") );
+  dInt1(*c) = 400 + m_offset + c->anInt();
+
+  const CVec* ctrig = 0;
+  CHECK( evtStore()->retrieve (ctrig, m_readPrefix + "ctrig") );
+  for (const C* celt : *ctrig)
+    dInt1(*celt) = 600 + m_offset + celt->anInt();
+
+  return StatusCode::SUCCESS;
+}
+
+
+/**
+ * @brief Algorithm finalization; called at the end of the job.
+ */
+StatusCode xAODTestDecor::finalize()
+{
+  return StatusCode::SUCCESS;
+}
+
+
+} // namespace DMTest
+
diff --git a/Control/DataModelTest/DataModelTestDataRead/src/xAODTestDecor.h b/Control/DataModelTest/DataModelTestDataRead/src/xAODTestDecor.h
new file mode 100644
index 0000000000000000000000000000000000000000..afea6afe07d4d276601b2865373b76fd905533d1
--- /dev/null
+++ b/Control/DataModelTest/DataModelTestDataRead/src/xAODTestDecor.h
@@ -0,0 +1,74 @@
+// 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 src/xAODTestDecor.h
+ * @author scott snyder <snyder@bnl.gov>
+ * @date May, 2014
+ * @brief Algorithm to test adding decorations to xAOD types.
+ */
+
+
+#ifndef DATAMODELTESTDATAREAD_XAODTESTDECOR_H
+#define DATAMODELTESTDATAREAD_XAODTESTDECOR_H
+
+
+#include "AthenaBaseComps/AthAlgorithm.h"
+
+
+namespace DMTest {
+
+
+/**
+ * @brief Algorithm to test adding decorations to xAOD data.
+ */
+class xAODTestDecor
+  : public AthAlgorithm
+{
+public:
+  /**
+   * @brief Constructor.
+   * @param name The algorithm name.
+   * @param svc The service locator.
+   */
+  xAODTestDecor (const std::string &name, ISvcLocator *pSvcLocator);
+  
+
+  /**
+   * @brief Algorithm initialization; called at the beginning of the job.
+   */
+  virtual StatusCode initialize();
+
+
+  /**
+   * @brief Algorithm event processing.
+   */
+  virtual StatusCode execute(); 
+
+
+  /**
+   * @brief Algorithm finalization; called at the end of the job.
+   */
+  virtual StatusCode finalize();
+
+
+private:
+  /// Parameter: Prefix for names read from SG.
+  std::string m_readPrefix;
+
+  /// Parameter: Name of the decoration.
+  std::string m_decorName;
+
+  /// Parameter: Offset to be applied to decoration.
+  int m_offset;
+};
+
+
+} // namespace DMTest
+
+
+#endif // not DATAMODELTESTDATAREAD_XAODTESTDECOR_H
diff --git a/Control/DataModelTest/DataModelTestDataRead/src/xAODTestRead.cxx b/Control/DataModelTest/DataModelTestDataRead/src/xAODTestRead.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..f46068254fd8219d20e1b74ae003c1257bcc7066
--- /dev/null
+++ b/Control/DataModelTest/DataModelTestDataRead/src/xAODTestRead.cxx
@@ -0,0 +1,211 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// $Id$
+/**
+ * @file  src/xAODTestRead.cxx
+ * @author snyder@bnl.gov
+ * @date May 2014
+ * @brief Algorithm to test reading xAOD data.
+ */
+
+
+#include "xAODTestRead.h"
+#include "DataModelTestDataCommon/CVec.h"
+#include "DataModelTestDataCommon/C.h"
+#include "DataModelTestDataCommon/CAuxContainer.h"
+#include "DataModelTestDataCommon/CTrigAuxContainer.h"
+#include "DataModelTestDataCommon/CInfoAuxContainer.h"
+#include "AthContainers/AuxTypeRegistry.h"
+#include "AthLinks/ElementLink.h"
+#include "AthenaKernel/errorcheck.h"
+#include <memory>
+
+
+namespace DMTest {
+
+
+/**
+ * @brief Constructor.
+ * @param name The algorithm name.
+ * @param svc The service locator.
+ */
+xAODTestRead::xAODTestRead (const std::string &name,
+                            ISvcLocator *pSvcLocator)
+  : AthAlgorithm (name, pSvcLocator),
+    m_count(0)
+{
+  declareProperty ("ReadPrefix",  m_readPrefix);
+  declareProperty ("WritePrefix", m_writePrefix);
+}
+  
+
+/**
+ * @brief Algorithm initialization; called at the beginning of the job.
+ */
+StatusCode xAODTestRead::initialize()
+{
+  return StatusCode::SUCCESS;
+}
+
+
+/**
+ * @brief Algorithm event processing.
+ */
+StatusCode xAODTestRead::execute()
+{
+  ++m_count;
+  std::cout << m_count << "\n";
+
+  const CVec* vec = 0;
+  CHECK( evtStore()->retrieve (vec, m_readPrefix + "cvec") );
+
+  static C::Accessor<int> anInt2 ("anInt2");
+  static C::Accessor<int> anInt10 ("anInt10");
+  static C::Accessor<int> dInt1 ("dInt1");
+  static C::Accessor<int> dInt100 ("dInt100");
+  static C::Accessor<int> dInt150 ("dInt150");
+  static C::Accessor<int> dInt200 ("dInt200");
+  static C::Accessor<int> dInt250 ("dInt250");
+  static C::Accessor<ElementLink<DMTest::CVec> > cEL ("cEL");
+
+  // Ordering of auxid is not reliable.  Sort by name.
+  const SG::AuxTypeRegistry& r = SG::AuxTypeRegistry::instance();
+  std::vector<std::string> names;
+  for (SG::auxid_t auxid : vec->getAuxIDs())
+    names.push_back (r.getName(auxid));
+  std::sort (names.begin(), names.end());
+  std::cout << "cvec aux items: ";
+  for (const std::string& n : names)
+    std::cout << n << " ";
+  std::cout << "\n";
+
+  for (const C* c : *vec) {
+    std::cout << " anInt1 " << c->anInt()
+              << " aFloat: " << c->aFloat()
+              << " anInt2: " << anInt2(*c)
+              << " dInt1: " << dInt1(*c);
+      if (dInt100.isAvailable(*c))
+        std::cout << " dInt100: " << dInt100(*c);
+      if (dInt150.isAvailable(*c))
+        std::cout << " dInt150: " << dInt150(*c);
+      if (dInt200.isAvailable(*c))
+        std::cout << " dInt200: " << dInt200(*c);
+      if (dInt250.isAvailable(*c))
+        std::cout << " dInt250: " << dInt250(*c);
+      if (anInt10.isAvailable(*c))
+        std::cout << " anInt10: " << anInt10(*c);
+      if (cEL.isAvailable(*c))
+        std::cout << " cEL: " << cEL(*c).dataID()
+                  << "[" << cEL(*c).index() << "]";
+    std::cout << "\n";
+  }
+
+  const C* cinfo = 0;
+  CHECK( evtStore()->retrieve (cinfo, m_readPrefix + "cinfo") );
+
+  names.clear();
+  for (SG::auxid_t auxid : cinfo->getAuxIDs())
+    names.push_back (r.getName(auxid));
+  std::sort (names.begin(), names.end());
+  std::cout << "cinfo aux items: ";
+  for (const std::string& n : names)
+    std::cout << n << " ";
+  std::cout << "\n";
+
+  std::cout << "cinfo "
+            << " anInt1 " << cinfo->anInt()
+            << " aFloat: " << cinfo->aFloat()
+            << " anInt2: " << anInt2(*cinfo)
+            << " dInt1: " << dInt1(*cinfo)
+            << " cEL: " << cEL(*cinfo).dataID()
+            << "[" << cEL(*cinfo).index() << "]";
+  if (dInt100.isAvailable(*cinfo))
+    std::cout << " dInt100: " << dInt100(*cinfo);
+  if (dInt150.isAvailable(*cinfo))
+    std::cout << " dInt150: " << dInt150(*cinfo);
+  if (dInt200.isAvailable(*cinfo))
+    std::cout << " dInt200: " << dInt200(*cinfo);
+  if (dInt250.isAvailable(*cinfo))
+    std::cout << " dInt250: " << dInt250(*cinfo);
+  if (anInt10.isAvailable(*cinfo))
+    std::cout << " anInt10: " << anInt10(*cinfo);
+  std::cout << "\n";
+
+  const CVec* ctrig = 0;
+  CHECK( evtStore()->retrieve (ctrig, m_readPrefix + "ctrig") );
+
+  names.clear();
+  for (SG::auxid_t auxid : ctrig->getAuxIDs())
+    names.push_back (r.getName(auxid));
+  std::sort (names.begin(), names.end());
+  std::cout << "ctrig aux items: ";
+  for (const std::string& n : names)
+    std::cout << n << " ";
+  std::cout << "\n";
+
+  for (const C* c : *ctrig) {
+    std::cout << " anInt1 " << c->anInt()
+              << " aFloat: " << c->aFloat()
+              << " anInt2: " << anInt2(*c)
+              << " dInt1: " << dInt1(*c);
+      if (dInt100.isAvailable(*c))
+        std::cout << " dInt100: " << dInt100(*c);
+      if (dInt150.isAvailable(*c))
+        std::cout << " dInt150: " << dInt150(*c);
+      if (dInt200.isAvailable(*c))
+        std::cout << " dInt200: " << dInt200(*c);
+      if (anInt10.isAvailable(*c))
+        std::cout << " anInt10: " << anInt10(*c);
+    std::cout << "\n";
+  }
+
+  if (!m_writePrefix.empty()) {
+    // Passing this as the third arg of record will make the object const.
+    bool LOCKED = false;
+
+    std::unique_ptr<CVec> vecnew (new CVec);
+    std::unique_ptr<CAuxContainer> store (new CAuxContainer);
+    vecnew->setStore (store.get());
+    for (size_t i = 0; i < vec->size(); i++) {
+      vecnew->push_back (new C);
+      *vecnew->back() = *(*vec)[i];
+    }
+    CHECK (evtStore()->record (std::move(vecnew), m_writePrefix + "cvec", LOCKED));
+    CHECK (evtStore()->record (std::move(store), m_writePrefix + "cvecAux.", LOCKED));
+
+    std::unique_ptr<C> cnew (new C);
+    std::unique_ptr<CInfoAuxContainer> info_store (new CInfoAuxContainer);
+    cnew->setStore (info_store.get());
+    *cnew = *cinfo;
+
+    CHECK (evtStore()->record (std::move(cnew), m_writePrefix + "cinfo", LOCKED));
+    CHECK (evtStore()->record (std::move(info_store), m_writePrefix + "cinfoAux.", LOCKED));
+
+    std::unique_ptr<CVec> ctrignew (new CVec);
+    std::unique_ptr<CTrigAuxContainer> trig_store (new CTrigAuxContainer);
+    ctrignew->setStore (trig_store.get());
+    for (size_t i = 0; i < ctrig->size(); i++) {
+      ctrignew->push_back (new C);
+      *ctrignew->back() = *(*ctrig)[i];
+    }
+    CHECK (evtStore()->record (std::move(ctrignew), m_writePrefix + "ctrig", LOCKED));
+    CHECK (evtStore()->record (std::move(trig_store), m_writePrefix + "ctrigAux.", LOCKED));
+  }
+
+  return StatusCode::SUCCESS;
+}
+
+
+/**
+ * @brief Algorithm finalization; called at the end of the job.
+ */
+StatusCode xAODTestRead::finalize()
+{
+  return StatusCode::SUCCESS;
+}
+
+
+} // namespace DMTest
+
diff --git a/Control/DataModelTest/DataModelTestDataRead/src/xAODTestRead.h b/Control/DataModelTest/DataModelTestDataRead/src/xAODTestRead.h
new file mode 100644
index 0000000000000000000000000000000000000000..053a2b252f493f139102e5be4db22a2c846b0c26
--- /dev/null
+++ b/Control/DataModelTest/DataModelTestDataRead/src/xAODTestRead.h
@@ -0,0 +1,74 @@
+// 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 src/xAODTestRead.h
+ * @author scott snyder <snyder@bnl.gov>
+ * @date May, 2014
+ * @brief Algorithm to test reading xAOD data.
+ */
+
+
+#ifndef DATAMODELTESTDATAREAD_XAODTESTREAD_H
+#define DATAMODELTESTDATAREAD_XAODTESTREAD_H
+
+
+#include "AthenaBaseComps/AthAlgorithm.h"
+
+
+namespace DMTest {
+
+
+/**
+ * @brief Algorithm to test reading xAOD data.
+ */
+class xAODTestRead
+  : public AthAlgorithm
+{
+public:
+  /**
+   * @brief Constructor.
+   * @param name The algorithm name.
+   * @param svc The service locator.
+   */
+  xAODTestRead (const std::string &name, ISvcLocator *pSvcLocator);
+  
+
+  /**
+   * @brief Algorithm initialization; called at the beginning of the job.
+   */
+  virtual StatusCode initialize();
+
+
+  /**
+   * @brief Algorithm event processing.
+   */
+  virtual StatusCode execute(); 
+
+
+  /**
+   * @brief Algorithm finalization; called at the end of the job.
+   */
+  virtual StatusCode finalize();
+
+
+private:
+  /// Parameter: Prefix for names read from SG.
+  std::string m_readPrefix;
+
+  /// Parameter: Prefix for names written to SG.  Null for no write.
+  std::string m_writePrefix;
+
+  /// Event counter.
+  int m_count;
+};
+
+
+} // namespace DMTest
+
+
+#endif // not DATAMODELTESTDATAREAD_XAODTESTREAD_H
diff --git a/Control/DataModelTest/DataModelTestDataRead/src/xAODTestShallowCopy.cxx b/Control/DataModelTest/DataModelTestDataRead/src/xAODTestShallowCopy.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..8fd9ae565f29197d50f88638f340799ed08a7588
--- /dev/null
+++ b/Control/DataModelTest/DataModelTestDataRead/src/xAODTestShallowCopy.cxx
@@ -0,0 +1,116 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// $Id$
+/**
+ * @file  src/xAODTestShallowCopy.cxx
+ * @author snyder@bnl.gov
+ * @date Jun, 2014
+ * @brief Algorithm to test shallow-copy of xAOD data.
+ */
+
+
+#include "xAODTestShallowCopy.h"
+#include "DataModelTestDataCommon/CVec.h"
+#include "DataModelTestDataCommon/C.h"
+#include "DataModelTestDataCommon/CAuxContainer.h"
+#include "DataModelTestDataCommon/CTrigAuxContainer.h"
+#include "DataModelTestDataCommon/CInfoAuxContainer.h"
+#include "xAODCore/ShallowCopy.h"
+#include "AthContainers/AuxTypeRegistry.h"
+#include "AthenaKernel/errorcheck.h"
+
+
+namespace DMTest {
+
+
+/**
+ * @brief Constructor.
+ * @param name The algorithm name.
+ * @param svc The service locator.
+ */
+xAODTestShallowCopy::xAODTestShallowCopy (const std::string &name,
+                            ISvcLocator *pSvcLocator)
+  : AthAlgorithm (name, pSvcLocator),
+    m_count(0)
+{
+  declareProperty ("ReadPrefix",  m_readPrefix);
+  declareProperty ("WritePrefix", m_writePrefix);
+}
+  
+
+/**
+ * @brief Algorithm initialization; called at the beginning of the job.
+ */
+StatusCode xAODTestShallowCopy::initialize()
+{
+  return StatusCode::SUCCESS;
+}
+
+
+/**
+ * @brief Algorithm event processing.
+ */
+StatusCode xAODTestShallowCopy::execute()
+{
+  ++m_count;
+
+  static C::Accessor<int> anInt10 ("anInt10");
+
+  {
+    const CVec* vec = 0;
+    CHECK( evtStore()->retrieve (vec, m_readPrefix + "cvec") );
+    auto ret = xAOD::shallowCopyContainer (*vec);
+
+    for (C* c : *ret.first)
+      anInt10(*c) = m_count * 20000 + c->anInt() * 100;
+
+    CHECK (evtStore()->record (ret.first, m_writePrefix + "cvec"));
+    CHECK (evtStore()->record (ret.second, m_writePrefix + "cvecAux."));
+    CHECK (evtStore()->setConst (ret.first));
+    CHECK (evtStore()->setConst (ret.second));
+  }
+
+  {
+    const C* cinfo = 0;
+    CHECK( evtStore()->retrieve (cinfo, m_readPrefix + "cinfo") );
+    auto ret = xAOD::shallowCopyObject (*cinfo);
+
+    anInt10(*ret.first) = m_count * 20000 + ret.first->anInt() * 200;
+
+    CHECK (evtStore()->record (ret.first, m_writePrefix + "cinfo"));
+    CHECK (evtStore()->record (ret.second, m_writePrefix + "cinfoAux."));
+    CHECK (evtStore()->setConst (ret.first));
+    CHECK (evtStore()->setConst (ret.second));
+  }
+
+  {
+    const CVec* ctrig = 0;
+    CHECK( evtStore()->retrieve (ctrig, m_readPrefix + "ctrig") );
+    auto ret = xAOD::shallowCopyContainer (*ctrig);
+
+    for (C* c : *ret.first)
+      anInt10(*c) = m_count * 20000 + c->anInt() * 300;
+
+    CHECK (evtStore()->record (ret.first, m_writePrefix + "ctrig"));
+    CHECK (evtStore()->record (ret.second, m_writePrefix + "ctrigAux."));
+    CHECK (evtStore()->setConst (ret.first));
+    CHECK (evtStore()->setConst (ret.second));
+  }
+
+  return StatusCode::SUCCESS;
+}
+
+
+/**
+ * @brief Algorithm finalization; called at the end of the job.
+ */
+StatusCode xAODTestShallowCopy::finalize()
+{
+  return StatusCode::SUCCESS;
+}
+
+
+} // namespace DMTest
+
diff --git a/Control/DataModelTest/DataModelTestDataRead/src/xAODTestShallowCopy.h b/Control/DataModelTest/DataModelTestDataRead/src/xAODTestShallowCopy.h
new file mode 100644
index 0000000000000000000000000000000000000000..5853c5c80f45572f5db6a7d02d8057e3e74bb585
--- /dev/null
+++ b/Control/DataModelTest/DataModelTestDataRead/src/xAODTestShallowCopy.h
@@ -0,0 +1,74 @@
+// 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 src/xAODTestShallowCopy.h
+ * @author scott snyder <snyder@bnl.gov>
+ * @date Jun, 2014
+ * @brief Algorithm to test shallow-copy of xAOD data.
+ */
+
+
+#ifndef DATAMODELTESTDATAREAD_XAODTESTSHALLOWCOPY_H
+#define DATAMODELTESTDATAREAD_XAODTESTSHALLOWCOPY_H
+
+
+#include "AthenaBaseComps/AthAlgorithm.h"
+
+
+namespace DMTest {
+
+
+/**
+ * @brief Algorithm for reading test aux data.
+ */
+class xAODTestShallowCopy
+  : public AthAlgorithm
+{
+public:
+  /**
+   * @brief Constructor.
+   * @param name The algorithm name.
+   * @param svc The service locator.
+   */
+  xAODTestShallowCopy (const std::string &name, ISvcLocator *pSvcLocator);
+  
+
+  /**
+   * @brief Algorithm initialization; called at the beginning of the job.
+   */
+  virtual StatusCode initialize();
+
+
+  /**
+   * @brief Algorithm event processing.
+   */
+  virtual StatusCode execute(); 
+
+
+  /**
+   * @brief Algorithm finalization; called at the end of the job.
+   */
+  virtual StatusCode finalize();
+
+
+private:
+  /// Parameter: Prefix for names read from SG.
+  std::string m_readPrefix;
+
+  /// Parameter: Prefix for names written to SG.  Null for no write.
+  std::string m_writePrefix;
+
+  /// Event counter.
+  int m_count;
+};
+
+
+} // namespace DMTest
+
+
+#endif // not DATAMODELTESTDATAREAD_XAODTESTSHALLOWCOPY_H
diff --git a/Control/DataModelTest/DataModelTestDataRead/src/xAODTestTypelessRead.cxx b/Control/DataModelTest/DataModelTestDataRead/src/xAODTestTypelessRead.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..71edaaf286e20daff7adfd0d328ab75904bc5f0d
--- /dev/null
+++ b/Control/DataModelTest/DataModelTestDataRead/src/xAODTestTypelessRead.cxx
@@ -0,0 +1,195 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// $Id$
+/**
+ * @file  src/xAODTestTypelessRead.cxx
+ * @author snyder@bnl.gov
+ * @date May 2014
+ * @brief Algorithm to test reading @c DataVector with auxiliary data,
+ *        without compile-time typing of aux data.
+ */
+
+
+#include "xAODTestTypelessRead.h"
+#include "DataModelTestDataCommon/C.h"
+#include "DataModelTestDataCommon/CVec.h"
+#include "DataModelTestDataCommon/CAuxContainer.h"
+#include "DataModelTestDataCommon/CTrigAuxContainer.h"
+#include "DataModelTestDataCommon/CInfoAuxContainer.h"
+#include "AthContainers/AuxTypeRegistry.h"
+#include "AthContainers/AuxStoreInternal.h"
+#include "AthLinks/ElementLink.h"
+#include "AthenaKernel/errorcheck.h"
+#include "CxxUtils/StrFormat.h"
+#include "GaudiKernel/System.h"
+#include <memory>
+
+
+namespace DMTest {
+
+
+/**
+ * @brief Constructor.
+ * @param name The algorithm name.
+ * @param svc The service locator.
+ */
+xAODTestTypelessRead::xAODTestTypelessRead (const std::string &name,
+                                            ISvcLocator *pSvcLocator)
+  : AthAlgorithm (name, pSvcLocator),
+    m_count(0)
+{
+  declareProperty ("WritePrefix", m_writePrefix);
+}
+  
+
+/**
+ * @brief Algorithm initialization; called at the beginning of the job.
+ */
+StatusCode xAODTestTypelessRead::initialize()
+{
+  return StatusCode::SUCCESS;
+}
+
+
+namespace {
+
+
+void dumpAuxItem (SG::auxid_t auxid, const SG::AuxVectorData& c, size_t i)
+{
+  const SG::AuxTypeRegistry& r = SG::AuxTypeRegistry::instance();
+  const std::type_info* ti = r.getType(auxid);
+  std::cout << r.getName(auxid) << ": ";
+  if (ti == &typeid(int))
+    std::cout << c.getData<int> (auxid, i) << "; ";
+  else if (ti == &typeid(float))
+    std::cout << CxxUtils::strformat ("%.1f", c.getData<float> (auxid, i)) << "; ";
+  else if (ti == &typeid(ElementLink<DMTest::CVec>)) {
+    const ElementLink<DMTest::CVec>& el =
+      c.getData<ElementLink<DMTest::CVec> > (auxid, i);
+    std::cout << el.dataID() << "[" << el.index() << "]; ";
+  }
+  else
+    std::cout << "xxx; ";
+}
+
+
+} // anonymous namespace
+
+
+/**
+ * @brief Algorithm event processing.
+ */
+StatusCode xAODTestTypelessRead::execute()
+{
+  ++m_count;
+  std::cout << m_count << "\n";
+
+  const SG::AuxTypeRegistry& r = SG::AuxTypeRegistry::instance();
+
+  const CVec* vec = 0;
+  CHECK( evtStore()->retrieve (vec, "cvec") );
+
+  // Sort auxids in name order.
+  std::map<std::string, SG::auxid_t> auxid_map;
+  for (SG::auxid_t auxid : vec->getAuxIDs())
+    auxid_map[r.getName(auxid)] = auxid;
+
+  std::cout << "cvec types: ";
+  for (const auto& m : auxid_map)
+    std::cout << r.getName(m.second) << "/" 
+              << System::typeinfoName (*r.getType(m.second)) << " ";
+  std::cout << "\n";
+  for (size_t i = 0; i < vec->size(); i++) {
+    std::cout << "  ";
+    for (const auto& m : auxid_map)
+      dumpAuxItem (m.second, *vec, i);
+    std::cout << "\n";
+  }
+
+  const C* c = 0;
+  CHECK( evtStore()->retrieve (c, "cinfo") );
+  const SG::AuxVectorData* cont = c->container();
+
+  std::map<std::string, SG::auxid_t> cauxid_map;
+  for (SG::auxid_t auxid : cont->getAuxIDs())
+    cauxid_map[r.getName(auxid)] = auxid;
+
+  std::cout << "cinfo types: ";
+  for (const auto& m : cauxid_map)
+    std::cout << r.getName(m.second) << "/" 
+              << System::typeinfoName (*r.getType(m.second)) << " ";
+  std::cout << "\n";
+  for (const auto& m : cauxid_map)
+    dumpAuxItem (m.second, *cont, 0);
+  std::cout << "\n";
+
+  const CVec* ctrig = 0;
+  CHECK( evtStore()->retrieve (ctrig, "ctrig") );
+
+  // Sort auxids in name order.
+  std::map<std::string, SG::auxid_t> trig_auxid_map;
+  for (SG::auxid_t auxid : ctrig->getAuxIDs())
+    trig_auxid_map[r.getName(auxid)] = auxid;
+
+  std::cout << "ctrig types: ";
+  for (const auto& m : trig_auxid_map)
+    std::cout << r.getName(m.second) << "/" 
+              << System::typeinfoName (*r.getType(m.second)) << " ";
+  std::cout << "\n";
+  for (size_t i = 0; i < ctrig->size(); i++) {
+    std::cout << "  ";
+    for (const auto& m : trig_auxid_map)
+      dumpAuxItem (m.second, *ctrig, i);
+    std::cout << "\n";
+  }
+
+  if (!m_writePrefix.empty()) {
+    // Passing this as the third arg of record will make the object const.
+    bool LOCKED = false;
+
+    std::unique_ptr<CVec> vecnew (new CVec);
+    std::unique_ptr<CAuxContainer> store (new CAuxContainer);
+    vecnew->setStore (store.get());
+    for (size_t i = 0; i < vec->size(); i++) {
+      vecnew->push_back (new C);
+      *vecnew->back() = *(*vec)[i];
+    }
+    CHECK (evtStore()->record (std::move(vecnew), m_writePrefix + "cvec", LOCKED));
+    CHECK (evtStore()->record (std::move(store), m_writePrefix + "cvecAux.", LOCKED));
+
+    std::unique_ptr<C> cnew (new C);
+    std::unique_ptr<CInfoAuxContainer> info_store (new CInfoAuxContainer);
+    cnew->setStore (info_store.get());
+    *cnew = *c;
+
+    CHECK (evtStore()->record (std::move(cnew), m_writePrefix + "cinfo", LOCKED));
+    CHECK (evtStore()->record (std::move(info_store), m_writePrefix + "cinfoAux.", LOCKED));
+
+    std::unique_ptr<CVec> ctrignew (new CVec);
+    std::unique_ptr<CTrigAuxContainer> trig_store (new CTrigAuxContainer);
+    ctrignew->setStore (trig_store.get());
+    for (size_t i = 0; i < ctrig->size(); i++) {
+      ctrignew->push_back (new C);
+      *ctrignew->back() = *(*ctrig)[i];
+    }
+    CHECK (evtStore()->record (std::move(ctrignew), m_writePrefix + "ctrig", LOCKED));
+    CHECK (evtStore()->record (std::move(trig_store), m_writePrefix + "ctrigAux.", LOCKED));
+  }
+
+  return StatusCode::SUCCESS;
+}
+
+
+/**
+ * @brief Algorithm finalization; called at the end of the job.
+ */
+StatusCode xAODTestTypelessRead::finalize()
+{
+  return StatusCode::SUCCESS;
+}
+
+
+} // namespace DMTest
+
diff --git a/Control/DataModelTest/DataModelTestDataRead/src/xAODTestTypelessRead.h b/Control/DataModelTest/DataModelTestDataRead/src/xAODTestTypelessRead.h
new file mode 100644
index 0000000000000000000000000000000000000000..4f6729365ba37b825448679a3dc0562ce6578e48
--- /dev/null
+++ b/Control/DataModelTest/DataModelTestDataRead/src/xAODTestTypelessRead.h
@@ -0,0 +1,71 @@
+// 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 src/xAODTestTypelessRead.h
+ * @author scott snyder <snyder@bnl.gov>
+ * @date May, 2014
+ * @brief Algorithm to test reading xAOD objects with auxiliary data,
+ *        without compile-time typing of aux data.
+ */
+
+#ifndef DATAMODELTESTDATAREAD_XAODTESTTYPELESSREAD_H
+#define DATAMODELTESTDATAREAD_XAODTESTTYPELESSREAD_H
+
+
+#include "AthenaBaseComps/AthAlgorithm.h"
+
+
+namespace DMTest {
+
+
+/**
+ * @brief Algorithm for reading test xAOD data.
+ */
+class xAODTestTypelessRead
+  : public AthAlgorithm
+{
+public:
+  /**
+   * @brief Constructor.
+   * @param name The algorithm name.
+   * @param svc The service locator.
+   */
+  xAODTestTypelessRead (const std::string &name, ISvcLocator *pSvcLocator);
+  
+
+  /**
+   * @brief Algorithm initialization; called at the beginning of the job.
+   */
+  virtual StatusCode initialize();
+
+
+  /**
+   * @brief Algorithm event processing.
+   */
+  virtual StatusCode execute(); 
+
+
+  /**
+   * @brief Algorithm finalization; called at the end of the job.
+   */
+  virtual StatusCode finalize();
+
+
+private:
+  /// Parameter: Prefix for names written to SG.  Null for no write.
+  std::string m_writePrefix;
+
+  /// Event counter.
+  int m_count;
+};
+
+
+} // namespace DMTest
+
+
+#endif // not DATAMODELTESTDATAREAD_XAODTESTTYPELESSREAD_H