From bd3ba5fc26ed7664b0ae95958b41ee1682934f58 Mon Sep 17 00:00:00 2001
From: Charles Leggett <charles.g.leggett@gmail.com>
Date: Tue, 20 Dec 2016 20:58:38 +0100
Subject: [PATCH] Property modernization w/ Gaudi v28 (StoreGate-03-09-00)

	* updates for Property modernization. see gaudi/Gaudi!182
	* updates for DataHandle::setKey being const
	* requires Gaudi v28
	* tag StoreGate-03-09-00

M       test/VarHandleKeyProperty_test.cxx
M       test/VarHandleProperty_test.cxx
M       src/VarHandleKeyArrayProperty.cxx
M       src/VarHandleKeyProperty.cxx
M       src/VarHandleKey.cxx
M       StoreGate/VarHandleProperty.h
M       StoreGate/VarHandleKey.h
M       StoreGate/VarHandleKeyArrayProperty.h
M       StoreGate/VarHandleKeyProperty.h

2016-12-13  scott snyder  <snyder@bnl.gov>

	* Tagging StoreGate-03-08-05.
	* src/SGImplSvc.cxx (recordObject): Do not return an invalid
	proxy.
...
(Long ChangeLog diff - truncated)
---
 Control/StoreGate/StoreGate/ReadHandle.icc    |   4 +-
 Control/StoreGate/StoreGate/StoreGateSvc.h    |   2 +
 Control/StoreGate/StoreGate/StoreGateSvc.icc  |   7 +
 Control/StoreGate/StoreGate/VarHandleBase.h   |  37 +++-
 Control/StoreGate/StoreGate/VarHandleKey.h    |   4 +-
 .../StoreGate/VarHandleKeyArrayProperty.h     |  37 ++--
 .../StoreGate/VarHandleKeyProperty.h          | 136 ++++++++++----
 .../StoreGate/StoreGate/VarHandleProperty.h   | 107 ++++++++---
 Control/StoreGate/StoreGate/WriteHandle.h     |  61 +++++-
 Control/StoreGate/StoreGate/WriteHandle.icc   | 158 ++++++++++++----
 Control/StoreGate/StoreGate/tools/SGImplSvc.h |   8 +-
 .../StoreGate/StoreGate/tools/SGImplSvc.icc   |   6 +
 Control/StoreGate/share/ReadHandle_test.ref   |  17 +-
 .../StoreGate/share/VarHandleBase_test.ref    |  26 +--
 Control/StoreGate/share/VarHandles_test.ref   |  23 +--
 Control/StoreGate/share/WriteHandle_test.ref  |  20 +-
 Control/StoreGate/src/ActiveStoreSvc.cxx      |  15 +-
 Control/StoreGate/src/SGHiveMgrSvc.cxx        |  48 ++++-
 Control/StoreGate/src/SGHiveMgrSvc.h          |  11 +-
 Control/StoreGate/src/SGImplSvc.cxx           |  30 ++-
 Control/StoreGate/src/StoreGateSvc.cxx        |  22 +--
 Control/StoreGate/src/VarHandleBase.cxx       | 174 ++++++++++++------
 Control/StoreGate/src/VarHandleKey.cxx        |   4 +-
 .../src/VarHandleKeyArrayProperty.cxx         |   2 +-
 .../StoreGate/src/VarHandleKeyProperty.cxx    |   2 +-
 .../src/components/StoreGateSvc_entries.cxx   |   3 -
 Control/StoreGate/test/SGtests.cxx            |  39 ++--
 Control/StoreGate/test/VarHandleBase_test.cxx | 105 +++++++++--
 .../test/VarHandleKeyProperty_test.cxx        |  13 +-
 .../StoreGate/test/VarHandleProperty_test.cxx |  13 +-
 Control/StoreGate/test/VarHandles_test.cxx    |  11 +-
 Control/StoreGate/test/WriteHandle_test.cxx   | 151 +++++++++++++--
 32 files changed, 948 insertions(+), 348 deletions(-)

diff --git a/Control/StoreGate/StoreGate/ReadHandle.icc b/Control/StoreGate/StoreGate/ReadHandle.icc
index 5696ec9f6c7..e63bfd4f5d7 100644
--- a/Control/StoreGate/StoreGate/ReadHandle.icc
+++ b/Control/StoreGate/StoreGate/ReadHandle.icc
@@ -2,7 +2,7 @@
   Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
 */
 
-// $Id: ReadHandle.icc 726621 2016-02-27 20:03:45Z ssnyder $
+// $Id: ReadHandle.icc 774989 2016-09-24 11:00:22Z ssnyder $
 /**
  * @file StoreGate/ReadHandle.icc
  * @author S. Binet, P. Calafiura, scott snyder <snyder@bnl.gov>
@@ -209,7 +209,7 @@ template <class T>
 inline
 bool ReadHandle<T>::isValid()
 {
-  return 0 != this->typeless_cptr(); 
+  return 0 != this->typeless_dataPointer(true); 
 }
 
 
diff --git a/Control/StoreGate/StoreGate/StoreGateSvc.h b/Control/StoreGate/StoreGate/StoreGateSvc.h
index 46d90c6f405..f8ae1db12e3 100644
--- a/Control/StoreGate/StoreGate/StoreGateSvc.h
+++ b/Control/StoreGate/StoreGate/StoreGateSvc.h
@@ -711,6 +711,8 @@ public:
 
   /// associate ProxyProviderSvc to this store
   void setProxyProviderSvc(IProxyProviderSvc* pPPSvc);
+  /// Return current ProxyProviderSvc.
+  IProxyProviderSvc* proxyProviderSvc();
   //@}
 
   /////////////////////////////////////////////////////////////////////////
diff --git a/Control/StoreGate/StoreGate/StoreGateSvc.icc b/Control/StoreGate/StoreGate/StoreGateSvc.icc
index e0d38a5fb33..f58f6ab3df7 100644
--- a/Control/StoreGate/StoreGate/StoreGateSvc.icc
+++ b/Control/StoreGate/StoreGate/StoreGateSvc.icc
@@ -528,6 +528,13 @@ StoreGateSvc::setProxyProviderSvc(IProxyProviderSvc* pPPSvc) {
 }
 
 
+inline
+IProxyProviderSvc*
+StoreGateSvc::proxyProviderSvc() {
+  _SGXCALL(proxyProviderSvc, (), nullptr);
+}
+
+
 /**
  * @brief associate a data object to its auxiliary store
  *        Return false if the aux store is not found.
diff --git a/Control/StoreGate/StoreGate/VarHandleBase.h b/Control/StoreGate/StoreGate/VarHandleBase.h
index e8007865bcb..29bf3b5a446 100644
--- a/Control/StoreGate/StoreGate/VarHandleBase.h
+++ b/Control/StoreGate/StoreGate/VarHandleBase.h
@@ -4,7 +4,7 @@
   Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
 */
 
-// $Id: VarHandleBase.h 757253 2016-06-23 13:01:18Z ssnyder $
+// $Id: VarHandleBase.h 787694 2016-12-01 20:03:47Z ssnyder $
 /**
  * @file StoreGate/VarHandleBase.h
  * @author S. Binet, P. Calafiura, scott snyder <snyder@bnl.gov>
@@ -340,6 +340,29 @@ namespace SG {
                             bool returnExisting);
 
 
+    /**
+     * @brief Helper to record an object in the event store.
+     *        Unlike record, put does not change the handle and does not
+     *        cache the pointer in the handle.
+     * @param The wrapped data object (DataBucket) to record.
+     * @param dataPtr Pointer to the transient object itself.
+     * @param allowMods If false, record the object as const.
+     * @param returnExisting Allow an existing object.
+     * @param[out] store The store being used.
+     *
+     * Returns the object placed in the store, or nullptr if there
+     * was an error.
+     * If there was already an object in the store with the given key,
+     * then return null, unless @c returnExisting is true, in which case
+     * return success.  In either case, @c dobj is destroyed.
+     */
+    const void* put_impl (std::unique_ptr<DataObject> dobj,
+                          void* dataPtr,
+                          bool allowMods,
+                          bool returnExisting,
+                          IProxyDict* & store) const;
+
+
     /**
      * @brief Retrieve an object from StoreGate.
      * @param quiet If true, suppress failure messages.
@@ -407,6 +430,18 @@ namespace SG {
      * @param proxy The new proxy.
      */
     void setProxy (SG::DataProxy* proxy);
+
+
+    /**
+     * @brief Retrieve a pointer from a proxy.
+     * @param proxy The proxy object.
+     * @param quiet If true, suppress failure messages.
+     *
+     * Warning --- doesn't enforce const rules; the caller must do that.
+     */
+    void* 
+    typeless_dataPointer_fromProxy (SG::DataProxy* proxy,
+                                    bool quiet) const;
   }; 
 
 
diff --git a/Control/StoreGate/StoreGate/VarHandleKey.h b/Control/StoreGate/StoreGate/VarHandleKey.h
index 9b084d72c48..93cbedd9511 100644
--- a/Control/StoreGate/StoreGate/VarHandleKey.h
+++ b/Control/StoreGate/StoreGate/VarHandleKey.h
@@ -131,8 +131,8 @@ public:
 
 private:
   /// Don't allow calling these.
-  virtual void setKey(const DataObjID& key) override final;
-  virtual void updateKey(const std::string& key) override final;
+  virtual void setKey(const DataObjID& key) const override final;
+  virtual void updateKey(const std::string& key) const override final;
 
 
   /**
diff --git a/Control/StoreGate/StoreGate/VarHandleKeyArrayProperty.h b/Control/StoreGate/StoreGate/VarHandleKeyArrayProperty.h
index eaa86d68f6c..6d2b09892a7 100644
--- a/Control/StoreGate/StoreGate/VarHandleKeyArrayProperty.h
+++ b/Control/StoreGate/StoreGate/VarHandleKeyArrayProperty.h
@@ -33,7 +33,7 @@ namespace Gaudi {
 namespace SG {
 
   class GAUDI_API VarHandleKeyArrayProperty
-    : public ::Property 
+    : public ::PropertyWithHandlers 
   {
   public:
  
@@ -42,17 +42,17 @@ namespace SG {
  
     VarHandleKeyArrayProperty& operator=( const SG::VarHandleKeyArray& value );
  
-    virtual VarHandleKeyArrayProperty* clone() const override;
+    VarHandleKeyArrayProperty* clone() const override;
  
-    virtual bool load( Property& destination ) const override;
+    bool load( Property& destination ) const override;
  
-    virtual bool assign( const Property& source ) override;
+    bool assign( const Property& source ) override;
  
-    virtual std::string toString() const override;
+    std::string toString() const override;
  
-    virtual void toStream(std::ostream& out) const override;
+    void toStream(std::ostream& out) const override;
  
-    virtual StatusCode fromString(const std::string& s) override;
+    StatusCode fromString(const std::string& s) override;
  
     const SG::VarHandleKeyArray& value() const;
  
@@ -69,35 +69,36 @@ namespace SG {
 
 } // namespace SG
 
+namespace Gaudi {
 template<>
-class SimplePropertyRef< SG::VarHandleKeyArray > :
-  public SG::VarHandleKeyArrayProperty
+  class Property<SG::VarHandleKeyArray&> : public SG::VarHandleKeyArrayProperty
 {
 public:
-  SimplePropertyRef(const std::string& name, SG::VarHandleKeyArray& value) :
+    Property(const std::string& name, SG::VarHandleKeyArray& value) : 
     SG::VarHandleKeyArrayProperty(name, value) {}
+    virtual ~Property() {}
 };
 
-
 template<typename T>
-class SimplePropertyRef< SG::ReadHandleKeyArray<T> > :
-  public SG::VarHandleKeyArrayProperty
+  class Property<SG::ReadHandleKeyArray<T>&> : public SG::VarHandleKeyArrayProperty
 {
 public:
-  SimplePropertyRef(const std::string& name, SG::ReadHandleKeyArray<T>& value) :
+    Property(const std::string& name, SG::ReadHandleKeyArray<T>& value) : 
     SG::VarHandleKeyArrayProperty(name, value) {}
+    virtual ~Property() {}
 };
 
 template<typename T>
-class SimplePropertyRef< SG::WriteHandleKeyArray<T> > :
-  public SG::VarHandleKeyArrayProperty
+  class Property<SG::WriteHandleKeyArray<T>&> : public SG::VarHandleKeyArrayProperty
 {
 public:
-  SimplePropertyRef( const std::string& name, 
-                     SG::WriteHandleKeyArray<T>& value ) :
+    Property(const std::string& name, SG::WriteHandleKeyArray<T>& value) : 
     SG::VarHandleKeyArrayProperty(name, value) {}
+    virtual ~Property() {}
 };
 
+}
+
 
 
 
diff --git a/Control/StoreGate/StoreGate/VarHandleKeyProperty.h b/Control/StoreGate/StoreGate/VarHandleKeyProperty.h
index 29acbe849a8..267ecae8dbb 100644
--- a/Control/StoreGate/StoreGate/VarHandleKeyProperty.h
+++ b/Control/StoreGate/StoreGate/VarHandleKeyProperty.h
@@ -21,6 +21,7 @@
 #define STOREGATE_VARHANDLEKEYPROPERTY_H
 
 
+#include "StoreGate/VarHandleKey.h"
 #include "StoreGate/ReadHandleKey.h"
 #include "StoreGate/ReadCondHandleKey.h"
 #include "StoreGate/WriteHandleKey.h"
@@ -75,8 +76,7 @@ namespace SG {
  * The Property object refers to an instance of @c SG::VarHandleKey
  * (the value object) and provides generic methods for manipulating it.
  */
