diff --git a/Control/AthAllocators/AthAllocators/Arena.h b/Control/AthAllocators/AthAllocators/Arena.h
new file mode 100755
index 0000000000000000000000000000000000000000..384dcab1f0950e34d40922a330a1d0bd61675a07
--- /dev/null
+++ b/Control/AthAllocators/AthAllocators/Arena.h
@@ -0,0 +1,341 @@
+// This file's extension implies that it's C, but it's really -*- C++ -*-.
+
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// $Id: Arena.h 470529 2011-11-24 23:54:22Z ssnyder $
+
+/**
+ * @file  AthAllocators/Arena.h
+ * @author scott snyder
+ * @date May 2007
+ * @brief Collection of memory allocators with a common lifetime,
+ *        plus subsystem summary.
+ *
+ * The Arena classes provide a framework for memory allocation.
+ * It supports the following general features:
+ *
+ *  - Segregated storage.  Objects of identical type are grouped together.
+ *    Memory is allocated from the system in large blocks and carved
+ *    up into the individual objects.  This allows eliminating malloc
+ *    overhead and it helps with reducing problems due to heap fragmentation.
+ *
+ *  - Objects may be `cached': the object constructor is run only when
+ *    the memory is first allocated.  If it is freed and then reallocated
+ *    by the application, the destructor/constructor calls may be eliminated.
+ *
+ *  - Memory allocations of similar lifetimes may be grouped together
+ *    in ``Arenas''.  All memory in a given Arena may be freed at once.
+ *
+ *  - We attempt to make individual object allocation and deallocation
+ *    very fast.  The code for the `common' case can be entirely inlined,
+ *    and should compile to a handful of instructions.
+ *
+ *  - We keep statistics about the amount of memory allocated
+ *    per type per Arena.
+ *
+ * First, a bit of terminology; this also summarizes the major components
+ * of the library.  This will be followed by more detailed descriptions.
+ * See also the individual class headers.
+ *
+ *   - An @em element is an individual piece of memory that the application
+ *     requests.
+ *
+ *   - A @em block is a piece of memory allocated from the system
+ *     It will usually be divided up into individual elements.
+ *
+ *   - An @em Allocator is the fundamental memory allocator, managing
+ *     storage for a single type of object.  Memory allocated from the
+ *     system associated with a single Allocator.  The Allocator
+ *     classes themselves do not depend on the types being allocated;
+ *     however, functions operating on these objects, such as constructors
+ *     and destructors, may be given to the Allocator to be called
+ *     at an appropriate time.  Multiple Allocator implementations
+ *     may be available, implementing different strategies.
+ *
+ *   - An @em Arena is a group of Allocators, which share a common lifetime.
+ *     The memory allocated by all Allocators in an Arena may be freed
+ *     in a single operation.
+ *
+ *   - An @em ArenaHeader represents a group of Arenas.  One Arena
+ *     is considered the `current' Arena; it is the one from which
+ *     memory allocations will be made.  Arenas within the group
+ *     may be made current in a stack-like manner.
+ *
+ *   - A @em Handle is the interface the application uses to allocate memory.
+ *     A Handle is templated on the type being allocated as well as on the
+ *     underlying Allocator.  A Handle does not refer to any particular
+ *     Allocator; rather, the one associated with the current Arena is the
+ *     one used.  (A new Allocator is automatically created if required.)
+ *     Multiple Handle implementations may be available, implementing
+ *     different strategies for initializing the elements.
+ *
+ * Here are some more details about these components.  For full details,
+ * see the individual class headers.
+ *
+ * An @em Allocator is the fundamental allocator for a single type.
+ * Allocator instances generally request memory from the system
+ * in big blocks and then divide it up into individual elements.
+ * The memory allocated from the system is generally not returned
+ * to the system unless explicitly requested; elements not currently
+ * in use are kept in a pool for fast allocation.  An Allocator
+ * class does not depend on the type being allocated.  Instead, the
+ * necessary information is passed to the Allocator on creation
+ * in a parameters structure.  This includes the element size,
+ * as well as three function pointers:
+ *
+ *   - The constructor function is called when an element is first
+ *     allocated from the system.
+ *   - The destructor function is called just before an element's
+ *     memory is released back to the system.
+ *   - The clear function is called after the application frees
+ *     an element.
+ *
+ * Any of these may be null, in which case the corresponding call is skipped.
+ *
+ * An Allocator has a name, which is used both to identify it in the
+ * Allocator registry when Allocators are created on demand and
+ * in memory statistics reports.
+ * An Allocator must support these operations:
+ *
+ *   - @c allocate, to allocate a new element.
+ *   - @c reset, to free all allocated elements.  The memory will generally
+ *     be retained by the Allocator to be reused again quickly.
+ *   - @c erase, to free all allocated elements, and return all
+ *     allocated memory to the system.
+ *   - @c reserve, to adjust the amount of current unused memory which
+ *     the Allocator keeps in its pool.  If the amount of memory requested
+ *     is greater than what is currently available, the new memory will
+ *     usually be allocated in a single block.  If the amount of memory
+ *     requested is less than what is currently available, free blocks
+ *     will be returned to the system, if possible.
+ *   - @c name to return the Allocator's name, and @c stats to return
+ *     the current statistics for the Allocator.
+ *
+ * There are some additional operations which an Allocator may optionally
+ * implement:
+ *
+ *   - @c free, to free an individual element.
+ *   - @c resetTo, to free all elements that were allocated after
+ *     a given element, as well as the element itself.
+ *   - An iterator, which iterates over all allocated blocks.
+ *
+ * Two @c Allocator implementations are currently available in the library:
+ *
+ *  - @c ArenaPoolAllocator: Allocates elements in a stack-like manner.
+ *    Implements the @c resetTo operation and an iterator, but does
+ *    not implement @c free.
+ *
+ *  - @c ArenaHeapAllocator: An Allocator that allows elements to be
+ *    individually freed.  Implements @c free, but not @c resetTo
+ *    nor an iterator.  This Allocator requires maintaining
+ *    a pointer with each free element.  By default, this pointer
+ *    is kept outside the element, increasing the effective size
+ *    per element.  However, if part of the element may be overwritten
+ *    while it is free, then the allocator may be configured
+ *    to have this pointer overlap part of the element.
+ *
+ * @c Allocator objects are grouped into @c Arenas.  Each @c Arena
+ * contains a vector of @c Allocator objects.  Each distinct @c Allocator
+ * type is assigned an index into this vector; these indices are
+ * globally unique.  An @c Arena is associated with a @c ArenaHeader,
+ * which maintains a notion of the `current' @c Arena; the @c ArenaHeader
+ * holds a reference to the @c Allocator vector of the current @c Arena.
+ * An @c Arena has a @c makeCurrent operation to nominate it as the
+ * current @c Arena for its @c ArenaHeader.  A helper class @c Arena::Push
+ * is provided to change the current @c Arena in a stack-like manner.
+ * An @c Arena also has operations to @c reset or @c erase all of its
+ * @c Allocators, as well as for summing statistics over them all.
+ * An @c Arena also has a name, which is used in printing statistics reports.
+ *
+ * The object that the application uses to allocate memory is provided
+ * by the @c Handle classes.  These are templated on the type being
+ * allocated as well as on the underlying @c Allocator class.
+ * A @c Handle is created by passing in the @c Arena (or @c ArenaHeader)
+ * with which it is created, as well as any optional creation
+ * parameters for the @c Allocator.  The first time a given type
+ * is seen, it is assigned an index the the @c Arena @c Allocator
+ * vector.  This index is then stored in the @c Handle.  When the
+ * @c Handle is used, this index is used to find the proper @c Allocator
+ * in the current @c Arena.  (A new @c Allocator is created automatically
+ * if needed.)  A @c Handle forwards the operations from the underlying
+ * @c Allocator.  The library provides two @c Handle implementations:
+ *
+ *  - @c ArenaHandle: When this @c Handle is used, the element
+ *    constructor/destructor are expected to be called every time
+ *    an element is allocated/freed by the application.  The @c allocate
+ *    method returns a @c void*; it is expected that this will then
+ *    be used in a placement new.  The destructor will be called
+ *    by the library when elements are freed.
+ *
+ *  - @ ArenaCachingHandle: This @c Handle allows `caching' already-constructed
+ *    objects, such that the constructor is run only when the element's
+ *    memory is first allocated from the system, and the destructor
+ *    is run only when the element's memory is released back to the system.
+ *    The @c allocate method thus returns an already-initialized @c T*.
+ *    An optional @c clear function may be called when the element
+ *    is freed by the application.
+ *
+ * An example of the basic usage might be something like this.
+ *
+ *@code
+ *    class Example { ...
+ *      SG::Arena m_arena;
+ *      SG::ArenaCachingHandle<MyObj, SG::ArenaPoolAllocator> m_handle;
+ *      ...};
+ *
+ *    Example::Example()
+ *      // Associates with the default ArenaHeader.
+ *      : m_arena ("myarena") { ...
+ *      ...}
+ *
+ *    ret Example::execute() {  ...
+ *      SG::Arena::Push push (m_arena);
+ *      MyObj* obj = m_handle.allocate();
+ *      ...}
+ *
+ *    ret Example::newEvent() { ...
+ *      m_arena.reset();
+ *      ... }
+ @endcode
+ *
+ * See also the unit tests for the Handle classes.
+ */
+
+
+#ifndef ATLALLOCATORS_ARENA_H
+#define ATLALLOCATORS_ARENA_H
+
+
+#include "AthAllocators/ArenaBase.h"
+#include "AthAllocators/ArenaHeader.h"
+#include "AthAllocators/ArenaAllocatorCreator.h"
+#include "AthAllocators/ArenaAllocatorBase.h"
+#include <cstdlib>
+#include <string>
+#include <string>
+#include <ostream>
+
+
+namespace SG {
+
+
+/**
+ * @brief Collection of memory allocators with a common lifetime,
+ *
+ * See the file-level comments for a full description.
+ */
+class Arena
+  : public SG::ArenaBase
+{
+public:
+  /**
+   * @brief Constructor.
+   * @param name The name of this @c Arena; to use in reports.
+   * @param header The header with which this @c Arena is associated.
+   *        If defaulted, the global default @c ArenaHeader will be used.
+   */
+  Arena (const std::string& name, ArenaHeader* header = 0);
+
+
+  /**
+   * @brief Destructor.
+   */
+  ~Arena();
+
+
+  /**
+   * @brief reset all contained allocators.  All elements will be freed.
+   */
+  void reset();
+
+
+  /**
+   * @brief erase all contained allocators.  All elements will be freed,
+   *        and the memory returned to the system.
+   */
+  void erase();
+
+
+  /**
+   * @brief Generate a report of the memory in use by this @c Arena.
+   * @param os The stream to which to write the report.
+   */
+  virtual void report (std::ostream& os) const;
+
+
+  /**
+   * @brief Return statistics summed over all allocators in this @c Arena.
+   */
+  const ArenaAllocatorBase::Stats& stats() const;
+
+
+  /**
+   * @brief Return the @c ArenaHeader with which this @c Arena is associated.
+   */
+  ArenaHeader* header() const;
+
+
+  /**
+   * @brief Return this @c Arena's name.
+   */
+  virtual const std::string& name() const;
+
+
+  /**
+   * @brief Make this @c Arena the current one for its @c ArenaHeader.
+   * @returns The previously current allocator vector.
+   */
+  ArenaHeader::ArenaAllocVec_t* makeCurrent();
+
+
+  /**
+   * @brief Helper class for making @c Arena instances current
+   *        in a stack-like manner.
+   */
+  class Push
+  {
+  public:
+
+    /**
+     * @brief Constructor.  Make @c a current.
+     * @param a The @c Arena to make current.
+     */
+    Push (Arena& a);
+
+
+    /**
+     * @brief Destructor.  Undoes the effect of the constructor.
+     */
+    ~Push();
+
+
+  private:
+    /// The @c ArenaHeader for the stack we're managing.
+    ArenaHeader* m_header;
+
+    /// The previously-current allocator vector.
+    ArenaHeader::ArenaAllocVec_t* m_allocs;
+  };
+
+
+private:
+  /// The @c ArenaHeader with which we're associated.
+  ArenaHeader* m_header;
+
+  /// Our allocator vector.
+  ArenaHeader::ArenaAllocVec_t m_allocs;
+
+  /// Our summed statistics block.
+  mutable ArenaAllocatorBase::Stats m_stats;
+
+  /// Our name.
+  std::string m_name;
+};
+
+
+} // namespace SG
+
+
+#endif // not ATLALLOCATORS_ARENA_H
diff --git a/Control/AthAllocators/AthAllocators/ArenaAllocatorBase.h b/Control/AthAllocators/AthAllocators/ArenaAllocatorBase.h
new file mode 100755
index 0000000000000000000000000000000000000000..60d4c21a40530a83320c86d3224c85d12933a9ad
--- /dev/null
+++ b/Control/AthAllocators/AthAllocators/ArenaAllocatorBase.h
@@ -0,0 +1,415 @@
+// This file's extension implies that it's C, but it's really -*- C++ -*-.
+
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// $Id: ArenaAllocatorBase.h 470529 2011-11-24 23:54:22Z ssnyder $
+
+/**
+ * @file  AthAllocators/ArenaAllocatorBase.h
+ * @author scott snyder
+ * @date May 2007
+ * @brief Common base class for arena allocator classes.
+ *        See Arena.h for an overview of the arena-based memory allocators.
+ */
+
+
+#ifndef ATLALLOCATORS_ARENAALLOCATORBASE_H
+#define ATLALLOCATORS_ARENAALLOCATORBASE_H
+
+
+#include <cstdlib>
+#include <new>
+#include <string>
+#include <iosfwd>
+#include "boost/type_traits.hpp"
+
+
+namespace SG {
+
+
+/**
+ * @brief Common base class for arena allocator classes.
+ *        See Arena.h for an overview of the arena-based memory allocators.
+ *
+ * This base class provides the interfaces and common behavior for
+ * arena allocator classes.  An allocator class is responsible for the
+ * actual allocation and deletion of objects.  It is expected that
+ * unallocated objects may be maintained in a pool for efficiency.
+ * In addition, it should be possible to free at once all the objects
+ * that this allocator has allocated.  See below for the details
+ * of the interface that classes deriving from this should implement.
+ *
+ * A matter of terminology.  The objects that we allocate and free are
+ * called `elements'.  As mentioned, it is expected that the memory will
+ * be allocated from the system for large groups of elements at any one
+ * time; these groups are called `blocks'.
+ *
+ * The allocator classes do not themselves depend on the type of the
+ * object being allocated.  Instead, the necessary information is included
+ * in a parameters object of class @c Params that is passed to the allocator
+ * on construction.  These parameters include:
+ *
+ *  - @c name: The name of this allocator.  This is used both in printed
+ *             reports and to identify this allocator in the registry.
+ *  - @c eltSize: The size in bytes of the individual elements
+ *             we're allocating.
+ *  - @c minSize: The minimum size that this Allocator allows for
+ *             an element.
+ *  - @c nblock: A hint for the number of elements to allocate in a single
+ *             block.  This is only a hint; the allocator may allocate
+ *             a different number if that would be more efficient.
+ *  - @c linkOffset: Some allocators may require keeping a pointer along
+ *             with the element.  This gives the offset (in bytes)
+ *             from the start of the element where that pointer
+ *             lives.  In some cases, it may be safe to save space
+ *             by allowing this pointer to overlap part of the element.
+ *             Calling code is responsible for setting this up correctly.
+ *  - @c constructor, @c destructor: It may be more efficient to call the
+ *             element's constructor and destructor not each time the element
+ *             is allocated and freed, but instead just when the element's
+ *             block is allocated from or freed to the system.  We thus
+ *             cache a free pool of already-initialized objects.  These
+ *             parameters are to support this case.  These are pointers
+ *             to functions with the signature void (*)(char*).  The
+ *             @c constructor function is called when an element is first
+ *             allocated from the system, and the @c destructor function
+ *             is called when the element is finally released to the system.
+ *             Either may be 0 to skip the call.
+ *  - @c clear: In addition to the constructor and destructor, it may be
+ *             necessary to reset the element state after the application
+ *             releases it.  If @c clear is not-null, this function will
+ *             be called when an application frees an element.
+ *  - @c canReclear: If true (the default), then it is safe to call @c clear
+ *             more than once on a given element after it has been released.
+ *  - @c mustClear: If true, then @c clear must be called before calling
+ *             @c destructor.  Otherwise (the default), @c destructor
+ *             may be called directly without calling @c clear.
+ *
+ * The allocator class should maintain statistics for the memory it has
+ * allocated.  These are grouped in the @c Stats structure.  It should
+ * report the amount of space in use, the amount of free space (allocated
+ * from the system but not allocated by the application), and the total
+ * space allocated from the system, broken down into blocks, elements,
+ * and bytes.  The derived allocator class may of course extend
+ * the provided statistics.
+ *
+ * The interface provided by derived allocator classes should consist
+ * of at least the following:
+ *
+ *  - A constructor from a @c Params structure.
+ *
+ *  - Implementations of the virtual methods @c reset, @c erase, @c reserve,
+ *    @c name, @c stats.  See documentation below.
+ *
+ *  - An implementation of the method
+ *@code
+ *      pointer allocate();
+ @endcode
+ *    This should be non-virtual, and may be inlined.  It should return
+ *    a pointer to an new element.  If @c constructor was provided,
+ *    then it should have been called on the element.
+ *
+ *  - Optionally, an implementation of the non-virtual method
+ *@code
+ *      void free (pointer);
+ @endcode
+ *     to free a single element.  @c clear will be called on the element
+ *     if it was provided.
+ *
+ *  - Optionally, an implementation of the non-virtual method
+ *@code
+ *      void resetTo (pointer);
+ @endcode
+ *     @c pointer should be a pointer to an element that was allocated
+ *     from this allocator.  That element and all elements that were
+ *     allocated after it will be freed.
+ *
+ *  - Optionally, @c iterator and @c const_iterator types and the
+ *    corresponding const and non-const @c begin and @c end methods.
+ *    These iterators should range over all allocated elements.
+ *    The @c value_type should be @c pointer, and they should be at least
+ *    forward iterators.
+ */
+class ArenaAllocatorBase
+{
+public:
+  /// Type for pointers to elements.
+  typedef char* pointer;
+
+  /// And a const version of the pointer.
+  typedef const char* const_pointer;
+
+  /// Type of functions for @c constructor, etc.
+  typedef void func_t (pointer);
+
+
+  /**
+   * @brief Allocator parameters.  See above for more details.
+   */
+  struct Params
+  {
+    /// The name of this allocator.
+    std::string name;
+
+    /// The size in bytes of the individual elements we're allocating.
+    size_t eltSize;
+
+    /// The minimum size that this Allocator allows for an element.
+    size_t minSize;
+
+    /// The number of elements we should allocate in a single block
+    /// (hint only).
+    size_t nblock;
+
+    /// Offset from the start of a free element to a pointer to be used
+    /// by the allocator.  Only used if the allocator requires it.
+    size_t linkOffset;
+
+    /// Constructor function for elements.
+
+    func_t* constructor;
+    /// Destructor function for elements.
+    func_t* destructor;
+
+    /// Clear function for elements.
+    func_t* clear;
+
+    /// If true, @c clear can be called more than once on a given element.
+    bool canReclear;
+
+    /// If true, the @c clear call cannot be skipped before @c destructor.
+    bool mustClear;
+  };
+
+
+  /**
+   * @brief Statistics for an allocator.  See above for more details.
+   */
+  struct Stats {
+    /// A single statistic.
+    struct Stat {
+      /// Default constructor.
+      Stat();
+      /// Reset to zero.
+      void clear();
+      /// Accumulate.
+      Stat& operator+= (const Stat& other);
+
+      /// Number of items currently allocated by the application.
+      size_t inuse;
+      /// Number of items currently not allocated by the application
+      /// but cached by the allocator.
+      size_t free;
+      /// Total number of items held by the allocator.
+      size_t total;
+    };
+    /// Reset to zero.
+    void clear();
+    /// Accumulate.
+    Stats& operator+= (const Stats& other);
+    /// Print report header.
+    static void header (std::ostream& os);
+
+    /// Counts of blocks.
+    Stat blocks;
+    /// Counts of elements.
+    Stat elts;
+    /// Counts of bytes.
+    Stat bytes;
+  };
+
+
+  /**
+   * @brief Destructor.
+   */
+  virtual ~ArenaAllocatorBase() {}
+
+
+  /**
+   * @brief Free all allocated elements.
+   *
+   * All elements allocated are returned to the free state.
+   * @c clear should be called on them if it was provided.
+   * The elements may continue to be cached internally, without
+   * returning to the system.
+   */
+  virtual void reset() = 0;
+
+
+  /**
+   * @brief Free all allocated elements and release memory back to the system.
+   *
+   * All elements allocated are freed, and all allocated blocks of memory
+   * are released back to the system.
+   * @c destructor should be called on them if it was provided
+   * (preceded by @c clear if provided and @c mustClear was set).
+   */
+  virtual void erase() = 0;
+
+
+  /**
+   * @brief Set the total number of elements cached by the allocator.
+   * @param size The desired pool size.
+   *
+   * This allows changing the number of elements that are currently free
+   * but cached.  Any allocated elements are not affected by this call.
+   *
+   * If @c size is greater than the total number of elements currently
+   * cached, then more will be allocated.  This will preferably done
+   * with a single block, but that is not guaranteed; in addition, the
+   * allocator may allocate more elements than is requested.
+   *
+   * If @c size is smaller than the total number of elements currently
+   * cached, as many blocks as possible will be released back to the system.
+   * It may not be possible to release the number of elements requested;
+   * this should be implemented on a best-effort basis.
+   */
+  virtual void reserve (size_t size) = 0;
+
+
+  /**
+   * @brief Return the statistics block for this allocator.
+   */
+  virtual const Stats& stats() const = 0;
+
+
+  /**
+   * @brief Return the name of this allocator.
+   */
+  virtual const std::string& name() const = 0;
+
+
+  /**
+   * @brief Generate a report on the memory usage of this allocator.
+   * @param os Stream to which the report should be written.
+   */
+  virtual void report (std::ostream& os) const;
+
+
+  //=========================================================================
+  /**
+   * @brief Helper to initialize a parameters structure.
+   *
+   * This creates a @c Params class appropriately initialized for class @c T.
+   * Assumptions made:
+   *  - The constructor and destructor calls will be filled in
+   *    if non-trivial, unless no_ctor or no_dtor is set to true.
+   *    These two arguments are useful if the ctor/dtor are to
+   *    be run elsewhere, or if they are trivial and can be skipped,
+   *    but the compiler cannot detect that by itself.
+   *  - The clear call will be filled in if the optional template parameter
+   *    @c clear is true.
+   *  - No space will be reserved for an extra link.
+   *  - @c canReclear is @c true and @c mustClear is @c false.
+   *
+   * If these are not appropriate, you can derive from this class
+   * and make the appropriate changes.
+   */
+  template <typename T,
+            bool clear = false,
+            bool no_ctor = false,
+            bool no_dtor = false>
+  struct initParams
+  {
+    /**
+     * @brief Constructor.
+     * @param nblock Value to set in the parameters structure for the
+     *               number of elements to allocate per block.
+     * @param name   Value to set in the parameters structure for the
+     *               allocator name.
+     */
+    initParams (size_t nblock = 1000, const std::string& name = "");
+
+    /// Return an initialized parameters structure.
+    Params params() const;
+
+    /// Return an initialized parameters structure.
+    // Note: gcc 3.2.3 doesn't allow defining this out-of-line.
+    operator Params() const { return params(); }
+
+
+  private:
+    /// Saved value of the number of elements to allocate per block.
+    size_t m_nblock;
+
+    /// Saved value of the allocator name.
+    std::string m_name;
+  };
+
+
+  /// Make a constructor function pointer for a non-trivial constructor.
+  template <class T>
+  static func_t* makeConstructor (const boost::false_type&);
+
+  /// Make a constructor function pointer for a trivial constructor.
+  template <class T>
+  static func_t* makeConstructor (const boost::true_type&);
+
+  /// Make a constructor function pointer for a non-trivial destructor.
+  template <class T>
+  static func_t* makeDestructor (const boost::false_type&);
+
+  /// Make a constructor function pointer for a trivial destructor.
+  template <class T>
+  static func_t* makeDestructor (const boost::true_type&);
+
+  /// Make a function pointer for a @c clear function.
+  template <class T>
+  static func_t* makeClear (const boost::false_type&);
+
+  /// Make a dummy @c clear function pointer.
+  template <class T>
+  static func_t* makeClear (const boost::true_type&);
+
+private:
+  /**
+   * @brief Call @c T's default constructor on the object at @c p.
+   * @param p The object on which to run the constructor.
+   */
+  template <typename T>
+  static void construct_fcn (pointer p);
+
+
+  /**
+   * @brief Call @c T's destructor on the object at @c p.
+   * @param p The object on which to run the destructor.
+   */
+  template <typename T>
+  static void destroy_fcn (pointer p);
+
+
+  /**
+   * @brief Call @c T::clear on the object at @c p.
+   * @param p The object on which to run the @c clear.
+   */
+  template <typename T>
+  static void clear_fcn (pointer p);
+};
+
+
+/**
+ * @brief Format a statistic structure.
+ * @param os The stream to which to write.
+ * @param stat The statistic structure to write.
+ */
+std::ostream& operator<< (std::ostream& os,
+                          const ArenaAllocatorBase::Stats::Stat& stat);
+
+
+/**
+ * @brief Format a complete statistics structure.
+ * @param os The stream to which to write.
+ * @param stats The statistics structure to write.
+ */
+std::ostream& operator<< (std::ostream& os,
+                          const ArenaAllocatorBase::Stats& stats);
+
+} // namespace SG
+
+
+#include "AthAllocators/ArenaAllocatorBase.icc"
+
+
+#endif // not ATLALLOCATORS_ARENAALLOCATORBASE_H
diff --git a/Control/AthAllocators/AthAllocators/ArenaAllocatorBase.icc b/Control/AthAllocators/AthAllocators/ArenaAllocatorBase.icc
new file mode 100755
index 0000000000000000000000000000000000000000..260a0f0508db485721749320e2ebbe2a6a525afd
--- /dev/null
+++ b/Control/AthAllocators/AthAllocators/ArenaAllocatorBase.icc
@@ -0,0 +1,174 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// $Id: ArenaAllocatorBase.icc 470529 2011-11-24 23:54:22Z ssnyder $
+/**
+ * @file  AthAllocators/ArenaAllocatorBase.icc
+ * @author scott snyder
+ * @date May 2007
+ * @brief Common base class for arena allocator classes.
+ *        Inline/template implementations.
+ */
+
+
+namespace SG {
+
+
+/**
+ * @brief Make a constructor function pointer for a non-trivial constructor.
+ */
+template <class T>
+ArenaAllocatorBase::func_t*
+ArenaAllocatorBase::makeConstructor (const boost::false_type&)
+{
+  return &construct_fcn<T>;
+}
+
+
+/**
+ * @brief Make a constructor function pointer for a trivial constructor.
+ */
+template <class T>
+ArenaAllocatorBase::func_t*
+ArenaAllocatorBase::makeConstructor (const boost::true_type&)
+{
+  return 0;
+}
+
+
+/**
+ * @brief Make a constructor function pointer for a non-trivial destructor.
+ */
+template <class T>
+ArenaAllocatorBase::func_t*
+ArenaAllocatorBase::makeDestructor (const boost::false_type&)
+{
+  return &destroy_fcn<T>;
+}
+
+
+/**
+ * @brief Make a constructor function pointer for a trivial destructor.
+ */
+template <class T>
+ArenaAllocatorBase::func_t*
+ArenaAllocatorBase::makeDestructor (const boost::true_type&)
+{
+  return 0;
+}
+
+
+/**
+ * @brief Make a function pointer for a @c clear function.
+ */
+template <class T>
+ArenaAllocatorBase::func_t*
+ArenaAllocatorBase::makeClear (const boost::false_type&)
+{
+  return &clear_fcn<T>;
+}
+
+
+/**
+ * @brief Make a dummy @c clear function pointer.
+ */
+template <class T>
+ArenaAllocatorBase::func_t*
+ArenaAllocatorBase::makeClear (const boost::true_type&)
+{
+  return 0;
+}
+
+
+/**
+ * @brief Call @c T's default constructor on the object at @c p.
+ * @param p The object on which to run the constructor.
+ */
+template <typename T>
+void ArenaAllocatorBase::construct_fcn (pointer p)
+{
+  new(p) T;
+}
+
+
+/**
+ * @brief Call @c T's destructor on the object at @c p.
+ * @param p The object on which to run the destructor.
+ */
+template <typename T>
+void ArenaAllocatorBase::destroy_fcn (pointer p)
+{
+  reinterpret_cast<T*>(p)->~T();
+}
+
+
+/**
+ * @brief Call @c T::clear on the object at @c p.
+ * @param p The object on which to run the @c clear.
+ */
+template <typename T>
+void ArenaAllocatorBase::clear_fcn (pointer p)
+{
+  reinterpret_cast<T*>(p)->clear();
+}
+
+
+/**
+ * @brief Constructor.
+ * @param nblock Value to set in the parameters structure for the
+ *               number of elements to allocate per block.
+ * @param name   Value to set in the parameters structure for the
+ *               allocator name.
+ */
+template <typename T, bool clear, bool no_ctor, bool no_dtor>
+ArenaAllocatorBase::initParams<T, clear, no_ctor, no_dtor>::initParams
+   (size_t nblock /*=1000*/,
+    const std::string& name /*= ""*/)
+  : m_nblock (nblock),
+    m_name (name)
+{
+}
+
+
+/**
+ * @brief Return an initialized parameters structure.
+ */
+template <typename T, bool clear, bool no_ctor, bool no_dtor>
+ArenaAllocatorBase::Params
+ArenaAllocatorBase::initParams<T, clear, no_ctor, no_dtor>::params() const
+{
+  Params params;
+
+  // Fill in the parameters that were passed to our constructor.
+  params.nblock = m_nblock;
+  params.name = m_name;
+
+  // We're not setting up a link.
+  params.linkOffset = 0;
+  params.eltSize = sizeof (T);
+  params.minSize = 1;
+
+  // Defaults for these.
+  params.canReclear = true;
+  params.mustClear = false;
+
+  // Set up the constructor/destructor.
+  // We want the pointers to be null if they're trivial.
+  params.constructor =
+    makeConstructor<T> (::boost::integral_constant<bool, 
+                          ::boost::has_trivial_constructor<T>::value ||
+                          no_ctor>());
+  params.destructor =
+    makeDestructor<T> (::boost::integral_constant<bool, 
+                          ::boost::has_trivial_destructor<T>::value ||
+                          no_dtor>());
+
+  // Set up the clear function --- only if the flag is set!
+  params.clear = makeClear<T> (::boost::integral_constant<bool, !clear>());
+
+  return params;
+}
+
+
+} // namespace SG
diff --git a/Control/AthAllocators/AthAllocators/ArenaAllocatorCreator.h b/Control/AthAllocators/AthAllocators/ArenaAllocatorCreator.h
new file mode 100755
index 0000000000000000000000000000000000000000..789b770c0fcdea3bd4b658e2aa112df145bb222f
--- /dev/null
+++ b/Control/AthAllocators/AthAllocators/ArenaAllocatorCreator.h
@@ -0,0 +1,52 @@
+// This file's extension implies that it's C, but it's really -*- C++ -*-.
+
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// $Id: ArenaAllocatorCreator.h 470529 2011-11-24 23:54:22Z ssnyder $
+
+/**
+ * @file  AthAllocators/ArenaAllocatorCreator.h
+ * @author scott snyder
+ * @date May 2007
+ * @brief Provide an interface for creating an arena Allocator.
+ *        See Arena.h for an overview of the arena-based memory allocators.
+ */
+
+
+#ifndef ATLALLOCATORS_ARENAALLOCATORCREATOR_H
+#define ATLALLOCATORS_ARENAALLOCATORCREATOR_H
+
+
+namespace SG {
+
+
+class ArenaAllocatorBase;
+
+
+/**
+ * @brief Provide an interface for creating an arena Allocator.
+ *        See Arena.h for an overview of the arena-based memory allocators.
+ *
+ * Objects deriving from this will be stored in @c ArenaAllocatorRegistry,
+ * and are used to create allocator instances on demand.
+ */
+class ArenaAllocatorCreator
+{
+public:
+  /// Destructor.
+  virtual ~ArenaAllocatorCreator() {}
+
+
+  /**
+   * @brief Create an allocator instance.
+   */
+  virtual ArenaAllocatorBase* create() = 0;
+};
+
+
+} // namespace SG
+
+
+#endif // not ATLALLOCATORS_ARENAALLOCATORCREATOR_H
diff --git a/Control/AthAllocators/AthAllocators/ArenaAllocatorRegistry.h b/Control/AthAllocators/AthAllocators/ArenaAllocatorRegistry.h
new file mode 100755
index 0000000000000000000000000000000000000000..1d74bd6aeffaa8b8b96d9963af9b0aaa74303de5
--- /dev/null
+++ b/Control/AthAllocators/AthAllocators/ArenaAllocatorRegistry.h
@@ -0,0 +1,101 @@
+// This file's extension implies that it's C, but it's really -*- C++ -*-.
+
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// $Id: ArenaAllocatorRegistry.h 470529 2011-11-24 23:54:22Z ssnyder $
+
+/**
+ * @file  AthAllocators/ArenaAllocatorRegistry.h
+ * @author scott snyder
+ * @date May 2007
+ * @brief Registry of allocator factories.
+ *        See Arena.h for an overview of the arena-based memory allocators.
+ */
+
+#ifndef ATLALLOCATORS_ARENAALLOCATORREGISTRY_H
+#define ATLALLOCATORS_ARENAALLOCATORREGISTRY_H
+
+
+#include <cstdlib>
+#include <string>
+
+
+namespace SG {
+
+
+class ArenaAllocatorBase;
+class ArenaAllocatorCreator;
+class ArenaAllocatorRegistryImpl;
+
+
+/**
+ * @brief Registry of allocator factories.
+ *        See Arena.h for an overview of the arena-based memory allocators.
+ *
+ * Each Allocator type that the application uses is registered here;
+ * we assign to each one a small integer index.  We can then create an instance
+ * of the Allocator given the index.  Allocators have names; we also
+ * handle finding the index for an Allocator given the name.
+ */
+class ArenaAllocatorRegistry
+{
+public:
+  /**
+   * @brief Register a new allocator type.
+   * @param name The name of the allocator type.  Must not already exist.
+   * @param creator The factory object to create instances of this type.
+   *                The registry takes ownership of this pointer.
+   * @return The new integer index for this allocator type.
+   */
+  size_t registerCreator (const std::string& name,
+                          ArenaAllocatorCreator* creator);
+
+
+  /**
+   * @brief Look up the index for an allocator type name.
+   * @param name The name of the allocator type to find.
+   * @return The index corresponding to the type, or @c std::string::npos
+   *         if it hasn't yet been registered.
+   */
+  size_t lookup (const std::string& name);
+
+
+  /**
+   * @brief Create a new instance of an allocator.
+   * @param i The index of the allocator to create.
+   * @return A newly-allocated allocator instance.
+   */
+  ArenaAllocatorBase* create (size_t i);
+
+
+  /**
+   * @brief Return a pointer to the global @c ArenaAllocatorRegistry instance.
+   */
+  static ArenaAllocatorRegistry* instance();
+
+
+private:
+  /// The implementation object.
+  ArenaAllocatorRegistryImpl* m_impl;
+
+  // Disallow copying.
+  ArenaAllocatorRegistry (const ArenaAllocatorRegistry&);
+  ArenaAllocatorRegistry& operator= (const ArenaAllocatorRegistry&);
+
+  /// Constructor.  Called only by @c instance.
+  ArenaAllocatorRegistry();
+
+  /// Destructor.  Called only by @c instance.
+  ~ArenaAllocatorRegistry();
+
+  // Just to avoid compiler warnings.
+  friend class ArenaAllocatorRegistryImpl;
+};
+
+
+} // namespace SG
+
+
+#endif // not ATLALLOCATORS_ARENAALLOCATORREGISTRY_H
diff --git a/Control/AthAllocators/AthAllocators/ArenaBase.h b/Control/AthAllocators/AthAllocators/ArenaBase.h
new file mode 100755
index 0000000000000000000000000000000000000000..85f0fef5f19debdcc426351f709431d0088e9a66
--- /dev/null
+++ b/Control/AthAllocators/AthAllocators/ArenaBase.h
@@ -0,0 +1,59 @@
+// This file's extension implies that it's C, but it's really -*- C++ -*-.
+
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// $Id: ArenaBase.h 470529 2011-11-24 23:54:22Z ssnyder $
+
+/**
+ * @file  AthAllocators/ArenaBase.h
+ * @author scott snyder
+ * @date May 2007
+ * @brief Reporting interface for @c Arena, to avoid a dependency
+ *        loop with @c ArenaHeader.
+ *        See Arena.h for an overview of the arena-based memory allocators.
+ */
+
+#ifndef ATLALLOCATORS_ARENABASE_H
+#define ATLALLOCATORS_ARENABASE_H
+
+
+#include <iosfwd>
+#include <string>
+
+
+namespace SG {
+
+
+/**
+ * @brief Reporting interface for @c Arena, to avoid a dependency
+ *        loop with @c ArenaHeader.
+ *        See Arena.h for an overview of the arena-based memory allocators.
+ */
+class ArenaBase
+{
+public:
+  /// Destructor.
+  virtual ~ArenaBase() {}
+
+
+  /**
+   * @brief Generate a report of the memory in use by this @c Arena.
+   * @param os The stream to which to write the report.
+   */
+  virtual void report (std::ostream& os) const = 0;
+
+
+  /**
+   * @brief Return this @c Arena's name.
+   */
+  virtual const std::string& name() const = 0;
+};
+
+
+} // namespace SG
+
+
+#endif // not ATLALLOCATORS_ARENABASE_H
+
diff --git a/Control/AthAllocators/AthAllocators/ArenaBlock.h b/Control/AthAllocators/AthAllocators/ArenaBlock.h
new file mode 100755
index 0000000000000000000000000000000000000000..1cde06626f8253166774642edde218b361059615
--- /dev/null
+++ b/Control/AthAllocators/AthAllocators/ArenaBlock.h
@@ -0,0 +1,207 @@
+// This file's extension implies that it's C, but it's really -*- C++ -*-.
+
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// $Id: ArenaBlock.h 470529 2011-11-24 23:54:22Z ssnyder $
+
+/**
+ * @file  AthAllocators/ArenaBlock.h
+ * @author scott snyder
+ * @date May 2007
+ * @brief A large memory block that gets carved into smaller uniform elements.
+ *        See Arena.h for an overview of the arena-based memory allocators.
+ */
+
+#ifndef ATLALLOCATORS_ARENABLOCK_H
+#define ATLALLOCATORS_ARENABLOCK_H
+
+
+#include <cstdlib>
+
+
+namespace SG {
+
+
+class ArenaAllocatorBase;
+
+
+/**
+ * @brief A large memory block that gets carved into smaller uniform elements.
+ *        See Arena.h for an overview of the arena-based memory allocators.
+ *
+ * The block-based memory allocators allocate memory in large blocks
+ * and then carve them up into smaller, uniform elements.  This class
+ * is used for those large blocks.  Actually, the contents of this class
+ * is a fixed header for the block; the contents of the block itself
+ * will immediately follow the class contents.
+ *
+ * Each block keeps some housekeeping information: the element size in bytes,
+ * the number of elements in the block, and a pointer that can be used
+ * to chain blocks together in singly-linked lists.  There are a few
+ * functions available to help manage such lists.
+ */
+class ArenaBlock
+{
+public:
+  /// Type for a pointer to an element.
+  typedef char* pointer;
+
+  /// Function that operates on an element.
+  typedef void func_t (pointer);
+
+
+  /**
+   * @brief Create a new block.
+   * @param n The number of elements in the new block.
+   * @param elt_size The size in bytes of each element.
+   * @param ctor If non-null, call this function on each element
+   *             in the new block.
+   */
+  static ArenaBlock* newBlock (size_t n, size_t elt_size, func_t* ctor);
+
+
+  /**
+   * @brief Destroy a block.
+   * @param p The block to destroy.
+   * @param dtor If non-null, call this function on each element in the block.
+   */
+  static void destroy (ArenaBlock* p, func_t* dtor);
+
+
+  /**
+   * @brief Destroy all blocks in a list.
+   * @param p The first block to destroy.
+   * @param dtor If non-null, call this function on each element in the blocks.
+   *
+   * Will destroy all blocks in the linked list headed by @c p.
+   */
+  static void destroyList (ArenaBlock* p, func_t* dtor);
+
+
+  /**
+   * @brief Concatenate two lists of blocks.
+   * @param headp Pointer to pointer to the head of the list.
+   * @param tail Pointer to list to append to the end.
+   *
+   * The list @c tail is appended to the end of the list @c *headp.
+   * (@c headp is a pointer-to-pointer to be able to handle the case
+   * of an empty list.)
+   */
+  static void appendList (ArenaBlock** headp, ArenaBlock* tail);
+
+
+  /**
+   * @brief Call a function on elements in a list of blocks.
+   * @param p Pointer to the head of the list.
+   * @param func Function to apply.
+   * @param n Number of elements in the first block on which
+   *        to call the function.
+   *
+   * This will loop through the elements in all blocks on the list,
+   * calling @c func.  In the first block, we apply the function
+   * only to the first @c n elements.  In subsequent blocks, the
+   * function is applied to all elements.
+   */
+  static void applyList (ArenaBlock* p, func_t* func, size_t n);
+
+
+  /**
+   * @brief Return the number of elements in the block.
+   */
+  size_t size() const;
+
+
+  /**
+   * @brief Return the size of the elements in the block.
+   */
+  size_t eltSize() const;
+
+
+  /**
+   * @brief Return the link pointer of the block.
+   */
+  ArenaBlock* & link();
+
+
+  /**
+   * @brief Return a pointer to element @c i in the block.
+   * @param i The index of the desired element.
+   */
+  pointer index (size_t i);
+
+
+  /**
+   * @brief Return a pointer to element @c i in the block.
+   * @param i The index of the desired element.
+   * @param elt_size The block's element size.
+   *
+   * This is provided in addition to the previous function as it may
+   * allow for better inlined code in when used in a loop, if @c elt_size
+   * is saved in a local.
+   */
+  pointer index (size_t i, size_t elt_size);
+
+
+  /**
+   * @brief Return the per-block memory overhead, in bytes.
+   *
+   * This tries to include malloc overhead as well, but that may just
+   * be an estimate.  Don't rely on this to be exact.
+   */
+  static size_t overhead();
+
+
+  /// Return the global number of blocks in use.
+  static size_t nactive();
+
+
+private:
+  /// Prohibit calling these.
+  ArenaBlock (size_t n, size_t elt_size);
+  ~ArenaBlock() {}
+  ArenaBlock (const ArenaBlock&);
+  ArenaBlock& operator= (const ArenaBlock&);
+
+  // This is not really needed.  It's just to squelch the g++ warning
+  // about classes with all private ctors/dtors and no friends.
+  friend class ArenaAllocatorBase;
+
+  /// The link for the linked list.
+  ArenaBlock* m_link;
+
+  /// Number of elements in this block.
+  size_t m_size;
+
+  /// Size, in bytes, of each element in this block.
+  size_t m_elt_size;
+
+  /// The start of the block body.
+  // Try to make sure it's maximally aligned.
+  // __attribute__ ((aligned)) will do that with gcc; on other compilers,
+  // try to get at least what a double requires.  That's probably enough.
+  double m_dummy
+#ifdef __GCC__
+    __attribute__ ((aligned))
+#endif
+    ;
+
+
+  /// Global count of the number of blocks in use.
+  static size_t s_nactive;
+};
+
+
+/// The offset from the start of the block to the first element.
+static const int ArenaBlockBodyOffset =
+  sizeof (ArenaBlock) - sizeof (double);
+
+
+} // namespace SG
+
+
+#include "AthAllocators/ArenaBlock.icc"
+
+
+#endif // not ATLALLOCATORS_ARENABLOCK_H
diff --git a/Control/AthAllocators/AthAllocators/ArenaBlock.icc b/Control/AthAllocators/AthAllocators/ArenaBlock.icc
new file mode 100755
index 0000000000000000000000000000000000000000..2719a1265df09650a6eee8d69d148f8f7bf73e78
--- /dev/null
+++ b/Control/AthAllocators/AthAllocators/ArenaBlock.icc
@@ -0,0 +1,86 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// $Id: ArenaBlock.icc 470529 2011-11-24 23:54:22Z ssnyder $
+/**
+ * @file  AthAllocators/ArenaBlock.icc
+ * @author scott snyder
+ * @date May 2007
+ * @brief These are large blocks of memory that get allocated and
+ *        divided up into smaller, uniform elements.
+ *        Inline/template implementations.
+ */
+
+namespace SG {
+
+
+/**
+ * @brief Return the number of elements in the block.
+ */
+inline
+size_t ArenaBlock::size() const
+{
+  return m_size;
+}
+
+
+/**
+ * @brief Return the size of the elements in the block.
+ */
+inline
+size_t ArenaBlock::eltSize() const
+{
+  return m_elt_size;
+}
+
+
+/**
+ * @brief Return the link pointer of the block.
+ */
+inline
+ArenaBlock*& ArenaBlock::link()
+{
+  return m_link;
+}
+
+
+/**
+ * @brief Return a pointer to element @c i in the block.
+ * @param i The index of the desired element.
+ */
+inline
+ArenaBlock::pointer ArenaBlock::index (size_t i)
+{
+  return reinterpret_cast<char*>(this) +
+    ArenaBlockBodyOffset + i*eltSize();
+}
+
+
+/**
+ * @brief Return a pointer to element @c i in the block.
+ * @param i The index of the desired element.
+ * @param elt_size The block's element size.
+ *
+ * This is provided in addition to the previous function as it may
+ * allow for better inlined code in when used in a loop, if @c elt_size
+ * is saved in a local.
+ */
+inline
+ArenaBlock::pointer ArenaBlock::index (size_t i, size_t elt_size)
+{
+  return reinterpret_cast<char*>(this) + ArenaBlockBodyOffset + i*elt_size;
+}
+
+
+/**
+ * @brief Return the global number of blocks in use.
+ */
+inline
+size_t ArenaBlock::nactive()
+{
+  return s_nactive;
+}
+
+
+} // namespace SG
diff --git a/Control/AthAllocators/AthAllocators/ArenaBlockAllocatorBase.h b/Control/AthAllocators/AthAllocators/ArenaBlockAllocatorBase.h
new file mode 100755
index 0000000000000000000000000000000000000000..87155e58a6adf5c111f968f7487deb3759c33098
--- /dev/null
+++ b/Control/AthAllocators/AthAllocators/ArenaBlockAllocatorBase.h
@@ -0,0 +1,121 @@
+// This file's extension implies that it's C, but it's really -*- C++ -*-.
+
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// $Id: ArenaBlockAllocatorBase.h 470529 2011-11-24 23:54:22Z ssnyder $
+
+/**
+ * @file  AthAllocators/ArenaBlockAllocatorBase.h
+ * @author scott snyder
+ * @date May 2007
+ * @brief Common functionality for block-oriented allocators.
+ */
+
+
+#ifndef ATLALLOCATORS_ARENABLOCKALLOCATORBASE_H
+#define ATLALLOCATORS_ARENABLOCKALLOCATORBASE_H
+
+
+#include "AthAllocators/ArenaAllocatorBase.h"
+
+
+namespace SG {
+
+
+class ArenaBlock;
+
+
+/**
+ * @brief Common functionality for block-oriented allocators.
+ *        See Arena.h for an overview of the arena-based memory allocators.
+ *
+ * This class factors out some common functionality for allocators
+ * that use @c ArenaBlock.
+ */
+class ArenaBlockAllocatorBase
+  : public ArenaAllocatorBase
+{
+public:
+  /**
+   * @brief Constructor.
+   * @param params The parameters structure for this allocator.
+   *               See @c  ArenaAllocatorBase.h for the contents.
+   */
+  ArenaBlockAllocatorBase (const Params& params);
+
+
+  /**
+   * @brief Set the total number of elements cached by the allocator.
+   * @param size The desired pool size.
+   *
+   * This allows changing the number of elements that are currently free
+   * but cached.  Any allocated elements are not affected by this call.
+   *
+   * If @c size is greater than the total number of elements currently
+   * cached, then more will be allocated.  This will preferably done
+   * with a single block, but that is not guaranteed; in addition, the
+   * allocator may allocate more elements than is requested.
+   *
+   * If @c size is smaller than the total number of elements currently
+   * cached, as many blocks as possible will be released back to the system.
+   * It may not be possible to release the number of elements requested;
+   * this should be implemented on a best-effort basis.
+   */
+  virtual void reserve (size_t size);
+
+
+  /**
+   * @brief Free all allocated elements and release memory back to the system.
+   *
+   * All elements allocated are freed, and all allocated blocks of memory
+   * are released back to the system.
+   * @c destructor should be called on them if it was provided
+   * (preceded by @c clear if provided and @c mustClear was set).
+   */
+  virtual void erase();
+
+
+  /**
+   * @brief Return the statistics block for this allocator.
+   */
+  virtual const Stats& stats() const;
+
+
+  /**
+   * @brief Return the name of this allocator.
+   */
+  virtual const std::string& name() const;
+
+
+  /**
+   * @brief Return this Allocator's parameters.
+   */
+  const Params& params() const;
+
+
+protected:
+  /**
+   * @brief Return an empty block, either newly-allocated or from the
+   *        free list.  Update statistics appropriately.
+   */
+  ArenaBlock* getBlock();
+
+  /// The parameters for this allocator.
+  Params m_params;
+
+  /// The list of blocks currently in use.
+  ArenaBlock* m_blocks;
+
+  /// The list of free blocks.
+  ArenaBlock* m_freeblocks;
+
+  /// The statistics structure.
+  mutable ArenaAllocatorBase::Stats m_stats;
+};
+
+
+} // namespace SG
+
+#endif // not ATLALLOCATORS_ARENABLOCKALLOCATORBASE_H
diff --git a/Control/AthAllocators/AthAllocators/ArenaCachingHandle.h b/Control/AthAllocators/AthAllocators/ArenaCachingHandle.h
new file mode 100755
index 0000000000000000000000000000000000000000..dca22ad3ca57bf9e9e4334df641813ec23f84f4e
--- /dev/null
+++ b/Control/AthAllocators/AthAllocators/ArenaCachingHandle.h
@@ -0,0 +1,170 @@
+// This file's extension implies that it's C, but it's really -*- C++ -*-.
+
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// $Id: ArenaCachingHandle.h 470529 2011-11-24 23:54:22Z ssnyder $
+
+/**
+ * @file  AthAllocators/ArenaCachingHandle.h
+ * @author scott snyder
+ * @date May 2007
+ * @brief User interface for allocating memory that caches constructed objects.
+ *        See Arena.h for an overview of the arena-based memory allocators.
+ */
+
+
+#ifndef ATLALLOCATORS_ARENACACHINGHANDLE_H
+#define ATLALLOCATORS_ARENACACHINGHANDLE_H
+
+
+#include "AthAllocators/ArenaHandleBaseT.h"
+#include "AthAllocators/Arena.h"
+
+
+namespace SG {
+
+
+/**
+ * @brief User interface for allocating memory that caches constructed objects.
+ *        See Arena.h for an overview of the arena-based memory allocators.
+ *
+ * A @em Handle is the interface the application uses to allocate memory.
+ * It is templated on the type being allocated as well as on the
+ * underlying Allocator.  A Handle does not refer to any particular
+ * Allocator; rather, the one associated with the current Arena is the
+ * one used.  (A new Allocator is automatically created if required.)
+ *
+ * This particular Handle implementation calls the element constructor
+ * only when the memory is first allocated by the system, and calls
+ * the destructor only when the memory is returned to the system.
+ * The @c allocate method thus returns an already-initialized pointer
+ * to the element.  The element's default constructor must work
+ * for this.
+ *
+ * Note that it's possible to set up an additional @c clear method
+ * that's called when the element is freed; see @c ArenaAllocatorBase.
+ * 
+ * Here's an example of how you might create the Handle and allocate
+ * memory:
+ *
+ *@code
+ *  SG::ArenaCachingHandle<MyObj, SG::ArenaPoolAllocator> handle;
+ *  MyObj* obj = handle.allocate();
+ @endcode
+ *
+ * This associates the Handle with the default @c ArenaHeader.
+ * You can then erase all objects allocated though this Handle
+ * in the current Allocator with
+ *
+ *@code
+ *  handle.reset();
+ @endcode
+ *
+ * Note that most of the public interface for this class is inherited
+ * from the base classes.
+ */
+template <class T, class ALLOC>
+class ArenaCachingHandle
+  : public ArenaHandleBaseT<T, ALLOC>
+{
+public:
+  /// Shorthand for our base class.
+  typedef ArenaHandleBaseT<T, ALLOC> Base;
+
+  /// Pointer to an element.
+  typedef T* pointer;
+
+  /// Iterators over elements.
+  /// (May only be instantiated if the underlying Allocator supports them.)
+  typedef typename Base::iterator iterator;
+  typedef typename Base::const_iterator const_iterator;
+
+
+  /**
+   * @brief Constructor, passing in an index.  (For internal/testing use.)
+   * @param header The group of Arenas which this Handle may reference.
+   *               May be null to select the global default.
+   * @param index The index of this Handle's Allocator type.
+   */
+  ArenaCachingHandle (ArenaHeader* header, size_t index);
+
+
+  /// The class that initializes the default parameter set.
+  typedef typename ALLOC::template initParams<T, false> defaultParams_t;
+
+
+  /**
+   * @brief Constructor, passing in an optional parameter set.
+   * @param params Parameters to pass to the Allocator.
+   */
+  ArenaCachingHandle (const typename ALLOC::Params& params =
+                      defaultParams_t());
+
+
+
+  /**
+   * @brief Constructor, passing in a Header and an optional parameter set.
+   * @param header The group of Arenas which this Handle may reference.
+   *               May be null to select the global default.
+   * @param params Parameters to pass to the Allocator.
+   */
+  ArenaCachingHandle (ArenaHeader* header,
+                      const typename ALLOC::Params& params =
+                      defaultParams_t());
+
+
+  /**
+   * @brief Constructor, passing in an Arena and an optional parameter set.
+   * @param arena One Arena in the group which this Handle may reference.
+   *               May be null to select the global default.
+   * @param params Parameters to pass to the Allocator.
+   */
+  ArenaCachingHandle (Arena* arena, const typename ALLOC::Params& params =
+                      defaultParams_t());
+
+
+  /**
+   * @brief Allocate a new element.
+   *
+   * This returns an already-initialized element.
+   */
+  pointer allocate() const;
+
+
+  /**
+   * @brief Internal helper: create a new Allocator instance.
+   * @param params The parameters for the Allocator.
+   */
+  static
+  ArenaAllocatorBase* makeAllocator (const typename ALLOC::Params& params);
+
+
+  // The following methods are inherited:
+  //  const ALLOC::Params& params() const;
+  //  void reset();
+  //  void erase();
+  //  void reserve(size_t);
+  //  const ArenaAllocatorBase::Stats& stats() const;
+  //
+  // The following inherited functions may be instantiated only
+  // if the Allocator supports them:
+  //  iterator begin();
+  //  const_iterator begin() const;
+  //  iterator end();
+  //  const_iterator end() const;
+  //  void free (pointer p) const;
+  //  void resetTo (pointer p) const;
+};
+
+
+} //  namespace SG
+
+
+
+#include "AthAllocators/ArenaCachingHandle.icc"
+
+
+
+#endif // not ATLALLOCATORS_ARENACACHINGHANDLE_H
diff --git a/Control/AthAllocators/AthAllocators/ArenaCachingHandle.icc b/Control/AthAllocators/AthAllocators/ArenaCachingHandle.icc
new file mode 100755
index 0000000000000000000000000000000000000000..525b810ef1399082f80ec5f499ace85e73c92ea3
--- /dev/null
+++ b/Control/AthAllocators/AthAllocators/ArenaCachingHandle.icc
@@ -0,0 +1,105 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// $Id: ArenaCachingHandle.icc 470529 2011-11-24 23:54:22Z ssnyder $
+/**
+ * @file  AthAllocators/ArenaCachingHandle.icc
+ * @author scott snyder
+ * @date May 2007
+ * @brief User interface for allocating memory that caches constructed objects.
+ *        Inline and template implementations.
+ */
+
+
+namespace SG {
+
+
+/**
+ * @brief Constructor, passing in an index.  (For internal/testing use.)
+ * @param header The group of Arenas which this Handle may reference.
+ *               May be null to select the global default.
+ * @param index The index of this Handle's Allocator type.
+ */
+template <class T, class ALLOC>
+ArenaCachingHandle<T, ALLOC>::ArenaCachingHandle (ArenaHeader* header,
+                                                  size_t index)
+  : ArenaHandleBaseT<T, ALLOC> (header, index)
+{
+}
+
+
+/**
+ * @brief Constructor, passing in an optional parameter set.
+ * @param params Parameters to pass to the Allocator.
+ */
+template <class T, class ALLOC>
+ArenaCachingHandle<T, ALLOC>::ArenaCachingHandle
+  (const typename ALLOC::Params& params)
+    : ArenaHandleBaseT<T, ALLOC> (0, typename Base::Creator (this, params))
+{
+}
+
+
+/**
+ * @brief Constructor, passing in a Header and an optional parameter set.
+ * @param header The group of Arenas which this Handle may reference.
+ *               May be null to select the global default.
+ * @param params Parameters to pass to the Allocator.
+ */
+template <class T, class ALLOC>
+ArenaCachingHandle<T, ALLOC>::ArenaCachingHandle
+  (ArenaHeader* header,
+   const typename ALLOC::Params& params)
+    : ArenaHandleBaseT<T, ALLOC> (header,
+                                  typename Base::Creator (this, params))
+{
+}
+
+
+/**
+ * @brief Constructor, passing in an Arena and an optional parameter set.
+ * @param arena One Arena in the group which this Handle may reference.
+ *               May be null to select the global default.
+ * @param params Parameters to pass to the Allocator.
+ */
+template <class T, class ALLOC>
+ArenaCachingHandle<T, ALLOC>::ArenaCachingHandle
+  (Arena* arena,
+   const typename ALLOC::Params& params)
+    : ArenaHandleBaseT<T, ALLOC> (arena ? arena->header() : 0,
+                                  typename Base::Creator (this, params))
+{
+}
+
+
+/**
+ * @brief Allocate a new element.
+ *
+ * This returns an already-initialized element.
+ *
+ * This is on the fast path for element allocation, so keep it small
+ * and inline.
+ */
+template <class T, class ALLOC>
+inline
+typename ArenaCachingHandle<T, ALLOC>::pointer
+ArenaCachingHandle<T, ALLOC>::allocate() const
+{
+  return reinterpret_cast<pointer> (this->allocator()->allocate());
+}
+
+
+/**
+ * @brief Internal helper: create a new Allocator instance.
+ * @param params The parameters for the Allocator.
+ */
+template <class T, class ALLOC>
+ArenaAllocatorBase* ArenaCachingHandle<T, ALLOC>::makeAllocator
+ (const typename ALLOC::Params& params)
+{
+  return new ALLOC (params);
+}
+
+
+} // namespace SG
diff --git a/Control/AthAllocators/AthAllocators/ArenaHandle.h b/Control/AthAllocators/AthAllocators/ArenaHandle.h
new file mode 100755
index 0000000000000000000000000000000000000000..e13d8b1b00f1faa53c57b6b39d1dcea1fa90a483
--- /dev/null
+++ b/Control/AthAllocators/AthAllocators/ArenaHandle.h
@@ -0,0 +1,163 @@
+// This file's extension implies that it's C, but it's really -*- C++ -*-.
+
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// $Id: ArenaHandle.h 470529 2011-11-24 23:54:22Z ssnyder $
+
+/**
+ * @file  AthAllocators/ArenaHandle.h
+ * @author scott snyder
+ * @date May 2007
+ * @brief User interface for allocating memory.
+ *        See Arena.h for an overview of the arena-based memory allocators.
+ */
+
+
+#ifndef ATLALLOCATORS_ARENAHANDLE_H
+#define ATLALLOCATORS_ARENAHANDLE_H
+
+
+#include "AthAllocators/ArenaHandleBaseT.h"
+#include "AthAllocators/Arena.h"
+
+
+namespace SG {
+
+
+/**
+ * @brief User interface for allocating memory.
+ *        See Arena.h for an overview of the arena-based memory allocators.
+ *
+ * A @em Handle is the interface the application uses to allocate memory.
+ * It is templated on the type being allocated as well as on the
+ * underlying Allocator.  A Handle does not refer to any particular
+ * Allocator; rather, the one associated with the current Arena is the
+ * one used.  (A new Allocator is automatically created if required.)
+ *
+ * This particular Handle implementation does not call element constructors,
+ * and calls destructors when elements are freed.  The @c allocate
+ * method returns a @c void*, so you're expected to use it in a placement new.
+ * Here's an example of how you might create the Handle and allocate
+ * memory:
+ *
+ *@code
+ *  SG::ArenaHandle<MyObj, SG::ArenaPoolAllocator> handle;
+ *  MyObj* obj = new (handle.allocate()) (...);
+ @endcode
+ *
+ * This associates the Handle with the default @c ArenaHeader.
+ * You can then erase all objects allocated though this Handle
+ * in the current Allocator with
+ *
+ *@code
+ *  handle.reset();
+ @endcode
+ *
+ * The destructors for the allocated objects will be called at that time.
+ *
+ * Note that most of the public interface for this class is inherited
+ * from the base classes.
+ */
+template <class T, class ALLOC>
+class ArenaHandle
+  : public ArenaHandleBaseT<T, ALLOC>
+{
+public:
+  /// Shorthand for our base class.
+  typedef ArenaHandleBaseT<T, ALLOC> Base;
+
+  /// Pointer to an element.
+  typedef typename Base::pointer pointer;
+
+  /// Iterators over elements.
+  /// (May only be instantiated if the underlying Allocator supports them.)
+  typedef typename Base::iterator iterator;
+  typedef typename Base::const_iterator const_iterator;
+
+
+  /**
+   * @brief Constructor, passing in an index.  (For internal/testing use.)
+   * @param header The group of Arenas which this Handle may reference.
+   *               May be null to select the global default.
+   * @param index The index of this Handle's Allocator type.
+   */
+  ArenaHandle (ArenaHeader* header, size_t index);
+
+
+  /// The class that initializes the default parameter set.
+  typedef typename ALLOC::template initParams<T, false, true> defaultParams_t;
+
+
+  /**
+   * @brief Constructor, passing in an optional parameter set.
+   * @param params Parameters to pass to the Allocator.
+   */
+  ArenaHandle (const typename ALLOC::Params& params =
+               defaultParams_t());
+
+
+  /**
+   * @brief Constructor, passing in a Header and an optional parameter set.
+   * @param header The group of Arenas which this Handle may reference.
+   *               May be null to select the global default.
+   * @param params Parameters to pass to the Allocator.
+   */
+  ArenaHandle (ArenaHeader* header,
+               const typename ALLOC::Params& params =
+               defaultParams_t());
+
+
+  /**
+   * @brief Constructor, passing in an Arena and an optional parameter set.
+   * @param arena One Arena in the group which this Handle may reference.
+   *               May be null to select the global default.
+   * @param params Parameters to pass to the Allocator.
+   */
+  ArenaHandle (Arena* arena, const typename ALLOC::Params& params =
+               defaultParams_t());
+
+
+  /**
+   * @brief Allocate a new element.
+   *
+   * The element's constructor will not have been called; thus, the memory
+   * is returned as a @c void*.
+   */
+  void* allocate() const;
+
+
+  /**
+   * @brief Internal helper: create a new Allocator instance.
+   * @param params The parameters for the Allocator.
+   */
+  static
+  ArenaAllocatorBase* makeAllocator (const typename ALLOC::Params& params);
+
+
+  // The following methods are inherited:
+  //  const ALLOC::Params& params() const;
+  //  void reset();
+  //  void erase();
+  //  void reserve(size_t);
+  //  const ArenaAllocatorBase::Stats& stats() const;
+  //
+  // The following inherited functions may be instantiated only
+  // if the Allocator supports them:
+  //  iterator begin();
+  //  const_iterator begin() const;
+  //  iterator end();
+  //  const_iterator end() const;
+  //  void free (pointer p) const;
+  //  void resetTo (pointer p) const;
+};
+
+
+} // namespace SG
+
+
+#include "AthAllocators/ArenaHandle.icc"
+
+
+#endif // not ATLALLOCATORS_ARENAHANDLE_H
diff --git a/Control/AthAllocators/AthAllocators/ArenaHandle.icc b/Control/AthAllocators/AthAllocators/ArenaHandle.icc
new file mode 100755
index 0000000000000000000000000000000000000000..26cb4c8740127ce061ee6305513501515ecf5053
--- /dev/null
+++ b/Control/AthAllocators/AthAllocators/ArenaHandle.icc
@@ -0,0 +1,126 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// $Id: ArenaHandle.icc 470529 2011-11-24 23:54:22Z ssnyder $
+/**
+ * @file  AthAllocators/ArenaHandle.icc
+ * @author scott snyder
+ * @date May 2007
+ * @brief User interface for allocating memory.
+ *        Inline and template implementations.
+ */
+
+
+namespace SG {
+
+
+/**
+ * @brief Constructor, passing in an index.  (For internal/testing use.)
+ * @param header The group of Arenas which this Handle may reference.
+ *               May be null to select the global default.
+ * @param index The index of this Handle's Allocator type.
+ */
+template <class T, class ALLOC>
+ArenaHandle<T, ALLOC>::ArenaHandle (ArenaHeader* header,
+                                    size_t index)
+  : ArenaHandleBaseT<T, ALLOC> (header, index)
+{
+}
+
+
+/**
+ * @brief Constructor, passing in an optional parameter set.
+ * @param params Parameters to pass to the Allocator.
+ */
+template <class T, class ALLOC>
+ArenaHandle<T, ALLOC>::ArenaHandle
+  (const typename ALLOC::Params& params)
+    : ArenaHandleBaseT<T, ALLOC> (0, typename Base::Creator (this, params))
+{
+}
+
+
+/**
+ * @brief Constructor, passing in a Header and an optional parameter set.
+ * @param header The group of Arenas which this Handle may reference.
+ *               May be null to select the global default.
+ * @param params Parameters to pass to the Allocator.
+ */
+template <class T, class ALLOC>
+ArenaHandle<T, ALLOC>::ArenaHandle
+  (ArenaHeader* header,
+   const typename ALLOC::Params& params)
+    : ArenaHandleBaseT<T, ALLOC> (header,
+                                  typename Base::Creator (this, params))
+{
+}
+
+
+/**
+ * @brief Constructor, passing in an Arena and an optional parameter set.
+ * @param arena One Arena in the group which this Handle may reference.
+ *               May be null to select the global default.
+ * @param params Parameters to pass to the Allocator.
+ */
+template <class T, class ALLOC>
+ArenaHandle<T, ALLOC>::ArenaHandle
+  (Arena* arena,
+   const typename ALLOC::Params& params)
+    : ArenaHandleBaseT<T, ALLOC> (arena ? arena->header() : 0,
+                                  typename Base::Creator (this, params))
+{
+}
+
+
+/**
+ * @brief Allocate a new element.
+ *
+ * The element's constructor will not be called; thus, the memory
+ * is returned as a @c void*.
+ *
+ * This is on the fast path for element allocation, so keep it small
+ * and inline.
+ */
+template <class T, class ALLOC>
+inline
+void* ArenaHandle<T, ALLOC>::allocate() const
+{
+  return this->allocator()->allocate();
+}
+
+
+/**
+ * @brief Internal helper: create a new Allocator instance.
+ * @param params The parameters for the Allocator.
+ */
+template <class T, class ALLOC>
+ArenaAllocatorBase* ArenaHandle<T, ALLOC>::makeAllocator
+ (const typename ALLOC::Params& params)
+{
+  typename ALLOC::Params newparams = params;
+
+  // We don't call the element constructor.
+  newparams.constructor = 0;
+
+  // The destructor is called when we free an element --- not when
+  // we return it to the system.
+  newparams.clear = newparams.destructor;
+  newparams.destructor = 0;
+
+  // We can't skip running the destructor.
+  newparams.mustClear = true;
+
+  // We can't call the destructor twice.
+  newparams.canReclear = false;
+
+  // If we need a link, it can overlap the element.
+  newparams.eltSize = std::max (sizeof(T), newparams.minSize);
+  newparams.linkOffset = 0;
+
+  // Make the Allocator.
+  return new ALLOC (newparams);
+}
+
+
+} // namespace SG
diff --git a/Control/AthAllocators/AthAllocators/ArenaHandleBase.h b/Control/AthAllocators/AthAllocators/ArenaHandleBase.h
new file mode 100755
index 0000000000000000000000000000000000000000..b167373abc502f3a80a0de6a0ca707357ff5de15
--- /dev/null
+++ b/Control/AthAllocators/AthAllocators/ArenaHandleBase.h
@@ -0,0 +1,142 @@
+// This file's extension implies that it's C, but it's really -*- C++ -*-.
+
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// $Id: ArenaHandleBase.h 470529 2011-11-24 23:54:22Z ssnyder $
+
+/**
+ * @file  AthAllocators/ArenaHandleBase.h
+ * @author scott snyder
+ * @date May 2007
+ * @brief Base class for all @c Handle classes, containing parts that
+ *        do not depend on the referenced type.
+ *        See Arena.h for an overview of the arena-based memory allocators.
+ */
+
+#ifndef ATLALLOCATORS_ARENAHANDLEBASE_H
+#define ATLALLOCATORS_ARENAHANDLEBASE_H
+
+#include "AthAllocators/ArenaHeader.h"
+#include "AthAllocators/ArenaAllocatorBase.h"
+#include <cstdlib>
+
+
+namespace SG {
+
+
+/**
+ * @brief Base class for all @c Handle classes, containing parts that
+ *        do not depend on the referenced type.
+ *        See Arena.h for an overview of the arena-based memory allocators.
+ *
+ * A @em Handle is the interface the application uses to allocate memory.
+ * A Handle is templated on the type being allocated as well as on the
+ * underlying Allocator.  A Handle does not refer to any particular
+ * Allocator; rather, the one associated with the current Arena is the
+ * one used.  (A new Allocator is automatically created if required.)
+ * Multiple Handle implementations may be available, implementing
+ * different strategies for initializing the elements.
+ *
+ * This class contains the parts of the Handle interface that do not
+ * depend on the template parameters.
+ *
+ * The first time a given Handle type
+ * is seen, it is assigned an index the the @c Arena @c Allocator
+ * vector.  This index is then stored in the @c Handle.  When the
+ * @c Handle is used, this index is used to find the proper @c Allocator
+ * in the current @c Arena.  (A new @c Allocator is created automatically
+ * if needed.)  A @c Handle forwards the operations from the underlying
+ * @c Allocator.
+ */
+class ArenaHandleBase
+{
+public:
+  /**
+   * @brief Constructor.
+   * @param header The group of Arenas which this Handle may reference.
+   *               May be null to select the global default.
+   * @param index The index of this Handle's Allocator type.
+   */
+  ArenaHandleBase (ArenaHeader* header, size_t index);
+
+
+  /**
+   * @brief Free all allocated elements (of this type in the current Arena).
+   *
+   * All elements allocated in the current Arena by our associated
+   * Allocator are returned to the
+   * free state.  @c clear should be called on them if it was provided.
+   * The elements may continue to be cached internally, without
+   * returning to the system.
+   */
+  void reset();
+
+
+  /**
+   * @brief Free all allocated elements and release memory back to the system
+   *        (of this type in the current Arena).
+   *
+   * All elements allocated in the current Arena by our associated
+   * Allocator are freed, and all allocated blocks of memory
+   * are released back to the system.
+   * @c destructor should be called on them if it was provided
+   * (preceded by @c clear if provided and @c mustClear was set).
+   */
+  void erase();
+
+
+  /**
+   * @brief Set the total number of elements cached by the allocator
+   *        (in the current Arena).
+   * @param size The desired pool size.
+   *
+   * This allows changing the number of elements that are currently free
+   * but cached.  Any allocated elements are not affected by this call.
+   *
+   * If @c size is greater than the total number of elements currently
+   * cached, then more will be allocated.  This will preferably done
+   * with a single block, but that is not guaranteed; in addition, the
+   * allocator may allocate more elements than is requested.
+   *
+   * If @c size is smaller than the total number of elements currently
+   * cached, as many blocks as possible will be released back to the system.
+   * It may not be possible to release the number of elements requested;
+   * this should be implemented on a best-effort basis.
+   */
+  void reserve (size_t size);
+
+
+  /**
+   * @brief Return the statistics block for this allocator,
+   * for the current Arena.
+   */
+  const ArenaAllocatorBase::Stats& stats() const;
+
+
+protected:
+  /**
+   * @brief Return the current Allocator which we are referencing.
+   *
+   * This may cause a new Allocator to be created.
+   */
+  ArenaAllocatorBase* baseAllocator() const;
+
+
+private:
+  /// The group of Arenas which this Handle may reference.
+  ArenaHeader* m_header;
+
+  /// The index of this Handle's Allocator type.
+  size_t m_index;
+};
+
+
+} // namespace SG
+
+
+#include "AthAllocators/ArenaHandleBase.icc"
+
+
+#endif // not ATLALLOCATORS_ARENAHANDLEBASE_H
diff --git a/Control/AthAllocators/AthAllocators/ArenaHandleBase.icc b/Control/AthAllocators/AthAllocators/ArenaHandleBase.icc
new file mode 100755
index 0000000000000000000000000000000000000000..719f9f77acc41a211e25420dd0f4a8db7cc24ea1
--- /dev/null
+++ b/Control/AthAllocators/AthAllocators/ArenaHandleBase.icc
@@ -0,0 +1,33 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// $Id: ArenaHandleBase.icc 470529 2011-11-24 23:54:22Z ssnyder $
+/**
+ * @file  AthAllocators/ArenaHandleBase.icc
+ * @author scott snyder
+ * @date May 2007
+ * @brief Base class for all @c Handle classes, containing parts that
+ *        do not depend on the referenced type.
+ *        Inline implementations.
+ */
+
+
+namespace SG {
+
+
+/**
+ * @brief Return the current Allocator which we are referencing.
+ *
+ * This may cause a new Allocator to be created.
+ *
+ * This is on the fast path for allocations, so keep it small and inline.
+ */
+inline
+ArenaAllocatorBase* ArenaHandleBase::baseAllocator() const
+{
+  return m_header->allocator (m_index);
+}
+
+
+} // namespace SG
diff --git a/Control/AthAllocators/AthAllocators/ArenaHandleBaseAllocT.h b/Control/AthAllocators/AthAllocators/ArenaHandleBaseAllocT.h
new file mode 100755
index 0000000000000000000000000000000000000000..96638c0e68d20cb6d3ab90698292e42cdd292628
--- /dev/null
+++ b/Control/AthAllocators/AthAllocators/ArenaHandleBaseAllocT.h
@@ -0,0 +1,169 @@
+// This file's extension implies that it's C, but it's really -*- C++ -*-.
+
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// $Id: ArenaHandleBaseAllocT.h 470529 2011-11-24 23:54:22Z ssnyder $
+
+/**
+ * @file  AthAllocators/ArenaHandleBaseAllocT.h
+ * @author scott snyder
+ * @date May 2007
+ * @brief Base class for @c Handle classes, containing parts that
+ *        depend only on the Allocator.
+ *        See Arena.h for an overview of the arena-based memory allocators.
+ */
+
+
+#ifndef ATLALLOCATORS_ARENAHANDLEBASEALLOCT_H
+#define ATLALLOCATORS_ARENAHANDLEBASEALLOCT_H
+
+
+#include "AthAllocators/ArenaHandleBase.h"
+#include "AthAllocators/ArenaAllocatorCreator.h"
+#include "AthAllocators/ArenaAllocatorRegistry.h"
+#include "GaudiKernel/System.h"
+#include <string>
+
+
+namespace SG {
+
+
+/**
+ * @brief Base class for @c Handle classes, containing parts that
+ *        depend only on the Allocator.
+ *        See Arena.h for an overview of the arena-based memory allocators.
+ *
+ * This is the part of @c Handle that depends only on the Allocator class
+ * (on which it is templated).  This implementation here is responsible
+ * for registering the Allocator and handling its possible creation.
+ *
+ * A @c Handle holds an index which identifies the particular Allocator
+ * class which it uses; the @c ArenaAllocatorRegistry class maps between
+ * these indices and instances of @c ArenaAllocatorCreator, which are
+ * capable of creating new @c Allocator instances.
+ * An @c ArenaHandleBaseAllocT may be created by either passing
+ * in the index directly or by passing in a concrete instance
+ * of @c ArenaAllocatorCreator.  In the latter case, we will
+ * look up the index, registering the creator if needed.
+ */
+template <typename ALLOC>
+class ArenaHandleBaseAllocT
+  : public ArenaHandleBase
+{
+public:
+  /// The @c Allocator we use.
+  typedef ALLOC alloc_t;
+
+
+  /**
+   * @brief Concrete ArenaAllocatorCreator class used to create
+   *        the Allocator for this handle.
+   *
+   * There are two members of this class: @c m_makeFunc is the function
+   * which actually creates the Allocator, and @c m_params is the
+   * parameters structure to pass to the new Allocator.  These will
+   * get filled in by @c ArenaAllocatorCreatorInit, which derives
+   * from this.
+   */
+  class Creator
+    : public ArenaAllocatorCreator
+  {
+  public:
+    /// Type for @c m_makeFunc --- a function returning a new Allocator
+    /// from a parameters structure.
+    typedef
+      ArenaAllocatorBase* makeFunc_t (const typename ALLOC::Params&);
+
+
+    /**
+     * @brief Constructor.
+     * @param hand Dummy to set the template argument type.
+     * @param params Allocator parameters.
+     *
+     * This initializes the @c Creator for creating an Allocator
+     * appropriate for the Handle class @c HANDLE.  The @c HANDLE
+     * class should have a static function @c makeAllocator
+     */
+    template <class HANDLE>
+    Creator (HANDLE* hand, const typename ALLOC::Params& params);
+
+
+    /**
+     * @brief Create an allocator instance.
+     */
+    virtual ArenaAllocatorBase* create();
+
+
+    /**
+     * @brief Return the name of the Allocator we create.
+     */
+    const std::string& name() const;
+
+
+  protected:
+    /// Function that creates an Allocator given a set of parameters.
+    makeFunc_t* m_makeFunc;
+
+    /// Set of parameters to use to create our allocator.
+    typename ALLOC::Params m_params;
+  };
+
+
+  /**
+   * @brief Constructor, passing in an index.
+   * @param header The group of Arenas which this Handle may reference.
+   *               May be null to select the global default.
+   * @param index The index of this Handle's Allocator type.
+   */
+  ArenaHandleBaseAllocT (ArenaHeader* header, size_t index);
+
+
+  /**
+   * @brief Constructor, passing in a creator instance.
+   * @param header The group of Arenas which this Handle may reference.
+   *               May be null to select the global default.
+   * @param creator A @c Creator instance that will create an instance
+   *                of the Allocator we use.
+   *
+   * We'll try looking up the allocator name (from @c creator) in the
+   * registry to find the proper index.  If it's not found, we'll
+   * register @c creator.
+   */
+  ArenaHandleBaseAllocT (ArenaHeader* header, const Creator& creator);
+
+
+  /**
+   * @brief Return our Allocator's parameters.
+   */
+  const typename ALLOC::Params& params() const;
+
+
+protected:
+  /**
+   * @brief Return our current Allocator.
+   *
+   * (Note that the current Allocator may change; see @c Arena.h)
+   */
+  ALLOC* allocator() const;
+
+  
+private:
+  /**
+   * @brief Find the index for @c Creator, registering it if needed.
+   *
+   * We look up in the registry the Allocator name we get from @c creator.
+   * If not found, then we register @c creator and return the new index.
+   */
+  size_t makeIndex (const Creator& creator);
+};
+
+
+} // namespace SG
+
+
+#include "AthAllocators/ArenaHandleBaseAllocT.icc"
+
+
+#endif // not ATLALLOCATORS_ARENAHANDLEBASEALLOCT_H
diff --git a/Control/AthAllocators/AthAllocators/ArenaHandleBaseAllocT.icc b/Control/AthAllocators/AthAllocators/ArenaHandleBaseAllocT.icc
new file mode 100755
index 0000000000000000000000000000000000000000..da799e093d6ea58b1f30cd7aa5924a2fd7f512c6
--- /dev/null
+++ b/Control/AthAllocators/AthAllocators/ArenaHandleBaseAllocT.icc
@@ -0,0 +1,130 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// $Id: ArenaHandleBaseAllocT.icc 470529 2011-11-24 23:54:22Z ssnyder $
+/**
+ * @file  AthAllocators/ArenaHandleBaseAllocT.icc
+ * @author scott snyder
+ * @date May 2007
+ * @brief Base class for @c Handle classes, containing parts that
+ *        depend only on the Allocator.
+ *        Inline and template implementations.
+ */
+
+
+namespace SG {
+
+
+template <typename ALLOC>
+template <class HANDLE>
+ArenaHandleBaseAllocT<ALLOC>::Creator::Creator
+  (HANDLE*, const typename ALLOC::Params& params)
+    : m_makeFunc (HANDLE::makeAllocator),
+      m_params (params)
+{
+  if (m_params.name.empty())
+    m_params.name = System::typeinfoName (typeid (HANDLE));
+}
+
+
+/**
+ * @brief Create an allocator instance.
+ */
+template <typename ALLOC>
+ArenaAllocatorBase* ArenaHandleBaseAllocT<ALLOC>::Creator::create()
+{
+  return m_makeFunc (m_params);
+}
+
+
+/**
+ * @brief Return the name of the Allocator we create.
+ */
+template <typename ALLOC>
+const std::string&
+ArenaHandleBaseAllocT<ALLOC>::Creator::name() const
+{
+  return m_params.name;
+}
+
+
+/**
+ * @brief Constructor, passing in an index.
+ * @param header The group of Arenas which this Handle may reference.
+ *               May be null to select the global default.
+ * @param index The index of this Handle's Allocator type.
+ */
+template <typename ALLOC>
+ArenaHandleBaseAllocT<ALLOC>::ArenaHandleBaseAllocT
+  (ArenaHeader* header, size_t index)
+  : ArenaHandleBase (header, index)
+{
+}
+
+
+/**
+ * @brief Constructor, passing in a creator instance.
+ * @param header The group of Arenas which this Handle may reference.
+ *               May be null to select the global default.
+ * @param creator A @c Creator instance that will create an instance
+ *                of the Allocator we use.
+ *
+ * We'll try looking up the allocator name (from @c creator) in the
+ * registry to find the proper index.  If it's not found, we'll
+ * register @c creator.
+ */
+template <typename ALLOC>
+ArenaHandleBaseAllocT<ALLOC>::ArenaHandleBaseAllocT (ArenaHeader* header,
+                                           const Creator& creator)
+  : ArenaHandleBase (header, makeIndex (creator))
+{
+}
+
+
+/**
+ * @brief Return our Allocator's parameters.
+ */
+template <typename ALLOC>
+const typename ALLOC::Params&
+ArenaHandleBaseAllocT<ALLOC>::params() const
+{
+  return dynamic_cast<const ALLOC*>(this->baseAllocator())->params();
+}
+
+
+/**
+ * @brief Return our current Allocator.
+ *
+ * (Note that the current Allocator may change; see @c Arena.h)
+ *
+ * This is on the fast path for allocation.  It should be kept
+ * simple and inline.
+ */
+template <typename ALLOC>
+inline
+ALLOC* ArenaHandleBaseAllocT<ALLOC>::allocator() const
+{
+  return reinterpret_cast<ALLOC*> (this->baseAllocator());
+}
+
+
+/**
+ * @brief Find the index for @c Creator, registering it if needed.
+ *
+ * We look up in the registry the Allocator name we get from @c creator.
+ * If not found, then we register @c creator and return the new index.
+ */
+template <typename ALLOC>
+size_t
+ArenaHandleBaseAllocT<ALLOC>::makeIndex (const Creator& creator)
+{
+  ArenaAllocatorRegistry* reg = ArenaAllocatorRegistry::instance();
+  size_t i = reg->lookup (creator.name());
+  if (i != std::string::npos)
+    return i;
+  return reg->registerCreator (creator.name(), new Creator (creator));
+}
+
+
+} // namespace SG
diff --git a/Control/AthAllocators/AthAllocators/ArenaHandleBaseT.h b/Control/AthAllocators/AthAllocators/ArenaHandleBaseT.h
new file mode 100755
index 0000000000000000000000000000000000000000..150a36657e7e9a779e827ce0539344014f6efd12
--- /dev/null
+++ b/Control/AthAllocators/AthAllocators/ArenaHandleBaseT.h
@@ -0,0 +1,244 @@
+// This file's extension implies that it's C, but it's really -*- C++ -*-.
+
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// $Id: ArenaHandleBaseT.h 470529 2011-11-24 23:54:22Z ssnyder $
+
+/**
+ * @file  AthAllocators/ArenaHandleBaseT.h
+ * @author scott snyder
+ * @date May 2007
+ * @brief Base class for @c Handle classes, containing parts that
+ *        are independent of how the Allocator gets created.
+ *        See Arena.h for an overview of the arena-based memory allocators.
+ */
+
+
+#ifndef ATLALLOCATORS_ARENAHANDLEBASET_H
+#define ATLALLOCATORS_ARENAHANDLEBASET_H
+
+#include "AthAllocators/ArenaHandleBaseAllocT.h"
+#include "AthAllocators/ArenaHeader.h"
+#include "boost/iterator/iterator_adaptor.hpp"
+#include <cstdlib>
+
+
+namespace SG {
+
+
+/**
+ * @brief Base class for @c Handle classes, containing parts that
+ *        are independent of how the Allocator gets created.
+ *        See Arena.h for an overview of the arena-based memory allocators.
+ */
+template <class T, class ALLOC>
+class ArenaHandleBaseT
+  : public ArenaHandleBaseAllocT<ALLOC>
+{
+public:
+  /// A pointer to the element type we're allocating.
+  typedef T* pointer;
+
+  /// Shorthand for our base class.
+  typedef ArenaHandleBaseAllocT<ALLOC> Base;
+
+  /// @c AllocatorCreatorBase concrete derived class for creating
+  /// our Allocator.
+  typedef typename Base::Creator Creator;
+
+
+  /**
+   * @brief Constructor, passing in an index.
+   * @param header The group of Arenas which this Handle may reference.
+   *               May be null to select the global default.
+   * @param index The index of this Handle's Allocator type.
+   */
+  ArenaHandleBaseT (ArenaHeader* header, size_t index);
+
+
+  /**
+   * @brief Constructor, passing in a creator instance.
+   * @param header The group of Arenas which this Handle may reference.
+   *               May be null to select the global default.
+   * @param creator A @c Creator instance that will create an instance
+   *                of the Allocator we use.
+   *
+   * We'll try looking up the allocator name (from @c creator) in the
+   * registry to find the proper index.  If it's not found, we'll
+   * register @c creator.
+   */
+  ArenaHandleBaseT (ArenaHeader* header, const Creator& creator);
+
+
+  // Forward declaration.
+  class const_iterator;
+
+
+  /**
+   * @brief Non-const iterator.
+   *        It iterates over all unallocated blocks in the current
+   *        Allocator (in unspecified order).  It will be at least
+   *        a @c forward_iterator.
+   *
+   *        Note that this is only supported if the underlying Allocator
+   *        supports it.  If it does not, you will not be able
+   *        to instantiate this type.
+   *
+   *        This uses @c boost::iterator_adaptor to handle casting
+   *        the element pointers to the proper type.
+   */
+  class iterator
+    : public boost::iterator_adaptor<
+    iterator,
+    typename ALLOC::iterator,
+    T,
+    boost::forward_traversal_tag>
+  {
+  public:
+    /**
+     * @brief Constructor.
+     * @param it The base iterator.
+     */
+    iterator (const typename ALLOC::iterator& it);
+
+
+    // To allow initializing a @c const_iterator from an @c iterator.
+    friend class const_iterator;
+
+
+  private:
+    // Required by @c iterator_adaptor.
+    friend class boost::iterator_core_access;
+
+
+    /**
+     * @brief Dereference the iterator.
+     */
+    typename iterator::reference dereference() const;
+  };
+
+
+  /**
+   * @brief Const iterator.
+   *        It iterates over all unallocated blocks in the current
+   *        Allocator (in unspecified order).  It will be at least
+   *        a @c forward_iterator.
+   *
+   *        Note that this is only supported if the underlying Allocator
+   *        supports it.  If it does not, you will not be able
+   *        to instantiate this type.
+   *
+   *        This uses @c boost::iterator_adaptor to handle casting
+   *        the element pointers to the proper type.
+   */
+  class const_iterator
+    : public boost::iterator_adaptor<
+    const_iterator,
+    typename ALLOC::const_iterator,
+    T const,
+    boost::forward_traversal_tag>
+  {
+
+  public:
+    /**
+     * @brief Constructor.
+     * @param it The base iterator.
+     */
+    const_iterator (const typename ALLOC::const_iterator& it);
+
+
+    /**
+     * @brief Constructor from a non-const iterator.
+     * @param it The non-const iterator.
+     */
+    const_iterator (const iterator& it);
+
+
+  private:
+    // Required by @c iterator_adaptor.
+    friend class boost::iterator_core_access;
+
+
+    /**
+     * @brief Dereference the iterator.
+     */
+    typename const_iterator::reference dereference() const;
+  };
+
+
+  /**
+   * @brief Starting iterator.
+   *
+   * This will iterate over all allocated elements (in unspecified order).
+   * It is at least a @c forward_iterator.
+   * This may only be instantiated if the underlying Allocator
+   * supports iterators.
+   */
+  iterator begin();
+
+
+  /**
+   * @brief Starting const iterator.
+   *
+   * This will iterate over all allocated elements (in unspecified order).
+   * It is at least a @c forward_iterator.
+   * This may only be instantiated if the underlying Allocator
+   * supports iterators.
+   */
+  const_iterator begin() const;
+
+
+  /**
+   * @brief Ending iterator.
+   *
+   * This may only be instantiated if the underlying Allocator
+   * supports iterators.
+   */
+  iterator end();
+
+
+  /**
+   * @brief Ending const iterator.
+   *
+   * This may only be instantiated if the underlying Allocator
+   * supports iterators.
+   */
+  const_iterator end() const;
+
+
+  /**
+   * @brief Free an element.
+   * @param p The element to be freed.
+   *
+   * @c clear() will be called on the element at this point,
+   * if it has been defined.
+   *
+   * This may only be instantiated if it's supported
+   * by the underlying Allocator.
+   */
+  void free (pointer p);
+
+
+  /**
+   * @brief Reset pool back to a previous state.
+   * @param p The pointer back to which to reset.
+   *
+   * This will free (a la @c reset) the element @c p and all elements
+   * that have been allocated after it from this allocator.
+   *
+   * This may only be instantiated if it's supported
+   * by the underlying Allocator.
+   */
+  void resetTo (pointer p);
+};
+
+
+} // namespace SG
+
+
+#include "AthAllocators/ArenaHandleBaseT.icc"
+
+
+#endif // not ATLALLOCATORS_ARENAHANDLEBASET_H
diff --git a/Control/AthAllocators/AthAllocators/ArenaHandleBaseT.icc b/Control/AthAllocators/AthAllocators/ArenaHandleBaseT.icc
new file mode 100755
index 0000000000000000000000000000000000000000..90ceeafe565088ff96f357929032f7c8c5883c8b
--- /dev/null
+++ b/Control/AthAllocators/AthAllocators/ArenaHandleBaseT.icc
@@ -0,0 +1,212 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// $Id: ArenaHandleBaseT.icc 470529 2011-11-24 23:54:22Z ssnyder $
+/**
+ * @file  AthAllocators/ArenaHandleBaseT.icc
+ * @author scott snyder
+ * @date May 2007
+ * @brief Base class for @c Handle classes, containing parts that
+ *        are independent of how the Allocator gets created.
+ *        Inline and template implementations.
+ */
+
+
+namespace SG {
+
+
+/**
+ * @brief Constructor, passing in an index.
+ * @param header The group of Arenas which this Handle may reference.
+ *               May be null to select the global default.
+ * @param index The index of this Handle's Allocator type.
+ */
+template <typename T, typename ALLOC>
+ArenaHandleBaseT<T, ALLOC>::ArenaHandleBaseT (ArenaHeader* header,
+                                              size_t index)
+  : Base (header, index)
+{
+}
+
+
+/**
+ * @brief Constructor, passing in a creator instance.
+ * @param header The group of Arenas which this Handle may reference.
+ *               May be null to select the global default.
+ * @param creator A @c Creator instance that will create an instance
+ *                of the Allocator we use.
+ *
+ * We'll try looking up the allocator name (from @c creator) in the
+ * registry to find the proper index.  If it's not found, we'll
+ * register @c creator.
+ */
+template <typename T, typename ALLOC>
+ArenaHandleBaseT<T, ALLOC>::ArenaHandleBaseT (ArenaHeader* header,
+                                           const Creator& creator)
+  : Base (header, creator)
+{
+}
+
+
+/**
+ * @brief Constructor.
+ * @param it The base iterator.
+ */
+template <typename T, typename ALLOC>
+inline
+ArenaHandleBaseT<T, ALLOC>::iterator::iterator
+  (const typename ALLOC::iterator& it)
+  : iterator::iterator_adaptor_ (it)
+{
+}
+
+
+/**
+ * @brief Dereference the iterator.
+ */
+template <typename T, typename ALLOC>
+inline
+typename ArenaHandleBaseT<T, ALLOC>::iterator::reference
+ArenaHandleBaseT<T, ALLOC>::iterator::dereference() const
+{
+  return reinterpret_cast<T&> (*this->base_reference());
+}
+
+
+/**
+ * @brief Constructor.
+ * @param it The base iterator.
+ */
+template <typename T, typename ALLOC>
+inline
+ArenaHandleBaseT<T, ALLOC>::const_iterator::const_iterator
+  (const typename ALLOC::const_iterator& it)
+  : const_iterator::iterator_adaptor_ (it)
+{
+}
+
+
+/**
+ * @brief Constructor from a non-const iterator.
+ * @param it The non-const iterator.
+ */
+template <typename T, typename ALLOC>
+inline
+ArenaHandleBaseT<T, ALLOC>::const_iterator::const_iterator
+   (const iterator& it)
+  : const_iterator::iterator_adaptor_ (it.base_reference())
+{
+}
+
+
+/**
+ * @brief Dereference the iterator.
+ */
+template <typename T, typename ALLOC>
+inline
+typename ArenaHandleBaseT<T, ALLOC>::const_iterator::reference
+ArenaHandleBaseT<T, ALLOC>::const_iterator::dereference() const
+{
+  return reinterpret_cast<const T&> (*this->base_reference());
+}
+
+
+/**
+ * @brief Starting iterator.
+ *
+ * This will iterate over all allocated elements (in unspecified order).
+ * It is at least a @c forward_iterator.
+ * This may only be instantiated if the underlying Allocator
+ * supports iterators.
+ */
+template <class T, class ALLOC>
+typename ArenaHandleBaseT<T, ALLOC>::iterator
+ArenaHandleBaseT<T, ALLOC>::begin()
+{
+  return const_cast<ALLOC*>(this->allocator())->begin();
+}
+
+
+/**
+ * @brief Starting const iterator.
+ *
+ * This will iterate over all allocated elements (in unspecified order).
+ * It is at least a @c forward_iterator.
+ * This may only be instantiated if the underlying Allocator
+ * supports iterators.
+ */
+template <class T, class ALLOC>
+typename ArenaHandleBaseT<T, ALLOC>::const_iterator
+ArenaHandleBaseT<T, ALLOC>::begin() const
+{
+  return const_cast<const ALLOC*>(this->allocator())->begin();
+}
+
+
+/**
+ * @brief Ending iterator.
+ *
+ * This may only be instantiated if the underlying Allocator
+ * supports iterators.
+ */
+template <class T, class ALLOC>
+typename ArenaHandleBaseT<T, ALLOC>::iterator
+ArenaHandleBaseT<T, ALLOC>::end()
+{
+  return const_cast<ALLOC*>(this->allocator())->end();
+}
+
+
+/**
+ * @brief Ending const iterator.
+ *
+ * This may only be instantiated if the underlying Allocator
+ * supports iterators.
+ */
+template <class T, class ALLOC>
+typename ArenaHandleBaseT<T, ALLOC>::const_iterator
+ArenaHandleBaseT<T, ALLOC>::end() const
+{
+  return const_cast<const ALLOC*>(this->allocator())->end();
+}
+
+
+/**
+ * @brief Free an element.
+ * @param p The element to be freed.
+ *
+ * @c clear() will be called on the element at this point,
+ * if it has been defined.
+ *
+ * This may only be instantiated if it's supported
+ * by the underlying Allocator.
+ */
+template <class T, class ALLOC>
+inline
+void ArenaHandleBaseT<T, ALLOC>::free (pointer p)
+{
+  this->allocator()->free
+    (reinterpret_cast<typename ALLOC::pointer>(p));
+}
+
+
+/**
+ * @brief Reset pool back to a previous state.
+ * @param p The pointer back to which to reset.
+ *
+ * This will free (a la @c reset) the element @c p and all elements
+ * that have been allocated after it from this allocator.
+ *
+ * This may only be instantiated if it's supported
+ * by the underlying Allocator.
+ */
+template <class T, class ALLOC>
+void ArenaHandleBaseT<T, ALLOC>::resetTo(pointer p)
+{
+  return this->allocator()->resetTo
+    (reinterpret_cast<typename ALLOC::pointer>(p));
+}
+
+
+} // namespace SG
diff --git a/Control/AthAllocators/AthAllocators/ArenaHeader.h b/Control/AthAllocators/AthAllocators/ArenaHeader.h
new file mode 100755
index 0000000000000000000000000000000000000000..8d348ca7bb6e10e5941f7e7ca2de77654c61dcec
--- /dev/null
+++ b/Control/AthAllocators/AthAllocators/ArenaHeader.h
@@ -0,0 +1,170 @@
+// This file's extension implies that it's C, but it's really -*- C++ -*-.
+
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// $Id: ArenaHeader.h 470529 2011-11-24 23:54:22Z ssnyder $
+
+/**
+ * @file  AthAllocators/ArenaHeader.h
+ * @author scott snyder
+ * @date May 2007
+ * @brief Proxy for a group of Arenas.
+ *        See Arena.h for an overview of the arena-based memory allocators.
+ */
+
+
+#ifndef ATLALLOCATORS_ARENAHEADER_H
+#define ATLALLOCATORS_ARENAHEADER_H
+
+
+#include <vector>
+#include <cstdlib>
+#include <string>
+#include <iosfwd>
+
+
+namespace SG {
+
+
+class ArenaAllocatorBase;
+class ArenaBase;
+
+
+/**
+ * @brief Proxy for a group of Arenas.
+ *        See Arena.h for an overview of the arena-based memory allocators.
+ *
+ * A Header collects a group of Arenas.  One of these is the current Arena,
+ * in which memory operations will take place.  We can also generate
+ * a report of memory usage from all the Arenas in the group.
+ *
+ * This is also where we handle the mapping from indices to Allocator
+ * instances.  This is done simply with a vector of Allocator pointers.
+ * Each Arena has such a vector.  We keep a pointer to one of these;
+ * that's what defines the notion of the current Arena.
+ */
+class ArenaHeader
+{
+public:
+  /// Vector of pointers to Allocator instances.
+  typedef std::vector<ArenaAllocatorBase*> ArenaAllocVec_t;
+
+
+  /**
+   * @brief Constructor.
+   */
+  ArenaHeader();
+
+
+  /**
+   * @brief Destructor.
+   *
+   * This will clean up any memory allocated in the default Arena.
+   */
+  ~ArenaHeader();
+
+
+  /**
+   * @brief Translate an integer index to an Allocator index.
+   * @param i The index to look up.
+   *
+   * If the index isn't valid, an assertion will be tripped.
+   */
+  ArenaAllocatorBase* allocator (size_t i);
+
+
+  /**
+   * @brief Set the current Arena.
+   * @param allocvec New vector of Allocator instances.
+   * @return The previous vector.
+   *
+   * This sets the notion of the current Arena.
+   */
+  ArenaAllocVec_t* setAllocVec (ArenaAllocVec_t* allocvec);
+
+
+  /**
+   * @brief Add a new Arena to the group.
+   * @param a The Arena to add.
+   */
+  void addArena (ArenaBase* a);
+
+
+  /**
+   * @brief Remove an Arena from the group.
+   * @param a The Arena to remove.
+   *
+   * Will trip an assertion if the Arena is not in the group.
+   */
+  void delArena (ArenaBase* a);
+
+
+  /**
+   * @brief Generate a report of all Arenas in the group.
+   * @param os Stream to which to send a report.
+   */
+  void report (std::ostream& os) const;
+
+
+  /**
+   * @brief Generate a report of all Arenas in the group, and return
+   *        the result as a string.
+   *
+   * We have this in addition to @c report() in order to make it easier
+   * to call from scripting languages.
+   */
+  std::string reportStr () const;
+
+
+  /**
+   * @brief Call @c reset on all Allocators in the current Arena.
+   *
+   * All elements allocated are returned to the free state.
+   * @c clear should be called on them if it was provided.
+   * The elements may continue to be cached internally, without
+   * returning to the system.
+   */
+  void reset();
+
+
+  /**
+   * @brief Return the global default Header instance.
+   */
+  static ArenaHeader* defaultHeader();
+
+
+private:
+  /**
+   * @brief Make a new Allocator for index i.
+   * @param i The index of the Allocator.
+   *
+   * The Allocator vector was empty for index @c i.  Make an appropriate
+   * new Allocator, store it in the vector, and return it.  Will trip
+   * an assertion if the index is not valid.
+   */
+  ArenaAllocatorBase* makeAllocator (size_t i);
+
+
+  /// Current vector of Allocators.
+  ArenaAllocVec_t* m_allocvec;
+
+  /// Vector of Allocators which are owned by this object.
+  /// This constitutes the default Arena.
+  ArenaAllocVec_t* m_ownedAllocvec;
+
+  /// List of all Arenas in our group.
+  std::vector<ArenaBase*>  m_arenas;
+};
+
+
+} // namespace SG
+
+
+#include "AthAllocators/ArenaHeader.icc"
+
+
+
+#endif // not ATLALLOCATORS_ARENAHEADER_H
+
diff --git a/Control/AthAllocators/AthAllocators/ArenaHeader.icc b/Control/AthAllocators/AthAllocators/ArenaHeader.icc
new file mode 100755
index 0000000000000000000000000000000000000000..bd358a02820b1f2b507a22b89d9d661c159b3646
--- /dev/null
+++ b/Control/AthAllocators/AthAllocators/ArenaHeader.icc
@@ -0,0 +1,38 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// $Id: ArenaHeader.icc 470529 2011-11-24 23:54:22Z ssnyder $
+/**
+ * @file  AthAllocators/ArenaHeader.icc
+ * @author scott snyder
+ * @date May 2007
+ * @brief Proxy for a group of Arenas.
+ *        Inline implementations.
+ */
+
+
+namespace SG {
+
+
+/**
+ * @brief Translate an integer index to an Allocator index.
+ * @param i The index to look up.
+ *
+ * If the index isn't valid, an assertion will be tripped.
+ *
+ * This is on the fast path for element allocation, so keep
+ * it small and inline.
+ */
+inline
+ArenaAllocatorBase* ArenaHeader::allocator (size_t i)
+{
+  if (m_allocvec && i < m_allocvec->size()) {
+    ArenaAllocatorBase* allocbase = (*m_allocvec)[i];
+    if (allocbase) return allocbase;
+  }
+  return makeAllocator (i);
+}
+
+
+} // namespace SG
diff --git a/Control/AthAllocators/AthAllocators/ArenaHeaderGaudiClear.h b/Control/AthAllocators/AthAllocators/ArenaHeaderGaudiClear.h
new file mode 100755
index 0000000000000000000000000000000000000000..a2e9f2c1f7e73aefa0d02162b48df736da59fd0e
--- /dev/null
+++ b/Control/AthAllocators/AthAllocators/ArenaHeaderGaudiClear.h
@@ -0,0 +1,105 @@
+// This file's extension implies that it's C, but it's really -*- C++ -*-.
+
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// $Id: ArenaHeaderGaudiClear.h 470529 2011-11-24 23:54:22Z ssnyder $
+
+/**
+ * @file  AthAllocators/ArenaHeaderGaudiClear.h
+ * @author scott snyder
+ * @date May 2007
+ * @brief An @c ArenaHeader that's cleared on every Gaudi event.
+ *        See Arena.h for an overview of the arena-based memory allocators.
+ */
+
+
+#ifndef ATLALLOCATORS_ARENAHEADERGAUDICLEAR_H
+#define ATLALLOCATORS_ARENAHEADERGAUDICLEAR_H
+
+
+#include "AthAllocators/ArenaHeader.h"
+#include "GaudiKernel/IIncidentListener.h"
+
+
+namespace SG {
+
+
+/**
+ * @brief An @c ArenaHeader that's cleared on every Gaudi event.
+ *
+ * This is a version of @c ArenaHeader on which @c reset will be called
+ * automatically on every new event.
+ */
+class ArenaHeaderGaudiClear
+  : public ArenaHeader,
+    public IIncidentListener
+{
+public:
+  /**
+   * @brief Constructor.
+   */
+  ArenaHeaderGaudiClear();
+
+
+  /**
+   * @brief Register with Gaudi.
+   */
+  void initialize();
+
+
+  /**
+   * @brief Handle a Gaudi incident.
+   * @param inc The incident to handle.
+   */
+  virtual void handle(const Incident& inc);
+
+
+  /**
+   * @brief Increase the reference count.  (Required by @c IInterface.)
+   */
+  virtual unsigned long addRef();
+
+
+  /**
+   * @brief Decrease the reference count.  (Required by @c IInterface.)
+   */
+  virtual unsigned long release();
+
+
+  /**
+   * @brief Return the Gaudi interface for this object.
+   *        (Required by @c IInterface.)
+   */
+  virtual StatusCode queryInterface(const InterfaceID& riid,
+                                    void** ppvInterface);
+
+
+  /**
+   * @brief Disable the Gaudi functionality.
+   *
+   * If this is called before @c initialize(), we will not attempt
+   * to register ourselves with Gaudi.  This can be used for running
+   * outside of the framework.
+   */
+  static void disable();
+
+
+private:
+  /// True after we've called @c initialize().
+  bool m_initialized;
+
+  /// Current reference count.
+  unsigned int m_instanceCount;
+
+  /// True if @c disable has been called.
+  static bool m_disabled;
+};
+
+
+} // namespace SG
+
+
+#endif // not ATLALLOCATORS_ARENAHEADERGAUDICLEAR_H
+
diff --git a/Control/AthAllocators/AthAllocators/ArenaHeapAllocator.h b/Control/AthAllocators/AthAllocators/ArenaHeapAllocator.h
new file mode 100755
index 0000000000000000000000000000000000000000..4f278d5aca448f8527db806ddb8fec8fd9b3de0e
--- /dev/null
+++ b/Control/AthAllocators/AthAllocators/ArenaHeapAllocator.h
@@ -0,0 +1,200 @@
+// This file's extension implies that it's C, but it's really -*- C++ -*-.
+
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// $Id: ArenaHeapAllocator.h 470529 2011-11-24 23:54:22Z ssnyder $
+
+/**
+ * @file  AthAllocators/ArenaHeapAllocator.h
+ * @author scott snyder
+ * @date May 2007
+ * @brief Heap-based allocator.
+ *        See Arena.h for an overview of the arena-based memory allocators.
+ */
+
+
+#ifndef ATLALLOCATORS_ARENAHEAPALLOCATOR_H
+#define ATLALLOCATORS_ARENAHEAPALLOCATOR_H
+
+
+#include "AthAllocators/ArenaBlockAllocatorBase.h"
+#include <cstdlib>
+
+
+namespace SG {
+
+
+class ArenaBlock;
+
+
+/**
+ * @brief Heap-based allocator.
+ *        See Arena.h for an overview of the arena-based memory allocators.
+ *
+ * This is a block-based memory allocator, with heap-like behavior.
+ * This allows freeing individual elements, but we don't implement
+ * @c resetTo or an iterator.
+ *
+ * There are some extra costs though.
+ *
+ *  - We need an additional pointer (`link') for each free element.
+ *
+ *    By default, this is done by increasing the element size by a pointer,
+ *    since we don't know whether there is data in the element itself
+ *    that must be preserved across free/allocate.  However, if you know
+ *    that part of the element may be safely while it is free, then
+ *    the allocator can be configured to use that as the link instead.
+ *
+ *  - When @c reset() is called, we need to call @c clear() on all
+ *    allocated elements (if it is defined).  If @c canReclear is set,
+ *    then we just call @c clear() on all elements in allocated blocks
+ *    on @c reset(), regardless of whether or not the individual elements
+ *    are allocated or not.  Otherwise, we make two passes over the elements,
+ *    first to build a list of those that are allocated and second
+ *    to actually call @c clear().
+ *
+ *    An intermediate strategy, not currently implemented, could be used
+ *    if the link does not overlap the element: set the link to a magic
+ *    value when an element is allocated.
+ */
+class ArenaHeapAllocator
+  : public ArenaBlockAllocatorBase
+{
+public:
+  /**
+   * @brief Helper to initialize a parameters structure.
+   *
+   * This creates a @c Params class appropriately initialized for class @c T.
+   * Assumptions made:
+   *  - The constructor and destructor calls will be filled in
+   *    if non-trivial, unless no_ctor or no_dtor is set to true.
+   *  - The clear call will be filled in if the optional template parameter
+   *    @c clear is true.
+   *  - No space will be reserved for an extra link.
+   *  - @c canReclear is @c true and @c mustClear is @c false.
+   *  - The link will be allocated externally to the element.
+   *
+   * If these are not appropriate, you can derive from this class
+   * and make the appropriate changes.
+   */
+  template <typename T,
+            bool clear = false,
+            bool no_ctor = false,
+            bool no_dtor = false>
+  struct initParams
+    : public ArenaAllocatorBase::initParams<T, clear, no_ctor, no_dtor>
+  {
+    // Short name for our base class.
+    typedef ArenaAllocatorBase::initParams<T, clear, no_ctor, no_dtor> Base;
+
+
+    /**
+     * @brief Constructor.
+     * @param nblock Value to set in the parameters structure for the
+     *               number of elements to allocate per block.
+     * @param name   Value to set in the parameters structure for the
+     *               allocator name.
+     */
+    initParams (size_t nblock = 1000, const std::string& name = "");
+
+    /// Return an initialized parameters structure.
+    ArenaAllocatorBase::Params params() const;
+
+    /// Return an initialized parameters structure.
+    // Note: gcc 3.2.3 doesn't allow defining this out-of-line.
+    operator ArenaAllocatorBase::Params() const { return params(); }
+  };
+
+
+  /**
+   * @brief Constructor.
+   * @param params The parameters structure for this allocator.
+   *               See @c  ArenaAllocatorBase.h for the contents.
+   */
+  ArenaHeapAllocator (const Params& params);
+
+
+  /**
+   * @brief Destructor.  This will free all the Allocator's storage.
+   */
+  ~ArenaHeapAllocator();
+
+
+  /**
+   * @brief Allocate a new element.
+   *
+   * The fast path of this will be completely inlined.
+   */
+  pointer allocate();
+
+
+  /**
+   * @brief Free an element.
+   * @param p The element to be freed.
+   *
+   * @c clear() will be called on the element at this point,
+   * if it has been defined.
+   */
+  void free (pointer p);
+
+
+  /**
+   * @brief Free all allocated elements.
+   *
+   * All elements allocated are returned to the free state.
+   * @c clear should be called on them if it was provided.
+   * The elements may continue to be cached internally, without
+   * returning to the system.
+   */
+  virtual void reset();
+
+
+  /**
+   * @brief Free all allocated elements and release memory back to the system.
+   *
+   * All elements allocated are freed, and all allocated blocks of memory
+   * are released back to the system.
+   * @c destructor should be called on them if it was provided
+   * (preceded by @c clear if provided and @c mustClear was set).
+   */
+  virtual void erase();
+
+
+  // These are just placeholders --- the iterators are not implemented.
+  typedef void iterator;
+  typedef void const_iterator;
+
+
+private:
+  /**
+   * @brief Call @c clear() for all allocated elements.
+   */
+  void slowClear();
+
+
+  /**
+   * @brief Add more free elements to the pool, and allocate a new element.
+   */
+  pointer refill();
+
+
+  /**
+   * @brief Return a reference to the link for an element.
+   * @param p The element.
+   */
+  pointer& link (pointer p) const;
+
+  /// Pointer to the next free element.
+  pointer m_freeptr;
+};
+
+
+} // namespace SG
+
+
+#include "AthAllocators/ArenaHeapAllocator.icc"
+
+
+#endif // not ATLALLOCATORS_ARENAHEAPALLOCATOR_H
diff --git a/Control/AthAllocators/AthAllocators/ArenaHeapAllocator.icc b/Control/AthAllocators/AthAllocators/ArenaHeapAllocator.icc
new file mode 100755
index 0000000000000000000000000000000000000000..47706751745086354b9c401e555b9760ea15aad3
--- /dev/null
+++ b/Control/AthAllocators/AthAllocators/ArenaHeapAllocator.icc
@@ -0,0 +1,107 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// $Id: ArenaHeapAllocator.icc 470529 2011-11-24 23:54:22Z ssnyder $
+/**
+ * @file  AthAllocators/ArenaPoolAllocator.icc
+ * @author scott snyder
+ * @date May 2007
+ * @brief Heap-based allocator.
+ *        Inline and template implementations.
+ */
+
+
+namespace SG {
+
+
+/**
+ * @brief Constructor for parameters helper.
+ * @param nblock Value to set in the parameters structure for the
+ *               number of elements to allocate per block.
+ * @param name   Value to set in the parameters structure for the
+ *               allocator name.
+ */
+template <typename T, bool clear, bool no_ctor, bool no_dtor>
+ArenaHeapAllocator::initParams<T, clear, no_ctor, no_dtor>::
+initParams (size_t nblock /*=1000*/, const std::string& name /*=""*/)
+  : Base (nblock, name)
+{
+}
+
+
+/**
+ * @brief Return an initialized parameters structure.
+ */
+template <typename T, bool clear, bool no_ctor, bool no_dtor>
+ArenaAllocatorBase::Params
+ArenaHeapAllocator::initParams<T, clear, no_ctor, no_dtor>::params() const
+{
+  // Do the base class stuff.
+  Params p = Base::operator ArenaAllocatorBase::Params();
+
+  // Allow space for an extra pointer.
+  struct Dummy {
+    T x;
+    pointer y;
+  };
+  p.eltSize = sizeof (Dummy);
+  Dummy* dummy = (Dummy*)0x1234;
+  p.linkOffset = (char*)&dummy->y - (char*)dummy;
+
+  // Need to allow at least enough space for a pointer.
+  p.minSize = sizeof (pointer);
+
+  return p;
+}
+
+
+/**
+ * @brief Allocate a new element.
+ *
+ * The fast path of this will be completely inlined.
+ */
+inline
+ArenaHeapAllocator::pointer ArenaHeapAllocator::allocate()
+{
+  ++m_stats.elts.inuse;
+  pointer ret = m_freeptr;
+  if (ret) {
+    m_freeptr = link (ret);
+    return ret;
+  }
+  return refill();
+}
+
+
+/**
+ * @brief Free an element.
+ * @param p The element to be freed.
+ *
+ * @c clear() will be called on the element at this point,
+ * if it has been defined.
+ */
+inline
+void ArenaHeapAllocator::free (pointer p)
+{
+  if (m_params.clear)
+    m_params.clear (p);
+  link (p) = m_freeptr;
+  m_freeptr = p;
+  --m_stats.elts.inuse;
+}
+
+
+/**
+ * @brief Return a reference to the link for an element.
+ * @param p The element.
+ */
+inline
+ArenaHeapAllocator::pointer& ArenaHeapAllocator::link (pointer p) const
+{
+  return *reinterpret_cast<pointer*> (p + m_params.linkOffset);
+}
+
+
+} // namespace SG
+
diff --git a/Control/AthAllocators/AthAllocators/ArenaHeapSTLAllocator.h b/Control/AthAllocators/AthAllocators/ArenaHeapSTLAllocator.h
new file mode 100644
index 0000000000000000000000000000000000000000..259f5ce28deead2fc67413d6425ae2cfa598d292
--- /dev/null
+++ b/Control/AthAllocators/AthAllocators/ArenaHeapSTLAllocator.h
@@ -0,0 +1,388 @@
+// This file's extension implies that it's C, but it's really -*- C++ -*-.
+
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// $Id: ArenaHeapSTLAllocator.h,v 1.2 2008-08-26 02:12:26 ssnyder Exp $
+
+/**
+ * @file  AthAllocators/ArenaHeapSTLAllocator.h
+ * @author scott snyder
+ * @date Nov 2011
+ * @brief STL-style allocator wrapper for @c ArenaHeapAllocator.
+ *
+ * This class defines a STL-style allocator for types @c T with the
+ * following special properties.
+ *
+ *  - We use an @c ArenaHeapAllocator for allocations.
+ *  - The memory is owned directly by the allocator object.
+ *  - Only one object at a time may be allocated.
+ *
+ * So, this allocator is suitable for an STL container which allocates
+ * lots of fixed-size objects, such as @c std::list.
+ *
+ * Much of the complexity here is due to the fact that the allocator
+ * type that gets passed to the container is an allocator for the
+ * container's value_type, but that allocator is not actually
+ * used to allocate memory.  Instead, an allocator for the internal
+ * node type is used.  This makes it awkward if you want to have
+ * allocators that store state.
+ *
+ * Further, to avoid creating a pool for the allocator for the container's
+ * value_type (when the container doesn't actually use that for allocation),
+ * this template has a second argument.  This defaults to the first argument,
+ * but is passed through by rebind.  If the first and second argument
+ * are the same, then we don't create a pool.
+ *
+ * The effect of all this is that you can give an allocator type like
+ *   ArenaHeapSTLAllocator<Mytype>
+ * to a STL container.  Allocators for Mytype won't use
+ * a pool, but an allocator for node<Mytype> will use the pool.
+ */
+
+
+#ifndef ATLALLOCATORS_ARENAHEAPSTLALLOCATOR
+#define ATLALLOCATORS_ARENAHEAPSTLALLOCATOR
+
+
+#include "AthAllocators/ArenaHeapAllocator.h"
+#include <string>
+
+
+namespace SG {
+
+
+/**
+ * @brief Initializer for pool allocator parameters.
+ *
+ *        We override the defaults to disable calling the payload ctor/dtor.
+ */
+template <class T>
+class ArenaHeapSTLAllocator_initParams
+  : public ArenaHeapAllocator::initParams<T, false, true, true>
+{
+public:
+  /// We take defaults from this.
+  typedef ArenaHeapAllocator::initParams<T, false, true, true> Base;
+
+    /**
+     * @brief Constructor.
+     * @param nblock Value to set in the parameters structure for the
+     *               number of elements to allocate per block.
+     * @param name   Value to set in the parameters structure for the
+     *               allocator name.
+     */
+    ArenaHeapSTLAllocator_initParams (size_t nblock = 1000,
+                                      const std::string& name = "");
+
+    /// Return an initialized parameters structure.
+    ArenaAllocatorBase::Params params() const;
+
+    /// Return an initialized parameters structure.
+    // Note: gcc 3.2.3 doesn't allow defining this out-of-line.
+    operator ArenaAllocatorBase::Params() const { return params(); }
+};
+
+
+/**
+ * @brief STL-style allocator wrapper for @c ArenaHeapAllocator.
+ *        This is the generic specialization, which uses the heap allocator.
+ *
+ * See the file-level comments for details.
+ */
+template <class T, class VETO=T>
+class ArenaHeapSTLAllocator
+{
+public:
+  /// Standard STL allocator typedefs.
+  typedef T*        pointer;
+  typedef const T*  const_pointer;
+  typedef T&        reference;
+  typedef const T&  const_reference;
+  typedef T         value_type;
+  typedef size_t    size_type;
+  typedef ptrdiff_t difference_type;
+
+
+  /// Standard STL allocator rebinder.
+  template <class U> struct rebind {
+    typedef ArenaHeapSTLAllocator<U, VETO> other;
+  };
+
+
+  /**
+   * @brief Default constructor.
+   * @param nblock Value to set in the parameters structure for the
+   *               number of elements to allocate per block.
+   * @param name   Value to set in the parameters structure for the
+   *               allocator name.
+   */
+  ArenaHeapSTLAllocator (size_t nblock = 1000, const std::string& name = "");
+
+
+  /**
+   * @brief Constructor from another @c ArenaHeapSTLAllocator.
+   *
+   * The @c name and @c nblock parameters are copied, but the data are not.
+   */
+  template <class U, class V>
+  ArenaHeapSTLAllocator (const ArenaHeapSTLAllocator<U, V>& a);
+
+  // We don't bother to supply a more general constructor --- shouldn't
+  // be needed.
+
+
+  /// Convert a reference to an address.
+  pointer address (reference x) const;
+  const_pointer address (const_reference x) const;
+
+
+  /**
+   * @brief Allocate new objects.
+   * @param n Number of objects to allocate.  Must be 1.
+   * @param hint Allocation hint.  Not used.
+   */
+  pointer allocate (size_type n, const void* hint = 0);
+
+
+  /**
+   * @brief Deallocate objects.
+   * @param n Number of objects to deallocate.  Must be 1.
+   */
+  void deallocate (pointer, size_type n);
+
+
+  /**
+   * @brief Return the maximum number of objects we can allocate at once.
+   *
+   * This always returns 1.
+   */
+  size_type max_size() const throw();
+
+
+  /**
+   * @brief Call the @c T constructor.
+   * @param p Location of the memory.
+   * @param val Parameter to pass to the constructor.
+   */
+  void construct (pointer p, const T& val);
+
+
+  /**
+   * @brief Call the @c T destructor.
+   * @param p Location of the memory.
+   */
+  void destroy (pointer p);
+
+
+  /**
+   * @brief Return the hinted number of objects allocated per block.
+   */
+  size_t nblock() const;
+
+
+  /**
+   * @brief Return the name of this allocator.
+   */
+  const std::string& name() const;
+
+
+  /**
+   * @brief Free all allocated elements.
+   *
+   * All elements allocated are returned to the free state.
+   * @c clear should be called on them if it was provided.
+   * The elements may continue to be cached internally, without
+   * returning to the system.
+   */
+  void reset();
+
+
+  /**
+   * @brief Free all allocated elements and release memory back to the system.
+   *
+   * All elements allocated are freed, and all allocated blocks of memory
+   * are released back to the system.
+   * @c destructor should be called on them if it was provided
+   * (preceded by @c clear if provided and @c mustClear was set).
+   */
+  void erase();
+
+
+  /**
+   * @brief Set the total number of elements cached by the allocator.
+   * @param size The desired pool size.
+   *
+   * This allows changing the number of elements that are currently free
+   * but cached.  Any allocated elements are not affected by this call.
+   *
+   * If @c size is greater than the total number of elements currently
+   * cached, then more will be allocated.  This will preferably done
+   * with a single block, but that is not guaranteed; in addition, the
+   * allocator may allocate more elements than is requested.
+   *
+   * If @c size is smaller than the total number of elements currently
+   * cached, as many blocks as possible will be released back to the system.
+   * It may not be possible to release the number of elements requested;
+   * this should be implemented on a best-effort basis.
+   */
+  void reserve (size_t size);
+
+
+  /**
+   * @brief Return the statistics block for this allocator.
+   */
+  const ArenaAllocatorBase::Stats& stats() const;
+
+
+  /**
+   * @brief Return a pointer to the underlying allocator (may be 0).
+   */
+  ArenaAllocatorBase* poolptr() const;
+
+
+private:
+  /// The underlying allocator.
+  ArenaHeapAllocator m_pool;
+};
+
+
+
+/**
+ * @brief STL-style allocator wrapper for @c ArenaHeapAllocator.
+ *        This is the specialization for the case of the vetoed type.
+ *
+ * See the file-level comments for details.
+ */
+template <class T>
+class ArenaHeapSTLAllocator<T, T>
+  : public std::allocator<T>
+{
+public:
+  typedef std::allocator<T> base;
+
+  /// Standard STL allocator typedefs.
+  typedef typename base::pointer         pointer;
+  typedef typename base::const_pointer   const_pointer;
+  typedef typename base::reference       reference;
+  typedef typename base::const_reference const_reference;
+  typedef typename base::value_type      value_type;
+  typedef typename base::size_type       size_type;
+  typedef typename base::difference_type difference_type;
+
+
+  /// Standard STL allocator rebinder.
+  template <class U> struct rebind {
+    typedef ArenaHeapSTLAllocator<U, T> other;
+  };
+
+
+  /**
+   * @brief Default constructor.
+   * @param nblock Value to set in the parameters structure for the
+   *               number of elements to allocate per block.
+   * @param name   Value to set in the parameters structure for the
+   *               allocator name.
+   */
+  ArenaHeapSTLAllocator (size_t nblock = 1000, const std::string& name = "");
+
+
+  /**
+   * @brief Constructor from another @c ArenaHeapSTLAllocator.
+   *
+   * The @c name and @c nblock parameters are copied, but the data are not.
+   */
+  template <class U, class V>
+  ArenaHeapSTLAllocator (const ArenaHeapSTLAllocator<U, V>& a);
+
+
+  // We don't bother to supply a more general constructor --- shouldn't
+  // be needed.
+
+
+  /**
+   * @brief Return the hinted number of objects allocated per block.
+   */
+  size_t nblock() const;
+
+
+  /**
+   * @brief Return the name of this allocator.
+   */
+  const std::string& name() const;
+
+
+  /**
+   * @brief Free all allocated elements.
+   *
+   * All elements allocated are returned to the free state.
+   * @c clear should be called on them if it was provided.
+   * The elements may continue to be cached internally, without
+   * returning to the system.
+   */
+  void reset();
+
+
+  /**
+   * @brief Free all allocated elements and release memory back to the system.
+   *
+   * All elements allocated are freed, and all allocated blocks of memory
+   * are released back to the system.
+   * @c destructor should be called on them if it was provided
+   * (preceded by @c clear if provided and @c mustClear was set).
+   */
+  void erase();
+
+
+  /**
+   * @brief Set the total number of elements cached by the allocator.
+   * @param size The desired pool size.
+   *
+   * This allows changing the number of elements that are currently free
+   * but cached.  Any allocated elements are not affected by this call.
+   *
+   * If @c size is greater than the total number of elements currently
+   * cached, then more will be allocated.  This will preferably done
+   * with a single block, but that is not guaranteed; in addition, the
+   * allocator may allocate more elements than is requested.
+   *
+   * If @c size is smaller than the total number of elements currently
+   * cached, as many blocks as possible will be released back to the system.
+   * It may not be possible to release the number of elements requested;
+   * this should be implemented on a best-effort basis.
+   */
+  void reserve (size_t size);
+
+
+  /**
+   * @brief Return the statistics block for this allocator.
+   */
+  const ArenaAllocatorBase::Stats& stats() const;
+
+
+  /**
+   * @brief Return a pointer to the underlying allocator (may be 0).
+   */
+  ArenaAllocatorBase* poolptr() const;
+
+
+private:
+  /// Saved hinted number of objects per block.
+  size_t m_nblock;
+
+  /// Saved allocator name.
+  std::string m_name;
+
+  /// Point at an underlying allocator from a different specialization.
+  ArenaAllocatorBase* m_poolptr;
+};
+
+
+} // namespace SG
+
+
+#include "AthAllocators/ArenaHeapSTLAllocator.icc"
+
+
+#endif // ATLALLOCATORS_ARENAHEAPSTLALLOCATOR
diff --git a/Control/AthAllocators/AthAllocators/ArenaHeapSTLAllocator.icc b/Control/AthAllocators/AthAllocators/ArenaHeapSTLAllocator.icc
new file mode 100644
index 0000000000000000000000000000000000000000..570fc5d2b7b679fc19b9921a54210acf8da4a595
--- /dev/null
+++ b/Control/AthAllocators/AthAllocators/ArenaHeapSTLAllocator.icc
@@ -0,0 +1,432 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// $Id: ArenaHeapSTLAllocator.icc,v 1.2 2008-08-26 02:12:26 ssnyder Exp $
+/**
+ * @file  AthAllocators/ArenaHeapSTLAllocator.icc
+ * @author scott snyder
+ * @date Nov 2011
+ * @brief STL-style allocator wrapper for @c ArenaHeapAllocator.
+ */
+
+
+#include <cassert>
+
+
+namespace SG {
+
+
+
+//****************************************************************************
+// Generic specialization
+//
+
+
+/**
+ * @brief Constructor.
+ * @param nblock Value to set in the parameters structure for the
+ *               number of elements to allocate per block.
+ * @param name   Value to set in the parameters structure for the
+ *               allocator name.
+ */
+template <class T>
+ArenaHeapSTLAllocator_initParams<T>::ArenaHeapSTLAllocator_initParams
+ (size_t nblock /*= 1000*/, const std::string& name /*= ""*/)
+   : Base (nblock, name)
+{
+}
+
+
+/**
+ * @brief Return an initialized parameters structure.
+ */
+template <class T>
+ArenaAllocatorBase::Params ArenaHeapSTLAllocator_initParams<T>::params() const
+{
+  // Do the base class stuff.
+  ArenaAllocatorBase::Params p =
+    Base::operator ArenaAllocatorBase::Params();
+
+  // Disable ctor/dtor.
+  p.constructor = 0;
+  p.destructor = 0;
+
+  // Overlap link over free struct.
+  p.eltSize = std::max (sizeof(T), p.minSize);
+  p.linkOffset = 0;
+
+  return p;
+}
+
+
+/**
+ * @brief Default constructor.
+ * @param nblock Value to set in the parameters structure for the
+ *               number of elements to allocate per block.
+ * @param name   Value to set in the parameters structure for the
+ *               allocator name.
+ */
+template <class T, class VETO>
+ArenaHeapSTLAllocator<T, VETO>::ArenaHeapSTLAllocator
+ (size_t nblock /*= 1000*/, const std::string& name /*= ""*/)
+   : m_pool (ArenaHeapSTLAllocator_initParams<T> (nblock, name))
+{
+}
+
+
+/**
+ * @brief Constructor from another @c ArenaHeapSTLAllocator.
+ *
+ * The @c name and @c nblock parameters are copied, but the data are not.
+ */
+template <class T, class VETO>
+template <class U, class V>
+ArenaHeapSTLAllocator<T, VETO>::ArenaHeapSTLAllocator
+  (const ArenaHeapSTLAllocator<U, V>& a)
+    : m_pool (ArenaHeapSTLAllocator_initParams<T> (a.nblock(), a.name()))
+{
+}
+
+
+/**
+ * @brief Convert a reference to an address.
+ */
+template <class T, class VETO>
+inline
+typename ArenaHeapSTLAllocator<T, VETO>::pointer
+ArenaHeapSTLAllocator<T, VETO>::address (reference x) const
+{
+  return &x;
+}
+
+
+/**
+ * @brief Convert a reference to an address.
+ */
+template <class T, class VETO>
+inline
+typename ArenaHeapSTLAllocator<T, VETO>::const_pointer
+ArenaHeapSTLAllocator<T, VETO>::address (const_reference x) const
+{
+  return &x;
+}
+
+
+
+/**
+ * @brief Allocate new objects.
+ * @param n Number of objects to allocate.  Must be 1.
+ * @param hint Allocation hint.  Not used.
+ */
+template <class T, class VETO>
+inline
+typename ArenaHeapSTLAllocator<T, VETO>::pointer
+ArenaHeapSTLAllocator<T, VETO>::allocate (size_type
+#ifndef NDEBUG
+                      n
+#endif
+                      , const void* /*hint = 0*/)
+{
+  assert (n == 1);
+  return reinterpret_cast<pointer> (m_pool.allocate());
+}
+
+
+/**
+ * @brief Deallocate objects.
+ * @param n Number of objects to deallocate.  Must be 1.
+ *
+ * This implementation doesn't do anything.
+ */
+template <class T, class VETO>
+inline
+void ArenaHeapSTLAllocator<T, VETO>::deallocate (pointer p, size_type 
+#ifndef NDEBUG
+                             n
+#endif
+                             )
+{
+  assert (n == 1);
+  m_pool.free (reinterpret_cast<ArenaHeapAllocator::pointer> (p));
+}
+
+
+/**
+ * @brief Return the maximum number of objects we can allocate at once.
+ *
+ * This always returns 1.
+ */
+template <class T, class VETO>
+inline
+typename ArenaHeapSTLAllocator<T, VETO>::size_type
+ArenaHeapSTLAllocator<T, VETO>::max_size() const throw() 
+{
+  return 1;
+}
+
+
+/**
+ * @brief Call the @c T constructor.
+ * @param p Location of the memory.
+ * @param val Parameter to pass to the constructor.
+ */
+template <class T, class VETO>
+inline
+void ArenaHeapSTLAllocator<T, VETO>::construct (pointer p, const T& val)
+{
+  new (reinterpret_cast<void*>(p)) T(val);
+}
+
+
+/**
+ * @brief Call the @c T destructor.
+ * @param p Location of the memory.
+ */
+template <class T, class VETO>
+inline
+void ArenaHeapSTLAllocator<T, VETO>::destroy (pointer p)
+{
+  p->~T();
+}
+
+
+/**
+ * @brief Return the hinted number of objects allocated per block.
+ */
+template <class T, class VETO>
+inline
+size_t ArenaHeapSTLAllocator<T, VETO>::nblock() const
+{
+  return m_pool.params().nblock;
+}
+
+
+/**
+ * @brief Return the name of this allocator.
+ */
+template <class T, class VETO>
+inline
+const std::string& ArenaHeapSTLAllocator<T, VETO>::name() const
+{
+  return m_pool.name();
+}
+
+
+/**
+ * @brief Free all allocated elements.
+ *
+ * All elements allocated are returned to the free state.
+ * @c clear should be called on them if it was provided.
+ * The elements may continue to be cached internally, without
+ * returning to the system.
+ */
+template <class T, class VETO>
+void ArenaHeapSTLAllocator<T, VETO>::reset()
+{
+  m_pool.reset();
+}
+
+
+/**
+ * @brief Free all allocated elements and release memory back to the system.
+ *
+ * All elements allocated are freed, and all allocated blocks of memory
+ * are released back to the system.
+ * @c destructor should be called on them if it was provided
+ * (preceded by @c clear if provided and @c mustClear was set).
+ */
+template <class T, class VETO>
+void ArenaHeapSTLAllocator<T, VETO>::erase()
+{
+  m_pool.erase();
+}
+
+
+/**
+ * @brief Set the total number of elements cached by the allocator.
+ * @param size The desired pool size.
+ *
+ * This allows changing the number of elements that are currently free
+ * but cached.  Any allocated elements are not affected by this call.
+ *
+ * If @c size is greater than the total number of elements currently
+ * cached, then more will be allocated.  This will preferably done
+ * with a single block, but that is not guaranteed; in addition, the
+ * allocator may allocate more elements than is requested.
+ *
+ * If @c size is smaller than the total number of elements currently
+ * cached, as many blocks as possible will be released back to the system.
+ * It may not be possible to release the number of elements requested;
+ * this should be implemented on a best-effort basis.
+ */
+template <class T, class VETO>
+void ArenaHeapSTLAllocator<T, VETO>::reserve (size_t size)
+{
+  m_pool.reserve (size);
+}
+
+
+/**
+ * @brief Return the statistics block for this allocator.
+ */
+template <class T, class VETO>
+const ArenaAllocatorBase::Stats& ArenaHeapSTLAllocator<T, VETO>::stats() const
+{
+  return m_pool.stats();
+}
+
+
+/**
+ * @brief Return a pointer to the underlying allocator (may be 0).
+ */
+template <class T, class VETO>
+ArenaAllocatorBase* ArenaHeapSTLAllocator<T, VETO>::poolptr() const
+{
+  const ArenaAllocatorBase* tmp = &m_pool;
+  return const_cast<ArenaAllocatorBase*> (tmp);
+}
+
+
+//****************************************************************************
+// Vetoed specialization.
+//
+
+
+/**
+ * @brief Default constructor.
+ * @param nblock Value to set in the parameters structure for the
+ *               number of elements to allocate per block.
+ * @param name   Value to set in the parameters structure for the
+ *               allocator name.
+ */
+template <class T>
+ArenaHeapSTLAllocator<T, T>::ArenaHeapSTLAllocator
+ (size_t nblock /*= 1000*/, const std::string& name /*= ""*/)
+    : m_nblock (nblock),
+      m_name (name),
+      m_poolptr (0)
+{
+}
+
+
+/**
+ * @brief Constructor from another @c ArenaHeapSTLAllocator.
+ *
+ * The @c name and @c nblock parameters are copied, but the data are not.
+ */
+template <class T>
+template <class U, class V>
+ArenaHeapSTLAllocator<T, T>::ArenaHeapSTLAllocator
+  (const ArenaHeapSTLAllocator<U, V>& a)
+    : m_nblock (a.nblock()),
+      m_name (a.name()),
+      m_poolptr (a.poolptr())
+{
+}
+
+
+/**
+ * @brief Return the hinted number of objects allocated per block.
+ */
+template <class T>
+inline
+size_t ArenaHeapSTLAllocator<T, T>::nblock() const
+{
+  return m_nblock;
+}
+
+
+/**
+ * @brief Return the name of this allocator.
+ */
+template <class T>
+inline
+const std::string& ArenaHeapSTLAllocator<T, T>::name() const
+{
+  return m_name;
+}
+
+
+/**
+ * @brief Free all allocated elements.
+ *
+ * All elements allocated are returned to the free state.
+ * @c clear should be called on them if it was provided.
+ * The elements may continue to be cached internally, without
+ * returning to the system.
+ */
+template <class T>
+void ArenaHeapSTLAllocator<T, T>::reset()
+{
+  if (m_poolptr)
+    m_poolptr->reset();
+}
+
+
+/**
+ * @brief Free all allocated elements and release memory back to the system.
+ *
+ * All elements allocated are freed, and all allocated blocks of memory
+ * are released back to the system.
+ * @c destructor should be called on them if it was provided
+ * (preceded by @c clear if provided and @c mustClear was set).
+ */
+template <class T>
+void ArenaHeapSTLAllocator<T, T>::erase()
+{
+  if (m_poolptr)
+    m_poolptr->erase();
+}
+
+
+/**
+ * @brief Set the total number of elements cached by the allocator.
+ * @param size The desired pool size.
+ *
+ * This allows changing the number of elements that are currently free
+ * but cached.  Any allocated elements are not affected by this call.
+ *
+ * If @c size is greater than the total number of elements currently
+ * cached, then more will be allocated.  This will preferably done
+ * with a single block, but that is not guaranteed; in addition, the
+ * allocator may allocate more elements than is requested.
+ *
+ * If @c size is smaller than the total number of elements currently
+ * cached, as many blocks as possible will be released back to the system.
+ * It may not be possible to release the number of elements requested;
+ * this should be implemented on a best-effort basis.
+ */
+template <class T>
+void ArenaHeapSTLAllocator<T, T>::reserve (size_t size)
+{
+  if (m_poolptr)
+    m_poolptr->reserve (size);
+}
+
+
+/**
+ * @brief Return the statistics block for this allocator.
+ */
+template <class T>
+const ArenaAllocatorBase::Stats&
+ArenaHeapSTLAllocator<T, T>::stats() const
+{
+  if (m_poolptr)
+    return m_poolptr->stats();
+  static ArenaAllocatorBase::Stats tmp;
+  return tmp;
+}
+
+
+/**
+ * @brief Return a pointer to the underlying allocator (may be 0).
+ */
+template <class T>
+ArenaAllocatorBase* ArenaHeapSTLAllocator<T, T>::poolptr() const
+{
+  return m_poolptr;
+}
+
+
+} // namespace SG
diff --git a/Control/AthAllocators/AthAllocators/ArenaPoolAllocator.h b/Control/AthAllocators/AthAllocators/ArenaPoolAllocator.h
new file mode 100755
index 0000000000000000000000000000000000000000..be2743f3851dcecdb4b47173ead3bd9958132879
--- /dev/null
+++ b/Control/AthAllocators/AthAllocators/ArenaPoolAllocator.h
@@ -0,0 +1,256 @@
+// This file's extension implies that it's C, but it's really -*- C++ -*-.
+
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// $Id: ArenaPoolAllocator.h 470529 2011-11-24 23:54:22Z ssnyder $
+
+/**
+ * @file  AthAllocators/ArenaPoolAllocator.h
+ * @author scott snyder
+ * @date May 2007
+ * @brief Pool-based allocator.
+ *        See Arena.h for an overview of the arena-based memory allocators.
+ */
+
+#ifndef ATLALLOCATORS_ARENAPOOLALLOCATOR_H
+#define ATLALLOCATORS_ARENAPOOLALLOCATOR_H
+
+
+#include "AthAllocators/ArenaBlockAllocatorBase.h"
+#include "boost/iterator/iterator_adaptor.hpp"
+#include <cstdlib>
+
+
+namespace SG {
+
+
+class ArenaBlock;
+
+
+/**
+ * @brief Pool-based allocator.
+ *        See Arena.h for an overview of the arena-based memory allocators.
+ *
+ * This is a block-based memory allocator, with stack-like behavior
+ * (like the @c DataPool class).  We do not allow freeing individual
+ * elements; instead, we support @c resetTo(p), which frees @p and all
+ * elements allocated after it (in this allocator).  We also implement
+ * an iterator over the allocated blocks.
+ */
+class ArenaPoolAllocator
+  : public ArenaBlockAllocatorBase
+{
+public:
+  // Needed forward declaration.
+  class const_iterator;
+
+  /**
+   * @brief Non-const iterator for the pool.
+   *        It iterates over all allocated blocks (in unspecified order).
+   *
+   *        We use @c boost::iterator_adaptor, and take a @c pointer
+   *        as the base iterator type.  Besides that, we also need
+   *        to record the current block which we're within.
+   */
+  class iterator
+    : public boost::iterator_adaptor<
+    iterator,
+    pointer,
+    boost::use_default,
+    boost::forward_traversal_tag>
+  {
+  public:
+    /**
+     * @brief Default constructor.
+     */
+    iterator ();
+
+
+    /**
+     * @brief Constructor.
+     * @param p Pointer to the element.
+     * @param block Block containing the element.
+     */
+    iterator (pointer p, ArenaBlock* block);
+
+
+    // To allow initializing a @c const_iterator from an @c iterator.
+    friend class const_iterator;
+
+
+  private:
+    /// Block containing the current element.
+    ArenaBlock* m_block;
+
+    // Required by @c iterator_adaptor.
+    friend class boost::iterator_core_access;
+
+    /// Move the iterator forward.
+    void increment();
+  };
+
+
+  /**
+   * @brief Const iterator for the pool.
+   *        It iterates over all allocated blocks (in unspecified order).
+   *
+   *        We use @c boost::iterator_adaptor, and take a @c pointer
+   *        as the base iterator type.  Besides that, we also need
+   *        to record the current block which we're within.
+   */
+  class const_iterator
+    : public boost::iterator_adaptor<
+    const_iterator,
+    const_pointer,
+    boost::use_default,
+    boost::forward_traversal_tag>
+  {
+  public:
+    /**
+     * @brief Default constructor.
+     */
+    const_iterator ();
+
+
+    /**
+     * @brief Constructor.
+     * @param p Pointer to the element.
+     * @param block Block containing the element.
+     */
+    const_iterator (pointer p, ArenaBlock* block);
+
+
+    /**
+     * @brief Constructor from @c iterator.
+     * @param it The iterator to copy.
+     */
+    const_iterator (const iterator& it);
+                                           
+
+  private:
+    /// Block containing the current element.
+    ArenaBlock* m_block;
+
+    // Required by @c iterator_adaptor.
+    friend class boost::iterator_core_access;
+
+    /// Move the iterator forward.
+    void increment();
+  };
+
+
+  /**
+   * @brief Constructor.
+   * @param params The parameters structure for this allocator.
+   *               See @c  ArenaAllocatorBase.h for the contents.
+   */
+  ArenaPoolAllocator (const Params& params);
+
+ 
+  /**
+   * @brief Destructor.  This will free all the Allocator's storage.
+   */
+  ~ArenaPoolAllocator();
+
+
+  /**
+   * @brief Allocate a new element.
+   *
+   * The fast path of this will be completely inlined.
+   */
+  pointer allocate();
+
+
+  /**
+   * @brief Free all allocated elements.
+   *
+   * All elements allocated are returned to the free state.
+   * @c clear should be called on them if it was provided.
+   * The elements may continue to be cached internally, without
+   * returning to the system.
+   */
+  virtual void reset();
+
+
+  /**
+   * @brief Free all allocated elements and release memory back to the system.
+   *
+   * All elements allocated are freed, and all allocated blocks of memory
+   * are released back to the system.
+   * @c destructor should be called on them if it was provided
+   * (preceded by @c clear if provided and @c mustClear was set).
+   */
+  virtual void erase();
+
+
+  /**
+   * @brief Reset pool back to a previous state.
+   * @param p The pointer back to which to reset.
+   *
+   * This will free (a la @c reset) the element @c p and all elements
+   * that have been allocated after it from this allocator.
+   */
+  void resetTo (pointer p);
+
+
+  /**
+   * @brief Starting pool iterator.
+   *
+   * This will iterate over all allocated elements (in unspecified order).
+   * It is a @c forward_iterator.
+   */
+  iterator begin();
+
+
+  /**
+   * @brief Starting pool const iterator.
+   *
+   * This will iterate over all allocated elements (in unspecified order).
+   * It is a @c forward_iterator.
+   */
+  const_iterator begin() const;
+
+
+  /**
+   * @brief Ending pool iterator.
+   */
+  iterator end();
+
+
+  /**
+   * @brief Ending pool const iterator.
+   */
+  const_iterator end() const;
+
+
+private:
+  /**
+   * @brief Add more free elements to the pool.
+   */
+  void refill();
+
+
+  /**
+   * @brief Reset all elements in the topmost block, and move the block
+   *        to the free list.
+   */
+  void clearBlock();
+
+
+  /// Pointer to the next free element to allocate, or null.
+  pointer m_ptr;
+
+  /// One past the last available element in the current block, of null.
+  pointer m_end;
+};
+
+
+} // namespace SG
+
+
+#include "AthAllocators/ArenaPoolAllocator.icc"
+
+
+#endif // not ATLALLOCATORS_ARENABLOCK_H
diff --git a/Control/AthAllocators/AthAllocators/ArenaPoolAllocator.icc b/Control/AthAllocators/AthAllocators/ArenaPoolAllocator.icc
new file mode 100755
index 0000000000000000000000000000000000000000..ea333449f1178ba3ff81b1243e68bcfb4fa980b9
--- /dev/null
+++ b/Control/AthAllocators/AthAllocators/ArenaPoolAllocator.icc
@@ -0,0 +1,102 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// $Id: ArenaPoolAllocator.icc 470529 2011-11-24 23:54:22Z ssnyder $
+/**
+ * @file  AthAllocators/ArenaPoolAllocator.icc
+ * @author scott snyder
+ * @date May 2007
+ * @brief Pool-based allocator.
+ *        Inline implementations.
+ */
+
+
+namespace SG {
+
+
+/**
+ * @brief Default constructor.
+ */
+inline
+ArenaPoolAllocator::iterator::iterator()
+  : iterator::iterator_adaptor_ (0),
+    m_block (0)
+{
+}
+
+
+/**
+ * @brief Constructor.
+ * @param p Pointer to the element.
+ * @param block Block containing the element.
+ */
+inline
+ArenaPoolAllocator::iterator::iterator (pointer p, ArenaBlock* block)
+  : iterator::iterator_adaptor_ (p),
+    m_block (block)
+{
+}
+
+
+/**
+ * @brief Default constructor.
+ */
+inline
+ArenaPoolAllocator::const_iterator::const_iterator ()
+  : const_iterator::iterator_adaptor_ (0),
+    m_block (0)
+{
+}
+
+
+/**
+ * @brief Constructor.
+ * @param p Pointer to the element.
+ * @param block Block containing the element.
+ */
+inline
+ArenaPoolAllocator::const_iterator::const_iterator (pointer p,
+                                                    ArenaBlock* block)
+  : const_iterator::iterator_adaptor_ (p),
+    m_block (block)
+{
+}
+
+
+/**
+ * @brief Constructor from @c iterator.
+ * @param it The iterator to copy.
+ */
+inline
+ArenaPoolAllocator::const_iterator::const_iterator (const iterator& it)
+  : const_iterator::iterator_adaptor_ (it.base_reference()),
+    m_block (it.m_block)
+{
+}
+
+
+/**
+ * @brief Allocate a new element.
+ *
+ * The fast path of this will be completely inlined.
+ */
+inline
+ArenaPoolAllocator::pointer ArenaPoolAllocator::allocate()
+{
+  // If there are no free elements get more.
+  if (m_ptr >= m_end)
+    refill();
+
+  // Take the first free element.
+  pointer ret = m_ptr;
+  m_ptr = m_ptr + m_params.eltSize;
+
+  // Update statistics.
+  ++m_stats.elts.inuse;
+
+  return ret;
+}
+
+
+} // namespace SG
diff --git a/Control/AthAllocators/AthAllocators/ArenaPoolSTLAllocator.h b/Control/AthAllocators/AthAllocators/ArenaPoolSTLAllocator.h
new file mode 100644
index 0000000000000000000000000000000000000000..5cbff761bdba837187de51a827ee2a29f462993e
--- /dev/null
+++ b/Control/AthAllocators/AthAllocators/ArenaPoolSTLAllocator.h
@@ -0,0 +1,532 @@
+// This file's extension implies that it's C, but it's really -*- C++ -*-.
+
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// $Id: ArenaPoolSTLAllocator.h,v 1.2 2008-08-26 02:12:26 ssnyder Exp $
+
+/**
+ * @file  AthAllocators/ArenaPoolSTLAllocator.h
+ * @author scott snyder
+ * @date Jul 2008
+ * @brief STL-style allocator wrapper for @c ArenaPoolAllocator.
+ *
+ * This class defines a STL-style allocator for types @c T with the
+ * following special properties.
+ *
+ *  - For non-pointer @c T's, we use an @c ArenaPoolAllocator.
+ *    For pointer @c T's, we use the standard STL allocator.
+ *    STL @c pair<> types will also use the standard STL allocator.
+ *    Further comments below apply to the first case.
+ *  - The memory is owned directly by the allocator object.
+ *  - Only one object at a time may be allocated.
+ *  - Deallocate doesn't do anything.  The only way to release
+ *    the memory is to delete the allocator.
+ *
+ * So, this allocator is suitable for an STL container which allocates
+ * lots of fixed-size objects, where the usage pattern is to fill the
+ * container up, use it for a while, then delete the container.
+ * (The particular scenario that inspired this was the map for
+ * @c NavigationToken.)
+ *
+ * Much of the complexity here is due to the fact that the allocator
+ * type that gets passed to the container is an allocator for the
+ * container's value_type, but that allocator is not actually
+ * used to allocate memory.  Instead, an allocator for the internal
+ * node type is used.  This makes it awkward if you want to have
+ * allocators that store state.  We also need to support hash tables,
+ * which make two types of allocation.  Nodes are fixed-size and
+ * are allocated individually, while the hash table is variable-sized
+ * and is of pointer type.
+ *
+ * Further, to avoid creating a pool for the allocator for the container's
+ * value_type (when the container doesn't actually use that for allocation),
+ * this template has a second argument.  This defaults to the first argument,
+ * but is passed through by rebind.  If the first and second argument
+ * are the same, then we don't create a pool.
+ *
+ * The effect of all this is that you can give an allocator type like
+ *   ArenaPoolSTLAllocator<Mytype>
+ * to a STL container.  Allocators for Mytype and Mytype* won't use
+ * a pool, but an allocator for node<Mytype> will use the pool.
+ */
+
+
+#ifndef ATLALLOCATORS_ARENAPOOLSTLALLOCATOR
+#define ATLALLOCATORS_ARENAPOOLSTLALLOCATOR
+
+
+#include "AthAllocators/ArenaPoolAllocator.h"
+#include <string>
+
+
+namespace SG {
+
+
+/**
+ * @brief Initializer for pool allocator parameters.
+ *
+ *        We override the defaults to disable calling the payload ctor/dtor.
+ */
+template <class T>
+class ArenaPoolSTLAllocator_initParams
+  : public ArenaAllocatorBase::initParams<T, false, true, true>
+{
+public:
+  /// We take defaults from this.
+  typedef ArenaAllocatorBase::initParams<T, false, true, true> Base;
+
+    /**
+     * @brief Constructor.
+     * @param nblock Value to set in the parameters structure for the
+     *               number of elements to allocate per block.
+     * @param name   Value to set in the parameters structure for the
+     *               allocator name.
+     */
+    ArenaPoolSTLAllocator_initParams (size_t nblock = 1000,
+                                      const std::string& name = "");
+
+    /// Return an initialized parameters structure.
+    ArenaAllocatorBase::Params params() const;
+
+    /// Return an initialized parameters structure.
+    // Note: gcc 3.2.3 doesn't allow defining this out-of-line.
+    operator ArenaAllocatorBase::Params() const { return params(); }
+};
+
+
+/**
+ * @brief STL-style allocator wrapper for @c ArenaPoolAllocator.
+ *        This is the generic specialization, which uses the pool allocator.
+ *
+ * See the file-level comments for details.
+ */
+template <class T, class VETO=T>
+class ArenaPoolSTLAllocator
+{
+public:
+  /// Standard STL allocator typedefs.
+  typedef T*        pointer;
+  typedef const T*  const_pointer;
+  typedef T&        reference;
+  typedef const T&  const_reference;
+  typedef T         value_type;
+  typedef size_t    size_type;
+  typedef ptrdiff_t difference_type;
+
+
+  /// Standard STL allocator rebinder.
+  template <class U> struct rebind {
+    typedef ArenaPoolSTLAllocator<U, VETO> other;
+  };
+
+
+  /**
+   * @brief Default constructor.
+   * @param nblock Value to set in the parameters structure for the
+   *               number of elements to allocate per block.
+   * @param name   Value to set in the parameters structure for the
+   *               allocator name.
+   */
+  ArenaPoolSTLAllocator (size_t nblock = 1000, const std::string& name = "");
+
+
+  /**
+   * @brief Constructor from another @c ArenaPoolSTLAllocator.
+   *
+   * The @c name and @c nblock parameters are copied, but the data are not.
+   */
+  template <class U, class V>
+  ArenaPoolSTLAllocator (const ArenaPoolSTLAllocator<U, V>& a);
+
+  // We don't bother to supply a more general constructor --- shouldn't
+  // be needed.
+
+
+  /// Convert a reference to an address.
+  pointer address (reference x) const;
+  const_pointer address (const_reference x) const;
+
+
+  /**
+   * @brief Allocate new objects.
+   * @param n Number of objects to allocate.  Must be 1.
+   * @param hint Allocation hint.  Not used.
+   */
+  pointer allocate (size_type n, const void* hint = 0);
+
+
+  /**
+   * @brief Deallocate objects.
+   * @param n Number of objects to deallocate.  Must be 1.
+   *
+   * This implementation doesn't do anything.
+   */
+  void deallocate (pointer, size_type n);
+
+
+  /**
+   * @brief Return the maximum number of objects we can allocate at once.
+   *
+   * This always returns 1.
+   */
+  size_type max_size() const throw();
+
+
+  /**
+   * @brief Call the @c T constructor.
+   * @param p Location of the memory.
+   * @param val Parameter to pass to the constructor.
+   */
+  void construct (pointer p, const T& val);
+
+
+  /**
+   * @brief Call the @c T destructor.
+   * @param p Location of the memory.
+   */
+  void destroy (pointer p);
+
+
+  /**
+   * @brief Return the hinted number of objects allocated per block.
+   */
+  size_t nblock() const;
+
+
+  /**
+   * @brief Return the name of this allocator.
+   */
+  const std::string& name() const;
+
+
+  /**
+   * @brief Free all allocated elements.
+   *
+   * All elements allocated are returned to the free state.
+   * @c clear should be called on them if it was provided.
+   * The elements may continue to be cached internally, without
+   * returning to the system.
+   */
+  void reset();
+
+
+  /**
+   * @brief Free all allocated elements and release memory back to the system.
+   *
+   * All elements allocated are freed, and all allocated blocks of memory
+   * are released back to the system.
+   * @c destructor should be called on them if it was provided
+   * (preceded by @c clear if provided and @c mustClear was set).
+   */
+  void erase();
+
+
+  /**
+   * @brief Set the total number of elements cached by the allocator.
+   * @param size The desired pool size.
+   *
+   * This allows changing the number of elements that are currently free
+   * but cached.  Any allocated elements are not affected by this call.
+   *
+   * If @c size is greater than the total number of elements currently
+   * cached, then more will be allocated.  This will preferably done
+   * with a single block, but that is not guaranteed; in addition, the
+   * allocator may allocate more elements than is requested.
+   *
+   * If @c size is smaller than the total number of elements currently
+   * cached, as many blocks as possible will be released back to the system.
+   * It may not be possible to release the number of elements requested;
+   * this should be implemented on a best-effort basis.
+   */
+  void reserve (size_t size);
+
+
+  /**
+   * @brief Return the statistics block for this allocator.
+   */
+  const ArenaAllocatorBase::Stats& stats() const;
+
+
+  /**
+   * @brief Return a pointer to the underlying allocator (may be 0).
+   */
+  ArenaAllocatorBase* poolptr() const;
+
+
+private:
+  /// The underlying allocator.
+  ArenaPoolAllocator m_pool;
+};
+
+
+
+/**
+ * @brief STL-style allocator wrapper for @c ArenaPoolAllocator.
+ *        This is the specialization for pointers, which uses
+ *        the standard STL allocator.
+ *
+ * See the file-level comments for details.
+ */
+template <class T, class VETO>
+class ArenaPoolSTLAllocator<T*, VETO>
+  : public std::allocator<T*>
+{
+public:
+  typedef std::allocator<T*> base;
+
+  /// Standard STL allocator typedefs.
+  typedef typename base::pointer         pointer;
+  typedef typename base::const_pointer   const_pointer;
+  typedef typename base::reference       reference;
+  typedef typename base::const_reference const_reference;
+  typedef typename base::value_type      value_type;
+  typedef typename base::size_type       size_type;
+  typedef typename base::difference_type difference_type;
+
+
+  /// Standard STL allocator rebinder.
+  template <class U> struct rebind {
+    typedef ArenaPoolSTLAllocator<U, VETO> other;
+  };
+
+
+  /**
+   * @brief Default constructor.
+   * @param nblock Value to set in the parameters structure for the
+   *               number of elements to allocate per block.
+   * @param name   Value to set in the parameters structure for the
+   *               allocator name.
+   */
+  ArenaPoolSTLAllocator (size_t nblock = 1000, const std::string& name = "");
+
+
+  /**
+   * @brief Constructor from another @c ArenaPoolSTLAllocator.
+   *
+   * The @c name and @c nblock parameters are copied, but the data are not.
+   */
+  template <class U, class V>
+  ArenaPoolSTLAllocator (const ArenaPoolSTLAllocator<U, V>& a);
+
+
+  // We don't bother to supply a more general constructor --- shouldn't
+  // be needed.
+
+
+  /**
+   * @brief Return the hinted number of objects allocated per block.
+   */
+  size_t nblock() const;
+
+
+  /**
+   * @brief Return the name of this allocator.
+   */
+  const std::string& name() const;
+
+
+  /**
+   * @brief Free all allocated elements.
+   *
+   * All elements allocated are returned to the free state.
+   * @c clear should be called on them if it was provided.
+   * The elements may continue to be cached internally, without
+   * returning to the system.
+   */
+  void reset();
+
+
+  /**
+   * @brief Free all allocated elements and release memory back to the system.
+   *
+   * All elements allocated are freed, and all allocated blocks of memory
+   * are released back to the system.
+   * @c destructor should be called on them if it was provided
+   * (preceded by @c clear if provided and @c mustClear was set).
+   */
+  void erase();
+
+
+  /**
+   * @brief Set the total number of elements cached by the allocator.
+   * @param size The desired pool size.
+   *
+   * This allows changing the number of elements that are currently free
+   * but cached.  Any allocated elements are not affected by this call.
+   *
+   * If @c size is greater than the total number of elements currently
+   * cached, then more will be allocated.  This will preferably done
+   * with a single block, but that is not guaranteed; in addition, the
+   * allocator may allocate more elements than is requested.
+   *
+   * If @c size is smaller than the total number of elements currently
+   * cached, as many blocks as possible will be released back to the system.
+   * It may not be possible to release the number of elements requested;
+   * this should be implemented on a best-effort basis.
+   */
+  void reserve (size_t size);
+
+
+  /**
+   * @brief Return the statistics block for this allocator.
+   */
+  const ArenaAllocatorBase::Stats& stats() const;
+
+
+  /**
+   * @brief Return a pointer to the underlying allocator (may be 0).
+   */
+  ArenaAllocatorBase* poolptr() const;
+
+
+private:
+  /// Saved hinted number of objects per block.
+  size_t m_nblock;
+
+  /// Saved allocator name.
+  std::string m_name;
+
+  /// Point at an underlying allocator from a different specialization.
+  ArenaAllocatorBase* m_poolptr;
+};
+
+
+/**
+ * @brief STL-style allocator wrapper for @c ArenaPoolAllocator.
+ *        This is the specialization for the case of the vetoed type.
+ *
+ * See the file-level comments for details.
+ */
+template <class T>
+class ArenaPoolSTLAllocator<T, T>
+  : public std::allocator<T>
+{
+public:
+  typedef std::allocator<T> base;
+
+  /// Standard STL allocator typedefs.
+  typedef typename base::pointer         pointer;
+  typedef typename base::const_pointer   const_pointer;
+  typedef typename base::reference       reference;
+  typedef typename base::const_reference const_reference;
+  typedef typename base::value_type      value_type;
+  typedef typename base::size_type       size_type;
+  typedef typename base::difference_type difference_type;
+
+
+  /// Standard STL allocator rebinder.
+  template <class U> struct rebind {
+    typedef ArenaPoolSTLAllocator<U, T> other;
+  };
+
+
+  /**
+   * @brief Default constructor.
+   * @param nblock Value to set in the parameters structure for the
+   *               number of elements to allocate per block.
+   * @param name   Value to set in the parameters structure for the
+   *               allocator name.
+   */
+  ArenaPoolSTLAllocator (size_t nblock = 1000, const std::string& name = "");
+
+
+  /**
+   * @brief Constructor from another @c ArenaPoolSTLAllocator.
+   *
+   * The @c name and @c nblock parameters are copied, but the data are not.
+   */
+  template <class U, class V>
+  ArenaPoolSTLAllocator (const ArenaPoolSTLAllocator<U, V>& a);
+
+
+  // We don't bother to supply a more general constructor --- shouldn't
+  // be needed.
+
+
+  /**
+   * @brief Return the hinted number of objects allocated per block.
+   */
+  size_t nblock() const;
+
+
+  /**
+   * @brief Return the name of this allocator.
+   */
+  const std::string& name() const;
+
+
+  /**
+   * @brief Free all allocated elements.
+   *
+   * All elements allocated are returned to the free state.
+   * @c clear should be called on them if it was provided.
+   * The elements may continue to be cached internally, without
+   * returning to the system.
+   */
+  void reset();
+
+
+  /**
+   * @brief Free all allocated elements and release memory back to the system.
+   *
+   * All elements allocated are freed, and all allocated blocks of memory
+   * are released back to the system.
+   * @c destructor should be called on them if it was provided
+   * (preceded by @c clear if provided and @c mustClear was set).
+   */
+  void erase();
+
+
+  /**
+   * @brief Set the total number of elements cached by the allocator.
+   * @param size The desired pool size.
+   *
+   * This allows changing the number of elements that are currently free
+   * but cached.  Any allocated elements are not affected by this call.
+   *
+   * If @c size is greater than the total number of elements currently
+   * cached, then more will be allocated.  This will preferably done
+   * with a single block, but that is not guaranteed; in addition, the
+   * allocator may allocate more elements than is requested.
+   *
+   * If @c size is smaller than the total number of elements currently
+   * cached, as many blocks as possible will be released back to the system.
+   * It may not be possible to release the number of elements requested;
+   * this should be implemented on a best-effort basis.
+   */
+  void reserve (size_t size);
+
+
+  /**
+   * @brief Return the statistics block for this allocator.
+   */
+  const ArenaAllocatorBase::Stats& stats() const;
+
+
+  /**
+   * @brief Return a pointer to the underlying allocator (may be 0).
+   */
+  ArenaAllocatorBase* poolptr() const;
+
+
+private:
+  /// Saved hinted number of objects per block.
+  size_t m_nblock;
+
+  /// Saved allocator name.
+  std::string m_name;
+
+  /// Point at an underlying allocator from a different specialization.
+  ArenaAllocatorBase* m_poolptr;
+};
+
+
+} // namespace SG
+
+
+#include "AthAllocators/ArenaPoolSTLAllocator.icc"
+
+
+#endif // ATLALLOCATORS_ARENAPOOLSTLALLOCATOR
diff --git a/Control/AthAllocators/AthAllocators/ArenaPoolSTLAllocator.icc b/Control/AthAllocators/AthAllocators/ArenaPoolSTLAllocator.icc
new file mode 100644
index 0000000000000000000000000000000000000000..1fe2420b4261881a00489e817f27147cb54f1e19
--- /dev/null
+++ b/Control/AthAllocators/AthAllocators/ArenaPoolSTLAllocator.icc
@@ -0,0 +1,567 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// $Id: ArenaPoolSTLAllocator.icc,v 1.2 2008-08-26 02:12:26 ssnyder Exp $
+/**
+ * @file  AthAllocators/ArenaPoolSTLAllocator.icc
+ * @author scott snyder
+ * @date Jul 2008
+ * @brief STL-style allocator wrapper for @c ArenaPoolAllocator.
+ */
+
+
+#include <cassert>
+
+
+namespace SG {
+
+
+
+//****************************************************************************
+// Generic specialization
+//
+
+
+/**
+ * @brief Constructor.
+ * @param nblock Value to set in the parameters structure for the
+ *               number of elements to allocate per block.
+ * @param name   Value to set in the parameters structure for the
+ *               allocator name.
+ */
+template <class T>
+ArenaPoolSTLAllocator_initParams<T>::ArenaPoolSTLAllocator_initParams
+ (size_t nblock /*= 1000*/, const std::string& name /*= ""*/)
+   : Base (nblock, name)
+{
+}
+
+
+/**
+ * @brief Return an initialized parameters structure.
+ */
+template <class T>
+ArenaAllocatorBase::Params ArenaPoolSTLAllocator_initParams<T>::params() const
+{
+  // Do the base class stuff.
+  ArenaAllocatorBase::Params p =
+    Base::operator ArenaAllocatorBase::Params();
+
+  // Disable ctor/dtor.
+  p.constructor = 0;
+  p.destructor = 0;
+
+  return p;
+}
+
+
+/**
+ * @brief Default constructor.
+ * @param nblock Value to set in the parameters structure for the
+ *               number of elements to allocate per block.
+ * @param name   Value to set in the parameters structure for the
+ *               allocator name.
+ */
+template <class T, class VETO>
+ArenaPoolSTLAllocator<T, VETO>::ArenaPoolSTLAllocator
+ (size_t nblock /*= 1000*/, const std::string& name /*= ""*/)
+   : m_pool (ArenaPoolSTLAllocator_initParams<T> (nblock, name))
+{
+}
+
+
+/**
+ * @brief Constructor from another @c ArenaPoolSTLAllocator.
+ *
+ * The @c name and @c nblock parameters are copied, but the data are not.
+ */
+template <class T, class VETO>
+template <class U, class V>
+ArenaPoolSTLAllocator<T, VETO>::ArenaPoolSTLAllocator
+  (const ArenaPoolSTLAllocator<U, V>& a)
+    : m_pool (ArenaPoolSTLAllocator_initParams<T> (a.nblock(), a.name()))
+{
+}
+
+
+/**
+ * @brief Convert a reference to an address.
+ */
+template <class T, class VETO>
+inline
+typename ArenaPoolSTLAllocator<T, VETO>::pointer
+ArenaPoolSTLAllocator<T, VETO>::address (reference x) const
+{
+  return &x;
+}
+
+
+/**
+ * @brief Convert a reference to an address.
+ */
+template <class T, class VETO>
+inline
+typename ArenaPoolSTLAllocator<T, VETO>::const_pointer
+ArenaPoolSTLAllocator<T, VETO>::address (const_reference x) const
+{
+  return &x;
+}
+
+
+
+/**
+ * @brief Allocate new objects.
+ * @param n Number of objects to allocate.  Must be 1.
+ * @param hint Allocation hint.  Not used.
+ */
+template <class T, class VETO>
+inline
+typename ArenaPoolSTLAllocator<T, VETO>::pointer
+ArenaPoolSTLAllocator<T, VETO>::allocate (size_type
+#ifndef NDEBUG
+                      n
+#endif
+                      , const void* /*hint = 0*/)
+{
+  assert (n == 1);
+  return reinterpret_cast<pointer> (m_pool.allocate());
+}
+
+
+/**
+ * @brief Deallocate objects.
+ * @param n Number of objects to deallocate.  Must be 1.
+ *
+ * This implementation doesn't do anything.
+ */
+template <class T, class VETO>
+inline
+void ArenaPoolSTLAllocator<T, VETO>::deallocate (pointer, size_type 
+#ifndef NDEBUG
+                             n
+#endif
+                             )
+{
+  assert (n == 1);
+}
+
+
+/**
+ * @brief Return the maximum number of objects we can allocate at once.
+ *
+ * This always returns 1.
+ */
+template <class T, class VETO>
+inline
+typename ArenaPoolSTLAllocator<T, VETO>::size_type
+ArenaPoolSTLAllocator<T, VETO>::max_size() const throw() 
+{
+  return 1;
+}
+
+
+/**
+ * @brief Call the @c T constructor.
+ * @param p Location of the memory.
+ * @param val Parameter to pass to the constructor.
+ */
+template <class T, class VETO>
+inline
+void ArenaPoolSTLAllocator<T, VETO>::construct (pointer p, const T& val)
+{
+  new (reinterpret_cast<void*>(p)) T(val);
+}
+
+
+/**
+ * @brief Call the @c T destructor.
+ * @param p Location of the memory.
+ */
+template <class T, class VETO>
+inline
+void ArenaPoolSTLAllocator<T, VETO>::destroy (pointer p)
+{
+  p->~T();
+}
+
+
+/**
+ * @brief Return the hinted number of objects allocated per block.
+ */
+template <class T, class VETO>
+inline
+size_t ArenaPoolSTLAllocator<T, VETO>::nblock() const
+{
+  return m_pool.params().nblock;
+}
+
+
+/**
+ * @brief Return the name of this allocator.
+ */
+template <class T, class VETO>
+inline
+const std::string& ArenaPoolSTLAllocator<T, VETO>::name() const
+{
+  return m_pool.name();
+}
+
+
+/**
+ * @brief Free all allocated elements.
+ *
+ * All elements allocated are returned to the free state.
+ * @c clear should be called on them if it was provided.
+ * The elements may continue to be cached internally, without
+ * returning to the system.
+ */
+template <class T, class VETO>
+void ArenaPoolSTLAllocator<T, VETO>::reset()
+{
+  m_pool.reset();
+}
+
+
+/**
+ * @brief Free all allocated elements and release memory back to the system.
+ *
+ * All elements allocated are freed, and all allocated blocks of memory
+ * are released back to the system.
+ * @c destructor should be called on them if it was provided
+ * (preceded by @c clear if provided and @c mustClear was set).
+ */
+template <class T, class VETO>
+void ArenaPoolSTLAllocator<T, VETO>::erase()
+{
+  m_pool.erase();
+}
+
+
+/**
+ * @brief Set the total number of elements cached by the allocator.
+ * @param size The desired pool size.
+ *
+ * This allows changing the number of elements that are currently free
+ * but cached.  Any allocated elements are not affected by this call.
+ *
+ * If @c size is greater than the total number of elements currently
+ * cached, then more will be allocated.  This will preferably done
+ * with a single block, but that is not guaranteed; in addition, the
+ * allocator may allocate more elements than is requested.
+ *
+ * If @c size is smaller than the total number of elements currently
+ * cached, as many blocks as possible will be released back to the system.
+ * It may not be possible to release the number of elements requested;
+ * this should be implemented on a best-effort basis.
+ */
+template <class T, class VETO>
+void ArenaPoolSTLAllocator<T, VETO>::reserve (size_t size)
+{
+  m_pool.reserve (size);
+}
+
+
+/**
+ * @brief Return the statistics block for this allocator.
+ */
+template <class T, class VETO>
+const ArenaAllocatorBase::Stats& ArenaPoolSTLAllocator<T, VETO>::stats() const
+{
+  return m_pool.stats();
+}
+
+
+/**
+ * @brief Return a pointer to the underlying allocator (may be 0).
+ */
+template <class T, class VETO>
+ArenaAllocatorBase* ArenaPoolSTLAllocator<T, VETO>::poolptr() const
+{
+  const ArenaAllocatorBase* tmp = &m_pool;
+  return const_cast<ArenaAllocatorBase*> (tmp);
+}
+
+
+//****************************************************************************
+// Pointer specialization.
+//
+
+
+/**
+ * @brief Default constructor.
+ * @param nblock Value to set in the parameters structure for the
+ *               number of elements to allocate per block.
+ * @param name   Value to set in the parameters structure for the
+ *               allocator name.
+ */
+template <class T, class VETO>
+ArenaPoolSTLAllocator<T*, VETO>::ArenaPoolSTLAllocator
+  (size_t nblock /*= 1000*/, const std::string& name /*= ""*/)
+    : m_nblock (nblock),
+      m_name (name),
+      m_poolptr (0)
+{
+}
+
+
+/**
+ * @brief Constructor from another @c ArenaPoolSTLAllocator.
+ *
+ * The @c name and @c nblock parameters are copied, but the data are not.
+ */
+template <class T, class VETO>
+template <class U, class V>
+ArenaPoolSTLAllocator<T*, VETO>::ArenaPoolSTLAllocator
+  (const ArenaPoolSTLAllocator<U, V>& a)
+    : m_nblock (a.nblock()),
+      m_name (a.name()),
+      m_poolptr (a.poolptr())
+{
+}
+
+
+/**
+ * @brief Return the hinted number of objects allocated per block.
+ */
+template <class T, class VETO>
+inline
+size_t ArenaPoolSTLAllocator<T*, VETO>::nblock() const
+{
+  return m_nblock;
+}
+
+
+/**
+ * @brief Return the name of this allocator.
+ */
+template <class T, class VETO>
+inline
+const std::string& ArenaPoolSTLAllocator<T*, VETO>::name() const
+{
+  return m_name;
+}
+
+
+/**
+ * @brief Free all allocated elements.
+ *
+ * All elements allocated are returned to the free state.
+ * @c clear should be called on them if it was provided.
+ * The elements may continue to be cached internally, without
+ * returning to the system.
+ */
+template <class T, class VETO>
+void ArenaPoolSTLAllocator<T*, VETO>::reset()
+{
+  if (m_poolptr)
+    m_poolptr->reset();
+}
+
+
+/**
+ * @brief Free all allocated elements and release memory back to the system.
+ *
+ * All elements allocated are freed, and all allocated blocks of memory
+ * are released back to the system.
+ * @c destructor should be called on them if it was provided
+ * (preceded by @c clear if provided and @c mustClear was set).
+ */
+template <class T, class VETO>
+void ArenaPoolSTLAllocator<T*, VETO>::erase()
+{
+  if (m_poolptr)
+    m_poolptr->erase();
+}
+
+
+/**
+ * @brief Set the total number of elements cached by the allocator.
+ * @param size The desired pool size.
+ *
+ * This allows changing the number of elements that are currently free
+ * but cached.  Any allocated elements are not affected by this call.
+ *
+ * If @c size is greater than the total number of elements currently
+ * cached, then more will be allocated.  This will preferably done
+ * with a single block, but that is not guaranteed; in addition, the
+ * allocator may allocate more elements than is requested.
+ *
+ * If @c size is smaller than the total number of elements currently
+ * cached, as many blocks as possible will be released back to the system.
+ * It may not be possible to release the number of elements requested;
+ * this should be implemented on a best-effort basis.
+ */
+template <class T, class VETO>
+void ArenaPoolSTLAllocator<T*, VETO>::reserve (size_t size)
+{
+  if (m_poolptr)
+    m_poolptr->reserve (size);
+}
+
+
+/**
+ * @brief Return the statistics block for this allocator.
+ */
+template <class T, class VETO>
+const ArenaAllocatorBase::Stats& ArenaPoolSTLAllocator<T*, VETO>::stats() const
+{
+  if (m_poolptr)
+    return m_poolptr->stats();
+  static ArenaAllocatorBase::Stats tmp;
+  return tmp;
+}
+
+
+/**
+ * @brief Return a pointer to the underlying allocator (may be 0).
+ */
+template <class T, class VETO>
+ArenaAllocatorBase* ArenaPoolSTLAllocator<T*, VETO>::poolptr() const
+{
+  return m_poolptr;
+}
+
+
+//****************************************************************************
+// Vetoed specialization.
+//
+
+
+/**
+ * @brief Default constructor.
+ * @param nblock Value to set in the parameters structure for the
+ *               number of elements to allocate per block.
+ * @param name   Value to set in the parameters structure for the
+ *               allocator name.
+ */
+template <class T>
+ArenaPoolSTLAllocator<T, T>::ArenaPoolSTLAllocator
+ (size_t nblock /*= 1000*/, const std::string& name /*= ""*/)
+    : m_nblock (nblock),
+      m_name (name),
+      m_poolptr (0)
+{
+}
+
+
+/**
+ * @brief Constructor from another @c ArenaPoolSTLAllocator.
+ *
+ * The @c name and @c nblock parameters are copied, but the data are not.
+ */
+template <class T>
+template <class U, class V>
+ArenaPoolSTLAllocator<T, T>::ArenaPoolSTLAllocator
+  (const ArenaPoolSTLAllocator<U, V>& a)
+    : m_nblock (a.nblock()),
+      m_name (a.name()),
+      m_poolptr (a.poolptr())
+{
+}
+
+
+/**
+ * @brief Return the hinted number of objects allocated per block.
+ */
+template <class T>
+inline
+size_t ArenaPoolSTLAllocator<T, T>::nblock() const
+{
+  return m_nblock;
+}
+
+
+/**
+ * @brief Return the name of this allocator.
+ */
+template <class T>
+inline
+const std::string& ArenaPoolSTLAllocator<T, T>::name() const
+{
+  return m_name;
+}
+
+
+/**
+ * @brief Free all allocated elements.
+ *
+ * All elements allocated are returned to the free state.
+ * @c clear should be called on them if it was provided.
+ * The elements may continue to be cached internally, without
+ * returning to the system.
+ */
+template <class T>
+void ArenaPoolSTLAllocator<T, T>::reset()
+{
+  if (m_poolptr)
+    m_poolptr->reset();
+}
+
+
+/**
+ * @brief Free all allocated elements and release memory back to the system.
+ *
+ * All elements allocated are freed, and all allocated blocks of memory
+ * are released back to the system.
+ * @c destructor should be called on them if it was provided
+ * (preceded by @c clear if provided and @c mustClear was set).
+ */
+template <class T>
+void ArenaPoolSTLAllocator<T, T>::erase()
+{
+  if (m_poolptr)
+    m_poolptr->erase();
+}
+
+
+/**
+ * @brief Set the total number of elements cached by the allocator.
+ * @param size The desired pool size.
+ *
+ * This allows changing the number of elements that are currently free
+ * but cached.  Any allocated elements are not affected by this call.
+ *
+ * If @c size is greater than the total number of elements currently
+ * cached, then more will be allocated.  This will preferably done
+ * with a single block, but that is not guaranteed; in addition, the
+ * allocator may allocate more elements than is requested.
+ *
+ * If @c size is smaller than the total number of elements currently
+ * cached, as many blocks as possible will be released back to the system.
+ * It may not be possible to release the number of elements requested;
+ * this should be implemented on a best-effort basis.
+ */
+template <class T>
+void ArenaPoolSTLAllocator<T, T>::reserve (size_t size)
+{
+  if (m_poolptr)
+    m_poolptr->reserve (size);
+}
+
+
+/**
+ * @brief Return the statistics block for this allocator.
+ */
+template <class T>
+const ArenaAllocatorBase::Stats&
+ArenaPoolSTLAllocator<T, T>::stats() const
+{
+  if (m_poolptr)
+    return m_poolptr->stats();
+  static ArenaAllocatorBase::Stats tmp;
+  return tmp;
+}
+
+
+/**
+ * @brief Return a pointer to the underlying allocator (may be 0).
+ */
+template <class T>
+ArenaAllocatorBase* ArenaPoolSTLAllocator<T, T>::poolptr() const
+{
+  return m_poolptr;
+}
+
+
+} // namespace SG
diff --git a/Control/AthAllocators/AthAllocators/ArenaSTLAllocator.h b/Control/AthAllocators/AthAllocators/ArenaSTLAllocator.h
new file mode 100644
index 0000000000000000000000000000000000000000..879f0eeaf620f631d7487b4cfa96b565f7edfc1d
--- /dev/null
+++ b/Control/AthAllocators/AthAllocators/ArenaSTLAllocator.h
@@ -0,0 +1,89 @@
+// This file's extension implies that it's C, but it's really -*- C++ -*-.
+
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// $Id: ArenaSTLAllocator.h 470825 2011-11-25 23:20:57Z ssnyder $
+/**
+ * @file AthAllocators/ArenaSTLAllocator.h
+ * @author scott snyder <snyder@bnl.gov>
+ * @date Nov, 2011
+ * @brief 
+ */
+
+
+#ifndef ATLALLOCATORS_ARENASTLALLOCATOR_H
+#define ATLALLOCATORS_ARENASTLALLOCATOR_H
+
+
+#include <string>
+#include <cstdlib>
+
+
+namespace SG {
+
+
+template <class BASE>
+class ArenaSTLAllocator
+  : public BASE
+{
+public:
+  /// Standard STL allocator typedefs.
+  typedef typename BASE::value_type value_type;
+  typedef value_type*               pointer;
+  typedef const value_type*         const_pointer;
+  typedef value_type&               reference;
+  typedef const value_type&         const_reference;
+  typedef size_t                    size_type;
+  typedef std::ptrdiff_t            difference_type;
+
+
+
+  /// Standard STL allocator rebinder.
+  template <class U> struct rebind {
+    typedef ArenaSTLAllocator<U> other;
+  };
+
+
+  /**
+   * @brief Default constructor.
+   * @param nblock Value to set in the parameters structure for the
+   *               number of elements to allocate per block.
+   * @param name   Value to use as the base for the allocator names.
+   */
+  ArenaSTLAllocator (size_t nblock = 1000,
+                     const std::string& name = "");
+
+
+  /**
+   * @brief Constructor from another @c ArenaSTLAllocator.
+   *
+   * The new STL allocator will reference the same set of underlying
+   * Arena allocators as the old one.
+   */
+  ArenaSTLAllocator (const ArenaSTLAllocator& a);
+
+
+  /**
+   * @brief Constructor from another @c ArenaSTLAllocator.
+   *
+   * The new STL allocator will reference the same set of underlying
+   * Arena allocators as the old one.
+   */
+  template <class U>
+  ArenaSTLAllocator (const ArenaSTLAllocator<U>& a);
+
+  // We don't bother to supply a more general constructor --- shouldn't
+  // be needed.
+
+};
+
+
+} // namespace SG
+
+
+
+#include "AthAllocators/ArenaSTLAllocator.icc"
+
+#endif // not ATLALLOCATORS_ARENASTLALLOCATOR_H
diff --git a/Control/AthAllocators/AthAllocators/ArenaSTLAllocator.icc b/Control/AthAllocators/AthAllocators/ArenaSTLAllocator.icc
new file mode 100644
index 0000000000000000000000000000000000000000..e056f0d9eededc8f5653fac80af91d389e066afa
--- /dev/null
+++ b/Control/AthAllocators/AthAllocators/ArenaSTLAllocator.icc
@@ -0,0 +1,40 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// $Id: ArenaSTLAllocator.icc 470825 2011-11-25 23:20:57Z ssnyder $
+/**
+ * @file AthAllocators/ArenaSTLAllocator.icc
+ * @author scott snyder <snyder@bnl.gov>
+ * @date Nov, 2011
+ * @brief 
+ */
+
+
+namespace SG {
+
+
+template <class BASE>
+ArenaSTLAllocator<BASE>::ArenaSTLAllocator (size_t nblock /*= 1000*/,
+                                         const std::string& name /*= ""*/)
+  : BASE (nblock, name)
+{
+}
+
+
+template <class BASE>
+ArenaSTLAllocator<BASE>::ArenaSTLAllocator (const ArenaSTLAllocator& a)
+  : BASE (a)
+{
+}
+
+
+template <class BASE>
+template <class U>
+ArenaSTLAllocator<BASE>::ArenaSTLAllocator (const ArenaSTLAllocator<U>& a)
+  : BASE (a)
+{
+}
+
+
+} // namespace SG
diff --git a/Control/AthAllocators/AthAllocators/ArenaSharedHeapSTLAllocator.h b/Control/AthAllocators/AthAllocators/ArenaSharedHeapSTLAllocator.h
new file mode 100644
index 0000000000000000000000000000000000000000..80dacc23ea107677945490f85abaf14633fee2d9
--- /dev/null
+++ b/Control/AthAllocators/AthAllocators/ArenaSharedHeapSTLAllocator.h
@@ -0,0 +1,410 @@
+// This file's extension implies that it's C, but it's really -*- C++ -*-.
+
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// $Id: ArenaSharedHeapSTLAllocator.h 552460 2013-06-25 17:29:25Z ssnyder $
+/**
+ * @file AthAllocators/ArenaSharedHeapSTLAllocator.h
+ * @author scott snyder <snyder@bnl.gov>
+ * @date Nov, 2011
+ * @brief STL-style allocator wrapper for @c ArenaHeapAllocator allowing
+ *        the heap to be shared between containers.
+ *
+ * This class defines a STL-style allocator for types @c T with the
+ * following special properties.
+ *
+ *  - We use an @c ArenaHeapAllocator for allocations.
+ *  - Only one object at a time may be allocated.
+ *  - The memory from several allocators may be grouped
+ *    together in the same memory pool.
+ *
+ * So, this allocator is suitable for an STL container which allocates
+ * lots of fixed-size objects, such as @c std::list, and further,
+ * you want to be able to have multiple list instances use
+ * the same pool.
+ *
+ * Note that this allocator will not work for containers that
+ * make variable-sized allocations, such as vector and the
+ * hash table containers.
+ *
+ * To use it, you should first explicitly create the allocator class,
+ * and then pass it to the constructors of the containers.
+ * The memory pool will be deleted when the original allocator
+ * instance is deleted.  Example:
+ *
+ *@code
+ *  {
+ *    typedef SG::ArenaSharedHeapSTLAllocator<int> alloc_t;
+ *    typedef std::list<int> list_t;
+ *
+ *    alloc_t allocator;
+ *    list_t list1 (allocator);
+ *    list_t list2 (allocator);
+ *    ... Now list1 and list2 will both use the same memory pool.
+ *  }
+ *  ... The memory pool is freed when the object `allocator' is deleted.
+ @endcode
+ *
+ * Implementation: Each allocator references a Header object,
+ * which is common to all allocators in the pool.  When an allocator
+ * is copied, the header pointer is copied too.  The Header object
+ * remembers the address of the allocator which originally created it,
+ * so that we can clean things up when that allocator goes away.
+ *
+ * A Header contains a list of ArenaHeapAllocator objects, one per
+ * payload type.  We use ArenaAllocatorRegistry to assign indices
+ * to the different allocator types.
+ */
+
+
+#ifndef ATLALLOCATORS_ARENASHAREDHEAPSTLALLOCATOR_H
+#define ATLALLOCATORS_ARENASHAREDHEAPSTLALLOCATOR_H
+
+
+#include "AthAllocators/ArenaSTLAllocator.h"
+#include "AthAllocators/ArenaHeapAllocator.h"
+#include "AthAllocators/ArenaHeapSTLAllocator.h"
+#include "AthAllocators/ArenaAllocatorRegistry.h"
+#include <string>
+#include <vector>
+
+
+namespace SG {
+
+/// Forward declaration.
+template <class T>
+class ArenaSharedHeapSTLAllocator;
+
+
+/**
+ * @brief Common header class for ArenaSharedHeapSTLAllocator.
+ *
+ * Each ArenaSharedHeapSTLAllocator has a pointer to a Header class.
+ * When a new ASHSTLAllocator object is constructed, we make a new Header;
+ * after that, the Header pointer is copied on copy-construction.
+ * The Header remembers the address of the object that created it,
+ * so that it can be deleted when that allocator is.
+ *
+ * The Header contains a list of ArenaHeapAllocator objects, one for
+ * each type we're allocating.
+ */
+class ArenaSharedHeapSTLHeader
+{
+public:
+  /**
+   * @brief Constructor.
+   * @param owner Address of the object that owns this Header.
+   * @param nblock Value to set in the parameters structure for the
+   *               number of elements to allocate per block.
+   * @param name   Value to use as the base for the allocator names.
+   */
+  ArenaSharedHeapSTLHeader (const void* owner,
+                            int nblock,
+                            const std::string& name);
+
+
+  /**
+   * @brief Destructor.
+   *
+   * Destroy all the allocators we own.
+   */
+  ~ArenaSharedHeapSTLHeader();
+
+
+  /**
+   * @brief Call this when an allocator is being deleted.
+   * @param a The address of calling allocator.
+   *
+   * If the address matches the address we were given when we were created,
+   * this object will be destroyed.
+   */
+  void maybe_delete (const void* a);
+
+
+  /**
+   * @brief Return allocator statistics summed over all our owned allocators.
+   */
+  ArenaAllocatorBase::Stats totstats() const;
+      
+
+  /**
+   * @brief Return the name to use for an allocator for type @c T.
+   */
+  template <class T>
+  std::string get_name();
+    
+
+  /**
+   * @brief Return the heap allocator for type @c T.
+   * @param index Reference to the index for type @c T.
+   *              Before the first call, this should be initialized
+   *              to std::string::npos.  This should generally
+   *              be a static variable.
+   */
+  template <class T>
+  ArenaHeapAllocator* get_pool (size_t& index);
+
+
+  void report (std::ostream& os) const
+  {
+    for (size_t i = 0; i < m_allocators.size(); i++)
+      if (m_allocators[i])
+        m_allocators[i]->report (os);
+  }
+
+
+private:
+  /// Address of the allocator that created this header.
+  const void* m_owner;
+
+  /// Saved value for nblock parameter.
+  size_t m_nblock;
+
+  /// Saved value for base name.
+  std::string m_name;
+
+  /// List of allocators.
+  std::vector<ArenaHeapAllocator*> m_allocators;
+};
+
+
+
+
+/**
+ * @brief STL-style allocator wrapper for @c ArenaHeapAllocator allowing
+ *        the heap to be shared between containers.
+ *
+ * See the file-level comments for details.
+ */
+template <class T>
+class ArenaSharedHeapSTLAllocator
+{
+public:
+  /// Make all instantiations of this class friends
+  /// (to be able to copy the header pointer).
+  template <class U> friend class ArenaSharedHeapSTLAllocator;
+
+  /// Standard STL allocator typedefs.
+  typedef T*        pointer;
+  typedef const T*  const_pointer;
+  typedef T&        reference;
+  typedef const T&  const_reference;
+  typedef T         value_type;
+  typedef size_t    size_type;
+  typedef ptrdiff_t difference_type;
+
+
+  /// Standard STL allocator rebinder.
+  template <class U> struct rebind {
+    typedef ArenaSharedHeapSTLAllocator<U> other;
+  };
+
+
+  /**
+   * @brief Default constructor.
+   * @param nblock Value to set in the parameters structure for the
+   *               number of elements to allocate per block.
+   * @param name   Value to use as the base for the allocator names.
+   */
+  ArenaSharedHeapSTLAllocator (size_t nblock = 1000,
+                               const std::string& name = "");
+
+
+  /**
+   * @brief Constructor from another @c ArenaHeapSTLAllocator.
+   *
+   * The new STL allocator will reference the same set of underlying
+   * Arena allocators as the old one.
+   */
+  ArenaSharedHeapSTLAllocator (const ArenaSharedHeapSTLAllocator& a);
+
+
+  /**
+   * @brief Constructor from another @c ArenaHeapSTLAllocator.
+   *
+   * The new STL allocator will reference the same set of underlying
+   * Arena allocators as the old one.
+   */
+  template <class U>
+  ArenaSharedHeapSTLAllocator (const ArenaSharedHeapSTLAllocator<U>& a);
+
+  // We don't bother to supply a more general constructor --- shouldn't
+  // be needed.
+
+  ~ArenaSharedHeapSTLAllocator();
+
+
+  /**
+   * @brief Assignment.
+   *
+   * We allow assignment only if the two objects involved represent
+   * the same arena, in which case it's a no-op.
+   * In other cases, we raise an exception.
+   *
+   * FIXME: By default, swap() is implemented in terms of this.
+   * It might be useful, though, to have a swap() that could
+   * handle different arenas.  We would need to be able handle
+   * updating the ownership back pointers from the headers, though;
+   * but that's much easier for swap than for the case of general
+   * assignments.
+   */
+  ArenaSharedHeapSTLAllocator&
+  operator= (const ArenaSharedHeapSTLAllocator& a);
+
+
+  /// Convert a reference to an address.
+  pointer address (reference x) const;
+  const_pointer address (const_reference x) const;
+
+
+  /**
+   * @brief Allocate new objects.
+   * @param n Number of objects to allocate.  Must be 1.
+   * @param hint Allocation hint.  Not used.
+   */
+  pointer allocate (size_type n, const void* hint = 0);
+
+
+  /**
+   * @brief Deallocate objects.
+   * @param n Number of objects to deallocate.  Must be 1.
+   */
+  void deallocate (pointer, size_type n);
+
+
+  /**
+   * @brief Return the maximum number of objects we can allocate at once.
+   *
+   * This always returns 1.
+   */
+  size_type max_size() const throw();
+
+
+  /**
+   * @brief Call the @c T constructor.
+   * @param p Location of the memory.
+   * @param val Parameter to pass to the constructor.
+   */
+  void construct (pointer p, const T& val);
+
+
+  /**
+   * @brief Call the @c T destructor.
+   * @param p Location of the memory.
+   */
+  void destroy (pointer p);
+
+
+  /**
+   * @brief Return the hinted number of objects allocated per block.
+   */
+  size_t nblock() const;
+
+
+  /**
+   * @brief Return the name of this allocator.
+   */
+  const std::string& name() const;
+
+
+  /**
+   * @brief Free all allocated elements.
+   *
+   * All elements allocated are returned to the free state.
+   * @c clear should be called on them if it was provided.
+   * The elements may continue to be cached internally, without
+   * returning to the system.
+   */
+  void reset();
+
+
+  /**
+   * @brief Free all allocated elements and release memory back to the system.
+   *
+   * All elements allocated are freed, and all allocated blocks of memory
+   * are released back to the system.
+   * @c destructor should be called on them if it was provided
+   * (preceded by @c clear if provided and @c mustClear was set).
+   */
+  void erase();
+
+
+  /**
+   * @brief Set the total number of elements cached by the allocator.
+   * @param size The desired pool size.
+   *
+   * This allows changing the number of elements that are currently free
+   * but cached.  Any allocated elements are not affected by this call.
+   *
+   * If @c size is greater than the total number of elements currently
+   * cached, then more will be allocated.  This will preferably done
+   * with a single block, but that is not guaranteed; in addition, the
+   * allocator may allocate more elements than is requested.
+   *
+   * If @c size is smaller than the total number of elements currently
+   * cached, as many blocks as possible will be released back to the system.
+   * It may not be possible to release the number of elements requested;
+   * this should be implemented on a best-effort basis.
+   */
+  void reserve (size_t size);
+
+
+  /**
+   * @brief Return the statistics block for this allocator.
+   */
+  const ArenaAllocatorBase::Stats& stats() const;
+
+
+  /**
+   * @brief Return the statistics blocks summed up over all allocators
+   *        using this pool.
+   */
+  ArenaAllocatorBase::Stats totstats() const;
+
+
+  /**
+   * @brief Return a pointer to the underlying allocator.
+   *        This creates the allocator if needed.
+   */
+  ArenaHeapAllocator* poolptr() const;
+
+
+  void report (std::ostream& os) const
+  {
+    m_header->report(os);
+  }
+
+
+
+  /**
+   * @brief Compare two allocators.  Needed by some @c swap implementations.
+   *
+   *        We consider two allocators to be the same if they're
+   *        referencing the same Header.
+   */
+  bool operator!= (const ArenaSharedHeapSTLAllocator& other) const;
+  
+
+private:
+  /**
+   * @brief Ask the Header for the allocator to use.
+   *        This will either return an existing one or create a new one.
+   */
+  void get_pool() const;
+
+  ArenaSharedHeapSTLHeader* m_header;
+  mutable ArenaHeapAllocator* m_pool;
+
+  static size_t s_index;
+};
+
+
+} // namespace SG
+
+
+#include "AthAllocators/ArenaSharedHeapSTLAllocator.icc"
+
+
+#endif // not ATLALLOCATORS_ARENASHAREDHEAPSTLALLOCATOR_H
diff --git a/Control/AthAllocators/AthAllocators/ArenaSharedHeapSTLAllocator.icc b/Control/AthAllocators/AthAllocators/ArenaSharedHeapSTLAllocator.icc
new file mode 100644
index 0000000000000000000000000000000000000000..633010dd767052505bc6b4022a96aa34695a5f83
--- /dev/null
+++ b/Control/AthAllocators/AthAllocators/ArenaSharedHeapSTLAllocator.icc
@@ -0,0 +1,407 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// $Id: ArenaSharedHeapSTLAllocator.icc 496835 2012-04-20 07:58:52Z ssnyder $
+/**
+ * @file AthAllocators/ArenaSharedHeapSTLAllocator.icc
+ * @author scott snyder <snyder@bnl.gov>
+ * @date Nov, 2011
+ * @brief STL-style allocator wrapper for @c ArenaHeapAllocator allowing
+ *        the heap to be shared between containers.
+ */
+
+
+#include "GaudiKernel/System.h"
+#include <cassert>
+#include <stdexcept>
+
+
+namespace SG {
+
+
+/**
+ * @brief Call this when an allocator is being deleted.
+ * @param a The address of calling allocator.
+ *
+ * If the address matches the address we were given when we were created,
+ * this object will be destroyed.
+ */
+inline
+void ArenaSharedHeapSTLHeader::maybe_delete (const void* a)
+{
+  if (a == m_owner) {
+    delete this;
+  }
+}
+
+
+/**
+ * @brief Return the name to use for an allocator for type @c T.
+ */
+template <class T>
+std::string ArenaSharedHeapSTLHeader::get_name()
+{
+  return m_name + "::ArenaSharedHeapSTLAllocator<" +
+    System::typeinfoName (typeid (T)) + ">";
+}
+
+
+/**
+ * @brief Return the heap allocator for type @c T.
+ * @param index Reference to the index for type @c T.
+ *              Before the first call, this should be initialized
+ *              to std::string::npos.  This should generally
+ *              be a static variable.
+ */
+template <class T>
+ArenaHeapAllocator* ArenaSharedHeapSTLHeader::get_pool (size_t& index)
+{
+  // If we need the name, we'll put it here.
+  std::string name;
+
+  // If we don't have an index yet, ask the global registry.
+  // Note: We're only using the registry for the name<->index
+  // mapping; we're not using it to construct the allocators
+  // for us.  This, we pass in a null pointer for the constructor.
+  // (We don't construct the allocators from the registry because
+  // we cant to be able to change the number of blocks from instance
+  // to instance, but there's no way passing that to the Registry
+  // interface.)
+  if (index == std::string::npos) {
+    name = get_name<T>();
+    ArenaAllocatorRegistry* reg = ArenaAllocatorRegistry::instance();
+    index = reg->lookup (name);
+    if (index == std::string::npos)
+      index = reg->registerCreator (name, 0);
+  }
+
+  // Expand the list of allocators if needed.
+  if (index >= m_allocators.size())
+    m_allocators.resize (index+1);
+
+  // Create the allocator if we haven't done so yet.
+  if (!m_allocators[index]) {
+    if (name.empty()) // Only construct the name once.
+      name = get_name<T>();
+    m_allocators[index] = new ArenaHeapAllocator
+      (ArenaHeapSTLAllocator_initParams<T> (m_nblock, name));
+  }
+
+  // Return the allocator.
+  return m_allocators[index];
+}
+
+
+
+//===========================================================================
+
+
+template <class T>
+size_t ArenaSharedHeapSTLAllocator<T>::s_index = -1;
+
+
+template <class T>
+ArenaSharedHeapSTLAllocator<T>::ArenaSharedHeapSTLAllocator
+  (size_t nblock /*= 1000*/,
+   const std::string& name /*= ""*/)
+    : m_header (new ArenaSharedHeapSTLHeader (this, nblock, name)),
+      m_pool (0)
+{
+}
+
+
+template <class T>
+inline
+ArenaSharedHeapSTLAllocator<T>::ArenaSharedHeapSTLAllocator
+  (const ArenaSharedHeapSTLAllocator& a)
+    : m_header (const_cast<ArenaSharedHeapSTLHeader*>(a.m_header)),
+      m_pool (const_cast<ArenaHeapAllocator*> (a.m_pool))
+{
+}
+
+
+template <class T>
+template <class U>
+inline
+ArenaSharedHeapSTLAllocator<T>::ArenaSharedHeapSTLAllocator
+  (const ArenaSharedHeapSTLAllocator<U>& a)
+    : m_header (const_cast<ArenaSharedHeapSTLHeader*>(a.m_header)),
+      m_pool (0)
+{
+}
+
+
+template <class T>
+inline
+ArenaSharedHeapSTLAllocator<T>::~ArenaSharedHeapSTLAllocator()
+{
+  m_header->maybe_delete (this);
+}
+
+
+/**
+ * @brief Assignment.
+ *
+ * We allow assignment only if the two objects involved represent
+ * the same arena, in which case it's a no-op.
+ * In other cases, we raise an exception.
+ */
+template <class T>
+ArenaSharedHeapSTLAllocator<T>&
+ArenaSharedHeapSTLAllocator<T>::operator=
+  (const ArenaSharedHeapSTLAllocator& a)
+{
+  if (&a != this) {
+    if (m_header != a.m_header)
+      throw std::runtime_error
+        ("Attempt to assign between ArenaSharedHeapSTLAllocators "
+         "for different arenas");
+    assert (m_pool == a.m_pool);
+  }
+  return *this;
+}
+
+
+/**
+ * @brief Convert a reference to an address.
+ */
+template <class T>
+inline
+typename ArenaSharedHeapSTLAllocator<T>::pointer
+ArenaSharedHeapSTLAllocator<T>::address (reference x) const
+{
+  return &x;
+}
+
+
+/**
+ * @brief Convert a reference to an address.
+ */
+template <class T>
+inline
+typename ArenaSharedHeapSTLAllocator<T>::const_pointer
+ArenaSharedHeapSTLAllocator<T>::address (const_reference x) const
+{
+  return &x;
+}
+
+
+/**
+ * @brief Allocate new objects.
+ * @param n Number of objects to allocate.  Must be 1.
+ * @param hint Allocation hint.  Not used.
+ */
+template <class T>
+inline
+typename ArenaSharedHeapSTLAllocator<T>::pointer
+ArenaSharedHeapSTLAllocator<T>::allocate (size_type
+#ifndef NDEBUG
+                      n
+#endif
+                      , const void* /*hint = 0*/)
+{
+  assert (n == 1);
+  return reinterpret_cast<pointer> (poolptr()->allocate());
+}
+
+
+/**
+ * @brief Deallocate objects.
+ * @param n Number of objects to deallocate.  Must be 1.
+ *
+ * This implementation doesn't do anything.
+ */
+template <class T>
+inline
+void ArenaSharedHeapSTLAllocator<T>::deallocate (pointer p, size_type 
+#ifndef NDEBUG
+                             n
+#endif
+                             )
+{
+  assert (n == 1);
+  poolptr()->free (reinterpret_cast<ArenaAllocatorBase::pointer> (p));
+}
+
+
+/**
+ * @brief Return the maximum number of objects we can allocate at once.
+ *
+ * This always returns 1.
+ */
+template <class T>
+inline
+typename ArenaSharedHeapSTLAllocator<T>::size_type
+ArenaSharedHeapSTLAllocator<T>::max_size() const throw() 
+{
+  return 1;
+}
+
+
+/**
+ * @brief Call the @c T constructor.
+ * @param p Location of the memory.
+ * @param val Parameter to pass to the constructor.
+ */
+template <class T>
+inline
+void ArenaSharedHeapSTLAllocator<T>::construct (pointer p, const T& val)
+{
+  new (reinterpret_cast<void*>(p)) T(val);
+}
+
+
+/**
+ * @brief Call the @c T destructor.
+ * @param p Location of the memory.
+ */
+template <class T>
+inline
+void ArenaSharedHeapSTLAllocator<T>::destroy (pointer p)
+{
+  p->~T();
+}
+
+
+/**
+ * @brief Return the hinted number of objects allocated per block.
+ */
+template <class T>
+inline
+size_t ArenaSharedHeapSTLAllocator<T>::nblock() const
+{
+  return poolptr()->params().nblock;
+}
+
+
+/**
+ * @brief Return the name of this allocator.
+ */
+template <class T>
+inline
+const std::string& ArenaSharedHeapSTLAllocator<T>::name() const
+{
+  return poolptr()->name();
+}
+
+
+/**
+ * @brief Free all allocated elements.
+ *
+ * All elements allocated are returned to the free state.
+ * @c clear should be called on them if it was provided.
+ * The elements may continue to be cached internally, without
+ * returning to the system.
+ */
+template <class T>
+void ArenaSharedHeapSTLAllocator<T>::reset()
+{
+  poolptr()->reset();
+}
+
+
+/**
+ * @brief Free all allocated elements and release memory back to the system.
+ *
+ * All elements allocated are freed, and all allocated blocks of memory
+ * are released back to the system.
+ * @c destructor should be called on them if it was provided
+ * (preceded by @c clear if provided and @c mustClear was set).
+ */
+template <class T>
+void ArenaSharedHeapSTLAllocator<T>::erase()
+{
+  poolptr()->erase();
+}
+
+
+/**
+ * @brief Set the total number of elements cached by the allocator.
+ * @param size The desired pool size.
+ *
+ * This allows changing the number of elements that are currently free
+ * but cached.  Any allocated elements are not affected by this call.
+ *
+ * If @c size is greater than the total number of elements currently
+ * cached, then more will be allocated.  This will preferably done
+ * with a single block, but that is not guaranteed; in addition, the
+ * allocator may allocate more elements than is requested.
+ *
+ * If @c size is smaller than the total number of elements currently
+ * cached, as many blocks as possible will be released back to the system.
+ * It may not be possible to release the number of elements requested;
+ * this should be implemented on a best-effort basis.
+ */
+template <class T>
+void ArenaSharedHeapSTLAllocator<T>::reserve (size_t size)
+{
+  poolptr()->reserve (size);
+}
+
+
+/**
+ * @brief Return the statistics block for this allocator.
+ */
+template <class T>
+const ArenaAllocatorBase::Stats&
+ArenaSharedHeapSTLAllocator<T>::stats() const
+{
+  return poolptr()->stats();
+}
+
+
+/**
+ * @brief Return the statistics blocks summed up over all allocators
+ *        using this pool.
+ */
+template <class T>
+inline
+ArenaAllocatorBase::Stats ArenaSharedHeapSTLAllocator<T>::totstats() const
+{
+  return m_header->totstats();
+}
+
+
+/**
+ * @brief Return a pointer to the underlying allocator.
+ *        This creates the allocator if needed.
+ */
+template <class T>
+inline
+ArenaHeapAllocator* ArenaSharedHeapSTLAllocator<T>::poolptr() const
+{
+  if (!m_pool)
+    get_pool();
+  return m_pool;
+}
+
+
+/**
+ * @brief Compare two allocators.  Needed by some @c swap implementations.
+ *
+ *        We consider two allocators to be the same if they're
+ *        referencing the same Header.
+ */
+template <class T>
+inline
+bool ArenaSharedHeapSTLAllocator<T>::operator!=
+  (const ArenaSharedHeapSTLAllocator& other) const
+{
+  return m_header != other.m_header;
+}
+
+
+/**
+ * @brief Ask the Header for the allocator to use.
+ *        This will either return an existing one or create a new one.
+ */
+template <class T>
+inline
+void ArenaSharedHeapSTLAllocator<T>::get_pool() const
+{
+  m_pool = m_header->get_pool<T> (s_index);
+}
+
+
+} // namespace SG
diff --git a/Control/AthAllocators/AthAllocators/AthAllocatorsDict.h b/Control/AthAllocators/AthAllocators/AthAllocatorsDict.h
new file mode 100755
index 0000000000000000000000000000000000000000..09baf47b511d8c2b80a673e8b8254b3aefaa1bbb
--- /dev/null
+++ b/Control/AthAllocators/AthAllocators/AthAllocatorsDict.h
@@ -0,0 +1,5 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#include "AthAllocators/ArenaHeader.h"
diff --git a/Control/AthAllocators/AthAllocators/DataPool.h b/Control/AthAllocators/AthAllocators/DataPool.h
new file mode 100755
index 0000000000000000000000000000000000000000..6a45c1b23df2f1649c804e350bd6a8abf008dbb9
--- /dev/null
+++ b/Control/AthAllocators/AthAllocators/DataPool.h
@@ -0,0 +1,154 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#ifndef ATHALLOCATORS_DATAPOOL_H
+#define ATHALLOCATORS_DATAPOOL_H
+/** @class DataPool
+ * @brief  a typed memory pool that saves time spent
+ *         allocation small object. This is typically used
+ *         by container such as DataVector and DataList
+ * @author Srini Rajagopalan - ATLAS Collaboration
+ *$Id: DataPool.h 470529 2011-11-24 23:54:22Z ssnyder $	
+ */
+
+#include "AthAllocators/ArenaCachingHandle.h"
+#include "AthAllocators/ArenaPoolAllocator.h"
+#include <string>
+#include "boost/iterator/iterator_adaptor.hpp"
+
+template <typename VALUE>
+class DataPool
+{
+private:
+  typedef SG::ArenaPoolAllocator alloc_t;
+  typedef SG::ArenaCachingHandle<VALUE, alloc_t> handle_t;
+  
+public:
+  typedef typename handle_t::pointer pointer;
+  typedef size_t size_type;
+
+  class const_iterator;
+
+  class iterator
+    : public boost::iterator_adaptor<
+    iterator,
+    typename handle_t::iterator,
+    VALUE *,
+    boost::forward_traversal_tag,
+    VALUE *>
+  {
+  public:
+    iterator (const typename handle_t::iterator& it)
+      : iterator::iterator_adaptor_ (it)
+    {
+    }
+
+    friend class const_iterator;
+
+  private:
+    friend class boost::iterator_core_access;
+
+    typename iterator::reference dereference() const
+    { return &*this->base_reference(); }
+  };
+
+  class const_iterator
+    : public boost::iterator_adaptor<
+    const_iterator,
+    typename handle_t::const_iterator,
+    VALUE const *,
+    boost::forward_traversal_tag,
+    VALUE const *>
+  {
+  public:
+    const_iterator (const typename handle_t::const_iterator& it)
+      : const_iterator::iterator_adaptor_ (it)
+    {
+    }
+
+    const_iterator (const iterator& it)
+      : const_iterator::iterator_adaptor_ (it.base_reference())
+    {
+    }
+
+  private:
+    friend class boost::iterator_core_access;
+
+    typename const_iterator::reference dereference() const
+    { return &*this->base_reference(); }
+  };
+
+
+  //////////////////////////////////////////////////////////////////////
+  /// Constructors:
+  //////////////////////////////////////////////////////////////////////
+
+  /// default constructor will initialize the pool with m_minRefCount
+  DataPool(size_type n = 0,
+           size_type block_size = 0,
+           SG::Arena* arena = 0);
+ 
+  ///////////////////////////////////////////////////////
+
+  /// release all elements in the pool.
+  void reset();
+
+  /// free all memory in the pool.
+  void erase();
+  
+  void reserve(unsigned int size);
+
+  /// return capacity of pool OK
+  unsigned int capacity();
+
+  /// return size already allocated OK
+  unsigned int allocated();
+
+  /// begin iterators over pool
+  iterator begin();
+  const_iterator begin() const;
+
+  /// the end() method will allow looping over only valid elements
+  /// and not over ALL elements of the pool 
+  iterator end();
+  const_iterator end() const;
+ 
+  /// obtain the next available element in pool by pointer
+  /// pool is resized if its limit has been reached
+  /// This may be faster than calling the constructors with 
+  /// the following two methods. But one must be sure to 
+  /// completely reset each object since it has values set in the 
+  /// previous event.
+  pointer nextElementPtr(); 
+
+  /// obtain the next available element in pool by pointer
+  /// return as void* to minimize misuse, client usage is:
+  /// MyElement* m = new(pool->mem) MyElement(...); // pool is ptr
+  /// DANGEROUS --- do we need this???
+  void* mem();
+
+  /// can also say: 
+  /// MyElement* m = new ((*pool)()) MyElement(...); // pool = pointer
+  /// MyElement* m = new (pool()) MyElement(...); // pool = value
+  /// DANGEROUS --- do we need this???
+  void *operator ()();
+
+   /// typename of pool
+   static const std::string& typeName();
+
+//-----------------------------------------------------------//
+
+ private:
+
+   handle_t m_handle;
+
+  /// minimum number of elements in pool
+  static const unsigned int m_minRefCount = 1024;
+};
+
+#include "AthAllocators/DataPool.icc"
+
+#endif
+
+
diff --git a/Control/AthAllocators/AthAllocators/DataPool.icc b/Control/AthAllocators/AthAllocators/DataPool.icc
new file mode 100755
index 0000000000000000000000000000000000000000..27d1a63de821d6d2cab78a89e890124ce8f9bd4f
--- /dev/null
+++ b/Control/AthAllocators/AthAllocators/DataPool.icc
@@ -0,0 +1,130 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+//-----------------------------------------------------------
+// .icc file for DataPool
+//-----------------------------------------------------------
+// includes:
+#include <algorithm>
+#include "GaudiKernel/System.h"
+//-----------------------------------------------------------
+
+/// default constructor will initialize the pool with m_minRefCount
+template <typename VALUE>
+DataPool<VALUE>::DataPool(size_type n /*= 0*/,
+                          size_type block_size /*= 0*/,
+                          SG::Arena* arena /*= 0*/)
+  : m_handle (arena,
+              typename alloc_t::initParams<VALUE> (std::max (block_size,
+                                                             static_cast<size_type>(1024u))))
+{
+  if (n > 0)
+    m_handle.reserve (n);
+}
+
+//-----------------------------------------------------------
+/// release all elements in the pool.
+template <typename VALUE>
+void DataPool<VALUE>::reset()
+{
+  m_handle.reset();
+}
+
+/// free all memory in the pool.
+template <typename VALUE>
+void DataPool<VALUE>::erase()
+{
+  m_handle.erase();
+}
+//-----------------------------------------------------------
+// reserve space for the pool
+// allocated elements will not be deleted.
+
+template <typename VALUE>
+void DataPool<VALUE>::reserve(unsigned int size)
+{
+  m_handle.reserve (size);
+}
+
+
+template <typename VALUE>
+unsigned int DataPool<VALUE>::capacity()
+{
+  return m_handle.stats().elts.total;
+}
+
+template <typename VALUE>
+unsigned int DataPool<VALUE>::allocated()
+{
+  return m_handle.stats().elts.inuse;
+}
+
+
+//-----------------------------------------------------------
+/// begin iterators over pool
+template <typename VALUE>
+typename DataPool<VALUE>::iterator DataPool<VALUE>::begin()
+{ 
+  return iterator (m_handle.begin());
+}
+
+template <typename VALUE>
+typename DataPool<VALUE>::const_iterator DataPool<VALUE>::begin() const
+{ 
+  return const_Iterator (m_handle.begin());
+}
+
+//-----------------------------------------------------------
+/// the end() method will allow looping over only valid elements
+/// and not over ALL elements of the pool 
+
+template <typename VALUE>
+typename DataPool<VALUE>::iterator DataPool<VALUE>::end()
+{ 
+  return iterator (m_handle.end());
+}
+
+template <typename VALUE>
+typename DataPool<VALUE>::const_iterator DataPool<VALUE>::end() const { 
+  return const_iterator (m_handle.end());
+}
+
+//-----------------------------------------------------------
+/// obtain the next available element in pool by pointer
+/// return as void* to minimize misuse, client usage is:
+/// MyElement* m = new(pool->mem) MyElement(...); // pool is ptr
+template <typename VALUE>
+void* DataPool<VALUE>::mem() {
+    pointer p = nextElementPtr();
+    return p;
+}
+
+/// can also say: 
+/// MyElement* m = new ((*pool)()) MyElement(...); // pool = pointer
+/// MyElement* m = new (pool()) MyElement(...); // pool = value
+
+template <typename VALUE>
+void* DataPool<VALUE>::operator()() { 
+    return mem(); 
+}
+
+//-----------------------------------------------------------
+/// typename of pool
+template <typename VALUE>
+const std::string& DataPool<VALUE>::typeName() {
+  static std::string name = System::typeinfoName (typeid (VALUE));
+  return name;
+}
+
+//-----------------------------------------------------------
+/// obtain the next available element in pool by pointer
+/// pool is resized if reached its limit
+template <typename VALUE>
+inline
+typename DataPool<VALUE>::pointer DataPool<VALUE>::nextElementPtr()
+{
+  return m_handle.allocate();
+}
+  
+
diff --git a/Control/AthAllocators/AthAllocators/selection.xml b/Control/AthAllocators/AthAllocators/selection.xml
new file mode 100755
index 0000000000000000000000000000000000000000..7bde1fab2f800e90aa3cfa827fa221055eff8bcd
--- /dev/null
+++ b/Control/AthAllocators/AthAllocators/selection.xml
@@ -0,0 +1,3 @@
+<lcgdict>
+  <class name="SG::ArenaHeader"/>
+</lcgdict>
diff --git a/Control/AthAllocators/cmt/requirements b/Control/AthAllocators/cmt/requirements
new file mode 100755
index 0000000000000000000000000000000000000000..ad012cf535deacc677cf2af0d3201e1b87532104
--- /dev/null
+++ b/Control/AthAllocators/cmt/requirements
@@ -0,0 +1,51 @@
+package AthAllocators
+
+author scott snyder   <snyder@bnl.gov>
+
+use AtlasPolicy    AtlasPolicy-*
+use GaudiInterface GaudiInterface-* External 
+use AtlasBoost     AtlasBoost-*     External
+
+
+private
+use CxxUtils       CxxUtils-*       Control
+end_private
+
+  
+apply_pattern installed_library
+library AthAllocators *.cxx
+
+
+private 
+use TestTools      TestTools-*         AtlasTest 
+
+apply_pattern UnitTest_run unit_test=ArenaAllocatorBase
+apply_pattern UnitTest_run unit_test=ArenaBlockAllocatorBase
+apply_pattern UnitTest_run unit_test=ArenaBlock
+apply_pattern UnitTest_run unit_test=ArenaPoolAllocator
+apply_pattern UnitTest_run unit_test=ArenaHeapAllocator
+apply_pattern UnitTest_run unit_test=ArenaHandleBase
+apply_pattern UnitTest_run unit_test=ArenaHandleBaseAllocT
+apply_pattern UnitTest_run unit_test=ArenaHandleBaseT
+apply_pattern UnitTest_run unit_test=ArenaHeader
+apply_pattern UnitTest_run unit_test=ArenaCachingHandle
+apply_pattern UnitTest_run unit_test=ArenaHandle
+apply_pattern UnitTest_run unit_test=ArenaAllocatorCreator
+apply_pattern UnitTest_run unit_test=ArenaAllocatorRegistry
+apply_pattern UnitTest_run unit_test=Arena
+apply_pattern UnitTest_run unit_test=ArenaBase
+apply_pattern UnitTest_run unit_test=ArenaHeaderGaudiClear \
+  extrapatterns="^IncidentSvc +DEBUG Adding"
+apply_pattern UnitTest_run unit_test=ArenaPoolSTLAllocator
+apply_pattern UnitTest_run unit_test=ArenaHeapSTLAllocator
+apply_pattern UnitTest_run unit_test=ArenaSharedHeapSTLAllocator
+apply_pattern UnitTest_run unit_test=DataPool \
+  extrapatterns="^IncidentSvc +DEBUG Adding|^HistogramPersis.* (INFO|DEBUG)|^JobOptionsSvc +INFO"
+
+macro_append DOXYGEN_INPUT " ../doc" 
+
+
+private
+use AtlasReflex      AtlasReflex-*         External
+apply_pattern lcgdict dict=AthAllocators selectionfile=selection.xml headerfiles="../AthAllocators/AthAllocatorsDict.h"
+
diff --git a/Control/AthAllocators/ispellwords b/Control/AthAllocators/ispellwords
new file mode 100755
index 0000000000000000000000000000000000000000..915b514e94953df0af6cff6cb8fc53bb4b361da6
--- /dev/null
+++ b/Control/AthAllocators/ispellwords
@@ -0,0 +1,732 @@
+personal_ws-1.1 en 698 
+assoPointer
+persistency
+IdentifiableContainer
+multi
+toContainedElement
+GaudiKernel
+situ
+someone's
+refcnt
+GENERATEINDEXINGPOLICIES
+elementShortRef
+originalSize
+unary
+blk
+arg
+objectContainer
+dataID
+bkt
+Amram
+endif
+typeid
+fooB
+ForwardIndexingPolicy
+JetCollection
+resized
+constr
+PackedArray
+const's
+RandomAccessIterator
+CompareAndPrint
+del
+IProxyDict
+deallocate
+dep
+DVLNoBase
+cassert
+creat
+ASHSTLAllocator
+ness
+Resizes
+autoselect
+doinit
+setElement
+DataVector
+theAsso
+addHostDObj
+gaudi
+Dreizin
+scott
+theAssociatedObjects
+cmt
+objIndex
+assocIndex
+dir
+ArenaAllocatorRegistry
+allocator's
+persistifiable
+InhVectorIntLink
+functor
+nclear
+crc
+elmts
+ssnyder
+Predwrapper
+MessageSvc
+DNC
+readback
+binet
+theTrack
+DL's
+DataPool
+Faz
+newAssoc
+fdl
+GenerateIndexingPolicy
+ConstDataVector
+AtlasReflex
+fangled
+fdv
+LongRef
+pCont's
+gcc
+Ilija
+HistogramPersis
+absFluff
+liint
+getAssociations
+allo
+isDefault
+utest
+ArenaCachingHandle
+depcy
+nctor
+ELs
+CVS
+ClassName
+destructor
+tTrack
+elt
+hashtable's
+PlainPtrElementLink
+ELV
+DList
+DSO
+resetWithKeyAndIndex
+DataLinkVector
+ElemLink
+resetWithKey
+typedef
+pbad
+dum
+firstAssoc
+cxx
+theStore
+BaseContainer
+persistified
+dvl
+endAssociation
+ispellwords
+ILink
+endHostDObjs
+shortRefs
+shortrefs
+GenParticleIndexing
+Elsing
+DV's
+BinaryPredicate
+anOther
+FooDequeLink
+moveHostDObjs
+theObjects
+FooDeque
+ArenaBase
+AtlasSEAL
+FNV
+NoBase
+icc
+iCtr
+NOGAUDI
+swapElement
+defaultHeader
+objectPointer
+src's
+StoreGateSvc
+hashtable
+CopyConstructible
+findProxy
+BeginEvent
+GNUC
+toPersistentDL
+iff
+firstAssObject
+bitsize
+pCopyDerFluff
+findAssociationObjects
+DataVectorBase
+fdvlcopy
+line'll
+func
+ArenaHandleBaseAllocT
+asDataList
+CLID's
+CLIDs
+convertable
+fdlcopy
+hoc
+DHAVE
+functionalities
+addArena
+dataGet
+namespaces
+StoreGate
+IOSTREAMS
+oldElem
+DataProxy
+paolo
+eltest
+jobOs
+AssociationLinks
+DataLink
+RVersion
+pAssoc
+hpp
+TODO
+valgrind
+DataProxyStorageBase
+srini
+getObject
+ASSCONT
+cerr
+proxying
+ASSOCONT
+DataListBase
+AthenaPOOL
+Calafiura
+MapIndexingPolicy
+param
+AssociationVector
+IProxyDictWithPool
+persistify
+changeState
+canReclear
+doxygen
+setHashAndIndex
+runtime
+lcg
+args
+DataList
+DataPtrs
+rebinder
+theAssociations
+inserters
+uint
+ndtor
+DVLCast
+theAssociationObjects
+assoStore
+AssociationVectorCollection
+isStreamable
+irt
+resetTo
+AssociationVectorIterator
+wronglmint
+pairtype
+pdata
+RemoveDataPtr
+theType
+printf
+setStorableObject
+ArenaHeapSTLAllocator
+iJet
+doRemap
+toPersistable
+OBJCONT
+deallocation
+iTracks
+getFirstAssociation
+SGFolder
+AssociationLinkCollection
+objectIter
+lhs
+storeName
+ArenaBlockAllocatorBase
+rvalue
+DerivedFluff
+ElemLinkVector
+ArenaHeaderGaudiClear
+mem
+hasher
+dobjs
+assoIter
+Quarrie
+hasAssociations
+assoContainer
+dereferencing
+cinquanta
+IdentContIndexingPolicy
+DVLDataBucket
+ElementLinkVector
+vers
+PDTR
+nav
+Hong
+forwardContainer
+cinq
+eltSize
+AtlasBoost
+CINT
+typeinfoName
+reverseIterators
+ArenaPoolAllocator
+kwd
+ndx
+resize
+indexingPolicy
+tradeoff
+ClusterContainer
+oldInt
+getDataSourcePointer
+MacOSX
+NavigationToken
+asso
+PlainPtrStorage
+bool
+shortref
+shortRef
+dieci
+DataMap
+Nir
+OBJTYPE
+asDataVector
+ArenaHeapAllocator
+DataLinks
+gmake
+mLink
+castfn
+AssociationBaseCollection
+clid
+deps
+LWG
+namespace
+IOHandler
+ArenaAllocatorCreatorInit
+pdf
+pAssocs
+dflt
+dfluff
+pDL
+reflextion
+typename
+typeName
+DVLIterator
+iTrack
+getDataSource
+initParams
+LXR
+DataBucket
+pDV
+pJets
+refCount
+snyder
+ASSOBJECT
+initGaudi
+Srini's
+multimap
+pTransient
+DataBucketTrait
+dict
+ElemLinkRefs
+interoperate
+nreserve
+lastAssObject
+theAssoc
+TrackContainer
+init
+minRefCount
+impl
+OwnershipPolicy
+otherElemLinkRefs
+AssociativeIndexingPolicy
+DataVector's
+oper
+IsSTLSequence
+findProxyFromKey
+newAss
+mutators
+addTrack
+IncidentSvc
+makeIndex
+sgkey
+StrictWeakOrdering
+lastTrack
+ClassID
+classID
+calaf
+rbegin
+containsAssociation
+SetIndexingPolicy
+ifndef
+assocPointer
+BaseConstReference
+pos
+PtrVector
+ret
+pre
+params
+BList
+theAssocs
+ArenaAllocatorBase
+Dufus
+GaudiClear
+ppvInterface
+reextracted
+lookup
+arghh
+rhs
+pointee
+maxRefCount
+config
+toPersistentState
+intL
+Sep
+hostDObjs
+ClassIDSvc
+ptr
+BVec
+intV
+pvp
+getDataSourcePointerFromGaudi
+RNG
+pTracks
+Metafunction
+ArenaHandleBase
+shortIterFromLong
+tCluster
+successFlag
+genreflex
+DataProxyStorage
+DataProxyStorageData
+theJet
+ElementType
+ELVDEBUG
+PtrList
+AllocatorCreatorBase
+asStorable
+ArenaSharedHeapSTLAllocator
+AthenaKernel
+ChangeLog
+getLastAssocation
+nblock
+dvlinfo
+DVLInfo
+PlainPtrDataLink
+src
+cout
+IDtype
+pcopy
+jobO
+Vec
+resizePool
+TestTools
+dtors
+DataPtr
+tdefs
+enums
+ArenaSTLAllocator
+findHostDObj
+DataList's
+toIndexedElement
+stl
+sizeof
+svc
+cptr
+sss
+checkreq
+dobj
+Vukotic
+packageinfo
+frexp
+str
+setData
+MyObj
+iter
+DVLEltBase
+AssociationType
+clidsvc
+CLIDSvc
+backNavigation
+toPersistent
+theCluster
+mustClear
+storable
+IInterface
+AssociationObjectIterator
+DefaultKey
+TSS
+inlined
+Rajagopalan
+makeFunc
+savannah
+ArenaBlock
+multiset
+GeneratorObjects
+reverseLookup
+DefaultState
+Obreshkov
+pred
+malloc
+myassert
+AthExStoreGateExamples
+DVLInfoBase
+setOwner
+txt
+myCluster
+FIXME
+LIBSTDCXX
+ArenaAllocatorCreator
+Gemmeren
+makeAllocator
+JetTrackAssociation
+IOVSvc
+prev
+newElement
+beginAssociation
+specializable
+removeHostDObj
+toAccessible
+RefVector
+EndEvent
+PersistentState
+tinfo
+myassertion
+elcnv
+ctor
+struct
+vpvp
+dereference
+allocvec
+getDataRef
+ElementParameter
+fdvl
+AthenaROOTAccess
+ControlTest
+objectIndex
+iHost
+emacs
+alloc
+pElem
+riid
+accessor
+setValid
+DataObject
+makeCurrent
+dpint
+symLink
+decls
+ElementLink
+bb
+anAss
+DataSource
+linkOffset
+linkoffset
+lookups
+refVector's
+DPSB
+isValid
+ibadlint
+ForwardIterator
+assoIndex
+firstTrack
+NDEBUG
+NULLs
+templated
+endl
+br
+getDataPtr
+venti
+eg
+dl
+mainpage
+VirtBases
+DefaultIndexingPolicy
+utests
+reportStr
+fd
+FooDataVectorLink
+CxxUtils
+ivint
+findInContainer
+dv
+DVLTYPE
+RehashPolicy
+ElementProxy
+theObject
+fn
+JetTrackAssociationCollection
+SGASSERTERROR
+checkForRemap
+iliint
+toTransient
+anotherString
+ctors
+AssociationLink
+FolderItem
+IdentContIndex
+dereferences
+iptrlint
+intLF
+DataModel
+getLastAssociation
+IP
+indices
+multithreaded
+sstream
+intLL
+ld
+destructors
+Elts
+ownPolicy
+tryELRemap
+li
+rvalues
+DeclareIndexingPolicy
+Koenig
+IndexingPolicies
+nd
+xyz
+Austern
+delArena
+TrackParticleContainer
+minSize
+toAccessibleState
+storagePolicy
+NavFourMon
+ArenaHandle
+ConstDataList
+ok
+TrackParticle
+ChronoStatSvc
+ElemLinkRef
+ns
+findAssociation
+Compwrapper
+proxied
+gccxml
+RegisterDVLEltBaseInit
+badI
+DataPoolTest
+os
+stdcont
+stdCont
+initializer
+lastAssoc
+DVec
+ri
+BaseInfo
+sg
+ElemLinks
+ElemLink's
+targ
+DirSearchPath
+ELVRef
+intVF
+headp
+BidirectionalIterator
+cplusplus
+Tavori
+SGElvRef
+dtor
+enum
+schaffer
+intVL
+vd
+ForwardContainerConcept
+InUse
+sz
+WG
+ArenaPoolSTLAllocator
+inline
+typedefs
+typedef's
+Vo
+getE
+vp
+sgname
+sgName
+rObj
+SequenceIndexing
+setStorable
+trenta
+AssociationMap
+abc
+thinning's
+newElem
+jobOptions
+getAssociationObjects
+myarena
+lvalues
+CategoryOrTraversal
+PTAss
+accessors
+Mytype
+raiseInvalidErrorBase
+MyElement
+rdata
+adaptors
+toPersistentNomap
+DVL's
+endcode
+aFoo
+ftemplate
+ExtractKey
+ArenaHandleBaseT
+defaultDataSource
+IdentifiedState
+lvalue
+ElementHolder
+adaptor
+preload
+ifdef
+AssociationBase
+theContext
+AssociationObject
+ArenaHeader
+ElementLinks
+toIdentified
+wrongvint
+AssociationObjects
+Baz
+overridable
+const
+SGTools
+NULLLINK
+DefaultKeyState
+getDataSourcePointerFunc
+libstdc
+persistable
+SGgetDataSource
+allocator
+Allocator
+allocators
+AthAllocators
+ATLALLOCATORS
+unallocated
+doesn
+hasn
+isn
+ve
+shouldn
+list2
+list1
+instantiations
+ArenaSharedHeapSTLAllocators
+wasn
+inuse
+elts
+a1
+a2
+test1
+a3
+test2
+test3
+test4
+p1
+p2
+Payload2
+alloc2
+alloc1
+JobOptionsSvc
+ain
+resizing
diff --git a/Control/AthAllocators/share/ArenaAllocatorBase_test.ref b/Control/AthAllocators/share/ArenaAllocatorBase_test.ref
new file mode 100755
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/Control/AthAllocators/share/ArenaAllocatorCreator_test.ref b/Control/AthAllocators/share/ArenaAllocatorCreator_test.ref
new file mode 100755
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/Control/AthAllocators/share/ArenaAllocatorRegistry_test.ref b/Control/AthAllocators/share/ArenaAllocatorRegistry_test.ref
new file mode 100755
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/Control/AthAllocators/share/ArenaBase_test.ref b/Control/AthAllocators/share/ArenaBase_test.ref
new file mode 100755
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/Control/AthAllocators/share/ArenaBlockAllocatorBase_test.ref b/Control/AthAllocators/share/ArenaBlockAllocatorBase_test.ref
new file mode 100755
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/Control/AthAllocators/share/ArenaBlock_test.ref b/Control/AthAllocators/share/ArenaBlock_test.ref
new file mode 100755
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/Control/AthAllocators/share/ArenaCachingHandle_test.ref b/Control/AthAllocators/share/ArenaCachingHandle_test.ref
new file mode 100755
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/Control/AthAllocators/share/ArenaHandleBaseAllocT_test.ref b/Control/AthAllocators/share/ArenaHandleBaseAllocT_test.ref
new file mode 100755
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/Control/AthAllocators/share/ArenaHandleBaseT_test.ref b/Control/AthAllocators/share/ArenaHandleBaseT_test.ref
new file mode 100755
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/Control/AthAllocators/share/ArenaHandleBase_test.ref b/Control/AthAllocators/share/ArenaHandleBase_test.ref
new file mode 100755
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/Control/AthAllocators/share/ArenaHandle_test.ref b/Control/AthAllocators/share/ArenaHandle_test.ref
new file mode 100755
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/Control/AthAllocators/share/ArenaHeaderGaudiClear_test.ref b/Control/AthAllocators/share/ArenaHeaderGaudiClear_test.ref
new file mode 100755
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/Control/AthAllocators/share/ArenaHeader_test.ref b/Control/AthAllocators/share/ArenaHeader_test.ref
new file mode 100755
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/Control/AthAllocators/share/ArenaHeapAllocator_test.ref b/Control/AthAllocators/share/ArenaHeapAllocator_test.ref
new file mode 100755
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/Control/AthAllocators/share/ArenaHeapSTLAllocator_test.ref b/Control/AthAllocators/share/ArenaHeapSTLAllocator_test.ref
new file mode 100644
index 0000000000000000000000000000000000000000..76983460f7f43b842604ab76921a6ea289362661
--- /dev/null
+++ b/Control/AthAllocators/share/ArenaHeapSTLAllocator_test.ref
@@ -0,0 +1,3 @@
+test1
+test2
+test3
diff --git a/Control/AthAllocators/share/ArenaPoolAllocator_test.ref b/Control/AthAllocators/share/ArenaPoolAllocator_test.ref
new file mode 100755
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/Control/AthAllocators/share/ArenaPoolSTLAllocator_test.ref b/Control/AthAllocators/share/ArenaPoolSTLAllocator_test.ref
new file mode 100644
index 0000000000000000000000000000000000000000..fadbf1d8531cefc931988be7e19da5fb524c3e74
--- /dev/null
+++ b/Control/AthAllocators/share/ArenaPoolSTLAllocator_test.ref
@@ -0,0 +1,4 @@
+test1
+test2
+test3
+test4
diff --git a/Control/AthAllocators/share/ArenaSharedHeapSTLAllocator_test.ref b/Control/AthAllocators/share/ArenaSharedHeapSTLAllocator_test.ref
new file mode 100644
index 0000000000000000000000000000000000000000..76983460f7f43b842604ab76921a6ea289362661
--- /dev/null
+++ b/Control/AthAllocators/share/ArenaSharedHeapSTLAllocator_test.ref
@@ -0,0 +1,3 @@
+test1
+test2
+test3
diff --git a/Control/AthAllocators/share/Arena_test.ref b/Control/AthAllocators/share/Arena_test.ref
new file mode 100755
index 0000000000000000000000000000000000000000..e69de29bb2d1d6434b8b29ae775ad8c2e48c5391
diff --git a/Control/AthAllocators/share/DataPool_test.ref b/Control/AthAllocators/share/DataPool_test.ref
new file mode 100755
index 0000000000000000000000000000000000000000..21159b5cdedac7044fe7546ed698f240706774f5
--- /dev/null
+++ b/Control/AthAllocators/share/DataPool_test.ref
@@ -0,0 +1,42 @@
+
+
+Initializing Gaudi ApplicationMgr using job opts ../share/DataPool_test.txt
+JobOptionsSvc        INFO # =======> /afs/cern.ch/user/s/ssnyder/atlas-work5/Control/DataModel/run/../share/DataPool_test.txt)
+JobOptionsSvc        INFO # (5,1): ApplicationMgr.DLLs += ["StoreGate"]
+JobOptionsSvc        INFO # (6,1): MessageSvc.OutputLevel = 2
+JobOptionsSvc        INFO # (8,1): ApplicationMgr.ExtSvc += ["IncidentSvc", "ChronoStatSvc", "AuditorSvc"]
+JobOptionsSvc        INFO Job options successfully read in from ../share/DataPool_test.txt
+ApplicationMgr      DEBUG Getting my own properties
+ApplicationMgr    SUCCESS 
+====================================================================================================================================
+                                                   Welcome to ApplicationMgr (GaudiCoreSvc v1r3p3)
+                                          running on lxplus446.cern.ch on Mon Apr 22 17:38:11 2013
+====================================================================================================================================
+ApplicationMgr       INFO Successfully loaded modules : StoreGate
+ApplicationMgr       INFO Application Manager Configured successfully
+ServiceManager      DEBUG Initializing service IncidentSvc
+IncidentSvc         DEBUG Service base class initialized successfully
+ServiceManager      DEBUG Initializing service ChronoStatSvc
+ChronoStatSvc       DEBUG Service base class initialized successfully
+ChronoStatSvc        INFO  Number of skipped events for MemStat-1
+ServiceManager      DEBUG Initializing service AuditorSvc
+AuditorSvc          DEBUG Service base class initialized successfully
+ServiceManager      DEBUG Initializing service AppMgrRunable
+AppMgrRunable       DEBUG Service base class initialized successfully
+ServiceManager      DEBUG Initializing service EventLoopMgr
+EventLoopMgr        DEBUG Service base class initialized successfully
+IncidentSvc         DEBUG Adding [AbortEvent] listener '<unknown>' with priority 0
+EventDataSvc        DEBUG Service base class initialized successfully
+EventPersistenc...  DEBUG Service base class initialized successfully
+EventLoopMgr      WARNING Unable to locate service "EventSelector" 
+EventLoopMgr      WARNING No events will be processed from external input.
+HistogramDataSvc    DEBUG Service base class initialized successfully
+HistogramPersis...  DEBUG  'CnvServices':[ 'RootHistSvc' ]
+HistogramPersis...  DEBUG Service base class initialized successfully
+HistogramPersis...WARNING Histograms saving not required.
+ApplicationMgr       INFO Application Manager Initialized successfully
+ApplicationMgr Ready
+ *** DataPool test in progress: 
+IncidentSvc         DEBUG Adding [BeginEvent] listener '<unknown>' with priority 100
+ **** DataPool test successfully completed **** 
+ChronoStatSvc        INFO Time User   : Tot=    0 [us]                                             #=  1
diff --git a/Control/AthAllocators/share/DataPool_test.txt b/Control/AthAllocators/share/DataPool_test.txt
new file mode 100755
index 0000000000000000000000000000000000000000..16fd9780103d6385ae566a851a76c960c5248f31
--- /dev/null
+++ b/Control/AthAllocators/share/DataPool_test.txt
@@ -0,0 +1,11 @@
+// common job opts for SG unit tests
+
+// $Id: DataPool_test.txt,v 1.1 2003-04-02 19:35:10 calaf Exp $
+
+ApplicationMgr.DLLs += { "StoreGate" };
+MessageSvc.OutputLevel = 2;
+
+ApplicationMgr.ExtSvc += {"IncidentSvc", "ChronoStatSvc", "AuditorSvc"};
+
+//AuditorSvc.Auditors += {"ChronoAuditor", "MemStatAuditor"};
+//MemStatAuditor.OutputLevel = 4;
diff --git a/Control/AthAllocators/src/Arena.cxx b/Control/AthAllocators/src/Arena.cxx
new file mode 100755
index 0000000000000000000000000000000000000000..df1c3ec5ff80efbf2a4d4ce30fc4b60e6c738c02
--- /dev/null
+++ b/Control/AthAllocators/src/Arena.cxx
@@ -0,0 +1,155 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// $Id: Arena.cxx 470529 2011-11-24 23:54:22Z ssnyder $
+/**
+ * @file  AthAllocators/src/Arena.cxx
+ * @author scott snyder
+ * @date May 2007
+ * @brief Collection of memory allocators with a common lifetime.
+ *        Out-of-line implementations.
+ */
+
+#include "AthAllocators/Arena.h"
+#include "AthAllocators/ArenaAllocatorBase.h"
+
+namespace SG {
+
+
+/**
+ * @brief Constructor.
+ * @param name The name of this @c Arena; to use in reports.
+ * @param header The header with which this @c Arena is associated.
+ *        If defaulted, the global default @c ArenaHeader will be used.
+ */
+Arena::Arena (const std::string& name, ArenaHeader* header /*= 0*/)
+  : m_header (header),
+    m_name (name)
+{
+  if (!m_header)
+    m_header = SG::ArenaHeader::defaultHeader();
+  m_header->addArena (this);
+}
+
+
+/**
+ * @brief Destructor.
+ */
+Arena::~Arena()
+{
+  m_header->delArena (this);
+  for (size_t i = 0; i < m_allocs.size(); i++)
+    delete m_allocs[i];
+}
+
+
+/**
+ * @brief reset all contained allocators.  All elements will be freed.
+ */
+void Arena::reset()
+{
+  for (size_t i = 0; i < m_allocs.size(); i++) {
+    if (m_allocs[i])
+      m_allocs[i]->reset();
+  }
+}
+
+
+/**
+ * @brief erase all contained allocators.  All elements will be freed,
+ *        and the memory returned to the system.
+ */
+void Arena::erase()
+{
+  for (size_t i = 0; i < m_allocs.size(); i++) {
+    if (m_allocs[i])
+      m_allocs[i]->erase();
+  }
+}
+
+
+/**
+ * @brief Generate a report of the memory in use by this @c Arena.
+ * @param os The stream to which to write the report.
+ */
+void Arena::report (std::ostream& os) const
+{
+  bool first = true;
+  for (size_t i = 0; i < m_allocs.size(); i++) {
+    if (m_allocs[i]) {
+      if (first) {
+        ArenaAllocatorBase::Stats::header (os);
+        os << std::endl;
+        first = false;
+      }
+      m_allocs[i]->report (os);
+    }
+  }
+}
+
+
+/**
+ * @brief Return statistics summed over all allocators in this @c Arena.
+ */
+const ArenaAllocatorBase::Stats& Arena::stats () const
+{
+  m_stats = ArenaAllocatorBase::Stats();
+  for (size_t i = 0; i < m_allocs.size(); i++) {
+    if (m_allocs[i]) {
+      m_stats += m_allocs[i]->stats();
+    }
+  }
+  return m_stats;
+}
+
+
+/**
+ * @brief Return the @c ArenaHeader with which this @c Arena is associated.
+ */
+ArenaHeader* Arena::header() const
+{
+  return m_header;
+}
+
+
+/**
+ * @brief Return this @c Arena's name.
+ */
+const std::string& Arena::name() const
+{
+  return m_name;
+}
+
+
+/**
+ * @brief Make this @c Arena the current one for its @c ArenaHeader.
+ * @returns The previously current allocator vector.
+ */
+ArenaHeader::ArenaAllocVec_t* Arena::makeCurrent()
+{
+  return m_header->setAllocVec (&m_allocs);
+}
+
+
+/**
+ * @brief Constructor.  Make @c a current.
+ * @param a The @c Arena to make current.
+ */
+Arena::Push::Push (Arena& a)
+  : m_header (a.header()),
+    m_allocs (a.makeCurrent())
+{
+}
+
+
+/**
+ * @brief Destructor.  Undoes the effect of the constructor.
+ */
+Arena::Push::~Push()
+{
+  m_header->setAllocVec (m_allocs);
+}
+
+
+} // namespace SG
diff --git a/Control/AthAllocators/src/ArenaAllocatorBase.cxx b/Control/AthAllocators/src/ArenaAllocatorBase.cxx
new file mode 100755
index 0000000000000000000000000000000000000000..466807f98bfb97170071664d8c18f2f810a7e071
--- /dev/null
+++ b/Control/AthAllocators/src/ArenaAllocatorBase.cxx
@@ -0,0 +1,136 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// $Id: ArenaAllocatorBase.cxx 470529 2011-11-24 23:54:22Z ssnyder $
+/**
+ * @file  AthAllocators/src/ArenaAllocatorBase.cxx
+ * @author scott snyder
+ * @date May 2007
+ * @brief Common base class for arena allocator classes.
+ *        Out-of-line implementations.
+ */
+
+#include "AthAllocators/ArenaAllocatorBase.h"
+#include <ostream>
+#include <iomanip>
+
+
+namespace SG {
+
+
+/**
+ * @brief Constructor for a single statistic.
+ */
+ArenaAllocatorBase::Stats::Stat::Stat()
+  : inuse (0),
+    free (0),
+    total (0)
+{
+}
+
+
+/**
+ * @brief Zero a statistic.
+ */
+void ArenaAllocatorBase::Stats::Stat::clear()
+{
+  inuse = free = total = 0;
+}
+
+
+/**
+ * @brief Accumulate a statistic.
+ * @param other The statistic to accumulate into this one.
+ */
+ArenaAllocatorBase::Stats::Stat&
+ArenaAllocatorBase::Stats::Stat::operator+= (const Stat& other)
+{
+  inuse += other.inuse;
+  free += other.free;
+  total += other.total;
+  return *this;
+}
+
+
+/* (hide from doxygen)
+ * @brief Format a statistic structure.
+ * @param os The stream to which to write.
+ * @param stat The statistic structure to write.
+ */
+std::ostream& operator<< (std::ostream& os,
+                          const ArenaAllocatorBase::Stats::Stat& stat)
+{
+  os << std::setw(7) << stat.inuse << "/"
+     << std::setw(7) << stat.free << "/" 
+     << std::setw(7) << stat.total;
+  return os;
+}
+
+
+//===========================================================================
+
+
+/**
+ * @brief Zero a complete statistics block.
+ */
+void ArenaAllocatorBase::Stats::clear()
+{
+  elts.clear();
+  bytes.clear();
+  blocks.clear();
+}
+
+
+/**
+ * @brief Accumulate a complete statistics block.
+ * @param other The statistics block to accumulate into this one.
+ */
+ArenaAllocatorBase::Stats&
+ArenaAllocatorBase::Stats::operator+= (const Stats& other)
+{
+  elts += other.elts;
+  bytes += other.bytes;
+  blocks += other.blocks;
+  return *this;
+}
+
+
+/* (hide from doxygen)
+ * @brief Format a complete statistics structure.
+ * @param os The stream to which to write.
+ * @param stats The statistics structure to write.
+ */
+std::ostream& operator<< (std::ostream& os,
+                          const ArenaAllocatorBase::Stats& stats)
+{
+  os << stats.elts << " " << stats.bytes << " " << stats.blocks;
+  return os;
+}
+
+
+/**
+ * @brief Write a header for the statistics report.
+ * @param os The stream to which to write.
+ */
+void ArenaAllocatorBase::Stats::header (std::ostream& os)
+{
+  os << "Elts InUse/Free/Total"
+     << "   Bytes InUse/Free/Total  Blocks InUse/Free/Total";
+}
+
+
+//===========================================================================
+
+
+/**
+ * @brief Generate a report on the memory usage of this allocator.
+ * @param os Stream to which the report should be written.
+ */
+void ArenaAllocatorBase::report (std::ostream& os) const
+{
+  os << " " << stats() << "  " << name() << std::endl;
+}
+
+
+} // namespace SG
diff --git a/Control/AthAllocators/src/ArenaAllocatorRegistry.cxx b/Control/AthAllocators/src/ArenaAllocatorRegistry.cxx
new file mode 100755
index 0000000000000000000000000000000000000000..48eaeb5c73b3d8aea4df1428ae59488821e67e1e
--- /dev/null
+++ b/Control/AthAllocators/src/ArenaAllocatorRegistry.cxx
@@ -0,0 +1,203 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+/**
+ * @file  AthAllocators/src/ArenaAllocatorRegistry.cxx
+ * @author scott snyder
+ * @date May 2007
+ * @brief Registry of allocator factories.
+ *        Out-of-line implementation.
+ */
+
+// xxx FIXME: not thread-safe.
+
+#include "AthAllocators/ArenaAllocatorRegistry.h"
+#include "AthAllocators/ArenaAllocatorCreator.h"
+#include <vector>
+#include <map>
+#include <cassert>
+
+
+namespace SG {
+
+
+/**
+ * @brief ArenaAllocatorRegistry implementation class.
+ */
+class ArenaAllocatorRegistryImpl
+{
+public:
+  /// Destructor.
+  ~ArenaAllocatorRegistryImpl();
+
+
+  /**
+   * @brief Register a new allocator type.
+   * @param name The name of the allocator type.  Must not already exist.
+   * @param creator The factory object to create instances of this type.
+   *                The registry takes ownership of this pointer.
+   * @return The new integer index for this allocator type.
+   */
+  size_t registerCreator (const std::string& name,
+                          ArenaAllocatorCreator* creator);
+
+
+  /**
+   * @brief Look up the index for an allocator type name.
+   * @param name The name of the allocator type to find.
+   * @return The index corresponding to the type, or @c std::string::npos
+   *         if it hasn't yet been registered.
+   */
+  size_t lookup (const std::string& name);
+
+
+  /**
+   * @brief Create a new instance of an allocator.
+   * @param i The index of the allocator to create.
+   * @return A newly-allocated allocator instance.
+   */
+  ArenaAllocatorBase* create (size_t i);
+
+
+private:
+  /// Map from names to indices.
+  typedef std::map<std::string, size_t> map_t;
+  map_t m_map;
+
+  /// Vector of factory instances.
+  std::vector<ArenaAllocatorCreator*> m_creators;
+};
+
+
+/**
+ * @brief Destructor.
+ */
+ArenaAllocatorRegistryImpl::~ArenaAllocatorRegistryImpl()
+{
+  // Free the saved factory instances.
+  for (size_t i = 0; i < m_creators.size(); i++)
+    delete m_creators[i];
+}
+
+
+/**
+ * @brief Register a new allocator type.
+ * @param name The name of the allocator type.  Must not already exist.
+ * @param creator The factory object to create instances of this type.
+ *                The registry takes ownership of this pointer.
+ * @return The new integer index for this allocator type.
+ */
+size_t
+ArenaAllocatorRegistryImpl::registerCreator (const std::string& name,
+                                             ArenaAllocatorCreator* creator)
+{
+  // The name must not already exist.
+  assert (m_map.count (name) == 0);
+
+  // The new index.
+  size_t i = m_creators.size();
+
+  // Remember the index and store the creator.
+  m_map[name] = i;
+  m_creators.push_back (creator);
+  return i;
+}
+
+
+/**
+ * @brief Look up the index for an allocator type name.
+ * @param name The name of the allocator type to find.
+ * @return The index corresponding to the type, or @c std::string::npos
+ *         if it hasn't yet been registered.
+ */
+size_t ArenaAllocatorRegistryImpl::lookup (const std::string& name)
+{
+  map_t::iterator it = m_map.find (name);
+  if (it == m_map.end())
+    return std::string::npos;
+  return it->second;
+}
+
+
+/**
+ * @brief Create a new instance of an allocator.
+ * @param i The index of the allocator to create.
+ * @return A newly-allocated allocator instance.
+ */
+ArenaAllocatorBase* ArenaAllocatorRegistryImpl::create (size_t i)
+{
+  assert (i < m_creators.size());
+  return m_creators[i]->create();
+}
+
+
+//==========================================================================
+
+/**
+ * @brief Register a new allocator type.
+ * @param name The name of the allocator type.  Must not already exist.
+ * @param creator The factory object to create instances of this type.
+ *                The registry takes ownership of this pointer.
+ * @return The new integer index for this allocator type.
+ */
+size_t
+ArenaAllocatorRegistry::registerCreator (const std::string& name,
+                                         ArenaAllocatorCreator* creator)
+{
+  return m_impl->registerCreator (name, creator);
+}
+
+
+/**
+ * @brief Look up the index for an allocator type name.
+ * @param name The name of the allocator type to find.
+ * @return The index corresponding to the type, or @c std::string::npos
+ *         if it hasn't yet been registered.
+ */
+size_t ArenaAllocatorRegistry::lookup (const std::string& name)
+{
+  return m_impl->lookup (name);
+}
+
+
+/**
+ * @brief Create a new instance of an allocator.
+ * @param i The index of the allocator to create.
+ * @return A newly-allocated allocator instance.
+ */
+ArenaAllocatorBase* ArenaAllocatorRegistry::create (size_t i)
+{
+  return m_impl->create (i);
+}
+
+
+/**
+ * @brief Return a pointer to the global @c ArenaAllocatorRegistry instance.
+ */
+ArenaAllocatorRegistry* ArenaAllocatorRegistry::instance()
+{
+  static ArenaAllocatorRegistry tmp;
+  return &tmp;
+}
+
+
+/**
+ * @brief Constructor.
+ */
+ArenaAllocatorRegistry::ArenaAllocatorRegistry()
+  : m_impl (new ArenaAllocatorRegistryImpl)
+{
+}
+
+
+/**
+ * @brief Destructor.
+ */
+ArenaAllocatorRegistry::~ArenaAllocatorRegistry()
+{
+  delete m_impl;
+}
+
+
+} // namespace SG
diff --git a/Control/AthAllocators/src/ArenaBlock.cxx b/Control/AthAllocators/src/ArenaBlock.cxx
new file mode 100755
index 0000000000000000000000000000000000000000..82c675b1b1588a3a24fabf34b49b54c5697d731e
--- /dev/null
+++ b/Control/AthAllocators/src/ArenaBlock.cxx
@@ -0,0 +1,147 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// $Id: ArenaBlock.cxx 470529 2011-11-24 23:54:22Z ssnyder $
+/**
+ * @file  AthAllocators/src/ArenaBlock.cxx
+ * @author scott snyder
+ * @date May 2007
+ * @brief These are large blocks of memory that get allocated and
+ *        divided up into smaller, uniform elements.
+ *        Out-of-line implementation.
+ */
+
+
+#include "AthAllocators/ArenaBlock.h"
+#include <cstdlib>
+
+
+namespace SG {
+
+
+/// Global number of blocks in use.
+size_t ArenaBlock::s_nactive = 0;
+
+
+/**
+ * @brief Create a new block.
+ * @param n The number of elements in the new block.
+ * @param elt_size The size in bytes of each element.
+ * @param ctor If non-null, call this function on each element
+ *             in the new block.
+ */
+ArenaBlock*
+ArenaBlock::newBlock (size_t n, size_t elt_size, func_t* ctor)
+{
+  size_t tot_size = n*elt_size + ArenaBlockBodyOffset;
+  ArenaBlock* p = reinterpret_cast<ArenaBlock*> (std::malloc (tot_size));
+  ++s_nactive;
+  p->m_link = 0;
+  p->m_elt_size = elt_size;
+  p->m_size = n;
+  if (ctor) {
+    for (size_t i = 0; i < n; i++)
+      ctor (p->index (i, elt_size));
+  }
+  return p;
+}
+
+
+/**
+ * @brief Destroy a block.
+ * @param p The block to destroy.
+ * @param dtor If non-null, call this function on each element in the block.
+ */
+void ArenaBlock::destroy (ArenaBlock* p, func_t* dtor)
+{
+  if (dtor) {
+    size_t elt_size = p->eltSize();
+    size_t n = p->size();
+    for (size_t i = 0; i < n; i++)
+      dtor (p->index (i, elt_size));
+  }
+  --s_nactive;
+  std::free (p);
+}
+
+
+/**
+ * @brief Destroy all blocks in a list.
+ * @param p The first block to destroy.
+ * @param dtor If non-null, call this function on each element the blocks.
+ *
+ * Will destroy all blocks in the linked list headed by @c p.
+ */
+void
+ArenaBlock::destroyList (ArenaBlock* p, func_t* dtor)
+{
+  while (p) {
+    ArenaBlock* next = p->link();
+    destroy (p, dtor);
+    p = next;
+  }
+}
+
+
+/**
+ * @brief Concatenate two lists of blocks.
+ * @param headp Pointer to pointer to the head of the list.
+ * @param tail Pointer to list to append to the end.
+ *
+ * The list @c tail is appended to the end of the list @c *headp.
+ * (@c headp is a pointer-to-pointer to be able to handle the case
+ * of an empty list.)
+ */
+void ArenaBlock::appendList (ArenaBlock** link, ArenaBlock* tail)
+{
+  while (*link)
+    link = &(*link)->link();
+  *link = tail;
+}
+
+
+/**
+ * @brief Call a function on elements in a list of blocks.
+ * @param p Pointer to the head of the list.
+ * @param func Function to apply.
+ * @param Number of elements in the first block on which
+ *        to call the function.
+ *
+ * This will loop through the elements in all blocks on the list,
+ * calling @c func.  In the first block, we apply the function
+ * only to the first @c n elements.  In subsequent blocks, the
+ * function is applied to all elements.
+ */
+void ArenaBlock::applyList (ArenaBlock* p,
+                            func_t* func,
+                            size_t n)
+{
+  if (!p) return;
+  size_t elt_size = p->eltSize();
+  if (n > p->size())
+    n = p->size();
+  while (1) {
+    for (size_t i = 0; i < n; i++)
+      func (p->index (i, elt_size));
+    p = p->link();
+    if (!p) break;
+    n = p->size();
+  }
+}
+
+
+/**
+ * @brief Return the per-block memory overhead, in bytes.
+ *
+ * This tries to include malloc overhead as well, but that may just
+ * be an estimate.  Don't rely on this to be exact.
+ */
+size_t ArenaBlock::overhead()
+{
+  // The extra size_t is a guesstimate of malloc overhead.
+  return ArenaBlockBodyOffset + sizeof (size_t);
+}
+
+
+} // namespace SG
diff --git a/Control/AthAllocators/src/ArenaBlockAllocatorBase.cxx b/Control/AthAllocators/src/ArenaBlockAllocatorBase.cxx
new file mode 100755
index 0000000000000000000000000000000000000000..de10b43833ce76742a60861dd4eb20f411e4e481
--- /dev/null
+++ b/Control/AthAllocators/src/ArenaBlockAllocatorBase.cxx
@@ -0,0 +1,185 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// $Id: ArenaBlockAllocatorBase.cxx 470529 2011-11-24 23:54:22Z ssnyder $
+/**
+ * @file  AthAllocators/src/ArenaBlockAllocatorBase.cxx
+ * @author scott snyder
+ * @date May 2007
+ * @brief Common functionality for block-oriented allocators.
+ *        Out-of-line implementations.
+ */
+
+#include "AthAllocators/ArenaBlockAllocatorBase.h"
+#include "AthAllocators/ArenaBlock.h"
+
+
+namespace SG {
+
+
+/**
+ * @brief Constructor.
+ * @param params The parameters structure for this allocator.
+ *               See @c  ArenaAllocatorBase.h for the contents.
+ */
+ArenaBlockAllocatorBase::ArenaBlockAllocatorBase (const Params& params)
+  : m_params (params),
+    m_blocks (0),
+    m_freeblocks (0)
+{
+}
+
+
+/**
+ * @brief Set the total number of elements cached by the allocator.
+ * @param size The desired pool size.
+ *
+ * This allows changing the number of elements that are currently free
+ * but cached.  Any allocated elements are not affected by this call.
+ *
+ * If @c size is greater than the total number of elements currently
+ * cached, then more will be allocated.  This will preferably done
+ * with a single block, but that is not guaranteed; in addition, the
+ * allocator may allocate more elements than is requested.
+ *
+ * If @c size is smaller than the total number of elements currently
+ * cached, as many blocks as possible will be released back to the system.
+ * It may not be possible to release the number of elements requested;
+ * this should be implemented on a best-effort basis.
+ */
+void ArenaBlockAllocatorBase::reserve (size_t size)
+{
+  if (size > m_stats.elts.total) {
+    // Growing the pool.
+    // Make a new block of the required size (but not less than nblock).
+    size_t sz = size - m_stats.elts.total;
+    if (sz < m_params.nblock)
+      sz = m_params.nblock;
+    ArenaBlock* newblock = ArenaBlock::newBlock (sz, m_params.eltSize,
+                                                 m_params.constructor);
+
+    // Update statistics (others are derived in stats()).
+    ++m_stats.blocks.free;
+    ++m_stats.blocks.total;
+    m_stats.elts.total += sz;
+
+    // Add to the free list.
+    newblock->link() = m_freeblocks;
+    m_freeblocks = newblock;
+  }
+  else {
+    // Shrinking the pool.
+    // Loop while we can get rid of the first free block.
+    while (size < m_stats.elts.total &&
+           m_freeblocks &&
+           m_freeblocks->size() <= (m_stats.elts.total - size))
+    {
+      // Remove it from the free list.
+      ArenaBlock* p = m_freeblocks;
+      m_freeblocks = m_freeblocks->link();
+
+      // Update statistics (others are derived in stats()).
+      m_stats.elts.total -= p->size();
+      --m_stats.blocks.free;
+      --m_stats.blocks.total;
+
+      // Free the block.
+      ArenaBlock::destroy (p, m_params.destructor);
+    }
+  }
+}
+
+
+/**
+ * @brief Free all allocated elements and release memory back to the system.
+ *
+ * All elements allocated are freed, and all allocated blocks of memory
+ * are released back to the system.
+ * @c destructor should be called on them if it was provided
+ * (preceded by @c clear if provided and @c mustClear was set).
+ */
+void ArenaBlockAllocatorBase::erase()
+{
+  // Do we need to run clear() on the allocated elements?
+  // If so, do so via reset().
+  if (m_params.mustClear && m_params.clear)
+    reset();
+
+  // Kill the block lists (both free and in use).
+  ArenaBlock::destroyList (m_blocks, m_params.destructor);
+  ArenaBlock::destroyList (m_freeblocks, m_params.destructor);
+  m_blocks = m_freeblocks = 0;
+
+  // Reset statistics.
+  m_stats.clear();
+}
+
+
+/**
+ * @brief Return the statistics block for this allocator.
+ */
+const ArenaAllocatorBase::Stats& ArenaBlockAllocatorBase::stats() const
+{
+  // Calculate derived statistics.
+  m_stats.elts.free = m_stats.elts.total - m_stats.elts.inuse;
+  m_stats.bytes.inuse = m_stats.elts.inuse   * m_params.eltSize +
+                        m_stats.blocks.inuse * ArenaBlock::overhead();
+  m_stats.bytes.total = m_stats.elts.total   * m_params.eltSize +
+                        m_stats.blocks.total * ArenaBlock::overhead();
+  m_stats.bytes.free  = m_stats.elts.free   * m_params.eltSize +
+                        m_stats.blocks.free * ArenaBlock::overhead();
+  return m_stats;
+}
+
+
+/**
+ * @brief Return the name of this allocator.
+ */
+const std::string& ArenaBlockAllocatorBase::name() const
+{
+  return m_params.name;
+}
+
+
+/**
+ * @brief Return this allocator's parameters.
+ */
+const ArenaAllocatorBase::Params&
+ArenaBlockAllocatorBase::params() const
+{
+  return m_params;
+}
+
+
+/**
+ * @brief Return an empty block, either newly-allocated or from the
+ *        free list.  Update statistics appropriately.
+ */
+ArenaBlock* ArenaBlockAllocatorBase::getBlock()
+{
+  ArenaBlock* newblock = m_freeblocks;
+  if (newblock) {
+    // There's something on the free list.  Remove it and update statistics.
+    m_freeblocks = newblock->link();
+    --m_stats.blocks.free;
+  }
+  else {
+    // Otherwise, we need to make a new block.
+    newblock = ArenaBlock::newBlock (m_params.nblock, m_params.eltSize,
+                                     m_params.constructor);
+    m_stats.elts.total += m_params.nblock;
+    ++m_stats.blocks.total;
+  }
+  // Finish updating statistics.
+  // (Remaining ones are computed in stats().)
+  ++m_stats.blocks.inuse;
+
+  // Link it into the in-use list and return.
+  newblock->link() = m_blocks;
+  m_blocks = newblock;
+  return newblock;
+}
+
+
+} // namespace SG
diff --git a/Control/AthAllocators/src/ArenaHandleBase.cxx b/Control/AthAllocators/src/ArenaHandleBase.cxx
new file mode 100755
index 0000000000000000000000000000000000000000..c7728e157c70b2411fbb35ec39522b4545f95780
--- /dev/null
+++ b/Control/AthAllocators/src/ArenaHandleBase.cxx
@@ -0,0 +1,103 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// $Id: ArenaHandleBase.cxx 470529 2011-11-24 23:54:22Z ssnyder $
+/**
+ * @file  AthAllocators/src/ArenaHandleBase.cxx
+ * @author scott snyder
+ * @date May 2007
+ * @brief Base class for all @c Handle classes, containing parts that
+ *        do not depend on the referenced type.
+ */
+
+
+#include "AthAllocators/ArenaHandleBase.h"
+#include "AthAllocators/ArenaAllocatorBase.h"
+
+
+namespace SG {
+
+
+/**
+ * @brief Constructor.
+ * @param header The group of Arenas which this Handle may reference.
+ *               May be null to select the global default.
+ * @param index The index of this Handle's Allocator type.
+ */
+ArenaHandleBase::ArenaHandleBase (ArenaHeader* header, size_t index)
+  : m_header (header),
+    m_index (index)
+{
+  // If the supplied header is null, use the global default.
+  if (!m_header)
+    m_header = ArenaHeader::defaultHeader();
+}
+
+
+/**
+ * @brief Free all allocated elements (of this type in the current Arena).
+ *
+ * All elements allocated in the current Arena by our associated
+ * Allocator are returned to the
+ * free state.  @c clear should be called on them if it was provided.
+ * The elements may continue to be cached internally, without
+ * returning to the system.
+ */
+void ArenaHandleBase::reset()
+{
+  return baseAllocator()->reset();
+}
+
+
+/**
+ * @brief Free all allocated elements and release memory back to the system
+ *        (of this type in the current Arena).
+ *
+ * All elements allocated in the current Arena by our associated
+ * Allocator are freed, and all allocated blocks of memory
+ * are released back to the system.
+ * @c destructor should be called on them if it was provided
+ * (preceded by @c clear if provided and @c mustClear was set).
+ */
+void ArenaHandleBase::erase()
+{
+  return baseAllocator()->erase();
+}
+
+
+/**
+ * @brief Set the total number of elements cached by the allocator
+ *        (in the current Arena).
+ * @param size The desired pool size.
+ *
+ * This allows changing the number of elements that are currently free
+ * but cached.  Any allocated elements are not affected by this call.
+ *
+ * If @c size is greater than the total number of elements currently
+ * cached, then more will be allocated.  This will preferably done
+ * with a single block, but that is not guaranteed; in addition, the
+ * allocator may allocate more elements than is requested.
+ *
+ * If @c size is smaller than the total number of elements currently
+ * cached, as many blocks as possible will be released back to the system.
+ * It may not be possible to release the number of elements requested;
+ * this should be implemented on a best-effort basis.
+ */
+void ArenaHandleBase::reserve (size_t size)
+{
+  return baseAllocator()->reserve (size);
+}
+
+
+/**
+ * @brief Return the statistics block for this allocator,
+ * for the current Arena.
+ */
+const ArenaAllocatorBase::Stats& ArenaHandleBase::stats() const
+{
+  return baseAllocator()->stats();
+}
+
+
+} // namespace SG
diff --git a/Control/AthAllocators/src/ArenaHeader.cxx b/Control/AthAllocators/src/ArenaHeader.cxx
new file mode 100755
index 0000000000000000000000000000000000000000..39452d850e7978a8b88451c843e4ee813d0e7aca
--- /dev/null
+++ b/Control/AthAllocators/src/ArenaHeader.cxx
@@ -0,0 +1,210 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// $Id: ArenaHeader.cxx 470529 2011-11-24 23:54:22Z ssnyder $
+/**
+ * @file  AthAllocators/src//ArenaHeader.cxx
+ * @author scott snyder
+ * @date May 2007
+ * @brief Proxy for a group of Arenas.
+ *        Out-of-line implementations.
+ */
+
+#include "AthAllocators/ArenaHeader.h"
+#include "AthAllocators/ArenaHeaderGaudiClear.h"
+#include "AthAllocators/ArenaAllocatorRegistry.h"
+#include "AthAllocators/ArenaAllocatorBase.h"
+#include "AthAllocators/ArenaBase.h"
+#include <algorithm>
+#include <ostream>
+#include <sstream>
+#include <cassert>
+
+
+namespace SG {
+
+
+/**
+ * @brief Constructor.
+ */
+ArenaHeader::ArenaHeader()
+  : m_allocvec (0),
+    m_ownedAllocvec (0)
+{
+}
+
+
+/**
+ * @brief Destructor.
+ *
+ * This will clean up any memory allocated in the default Arena.
+ */
+ArenaHeader::~ArenaHeader()
+{
+  if (m_ownedAllocvec) {
+    for (size_t i = 0 ; i < m_ownedAllocvec->size(); i++)
+      delete (*m_ownedAllocvec)[i];
+    delete m_ownedAllocvec;
+  }
+}
+
+
+/**
+ * @brief Set the current Arena.
+ * @param allocvec New vector of Allocator instances.
+ * @return The previous vector.
+ *
+ * This sets the notion of the current Arena.
+ */
+ArenaHeader::ArenaAllocVec_t*
+ArenaHeader::setAllocVec (ArenaAllocVec_t* allocvec)
+{
+  ArenaAllocVec_t* ret = m_allocvec;
+  m_allocvec = allocvec;
+  return ret;
+}
+
+
+/**
+ * @brief Add a new Arena to the group.
+ * @param a The Arena to add.
+ */
+void ArenaHeader::addArena (ArenaBase* a)
+{
+  m_arenas.push_back (a);
+}
+
+
+/**
+ * @brief Remove an Arena from the group.
+ * @param a The Arena to remove.
+ *
+ * Will trip an assertion if the Arena is not in the group.
+ */
+void ArenaHeader::delArena (ArenaBase* a)
+{
+  std::vector<ArenaBase*>::iterator it =
+    std::find (m_arenas.begin(), m_arenas.end(), a);
+  assert (it != m_arenas.end());
+  m_arenas.erase (it);
+}
+
+
+/**
+ * @brief Generate a report of all Arenas in the group.
+ * @param os Stream to which to send a report.
+ */
+void ArenaHeader::report (std::ostream& os) const
+{
+  // All Allocators in the group.
+  for (size_t i = 0; i < m_arenas.size(); i++) {
+    os << "=== " << m_arenas[i]->name() << " ===" << std::endl;
+    m_arenas[i]->report (os);
+  }
+
+  // The default Arena.
+  if (m_ownedAllocvec) {
+    os << "=== default ===" << std::endl;
+    ArenaAllocatorBase::Stats::header (os);
+    os << std::endl;
+    for (size_t i = 0; i < m_ownedAllocvec->size(); i++) {
+      if ((*m_ownedAllocvec)[i])
+        (*m_ownedAllocvec)[i]->report (os);
+    }
+  }
+}
+
+
+/**
+ * @brief Generate a report of all Arenas in the group, and return
+ *        the result as a string.
+ *
+ * We have this in addition to @c report() in order to make it easier
+ * to call from scripting languages.
+ */
+std::string ArenaHeader::reportStr() const
+{
+  std::ostringstream s;
+  report (s);
+  return s.str();
+}
+
+
+/**
+ * @brief Call @c reset on all Allocators in the current Arena.
+ *
+ * All elements allocated are returned to the free state.
+ * @c clear should be called on them if it was provided.
+ * The elements may continue to be cached internally, without
+ * returning to the system.
+ */
+void ArenaHeader::reset()
+{
+  if (m_allocvec) {
+    for (size_t i = 0; i < m_allocvec->size(); i++) {
+      if ((*m_allocvec)[i])
+        (*m_allocvec)[i]->reset();
+    }
+  }
+}
+
+
+/**
+ * @brief Return the global default Header instance.
+ */
+ArenaHeader* ArenaHeader::defaultHeader()
+{
+  // FIXME xxx should be thread-local!
+  // FIXME xxx don't depend on gaudi here!
+  static ArenaHeaderGaudiClear head;
+  head.addRef();
+  head.initialize();
+  return &head;
+}
+
+
+/**
+ * @brief Make a new Allocator for index i.
+ * @param i The index of the Allocator.
+ *
+ * The Allocator vector was empty for index @c i.  Make an appropriate
+ * new Allocator, store it in the vector, and return it.  Will trip
+ * an assertion if the index is not valid.
+ */
+ArenaAllocatorBase* ArenaHeader::makeAllocator (size_t i)
+{
+  // If we don't have an Arena set, use the default one.
+  if (!m_allocvec) {
+
+    // Create the default Arena if needed.
+    if (!m_ownedAllocvec)
+      m_ownedAllocvec = new ArenaAllocVec_t;
+
+    // Install the default Arena.
+    m_allocvec = m_ownedAllocvec;
+
+    // See if the index is now in the default Arena.
+    if (i < m_allocvec->size()) {
+      ArenaAllocatorBase* allocbase = (*m_allocvec)[i];
+      if (allocbase) return allocbase;
+    }
+  }
+
+  // We have to create a new Allocator.
+  // Make sure there's room in the vector.
+  if (m_allocvec->size() <= i)
+    m_allocvec->resize (i+1);
+
+  // Create the Allocator, using the Registry.
+  ArenaAllocatorBase* alloc =
+    ArenaAllocatorRegistry::instance()->create (i);
+
+  // Install it in the vector.
+  (*m_allocvec)[i] = alloc;
+
+  return alloc;
+}
+
+
+} // namespace SG
diff --git a/Control/AthAllocators/src/ArenaHeaderGaudiClear.cxx b/Control/AthAllocators/src/ArenaHeaderGaudiClear.cxx
new file mode 100755
index 0000000000000000000000000000000000000000..0756156bccb7349df54562b2e9430def25ed7a0c
--- /dev/null
+++ b/Control/AthAllocators/src/ArenaHeaderGaudiClear.cxx
@@ -0,0 +1,131 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// $Id: ArenaHeaderGaudiClear.cxx 470529 2011-11-24 23:54:22Z ssnyder $
+/**
+ * @file  AthAllocators/src/ArenaHeaderGaudiClear.cxx
+ * @author scott snyder
+ * @date May 2007
+ * @brief An @c ArenaHeader that's cleared on every Gaudi event.
+ *        Out-of-line implementations.
+ */
+
+
+#include "AthAllocators/ArenaHeaderGaudiClear.h"
+#include "GaudiKernel/Bootstrap.h"
+#include "GaudiKernel/ISvcLocator.h"
+#include "GaudiKernel/IIncidentSvc.h"
+#include <stdexcept>
+#include <exception>
+
+
+namespace SG {
+
+
+/// True if @c disable has been called.
+bool ArenaHeaderGaudiClear::m_disabled = false;
+
+
+/**
+ * @brief Constructor.
+ */
+ArenaHeaderGaudiClear::ArenaHeaderGaudiClear()
+  : m_initialized (false),
+    m_instanceCount (0)
+{
+}
+
+
+/**
+ * @brief Register with Gaudi.
+ */
+void ArenaHeaderGaudiClear::initialize()
+{
+  // Don't do anything if we're disabled or have already been called.
+  if (m_initialized || m_disabled)
+    return;
+
+  // Find the Gaudi incident service.
+  IIncidentSvc* incsvc;
+  if (!(Gaudi::svcLocator()->service("IncidentSvc", incsvc)).isSuccess())
+  {
+    throw std::runtime_error("ArenaHeaderGaudiClear: "
+                             "Could not locate Incident Service");
+  }
+
+  // Register with the service.
+  const int PRIORITY = 100;
+  incsvc->addListener(this, "BeginEvent", PRIORITY);
+
+  m_initialized = true;
+}
+
+
+/**
+ * @brief Handle a Gaudi incident.
+ * @param inc The incident to handle.
+ */
+void ArenaHeaderGaudiClear::handle(const Incident& inc)
+{
+  // Reset on begin-event.
+  if (inc.type() == "BeginEvent")
+    reset();
+}
+
+
+/**
+ * @brief Increase the reference count.  (Required by @c IInterface.)
+ */
+unsigned long ArenaHeaderGaudiClear::addRef()
+{
+  m_instanceCount++;
+  return m_instanceCount;
+}
+
+
+/**
+ * @brief Decrease the reference count.  (Required by @c IInterface.)
+ */
+unsigned long ArenaHeaderGaudiClear::release()
+{
+  m_instanceCount--;
+  unsigned long count = m_instanceCount;
+  if (count <= 0) delete this;
+  return count;
+}
+
+
+/**
+ * @brief Return the Gaudi interface for this object.
+ *        (Required by @c IInterface.)
+ */
+StatusCode
+ArenaHeaderGaudiClear::queryInterface(const InterfaceID& riid,
+                                      void** ppvInterface)
+{
+  if (interfaceID().versionMatch(riid)) {
+    *ppvInterface = this;
+  }
+  else {
+    return StatusCode::FAILURE;
+  }
+  addRef();
+  return StatusCode::SUCCESS;
+}
+
+
+/**
+ * @brief Disable the Gaudi functionality.
+ *
+ * If this is called before @c initialize(), we will not attempt
+ * to register ourselves with Gaudi.  This can be used for running
+ * outside of the framework.
+ */
+void ArenaHeaderGaudiClear::disable()
+{
+  m_disabled = true;
+}
+
+
+} // namespace SG
diff --git a/Control/AthAllocators/src/ArenaHeapAllocator.cxx b/Control/AthAllocators/src/ArenaHeapAllocator.cxx
new file mode 100755
index 0000000000000000000000000000000000000000..9d9e546dfd44b21b497857438c531cfe99da2e47
--- /dev/null
+++ b/Control/AthAllocators/src/ArenaHeapAllocator.cxx
@@ -0,0 +1,162 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// $Id: ArenaHeapAllocator.cxx 470529 2011-11-24 23:54:22Z ssnyder $
+/**
+ * @file  AthAllocators/src/ArenaHeapAllocator.cxx
+ * @author scott snyder
+ * @date May 2007
+ * @brief Heap-based allocator.
+ *        Out-of-line implementations.
+ */
+
+#include "AthAllocators/ArenaHeapAllocator.h"
+#include "AthAllocators/ArenaBlock.h"
+#include <vector>
+#include <algorithm>
+#include <cassert>
+
+
+namespace SG {
+
+
+/**
+ * @brief Constructor.
+ * @param params The parameters structure for this allocator.
+ *               See @c  ArenaAllocatorBase.h for the contents.
+ */
+ArenaHeapAllocator::ArenaHeapAllocator (const Params& params)
+  : ArenaBlockAllocatorBase (params),
+    m_freeptr (0)
+{
+  // Consistency check.
+  assert (params.linkOffset + sizeof (pointer) <= params.eltSize);
+}
+
+
+/**
+ * @brief Destructor.  This will free all the Allocator's storage.
+ */
+ArenaHeapAllocator::~ArenaHeapAllocator()
+{
+  erase();
+}
+
+
+/**
+ * @brief Free all allocated elements.
+ *
+ * All elements allocated are returned to the free state.
+ * @c clear should be called on them if it was provided.
+ * The elements may continue to be cached internally, without
+ * returning to the system.
+ */
+void ArenaHeapAllocator::reset()
+{
+  if (!m_blocks) return;
+  if (m_params.clear) {
+    if (m_params.canReclear || m_freeptr == 0) {
+      // Just call clear() on all blocks --- allocated or not.
+      ArenaBlock::applyList (m_blocks, m_params.clear, m_blocks->size());
+    }
+    else {
+      // We can only call clear() on allocated blocks.
+      slowClear();
+    }
+  }
+
+  // Move all blocks back to the free list.
+  ArenaBlock::appendList (&m_freeblocks, m_blocks);
+
+  // Reset state.
+  m_blocks = 0;
+  m_freeptr = 0;
+  m_stats.elts.inuse = 0;
+  m_stats.blocks.free += m_stats.blocks.inuse;
+  m_stats.blocks.inuse = 0;
+}
+
+
+/**
+ * @brief Free all allocated elements and release memory back to the system.
+ *
+ * All elements allocated are freed, and all allocated blocks of memory
+ * are released back to the system.
+ * @c destructor should be called on them if it was provided
+ * (preceded by @c clear if provided and @c mustClear was set).
+ */
+void ArenaHeapAllocator::erase()
+{
+  ArenaBlockAllocatorBase::erase();
+  m_freeptr = 0;
+}
+
+
+/**
+ * @brief Add more free elements to the pool, and allocate a new element.
+ */
+ArenaHeapAllocator::pointer ArenaHeapAllocator::refill()
+{
+  // Get a new block.
+  ArenaBlock* newblock = getBlock();
+
+  // Set up the links for the new free elements.
+  pointer lastelt = 0;
+  size_t sz = newblock->size();
+  size_t elt_size = newblock->eltSize();
+  for (size_t i=1; i < sz; i++) {
+    pointer elt = newblock->index (i, elt_size);
+    link(elt) = lastelt;
+    lastelt = elt;
+  }
+  // Set the free pointer to the next-to-last one.
+  m_freeptr = newblock->index (sz-1, elt_size);
+
+  // And return the last one.
+  return newblock->index (0, elt_size);
+}
+
+
+/**
+ * @brief Call @c clear() for all allocated elements.
+ */
+void ArenaHeapAllocator::slowClear()
+{
+  // Make a list of all free elements, in sorted order.
+  std::vector<pointer> free_ptrs;
+  free_ptrs.reserve (m_stats.elts.total - m_stats.elts.inuse);
+  for (pointer p = m_freeptr; p; p = link(p))
+    free_ptrs.push_back (p);
+  std::sort (free_ptrs.begin(), free_ptrs.end());
+
+  // Make a list of all used blocks, in sorted order.
+  std::vector<ArenaBlock*> blocks;
+  for (ArenaBlock* p = m_blocks; p; p = p->link())
+    blocks.push_back (p);
+  std::sort (blocks.begin(), blocks.end());
+
+  // Walk through both of these lists.
+  // For each block, walk through its elements, and call @c clear
+  // for those not on the free list.
+  std::vector<pointer>::iterator pi = free_ptrs.begin();
+  std::vector<pointer>::iterator pi_end = free_ptrs.end();
+  std::vector<ArenaBlock*>::iterator bi = blocks.begin();
+  std::vector<ArenaBlock*>::iterator bi_end = blocks.end();
+  func_t* clear = m_params.clear;
+  for (; bi != bi_end; bi++) {
+    ArenaBlock& bl = **bi;
+    size_t sz = bl.size();
+    size_t elt_size = bl.eltSize();
+    for (size_t i = 0; i < sz; i++) {
+      pointer ptr = bl.index (i, elt_size);
+      if (pi != pi_end && ptr == *pi)
+        ++pi;
+      else
+        clear (ptr);
+    }
+  }
+}
+
+
+} // namespace SG
diff --git a/Control/AthAllocators/src/ArenaPoolAllocator.cxx b/Control/AthAllocators/src/ArenaPoolAllocator.cxx
new file mode 100755
index 0000000000000000000000000000000000000000..104520c970a264a20cd86c23d6237790fcd289e5
--- /dev/null
+++ b/Control/AthAllocators/src/ArenaPoolAllocator.cxx
@@ -0,0 +1,292 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// $Id: ArenaPoolAllocator.cxx 470529 2011-11-24 23:54:22Z ssnyder $
+/**
+ * @file  AthAllocators/src/ArenaPoolAllocator.cxx
+ * @author scott snyder
+ * @date May 2007
+ * @brief Pool-based allocator.
+ *        Out-of-line implementations.
+ */
+
+#include "AthAllocators/ArenaPoolAllocator.h"
+#include "AthAllocators/ArenaBlock.h"
+#include <cassert>
+
+
+namespace SG {
+
+
+/**
+ * @brief Helper: common code for advancing an iterator.
+ * @param base Element pointer.
+ * @param block Block pointer.
+ */
+inline
+ArenaPoolAllocator::pointer
+ArenaPoolAllocator_iterator_increment (ArenaPoolAllocator::pointer base,
+                                       ArenaBlock* & block)
+{
+  // If we haven't yet reached the start of this block, move the iterator
+  // back one.
+  if (base > block->index(0,0))
+    return base - block->eltSize();
+  else {
+    // Move to the previous block.
+    block = block->link();
+    if (block)
+      return block->index (block->size()-1, block->eltSize());
+    else
+      return 0;
+  }
+}
+
+
+/**
+ * @brief Move the iterator forward.
+ */
+void ArenaPoolAllocator::iterator::increment()
+{
+  this->base_reference() =
+    ArenaPoolAllocator_iterator_increment (this->base_reference(), m_block);
+}
+
+
+/**
+ * @brief Move the iterator forward.
+ */
+void ArenaPoolAllocator::const_iterator::increment()
+{
+  ArenaPoolAllocator::pointer base =
+    const_cast<ArenaPoolAllocator::pointer> (this->base_reference());
+  base = ArenaPoolAllocator_iterator_increment (base, m_block);
+  this->base_reference() = base;
+}
+
+
+/**
+ * @brief Constructor.
+ * @param params The parameters structure for this allocator.
+ *               See @c  ArenaAllocatorBase.h for the contents.
+ */
+ArenaPoolAllocator::ArenaPoolAllocator (const Params& params)
+  : ArenaBlockAllocatorBase (params),
+    m_ptr (0),
+    m_end (0)
+{
+}
+
+
+/**
+ * @brief Destructor.  This will free all the Allocator's storage.
+ */
+ArenaPoolAllocator::~ArenaPoolAllocator()
+{
+  erase();
+}
+
+
+/**
+ * @brief Free all allocated elements.
+ *
+ * All elements allocated are returned to the free state.
+ * @c clear should be called on them if it was provided.
+ * The elements may continue to be cached internally, without
+ * returning to the system.
+ */
+void ArenaPoolAllocator::reset()
+{
+  // Clear each block in turn.
+  while (m_blocks)
+    clearBlock();
+
+  // Check that things are consistent.
+  assert (m_stats.elts.inuse == 0);
+  assert (m_ptr == 0);
+  assert (m_end == 0);
+}
+
+
+/**
+ * @brief Free all allocated elements and release memory back to the system.
+ *
+ * All elements allocated are freed, and all allocated blocks of memory
+ * are released back to the system.
+ * @c destructor should be called on them if it was provided
+ * (preceded by @c clear if provided and @c mustClear was set).
+ */
+void ArenaPoolAllocator::erase()
+{
+  // Delete all the blocks.
+  ArenaBlockAllocatorBase::erase();
+
+  // Reset pointers.
+  m_ptr = m_end = 0;
+}
+
+
+/**
+ * @brief Reset pool back to a previous state.
+ * @param blk The pointer back to which to reset.
+ *
+ * This will free (a la @c reset) the element @c p and all elements
+ * that have been allocated after it from this allocator.
+ */
+void ArenaPoolAllocator::resetTo (pointer blk)
+{
+  // Clear the topmost block, as long as it doesn't contain the sought-after
+  // pointer.
+  ArenaBlock* p = m_blocks;
+  assert (p != 0);
+  size_t elt_size = p->eltSize();
+  while (p && !(blk >= p->index(0, elt_size) &&
+                blk < p->index(p->size(), elt_size)))
+  {
+    clearBlock();
+    p = m_blocks;
+  }
+
+  // We'll trip this if the supplied pointer wasn't in any block.
+  assert (p != 0);
+
+  // If the element is at the beginning of this block, just clear the whole
+  // thing.
+  if (blk == p->index(0, elt_size))
+    clearBlock();
+  else {
+    // Otherwise, we need to clear some of the elements in this block.
+    // See if we need to call @c clear.
+    func_t* clear = m_params.clear;
+    if (clear) {
+      // Yeah, we do.  Call @c clear on each element in turn.
+      while (m_ptr > blk) {
+        m_ptr -= elt_size;
+        clear (m_ptr);
+        --m_stats.elts.inuse;
+      }
+      // We'll trip this if the supplied pointer wasn't on an element
+      // boundary.
+      assert (m_ptr == blk);
+    }
+    else {
+      // We don't need to call @c clear.
+      // So we can do it the fast way --- just reset pointers.
+      m_stats.elts.inuse -= (m_ptr - blk) / elt_size;
+      m_ptr = blk;
+    }
+  }
+}
+
+
+/**
+ * @brief Starting pool iterator.
+ *
+ * This will iterate over all allocated elements (in unspecified order).
+ * It is a @c forward_iterator.
+ */
+ArenaPoolAllocator::iterator ArenaPoolAllocator::begin()
+{
+  // If @c m_ptr is one set, it is one more than the last allocated element.
+  return iterator (m_ptr ? m_ptr - m_params.eltSize : 0, m_blocks);
+}
+
+
+/**
+ * @brief Starting pool const iterator.
+ *
+ * This will iterate over all allocated elements (in unspecified order).
+ * It is a @c forward_iterator.
+ */
+ArenaPoolAllocator::const_iterator ArenaPoolAllocator::begin() const
+{
+  // If @c m_ptr is one set, it is one more than the last allocated element.
+  return const_iterator (m_ptr ? m_ptr - m_params.eltSize : 0, m_blocks);
+}
+
+
+/**
+ * @brief Ending pool iterator.
+ */
+ArenaPoolAllocator::iterator ArenaPoolAllocator::end()
+{
+  // Use a null iterator to signal the end.
+  return iterator ();
+}
+
+
+/**
+ * @brief Ending pool const iterator.
+ */
+ArenaPoolAllocator::const_iterator ArenaPoolAllocator::end() const
+{
+  // Use a null iterator to signal the end.
+  return const_iterator ();
+}
+
+
+/**
+ * @brief Add more free elements to the pool.
+ */
+void ArenaPoolAllocator::refill()
+{
+  // Get a new block.
+  ArenaBlock* newblock = getBlock();
+
+  // Set the pointers.
+  m_ptr = newblock->index (0,                m_params.eltSize);
+  m_end = newblock->index (newblock->size(), m_params.eltSize);
+}
+
+
+/**
+ * @brief Reset all elements in the topmost block, and move the block
+ *        to the free list.
+ */
+void ArenaPoolAllocator::clearBlock()
+{
+  // The topmost block.
+  ArenaBlock* p = m_blocks;
+
+  // Nothing to do if there are no allocated blocks!
+  if (!p) return;
+
+  size_t elt_size = p->eltSize();
+
+  // The first element of the block.
+  pointer base = p->index(0, elt_size);
+
+  // Do we need to call @c clear?  If so, call it on all allocated elements
+  // in this block.
+  func_t* clear = m_params.clear;
+  if (clear) {
+    pointer elt = base;
+    while (elt < m_ptr) {
+      clear (elt);
+      elt += elt_size;
+    }
+  }
+
+  // Update statistics.
+  --m_stats.blocks.inuse;
+  ++m_stats.blocks.free;
+  m_stats.elts.inuse -= (m_ptr - base) / elt_size;
+
+  // Move the block from the allocated to the free list.
+  m_blocks = p->link();
+  p->link() = m_freeblocks;
+  m_freeblocks = p;
+  p = m_blocks;
+
+  // Reset the pointers.
+  if (p) {
+    m_ptr = m_end = p->index(p->size());
+  }
+  else {
+    m_ptr = m_end = 0;
+  }
+}
+
+
+} // namespace SG
diff --git a/Control/AthAllocators/src/ArenaSharedHeapSTLAllocator.cxx b/Control/AthAllocators/src/ArenaSharedHeapSTLAllocator.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..aa1966fcc63a02a6abbfe9ba76a5e76c5ce056ac
--- /dev/null
+++ b/Control/AthAllocators/src/ArenaSharedHeapSTLAllocator.cxx
@@ -0,0 +1,66 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// $Id: ArenaSharedHeapSTLAllocator.cxx 470825 2011-11-25 23:20:57Z ssnyder $
+/**
+ * @file AthAllocators/src/ArenaSharedHeapSTLAllocator.cxx
+ * @author scott snyder <snyder@bnl.gov>
+ * @date Nov, 2011
+ * @brief STL-style allocator wrapper for @c ArenaHeapAllocator allowing
+ *        the heap to be shared between containers.
+ */
+
+
+#include "AthAllocators/ArenaSharedHeapSTLAllocator.h"
+
+
+namespace SG {
+
+
+/**
+ * @brief Constructor.
+ * @param owner Address of the object that owns this Header.
+ * @param nblock Value to set in the parameters structure for the
+ *               number of elements to allocate per block.
+ * @param name   Value to use as the base for the allocator names.
+ */
+ArenaSharedHeapSTLHeader::ArenaSharedHeapSTLHeader (const void* owner,
+                                                    int nblock,
+                                                    const std::string& name)
+  : m_owner (owner),
+    m_nblock (nblock),
+    m_name (name)
+{
+}
+
+
+/**
+ * @brief Destructor.
+ *
+ * Destroy all the allocators we own.
+ */
+ArenaSharedHeapSTLHeader::~ArenaSharedHeapSTLHeader()
+{
+  size_t sz = m_allocators.size();
+  for (size_t i = 0; i < sz; i++)
+    delete m_allocators[i];
+}
+
+
+/**
+ * @brief Return allocator statistics summed over all our owned allocators.
+ */
+ArenaAllocatorBase::Stats ArenaSharedHeapSTLHeader::totstats() const
+{
+  ArenaAllocatorBase::Stats stats;
+  size_t sz = m_allocators.size();
+  for (size_t i = 0; i < sz; i++) {
+    if (m_allocators[i])
+      stats += m_allocators[i]->stats();
+  }
+  return stats;
+}
+      
+
+} // namespace SG
diff --git a/Control/AthAllocators/test/ArenaAllocatorBase_test.cxx b/Control/AthAllocators/test/ArenaAllocatorBase_test.cxx
new file mode 100755
index 0000000000000000000000000000000000000000..e266a771105e90d4e26f1f63032979b3bbba3f8e
--- /dev/null
+++ b/Control/AthAllocators/test/ArenaAllocatorBase_test.cxx
@@ -0,0 +1,155 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// $Id: ArenaAllocatorBase_test.cxx 470529 2011-11-24 23:54:22Z ssnyder $
+/**
+ * @file AthAllocators/test/ArenaAllocatorBase_test.cxx
+ * @author scott snyder <snyder@bnl.gov>
+ * @date May, 2007
+ * @brief Regression tests for ArenaAllocatorBase.
+ */
+
+#undef NDEBUG
+#include "AthAllocators/ArenaAllocatorBase.h"
+#include <cassert>
+#include <sstream>
+
+
+int testcount = 0;
+
+class Test
+{
+public:
+  Test() { ++testcount; }
+  ~Test() { --testcount; }
+
+  int x;
+};
+
+class Test2
+  : public Test
+{
+public:
+  void clear() { testcount += 10; }
+};
+
+
+class ArenaTestAllocator
+  : public SG::ArenaAllocatorBase
+{
+public:
+  virtual void reset() {}
+  virtual void erase() {}
+  virtual void reserve (size_t /*size*/) { }
+  virtual const ArenaAllocatorBase::Stats& stats() const
+  { return m_stats; }
+  virtual const std::string& name() const { return m_name; }
+  ArenaAllocatorBase::Stats m_stats;
+  std::string m_name;
+};
+
+
+void set_stat (SG::ArenaAllocatorBase::Stats::Stat& stat, int x)
+{
+  stat.inuse = x;
+  stat.free = x+1;
+  stat.total = x+2;
+}
+
+void set_stats (SG::ArenaAllocatorBase::Stats& stats, int x)
+{
+  set_stat (stats.elts, x);
+  set_stat (stats.bytes, x + 1000);
+  set_stat (stats.blocks, x + 2000);
+}
+
+
+void check_stat_sum (const SG::ArenaAllocatorBase::Stats::Stat& stat1,
+                     const SG::ArenaAllocatorBase::Stats::Stat& stat2,
+                     const SG::ArenaAllocatorBase::Stats::Stat& stat3)
+{
+  assert (stat1.inuse + stat2.inuse == stat3.inuse);
+  assert (stat1.free +  stat2.free  == stat3.free);
+  assert (stat1.total + stat2.total == stat3.total);
+}
+void check_stats_sum (const SG::ArenaAllocatorBase::Stats& stats1,
+                      const SG::ArenaAllocatorBase::Stats& stats2,
+                      const SG::ArenaAllocatorBase::Stats& stats3)
+{
+  check_stat_sum (stats1.elts, stats2.elts, stats3.elts);
+  check_stat_sum (stats1.bytes, stats2.bytes, stats3.bytes);
+  check_stat_sum (stats1.blocks, stats2.blocks, stats3.blocks);
+}
+
+void check_stat_zero (const SG::ArenaAllocatorBase::Stats::Stat& stat)
+{
+  assert (stat.inuse == 0);
+  assert (stat.free  == 0);
+  assert (stat.total == 0);
+}
+void check_stats_zero (const SG::ArenaAllocatorBase::Stats& stats)
+{
+  check_stat_zero (stats.elts);
+  check_stat_zero (stats.bytes);
+  check_stat_zero (stats.blocks);
+}
+
+
+int main()
+{
+  ArenaTestAllocator ata;
+  ata.reset();
+  ata.erase();
+  ata.reserve(0);
+  assert (ata.stats().elts.inuse == 0);
+  assert (ata.name() == "");
+
+  SG::ArenaAllocatorBase::Params params =
+    SG::ArenaAllocatorBase::initParams<Test>(500, "foo");
+  assert (params.name == "foo");
+  assert (params.nblock == 500);
+  assert (params.eltSize == sizeof (Test));
+  char* p = new char[sizeof(Test)];
+  assert (testcount == 0);
+  params.constructor (p);
+  assert (testcount == 1);
+  params.destructor (p);
+  assert (testcount == 0);
+
+  params = SG::ArenaAllocatorBase::initParams<Test2>(500);
+  assert (params.clear == 0);
+  params = SG::ArenaAllocatorBase::initParams<Test2, true>(500);
+  assert (params.clear != 0);
+  params.clear (p);
+  assert (testcount == 10);
+
+  params = SG::ArenaAllocatorBase::initParams<int>(500);
+  assert (params.constructor == 0);
+  assert (params.destructor == 0);
+
+  SG::ArenaAllocatorBase::Stats stats1;
+  SG::ArenaAllocatorBase::Stats stats2;
+
+  set_stats (stats1, 1);
+  set_stats (stats2, 20);
+
+  SG::ArenaAllocatorBase::Stats stats3 = stats1;
+  stats3 += stats2;
+  check_stats_sum (stats1, stats2, stats3);
+  stats3.clear();
+  check_stats_zero (stats3);
+
+  ata.m_name = "foo";
+  assert (ata.name() == "foo");
+  set_stats (ata.m_stats, 1);
+  std::ostringstream os;
+  ata.report (os);
+  assert (os.str() == "       1/      2/      3    1001/   1002/   1003    2001/   2002/   2003  foo\n");
+  std::ostringstream os2;
+  stats1.header (os2);
+  assert (os2.str() == "Elts InUse/Free/Total   Bytes InUse/Free/Total  Blocks InUse/Free/Total");
+
+  delete  [] p;
+  return 0;
+}
diff --git a/Control/AthAllocators/test/ArenaAllocatorCreator_test.cxx b/Control/AthAllocators/test/ArenaAllocatorCreator_test.cxx
new file mode 100755
index 0000000000000000000000000000000000000000..e878e9fa4141e1db4f049143a705476a70dd3bb4
--- /dev/null
+++ b/Control/AthAllocators/test/ArenaAllocatorCreator_test.cxx
@@ -0,0 +1,30 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// $Id: ArenaAllocatorCreator_test.cxx 470529 2011-11-24 23:54:22Z ssnyder $
+/**
+ * @file AthAllocators/test/ArenaAllocatorCreator_test.cxx
+ * @author scott snyder <snyder@bnl.gov>
+ * @date May, 2007
+ * @brief Regression tests for ArenaAllocatorCreator.
+ */
+
+#undef NDEBUG
+#include "AthAllocators/ArenaAllocatorCreator.h"
+#include <cassert>
+
+class Test
+  : public SG::ArenaAllocatorCreator
+{
+public:
+  virtual SG::ArenaAllocatorBase* create() { return 0; }
+};
+  
+
+int main()
+{
+  Test test;
+  assert (test.create() == 0);
+  return 0;
+}
diff --git a/Control/AthAllocators/test/ArenaAllocatorRegistry_test.cxx b/Control/AthAllocators/test/ArenaAllocatorRegistry_test.cxx
new file mode 100755
index 0000000000000000000000000000000000000000..281f8bcccfec85191f3b5720c4a2d33642dfa22b
--- /dev/null
+++ b/Control/AthAllocators/test/ArenaAllocatorRegistry_test.cxx
@@ -0,0 +1,62 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// $Id: ArenaAllocatorRegistry_test.cxx 470529 2011-11-24 23:54:22Z ssnyder $
+/**
+ * @file AthAllocators/test/ArenaAllocatorRegistry_test.cxx
+ * @author scott snyder <snyder@bnl.gov>
+ * @date May, 2007
+ * @brief Regression tests for ArenaAllocatorRegistry.
+ */
+
+#undef NDEBUG
+#include "AthAllocators/ArenaAllocatorRegistry.h"
+#include "AthAllocators/ArenaAllocatorBase.h"
+#include "AthAllocators/ArenaAllocatorCreator.h"
+#include <cassert>
+
+class Alloc
+  : public SG::ArenaAllocatorBase
+{
+public:
+  Alloc(int x) { m_stats.elts.total = x; }
+  virtual void reset() {}
+  virtual void erase() {}
+  virtual void reserve (size_t /*size*/) {}
+  virtual const std::string& name() const { return m_name; }
+  virtual const SG::ArenaAllocatorBase::Stats& stats() const
+  { return m_stats; }
+private:
+  SG::ArenaAllocatorBase::Stats m_stats;
+  std::string m_name;
+};
+
+class Creator
+  : public SG::ArenaAllocatorCreator
+{
+public:
+  Creator (int x) : m_x (x) {}
+  virtual SG::ArenaAllocatorBase* create() { return new Alloc (m_x); }
+private:
+  int m_x;
+};
+
+void test1()
+{
+  SG::ArenaAllocatorRegistry* reg =
+    SG::ArenaAllocatorRegistry::instance();
+  assert (reg->lookup ("foo") == std::string::npos);
+  assert (reg->registerCreator ("foo", new Creator (0)) == 0);
+  assert (reg->registerCreator ("bar", new Creator (1)) == 1);
+  assert (reg->lookup ("foo") == 0);
+  assert (reg->lookup ("bar") == 1);
+  assert (reg->create(0)->stats().elts.total == 0);
+  assert (reg->create(1)->stats().elts.total == 1);
+}
+
+int main()
+{
+  test1();
+  return 0;
+}
diff --git a/Control/AthAllocators/test/ArenaBase_test.cxx b/Control/AthAllocators/test/ArenaBase_test.cxx
new file mode 100755
index 0000000000000000000000000000000000000000..63f7a021fc03c4fe3acab2defdb18641aea192c8
--- /dev/null
+++ b/Control/AthAllocators/test/ArenaBase_test.cxx
@@ -0,0 +1,46 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// $Id: ArenaBase_test.cxx 470529 2011-11-24 23:54:22Z ssnyder $
+/**
+ * @file AthAllocators/test/ArenaBase_test.cxx
+ * @author scott snyder <snyder@bnl.gov>
+ * @date May, 2007
+ * @brief Regression tests for ArenaBase.
+ */
+
+#undef NDEBUG
+#include "AthAllocators/ArenaBase.h"
+#include <ostream>
+#include <sstream>
+#include <cassert>
+
+
+std::string xname = "bar";
+
+class TestArena
+  : public SG::ArenaBase
+{
+public:
+  virtual void report (std::ostream& os) const { os << "foo"; }
+  virtual const std::string& name() const { return xname; }
+};
+
+
+void test1()
+{
+  TestArena t;
+  std::ostringstream s;
+  t.report (s);
+  assert (s.str() == "foo");
+  assert (t.name() == "bar");
+}
+
+
+int main()
+{
+  test1();
+  return 0;
+}
+
diff --git a/Control/AthAllocators/test/ArenaBlockAllocatorBase_test.cxx b/Control/AthAllocators/test/ArenaBlockAllocatorBase_test.cxx
new file mode 100755
index 0000000000000000000000000000000000000000..e46534b549be8180f1ecf5415bf9749e90cbb1b6
--- /dev/null
+++ b/Control/AthAllocators/test/ArenaBlockAllocatorBase_test.cxx
@@ -0,0 +1,111 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// $Id: ArenaBlockAllocatorBase_test.cxx 470529 2011-11-24 23:54:22Z ssnyder $
+/**
+ * @file AthAllocators/test/ArenaBlockAllocatorBase_test.cxx
+ * @author scott snyder <snyder@bnl.gov>
+ * @date May, 2007
+ * @brief Regression tests for ArenaBlockAllocatorBase.
+ */
+
+#undef NDEBUG
+#include "AthAllocators/ArenaBlockAllocatorBase.h"
+#include "AthAllocators/ArenaBlock.h"
+#include <cassert>
+
+
+struct Payload
+{
+  Payload();
+  ~Payload();
+  void clear();
+
+  int x;
+  int y;
+  static int n;
+  //static std::vector<int> v;
+};
+
+Payload::Payload()
+{
+  x = n++;
+  y = 0;
+  //v.push_back (x);
+}
+
+Payload::~Payload()
+{
+  //v.push_back (-x);
+}
+
+void Payload::clear ()
+{
+  y = 0;
+}
+
+int Payload::n = 0;
+//std::vector<int> Payload::v;
+
+
+class TestAlloc
+  : public SG::ArenaBlockAllocatorBase
+{
+public:
+  TestAlloc (const Params& params) : SG::ArenaBlockAllocatorBase (params){}
+  virtual void reset() {}
+};
+
+
+void test_stats (const SG::ArenaBlockAllocatorBase& bab,
+                 size_t nblock,
+                 size_t nelt)
+{
+  size_t elt_size = bab.params().eltSize;
+  size_t block_ov = SG::ArenaBlock::overhead();
+  const SG::ArenaAllocatorBase::Stats& stats = bab.stats();
+  assert (stats.blocks.total == nblock);
+  assert (stats.blocks.inuse == 0);
+  assert (stats.blocks.free  == nblock);
+  assert (stats.elts.total == nelt);
+  assert (stats.elts.inuse == 0);
+  assert (stats.elts.free  == nelt);
+  assert (stats.bytes.total == nelt * elt_size + nblock * block_ov);
+  assert (stats.bytes.inuse == 0);
+  assert (stats.bytes.free  == nelt * elt_size + nblock * block_ov);
+}
+
+
+void test1()
+{
+  TestAlloc bab
+    (SG::ArenaAllocatorBase::initParams<Payload, true> (100, "foo"));
+  assert (bab.name() == "foo");
+  assert (bab.params().name == "foo");
+  test_stats (bab, 0, 0);
+
+  bab.reserve (1000);
+  test_stats (bab, 1, 1000);
+
+  bab.reserve (500);
+  test_stats (bab, 1, 1000);
+
+  bab.reserve (0);
+  test_stats (bab, 0, 0);
+
+  bab.reserve (500);
+  test_stats (bab, 1, 500);
+  bab.reserve (1000);
+  test_stats (bab, 2, 1000);
+  bab.reserve (500);
+  test_stats (bab, 1, 500);
+  bab.erase();
+  test_stats (bab, 0, 0);
+}
+
+int main()
+{
+  test1();
+  return 0;
+}
diff --git a/Control/AthAllocators/test/ArenaBlock_test.cxx b/Control/AthAllocators/test/ArenaBlock_test.cxx
new file mode 100755
index 0000000000000000000000000000000000000000..3c1df22c8c44bfc5ae7865a5e19c65670f34741b
--- /dev/null
+++ b/Control/AthAllocators/test/ArenaBlock_test.cxx
@@ -0,0 +1,144 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// $Id: ArenaBlock_test.cxx 470529 2011-11-24 23:54:22Z ssnyder $
+/**
+ * @file AthAllocators/test/ArenaBlock_test.cxx
+ * @author scott snyder <snyder@bnl.gov>
+ * @date May, 2007
+ * @brief Regression tests for ArenaBlock.
+ */
+
+#undef NDEBUG
+#include "AthAllocators/ArenaBlock.h"
+#include <cassert>
+#include <vector>
+
+//==========================================================================
+
+struct Payload
+{
+  Payload();
+  ~Payload();
+  static void constructor (char*);
+  static void destructor (char*);
+  static void scan (char*);
+
+  int x;
+  static int n;
+  static std::vector<int> v;
+};
+
+Payload::Payload()
+{
+  x = n++;
+  v.push_back (x);
+}
+
+Payload::~Payload()
+{
+  v.push_back (-x);
+}
+
+void Payload::constructor (char* p)
+{
+  new (p) Payload;
+}
+
+void Payload::destructor (char* p)
+{
+  reinterpret_cast<Payload*>(p)->~Payload();
+}
+
+void Payload::scan (char* p)
+{
+  Payload::v.push_back (reinterpret_cast<Payload*>(p)->x);
+}
+
+int Payload::n = 0;
+std::vector<int> Payload::v;
+
+//==========================================================================
+
+const size_t elt_size = sizeof (Payload);
+
+int& word (SG::ArenaBlock* bl, size_t i=0)
+{
+  return *(int*)bl->index (i, elt_size);
+}
+
+Payload& payload (SG::ArenaBlock* bl, size_t i=0)
+{
+  return *(Payload*)bl->index (i, elt_size);
+}
+
+void test1()
+{
+  assert (SG::ArenaBlock::nactive() == 0);
+  SG::ArenaBlock* bl = SG::ArenaBlock::newBlock (20, elt_size, 0);
+  assert (SG::ArenaBlock::nactive() == 1);
+  assert (bl->overhead() > 0 && bl->overhead() < 100);
+  assert (bl->size() == 20);
+  assert (bl->eltSize() == elt_size);
+  word(bl, 0) = 0;
+  word(bl, 1) = 0;
+  assert ((char*)bl->index(1) -
+          (char*)bl->index(0) == (int)elt_size);
+  assert (bl->link() == 0);
+  bl->link() = bl;
+  assert (bl->link() == bl);
+  SG::ArenaBlock::destroy (bl, 0);
+  assert (SG::ArenaBlock::nactive() == 0);
+}
+
+
+void test2()
+{
+  SG::ArenaBlock* b1 = SG::ArenaBlock::newBlock (20, elt_size,
+                                                 Payload::constructor);
+  SG::ArenaBlock* b2 = SG::ArenaBlock::newBlock (20, elt_size,
+                                                 Payload::constructor);
+  SG::ArenaBlock* b3 = SG::ArenaBlock::newBlock (20, elt_size,
+                                                 Payload::constructor);
+  int i = 0;
+  for (size_t j = 0; j < b1->size(); j++) {
+    assert (payload(b1, j).x == i);
+    assert (Payload::v[i] == i);
+    ++i;
+  }
+  b1->link() = b2;
+  SG::ArenaBlock::appendList (&b1, b3);
+  assert (payload(b1).x == 0);
+  assert (payload(b1->link()).x == 20);
+  assert (payload(b1->link()->link()).x == 40);
+  assert(b1->link()->link()->link() == 0);
+  SG::ArenaBlock* bb = 0;
+  SG::ArenaBlock::appendList (&bb, b1);
+  assert (bb == b1);
+
+  Payload::v.clear();
+  SG::ArenaBlock::applyList (b1, Payload::scan, 10);
+  assert (Payload::v.size() == 50);
+  for (size_t j = 0; j < 10; ++j) {
+    assert (Payload::v[j] == (int)j);
+  }
+  for (size_t j = 10; j < Payload::v.size(); ++j) {
+    assert (Payload::v[j] == (int)j+10);
+  }
+
+  Payload::v.clear();
+  SG::ArenaBlock::destroyList (b1, Payload::destructor);
+  assert (Payload::v.size() == 60);
+  for (size_t j = 0; j < Payload::v.size(); ++j) {
+    assert (Payload::v[j] == -(int)j);
+  }
+}
+
+
+int main()
+{
+  test1();
+  test2();
+  return 0;
+}
diff --git a/Control/AthAllocators/test/ArenaCachingHandle_test.cxx b/Control/AthAllocators/test/ArenaCachingHandle_test.cxx
new file mode 100755
index 0000000000000000000000000000000000000000..acbc8aa905e98ef879a51b0332397a6e8c2a661d
--- /dev/null
+++ b/Control/AthAllocators/test/ArenaCachingHandle_test.cxx
@@ -0,0 +1,242 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// $Id: ArenaCachingHandle_test.cxx 470529 2011-11-24 23:54:22Z ssnyder $
+/**
+ * @file AthAllocators/test/ArenaCachingHandle_test.cxx
+ * @author scott snyder <snyder@bnl.gov>
+ * @date May, 2007
+ * @brief Regression tests for ArenaCachingHandle.
+ */
+
+#undef NDEBUG
+#include "AthAllocators/ArenaCachingHandle.h"
+#include "AthAllocators/ArenaHeader.h"
+#include "AthAllocators/ArenaHeaderGaudiClear.h"
+#include "AthAllocators/ArenaPoolAllocator.h"
+#include "AthAllocators/ArenaHeapAllocator.h"
+#include "AthAllocators/ArenaBlock.h"
+#include <cassert>
+
+int count = 0;
+int nctor = 0;
+int ndtor = 0;
+int nclear = 0;
+struct Payload
+{
+  int x;
+  int y;
+  Payload() { x = ++count;  y = 0; ++nctor; }
+  ~Payload() { ++ndtor; }
+  void clear() { y = 0; ++nclear; }
+};
+
+void test1()
+{
+  count = 0;
+  nctor = 0;
+  ndtor = 0;
+  nclear = 0;
+
+  typedef
+    SG::ArenaCachingHandle<Payload, SG::ArenaPoolAllocator> Handtype;
+  SG::ArenaHeader head;
+  SG::Arena arena  ("a", &head);
+  SG::Arena::Push push (arena);
+
+  Handtype hand (&arena,
+                 SG::ArenaPoolAllocator::initParams<Payload, true>(50));
+  std::vector<Payload*> ptrs;
+  for (int i=0; i < 100; i++) {
+    Payload* p = hand.allocate();
+    assert (p->y == 0);
+    p->y = i+1;
+    ptrs.push_back (p);
+  }
+  assert (nctor == 100);
+  assert (ndtor == 0);
+  assert (nclear == 0);
+  assert (hand.stats().elts.inuse == 100);
+  assert (hand.stats().elts.free == 0);
+  assert (hand.stats().elts.total == 100);
+  size_t elt_size = hand.params().eltSize;
+  size_t block_ov = SG::ArenaBlock::overhead();
+
+  std::vector<int> v;
+  for (Handtype::iterator ii = hand.begin();
+       ii != hand.end();
+       ++ii)
+  {
+    assert (ii->y != 0);
+    v.push_back (ii->x);
+  }
+  assert (v.size() == 100);
+  for (size_t i = 0; i < v.size(); i++) {
+    assert (v[i] == 100-(int)i);
+  }
+
+  const Handtype& chand = hand;
+  v.clear();
+  for (Handtype::const_iterator ii = chand.begin();
+       ii != chand.end();
+       ++ii)
+  {
+    assert (ii->y != 0);
+    v.push_back (ii->x);
+  }
+  assert (v.size() == 100);
+  for (size_t i = 0; i < v.size(); i++) {
+    assert (v[i] == 100-(int)i);
+  }
+
+  v.clear();
+  for (Handtype::const_iterator ii = hand.begin();
+       ii != hand.end();
+       ++ii)
+  {
+    assert (ii->y != 0);
+    v.push_back (ii->x);
+  }
+  assert (v.size() == 100);
+  for (size_t i = 0; i < v.size(); i++) {
+    assert (v[i] == 100-(int)i);
+  }
+
+  hand.reset();
+  assert (nctor == 100);
+  assert (ndtor == 0);
+  assert (nclear == 100);
+  assert (hand.stats().elts.inuse == 0);
+  assert (hand.stats().elts.free == 100);
+  assert (hand.stats().elts.total == 100);
+
+  ptrs.clear();
+  for (int i=0; i < 100; i++) {
+    Payload* p = hand.allocate();
+    assert (p->y == 0);
+    p->y = i + 1;
+    ptrs.push_back (p);
+  }
+  assert (nctor == 100);
+  assert (ndtor == 0);
+  assert (nclear == 100);
+  assert (hand.stats().elts.inuse == 100);
+  assert (hand.stats().elts.free == 0);
+  assert (hand.stats().elts.total == 100);
+
+  Handtype hand2 (&head, 0);
+
+  hand2.resetTo (ptrs[50]);
+  assert (nctor == 100);
+  assert (ndtor == 0);
+  assert (nclear == 150);
+  assert (hand2.stats().elts.inuse == 50);
+  assert (hand2.stats().elts.free == 50);
+  assert (hand2.stats().elts.total == 100);
+  assert (hand2.stats().blocks.inuse == 1);
+  assert (hand2.stats().blocks.free == 1);
+  assert (hand2.stats().blocks.total == 2);
+  assert (hand2.stats().bytes.inuse == 50 * elt_size + block_ov);
+  assert (hand2.stats().bytes.free == 50 * elt_size + block_ov);
+  assert (hand2.stats().bytes.total == 100 * elt_size + 2*block_ov);
+
+  hand2.erase();
+  assert (nctor == 100);
+  assert (ndtor == 100);
+  assert (nclear == 150);
+  assert (hand2.stats().elts.inuse == 0);
+  assert (hand2.stats().elts.free == 0);
+  assert (hand2.stats().elts.total == 0);
+}
+
+
+void test2()
+{
+  count = 0;
+  nctor = 0;
+  ndtor = 0;
+  nclear = 0;
+
+  typedef
+    SG::ArenaCachingHandle<Payload, SG::ArenaHeapAllocator> Handtype;
+  
+  Handtype hand (SG::ArenaHeapAllocator::initParams<Payload, true>(50));
+  size_t elt_size = hand.params().eltSize;
+  assert (elt_size > sizeof (Payload));
+
+  std::vector<Payload*> ptrs;
+  for (int i=0; i < 100; i++) {
+    Payload* p = hand.allocate();
+    assert (p->y == 0);
+    p->y = i+1;
+    ptrs.push_back (p);
+  }
+  //printf ("%d %d %d\n", nctor, ndtor, nclear);
+  //printf ("%d %d %d\n", hand.stats().elts.inuse, hand.stats().elts.free, hand.stats().elts.total());
+  assert (nctor == 100);
+  assert (ndtor == 0);
+  assert (nclear == 0);
+  assert (hand.stats().elts.inuse == 100);
+  assert (hand.stats().elts.free == 0);
+  assert (hand.stats().elts.total == 100);
+
+  for (size_t i = 0; i < ptrs.size(); i+=2) {
+    hand.free (ptrs[i]);
+  }
+
+  assert (nctor == 100);
+  assert (ndtor == 0);
+  assert (nclear == 50);
+  assert (hand.stats().elts.inuse == 50);
+  assert (hand.stats().elts.free == 50);
+  assert (hand.stats().elts.total == 100);
+
+  hand.reset();
+  assert (nctor == 100);
+  assert (ndtor == 0);
+  assert (nclear == 150);
+  assert (hand.stats().elts.inuse == 0);
+  assert (hand.stats().elts.free == 100);
+  assert (hand.stats().elts.total == 100);
+
+  ptrs.clear();
+  for (int i=0; i < 100; i++) {
+    Payload* p = hand.allocate();
+    assert (p->y == 0);
+    p->y = i+1;
+    ptrs.push_back (p);
+  }
+  assert (nctor == 100);
+  assert (ndtor == 0);
+  assert (nclear == 150);
+  assert (hand.stats().elts.inuse == 100);
+  assert (hand.stats().elts.free == 0);
+  assert (hand.stats().elts.total == 100);
+}
+
+
+void test3()
+{
+  typedef
+    SG::ArenaCachingHandle<Payload, SG::ArenaHeapAllocator> Handtype;
+  
+  SG::ArenaHeader head;
+  Handtype hand (&head,
+                 SG::ArenaHeapAllocator::initParams<Payload, true>(50));
+
+  hand.reserve (100);
+  assert (hand.stats().elts.inuse == 0);
+  assert (hand.stats().elts.free == 100);
+  assert (hand.stats().elts.total == 100);
+}
+
+
+int main()
+{
+  SG::ArenaHeaderGaudiClear::disable();
+  test1();
+  test2();
+  test3();
+  return 0;
+}
diff --git a/Control/AthAllocators/test/ArenaHandleBaseAllocT_test.cxx b/Control/AthAllocators/test/ArenaHandleBaseAllocT_test.cxx
new file mode 100755
index 0000000000000000000000000000000000000000..e1b3cbdb2716dd5cc3313223ef5ab0201d790d7a
--- /dev/null
+++ b/Control/AthAllocators/test/ArenaHandleBaseAllocT_test.cxx
@@ -0,0 +1,72 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// $Id: ArenaHandleBaseAllocT_test.cxx 470529 2011-11-24 23:54:22Z ssnyder $
+/**
+ * @file AthAllocators/test/ArenaHandleBase_test.cxx
+ * @author scott snyder <snyder@bnl.gov>
+ * @date May, 2007
+ * @brief Regression tests for ArenaHandleBaseAllocT.
+ */
+
+#undef NDEBUG
+#include "AthAllocators/ArenaHandleBaseAllocT.h"
+#include "AthAllocators/ArenaHeader.h"
+#include "AthAllocators/ArenaHeaderGaudiClear.h"
+#include "AthAllocators/ArenaAllocatorBase.h"
+#include <cassert>
+
+class TestAlloc
+  : public SG::ArenaAllocatorBase
+{
+public:
+  TestAlloc (const Params& params) : m_params (params) {}
+  virtual void reset() {}
+  virtual void erase() {}
+  virtual void reserve(size_t) {}
+  virtual const std::string& name() const { return m_params.name; }
+  virtual const Stats& stats() const { return m_stats; }
+  const Params& params() const { return m_params; }
+  int foo() { return 42; }
+
+  static SG::ArenaAllocatorBase* makeAllocator (const Params& params)
+  { return new TestAlloc (params); }
+
+private:
+  Stats m_stats;
+  Params m_params;
+};
+
+class TestHandle
+  : public SG::ArenaHandleBaseAllocT<TestAlloc>
+{
+public:
+  typedef SG::ArenaHandleBaseAllocT<TestAlloc> Base;
+  TestHandle (SG::ArenaHeader* header, size_t index)
+    : Base (header, index) {}
+  TestHandle (SG::ArenaHeader* header, const Creator& creator)
+    : Base (header, creator) {}
+  int foo() { return allocator()->foo(); }
+};
+
+void test1()
+{
+  SG::ArenaHeader head;
+  TestAlloc::Params params;
+  params.name = "foo";
+  TestHandle hand (&head, TestHandle::Creator (static_cast<TestAlloc*>(0),
+                                               params));
+  assert (hand.params().name == "foo");
+
+  TestHandle hand2 (&head, 0);
+  assert (hand2.foo() == 42);
+}
+
+int main()
+{
+  SG::ArenaHeaderGaudiClear::disable();
+  test1();
+  return 0;
+}
+
diff --git a/Control/AthAllocators/test/ArenaHandleBaseT_test.cxx b/Control/AthAllocators/test/ArenaHandleBaseT_test.cxx
new file mode 100755
index 0000000000000000000000000000000000000000..52056a6a3a8a509751c37d277a7c055cb2c538c9
--- /dev/null
+++ b/Control/AthAllocators/test/ArenaHandleBaseT_test.cxx
@@ -0,0 +1,173 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// $Id: ArenaHandleBaseT_test.cxx 470529 2011-11-24 23:54:22Z ssnyder $
+/**
+ * @file AthAllocators/test/ArenaHandleBaseT_test.cxx
+ * @author scott snyder <snyder@bnl.gov>
+ * @date May, 2007
+ * @brief Regression tests for ArenaHandleBaseT.
+ */
+
+#undef NDEBUG
+#include "AthAllocators/ArenaHandleBaseT.h"
+#include "AthAllocators/ArenaHeader.h"
+#include "AthAllocators/ArenaHeaderGaudiClear.h"
+#include "AthAllocators/ArenaAllocatorBase.h"
+#include <cassert>
+#include <iterator>
+
+
+class Payload
+{
+public:
+  Payload (int i) : m_x (i) {}
+  int m_x;
+};
+
+
+class TestAlloc
+  : public SG::ArenaAllocatorBase
+{
+public:
+  TestAlloc (const Params& params);
+  virtual void reset() {}
+  virtual void erase() {}
+  virtual void reserve(size_t) {}
+  virtual const std::string& name() const { return m_params.name; }
+  virtual const Stats& stats() const { return m_stats; }
+  const Params& params() const { return m_params; }
+  int foo() { return 42; }
+  void free (pointer p) { ptmp = p; }
+  void resetTo (pointer p) { ptmp = p+1; }
+  static pointer ptmp;
+
+  class const_iterator;
+
+  class iterator
+    : public std::iterator<std::forward_iterator_tag, Payload>
+  {
+  public:
+    iterator (std::vector<Payload>::iterator it)
+      : m_it (it) {}
+    reference operator*() const { return *m_it; }
+    iterator& operator++() { m_it++; return *this; }
+    bool operator== (const iterator& other) const
+    { return m_it == other.m_it; }
+
+    friend class const_iterator;
+
+  private:
+    std::vector<Payload>::iterator m_it;
+  };
+
+  class const_iterator
+    : public std::iterator<std::forward_iterator_tag, const Payload>
+  {
+  public:
+    const_iterator (std::vector<Payload>::const_iterator it)
+      : m_it (it) {}
+    const_iterator (TestAlloc::iterator it)
+      : m_it (&*it) {}
+    reference operator*() const { return *m_it; }
+    const_iterator& operator++() { m_it++; return *this; }
+    bool operator== (const const_iterator& other) const
+    { return m_it == other.m_it; }
+    bool operator== (const TestAlloc::iterator& other) const
+    { return m_it == other.m_it; }
+
+  private:
+    std::vector<Payload>::const_iterator m_it;
+  };
+
+  iterator begin()  { return iterator (m_vec.begin()); }
+  iterator end()    { return iterator (m_vec.end()); }
+  const_iterator begin() const  { return const_iterator (m_vec.begin()); }
+  const_iterator end() const    { return const_iterator (m_vec.end()); }
+
+  static SG::ArenaAllocatorBase* makeAllocator (const Params& params)
+  { return new TestAlloc (params); }
+
+private:
+  std::vector<Payload> m_vec;
+  Stats m_stats;
+  Params m_params;
+};
+
+
+TestAlloc::TestAlloc (const Params& params)
+  : m_params (params)
+{
+  for (int i = 0; i < 10; i++)
+    m_vec.push_back (i);
+}
+
+TestAlloc::pointer TestAlloc::ptmp = 0;
+
+class TestHandle
+  : public SG::ArenaHandleBaseT<Payload, TestAlloc>
+{
+public:
+  typedef SG::ArenaHandleBaseT<Payload, TestAlloc> Base;
+  TestHandle (SG::ArenaHeader* header, size_t index)
+    : Base (header, index) {}
+  TestHandle (SG::ArenaHeader* header, const Creator& creator)
+    : Base (header, creator) {}
+  int foo() { return allocator()->foo(); }
+};
+
+void test1()
+{
+  SG::ArenaHeader head;
+  TestAlloc::Params params;
+  params.name = "foo";
+  TestHandle hand (&head, TestHandle::Creator (static_cast<TestAlloc*>(0),
+                                               params));
+  assert (hand.params().name == "foo");
+  TestHandle::pointer p = reinterpret_cast<TestHandle::pointer>(0x1234);
+  hand.free (p);
+  assert (TestAlloc::ptmp == reinterpret_cast<TestAlloc::pointer>(p));
+  hand.resetTo (p);
+  assert (TestAlloc::ptmp == reinterpret_cast<TestAlloc::pointer>(p)+1);
+
+  TestHandle hand2 (&head, 0);
+  int i = 0;
+  for (TestHandle::iterator it = hand2.begin();
+       it != hand2.end();
+       ++it)
+  {
+    assert ((*it).m_x == i);
+    assert (it->m_x == i);
+    ++i;
+  }
+
+  i = 0;
+  const TestHandle& chand = hand2;
+  for (TestHandle::const_iterator it = chand.begin();
+       it != chand.end();
+       ++it)
+  {
+    assert ((*it).m_x == i);
+    assert (it->m_x == i);
+    ++i;
+  }
+
+  i = 0;
+  for (TestHandle::const_iterator it = hand2.begin();
+       it != hand2.end();
+       ++it)
+  {
+    assert ((*it).m_x == i);
+    assert (it->m_x == i);
+    ++i;
+  }
+}
+
+
+int main()
+{
+  SG::ArenaHeaderGaudiClear::disable();
+  test1();
+  return 0;
+}
diff --git a/Control/AthAllocators/test/ArenaHandleBase_test.cxx b/Control/AthAllocators/test/ArenaHandleBase_test.cxx
new file mode 100755
index 0000000000000000000000000000000000000000..b0fa7a461d7bc92ea36b2946963d28e055a2bc34
--- /dev/null
+++ b/Control/AthAllocators/test/ArenaHandleBase_test.cxx
@@ -0,0 +1,74 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// $Id: ArenaHandleBase_test.cxx 470529 2011-11-24 23:54:22Z ssnyder $
+/**
+ * @file AthAllocators/test/ArenaHandleBase_test.cxx
+ * @author scott snyder <snyder@bnl.gov>
+ * @date May, 2007
+ * @brief Regression tests for ArenaHandleBase.
+ */
+
+
+#undef NDEBUG
+#include "AthAllocators/ArenaHandleBase.h"
+#include "AthAllocators/ArenaHeader.h"
+#include "AthAllocators/ArenaHeaderGaudiClear.h"
+#include "AthAllocators/ArenaPoolAllocator.h"
+#include "AthAllocators/ArenaBlock.h"
+#include <cassert>
+
+struct Payload
+{
+  int x;
+};
+
+void test1()
+{
+  SG::ArenaHeader header;
+  SG::ArenaHeader::ArenaAllocVec_t vec;
+  vec.push_back (new SG::ArenaPoolAllocator
+                 (SG::ArenaPoolAllocator::initParams<Payload>(1000)));
+  header.setAllocVec (&vec);
+  SG::ArenaHandleBase test (&header, 0);
+  size_t elt_size =
+    dynamic_cast<SG::ArenaPoolAllocator*>(vec[0])->params().eltSize;
+  size_t block_ov = SG::ArenaBlock::overhead();
+
+  assert (test.stats().elts.inuse == 0);
+  assert (test.stats().elts.free == 0);
+  assert (test.stats().elts.total == 0);
+  test.reserve (10);
+  assert (test.stats().elts.inuse == 0);
+  assert (test.stats().elts.free == 1000);
+  assert (test.stats().elts.total == 1000);
+  assert (test.stats().blocks.inuse == 0);
+  assert (test.stats().blocks.free == 1);
+  assert (test.stats().blocks.total == 1);
+  assert (test.stats().bytes.inuse == 0);
+  assert (test.stats().bytes.free == 1000 * elt_size + block_ov);
+  assert (test.stats().bytes.total == 1000 * elt_size + block_ov);
+  test.reset ();
+  assert (test.stats().elts.inuse == 0);
+  assert (test.stats().elts.free == 1000);
+  assert (test.stats().elts.total == 1000);
+  test.erase ();
+  assert (test.stats().elts.inuse == 0);
+  assert (test.stats().elts.free == 0);
+  assert (test.stats().elts.total == 0);
+
+  SG::ArenaHandleBase test2 (0, 0);
+  SG::ArenaHeader::defaultHeader()->setAllocVec (&vec);
+  test2.reserve (10);
+  assert (test2.stats().elts.inuse == 0);
+  assert (test2.stats().elts.free == 1000);
+  assert (test2.stats().elts.total == 1000);
+}
+
+int main()
+{
+  SG::ArenaHeaderGaudiClear::disable();
+  test1();
+  return 0;
+}
diff --git a/Control/AthAllocators/test/ArenaHandle_test.cxx b/Control/AthAllocators/test/ArenaHandle_test.cxx
new file mode 100755
index 0000000000000000000000000000000000000000..8d8d2c8ed4d284696e95fa1eeda753a73ccc4c66
--- /dev/null
+++ b/Control/AthAllocators/test/ArenaHandle_test.cxx
@@ -0,0 +1,238 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// $Id: ArenaHandle_test.cxx 470529 2011-11-24 23:54:22Z ssnyder $
+/**
+ * @file AthAllocators/test/ArenaHandle_test.cxx
+ * @author scott snyder <snyder@bnl.gov>
+ * @date May, 2007
+ * @brief Regression tests for ArenaHandle.
+ */
+
+#undef NDEBUG
+#include "AthAllocators/ArenaHandle.h"
+#include "AthAllocators/ArenaHeader.h"
+#include "AthAllocators/ArenaHeaderGaudiClear.h"
+#include "AthAllocators/ArenaPoolAllocator.h"
+#include "AthAllocators/ArenaHeapAllocator.h"
+#include "AthAllocators/ArenaBlock.h"
+#include <cassert>
+
+int count = 0;
+int nctor = 0;
+int ndtor = 0;
+int nclear = 0;
+struct Payload
+{
+  int x;
+  int y;
+  Payload() { x = ++count;  y = 0; ++nctor; }
+  ~Payload() { ++ndtor; }
+  void clear() { y = 0; ++nclear; }
+};
+
+void test1()
+{
+  count = 0;
+  nctor = 0;
+  ndtor = 0;
+  nclear = 0;
+
+  typedef
+    SG::ArenaHandle<Payload, SG::ArenaPoolAllocator> Handtype;
+  SG::ArenaHeader head;
+  SG::Arena arena  ("a", &head);
+  SG::Arena::Push push (arena);
+  
+
+  Handtype hand (&arena,
+                 SG::ArenaPoolAllocator::initParams<Payload, true>(50));
+  std::vector<Payload*> ptrs;
+  for (int i=0; i < 100; i++) {
+    Payload* p = new (hand.allocate()) Payload;
+    assert (p->y == 0);
+    p->y = i+1;
+    ptrs.push_back (p);
+  }
+  assert (nctor == 100);
+  assert (ndtor == 0);
+  assert (nclear == 0);
+  assert (hand.stats().elts.inuse == 100);
+  assert (hand.stats().elts.free == 0);
+  assert (hand.stats().elts.total == 100);
+
+  std::vector<int> v;
+  for (Handtype::iterator ii = hand.begin();
+       ii != hand.end();
+       ++ii)
+  {
+    assert (ii->y != 0);
+    v.push_back (ii->x);
+  }
+  assert (v.size() == 100);
+  for (size_t i = 0; i < v.size(); i++) {
+    assert (v[i] == 100-(int)i);
+  }
+
+  const Handtype& chand = hand;
+  v.clear();
+  for (Handtype::const_iterator ii = chand.begin();
+       ii != chand.end();
+       ++ii)
+  {
+    assert (ii->y != 0);
+    v.push_back (ii->x);
+  }
+  assert (v.size() == 100);
+  for (size_t i = 0; i < v.size(); i++) {
+    assert (v[i] == 100-(int)i);
+  }
+
+  v.clear();
+  for (Handtype::const_iterator ii = hand.begin();
+       ii != hand.end();
+       ++ii)
+  {
+    assert (ii->y != 0);
+    v.push_back (ii->x);
+  }
+  assert (v.size() == 100);
+  for (size_t i = 0; i < v.size(); i++) {
+    assert (v[i] == 100-(int)i);
+  }
+
+  hand.reset();
+  assert (nctor == 100);
+  assert (ndtor == 100);
+  assert (nclear == 0);
+  assert (hand.stats().elts.inuse == 0);
+  assert (hand.stats().elts.free == 100);
+  assert (hand.stats().elts.total == 100);
+
+  ptrs.clear();
+  for (int i=0; i < 100; i++) {
+    Payload* p = new (hand.allocate()) Payload;
+    p->y = i + 1;
+    ptrs.push_back (p);
+  }
+  assert (nctor == 200);
+  assert (ndtor == 100);
+  assert (nclear == 0);
+  assert (hand.stats().elts.inuse == 100);
+  assert (hand.stats().elts.free == 0);
+  assert (hand.stats().elts.total == 100);
+
+  Handtype hand2 (&head, 0);
+
+  hand2.resetTo (ptrs[50]);
+  assert (nctor == 200);
+  assert (ndtor == 150);
+  assert (nclear == 00);
+  assert (hand2.stats().elts.inuse == 50);
+  assert (hand2.stats().elts.free == 50);
+  assert (hand2.stats().elts.total == 100);
+
+  hand2.erase();
+  assert (nctor == 200);
+  assert (ndtor == 200);
+  assert (nclear == 0);
+  assert (hand2.stats().elts.inuse == 0);
+  assert (hand2.stats().elts.free == 0);
+  assert (hand2.stats().elts.total == 0);
+}
+
+
+void test2()
+{
+  count = 0;
+  nctor = 0;
+  ndtor = 0;
+  nclear = 0;
+
+  typedef
+    SG::ArenaHandle<Payload, SG::ArenaHeapAllocator> Handtype;
+  
+  Handtype hand (SG::ArenaHeapAllocator::initParams<Payload, true>(50));
+  size_t elt_size = hand.params().eltSize;
+  assert (elt_size == sizeof (Payload));
+  size_t block_ov = SG::ArenaBlock::overhead();
+
+  std::vector<Payload*> ptrs;
+  for (int i=0; i < 100; i++) {
+    Payload* p = new (hand.allocate()) Payload;
+    assert (p->y == 0);
+    p->y = i+1;
+    ptrs.push_back (p);
+  }
+  assert (nctor == 100);
+  assert (ndtor == 0);
+  assert (nclear == 0);
+  assert (hand.stats().elts.inuse == 100);
+  assert (hand.stats().elts.free == 0);
+  assert (hand.stats().elts.total == 100);
+
+  for (size_t i = 0; i < ptrs.size(); i+=2) {
+    hand.free (ptrs[i]);
+  }
+  assert (nctor == 100);
+  assert (ndtor == 50);
+  assert (nclear == 0);
+  assert (hand.stats().elts.inuse == 50);
+  assert (hand.stats().elts.free == 50);
+  assert (hand.stats().elts.total == 100);
+  assert (hand.stats().blocks.inuse == 2);
+  assert (hand.stats().blocks.free == 0);
+  assert (hand.stats().blocks.total == 2);
+  assert (hand.stats().bytes.inuse ==  50 * elt_size + 2 * block_ov);
+  assert (hand.stats().bytes.free  ==  50 * elt_size);
+  assert (hand.stats().bytes.total == 100 * elt_size + 2 * block_ov);
+
+  hand.reset();
+  assert (nctor == 100);
+  assert (ndtor == 100);
+  assert (nclear == 0);
+  assert (hand.stats().elts.inuse == 0);
+  assert (hand.stats().elts.free == 100);
+  assert (hand.stats().elts.total == 100);
+
+  ptrs.clear();
+  for (int i=0; i < 100; i++) {
+    Payload* p = new (hand.allocate()) Payload;
+    assert (p->y == 0);
+    p->y = i+1;
+    ptrs.push_back (p);
+  }
+  assert (nctor == 200);
+  assert (ndtor == 100);
+  assert (nclear == 0);
+  assert (hand.stats().elts.inuse == 100);
+  assert (hand.stats().elts.free == 0);
+  assert (hand.stats().elts.total == 100);
+}
+
+
+void test3()
+{
+  typedef
+    SG::ArenaHandle<Payload, SG::ArenaHeapAllocator> Handtype;
+  
+  SG::ArenaHeader head;
+  Handtype hand (&head,
+                 SG::ArenaHeapAllocator::initParams<Payload, true>(50));
+
+  hand.reserve (100);
+  assert (hand.stats().elts.inuse == 0);
+  assert (hand.stats().elts.free == 100);
+  assert (hand.stats().elts.total == 100);
+}
+
+
+int main()
+{
+  SG::ArenaHeaderGaudiClear::disable();
+  test1();
+  test2();
+  test3();
+  return 0;
+}
diff --git a/Control/AthAllocators/test/ArenaHeaderGaudiClear_test.cxx b/Control/AthAllocators/test/ArenaHeaderGaudiClear_test.cxx
new file mode 100755
index 0000000000000000000000000000000000000000..70d9f9b0b11a98fcdc2b9bfe21ca7315ebd85442
--- /dev/null
+++ b/Control/AthAllocators/test/ArenaHeaderGaudiClear_test.cxx
@@ -0,0 +1,92 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// $Id: ArenaHeaderGaudiClear_test.cxx 470529 2011-11-24 23:54:22Z ssnyder $
+/**
+ * @file AthAllocators/test/ArenaHeaderGaudiClear_test.cxx
+ * @author scott snyder <snyder@bnl.gov>
+ * @date Jun, 2007
+ * @brief Regression tests for ArenaHeaderGaudiClear.
+ */
+
+#undef NDEBUG
+#include "AthAllocators/ArenaHeaderGaudiClear.h"
+#include "AthAllocators/ArenaAllocatorBase.h"
+#include <cassert>
+
+
+int nreset = 0;
+class TestAlloc
+  : public SG::ArenaAllocatorBase
+{
+public:
+  virtual void reset() { ++nreset; }
+  virtual void erase() {}
+  virtual void reserve (size_t /*size*/) { }
+  virtual const ArenaAllocatorBase::Stats& stats() const
+  { return m_stats; }
+  virtual const std::string& name() const { return m_name; }
+  ArenaAllocatorBase::Stats m_stats;
+  std::string m_name;
+};
+
+
+int ndel = 0;
+class TestHeader
+  : public SG::ArenaHeaderGaudiClear
+{
+public:
+  virtual ~TestHeader() { ++ndel; }
+};
+
+
+void test1()
+{
+  ndel = nreset = 0;
+
+  SG::ArenaHeaderGaudiClear* h = new TestHeader;
+  h->initialize();
+
+  SG::ArenaHeader::ArenaAllocVec_t vec;
+  vec.push_back (new TestAlloc);
+  h->setAllocVec (&vec);
+  assert (nreset == 0);
+  h->handle (Incident ("test", "BeginEvent"));
+  assert (nreset == 1);
+  h->handle (Incident ("test", "EndEvent"));
+  assert (nreset == 1);
+  h->handle (Incident ("test", "BeginEvent"));
+  assert (nreset == 2);
+
+  h->addRef();
+  assert (ndel == 0);
+  h->release();
+  assert (ndel == 1);
+}
+
+
+void test2()
+{
+  ndel = nreset = 0;
+  SG::ArenaHeaderGaudiClear* h = new TestHeader;
+  SG::ArenaHeaderGaudiClear::disable();
+  h->initialize();
+
+  assert (nreset == 0);
+  h->handle (Incident ("test", "BeginEvent"));
+  assert (nreset == 0);
+
+  h->addRef();
+  assert (ndel == 0);
+  h->release();
+  assert (ndel == 1);
+}
+
+
+int main()
+{
+  test1();
+  test2();
+  return 0;
+}
diff --git a/Control/AthAllocators/test/ArenaHeader_test.cxx b/Control/AthAllocators/test/ArenaHeader_test.cxx
new file mode 100755
index 0000000000000000000000000000000000000000..6953b0fe190c319f5db6fa4229dc79f788b98853
--- /dev/null
+++ b/Control/AthAllocators/test/ArenaHeader_test.cxx
@@ -0,0 +1,124 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// $Id: ArenaHeader_test.cxx 470529 2011-11-24 23:54:22Z ssnyder $
+/**
+ * @file AthAllocators/test/ArenaHeader_test.cxx
+ * @author scott snyder <snyder@bnl.gov>
+ * @date May, 2007
+ * @brief Regression tests for ArenaHeader.
+ */
+
+#undef NDEBUG
+#include "AthAllocators/ArenaHeader.h"
+#include "AthAllocators/ArenaHeaderGaudiClear.h"
+#include "AthAllocators/ArenaAllocatorBase.h"
+#include "AthAllocators/ArenaAllocatorRegistry.h"
+#include "AthAllocators/ArenaAllocatorCreator.h"
+#include "AthAllocators/ArenaBase.h"
+#include <cassert>
+#include <ostream>
+
+std::string reset;
+class TestAlloc
+  : public SG::ArenaAllocatorBase
+{
+public:
+  TestAlloc (int x, const std::string& name)
+    : m_name (name) { m_stats.bytes.total = x; }
+  virtual void reset() { ::reset = m_name; }
+  virtual void erase() {}
+  virtual void reserve (size_t /*size*/) {}
+  virtual const SG::ArenaAllocatorBase::Stats& stats() const
+  { return m_stats; }
+  virtual const std::string& name() const { return m_name; }
+private:
+  SG::ArenaAllocatorBase::Stats m_stats;
+  std::string m_name;
+};
+
+class Creator
+  : public SG::ArenaAllocatorCreator
+{
+public:
+  Creator (int x) : m_x (x) {}
+  virtual SG::ArenaAllocatorBase* create()
+  { return new TestAlloc (m_x, "creat"); }
+private:
+  int m_x;
+};
+
+
+class TestArena
+  : public SG::ArenaBase
+{
+public:
+  TestArena (const std::string& name, int x) : m_name (name), m_x (x) {}
+  virtual void report (std::ostream& os) const
+  { os << "foo " << m_x << "\n"; }
+  virtual const std::string& name() const { return m_name; }
+private:
+  std::string m_name;
+  int m_x;
+};
+
+
+void test1()
+{
+  SG::ArenaHeader::ArenaAllocVec_t vec1;
+  vec1.resize (10);
+  vec1[2] = new TestAlloc (0, "a");
+  SG::ArenaHeader::ArenaAllocVec_t vec2;
+  vec2.resize (10);
+  vec2[5] = new TestAlloc (1, "b");
+
+  SG::ArenaHeader* head = SG::ArenaHeader::defaultHeader();
+  assert (head->setAllocVec(&vec1) == 0);
+  assert (head->allocator(2) == vec1[2]);
+  assert (head->setAllocVec(&vec2) == &vec1);
+  assert (head->allocator(5) == vec2[5]);
+  head->reset();
+  assert (reset == "b");
+
+  SG::ArenaHeader::ArenaAllocVec_t vec3;
+  assert (head->setAllocVec(0) == &vec2);
+  SG::ArenaAllocatorRegistry* reg =
+    SG::ArenaAllocatorRegistry::instance();
+  size_t i = reg->registerCreator ("foo", new Creator (1));
+  assert (i == 0);
+  assert (head->allocator(i)->stats().bytes.total == 1);
+}
+
+
+void test2()
+{
+  SG::ArenaHeader head;
+  TestArena a1 ("a1", 1);
+  TestArena a2 ("a2", 2);
+  head.addArena (&a1);
+  head.addArena (&a2);
+  std::string s = head.reportStr();
+  assert (s == "=== a1 ===\n\
+foo 1\n\
+=== a2 ===\n\
+foo 2\n");
+  head.delArena (&a1);
+  assert (head.allocator(0)->stats().bytes.total == 1);
+  s = head.reportStr();
+  assert (s == "=== a2 ===\n\
+foo 2\n\
+=== default ===\n\
+Elts InUse/Free/Total   Bytes InUse/Free/Total  Blocks InUse/Free/Total\n\
+       0/      0/      0       0/      0/      1       0/      0/      0  creat\n");
+
+}
+
+
+int main()
+{
+  SG::ArenaHeaderGaudiClear::disable();
+  test1();
+  test2();
+  return 0;
+}
diff --git a/Control/AthAllocators/test/ArenaHeapAllocator_test.cxx b/Control/AthAllocators/test/ArenaHeapAllocator_test.cxx
new file mode 100755
index 0000000000000000000000000000000000000000..493a64c3bcd4d0f13c47307484c2381e2d512d37
--- /dev/null
+++ b/Control/AthAllocators/test/ArenaHeapAllocator_test.cxx
@@ -0,0 +1,218 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// $Id: ArenaHeapAllocator_test.cxx 470529 2011-11-24 23:54:22Z ssnyder $
+/**
+ * @file AthAllocators/test/ArenaHeapAllocator_test.cxx
+ * @author scott snyder <snyder@bnl.gov>
+ * @date May, 2007
+ * @brief Regression tests for ArenaHeapAllocator.
+ */
+
+#undef NDEBUG
+#include "AthAllocators/ArenaHeapAllocator.h"
+#include "AthAllocators/ArenaBlock.h"
+#include <vector>
+#include <cassert>
+#include <algorithm>
+
+//==========================================================================
+
+int nclear;
+struct Payload
+{
+  Payload();
+  ~Payload();
+  void clear();
+
+  int x;
+  int y;
+  static int n;
+  static std::vector<int> v;
+};
+
+Payload::Payload()
+{
+  x = n++;
+  y = 0;
+  v.push_back (x);
+}
+
+Payload::~Payload()
+{
+  v.push_back (-x);
+}
+
+void Payload::clear ()
+{
+  y = 0;
+  ++nclear;
+}
+
+int Payload::n = 0;
+std::vector<int> Payload::v;
+
+//==========================================================================
+
+void test1()
+{
+  SG::ArenaHeapAllocator aha
+    (SG::ArenaHeapAllocator::initParams<Payload, true>(100, "foo"));
+  assert (aha.name() == "foo");
+  assert (aha.stats().elts.inuse == 0);
+  assert (aha.stats().elts.free == 0);
+  assert (aha.stats().elts.total == 0);
+  assert (aha.stats().blocks.inuse == 0);
+  assert (aha.stats().blocks.free  == 0);
+  assert (aha.stats().blocks.total == 0);
+  size_t elt_size = aha.params().eltSize;
+  size_t block_ov = SG::ArenaBlock::overhead();
+
+  int nptr = 987;
+  std::vector<Payload*> ptrs;
+  for (int i=0; i < nptr; i++) {
+    Payload* p = reinterpret_cast<Payload*> (aha.allocate());
+    ptrs.push_back (p);
+    p->y = 2*p->x;
+  }
+  assert  (Payload::v.size() == 1000);
+  for (int i=0; i < 1000; ++i) {
+    assert (Payload::v[i] == i);
+  }
+  assert (aha.stats().elts.inuse == 987);
+  assert (aha.stats().elts.free == 13);
+  assert (aha.stats().elts.total == 1000);
+  assert (aha.stats().blocks.inuse == 10);
+  assert (aha.stats().blocks.free  ==  0);
+  assert (aha.stats().blocks.total == 10);
+
+  for (size_t i = 0; i < ptrs.size(); i += 2)
+    aha.free ((char*)ptrs[i]);
+  assert (aha.stats().elts.inuse == 493);
+  assert (aha.stats().elts.free == 507);
+  assert (aha.stats().elts.total == 1000);
+  assert (aha.stats().blocks.inuse == 10);
+  assert (aha.stats().blocks.free  ==  0);
+  assert (aha.stats().blocks.total == 10);
+  for (size_t i = 0; i < ptrs.size(); i += 2)
+    assert (ptrs[i]->y == 0);
+  for (size_t i = 0; i < 300; i++)
+    ptrs.push_back (reinterpret_cast<Payload*>(aha.allocate()));
+  //printf ("%d %d %d\n", aha.stats().elts.inuse, aha.stats().elts.free, aha.stats().elts.total);
+  assert (aha.stats().elts.inuse == 793);
+  assert (aha.stats().elts.free == 207);
+  assert (aha.stats().elts.total == 1000);
+  assert (aha.stats().blocks.inuse == 10);
+  assert (aha.stats().blocks.free  ==  0);
+  assert (aha.stats().blocks.total == 10);
+
+  assert (aha.stats().bytes.inuse ==  (793 * elt_size + 10 * block_ov));
+  assert (aha.stats().bytes.free  ==  207 * elt_size);
+  assert (aha.stats().bytes.total == (1000 * elt_size + 10 * block_ov));
+
+  aha.reset();
+  assert (aha.stats().elts.inuse == 0);
+  assert (aha.stats().elts.free == 1000);
+  assert (aha.stats().elts.total == 1000);
+  assert (aha.stats().blocks.inuse ==  0);
+  assert (aha.stats().blocks.free  == 10);
+  assert (aha.stats().blocks.total == 10);
+
+  ptrs.clear();
+  for (size_t i = 0; i < 300; i++)
+    ptrs.push_back (reinterpret_cast<Payload*>(aha.allocate()));
+  assert (aha.stats().elts.inuse == 300);
+  assert (aha.stats().elts.free == 700);
+  assert (aha.stats().elts.total == 1000);
+  assert (aha.stats().blocks.inuse ==  3);
+  assert (aha.stats().blocks.free  ==  7);
+  assert (aha.stats().blocks.total == 10);
+
+  aha.reserve (550);
+  assert (aha.stats().elts.inuse == 300);
+  assert (aha.stats().elts.free == 300);
+  assert (aha.stats().elts.total == 600);
+  assert (aha.stats().blocks.inuse ==  3);
+  assert (aha.stats().blocks.free  ==  3);
+  assert (aha.stats().blocks.total ==  6);
+
+  aha.reserve (1000);
+  //printf ("%d %d %d\n", aha.stats().elts.inuse, aha.stats().elts.free, aha.stats().elts.total);
+  assert (aha.stats().elts.inuse == 300);
+  assert (aha.stats().elts.free == 700);
+  assert (aha.stats().elts.total == 1000);
+  assert (aha.stats().blocks.inuse ==  3);
+  assert (aha.stats().blocks.free  ==  4);
+  assert (aha.stats().blocks.total ==  7);
+
+  Payload::v.clear();
+  aha.erase();
+  assert (aha.stats().elts.inuse == 0);
+  assert (aha.stats().elts.free == 0);
+  assert (aha.stats().elts.total == 0);
+  assert (aha.stats().blocks.inuse ==  0);
+  assert (aha.stats().blocks.free  ==  0);
+  assert (aha.stats().blocks.total ==  0);
+  assert (Payload::v.size() == 1000);
+  std::sort (Payload::v.begin(), Payload::v.end());
+  for (size_t i = 0; i < 700; i++) {
+    assert (Payload::v[i] == (int)i-1399);
+    //printf ("%d %d\n", Payload::v[i], i);
+  }
+  for (size_t i = 700; i < Payload::v.size(); i++) {
+    assert (Payload::v[i] == (int)i-999);
+  }
+}
+
+
+void test2()
+{
+  SG::ArenaHeapAllocator::Params params = 
+    SG::ArenaHeapAllocator::initParams<Payload, true>(100);
+  params.mustClear = true;
+  params.canReclear = false;
+  SG::ArenaHeapAllocator aha (params);
+  assert (aha.stats().elts.inuse == 0);
+  assert (aha.stats().elts.free == 0);
+  assert (aha.stats().elts.total == 0);
+  assert (aha.stats().blocks.inuse ==  0);
+  assert (aha.stats().blocks.free  ==  0);
+  assert (aha.stats().blocks.total ==  0);
+
+  nclear = 0;
+  std::vector<Payload*> ptrs;
+  for (int i=0; i < 987; i++) {
+    Payload* p = reinterpret_cast<Payload*> (aha.allocate());
+    ptrs.push_back (p);
+    p->y = 2*p->x;
+  }
+  for (size_t i = 0; i < ptrs.size(); i+=2) {
+    aha.free ((char*)ptrs[i]);
+    assert (ptrs[i]->y == 0);
+    ptrs[i]->y = 1;
+  }
+  aha.reset();
+  assert (nclear == 987);
+  assert (aha.stats().elts.inuse == 0);
+  assert (aha.stats().elts.free == 1000);
+  assert (aha.stats().elts.total == 1000);
+  assert (aha.stats().blocks.inuse ==  0);
+  assert (aha.stats().blocks.free  == 10);
+  assert (aha.stats().blocks.total == 10);
+
+  for (size_t i = 0; i < ptrs.size(); i++) {
+    if ((i&1) != 0)
+      assert (ptrs[i]->y == 0);
+    else
+      assert (ptrs[i]->y == 1);
+  }
+}
+
+
+int main()
+{
+  test1();
+  test2();
+  return 0;
+}
diff --git a/Control/AthAllocators/test/ArenaHeapSTLAllocator_test.cxx b/Control/AthAllocators/test/ArenaHeapSTLAllocator_test.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..3c573e475ae4bccb4ab5bbf1053903585a7b2fda
--- /dev/null
+++ b/Control/AthAllocators/test/ArenaHeapSTLAllocator_test.cxx
@@ -0,0 +1,265 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// $Id: ArenaHeapSTLAllocator_test.cxx,v 1.2 2008-08-26 02:12:26 ssnyder Exp $
+/**
+ * @file AthAllocators/test/ArenaHeapSTLAllocator_test.cxx
+ * @author scott snyder <snyder@bnl.gov>
+ * @date Nov 2011
+ * @brief Regression tests for ArenaHeapSTLAllocator.
+ */
+
+
+#undef NDEBUG
+#include "AthAllocators/ArenaHeapSTLAllocator.h"
+#include "boost/assign/list_of.hpp"
+#include <list>
+#include <vector>
+#include <cassert>
+#include <iostream>
+
+using boost::assign::list_of;
+
+
+
+//==========================================================================
+
+struct Payload
+{
+  Payload(int = 0);
+  Payload(const Payload& p);
+  ~Payload();
+  void clear();
+
+  int x;
+  int y;
+  static int n;
+  static std::vector<int> v;
+};
+
+Payload::Payload(int the_y)
+{
+  x = n++;
+  y = the_y;
+  v.push_back (x);
+}
+
+Payload::Payload (const Payload& p)
+  : x (p.x),
+    y (p.y)
+{
+  v.push_back (x);
+}
+
+
+Payload::~Payload()
+{
+  v.push_back (-x);
+}
+
+void Payload::clear ()
+{
+  y = 0;
+}
+
+int Payload::n = 0;
+std::vector<int> Payload::v;
+
+//==========================================================================
+
+// Test generic specialization.
+void test1()
+{
+  Payload::v.clear();
+  Payload::n = 0;
+
+  std::cout << "test1\n";
+
+  SG::ArenaHeapSTLAllocator<Payload> a1;
+  assert (a1.nblock() == 1000);
+  assert (a1.name() == "");
+
+  SG::ArenaHeapSTLAllocator<Payload> a2 (100, "a2");
+  assert (a2.nblock() == 100);
+  assert (a2.name() == "a2");
+
+  SG::ArenaHeapSTLAllocator<Payload*, int> a3 (100, "a3");
+  assert (a3.nblock() == 100);
+  assert (a3.name() == "a3");
+
+  SG::ArenaHeapSTLAllocator<Payload, int> a4 (a3);
+  assert (a4.nblock() == 100);
+  assert (a4.name() == "a3");
+  assert (a4.poolptr() != 0);
+
+  {
+    Payload p;
+    Payload& pr = p;
+    const Payload& pcr = p;
+    assert (a4.address (pr) == &p);
+    assert (a4.address (pcr) == &p);
+  }
+  assert (Payload::n == 1);
+  assert (Payload::v.size() == 2);
+  Payload::v.clear();
+
+  std::vector<Payload*> pv;
+  for (int i=0; i < 10; i++)
+    pv.push_back (a4.allocate (1));
+
+  assert (Payload::n == 1);
+  assert (Payload::v.size() == 0);
+
+  assert (a4.max_size() == 1);
+
+  a4.construct (pv[0], Payload(10));
+  a4.destroy (pv[0]);
+
+  assert (Payload::n == 2);
+  std::vector<int> exp1 = list_of(1)(1)(-1)(-1);
+  assert (Payload::v == exp1);
+  Payload::v.clear();
+
+  for (int i=0; i < 9; i++) {
+    if (i > 0)
+      assert (pv[i] != pv[i-1]);
+    a4.deallocate (pv[i], 1);
+  }
+
+  assert (a4.stats().elts.inuse == 1);
+  assert (a4.stats().elts.total == 100);
+
+  a4.reset();
+  assert (a4.stats().elts.inuse == 0);
+  assert (a4.stats().elts.total == 100);
+
+  a4.erase();
+  assert (a4.stats().elts.inuse == 0);
+  assert (a4.stats().elts.total == 0);
+
+  a4.reserve(5000);
+  assert (a4.stats().elts.inuse == 0);
+  assert (a4.stats().elts.total == 5000);
+
+  assert (Payload::n == 2);
+  assert (Payload::v.size() == 0);
+}
+
+
+// Test vetoed specialization.
+void test2()
+{
+  Payload::v.clear();
+  Payload::n = 0;
+
+  std::cout << "test2\n";
+
+  SG::ArenaHeapSTLAllocator<int, int> a1;
+  assert (a1.nblock() == 1000);
+  assert (a1.name() == "");
+  assert (a1.poolptr() == 0);
+
+  SG::ArenaHeapSTLAllocator<int, int> a2 (100, "a2");
+  assert (a2.nblock() == 100);
+  assert (a2.name() == "a2");
+  assert (a2.poolptr() == 0);
+
+  a2.reset();
+  a2.erase();
+  a2.reserve(10);
+  assert (a2.stats().elts.total == 0);
+
+  SG::ArenaHeapSTLAllocator<Payload, int> a3 (500, "a3");
+  a3.reserve (1000);
+  SG::ArenaHeapSTLAllocator<int> a4 (a3);
+  assert (a4.nblock() == 500);
+  assert (a4.name() == "a3");
+  assert (a4.poolptr() == a3.poolptr());
+
+  (void)a3.allocate (1);
+  assert (a3.stats().elts.inuse == 1);
+  assert (a3.stats().elts.total == 1000);
+
+  assert (a4.stats().elts.inuse == 1);
+  assert (a4.stats().elts.total == 1000);
+  assert (&a3.stats() == &a4.stats());
+
+  a4.reset();
+  assert (a4.stats().elts.inuse == 0);
+  assert (a4.stats().elts.total == 1000);
+
+  a4.erase();
+  assert (a4.stats().elts.inuse == 0);
+  assert (a4.stats().elts.total == 0);
+
+  a4.reserve(1000);
+  assert (a4.stats().elts.inuse == 0);
+  assert (a4.stats().elts.total == 1000);
+
+  int* p = a4.allocate (2, 0);
+  assert (a4.stats().elts.inuse == 0);
+  assert (a4.stats().elts.total == 1000);
+
+  a4.deallocate (p, 2);
+  assert (a4.stats().elts.inuse == 0);
+  assert (a4.stats().elts.total == 1000);
+
+  assert (Payload::n == 0);
+  assert (Payload::v.size() == 0);
+}
+
+
+// In-situ test.
+void test3()
+{
+  Payload::v.clear();
+  Payload::n = 0;
+
+  std::cout << "test3\n";
+
+  typedef std::list<int, SG::ArenaHeapSTLAllocator<int> > list_t;
+
+  list_t::allocator_type allo (500, "allo");
+  list_t list (allo);
+
+  for (int i = 0; i < 10; i++)
+    list.push_back (i);
+
+  assert (list.size() == 10);
+  assert (list.get_allocator().stats().elts.total == 500);
+  assert (list.get_allocator().stats().elts.inuse == 10);
+
+  for (list_t::iterator i = list.begin();
+       i != list.end();
+       ++i)
+  {
+    i = list.erase (i);
+    if (i == list.end()) break;
+  }
+
+  assert (list.size() == 5);
+  assert (list.get_allocator().stats().elts.total == 500);
+  assert (list.get_allocator().stats().elts.inuse == 5);
+
+  list.clear();
+  assert (list.size() == 0);
+  assert (list.get_allocator().stats().elts.total == 500);
+  assert (list.get_allocator().stats().elts.inuse == 0);
+
+  list.get_allocator().reset();
+  assert (list.get_allocator().stats().elts.total == 500);
+  assert (list.get_allocator().stats().elts.inuse == 0);
+
+  assert (Payload::n == 0);
+  assert (Payload::v.size() == 0);
+}
+
+
+int main()
+{
+  test1();
+  test2();
+  test3();
+  return 0;
+}
diff --git a/Control/AthAllocators/test/ArenaPoolAllocator_test.cxx b/Control/AthAllocators/test/ArenaPoolAllocator_test.cxx
new file mode 100755
index 0000000000000000000000000000000000000000..7c705cc13458f4f550e8589c6f812d68d305ad42
--- /dev/null
+++ b/Control/AthAllocators/test/ArenaPoolAllocator_test.cxx
@@ -0,0 +1,262 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// $Id: ArenaPoolAllocator_test.cxx 470529 2011-11-24 23:54:22Z ssnyder $
+/**
+ * @file AthAllocators/test/ArenaPoolAllocator_test.cxx
+ * @author scott snyder <snyder@bnl.gov>
+ * @date May, 2007
+ * @brief Regression tests for ArenaPoolAllocator.
+ */
+
+#undef NDEBUG
+#include "AthAllocators/ArenaPoolAllocator.h"
+#include "AthAllocators/ArenaBlock.h"
+#include <vector>
+#include <cassert>
+#include <algorithm>
+
+//==========================================================================
+
+struct Payload
+{
+  Payload();
+  ~Payload();
+  void clear();
+
+  int x;
+  int y;
+  static int n;
+  static std::vector<int> v;
+};
+
+Payload::Payload()
+{
+  x = n++;
+  y = 0;
+  v.push_back (x);
+}
+
+Payload::~Payload()
+{
+  v.push_back (-x);
+}
+
+void Payload::clear ()
+{
+  y = 0;
+}
+
+int Payload::n = 0;
+std::vector<int> Payload::v;
+
+//==========================================================================
+
+void test1()
+{
+  SG::ArenaPoolAllocator apa
+    (SG::ArenaPoolAllocator::initParams<Payload, true>(100, "foo"));
+  assert (apa.name() == "foo");
+  assert (apa.stats().elts.inuse == 0);
+  assert (apa.stats().elts.free == 0);
+  assert (apa.stats().elts.total == 0);
+  assert (apa.stats().blocks.inuse == 0);
+  assert (apa.stats().blocks.free == 0);
+  assert (apa.stats().blocks.total == 0);
+  assert (apa.params().eltSize == sizeof (Payload));
+
+  int nptr = 987;
+  std::vector<Payload*> ptrs;
+  for (int i=0; i < nptr; i++) {
+    Payload* p = reinterpret_cast<Payload*> (apa.allocate());
+    ptrs.push_back (p);
+    p->y = 2*p->x;
+  }
+  assert  (Payload::v.size() == 1000);
+  for (int i=0; i < 1000; ++i) {
+    assert (Payload::v[i] == i);
+  }
+  assert (apa.stats().elts.inuse == 987);
+  assert (apa.stats().elts.free == 13);
+  assert (apa.stats().elts.total == 1000);
+  assert (apa.stats().blocks.inuse == 10);
+  assert (apa.stats().blocks.free == 0);
+  assert (apa.stats().blocks.total == 10);
+
+  Payload::v.clear();
+  apa.reset();
+  assert (apa.stats().elts.inuse == 0);
+  assert (apa.stats().elts.free == 1000);
+  assert (apa.stats().elts.total == 1000);
+  assert (apa.stats().blocks.inuse == 0);
+  assert (apa.stats().blocks.free == 10);
+  assert (apa.stats().blocks.total == 10);
+
+  for (int i=0; i < 300; i++) {
+    Payload* p = reinterpret_cast<Payload*> (apa.allocate());
+    assert (p->y == 0);
+    ptrs.push_back (p);
+    p->y = 2*p->x;
+  }
+  assert (Payload::v.size() == 0);
+  assert (apa.stats().elts.inuse == 300);
+  assert (apa.stats().elts.free == 700);
+  assert (apa.stats().elts.total == 1000);
+  assert (apa.stats().blocks.inuse == 3);
+  assert (apa.stats().blocks.free == 7);
+  assert (apa.stats().blocks.total == 10);
+
+  apa.allocate();
+  std::vector<int> vv;
+  for (SG::ArenaPoolAllocator::iterator ii = apa.begin();
+       ii != apa.end();
+       ++ii)
+  {
+    vv.push_back (reinterpret_cast<Payload*> (&*ii)->x);
+  }
+  std::sort (vv.begin(), vv.end());
+  assert (vv.size() == 301);
+  for (size_t jj = 0; jj < vv.size(); jj++) {
+    assert (vv[jj] == (int)jj);
+  }
+
+  vv.clear();
+  const SG::ArenaPoolAllocator& capa = apa;
+  for (SG::ArenaPoolAllocator::const_iterator ii = capa.begin();
+       ii != capa.end();
+       ++ii)
+  {
+    vv.push_back (reinterpret_cast<const Payload*> (&*ii)->x);
+  }
+  std::sort (vv.begin(), vv.end());
+  assert (vv.size() == 301);
+  for (size_t jj = 0; jj < vv.size(); jj++) {
+    assert (vv[jj] == (int)jj);
+  }
+
+  vv.clear();
+  for (SG::ArenaPoolAllocator::const_iterator ii = apa.begin();
+       ii != apa.end();
+       ++ii)
+  {
+    vv.push_back (reinterpret_cast<const Payload*> (&*ii)->x);
+  }
+  std::sort (vv.begin(), vv.end());
+  assert (vv.size() == 301);
+  for (size_t jj = 0; jj < vv.size(); jj++) {
+    assert (vv[jj] == (int)jj);
+  }
+
+  Payload::v.clear();
+  apa.reset();
+  for (int i=0; i < 400; i++) {
+    Payload* p = reinterpret_cast<Payload*> (apa.allocate());
+    assert (p->y == 0);
+    ptrs.push_back (p);
+    p->y = 2*p->x;
+  }
+  assert (Payload::v.size() == 0);
+  assert (apa.stats().elts.inuse == 400);
+  assert (apa.stats().elts.free == 600);
+  assert (apa.stats().elts.total == 1000);
+  assert (apa.stats().blocks.inuse == 4);
+  assert (apa.stats().blocks.free == 6);
+  assert (apa.stats().blocks.total == 10);
+
+  Payload::v.clear();
+  apa.reserve (550);
+  assert (apa.stats().elts.inuse == 400);
+  assert (apa.stats().elts.free == 200);
+  assert (apa.stats().elts.total == 600);
+  assert (apa.stats().blocks.inuse == 4);
+  assert (apa.stats().blocks.free == 2);
+  assert (apa.stats().blocks.total == 6);
+  assert (Payload::v.size() == 400);
+  std::sort (Payload::v.begin(), Payload::v.end());
+  for (size_t i=0; i < 100; i++) {
+    assert (Payload::v[i] == (int)i-799);
+  }
+  for (size_t i=100; i < Payload::v.size(); i++) {
+    assert (Payload::v[i] == (int)i-799);
+  }
+
+  Payload::v.clear();
+  apa.reserve (950);
+  assert (apa.stats().elts.inuse == 400);
+  assert (apa.stats().elts.free == 550);
+  assert (apa.stats().elts.total == 950);
+  assert (apa.stats().blocks.inuse == 4);
+  assert (apa.stats().blocks.free == 3);
+  assert (apa.stats().blocks.total == 7);
+  assert (Payload::v.size() == 350);
+  std::sort (Payload::v.begin(), Payload::v.end());
+  for (size_t i=0; i < Payload::v.size(); i++) {
+    assert (Payload::v[i] == (int)i+1000);
+  }
+
+  Payload::v.clear();
+  apa.erase();
+  assert (Payload::v.size() == 950);
+  std::sort (Payload::v.begin(), Payload::v.end());
+  for (size_t i=0; i < 550; i++) {
+    assert (Payload::v[i] == (int)i-1349);
+  }
+  for (size_t i=550; i < Payload::v.size(); i++) {
+    assert (Payload::v[i] == (int)i-949);
+  }
+  assert (apa.stats().elts.inuse == 0);
+  assert (apa.stats().elts.free == 0);
+  assert (apa.stats().elts.total == 0);
+  assert (apa.stats().blocks.inuse == 0);
+  assert (apa.stats().blocks.free  == 0);
+  assert (apa.stats().blocks.total == 0);
+}
+
+
+void test2()
+{
+  Payload::v.clear();
+  SG::ArenaPoolAllocator apa
+    (SG::ArenaPoolAllocator::initParams<Payload, true>(100));
+  for (int i=0; i < 150; i++) {
+    apa.allocate();
+  }
+  assert (Payload::v.size() == 200);
+  SG::ArenaPoolAllocator::pointer p = apa.allocate();
+  assert (Payload::v.size() == 200);
+  for (int i=0; i < 150; i++) {
+    apa.allocate();
+  }
+  assert (Payload::v.size() == 400);
+  assert (apa.stats().elts.inuse == 301);
+  assert (apa.stats().elts.free == 99);
+  assert (apa.stats().elts.total == 400);
+  assert (apa.stats().blocks.inuse == 4);
+  assert (apa.stats().blocks.free  == 0);
+  assert (apa.stats().blocks.total == 4);
+
+  size_t elt_size = apa.params().eltSize;
+  size_t block_ov = SG::ArenaBlock::overhead();
+
+  apa.resetTo (p);
+
+  assert (apa.stats().elts.inuse == 150);
+  assert (apa.stats().elts.free == 250);
+  assert (apa.stats().elts.total == 400);
+  assert (apa.stats().blocks.inuse == 2);
+  assert (apa.stats().blocks.free  == 2);
+  assert (apa.stats().blocks.total == 4);
+
+  assert (apa.stats().bytes.inuse == (150 * elt_size + 2 * block_ov));
+  assert (apa.stats().bytes.free == (250 * elt_size + 2 * block_ov));
+  assert (apa.stats().bytes.total == (400 * elt_size + 4 * block_ov));
+}
+
+
+int main()
+{
+  test1();
+  test2();
+  return 0;
+}
diff --git a/Control/AthAllocators/test/ArenaPoolSTLAllocator_test.cxx b/Control/AthAllocators/test/ArenaPoolSTLAllocator_test.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..050e8d6c399b65fca5c0cb29ebe1a5c9a85956bd
--- /dev/null
+++ b/Control/AthAllocators/test/ArenaPoolSTLAllocator_test.cxx
@@ -0,0 +1,318 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// $Id: ArenaPoolSTLAllocator_test.cxx 470529 2011-11-24 23:54:22Z ssnyder $
+/**
+ * @file AthAllocators/test/ArenaPoolAllocator_test.cxx
+ * @author scott snyder <snyder@bnl.gov>
+ * @date Jul, 2008
+ * @brief Regression tests for ArenaPoolSTLAllocator.
+ */
+
+
+#undef NDEBUG
+#include "AthAllocators/ArenaPoolSTLAllocator.h"
+#include "CxxUtils/unordered_map.h"
+#include "boost/assign/list_of.hpp"
+#include <vector>
+#include <cassert>
+#include <iostream>
+
+using boost::assign::list_of;
+
+
+
+//==========================================================================
+
+struct Payload
+{
+  Payload(int = 0);
+  Payload(const Payload& p);
+  ~Payload();
+  void clear();
+
+  int x;
+  int y;
+  static int n;
+  static std::vector<int> v;
+};
+
+Payload::Payload(int the_y)
+{
+  x = n++;
+  y = the_y;
+  v.push_back (x);
+}
+
+Payload::Payload (const Payload& p)
+  : x (p.x),
+    y (p.y)
+{
+  v.push_back (x);
+}
+
+
+Payload::~Payload()
+{
+  v.push_back (-x);
+}
+
+void Payload::clear ()
+{
+  y = 0;
+}
+
+int Payload::n = 0;
+std::vector<int> Payload::v;
+
+//==========================================================================
+
+// Test generic specialization.
+void test1()
+{
+  Payload::v.clear();
+  Payload::n = 0;
+
+  std::cout << "test1\n";
+
+  SG::ArenaPoolSTLAllocator<Payload> a1;
+  assert (a1.nblock() == 1000);
+  assert (a1.name() == "");
+
+  SG::ArenaPoolSTLAllocator<Payload> a2 (100, "a2");
+  assert (a2.nblock() == 100);
+  assert (a2.name() == "a2");
+
+  SG::ArenaPoolSTLAllocator<Payload*, int> a3 (100, "a3");
+  assert (a3.nblock() == 100);
+  assert (a3.name() == "a3");
+
+  SG::ArenaPoolSTLAllocator<Payload, int> a4 (a3);
+  assert (a4.nblock() == 100);
+  assert (a4.name() == "a3");
+  assert (a4.poolptr() != 0);
+
+  {
+    Payload p;
+    Payload& pr = p;
+    const Payload& pcr = p;
+    assert (a4.address (pr) == &p);
+    assert (a4.address (pcr) == &p);
+  }
+  assert (Payload::n == 1);
+  assert (Payload::v.size() == 2);
+  Payload::v.clear();
+
+  std::vector<Payload*> pv;
+  for (int i=0; i < 10; i++)
+    pv.push_back (a4.allocate (1));
+
+  assert (Payload::n == 1);
+  assert (Payload::v.size() == 0);
+
+  assert (a4.max_size() == 1);
+
+  a4.construct (pv[0], Payload(10));
+  a4.destroy (pv[0]);
+
+  assert (Payload::n == 2);
+  std::vector<int> exp1 = list_of(1)(1)(-1)(-1);
+  assert (Payload::v == exp1);
+  Payload::v.clear();
+
+  for (int i=0; i < 10; i++) {
+    if (i > 0)
+      assert (pv[i] != pv[i-1]);
+    a4.deallocate (pv[i], 1);
+  }
+
+  assert (a4.stats().elts.inuse == 10);
+  assert (a4.stats().elts.total == 100);
+
+  a4.reset();
+  assert (a4.stats().elts.inuse == 0);
+  assert (a4.stats().elts.total == 100);
+
+  a4.erase();
+  assert (a4.stats().elts.inuse == 0);
+  assert (a4.stats().elts.total == 0);
+
+  a4.reserve(5000);
+  assert (a4.stats().elts.inuse == 0);
+  assert (a4.stats().elts.total == 5000);
+
+  assert (Payload::n == 2);
+  assert (Payload::v.size() == 0);
+}
+
+
+// Test pointer specialization.
+void test2()
+{
+  Payload::v.clear();
+  Payload::n = 0;
+
+  std::cout << "test2\n";
+
+  SG::ArenaPoolSTLAllocator<Payload*, int> a1;
+  assert (a1.nblock() == 1000);
+  assert (a1.name() == "");
+  assert (a1.poolptr() == 0);
+
+  SG::ArenaPoolSTLAllocator<Payload*, int> a2 (100, "a2");
+  assert (a2.nblock() == 100);
+  assert (a2.name() == "a2");
+  assert (a2.poolptr() == 0);
+
+  a2.reset();
+  a2.erase();
+  a2.reserve(10);
+  assert (a2.stats().elts.total == 0);
+
+  SG::ArenaPoolSTLAllocator<Payload, int> a3 (500, "a3");
+  a3.reserve (1000);
+  SG::ArenaPoolSTLAllocator<Payload*, int> a4 (a3);
+  assert (a4.nblock() == 500);
+  assert (a4.name() == "a3");
+  assert (a4.poolptr() == a3.poolptr());
+
+  (void)a3.allocate (1);
+  assert (a3.stats().elts.inuse == 1);
+  assert (a3.stats().elts.total == 1000);
+
+  assert (a4.stats().elts.inuse == 1);
+  assert (a4.stats().elts.total == 1000);
+  assert (&a3.stats() == &a4.stats());
+
+  a4.reset();
+  assert (a4.stats().elts.inuse == 0);
+  assert (a4.stats().elts.total == 1000);
+
+  a4.erase();
+  assert (a4.stats().elts.inuse == 0);
+  assert (a4.stats().elts.total == 0);
+
+  a4.reserve(1000);
+  assert (a4.stats().elts.inuse == 0);
+  assert (a4.stats().elts.total == 1000);
+
+  Payload** p = a4.allocate (2, 0);
+  assert (a4.stats().elts.inuse == 0);
+  assert (a4.stats().elts.total == 1000);
+
+  a4.deallocate (p, 2);
+  assert (a4.stats().elts.inuse == 0);
+  assert (a4.stats().elts.total == 1000);
+
+  assert (Payload::n == 0);
+  assert (Payload::v.size() == 0);
+}
+
+
+// Test vetoed specialization.
+void test3()
+{
+  Payload::v.clear();
+  Payload::n = 0;
+
+  std::cout << "test3\n";
+
+  SG::ArenaPoolSTLAllocator<int, int> a1;
+  assert (a1.nblock() == 1000);
+  assert (a1.name() == "");
+  assert (a1.poolptr() == 0);
+
+  SG::ArenaPoolSTLAllocator<int, int> a2 (100, "a2");
+  assert (a2.nblock() == 100);
+  assert (a2.name() == "a2");
+  assert (a2.poolptr() == 0);
+
+  a2.reset();
+  a2.erase();
+  a2.reserve(10);
+  assert (a2.stats().elts.total == 0);
+
+  SG::ArenaPoolSTLAllocator<Payload, int> a3 (500, "a3");
+  a3.reserve (1000);
+  SG::ArenaPoolSTLAllocator<int> a4 (a3);
+  assert (a4.nblock() == 500);
+  assert (a4.name() == "a3");
+  assert (a4.poolptr() == a3.poolptr());
+
+  (void)a3.allocate (1);
+  assert (a3.stats().elts.inuse == 1);
+  assert (a3.stats().elts.total == 1000);
+
+  assert (a4.stats().elts.inuse == 1);
+  assert (a4.stats().elts.total == 1000);
+  assert (&a3.stats() == &a4.stats());
+
+  a4.reset();
+  assert (a4.stats().elts.inuse == 0);
+  assert (a4.stats().elts.total == 1000);
+
+  a4.erase();
+  assert (a4.stats().elts.inuse == 0);
+  assert (a4.stats().elts.total == 0);
+
+  a4.reserve(1000);
+  assert (a4.stats().elts.inuse == 0);
+  assert (a4.stats().elts.total == 1000);
+
+  int* p = a4.allocate (2, 0);
+  assert (a4.stats().elts.inuse == 0);
+  assert (a4.stats().elts.total == 1000);
+
+  a4.deallocate (p, 2);
+  assert (a4.stats().elts.inuse == 0);
+  assert (a4.stats().elts.total == 1000);
+
+  assert (Payload::n == 0);
+  assert (Payload::v.size() == 0);
+}
+
+
+// In-situ test.
+void test4()
+{
+  Payload::v.clear();
+  Payload::n = 0;
+
+  std::cout << "test4\n";
+
+  typedef SG::unordered_map<int, int, SG::hash<int>, std::equal_to<int>,
+    SG::ArenaPoolSTLAllocator<std::pair<const int, int> > > map_t;
+
+  map_t::allocator_type allo (500, "allo");
+  map_t map (10, map_t::hasher(), map_t::key_equal(), allo);
+
+  for (int i = 0; i < 10; i++)
+    map[i] = i;
+
+  assert (map.size() == 10);
+  assert (map.get_allocator().stats().elts.total == 500);
+  assert (map.get_allocator().stats().elts.inuse == 10);
+
+  map.clear();
+  assert (map.size() == 0);
+  assert (map.get_allocator().stats().elts.total == 500);
+  assert (map.get_allocator().stats().elts.inuse == 10);
+
+  map.get_allocator().reset();
+  assert (map.get_allocator().stats().elts.total == 500);
+  assert (map.get_allocator().stats().elts.inuse == 0);
+
+  assert (Payload::n == 0);
+  assert (Payload::v.size() == 0);
+}
+
+
+int main()
+{
+  test1();
+  test2();
+  test3();
+  test4();
+  return 0;
+}
diff --git a/Control/AthAllocators/test/ArenaSharedHeapSTLAllocator_test.cxx b/Control/AthAllocators/test/ArenaSharedHeapSTLAllocator_test.cxx
new file mode 100644
index 0000000000000000000000000000000000000000..ef3025b1956344c35a5d74a54ecf18e1e6140abc
--- /dev/null
+++ b/Control/AthAllocators/test/ArenaSharedHeapSTLAllocator_test.cxx
@@ -0,0 +1,283 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// $Id: ArenaSharedHeapSTLAllocator_test.cxx 470825 2011-11-25 23:20:57Z ssnyder $
+/**
+ * @file AthAllocators/test/ArenaSharedHeapSTLAllocator_test.cxx
+ * @author scott snyder <snyder@bnl.gov>
+ * @date Nov 2011
+ * @brief Regression tests for ArenaSharedHeapSTLAllocator.
+ */
+
+
+#undef NDEBUG
+#include "AthAllocators/ArenaSharedHeapSTLAllocator.h"
+#include "AthAllocators/ArenaBlock.h"
+#include "boost/assign/list_of.hpp"
+#include <list>
+#include <vector>
+#include <cassert>
+#include <iostream>
+
+using boost::assign::list_of;
+
+
+
+//==========================================================================
+
+struct Payload
+{
+  Payload(int = 0);
+  Payload(const Payload& p);
+  ~Payload();
+  void clear();
+
+  int x;
+  int y;
+  static int n;
+  static std::vector<int> v;
+};
+
+Payload::Payload(int the_y)
+{
+  x = n++;
+  y = the_y;
+  v.push_back (x);
+}
+
+Payload::Payload (const Payload& p)
+  : x (p.x),
+    y (p.y)
+{
+  v.push_back (x);
+}
+
+
+Payload::~Payload()
+{
+  v.push_back (-x);
+}
+
+void Payload::clear ()
+{
+  y = 0;
+}
+
+int Payload::n = 0;
+std::vector<int> Payload::v;
+
+
+struct Payload2 : public Payload
+{
+  Payload2() {}
+  Payload2(int y) : Payload(y) {}
+};
+
+//==========================================================================
+
+// Test generic specialization.
+void test1()
+{
+  Payload::v.clear();
+  Payload::n = 0;
+
+  std::cout << "test1\n";
+
+  SG::ArenaSharedHeapSTLAllocator<Payload> a1;
+  assert (a1.nblock() == 1000);
+  assert (a1.name() == "::ArenaSharedHeapSTLAllocator<Payload>");
+
+  SG::ArenaSharedHeapSTLAllocator<Payload> a2 (100, "a2");
+  assert (a2.nblock() == 100);
+  assert (a2.name() == "a2::ArenaSharedHeapSTLAllocator<Payload>");
+
+  {
+    Payload p;
+    Payload& pr = p;
+    const Payload& pcr = p;
+    assert (a2.address (pr) == &p);
+    assert (a2.address (pcr) == &p);
+  }
+  assert (Payload::n == 1);
+  assert (Payload::v.size() == 2);
+  Payload::v.clear();
+
+  std::vector<Payload*> pv;
+  for (int i=0; i < 10; i++)
+    pv.push_back (a2.allocate (1));
+
+  assert (Payload::n == 1);
+  assert (Payload::v.size() == 0);
+
+  assert (a2.max_size() == 1);
+
+  a2.construct (pv[0], Payload(10));
+  a2.destroy (pv[0]);
+
+  assert (Payload::n == 2);
+  std::vector<int> exp1 = list_of(1)(1)(-1)(-1);
+  assert (Payload::v == exp1);
+  Payload::v.clear();
+
+  for (int i=0; i < 9; i++) {
+    if (i > 0)
+      assert (pv[i] != pv[i-1]);
+    a2.deallocate (pv[i], 1);
+  }
+
+  assert (a2.stats().elts.inuse == 1);
+  assert (a2.stats().elts.total == 100);
+
+  a2.reset();
+  assert (a2.stats().elts.inuse == 0);
+  assert (a2.stats().elts.total == 100);
+
+  a2.erase();
+  assert (a2.stats().elts.inuse == 0);
+  assert (a2.stats().elts.total == 0);
+
+  a2.reserve(5000);
+  assert (a2.stats().elts.inuse == 0);
+  assert (a2.stats().elts.total == 5000);
+
+  assert (Payload::n == 2);
+  assert (Payload::v.size() == 0);
+
+  SG::ArenaSharedHeapSTLAllocator<Payload> a3 (a2);
+  assert (a2.nblock() == 100);
+  assert (a2.name() == "a2::ArenaSharedHeapSTLAllocator<Payload>");
+
+  Payload* p1 = a2.allocate (1);
+  assert (a2.stats().elts.inuse == 1);
+  assert (a2.stats().elts.total == 5000);
+
+  Payload* p2 = a3.allocate (1);
+  assert (a3.stats().elts.inuse == 2);
+  assert (a3.stats().elts.total == 5000);
+
+  SG::ArenaSharedHeapSTLAllocator<int> a4 (a2);
+  assert (a4.nblock() == 100);
+  assert (a4.name() == "a2::ArenaSharedHeapSTLAllocator<int>");
+
+  int* p3 = a4.allocate(1);
+  assert (a3.stats().elts.inuse == 2);
+  assert (a3.stats().elts.total == 5000);
+  assert (a4.stats().elts.inuse == 1);
+  assert (a4.stats().elts.total == 100);
+
+  a2.deallocate (p1, 1);
+  a3.deallocate (p2, 1);
+  a4.deallocate (p3, 1);
+ }
+
+
+// Test deallocation.
+void test2()
+{
+  Payload::v.clear();
+  Payload::n = 0;
+
+  std::cout << "test2\n";
+
+  //Payload* p1;
+  //Payload2* p2;
+
+  {
+    SG::ArenaSharedHeapSTLAllocator<Payload> a1;
+    SG::ArenaSharedHeapSTLAllocator<Payload2> a2 (a1);
+
+    a1.allocate(1);
+    a2.allocate(1);
+  }
+}
+
+
+// In-situ test.
+void test3()
+{
+  Payload::v.clear();
+  Payload::n = 0;
+
+  std::cout << "test3\n";
+
+  typedef std::list<int, SG::ArenaSharedHeapSTLAllocator<int> > list_t;
+
+  list_t::allocator_type allo (500, "allo");
+  list_t list (allo);
+
+  for (int i = 0; i < 10; i++)
+    list.push_back (i);
+
+  assert (list.size() == 10);
+  SG::ArenaAllocatorBase::Stats stats;
+  stats = list.get_allocator().totstats();
+  assert (stats.elts.total == 500);
+  assert (stats.elts.inuse == 10);
+
+  for (list_t::iterator i = list.begin();
+       i != list.end();
+       ++i)
+  {
+    i = list.erase (i);
+    if (i == list.end()) break;
+  }
+
+  assert (list.size() == 5);
+  stats = list.get_allocator().totstats();
+  assert (stats.elts.total == 500);
+  assert (stats.elts.inuse == 5);
+
+  list_t list2 (allo);
+  list2.push_back (10);
+  stats = list2.get_allocator().totstats();
+  assert (stats.elts.inuse == 6);
+
+  list_t list3 (list2);
+  stats = list2.get_allocator().totstats();
+  assert (stats.elts.inuse == 7);
+
+  list.clear();
+  assert (list.size() == 0);
+  stats = list.get_allocator().totstats();
+  assert (stats.elts.total == 500);
+  assert (stats.elts.inuse == 2);
+
+  list2.clear();
+  stats = list.get_allocator().totstats();
+  assert (stats.elts.inuse == 1);
+
+  list3.clear();
+  stats = list.get_allocator().totstats();
+  assert (stats.elts.inuse == 0);
+
+  list.get_allocator().reset();
+  stats = list.get_allocator().totstats();
+  assert (stats.elts.total == 500);
+  assert (stats.elts.inuse == 0);
+
+  list.push_back(1);
+  stats = list.get_allocator().totstats();
+  assert (stats.elts.inuse == 1);
+
+  list2 = list;
+  stats = list.get_allocator().totstats();
+  assert (stats.elts.inuse == 2);
+
+  list.swap(list2);
+  stats = list.get_allocator().totstats();
+  assert (stats.elts.inuse == 2);
+
+  assert (Payload::n == 0);
+  assert (Payload::v.size() == 0);
+}
+
+
+int main()
+{
+  test1();
+  test2();
+  test3();
+  assert (SG::ArenaBlock::nactive() == 0);
+  return 0;
+}
diff --git a/Control/AthAllocators/test/Arena_test.cxx b/Control/AthAllocators/test/Arena_test.cxx
new file mode 100755
index 0000000000000000000000000000000000000000..632d1bf17239b00e7ef45e9f65c9e242c218273a
--- /dev/null
+++ b/Control/AthAllocators/test/Arena_test.cxx
@@ -0,0 +1,102 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+// $Id: Arena_test.cxx 470529 2011-11-24 23:54:22Z ssnyder $
+/**
+ * @file AthAllocators/test/Arena_test.cxx
+ * @author scott snyder <snyder@bnl.gov>
+ * @date May, 2007
+ * @brief Regression tests for Arena.
+ */
+
+#undef NDEBUG
+#include "AthAllocators/Arena.h"
+#include "AthAllocators/ArenaHeader.h"
+#include "AthAllocators/ArenaHeaderGaudiClear.h"
+#include "AthAllocators/ArenaAllocatorBase.h"
+#include "AthAllocators/ArenaAllocatorCreator.h"
+#include "AthAllocators/ArenaAllocatorRegistry.h"
+#include <cassert>
+#include <sstream>
+
+
+int xxx = 0;
+class Alloc
+  : public SG::ArenaAllocatorBase
+{
+public:
+  Alloc(int x);
+  virtual void reset() { xxx += m_x; }
+  virtual void erase() { xxx += 2*m_x; }
+  virtual void reserve (size_t /*size*/) {}
+  virtual const SG::ArenaAllocatorBase::Stats& stats() const
+  { return m_stats; }
+  virtual const std::string& name() const { return m_name; }
+private:
+  std::string m_name;
+  int m_x;
+  SG::ArenaAllocatorBase::Stats m_stats;
+};
+
+Alloc::Alloc (int x)
+  : m_x (x)
+{
+  m_stats.bytes.inuse = x;
+  m_stats.bytes.free = 2*x;
+  m_stats.bytes.total = 3*x;
+
+  std::ostringstream os;
+  os << "alloc" << x;
+  m_name = os.str();
+}
+
+class Creator
+  : public SG::ArenaAllocatorCreator
+{
+public:
+  Creator (int x) : m_x (x) {}
+  virtual SG::ArenaAllocatorBase* create() { return new Alloc (m_x); }
+private:
+  int m_x;
+};
+
+void test1()
+{
+  SG::ArenaHeader head;
+  SG::Arena a ("a", &head);
+  {
+    SG::Arena::Push p (a);
+    SG::ArenaAllocatorRegistry* reg =
+      SG::ArenaAllocatorRegistry::instance();
+    assert (reg->registerCreator ("1", new Creator(1)) == 0);
+    assert (reg->registerCreator ("2", new Creator(2)) == 1);
+    assert (head.allocator(0)->stats().bytes.inuse == 1);
+    assert (head.allocator(1)->stats().bytes.inuse == 2);
+
+    assert (a.stats().bytes.inuse == 3);
+    assert (a.stats().bytes.free  == 6);
+    assert (a.stats().bytes.total == 9);
+
+    std::ostringstream os;
+    a.report (os);
+    assert (os.str() == "Elts InUse/Free/Total   Bytes InUse/Free/Total  Blocks InUse/Free/Total\n\
+       0/      0/      0       1/      2/      3       0/      0/      0  alloc1\n\
+       0/      0/      0       2/      4/      6       0/      0/      0  alloc2\n");
+
+    assert (xxx == 0);
+    a.reset();
+    assert (xxx == 3);
+    a.erase();
+    assert (xxx == 9);
+  }
+}
+
+
+int main()
+{
+  SG::ArenaHeaderGaudiClear::disable();
+  test1();
+  return 0;
+}
+
diff --git a/Control/AthAllocators/test/AthAllocators.xml b/Control/AthAllocators/test/AthAllocators.xml
new file mode 100755
index 0000000000000000000000000000000000000000..df18d25030babd6f3468c9b1d7875b77a8860f1e
--- /dev/null
+++ b/Control/AthAllocators/test/AthAllocators.xml
@@ -0,0 +1,16 @@
+<?xml version="1.0"?>
+<atn>
+   <TEST name="AthAllocatorsTest" type="makecheck" suite="Examples">
+      <package>Control/AthAllocators</package>
+      <timelimit>40</timelimit>
+      <author> Paolo Calafiura </author>
+      <mailto> pcalafiura@lbl.gov, snyder@fnal.gov, binet@cern.ch</mailto>
+      <expectations>
+         <errorMessage>Athena exited abnormally</errorMessage>
+         <errorMessage>differ</errorMessage>
+         <warningMessage> # WARNING_MESSAGE : post.sh> ERROR</warningMessage>
+         <successMessage>check ok</successMessage>
+         <returnValue>0</returnValue>
+      </expectations>
+   </TEST>
+</atn>
diff --git a/Control/AthAllocators/test/DataPool_test.cxx b/Control/AthAllocators/test/DataPool_test.cxx
new file mode 100755
index 0000000000000000000000000000000000000000..b6d91e12bcf0bdd65e8da7ee54d4b73363e5af64
--- /dev/null
+++ b/Control/AthAllocators/test/DataPool_test.cxx
@@ -0,0 +1,143 @@
+/*
+  Copyright (C) 2002-2017 CERN for the benefit of the ATLAS collaboration
+*/
+
+#undef NDEBUG
+
+#include "AthAllocators/DataPool.h"
+#include "GaudiKernel/ISvcLocator.h"
+#include "GaudiKernel/IChronoStatSvc.h"
+#include "TestTools/initGaudi.h"
+
+#include <cassert>
+#include <iostream>
+#include <string>
+#include <vector>
+
+using namespace std;
+
+class Fluff
+{
+	public:
+		virtual ~Fluff() { }
+		Fluff() : m_int(1), m_float(-379.456f),
+			m_string("this is the Fluff struct")
+		{
+		}
+
+		Fluff(const Fluff& f)
+		{
+			m_int = f.m_int;
+			m_float = f.m_float;
+			m_string = f.m_string;
+		}
+
+		void setPar(int j) { m_int = j; }
+		int value() const { return m_int; }
+
+	private:
+
+		int m_int;
+		float m_float;
+		string m_string;
+
+};
+
+int main ()
+{
+
+	ISvcLocator* pSvcLoc;
+	if (!Athena_test::initGaudi("DataPool_test.txt", pSvcLoc))
+	{
+		std::cerr << " This test cannot be run without init Gaudi" << endl;
+	}
+	assert(pSvcLoc);
+
+	IChronoStatSvc* p_svc;
+	if ((pSvcLoc->service("ChronoStatSvc", p_svc)).isSuccess())
+	{
+		p_svc->chronoStart("ChronoStatSvc");
+	}
+
+	std::cout << " *** DataPool test in progress: " << std::endl;
+
+	// ask for 10 Fluff's in memory, but default is 1024!
+	DataPool<Fluff>* df = new DataPool<Fluff>(10);
+	DataPool<Fluff>::const_iterator iter = df->begin();
+	DataPool<Fluff>::const_iterator iend = df->end();
+	assert(iter == iend);		 // because pool ain't accessed yet.
+	assert (0 == df->allocated());
+	//  check pool capacity: default is 1024 even though we asked for 10
+	assert (1024 == df->capacity());
+
+	// Now use the first 5 of these Fluff's
+	for (int j = 10; j < 15; j++)
+	{
+		Fluff* f = df->nextElementPtr();
+		f->setPar(j);
+	}
+	assert (5 == df->allocated());
+
+	// loop again and check whether the first five are set:
+	int k = 10;
+	DataPool<Fluff>::const_iterator iter2 = df->begin();
+	DataPool<Fluff>::const_iterator iend2 = df->end();
+	for (; iter2 != iend2; iter2++)
+	{
+		assert(0 != (*iter2));
+                // Note: we iterate backwards...
+		assert(24-k == (*iter2)->value());
+		k++;
+	}
+
+	
+	df->reset();						// reset DataPool
+	DataPool<Fluff>::const_iterator iter3 = df->begin();
+	DataPool<Fluff>::const_iterator iend3 = df->end();
+	assert (iter3 == iend3);	 // after reset
+	assert (0 == df->allocated());
+	assert (1024 == df->capacity());			// should be same
+
+	// Now use 1500 of these Fluff's.. should automatically resize
+	//cout << "You should see a message on automatic increase of pool size" << endl;
+
+	for (int j = 0; j < 1500; j++)
+	{
+		Fluff* f = df->nextElementPtr();
+		f->setPar(j);
+	}
+
+	assert(1500 == df->allocated());			// up by 2 automatically
+								 
+	assert(2048 == df->capacity());
+
+	// check that resizing to less than m_refCount doesn't work
+	df->reserve(1000);
+	assert(2048==df->capacity());
+	assert(1500==df->allocated());
+
+	// check that resizing to less than m_maxRefCount works
+	// changes related to m_maxRefCount are not visible in capacity() or allocated().
+	df->reserve(1600);			
+
+	assert(2048==df->capacity());
+	assert(1500==df->allocated());
+
+	// this is test by cheating. We reset the data pool (objects are not deleted
+	// we go to the memory location and check if all values are still ok.
+	df->reset();
+	for (int j = 0; j < 1500; j++)
+	{
+		Fluff* f = static_cast<Fluff*>(df->mem());
+		assert(j == f->value());
+	}
+
+	// call the pool destructor
+	delete df;
+
+	cout << " **** DataPool test successfully completed **** " << endl;
+	p_svc->chronoStop("ChronoStatSvc");
+	p_svc->chronoPrint("ChronoStatSvc");
+
+	return 0;
+}