-class GAUDI_API VarHandleKeyProperty
-  : public ::Property 
+class GAUDI_API VarHandleKeyProperty : public PropertyWithHandlers 
 {
 public:
 
@@ -103,7 +103,7 @@ public:
    * The new object will be associated with the _same_ value object
    * as the original.
    */
-  virtual VarHandleKeyProperty* clone() const override;
+  VarHandleKeyProperty* clone() const override;
 
 
   /**
@@ -114,7 +114,7 @@ public:
    * by converting to a string and back again.  Returns true on success,
    * false on failure.
    */
-  virtual bool load( Property& destination ) const override;
+  bool load( Property& destination ) const override;
 
 
   /**
@@ -125,20 +125,20 @@ public:
    * by converting to a string and back again.  Returns true on success,
    * false on failure.
    */
-  virtual bool assign( const Property& source ) override;
+  bool assign( const Property& source ) override;
 
 
   /**
    * @brief Return a string representation of the value object.
    */
-  virtual std::string toString() const override;
+  std::string toString() const override;
 
 
   /**
    * @brief Write a string representation of the value object to a stream.
    * @param out Stream to which to write.
    */
-  virtual void toStream(std::ostream& out) const override;
+  void toStream(std::ostream& out) const override;
 
 
   /**
@@ -147,7 +147,7 @@ public:
    *
    * Returns failure if the conversion does not succeed.
    */
-  virtual StatusCode fromString(const std::string& s) override;
+  StatusCode fromString(const std::string& s) override;
 
 
   /**
@@ -178,62 +178,118 @@ private:
 
 // ** Specializations of SimplePropertyRef for the HandleKey classes.
 
+namespace Gaudi {
 template<>
-class SimplePropertyRef< SG::VarHandleKey > :
-  public SG::VarHandleKeyProperty
-{
+  class Property<::SG::VarHandleKey&> : public ::SG::VarHandleKeyProperty {
 public:
-  SimplePropertyRef(const std::string& name, SG::VarHandleKey& value) :
-    SG::VarHandleKeyProperty(name, value) {}
-};
+    Property(const std::string& name, ::SG::VarHandleKey& value) : ::SG::VarHandleKeyProperty(name,value) {}
 
+    virtual ~Property() {}
+  };
 
 template<typename T>
-class SimplePropertyRef< SG::ReadHandleKey<T> > :
-  public SG::VarHandleKeyProperty
-{
+  class Property<::SG::ReadHandleKey<T>&> : public ::SG::VarHandleKeyProperty {
 public:
-  SimplePropertyRef(const std::string& name, SG::ReadHandleKey<T>& value) :
-    SG::VarHandleKeyProperty(name, value) {}
+    Property(const std::string& name, ::SG::ReadHandleKey<T>& value) : ::SG::VarHandleKeyProperty(name,value) {}
+
+    virtual ~Property() {}
 };
 
 template<typename T>
-class SimplePropertyRef< SG::ReadCondHandleKey<T> > :
-  public SG::VarHandleKeyProperty
-{
+  class Property<::SG::WriteHandleKey<T>&> : public ::SG::VarHandleKeyProperty {
 public:
-  SimplePropertyRef(const std::string& name, SG::ReadCondHandleKey<T>& value) :
-    SG::VarHandleKeyProperty(name, value) {}
-};
+    Property(const std::string& name, ::SG::WriteHandleKey<T>& value) : ::SG::VarHandleKeyProperty(name,value) {}
 
+    virtual ~Property() {}
+  };
 
 template<typename T>
-class SimplePropertyRef< SG::UpdateHandleKey<T> > :
-  public SG::VarHandleKeyProperty
-{
+  class Property<::SG::UpdateHandleKey<T>&> : public ::SG::VarHandleKeyProperty {
 public:
-  SimplePropertyRef( const std::string& name, SG::UpdateHandleKey<T>& value ) :
-    SG::VarHandleKeyProperty(name, value) {}
+    Property(const std::string& name, ::SG::UpdateHandleKey<T>& value) : ::SG::VarHandleKeyProperty(name,value) {}
+
+    virtual ~Property() {}
 };
 
 
 template<typename T>
-class SimplePropertyRef< SG::WriteHandleKey<T> > :
-  public SG::VarHandleKeyProperty
-{
+  class Property<::SG::ReadCondHandleKey<T>&> : public ::SG::VarHandleKeyProperty {
 public:
-  SimplePropertyRef( const std::string& name, SG::WriteHandleKey<T>& value ) :
-    SG::VarHandleKeyProperty(name, value) {}
+    Property(const std::string& name, ::SG::ReadCondHandleKey<T>& value) : ::SG::VarHandleKeyProperty(name,value) {}
+
+    virtual ~Property() {}
 };
 
 template<typename T>
-class SimplePropertyRef< SG::WriteCondHandleKey<T> > :
-  public SG::VarHandleKeyProperty
-{
+  class Property<::SG::WriteCondHandleKey<T>&> : public ::SG::VarHandleKeyProperty {
 public:
-  SimplePropertyRef( const std::string& name, SG::WriteCondHandleKey<T>& value ) :
-    SG::VarHandleKeyProperty(name, value) {}
+    Property(const std::string& name, ::SG::WriteCondHandleKey<T>& value) : ::SG::VarHandleKeyProperty(name,value) {}
+
+    virtual ~Property() {}
 };
 
 
+
+}
+
+
+
+// template<>
+// class SimplePropertyRef< SG::VarHandleKey > :
+//   public SG::VarHandleKeyProperty
+// {
+// public:
+//   SimplePropertyRef(const std::string& name, SG::VarHandleKey& value) :
+//     SG::VarHandleKeyProperty(name, value) {}
+// };
+
+
+// template<typename T>
+// class SimplePropertyRef< SG::ReadHandleKey<T> > :
+//   public SG::VarHandleKeyProperty
+// {
+// public:
+//   SimplePropertyRef(const std::string& name, SG::ReadHandleKey<T>& value) :
+//     SG::VarHandleKeyProperty(name, value) {}
+// };
+
+// template<typename T>
+// class SimplePropertyRef< SG::ReadCondHandleKey<T> > :
+//   public SG::VarHandleKeyProperty
+// {
+// public:
+//   SimplePropertyRef(const std::string& name, SG::ReadCondHandleKey<T>& value) :
+//     SG::VarHandleKeyProperty(name, value) {}
+// };
+
+
+// template<typename T>
+// class SimplePropertyRef< SG::UpdateHandleKey<T> > :
+//   public SG::VarHandleKeyProperty
+// {
+// public:
+//   SimplePropertyRef( const std::string& name, SG::UpdateHandleKey<T>& value ) :
+//     SG::VarHandleKeyProperty(name, value) {}
+// };
+
+
+// template<typename T>
+// class SimplePropertyRef< SG::WriteHandleKey<T> > :
+//   public SG::VarHandleKeyProperty
+// {
+// public:
+//   SimplePropertyRef( const std::string& name, SG::WriteHandleKey<T>& value ) :
+//     SG::VarHandleKeyProperty(name, value) {}
+// };
+
+// template<typename T>
+// class SimplePropertyRef< SG::WriteCondHandleKey<T> > :
+//   public SG::VarHandleKeyProperty
+// {
+// public:
+//   SimplePropertyRef( const std::string& name, SG::WriteCondHandleKey<T>& value ) :
+//     SG::VarHandleKeyProperty(name, value) {}
+// };
+
+
 #endif // not STOREGATE_VARHANDLEKEYPROPERTY_H
diff --git a/Control/StoreGate/StoreGate/VarHandleProperty.h b/Control/StoreGate/StoreGate/VarHandleProperty.h
index ff7155d2075..9aa6a4100b0 100644
--- a/Control/StoreGate/StoreGate/VarHandleProperty.h
+++ b/Control/StoreGate/StoreGate/VarHandleProperty.h
@@ -22,63 +22,116 @@
 
 // ** Specializations of SimplePropertyRef for the VarHandle classes.
 
+namespace Gaudi {
 template<>
-class SimplePropertyRef< SG::VarHandleBase > :
-  public SG::VarHandleKeyProperty
-{
+  class Property<SG::VarHandleBase&> : public SG::VarHandleKeyProperty {
 public:
-  SimplePropertyRef(const std::string& name, SG::VarHandleBase& value) :
+    Property(const std::string& name, SG::VarHandleBase& value) : 
     SG::VarHandleKeyProperty(name, value) {}
+    virtual ~Property() {}
 };
 
-
 template<typename T>
-class SimplePropertyRef< SG::ReadHandle<T> > :
-  public SG::VarHandleKeyProperty
-{
+  class Property<SG::ReadHandle<T>&> : public SG::VarHandleKeyProperty {
 public:
-  SimplePropertyRef(const std::string& name, SG::ReadHandle<T>& value) :
+    Property(const std::string& name, SG::ReadHandle<T>& value) : 
     SG::VarHandleKeyProperty(name, value) {}
+    virtual ~Property() {}
 };
 
-
 template<typename T>
-class SimplePropertyRef< SG::UpdateHandle<T> > :
-  public SG::VarHandleKeyProperty
-{
+  class Property<SG::WriteHandle<T>&> : public SG::VarHandleKeyProperty {
 public:
-  SimplePropertyRef( const std::string& name, SG::UpdateHandle<T>& value ) :
+    Property(const std::string& name, SG::WriteHandle<T>& value) : 
     SG::VarHandleKeyProperty(name, value) {}
+    virtual ~Property() {}
 };
 
-
 template<typename T>
-class SimplePropertyRef< SG::WriteHandle<T> > :
-  public SG::VarHandleKeyProperty
-{
+  class Property<SG::UpdateHandle<T>&> : public SG::VarHandleKeyProperty {
 public:
-  SimplePropertyRef( const std::string& name, SG::WriteHandle<T>& value ) :
+    Property(const std::string& name, SG::UpdateHandle<T>& value) : 
     SG::VarHandleKeyProperty(name, value) {}
+    virtual ~Property() {}
 };
 
+
 template<typename T>
-class SimplePropertyRef< SG::ReadCondHandle<T> > :
-  public SG::VarHandleKeyProperty
-{
+  class Property<SG::ReadCondHandle<T>&> : public SG::VarHandleKeyProperty {
 public:
-  SimplePropertyRef(const std::string& name, SG::ReadCondHandle<T>& value) :
+    Property(const std::string& name, SG::ReadCondHandle<T>& value) : 
     SG::VarHandleKeyProperty(name, value) {}
+    virtual ~Property() {}
 };
 
 template<typename T>
-class SimplePropertyRef< SG::WriteCondHandle<T> > :
-  public SG::VarHandleKeyProperty
-{
+  class Property<SG::WriteCondHandle<T>&> : public SG::VarHandleKeyProperty {
 public:
-  SimplePropertyRef(const std::string& name, SG::WriteCondHandle<T>& value) :
+    Property(const std::string& name, SG::WriteCondHandle<T>& value) : 
     SG::VarHandleKeyProperty(name, value) {}
+    virtual ~Property() {}
 };
 
 
+}
+
+// template<>
+// class SimplePropertyRef< SG::VarHandleBase > :
+//   public SG::VarHandleKeyProperty
+// {
+// public:
+//   SimplePropertyRef(const std::string& name, SG::VarHandleBase& value) :
+//     SG::VarHandleKeyProperty(name, value) {}
+// };
+
+
+// template<typename T>
+// class SimplePropertyRef< SG::ReadHandle<T> > :
+//   public SG::VarHandleKeyProperty
+// {
+// public:
+//   SimplePropertyRef(const std::string& name, SG::ReadHandle<T>& value) :
+//     SG::VarHandleKeyProperty(name, value) {}
+// };
+
+
+// template<typename T>
+// class SimplePropertyRef< SG::UpdateHandle<T> > :
+//   public SG::VarHandleKeyProperty
+// {
+// public:
+//   SimplePropertyRef( const std::string& name, SG::UpdateHandle<T>& value ) :
+//     SG::VarHandleKeyProperty(name, value) {}
+// };
+
+
+// template<typename T>
+// class SimplePropertyRef< SG::WriteHandle<T> > :
+//   public SG::VarHandleKeyProperty
+// {
+// public:
+//   SimplePropertyRef( const std::string& name, SG::WriteHandle<T>& value ) :
+//     SG::VarHandleKeyProperty(name, value) {}
+// };
+
+// template<typename T>
+// class SimplePropertyRef< SG::ReadCondHandle<T> > :
+//   public SG::VarHandleKeyProperty
+// {
+// public:
+//   SimplePropertyRef(const std::string& name, SG::ReadCondHandle<T>& value) :
+//     SG::VarHandleKeyProperty(name, value) {}
+// };
+
+// template<typename T>
+// class SimplePropertyRef< SG::WriteCondHandle<T> > :
+//   public SG::VarHandleKeyProperty
+// {
+// public:
+//   SimplePropertyRef(const std::string& name, SG::WriteCondHandle<T>& value) :
+//     SG::VarHandleKeyProperty(name, value) {}
+// };
+
+
 #endif /* !STOREGATE_VARHANDLEPROPERTY_H */
 
diff --git a/Control/StoreGate/StoreGate/WriteHandle.h b/Control/StoreGate/StoreGate/WriteHandle.h
index 84d99dcff00..b638c69aff2 100644
--- a/Control/StoreGate/StoreGate/WriteHandle.h
+++ b/Control/StoreGate/StoreGate/WriteHandle.h
@@ -4,7 +4,7 @@
   Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
 */
 
-// $Id: WriteHandle.h 756419 2016-06-21 02:02:43Z ssnyder $
+// $Id: WriteHandle.h 787694 2016-12-01 20:03:47Z ssnyder $
 /**
  * @file StoreGate/WriteHandle.h
  * @author S. Binet, P. Calafiura, scott snyder <snyder@bnl.gov>
@@ -53,7 +53,7 @@ namespace SG {
  *
  *   StatusCode MyAlg::execute()
  *   {
- *     ATH_CHECK( m_int.record (CxxUtils::make_unique<int>(42)) );
+ *     ATH_CHECK( m_int.record (std::make_unique<int>(42)) );
  *     ATH_MSG_INFO("int value @[" << m_int.name() << "]="
  *                  << *m_int);
  *     *m_int += 10;
@@ -258,6 +258,63 @@ public:
   StatusCode recordNonConst (SG::DataObjectSharedPtr<T> data);
 
 
+  /**
+   * @brief Record a const object to the store.
+   * @param data The object to record.
+   * @param returnExisting Allow an existing object?
+   *
+   * Unlike record(), this does not change the handle object.
+   * That means that will not be able to get the object back
+   * by dereferencing the handle.
+   * Returns the object placed in the store, or nullptr if there
+   * was an error.
+   * If there was already an object in the store with the given key,
+   * then return null, unless @c returnExisting is true, in which case
+   * return success.  In either case, @c data is destroyed.
+   */
+  const T* put (std::unique_ptr<T> data,
+                bool returnExisting = false) const;
+
+
+  /**
+   * @brief Record a const object to the store.
+   * @param data The object to record.
+   * @param returnExisting Allow an existing object?
+   * @param[out] store The store being used.
+   *
+   * Unlike record(), this does not change the handle object.
+   * That means that will not be able to get the object back
+   * by dereferencing the handle.
+   * Returns the object placed in the store, or nullptr if there
+   * was an error.
+   * If there was already an object in the store with the given key,
+   * then return null, unless @c returnExisting is true, in which case
+   * return success.  In either case, @c data is destroyed.
+   */
+  const T* put (std::unique_ptr<T> data,
+                bool returnExisting,
+                IProxyDict* & store) const;
+
+
+  /**
+   * @brief Record an object and its auxiliary store to the store.
+   * @param data The object to record.
+   * @param auxstore Auxiliary store object.
+   *
+   * Unlike record(), this does not change the handle object.
+   * That means that will not be able to get the object back
+   * by dereferencing the handle.
+   * Returns the object placed in the store, or nullptr if there
+   * was an error.
+   * If there was already an object in the store with the given key,
+   * then return null, and the objects passed in are destroyed.
+   */
+  template <class AUXSTORE>
+  const T*
+  put (std::unique_ptr<T> data,
+       std::unique_ptr<AUXSTORE> auxstore) const;
+
+
   // Commit this out for now since it looks like we don't actually need it.
 #if 0
   /**
diff --git a/Control/StoreGate/StoreGate/WriteHandle.icc b/Control/StoreGate/StoreGate/WriteHandle.icc
index 4b5e3f016dd..3760fddd7fc 100644
--- a/Control/StoreGate/StoreGate/WriteHandle.icc
+++ b/Control/StoreGate/StoreGate/WriteHandle.icc
@@ -2,7 +2,7 @@
   Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
 */
 
-// $Id: WriteHandle.icc 756419 2016-06-21 02:02:43Z ssnyder $
+// $Id: WriteHandle.icc 787694 2016-12-01 20:03:47Z ssnyder $
 /**
  * @file StoreGate/WriteHandle.icc
  * @author S. Binet, P. Calafiura, scott snyder <snyder@bnl.gov>
@@ -23,36 +23,6 @@
 namespace SG {
 
 
-/**
- * @brief Helper to temporarily clear aux store association.
- *
- * This is used in the object+store version of record, in order to prevent
- * the store from being locked prematurely.
- */
-template <class T>
-class SaveStore
-{
-public:
-  SaveStore (T& o)
-    : m_store (o.getStore()),
-      m_o (o)
-  {
-    if (m_store)
-      o.setStore (static_cast<SG::IAuxStore*>(nullptr));
-  }
-
-  ~SaveStore()
-  {
-    if (m_store)
-      m_o.setStore (m_store);
-  }
-
-private:
-  IAuxStore* m_store;
-  T& m_o;
-};
-
-
 //************************************************************************
 // Constructors, etc.
 //
@@ -139,6 +109,8 @@ template <class T>
 WriteHandle<T>::WriteHandle(WriteHandle&& h)
   : VarHandleBase(std::move(h))
 {
+  m_lockAuxPending = h.m_lockAuxPending;
+  h.m_lockAuxPending = nullptr;
 }
 
 
@@ -164,8 +136,11 @@ inline
 WriteHandle<T>& 
 WriteHandle<T>::operator= (WriteHandle&& h)
 {
-  if (this != &h)
+  if (this != &h) {
     this->VarHandleBase::operator=(std::move(h));
+    m_lockAuxPending = h.m_lockAuxPending;
+    h.m_lockAuxPending = nullptr;
+  }
   return *this;
 }
 
@@ -357,6 +332,113 @@ WriteHandle<T>::recordNonConst (SG::DataObjectSharedPtr<T> data)
 }
 
 
+/**
+ * @brief Record a const object to the store.
+ * @param data The object to record.
+ * @param returnExisting Allow an existing object?
+ *
+ * Unlike record(), this does not change the handle object.
+ * That means that will not be able to get the object back
+ * by dereferencing the handle.
+ * Returns the object placed in the store, or nullptr if there
+ * was an error.
+ * If there was already an object in the store with the given key,
+ * then return null, unless @c returnExisting is true, in which case
+ * return success.  In either case, @c data is destroyed.
+ */
+template <class T>
+inline
+const T* WriteHandle<T>::put (std::unique_ptr<T> data,
+                              bool returnExisting /*= false*/) const
+{
+  IProxyDict* store = nullptr;
+  return put (std::move(data), returnExisting, store);
+}
+
+
+/**
+ * @brief Record a const object to the store.
+ * @param data The object to record.
+ * @param returnExisting Allow an existing object?
+ * @param[out] store The store being used.
+ *
+ * Unlike record(), this does not change the handle object.
+ * That means that will not be able to get the object back
+ * by dereferencing the handle.
+ * Returns the object placed in the store, or nullptr if there
+ * was an error.
+ * If there was already an object in the store with the given key,
+ * then return null, unless @c returnExisting is true, in which case
+ * return success.  In either case, @c data is destroyed.
+ */
+template <class T>
+const T* WriteHandle<T>::put (std::unique_ptr<T> data,
+                              bool returnExisting,
+                              IProxyDict* & store) const
+{
+  //typedef typename U::element_type elt_t;
+  typedef T elt_t;
+  
+  // make sure the BaseInfo(Base) structure is initialized
+  SG::BaseInfo<elt_t>::baseinfo();
+
+  void* dataPtr(data.get());
+  std::unique_ptr<DataObject> dobj (SG::asStorable (std::move (data)));
+  return reinterpret_cast<const T*>
+    (this->put_impl (std::move(dobj), dataPtr, false, returnExisting, store));
+}
+
+
+/**
+ * @brief Record an object and its auxiliary store to the store.
+ * @param data The object to record.
+ * @param auxstore Auxiliary store object.
+ *
+ * Unlike record(), this does not change the handle object.
+ * That means that will not be able to get the object back
+ * by dereferencing the handle.
+ * Returns the object placed in the store, or nullptr if there
+ * was an error.
+ * If there was already an object in the store with the given key,
+ * then return null, and the objects passed in are destroyed.
+ */
+template <class T>
+template <class AUXSTORE>
+const T*
+WriteHandle<T>::put (std::unique_ptr<T> data,
+                     std::unique_ptr<AUXSTORE> auxstore) const
+{
+  T& dref = *data;
+
+  // If there's no store association, do it now.
+  if (data->getStore() == nullptr)
+    data->setStore (auxstore.get());
+
+  IProxyDict* store = nullptr;
+  const T* ptr = this->put (std::move(data), false, store);
+  if (!ptr) return nullptr;
+
+  SG::DataObjectSharedPtr<DataObject> dobj
+    (SG::asStorable (std::move (auxstore)));
+  SG::DataProxy* proxy = store->recordObject (std::move(dobj),
+                                              this->name() + "Aux.",
+                                              false,
+                                              false);
+  if (!proxy) {
+    REPORT_ERROR (StatusCode::FAILURE)
+      << "recordObject of aux store failed";
+
+    // If we've failed here, then the aux store object has been deleted,
+    // but not the primary object.  Null out the store pointer to prevent
+    // having a dangling pointer to a deleted object.
+    dref.setStore (static_cast<SG::IConstAuxStore*>(nullptr));
+    return nullptr;
+  }
+
+  return ptr;
+}
+
+
 #if 0
 /**
  * @brief Record a new non-const object, or retrieve an old one.
@@ -458,11 +540,20 @@ WriteHandle<T>::record (std::unique_ptr<T> data,
 {
   T& dref = *data;
 
+  // If there's no store association, do it now.
+  if (data->getStore() == nullptr)
+    data->setStore (auxstore.get());
+
   if (isConst) {
     // Temporarily clear the store association, in order to prevent
     // the aux store from being locked at this point.
-    SaveStore<T> ss (*data);
+    IAuxStore* store = dref.getStore();
+    if (store)
+      dref.setStore (static_cast<SG::IAuxStore*>(nullptr));
     CHECK (this->record(std::move(data)));
+    // Deliberately not using RAII here.  If there is an error,
+    // then the object referenced by data will be deleted.
+    dref.setStore (store);
   }
   else
     CHECK (this->recordNonConst(std::move(data)));
@@ -488,6 +579,7 @@ WriteHandle<T>::record (std::unique_ptr<T> data,
 
   if (m_proxy->isConst())
     m_lockAuxPending = proxy;
+
   return StatusCode::SUCCESS;
 }
 
diff --git a/Control/StoreGate/StoreGate/tools/SGImplSvc.h b/Control/StoreGate/StoreGate/tools/SGImplSvc.h
index bb75e2cdbcd..f7a7638887f 100644
--- a/Control/StoreGate/StoreGate/tools/SGImplSvc.h
+++ b/Control/StoreGate/StoreGate/tools/SGImplSvc.h
@@ -61,7 +61,6 @@
 #include "SGTools/SGVersionedKey.h"
 #include "StoreGate/SGObjectWithVersion.h"
 #include "AthAllocators/Arena.h"
-#include "SGTools/IProxyDictWithPool.h" // TEMPORARY
 
 #include "GaudiKernel/IIncidentSvc.h"
 #include "GaudiKernel/ServiceHandle.h"
@@ -113,7 +112,7 @@ namespace PerfMon { class StorePayloadMon; }
  * @param "FolderNameList" property (default ""): data folders to be created 
  *                                                in this store
  * @author ATLAS Collaboration
- * $Id: SGImplSvc.h 766223 2016-08-03 12:32:24Z will $
+ * $Id: SGImplSvc.h 785927 2016-11-23 03:58:33Z ssnyder $
  **/
 class SGImplSvc :
   public Service, 
@@ -661,6 +660,8 @@ public:
 
   /// associate ProxyProviderSvc to this store
   void setProxyProviderSvc(IProxyProviderSvc* pPPSvc);
+  /// Return current ProxyProviderSvc.
+  IProxyProviderSvc* proxyProviderSvc();
   //@}
 
   /////////////////////////////////////////////////////////////////////////
@@ -937,7 +938,8 @@ private:
                               bool allowMods, bool resetOnly,
                               bool noHist,
                               const std::type_info* tinfo,
-                              SG::DataProxy** proxy_ret);
+                              SG::DataProxy** proxy_ret,
+                              bool noOverwrite);
 
   /// real recording of an object with a key, allow possibility of
   /// specifying const-access
diff --git a/Control/StoreGate/StoreGate/tools/SGImplSvc.icc b/Control/StoreGate/StoreGate/tools/SGImplSvc.icc
index 6ca36a5dc8f..acd34c861cb 100644
--- a/Control/StoreGate/StoreGate/tools/SGImplSvc.icc
+++ b/Control/StoreGate/StoreGate/tools/SGImplSvc.icc
@@ -957,6 +957,12 @@ SGImplSvc::setProxyProviderSvc(IProxyProviderSvc* pPPSvc) {
   m_pPPS = pPPSvc;
 }
 
+inline
+IProxyProviderSvc*
+SGImplSvc::proxyProviderSvc() {
+  return m_pPPS;
+}
+
 //////////////////////////////////////////////////////////////////
 
 template <typename H, typename TKEY>
diff --git a/Control/StoreGate/share/ReadHandle_test.ref b/Control/StoreGate/share/ReadHandle_test.ref
index 22ba7c76fa0..b98311c8b50 100644
--- a/Control/StoreGate/share/ReadHandle_test.ref
+++ b/Control/StoreGate/share/ReadHandle_test.ref
@@ -1,29 +1,25 @@
 
 
 Initializing Gaudi ApplicationMgr using job opts ../share/VarHandleBase_test.txt
-JobOptionsSvc        INFO # =======> /home/sss/nobackup/atlas/build/../tests/../share/VarHandleBase_test.txt
+JobOptionsSvc        INFO # =======> /afs/cern.ch/user/s/ssnyder/atlas-work3/Control/StoreGate/share/../share/VarHandleBase_test.txt
 JobOptionsSvc        INFO # (1,1): ApplicationMgr.ExtSvc = ["StoreGateSvc/OtherStore"]
 JobOptionsSvc        INFO # (2,1): OtherStore.ProxyProviderSvc = ""
 JobOptionsSvc        INFO Job options successfully read in from ../share/VarHandleBase_test.txt
 ApplicationMgr    SUCCESS 
 ====================================================================================================================================
-                                                   Welcome to ApplicationMgr (GaudiCoreSvc v999r999)
-                                          running on karma on Sun Apr 24 21:57:53 2016
+                                                   Welcome to ApplicationMgr (GaudiCoreSvc v4r1)
+                                          running on lxplus003.cern.ch on Fri Sep 23 19:48:51 2016
 ====================================================================================================================================
 ApplicationMgr       INFO Application Manager Configured successfully
-OtherStore           INFO Initializing OtherStore - package version StoreGate-00-00-00
-ClassIDSvc           INFO Initializing ClassIDSvc - package version CLIDComps-00-00-00
-ClassIDSvc           INFO  getRegistryEntries: read 155 CLIDRegistry entries for module ALL
-ClassIDSvc          ERROR uncheckedSetTypePackageForID: PyAnalysisExamples-00-00-00 can not set CLID <86839352> for type name MyObj: Known CLID for this name <293847295> It was set by StoreGate-00-00-00
+ClassIDSvc           INFO  getRegistryEntries: read 214 CLIDRegistry entries for module ALL
+ClassIDSvc          ERROR uncheckedSetTypePackageForID: PyAnalysisExamples-00-00-49 can not set CLID <86839352> for type name MyObj: Known CLID for this name <293847295> It was set by StoreGate-03-07-13
 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
-StoreGateSvc         INFO Initializing StoreGateSvc - package version StoreGate-00-00-00
-ProxyProviderSvc     INFO Initializing ProxyProviderSvc - package version SGComps-00-00-00
-ClassIDSvc           INFO  getRegistryEntries: read 833 CLIDRegistry entries for module ALL
+ClassIDSvc           INFO  getRegistryEntries: read 867 CLIDRegistry entries for module ALL
 ServiceManager      FATAL No Service factory for BazSvc available.
 VarHandleKey.Se...  ERROR ServiceLocatorHelper::service: can not locate service BazSvc
                     FATAL FILE:LINE (StatusCode SG::VarHandleKey::initialize()): code 0: m_storeHandle.retrieve()
@@ -36,7 +32,6 @@ VarHandle(FooSv...WARNING FILE:LINE (void*SG::VarHandleBase::typeless_dataPointe
 VarHandle(FooSv...WARNING FILE:LINE (void*SG::VarHandleBase::typeless_dataPointer_impl(bool)): could not get proxy for key foox
 VarHandle(FooSv...WARNING FILE:LINE (void*SG::VarHandleBase::typeless_dataPointer_impl(bool)): could not get proxy for key foox
 VarHandle(FooSv...WARNING FILE:LINE (void*SG::VarHandleBase::typeless_dataPointer_impl(bool)): could not get proxy for key foox
-VarHandle(FooSv...WARNING FILE:LINE (void*SG::VarHandleBase::typeless_dataPointer_impl(bool)): could not get proxy for key foox
 test4
 ServiceManager      FATAL No Service factory for BazSvc available.
 VarHandleKey.Se...  ERROR ServiceLocatorHelper::service: can not locate service BazSvc
diff --git a/Control/StoreGate/share/VarHandleBase_test.ref b/Control/StoreGate/share/VarHandleBase_test.ref
index 52a5f3640bb..310d34e197d 100644
--- a/Control/StoreGate/share/VarHandleBase_test.ref
+++ b/Control/StoreGate/share/VarHandleBase_test.ref
@@ -1,29 +1,24 @@
 
 
 Initializing Gaudi ApplicationMgr using job opts ../share/VarHandleBase_test.txt
-JobOptionsSvc        INFO # =======> /home/sss/nobackup/atlas/build/../tests/../share/VarHandleBase_test.txt
+JobOptionsSvc        INFO # =======> /home/sss/atlas/dvtest/build/../tests/../share/VarHandleBase_test.txt
 JobOptionsSvc        INFO # (1,1): ApplicationMgr.ExtSvc = ["StoreGateSvc/OtherStore"]
 JobOptionsSvc        INFO # (2,1): OtherStore.ProxyProviderSvc = ""
 JobOptionsSvc        INFO Job options successfully read in from ../share/VarHandleBase_test.txt
 ApplicationMgr    SUCCESS 
 ====================================================================================================================================
-                                                   Welcome to ApplicationMgr (GaudiCoreSvc v999r999)
-                                          running on karma on Sun Apr 24 21:36:13 2016
+                                                   Welcome to ApplicationMgr (GaudiCoreSvc v27r1p99)
+                                          running on karma on Thu Dec  1 11:27:38 2016
 ====================================================================================================================================
 ApplicationMgr       INFO Application Manager Configured successfully
-OtherStore           INFO Initializing OtherStore - package version StoreGate-00-00-00
-ClassIDSvc           INFO Initializing ClassIDSvc - package version CLIDComps-00-00-00
-ClassIDSvc           INFO  getRegistryEntries: read 156 CLIDRegistry entries for module ALL
-ClassIDSvc          ERROR uncheckedSetTypePackageForID: PyAnalysisExamples-00-00-00 can not set CLID <86839352> for type name MyObj: Known CLID for this name <293847295> It was set by StoreGate-00-00-00
+ClassIDSvc           INFO  getRegistryEntries: read 215 CLIDRegistry entries for module ALL
 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
-StoreGateSvc         INFO Initializing StoreGateSvc - package version StoreGate-00-00-00
-ProxyProviderSvc     INFO Initializing ProxyProviderSvc - package version SGComps-00-00-00
-ClassIDSvc           INFO  getRegistryEntries: read 833 CLIDRegistry entries for module ALL
+ClassIDSvc           INFO  getRegistryEntries: read 867 CLIDRegistry entries for module ALL
 ServiceManager      FATAL No Service factory for BazSvc available.
 VarHandleKey.Se...  ERROR ServiceLocatorHelper::service: can not locate service BazSvc
                     FATAL FILE:LINE (StatusCode SG::VarHandleKey::initialize()): code 0: m_storeHandle.retrieve()
@@ -55,7 +50,12 @@ VarHandle(FooSv...  ERROR FILE:LINE (StatusCode SG::VarHandleBase::record_impl(s
 test8
 VarHandle(FooSv...WARNING FILE:LINE (void*SG::VarHandleBase::typeless_dataPointer_impl(bool)): could not get proxy for key foo
 VarHandle(FooSv...WARNING FILE:LINE (void*SG::VarHandleBase::typeless_dataPointer_impl(bool)):  try using a ReadHandle
-VarHandle(FooSv...WARNING FILE:LINE (void*SG::VarHandleBase::typeless_dataPointer_impl(bool)): Proxy  [293847295/foo] is in an invalid state
-VarHandle(FooSv...WARNING FILE:LINE (void*SG::VarHandleBase::typeless_dataPointer_impl(bool)): Request for an invalid object; requested CLID = 293847295, proxy primary ID is 293847296
+VarHandle(FooSv...WARNING FILE:LINE (void*SG::VarHandleBase::typeless_dataPointer_fromProxy(SG::DataProxy*, bool) const): Proxy  [293847295/foo] is in an invalid state
+VarHandle(FooSv...WARNING FILE:LINE (void*SG::VarHandleBase::typeless_dataPointer_fromProxy(SG::DataProxy*, bool) const): Request for an invalid object; requested CLID = 293847295, proxy primary ID is 293847296
 test9
-VarHandleBase @0x7ffcec9b1760 store=FooSvc, clid=293847295, key=foo----------- ptr@0, proxy@0
+VarHandleBase @0x7ffd763ece70 store=FooSvc, clid=293847295, key=foo----------- ptr@0, proxy@0
+test10
+ServiceManager      FATAL No Service factory for FooSvc available.
+VarHandleKey.Se...  ERROR ServiceLocatorHelper::service: can not locate service FooSvc
+VarHandle(FooSv...  ERROR FILE:LINE (const void*SG::VarHandleBase::put_impl(std::unique_ptr<DataObject>, void*, bool, bool, IProxyDict*&) const): code 0: recordObject failed
+VarHandle(FooSv...  ERROR FILE:LINE (const void*SG::VarHandleBase::put_impl(std::unique_ptr<DataObject>, void*, bool, bool, IProxyDict*&) const): code 0: Attempt to record an object with a null key
diff --git a/Control/StoreGate/share/VarHandles_test.ref b/Control/StoreGate/share/VarHandles_test.ref
index 46e2124be7d..f7bdeb31611 100644
--- a/Control/StoreGate/share/VarHandles_test.ref
+++ b/Control/StoreGate/share/VarHandles_test.ref
@@ -1,7 +1,7 @@
 ApplicationMgr    SUCCESS 
 ====================================================================================================================================
-                                                   Welcome to ApplicationMgr (GaudiCoreSvc v999r999)
-                                          running on karma on Sun Apr 24 21:38:57 2016
+                                                   Welcome to ApplicationMgr (GaudiCoreSvc v4r1)
+                                          running on lxplus003.cern.ch on Fri Sep 23 19:50:23 2016
 ====================================================================================================================================
 ApplicationMgr       INFO Application Manager Configured successfully
 EventLoopMgr      WARNING Unable to locate service "EventSelector" 
@@ -10,24 +10,9 @@ HistogramPersis...WARNING Histograms saving not required.
 ApplicationMgr       INFO Application Manager Initialized successfully
 ApplicationMgr Ready
 *** VarHandles_test starts ***
-ClassIDSvc           INFO Initializing ClassIDSvc - package version CLIDComps-00-00-00
-ClassIDSvc           INFO  getRegistryEntries: read 156 CLIDRegistry entries for module ALL
-Now we expect to see an error message:
-----Error Message Starts--->>
-StoreGateSvc         INFO Initializing StoreGateSvc - package version StoreGate-00-00-00
-ProxyProviderSvc     INFO Initializing ProxyProviderSvc - package version SGComps-00-00-00
-VarHandle(Store...WARNING ../src/VarHandleBase.cxx:658 (void*SG::VarHandleBase::typeless_dataPointer_impl(bool)): could not get proxy for key foo
-<<---Error Message Ends-------
-ClassIDSvc           INFO  getRegistryEntries: read 835 CLIDRegistry entries for module ALL
+ClassIDSvc           INFO  getRegistryEntries: read 215 CLIDRegistry entries for module ALL
+ClassIDSvc           INFO  getRegistryEntries: read 869 CLIDRegistry entries for module ALL
 *** VarHandles_test static handle test OK ***
-Now we expect to see an error message:
-----Error Message Starts--->>
-VarHandle(Store...WARNING ../src/VarHandleBase.cxx:658 (void*SG::VarHandleBase::typeless_dataPointer_impl(bool)): could not get proxy for key noReset
-<<---Error Message Ends-------
-Now we expect to see an error message:
-----Error Message Starts--->>
-VarHandle(Store...WARNING ../src/VarHandleBase.cxx:658 (void*SG::VarHandleBase::typeless_dataPointer_impl(bool)): could not get proxy for key noReset
-<<---Error Message Ends-------
 *** VarHandles_test resetable test OK ***
 *** VarHandles_test ref count test OK ***
 *** VarHandles_test OK ***
diff --git a/Control/StoreGate/share/WriteHandle_test.ref b/Control/StoreGate/share/WriteHandle_test.ref
index e6238ae9a17..08cc7a8a135 100644
--- a/Control/StoreGate/share/WriteHandle_test.ref
+++ b/Control/StoreGate/share/WriteHandle_test.ref
@@ -1,29 +1,24 @@
 
 
 Initializing Gaudi ApplicationMgr using job opts ../share/VarHandleBase_test.txt
-JobOptionsSvc        INFO # =======> /home/sss/nobackup/atlas/build/../tests/../share/VarHandleBase_test.txt
+JobOptionsSvc        INFO # =======> /home/sss/atlas/dvtest/build/../tests/../share/VarHandleBase_test.txt
 JobOptionsSvc        INFO # (1,1): ApplicationMgr.ExtSvc = ["StoreGateSvc/OtherStore"]
 JobOptionsSvc        INFO # (2,1): OtherStore.ProxyProviderSvc = ""
 JobOptionsSvc        INFO Job options successfully read in from ../share/VarHandleBase_test.txt
 ApplicationMgr    SUCCESS 
 ====================================================================================================================================
-                                                   Welcome to ApplicationMgr (GaudiCoreSvc v999r999)
-                                          running on karma on Sun Apr 24 21:56:59 2016
+                                                   Welcome to ApplicationMgr (GaudiCoreSvc v27r1p99)
+                                          running on karma on Thu Dec  1 12:34:13 2016
 ====================================================================================================================================
 ApplicationMgr       INFO Application Manager Configured successfully
-OtherStore           INFO Initializing OtherStore - package version StoreGate-00-00-00
-ClassIDSvc           INFO Initializing ClassIDSvc - package version CLIDComps-00-00-00
-ClassIDSvc           INFO  getRegistryEntries: read 159 CLIDRegistry entries for module ALL
-ClassIDSvc          ERROR uncheckedSetTypePackageForID: PyAnalysisExamples-00-00-00 can not set CLID <86839352> for type name MyObj: Known CLID for this name <293847295> It was set by StoreGate-00-00-00
+ClassIDSvc           INFO  getRegistryEntries: read 218 CLIDRegistry entries for module ALL
 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
-StoreGateSvc         INFO Initializing StoreGateSvc - package version StoreGate-00-00-00
-ProxyProviderSvc     INFO Initializing ProxyProviderSvc - package version SGComps-00-00-00
-ClassIDSvc           INFO  getRegistryEntries: read 833 CLIDRegistry entries for module ALL
+ClassIDSvc           INFO  getRegistryEntries: read 867 CLIDRegistry entries for module ALL
 ServiceManager      FATAL No Service factory for BazSvc available.
 VarHandleKey.Se...  ERROR ServiceLocatorHelper::service: can not locate service BazSvc
                     FATAL FILE:LINE (FUNC): code 0: m_storeHandle.retrieve()
@@ -47,3 +42,8 @@ VarHandleKey.Se...  ERROR ServiceLocatorHelper::service: can not locate service
 ServiceManager      FATAL No Service factory for BazSvc available.
 VarHandleKey.Se...  ERROR ServiceLocatorHelper::service: can not locate service BazSvc
                     FATAL FILE:LINE (FUNC): code 0: m_storeHandle.retrieve()
+test9
+VarHandle(FooSv...  ERROR FILE:LINE (FUNC): code 0: recordObject failed
+test10
+VarHandle(FooSv...  ERROR FILE:LINE (FUNC): code 0: recordObject failed
+                    ERROR FILE:LINE (FUNC): code 0: recordObject of aux store failed
diff --git a/Control/StoreGate/src/ActiveStoreSvc.cxx b/Control/StoreGate/src/ActiveStoreSvc.cxx
index 2d854a7ec4c..d94b42271a1 100644
--- a/Control/StoreGate/src/ActiveStoreSvc.cxx
+++ b/Control/StoreGate/src/ActiveStoreSvc.cxx
@@ -4,6 +4,7 @@
 
 #include "StoreGate/ActiveStoreSvc.h"
 #include "StoreGate/StoreGateSvc.h"
+#include "AthenaKernel/errorcheck.h"
 
 #include "GaudiKernel/MsgStream.h"
 #include "GaudiKernel/ISvcLocator.h"
@@ -29,22 +30,14 @@ ActiveStoreSvc::~ActiveStoreSvc()
 /// Service initialisation
 StatusCode ActiveStoreSvc::initialize()    {
 
-  // Initialize service:
-  if(!(Service::initialize()).isSuccess()) return StatusCode::FAILURE;
+  CHECK( Service::initialize() );
 
-  MsgStream log( msgSvc(), name() );
-  log << MSG::INFO << "Initializing " << name() 
+  msg() << MSG::VERBOSE << "Initializing " << name() 
       << " - package version " << PACKAGE_VERSION << endmsg ;
 
   const bool CREATEIF(true);
-  StatusCode sc = service(m_storeName, p_activeStore, CREATEIF);
-  if ( !sc.isSuccess() ) {
-    log << MSG::ERROR << "Could not locate default store" << endmsg;
-    return sc;
-  }
-
+  CHECK(  service(m_storeName, p_activeStore, CREATEIF) );
   return StatusCode::SUCCESS;
-
 }
 
 ///set the active store pointer: used by the event loop mgrs
diff --git a/Control/StoreGate/src/SGHiveMgrSvc.cxx b/Control/StoreGate/src/SGHiveMgrSvc.cxx
index 94b731f7ba6..2a0079e6775 100644
--- a/Control/StoreGate/src/SGHiveMgrSvc.cxx
+++ b/Control/StoreGate/src/SGHiveMgrSvc.cxx
@@ -2,7 +2,6 @@
   Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
 */
 
-#ifdef ATHENAHIVE
 #include "AthenaKernel/CloneService.h"
 #include "AthenaKernel/errorcheck.h"
 #include "StoreGate/StoreGateSvc.h"
@@ -29,11 +28,17 @@ HiveMgrSvc::HiveMgrSvc(const std::string& name,
  * @param  slot     [IN]     Slot number (event slot)   *
  * @return Status code indicating failure or success.
  */
+#ifdef ATHENAHIVE
 StatusCode HiveMgrSvc::selectStore(size_t slotIndex) {
   s_current = &m_slots[slotIndex];
   StoreGateSvc::setSlot(s_current);
   return StatusCode::SUCCESS;
 }
+#else
+StatusCode HiveMgrSvc::selectStore(size_t /*slotIndex*/) {
+  return StatusCode::SUCCESS;
+}
+#endif
 
 /** Clear a given 'slot'.
  *
@@ -43,7 +48,11 @@ StatusCode HiveMgrSvc::selectStore(size_t slotIndex) {
 StatusCode HiveMgrSvc::clearStore(size_t slotIndex) {
   StatusCode rc(StatusCode::FAILURE);
   if (slotIndex < m_nSlots) {
+#ifdef ATHENAHIVE
     rc=m_slots[slotIndex].pEvtStore->clearStore();
+#else
+    rc = m_hiveStore->clearStore();
+#endif
     if (rc.isSuccess()) debug() << "cleared store " << slotIndex << endmsg;
   }    
   if (!rc.isSuccess()) error() << "could not clear store " << slotIndex << endmsg;
@@ -61,13 +70,17 @@ StatusCode HiveMgrSvc::setNumberOfStores(size_t slots) {
     fatal() << "Too late to change the number of slots!" << endmsg;
     return StatusCode::FAILURE;
   } else {
+#ifdef ATHENAHIVE
     m_slots.resize(slots);
     m_nSlots = slots;
+#else
+    if (slots != 1) return StatusCode::FAILURE;
+#endif
     return StatusCode::SUCCESS;
   }
 }
 
-size_t HiveMgrSvc::getNumberOfStores() {
+size_t HiveMgrSvc::getNumberOfStores() const {
   return m_nSlots;
 }
 
@@ -79,6 +92,7 @@ size_t HiveMgrSvc::getNumberOfStores() {
  * @param     slot     [OUT]    Returned slot or slot number
  * @return Slot number (npos to indicate an error).
  */
+#ifdef ATHENAHIVE
 size_t HiveMgrSvc::allocateStore( int evtNumber ) {
   for (size_t index=0; index<m_nSlots; ++index) {
     if( m_slots[index].eventNumber == evtNumber) {
@@ -94,6 +108,12 @@ size_t HiveMgrSvc::allocateStore( int evtNumber ) {
   error() << "No slots available for event number " << evtNumber << endmsg;
   return std::string::npos;
 }
+#else
+size_t HiveMgrSvc::allocateStore( int /*evtNumber*/ )
+{
+  return 0;
+}
+#endif
   
 /** Free a store slot
  *
@@ -102,7 +122,9 @@ size_t HiveMgrSvc::allocateStore( int evtNumber ) {
  */
 StatusCode HiveMgrSvc::freeStore( size_t slotIndex ) {
   if (slotIndex < m_nSlots) {
+#ifdef ATHENAHIVE
     m_slots[slotIndex].eventNumber = -1;
+#endif
     debug() << "Freed slot " << slotIndex << endmsg;
     return StatusCode::SUCCESS;
   } else {
@@ -117,12 +139,18 @@ StatusCode HiveMgrSvc::freeStore( size_t slotIndex ) {
  * @param     evtNumber     [IN]     Event number
  * @return    slot number (npos to indicate an error).
  */
+#ifdef ATHENAHIVE
 size_t HiveMgrSvc::getPartitionNumber(int evtNumber) const {
   for (size_t index=0; index<m_nSlots; ++index) {
     if( m_slots[index].eventNumber == evtNumber) return index;
   }
   return std::string::npos;
 }
+#else
+size_t HiveMgrSvc::getPartitionNumber(int /*evtNumber*/) const {
+  return 0;
+}
+#endif
 
 
 StatusCode HiveMgrSvc::getNewDataObjects(DataObjIDColl& products) {
@@ -134,8 +162,8 @@ bool HiveMgrSvc::newDataObjectsPresent() {
 } 
 
 StatusCode HiveMgrSvc::initialize() {
-  info() << "Initializing " << name() 
-         << " - package version " << PACKAGE_VERSION << endmsg ;
+  verbose() << "Initializing " << name() 
+            << " - package version " << PACKAGE_VERSION << endmsg ;
 
   if ( !(Service::initialize().isSuccess()) )  {
     fatal() << "Unable to initialize base class" << endmsg;
@@ -147,6 +175,7 @@ StatusCode HiveMgrSvc::initialize() {
     return StatusCode::FAILURE;
   }
 
+#ifdef ATHENAHIVE
   //use hiveStore default impl store as prototype
   Service* child(0);
   SGImplSvc* pSG(0);
@@ -165,18 +194,26 @@ StatusCode HiveMgrSvc::initialize() {
       return StatusCode::FAILURE;
     }
   }
+#else
+  if (m_nSlots != 1) {
+    fatal() << "Bad value of NSlots for serial build: " << m_nSlots << endmsg;
+    return StatusCode::FAILURE;
+  }
+#endif
   return selectStore(0);
 }
 StatusCode HiveMgrSvc::finalize() {
   info() <<  "Finalizing " << name() 
          << " - package version " << PACKAGE_VERSION << endmsg ;
 
+#ifdef ATHENAHIVE
   for (SG::HiveEventSlot& s : m_slots) {
     // The impl services are not set to active, so ServiceMananger
     // won't finalize them.
     CHECK( s.pEvtStore->finalize() );
     s.pEvtStore->release();
   }
+#endif
 
   return StatusCode::SUCCESS;
 }
@@ -192,6 +229,3 @@ StatusCode HiveMgrSvc::queryInterface( const InterfaceID& riid, void** ppvInterf
   addRef();
   return StatusCode::SUCCESS;
 }
-#endif /*ATHENAHIVE*/
-
-
diff --git a/Control/StoreGate/src/SGHiveMgrSvc.h b/Control/StoreGate/src/SGHiveMgrSvc.h
index ae4c5797260..108335039e3 100644
--- a/Control/StoreGate/src/SGHiveMgrSvc.h
+++ b/Control/StoreGate/src/SGHiveMgrSvc.h
@@ -2,7 +2,6 @@
   Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
 */
 
-#ifdef ATHENAHIVE
 #ifndef STOREGATE_HIVEMGRSVC_H
 #define STOREGATE_HIVEMGRSVC_H
 
@@ -27,7 +26,7 @@ template <class TYPE> class SvcFactory;
  *  @brief A service that manages a multi-event collection of StoreGateSvc
  *  It implements the IHiveWhiteBoard interface
  *
- *  $Id: SGHiveMgrSvc.h 694789 2015-09-14 19:36:04Z leggett $
+ *  $Id: SGHiveMgrSvc.h 783783 2016-11-11 18:25:23Z leggett $
  **/
 namespace SG {
 class HiveMgrSvc : virtual public IHiveWhiteBoard, public Service {
@@ -61,7 +60,7 @@ public:
    * 
    * @return Number of event stores allocated in the whiteboard
    */
-  virtual size_t getNumberOfStores();
+  virtual size_t getNumberOfStores() const;
  
   /** Get the latest new data objects registred in store.
    *
@@ -109,7 +108,9 @@ public:
 private:
   ServiceHandle<StoreGateSvc> m_hiveStore;
   size_t m_nSlots; //property settable also by setNumberOfStores
+#ifdef ATHENAHIVE
   std::vector<SG::HiveEventSlot> m_slots;
+#endif
   //maybe  ServiceHandle<ActiveStoreSvc> m_active;
 
 protected:
@@ -121,7 +122,3 @@ protected:
 };
 } //namespace SG
 #endif // STOREGATE_HIVEMGRSVC_H
-#endif // ATHENAHIVE
-
-
-
diff --git a/Control/StoreGate/src/SGImplSvc.cxx b/Control/StoreGate/src/SGImplSvc.cxx
index 64711843a3a..d700d216fd9 100644
--- a/Control/StoreGate/src/SGImplSvc.cxx
+++ b/Control/StoreGate/src/SGImplSvc.cxx
@@ -10,6 +10,7 @@
 #include <iostream>
 #include <functional>
 #include <string>
+#include <unordered_map>
 
 #include <sstream>
 #include <iomanip>
@@ -35,7 +36,6 @@
 #include "SGTools/StringPool.h"
 #include "SGTools/TransientAddress.h"
 #include "SGTools/SGVersionedKey.h"
-#include "CxxUtils/unordered_map.h"
 #include "StoreGate/ActiveStoreSvc.h"
 #include "StoreGate/StoreClearedIncident.h"
 #include "AthAllocators/ArenaHeader.h"
@@ -126,7 +126,7 @@ namespace SG {
       sgkey_t target;
       off_t index_offset;
     };
-    typedef SG::unordered_map<sgkey_t, remap_t, keyhash> remap_map_t;
+    typedef std::unordered_map<sgkey_t, remap_t, keyhash> remap_map_t;
     remap_map_t m_remaps;
   };
 
@@ -181,13 +181,10 @@ SGImplSvc::~SGImplSvc()  {
 /// Service initialisation
 StatusCode SGImplSvc::initialize()    {
 
-  msg() << MSG::VERBOSE << "Initializing " << name() 
-        << " - package version " << PACKAGE_VERSION << endmsg ;
+  msg() << MSG::VERBOSE <<  "Initializing " << name() 
+        << " - package version " << PACKAGE_VERSION << endmsg;
 
-  if(!(Service::initialize()).isSuccess()) {
-    msg() << MSG::ERROR << "Could not initialize base Service !!" << endmsg;
-    return StatusCode::FAILURE;
-  }
+  CHECK( Service::initialize() );
 
   if (!m_pStore)
     m_pStore = new DataStore (*this);
@@ -785,11 +782,11 @@ SG::DataProxy* SGImplSvc::recordObject (SG::DataObjectSharedPtr<DataObject> obj,
 
   if (returnExisting) {
     SG::DataProxy* proxy = this->proxy (obj->clID(), key);
-    if (proxy) return proxy;
+    if (proxy && proxy->isValid()) return proxy;
 
     // Look for the same object recorded under a different key.
     proxy = this->proxy (raw_ptr);
-    if (proxy) {
+    if (proxy && proxy->isValid()) {
       // Make an alias.
       if (addAlias (key, proxy).isFailure()) {
         CLID clid = proxy->clID();
@@ -812,7 +809,7 @@ SG::DataProxy* SGImplSvc::recordObject (SG::DataObjectSharedPtr<DataObject> obj,
   SG::DataProxy* proxy = nullptr;
   if (this->typeless_record (obj.get(), key, raw_ptr,
                              allowMods, resetOnly, noHist, tinfo,
-                             &proxy).isFailure())
+                             &proxy, true).isFailure())
     {
       return nullptr;
     }
@@ -924,7 +921,7 @@ SGImplSvc::typeless_record( DataObject* obj, const std::string& key,
                             bool allowMods, bool resetOnly, bool noHist)
 {
   return typeless_record (obj, key, raw_ptr, allowMods, resetOnly, noHist, 0,
-                          nullptr);
+                          nullptr, false);
 }
 
 
@@ -935,7 +932,7 @@ SGImplSvc::typeless_record( DataObject* obj, const std::string& key,
                             const std::type_info* tinfo)
 {
   return typeless_record (obj, key, raw_ptr, allowMods, resetOnly, noHist,tinfo,
-                          nullptr);
+                          nullptr, false);
 }
 
 
@@ -944,11 +941,11 @@ SGImplSvc::typeless_record( DataObject* obj, const std::string& key,
                             const void* const raw_ptr,
                             bool allowMods, bool resetOnly, bool noHist,
                             const std::type_info* tinfo,
-                            SG::DataProxy** proxy_ret)
+                            SG::DataProxy** proxy_ret,
+                            bool noOverwrite)
 {
-  const bool NOOVERWRITE(false);
   SG::DataProxy* proxy =
-    record_impl( obj, key, raw_ptr, allowMods, resetOnly, NOOVERWRITE, tinfo);
+    record_impl( obj, key, raw_ptr, allowMods, resetOnly, noOverwrite, tinfo);
   if ( proxy == nullptr )
     return StatusCode::FAILURE;
   if (proxy_ret)
@@ -1072,6 +1069,7 @@ SGImplSvc::record_impl( DataObject* pDObj, const std::string& key,
           << endmsg;
     if (pDObj != dp->object()) {
       DataBucketBase* pDBB(dynamic_cast<DataBucketBase*>(pDObj));
+      if (!pDBB) std::abort();
       pDBB->relinquish(); //don't own the data obj already recorded!
     }
     this->recycle(pDObj);
diff --git a/Control/StoreGate/src/StoreGateSvc.cxx b/Control/StoreGate/src/StoreGateSvc.cxx
index a4129e76099..f48646fcb50 100644
--- a/Control/StoreGate/src/StoreGateSvc.cxx
+++ b/Control/StoreGate/src/StoreGateSvc.cxx
@@ -3,11 +3,6 @@
 */
 
 #ifdef ATHENAHIVE
-#include "GaudiKernel/Bootstrap.h"
-#include "GaudiKernel/MsgStream.h"
-#include "GaudiKernel/IAppMgrUI.h"
-#include "GaudiKernel/IJobOptionsSvc.h"
-#include "GaudiKernel/ISvcLocator.h"
 #include "GaudiKernel/IIncidentSvc.h"
 #include "AthenaKernel/errorcheck.h"
 #include "StoreGate/StoreClearedIncident.h"
@@ -17,6 +12,9 @@
 #include "StoreGate/ActiveStoreSvc.h"
 #include "StoreGate/tools/SGImplSvc.h"
 
+#include "GaudiKernel/IAppMgrUI.h"
+#include "GaudiKernel/IJobOptionsSvc.h"
+
 using namespace SG;
 using namespace std;
 
@@ -144,11 +142,10 @@ StoreGateSvc::keys(const CLID& id, bool allKeys){
 StatusCode StoreGateSvc::initialize()    {
 
   // Initialize service:
-  if(!(Service::initialize()).isSuccess()) return StatusCode::FAILURE;
+  CHECK( Service::initialize() );
 
-  MsgStream log( messageService(), name() );
-  log << MSG::VERBOSE << "Initializing " << name() 
-      << " - package version " << PACKAGE_VERSION << endmsg ;
+  msg() << MSG::VERBOSE << "Initializing " << name() 
+        << " - package version " << PACKAGE_VERSION << endmsg;
 
   // lifted from AlwaysPrivateToolSvc (see Wim comment about lack of global jo svc accessor
   // retrieve the job options svc (TODO: the code below relies heavily on
@@ -232,10 +229,9 @@ IIOVSvc* StoreGateSvc::getIIOVSvc() {
 
 StatusCode
 StoreGateSvc::finalize() {
-  if(!(Service::finalize()).isSuccess()) return StatusCode::FAILURE;
-  MsgStream log( messageService(), name() );
-  log << MSG::VERBOSE << "Finalizing " << name() 
-      << " - package version " << PACKAGE_VERSION << endmsg ;
+  CHECK( Service::finalize() );
+  msg() << MSG::VERBOSE << "Finalizing " << name() 
+        << " - package version " << PACKAGE_VERSION << endmsg;
   if (m_defaultStore) {
     // m_defaultStore is not active, so ServiceManager won't finalize it!
     CHECK( m_defaultStore->finalize());
diff --git a/Control/StoreGate/src/VarHandleBase.cxx b/Control/StoreGate/src/VarHandleBase.cxx
index 0e981f3a5ed..934de062f39 100644
--- a/Control/StoreGate/src/VarHandleBase.cxx
+++ b/Control/StoreGate/src/VarHandleBase.cxx
@@ -319,7 +319,7 @@ namespace SG {
   {
     const DataProxy* proxy = m_proxy;
     if (!proxy) {
-      IProxyDict* store = m_store;
+      const IProxyDict* store = m_store;
       if (!store)
         store = this->storeHandle().get();
       if (store)
@@ -399,7 +399,7 @@ namespace SG {
   {
     if (!m_store) {
       CHECK( VarHandleKey::initialize() );
-      m_store = this->storeHandle().get();
+      m_store = &*(this->storeHandle());
     }
 
     if (!m_store)
@@ -592,7 +592,7 @@ namespace SG {
   {
     if (!m_store) {
       CHECK (VarHandleKey::initialize());
-      m_store = this->storeHandle().get();
+      m_store = &*(this->storeHandle());
     }
 
     if (this->name() == "") {
@@ -633,6 +633,61 @@ namespace SG {
   }
 
 
+  /**
+   * @brief Helper to record an object in the event store.
+   *        Unlike record, put does not change the handle and does not
+   *        cache the pointer in the handle.
+   * @param The wrapped data object (DataBucket) to record.
+   * @param dataPtr Pointer to the transient object itself.
+   * @param allowMods If false, record the object as const.
+   * @param returnExisting Allow an existing object.
+   * @param[out] store The store being used.
+   *
+   * Returns the object placed in the store, or nullptr if there
+   * was an error.
+   * If there was already an object in the store with the given key,
+   * then return null, unless @c returnExisting is true, in which case
+   * return success.  In either case, @c dobj is destroyed.
+   */
+  const void*
+  VarHandleBase::put_impl (std::unique_ptr<DataObject> dobj,
+                           void* dataPtr,
+                           bool allowMods,
+                           bool returnExisting,
+                           IProxyDict* & store) const
+  {
+    store = m_store;
+    if (!store) {
+      ServiceHandle<IProxyDict> h = storeHandle();
+      if (h.retrieve().isFailure())
+        return nullptr;
+      store = &*h;
+    }
+
+    if (this->name() == "") {
+      REPORT_ERROR (StatusCode::FAILURE) << "Attempt to record an object with a null key";
+      return nullptr;
+    }
+
+    SG::DataObjectSharedPtr<DataObject> sptr (dobj.release());
+    unsigned int initRefCount = sptr->refCount();
+    SG::DataProxy* new_proxy = 
+      store->recordObject (sptr, this->name(), allowMods, returnExisting);
+    if (!new_proxy) {
+      REPORT_ERROR (StatusCode::FAILURE) << "recordObject failed";
+      return nullptr;
+    }
+  
+    if (new_proxy && initRefCount == sptr->refCount() && new_proxy->isValid()) {
+      // If the reference count hasn't changed, then we've returned an existing
+      // object rather than recording a new one.  Retrieve the pointer.
+      dataPtr = typeless_dataPointer_fromProxy (new_proxy, true);
+    }
+
+    return dataPtr;
+  }
+
+
   /**
    * @brief Retrieve an object from StoreGate.
    * @param quiet If true, suppress failure messages.
@@ -670,54 +725,7 @@ namespace SG {
       } //setstate
     } //m_proxy
 
-    if (!m_proxy || !m_proxy->isValid()) {
-      // invalid proxy
-      if (!quiet) {
-        REPORT_MESSAGE(MSG::WARNING)
-          << "Proxy "
-          << " [" << (m_proxy != 0 ? m_proxy->clID() : 0)
-          << "/" << (m_proxy != 0 
-                     ? m_proxy->name() 
-                     : std::string("<N/A>"))
-          << "] is in an invalid state";
-      } //quiet
-      return m_ptr;
-    }
-
-    DataObject* dobj = m_proxy->accessData();
-    if (!dobj) {
-      // invalid dobj
-      if (!quiet) {
-        REPORT_MESSAGE(MSG::WARNING)
-          << "this proxy " << MSG::hex << m_proxy
-          << MSG::dec << " has a NULL data object ptr";
-      }
-      return m_ptr;
-    }
-
-    const CLID clid = this->clid();
-    m_ptr = SG::Storable_cast(dobj, clid, m_proxy);
-    if (m_ptr) {
-      return m_ptr;
-    }
-
-    // if m_ptr is null, probably the clid we gave wasn't the clid
-    // the object was stored with, nor it inherits from it.
-    // before giving up, let's check its transient CLIDs
-    DataBucketBase *dbb = 0;
-    if (m_proxy->transientAddress()->transientID(clid) &&
-        0 != (dbb = dynamic_cast<DataBucketBase*>(dobj))) {
-      // it is a symlink after all.
-      // Let's hard cast (and keep our fingers Xed)
-      m_ptr = static_cast<void*>(dbb->object());
-    } else {
-      if (!quiet) {
-        REPORT_MESSAGE(MSG::WARNING)
-          << "Request for an invalid object; requested CLID = " 
-          << clid 
-          << ", proxy primary ID is " << m_proxy->clID();
-      }
-    } // try symlink -- endif
+    m_ptr = typeless_dataPointer_fromProxy (m_proxy, quiet);
     return m_ptr;
   }
 
@@ -783,7 +791,69 @@ namespace SG {
   }
 
 
-  //*************************************************************************
+  /**
+   * @brief Retrieve a pointer from a proxy.
+   * @param proxy The proxy object.
+   * @param quiet If true, suppress failure messages.
+   *
+   * Warning --- doesn't enforce const rules; the caller must do that.
+   */
+  void* 
+  VarHandleBase::typeless_dataPointer_fromProxy (SG::DataProxy* proxy,
+                                                 bool quiet) const
+  {
+    if (!proxy || !proxy->isValid()) {
+      // invalid proxy
+      if (!quiet) {
+        REPORT_MESSAGE(MSG::WARNING)
+          << "Proxy "
+          << " [" << (proxy != 0 ? proxy->clID() : 0)
+          << "/" << (proxy != 0 
+                     ? proxy->name() 
+                     : std::string("<N/A>"))
+          << "] is in an invalid state";
+      } //quiet
+      return nullptr;
+    }
+
+    DataObject* dobj = proxy->accessData();
+    if (!dobj) {
+      // invalid dobj
+      if (!quiet) {
+        REPORT_MESSAGE(MSG::WARNING)
+          << "this proxy " << MSG::hex << proxy
+          << MSG::dec << " has a NULL data object ptr";
+      }
+      return nullptr;
+    }
+
+    const CLID clid = this->clid();
+    void* ptr = SG::Storable_cast(dobj, clid, proxy);
+    if (ptr)
+      return ptr;
+
+    // If ptr is null, probably the clid we gave wasn't the clid
+    // the object was stored with, nor it inherits from it.
+    // before giving up, let's check its transient CLIDs
+    DataBucketBase *dbb = 0;
+    if (proxy->transientAddress()->transientID(clid) &&
+        0 != (dbb = dynamic_cast<DataBucketBase*>(dobj))) {
+      // it is a symlink after all.
+      // Let's hard cast (and keep our fingers Xed)
+      ptr = static_cast<void*>(dbb->object());
+    } else {
+      if (!quiet) {
+        REPORT_MESSAGE(MSG::WARNING)
+          << "Request for an invalid object; requested CLID = " 
+          << clid 
+          << ", proxy primary ID is " << proxy->clID();
+      }
+    } // try symlink -- endif
+    return ptr;
+  }
+
+
+//*************************************************************************
   // Free functions.
   //
 
diff --git a/Control/StoreGate/src/VarHandleKey.cxx b/Control/StoreGate/src/VarHandleKey.cxx
index f9627bb3727..8ff5711a642 100644
--- a/Control/StoreGate/src/VarHandleKey.cxx
+++ b/Control/StoreGate/src/VarHandleKey.cxx
@@ -132,7 +132,7 @@ ServiceHandle<IProxyDict> VarHandleKey::storeHandle() const
 /**
  * @brief Prevent this method from being called.
  */
-void VarHandleKey::setKey(const DataObjID& /*key*/)
+void VarHandleKey::setKey(const DataObjID& /*key*/) const
 {
   throw SG::ExcForbiddenMethod ("VarHandleKey::setKey");
 }
@@ -141,7 +141,7 @@ void VarHandleKey::setKey(const DataObjID& /*key*/)
 /**
  * @brief Prevent this method from being called.
  */
-void VarHandleKey::updateKey(const std::string& /*key*/)
+void VarHandleKey::updateKey(const std::string& /*key*/) const
 {
   throw SG::ExcForbiddenMethod ("VarHandleKey::updateKey");
 }
diff --git a/Control/StoreGate/src/VarHandleKeyArrayProperty.cxx b/Control/StoreGate/src/VarHandleKeyArrayProperty.cxx
index c1996368821..f6818bab665 100644
--- a/Control/StoreGate/src/VarHandleKeyArrayProperty.cxx
+++ b/Control/StoreGate/src/VarHandleKeyArrayProperty.cxx
@@ -72,7 +72,7 @@ namespace SG {
  */
   VarHandleKeyArrayProperty::VarHandleKeyArrayProperty( const std::string& name, 
                                                         SG::VarHandleKeyArray& ref )
-    : Property( name, typeid( SG::VarHandleKeyArray ) ), 
+    : PropertyWithHandlers( name, typeid( SG::VarHandleKeyArray ) ), 
       m_pValue( &ref ) 
   {
 }
diff --git a/Control/StoreGate/src/VarHandleKeyProperty.cxx b/Control/StoreGate/src/VarHandleKeyProperty.cxx
index 2b99b88a26e..d8480608b0d 100644
--- a/Control/StoreGate/src/VarHandleKeyProperty.cxx
+++ b/Control/StoreGate/src/VarHandleKeyProperty.cxx
@@ -77,7 +77,7 @@ namespace SG {
  */
 VarHandleKeyProperty::VarHandleKeyProperty( const std::string& name, 
                                             SG::VarHandleKey& ref )
-  : Property( name, typeid( SG::VarHandleKey ) ), 
+  : PropertyWithHandlers( name, typeid( SG::VarHandleKey ) ), 
     m_pValue( &ref ) 
 {
 }
diff --git a/Control/StoreGate/src/components/StoreGateSvc_entries.cxx b/Control/StoreGate/src/components/StoreGateSvc_entries.cxx
index 3c6d7b9a9cd..9ebf1ede24d 100644
--- a/Control/StoreGate/src/components/StoreGateSvc_entries.cxx
+++ b/Control/StoreGate/src/components/StoreGateSvc_entries.cxx
@@ -9,8 +9,5 @@ DECLARE_SERVICE_FACTORY( ActiveStoreSvc )
 DECLARE_SERVICE_FACTORY( StoreGateSvc )
 DECLARE_SERVICE_FACTORY( SGImplSvc )
 DECLARE_SERVICE_FACTORY( SegMemSvc )
-
-#ifdef ATHENAHIVE
 DECLARE_NAMESPACE_SERVICE_FACTORY( SG, HiveMgrSvc )
-#endif
 
diff --git a/Control/StoreGate/test/SGtests.cxx b/Control/StoreGate/test/SGtests.cxx
index 4013bbc9380..4d4ac3d86e1 100644
--- a/Control/StoreGate/test/SGtests.cxx
+++ b/Control/StoreGate/test/SGtests.cxx
@@ -35,7 +35,6 @@
 #include "SGTools/DataStore.h"
 #include "SGTools/SGVersionedKey.h"
 #include "AthenaKernel/IProxyProviderSvc.h"
-#include "CxxUtils/make_unique.h"
 #include "GaudiKernel/IConversionSvc.h"
 #include "GaudiKernel/IOpaqueAddress.h"
 
@@ -43,9 +42,7 @@ using namespace std;
 using namespace SG;
 
 using SG::DataStore;
-#if __cplusplus > 201100
-using CxxUtils::make_unique;
-#endif
+using std::make_unique;
 
 class Base {};
 class Foo : public Base {
@@ -991,7 +988,7 @@ namespace Athena_test {
 
     {
       SG::WriteHandle<int> h ("testBoundReset", rSG.name());
-      h = CxxUtils::make_unique<int> (10);
+      h = std::make_unique<int> (10);
       assert (h.isValid());
       assert (*h.cachedPtr() == 10);
       rSG.commitNewDataObjects();
@@ -1005,7 +1002,7 @@ namespace Athena_test {
     }
 
     // Force the existing proxy to be deleted.
-    assert (rSG.overwrite (CxxUtils::make_unique<int> (20),
+    assert (rSG.overwrite (std::make_unique<int> (20),
                            "testBoundReset",
                            true));
     rSG.commitNewDataObjects();
@@ -1020,7 +1017,7 @@ namespace Athena_test {
     Foo::dtor_log.clear();
 
     SG::DataObjectSharedPtr<DataObject> obj101 =
-      SG::asStorable (CxxUtils::make_unique<Foo> (101));
+      SG::asStorable (std::make_unique<Foo> (101));
     SG::DataProxy* proxy101 = rSG.recordObject (obj101, "obj101", false, false);
     assert (proxy101->name() == "obj101");
     assert (proxy101->object() == obj101.get());
@@ -1029,7 +1026,7 @@ namespace Athena_test {
     assert (proxy101->isConst());
 
     SG::DataObjectSharedPtr<DataObject> obj102 =
-      SG::asStorable (CxxUtils::make_unique<Foo> (102));
+      SG::asStorable (std::make_unique<Foo> (102));
     SG::DataProxy* proxy102 = rSG.recordObject (obj102, "obj102", true, false);
     assert (proxy102->name() == "obj102");
     assert (proxy102->object() == obj102.get());
@@ -1040,14 +1037,14 @@ namespace Athena_test {
 
     std::cout << ">>> test duplicate record1\n";
     SG::DataObjectSharedPtr<DataObject> obj103 =
-      SG::asStorable (CxxUtils::make_unique<Foo> (103));
+      SG::asStorable (std::make_unique<Foo> (103));
     SG::DataProxy* proxy103 = rSG.recordObject (obj103, "obj101", false, false);
     assert (proxy103 == nullptr);
     assert (obj103->refCount() == 2); // Held by m_trash
     std::cout << "<<< test duplicate record1\n";
 
     SG::DataObjectSharedPtr<DataObject> obj104=
-      SG::asStorable (CxxUtils::make_unique<Foo> (104));
+      SG::asStorable (std::make_unique<Foo> (104));
     SG::DataProxy* proxy104 = rSG.recordObject (obj104, "obj101", false, true);
     assert (proxy104 == proxy101);
     assert (obj104->refCount() == 1);
@@ -1070,6 +1067,24 @@ namespace Athena_test {
     assert (obj103->refCount() == 1);
     assert (obj104->refCount() == 1);
 
+    SG::DataProxy* proxy101a= rSG.recordObject (obj101, "obj101", false, false);
+    assert (proxy101 == proxy101a);
+    assert (proxy101->name() == "obj101");
+    assert (proxy101->object() == obj101.get());
+    assert (obj101->refCount() == 2);
+    assert (proxy101->refCount() == 2);
+    assert (proxy101->isConst());
+
+    rSG.clearStore();
+
+    SG::DataProxy* proxy101b = rSG.recordObject (obj101, "obj101", false, true);
+    assert (proxy101 == proxy101b);
+    assert (proxy101->name() == "obj101");
+    assert (proxy101->object() == obj101.get());
+    assert (obj101->refCount() == 2);
+    assert (proxy101->refCount() == 2);
+    assert (proxy101->isConst());
+
     cout << "\n*** StoreGateSvcClient_test testRecordObject OK ***" << endl;
   }
 
@@ -1081,8 +1096,8 @@ namespace Athena_test {
     TestAuxStore* paux = nullptr;
     {
       SG::WriteHandle<BX> h ("testWriteAux", rSG.name());
-      auto obj = CxxUtils::make_unique<BX> (10);
-      auto objAux = CxxUtils::make_unique<TestAuxStore>();
+      auto obj = std::make_unique<BX> (10);
+      auto objAux = std::make_unique<TestAuxStore>();
       paux = objAux.get();
       assert (h.record (std::move(obj), std::move(objAux)).isSuccess());
       assert (!paux->m_locked);
diff --git a/Control/StoreGate/test/VarHandleBase_test.cxx b/Control/StoreGate/test/VarHandleBase_test.cxx
index 2ee146cd52f..88e3d804ec7 100644
--- a/Control/StoreGate/test/VarHandleBase_test.cxx
+++ b/Control/StoreGate/test/VarHandleBase_test.cxx
@@ -21,7 +21,6 @@
 #include "TestTools/initGaudi.h"
 #include "TestTools/expect_exception.h"
 #include "AthenaKernel/errorcheck.h"
-#include "CxxUtils/make_unique.h"
 #include "GaudiKernel/ThreadLocalContext.h"
 #include <cassert>
 #include <iostream>
@@ -47,6 +46,7 @@ public:
   using SG::VarHandleBase::typeless_cptr;
   using SG::VarHandleBase::typeless_ptr;
   using SG::VarHandleBase::record_impl;
+  using SG::VarHandleBase::put_impl;
   using SG::VarHandleBase::m_store;
   using SG::VarHandleBase::m_proxy;
   using SG::VarHandleBase::m_ptr;
@@ -125,9 +125,9 @@ void test2()
 {
   std::cout << "test2\n";
 
-  auto obj = CxxUtils::make_unique<MyObj>();
+  auto obj = std::make_unique<MyObj>();
   MyObj* objptr = obj.get();
-  auto taddr = CxxUtils::make_unique<SG::TransientAddress> (293847295, "foo");
+  auto taddr = std::make_unique<SG::TransientAddress> (293847295, "foo");
   SG::DataProxy* proxy = new SG::DataProxy (SG::asStorable (std::move(obj)),
                                             taddr.release());
   SGTest::TestStore testStore;
@@ -224,9 +224,9 @@ void test2()
   assert ((testStore.m_boundHandles == std::vector<IResetable*>{&h1}));
 
   // Test a !resetOnly proxy.
-  auto obj5 = CxxUtils::make_unique<MyObj>();
+  auto obj5 = std::make_unique<MyObj>();
   //MyObj* objptr5 = obj5.get();
-  auto taddr5 = CxxUtils::make_unique<SG::TransientAddress> (293847295, "foo");
+  auto taddr5 = std::make_unique<SG::TransientAddress> (293847295, "foo");
   SG::DataProxy* proxy5 = new SG::DataProxy (SG::asStorable (std::move(obj5)),
                                              taddr5.release(),
                                              false, false);
@@ -323,9 +323,9 @@ void test5()
   SGTest::TestStore testStore;
 
   TestHandle h1 (293847295, "foo", Gaudi::DataHandle::Writer, "FooSvc");
-  auto obj = CxxUtils::make_unique<MyObj>();
+  auto obj = std::make_unique<MyObj>();
   //MyObj* objptr = obj.get();
-  auto taddr = CxxUtils::make_unique<SG::TransientAddress> (293847295, "foo");
+  auto taddr = std::make_unique<SG::TransientAddress> (293847295, "foo");
   SG::DataProxy* proxy = new SG::DataProxy (SG::asStorable (std::move(obj)),
                                             taddr.release());
   assert (h1.setConst().isFailure());
@@ -353,7 +353,7 @@ void test6()
   SG::DataProxy* proxy1 = nullptr;
   assert (h1.setState(proxy1).isFailure());
 
-  auto taddr1 = CxxUtils::make_unique<SG::TransientAddress> (293847295, "foo");
+  auto taddr1 = std::make_unique<SG::TransientAddress> (293847295, "foo");
   proxy1 = new SG::DataProxy (taddr1.release(), nullptr);
   proxy1->addRef();
   proxy1->setStore (&testStore);
@@ -362,7 +362,7 @@ void test6()
   assert (proxy1->refCount() == 1);
   assert ((testStore.m_boundHandles == std::vector<IResetable*>{}));
 
-  auto obj1 = CxxUtils::make_unique<MyObj>();
+  auto obj1 = std::make_unique<MyObj>();
   proxy1->setObject (SG::asStorable (std::move(obj1)));
   assert (h1.setState(proxy1).isSuccess());
   assert (proxy1->refCount() == 2);
@@ -374,12 +374,12 @@ void test6()
   assert ((testStore.m_boundHandles == std::vector<IResetable*>{&h1}));
   assert (h1.m_proxy == proxy1);
 
-  auto taddr2 = CxxUtils::make_unique<SG::TransientAddress> (293847295, "foo");
+  auto taddr2 = std::make_unique<SG::TransientAddress> (293847295, "foo");
   SG::DataProxy* proxy2 = new SG::DataProxy (taddr2.release(), nullptr);
   proxy2->addRef();
   proxy2->setStore (&testStore);
   assert (proxy2->refCount() == 1);
-  auto obj2 = CxxUtils::make_unique<MyObj>();
+  auto obj2 = std::make_unique<MyObj>();
   proxy2->setObject (SG::asStorable (std::move(obj2)));
 
   assert (h1.setState(proxy2).isSuccess());
@@ -411,14 +411,14 @@ void test7()
   MyObj* objptr = nullptr;
 
   TestHandle h1 (293847295, "foo", Gaudi::DataHandle::Writer, "FooSvc");
-  obj = CxxUtils::make_unique<MyObj>();
+  obj = std::make_unique<MyObj>();
   objptr = obj.get();
   assert (h1.record_impl (std::unique_ptr<DataObject>(SG::asStorable(std::move(obj))),
                           objptr,
                           true, false).isFailure());
 
   assert (h1.setProxyDict (&testStore).isSuccess());
-  obj = CxxUtils::make_unique<MyObj>();
+  obj = std::make_unique<MyObj>();
   objptr = obj.get();
   assert (h1.record_impl (std::unique_ptr<DataObject>(SG::asStorable(std::move(obj))),
                           objptr,
@@ -428,7 +428,7 @@ void test7()
 
   TestHandle h2 (293847295, "foo", Gaudi::DataHandle::Writer, "FooSvc");
   assert (h2.setProxyDict (&testStore).isSuccess());
-  obj = CxxUtils::make_unique<MyObj>();
+  obj = std::make_unique<MyObj>();
   objptr = obj.get();
   assert (h2.record_impl (std::unique_ptr<DataObject>(SG::asStorable(std::move(obj))),
                           objptr,
@@ -437,7 +437,7 @@ void test7()
   assert (h2.m_ptr == nullptr);
 
 
-  obj = CxxUtils::make_unique<MyObj>();
+  obj = std::make_unique<MyObj>();
   objptr = obj.get();
   assert (h2.record_impl (std::unique_ptr<DataObject>(SG::asStorable(std::move(obj))),
                           objptr,
@@ -446,7 +446,7 @@ void test7()
   assert (h2.m_ptr == fooptr);
   assert (!h2.isConst());
 
-  obj = CxxUtils::make_unique<MyObj>();
+  obj = std::make_unique<MyObj>();
   objptr = obj.get();
   assert (h2.record_impl (std::unique_ptr<DataObject>(SG::asStorable(std::move(obj))),
                           objptr,
@@ -457,7 +457,7 @@ void test7()
 
   TestHandle h3 (293847295, "", Gaudi::DataHandle::Writer, "FooSvc");
   assert (h3.setProxyDict (&testStore).isSuccess());
-  obj = CxxUtils::make_unique<MyObj>();
+  obj = std::make_unique<MyObj>();
   objptr = obj.get();
   assert (h3.record_impl (std::unique_ptr<DataObject>(SG::asStorable(std::move(obj))),
                           objptr,
@@ -474,7 +474,7 @@ void test8()
   TestHandle h1 (293847295, "foo", Gaudi::DataHandle::Writer, "FooSvc");
   assert (h1.setProxyDict (&testStore).isSuccess());
 
-  auto obj = CxxUtils::make_unique<MyObj>();
+  auto obj = std::make_unique<MyObj>();
   assert (h1.m_ptr == nullptr);
   h1.m_ptr = obj.get();
   assert (h1.typeless_dataPointer_impl(false) == obj.get());
@@ -492,13 +492,13 @@ void test8()
 
   TestHandle h2 (293847295, "bar", Gaudi::DataHandle::Writer, "FooSvc");
   assert (h2.setProxyDict (&testStore).isSuccess());
-  obj = CxxUtils::make_unique<MyObj>();
+  obj = std::make_unique<MyObj>();
   MyObj* objptr = obj.get();
   testStore.record (obj.release(), "bar");
 
   assert (h2.typeless_dataPointer_impl(false) == objptr);
 
-  auto obj2 = CxxUtils::make_unique<MyObj2>();
+  auto obj2 = std::make_unique<MyObj2>();
   MyObj2* obj2ptr = obj2.get();
   testStore.record (obj2.release(), "fee");
 
@@ -535,6 +535,70 @@ void test9()
 }
 
 
+// put_impl
+void test10()
+{
+  std::cout << "test10\n";
+
+  SGTest::TestStore testStore;
+  IProxyDict* store = nullptr;
+
+  std::unique_ptr<MyObj> obj;
+  MyObj* objptr = nullptr;
+
+  TestHandle h1 (293847295, "foo", Gaudi::DataHandle::Writer, "FooSvc");
+  obj = std::make_unique<MyObj>();
+  objptr = obj.get();
+  assert (h1.put_impl (std::unique_ptr<DataObject>(SG::asStorable(std::move(obj))),
+                       objptr,
+                       true, false, store) == nullptr);
+  assert (store == nullptr);
+
+  assert (h1.setProxyDict (&testStore).isSuccess());
+  obj = std::make_unique<MyObj>();
+  objptr = obj.get();
+  const void* newptr =
+    h1.put_impl (std::unique_ptr<DataObject>(SG::asStorable(std::move(obj))),
+                 objptr,
+                 true, false, store);
+  assert (store == &testStore);
+  assert (newptr != nullptr);
+  MyObj* fooptr = objptr;
+  assert (newptr == fooptr);
+
+  TestHandle h2 (293847295, "foo", Gaudi::DataHandle::Writer, "FooSvc");
+  assert (h2.setProxyDict (&testStore).isSuccess());
+  obj = std::make_unique<MyObj>();
+  objptr = obj.get();
+  assert (h2.put_impl (std::unique_ptr<DataObject>(SG::asStorable(std::move(obj))),
+                       objptr,
+                       true, false, store) == nullptr);
+
+  obj = std::make_unique<MyObj>();
+  objptr = obj.get();
+  newptr = h2.put_impl (std::unique_ptr<DataObject>(SG::asStorable(std::move(obj))),
+                        objptr,
+                        true, true, store);
+  assert (newptr != nullptr);
+  assert (newptr == fooptr);
+
+  obj = std::make_unique<MyObj>();
+  objptr = obj.get();
+  newptr = h2.put_impl (std::unique_ptr<DataObject>(SG::asStorable(std::move(obj))),
+                        objptr,
+                        false, true, store);
+  assert (newptr == fooptr);
+
+  TestHandle h3 (293847295, "", Gaudi::DataHandle::Writer, "FooSvc");
+  assert (h3.setProxyDict (&testStore).isSuccess());
+  obj = std::make_unique<MyObj>();
+  objptr = obj.get();
+  assert (h3.put_impl (std::unique_ptr<DataObject>(SG::asStorable(std::move(obj))),
+                       objptr,
+                       true, false, store) == nullptr);
+}
+
+
 int main()
 {
   errorcheck::ReportMessage::hideErrorLocus();
@@ -550,6 +614,7 @@ int main()
   test7();
   test8();
   test9();
+  test10();
   return 0;
 }
 
diff --git a/Control/StoreGate/test/VarHandleKeyProperty_test.cxx b/Control/StoreGate/test/VarHandleKeyProperty_test.cxx
index 2cbe0607d5e..3a1ee3ffa14 100644
--- a/Control/StoreGate/test/VarHandleKeyProperty_test.cxx
+++ b/Control/StoreGate/test/VarHandleKeyProperty_test.cxx
@@ -16,7 +16,7 @@
 #include "StoreGate/exceptions.h"
 #include "TestTools/initGaudi.h"
 #include "TestTools/expect_exception.h"
-#include "GaudiKernel/PropertyMgr.h"
+#include "GaudiKernel/PropertyHolder.h"
 #include "GaudiKernel/IProperty.h"
 #include "GaudiKernel/IJobOptionsSvc.h"
 #include "GaudiKernel/ServiceHandle.h"
@@ -28,6 +28,15 @@
 class MyObj {};
 CLASS_DEF (MyObj, 293847295, 1)
 
+namespace
+{
+  const std::string emptyName{};
+  /// Helper to allow instantiation of PropertyHolder.
+  struct AnonymousPropertyHolder : public PropertyHolder<implements<IProperty, INamedInterface>> {
+    const std::string& name() const override { return emptyName; }
+  };
+}
+
 
 void test1()
 {
@@ -168,7 +177,7 @@ public:
   virtual bool hasProperty(const std::string& name) const override
   { return mgr.hasProperty(name); }
 
-  PropertyMgr mgr;
+  AnonymousPropertyHolder mgr;
 };
 
 
diff --git a/Control/StoreGate/test/VarHandleProperty_test.cxx b/Control/StoreGate/test/VarHandleProperty_test.cxx
index 1fbd9ffdba7..2375bbf40c3 100644
--- a/Control/StoreGate/test/VarHandleProperty_test.cxx
+++ b/Control/StoreGate/test/VarHandleProperty_test.cxx
@@ -16,7 +16,7 @@
 #include "StoreGate/exceptions.h"
 #include "TestTools/initGaudi.h"
 #include "TestTools/expect_exception.h"
-#include "GaudiKernel/PropertyMgr.h"
+#include "GaudiKernel/PropertyHolder.h"
 #include "GaudiKernel/IProperty.h"
 #include "GaudiKernel/IJobOptionsSvc.h"
 #include "GaudiKernel/ServiceHandle.h"
@@ -28,6 +28,15 @@
 class MyObj {};
 CLASS_DEF (MyObj, 293847295, 1)
 
+namespace
+{
+  const std::string emptyName{};
+  /// Helper to allow instantiation of PropertyHolder.
+  struct AnonymousPropertyHolder : public PropertyHolder<implements<IProperty, INamedInterface>> {
+    const std::string& name() const override { return emptyName; }
+  };
+}
+
 
 class PropTest
   : public IProperty
@@ -56,7 +65,7 @@ public:
   virtual bool hasProperty(const std::string& name) const override
   { return mgr.hasProperty(name); }
 
-  PropertyMgr mgr;
+  AnonymousPropertyHolder mgr;
 };
 
 
diff --git a/Control/StoreGate/test/VarHandles_test.cxx b/Control/StoreGate/test/VarHandles_test.cxx
index c6d624867e8..775f0fc7d2d 100644
--- a/Control/StoreGate/test/VarHandles_test.cxx
+++ b/Control/StoreGate/test/VarHandles_test.cxx
@@ -11,7 +11,6 @@
 #include "SGTools/TransientAddress.h"
 #include "SGTools/DataProxy.h"
 #include "SGTools/TestStore.h"
-#include "CxxUtils/make_unique.h"
 
 #include <cassert>
 #include <iostream>
@@ -42,7 +41,7 @@ bool operator==(const MyDataObj& lhs, const MyDataObj& rhs) {
 typedef std::list<int> IntList;
 /** @file DataHandle_test.cxx  unit test for DataHandle
  * @author ATLAS Collaboration
- * $Id: VarHandles_test.cxx 757253 2016-06-23 13:01:18Z ssnyder $
+ * $Id: VarHandles_test.cxx 781577 2016-11-01 14:41:16Z ssnyder $
  ***************************************************************************/
 
 #include "SGTools/CLASS_DEF.h"
@@ -69,7 +68,7 @@ namespace Athena_test {
     assert(!emptyProxy.isSet());
     assert(!emptyProxy.isConst());
     assert(emptyProxy.cachedPtr() == nullptr);
-    SGASSERTERROR(emptyProxy.isValid());
+    assert(!emptyProxy.isValid());
 
     //init with a valid proxy
     DataProxy* pMyProxy(new DataProxy(StoreGateSvc::asStorable(new MyDataObj),
@@ -102,7 +101,7 @@ namespace Athena_test {
     assert(!hMy.isInitialized());
     assert(hMy.cachedPtr() == nullptr);
     hMy.setProxyDict (&SGTest::store);
-    hMy = CxxUtils::make_unique<MyDataObj>(4);
+    hMy = std::make_unique<MyDataObj>(4);
     //assert(hMy.setState(pMyProxy).isSuccess());
     assert(hMy.isInitialized());
     assert(hMy.isSet());
@@ -211,7 +210,7 @@ namespace Athena_test {
     assert(33 == hNR->i());
     hNR.reset(true);
     assert(!hNR.isInitialized());
-    SGASSERTERROR(hNR.isValid());
+    assert(!hNR.isValid());
 
     pNR = new DataProxy(StoreGateSvc::asStorable(new MyDataObj(33)),
                         new TransientAddress(CLID(8000), "noReset"),
@@ -221,7 +220,7 @@ namespace Athena_test {
     assert(33 == hNR->i());
     hNR.reset(false);
     assert(!hNR.isInitialized());
-    SGASSERTERROR(hNR.isValid());
+    assert(!hNR.isValid());
 
     //now with the RESETONLY
     DataProxy* pRO(new DataProxy(StoreGateSvc::asStorable(new MyDataObj(44)),
diff --git a/Control/StoreGate/test/WriteHandle_test.cxx b/Control/StoreGate/test/WriteHandle_test.cxx
index 5093c09ee52..f3f8e6c6518 100644
--- a/Control/StoreGate/test/WriteHandle_test.cxx
+++ b/Control/StoreGate/test/WriteHandle_test.cxx
@@ -23,7 +23,6 @@
 #include "TestTools/expect_exception.h"
 #include "AthContainersInterfaces/IConstAuxStore.h"
 #include "AthenaKernel/errorcheck.h"
-#include "CxxUtils/make_unique.h"
 #include "CxxUtils/unused.h"
 #include <cassert>
 #include <iostream>
@@ -83,8 +82,8 @@ CLASS_DEF (MyDObj, 293847297, 1)
 std::pair<std::unique_ptr<MyObj>, std::unique_ptr<MyObjAux> >
 makeWithAux (int x=0)
 {
-  auto obj = CxxUtils::make_unique<MyObj>(x);
-  auto aux = CxxUtils::make_unique<MyObjAux>(x+100);
+  auto obj = std::make_unique<MyObj>(x);
+  auto aux = std::make_unique<MyObjAux>(x+100);
   obj->setStore (aux.get());
   return std::make_pair (std::move(obj), std::move(aux));
 }
@@ -171,7 +170,7 @@ void test2()
   assert (h1.setProxyDict (&testStore).isSuccess());
   assert (h1.store() == "TestStore");
 
-  auto fooobj = CxxUtils::make_unique<MyObj>();
+  auto fooobj = std::make_unique<MyObj>();
   MyObj* fooptr = fooobj.get();
   assert (h1.record (std::move(fooobj)).isSuccess());
   assert (h1.isInitialized());
@@ -201,7 +200,7 @@ void test2()
   SG::WriteHandle<MyObj> h4 ("bar", "FooSvc");
   assert (h4.setProxyDict (&testStore).isSuccess());
 
-  auto barobj = CxxUtils::make_unique<MyObj>();
+  auto barobj = std::make_unique<MyObj>();
   MyObj* barptr = barobj.get();
   assert (h4.record (std::move(barobj)).isSuccess());
   assert (h4.isInitialized());
@@ -257,7 +256,7 @@ void test3()
   EXPECT_EXCEPTION (SG::ExcNullWriteHandle, xx = (*h1).x);
   EXPECT_EXCEPTION (SG::ExcNullWriteHandle, xx = h1->x);
 
-  auto obj = CxxUtils::make_unique<MyObj>(10);
+  auto obj = std::make_unique<MyObj>(10);
   MyObj* objptr = obj.get();
   assert (h1.record(std::move(obj)).isSuccess());
 
@@ -282,7 +281,7 @@ void test4()
   assert (!h1.isInitialized());
   assert (!h1.isValid());
 
-  assert (h1.recordNonConst (CxxUtils::make_unique<MyObj>(20)).isSuccess());
+  assert (h1.recordNonConst (std::make_unique<MyObj>(20)).isSuccess());
   assert (h1.isInitialized());
   assert (h1.isValid());
   assert (h1->x == 20);
@@ -290,7 +289,7 @@ void test4()
 
   SG::WriteHandle<MyObj> h4 ("foo4", "FooSvc");
   assert (h4.setProxyDict (&testStore).isSuccess());
-  assert (h4.record (CxxUtils::make_unique<MyObj>(23)).isSuccess());
+  assert (h4.record (std::make_unique<MyObj>(23)).isSuccess());
   assert (h4.isInitialized());
   assert (h4.isValid());
   assert (h4->x == 23);
@@ -300,12 +299,22 @@ void test4()
   MyObj::deleted.clear();
   SG::WriteHandle<MyObj> h5 ("foo1", "FooSvc");
   assert (h5.setProxyDict (&testStore).isSuccess());
-  assert (h5.record (CxxUtils::make_unique<MyObj>(25)).isFailure());
+  assert (h5.record (std::make_unique<MyObj>(25)).isFailure());
   assert (MyObj::deleted == std::vector<int>{25});
 }
 
 
 // record (with aux store)
+SG::WriteHandle<MyObj> test5a (IProxyDict& testStore, MyObjAux*& paux)
+{
+  SG::WriteHandle<MyObj> h7a ("foo7a", "FooSvc");
+  assert (h7a.setProxyDict (&testStore).isSuccess());
+  auto ptrs7a = makeWithAux(31);
+  paux = ptrs7a.second.get();
+  assert (h7a.record (std::move(ptrs7a.first), std::move(ptrs7a.second)).isSuccess());
+  assert (!paux->m_locked);
+  return h7a;
+}
 void test5()
 {
   std::cout << "test5\n";
@@ -378,6 +387,28 @@ void test5()
     assert (!paux->m_locked);
   }
   assert (paux->m_locked);
+
+  paux = nullptr;
+  {
+    SG::WriteHandle<MyObj> h7b;
+    {
+      SG::WriteHandle<MyObj> h7a = test5a (testStore, paux);
+      assert (!paux->m_locked);
+      h7b = std::move(h7a);
+    }
+    assert (!paux->m_locked);
+  }
+  assert (paux->m_locked);
+
+  // Test record() setting store pointer.
+  SG::WriteHandle<MyObj> h8 ("foo8", "FooSvc");
+  assert (h8.setProxyDict (&testStore).isSuccess());
+  auto ptrs8 = makeWithAux(30);
+  ptrs8.first->setStore (nullptr);
+  assert (h8.record (std::move(ptrs8.first), std::move(ptrs8.second)).isSuccess());
+  assert (h8.isInitialized());
+  assert (h8.isValid());
+  assert (h8->x == 30);
 }
 
 
@@ -425,7 +456,7 @@ void test7()
 
   SG::WriteHandle<MyObj> h1 ("foo1", "FooSvc");
   assert (h1.setProxyDict (&testStore).isSuccess());
-  auto obj1 = CxxUtils::make_unique<MyObj>(400);
+  auto obj1 = std::make_unique<MyObj>(400);
   MyObj* objptr = obj1.get();
   assert (h1.recordOrRetrieve (std::move(obj1)).isSuccess());
   assert (h1.isValid());
@@ -436,7 +467,7 @@ void test7()
   MyObj::deleted.clear();
   SG::WriteHandle<MyObj> h2 ("foo1", "FooSvc");
   assert (h2.setProxyDict (&testStore).isSuccess());
-  auto obj2 = CxxUtils::make_unique<MyObj>(401);
+  auto obj2 = std::make_unique<MyObj>(401);
   assert (h2.recordOrRetrieve (std::move(obj2)).isSuccess());
   assert (h2.isValid());
   assert (h2->x == 400);
@@ -448,7 +479,7 @@ void test7()
   assert (h1.setConst().isSuccess());
   SG::WriteHandle<MyObj> h3 ("foo1", "FooSvc");
   assert (h3.setProxyDict (&testStore).isSuccess());
-  auto obj3 = CxxUtils::make_unique<MyObj>(402);
+  auto obj3 = std::make_unique<MyObj>(402);
   assert (h3.recordOrRetrieve (std::move(obj3)).isFailure());
   assert (MyObj::deleted == std::vector<int>{402});
 }
@@ -498,6 +529,100 @@ void test8()
 }
 
 
+// put (unique_ptr)
+void test9()
+{
+  std::cout << "test9\n";
+  SGTest::TestStore testStore;
+
+  SG::WriteHandle<MyObj> h4 ("foo4", "FooSvc");
+  assert (h4.setProxyDict (&testStore).isSuccess());
+  const MyObj* o = h4.put (std::make_unique<MyObj>(23));
+  assert (o->x == 23);
+
+  // Record existing object --- should fail.
+  MyObj::deleted.clear();
+  SG::WriteHandle<MyObj> h5 ("foo4", "FooSvc");
+  assert (h5.setProxyDict (&testStore).isSuccess());
+  assert (h5.put (std::make_unique<MyObj>(25)) == nullptr);
+  assert (MyObj::deleted == std::vector<int>{25});
+
+  // Record existing object, requesting retrieval of existing.
+  MyObj::deleted.clear();
+  o = h5.put (std::make_unique<MyObj>(25), true);
+  assert (MyObj::deleted == std::vector<int>{25});
+  assert (o->x == 23);
+}
+
+
+// put (with aux store)
+#if 0
+SG::WriteHandle<MyObj> test5a (IProxyDict& testStore, MyObjAux*& paux)
+{
+  SG::WriteHandle<MyObj> h7a ("foo7a", "FooSvc");
+  assert (h7a.setProxyDict (&testStore).isSuccess());
+  auto ptrs7a = makeWithAux(31);
+  paux = ptrs7a.second.get();
+  assert (h7a.record (std::move(ptrs7a.first), std::move(ptrs7a.second)).isSuccess());
+  assert (!paux->m_locked);
+  return h7a;
+}
+#endif
+void test10()
+{
+  std::cout << "test10\n";
+  SGTest::TestStore testStore;
+
+  SG::WriteHandle<MyObj> h1 ("foo1", "FooSvc");
+  assert (h1.setProxyDict (&testStore).isSuccess());
+  auto ptrs1 = makeWithAux(30);
+  const MyObj* o = h1.put (std::move(ptrs1.first), std::move(ptrs1.second));
+  assert (o->x == 30);
+
+  SG::ReadHandle<MyObjAux> h1a ("foo1Aux.", "FooSvc");
+  assert (h1a.setProxyDict (&testStore).isSuccess());
+  assert (h1a.isValid());
+  assert (h1a.isInitialized());
+  assert (h1a->x == 130);
+  assert (h1a.isConst());
+  assert (o->aux->x == 130);
+
+  MyObj::deleted.clear();
+  MyObjAux::deleted.clear();
+  SG::WriteHandle<MyObj> h5 ("foo1", "FooSvc");
+  assert (h5.setProxyDict (&testStore).isSuccess());
+  auto ptrs5 = makeWithAux(34);
+  assert (h5.put (std::move(ptrs5.first), std::move(ptrs5.second)) == nullptr);
+  assert (MyObj::deleted == std::vector<int>{34});
+  assert (MyObjAux::deleted == std::vector<int>{134});
+
+  testStore.record (new MyObjAux(200), "barAux.");
+  MyObj::deleted.clear();
+  MyObjAux::deleted.clear();
+  SG::WriteHandle<MyObj> h6 ("bar", "FooSvc");
+  assert (h6.setProxyDict (&testStore).isSuccess());
+  auto ptrs6 = makeWithAux(35);
+  assert (h6.put (std::move(ptrs6.first), std::move(ptrs6.second)) == nullptr);
+  SG::ReadHandle<MyObj> h6a ("bar", "FooSvc");
+  assert (h6a.setProxyDict (&testStore).isSuccess());
+  assert (h6a->x == 35);
+  assert (h6a->aux == nullptr);
+  assert (MyObj::deleted == std::vector<int>{});
+  assert (MyObjAux::deleted == std::vector<int>{135});
+
+  // Test put() setting store pointer.
+  SG::WriteHandle<MyObj> h8 ("foo8", "FooSvc");
+  assert (h8.setProxyDict (&testStore).isSuccess());
+  auto ptrs8 = makeWithAux(30);
+  MyObjAux* auxptr = ptrs8.second.get();
+  ptrs8.first->setStore (nullptr);
+  o = h8.put (std::move(ptrs8.first), std::move(ptrs8.second));
+  assert (o != 0);
+  assert (o->x == 30);
+  assert (o->aux == auxptr);
+}
+
+
 int main()
 {
   errorcheck::ReportMessage::hideErrorLocus();
@@ -513,5 +638,7 @@ int main()
   test6();
   //test7();
   test8();
+  test9();
+  test10();
   return 0;
 }
-- 
GitLab