From 0296a11b38bf48363a2dddcc4769959a320e79a5 Mon Sep 17 00:00:00 2001
From: Rene Brun <Rene.Brun@cern.ch>
Date: Fri, 29 Oct 2004 18:03:11 +0000
Subject: [PATCH] from Markus Frank (main work) + Philippe & Rene Add support
 for all STL collections, including collections of collections. TTree has been
 extended to support split mode for most STL collections. The test program
 bench.cxx/TBench.cxx has been extended to test STL collections of objects or
 pointers.

git-svn-id: http://root.cern.ch/svn/root/trunk@10431 27541ba8-7e3a-0410-8455-c3a389f83636
---
 cont/inc/TCollectionProxy.h           |  486 +++++++++++
 cont/inc/TEmulatedCollectionProxy.h   |  110 +++
 cont/inc/TEmulatedMapProxy.h          |   66 ++
 cont/inc/TEmulatedVectorProxy.h       |   10 +-
 cont/inc/TGenCollectionProxy.h        |  311 +++++++
 cont/inc/TGenCollectionStreamer.h     |   89 ++
 cont/inc/TVectorProxy.h               |    5 +-
 cont/inc/TVirtualCollectionProxy.h    |   11 +-
 cont/src/TCollectionProxy.cxx         |  273 ++++++
 cont/src/TEmulatedCollectionProxy.cxx |  437 ++++++++++
 cont/src/TEmulatedMapProxy.cxx        |  221 +++++
 cont/src/TGenCollectionProxy.cxx      |  714 ++++++++++++++++
 cont/src/TGenCollectionStreamer.cxx   |  490 +++++++++++
 io/inc/TEmulatedCollectionProxy.h     |  110 +++
 io/inc/TEmulatedMapProxy.h            |   66 ++
 io/inc/TGenCollectionProxy.h          |  311 +++++++
 io/inc/TGenCollectionStreamer.h       |   89 ++
 io/src/TEmulatedCollectionProxy.cxx   |  437 ++++++++++
 io/src/TEmulatedMapProxy.cxx          |  221 +++++
 io/src/TGenCollectionProxy.cxx        |  714 ++++++++++++++++
 io/src/TGenCollectionStreamer.cxx     |  490 +++++++++++
 meta/src/TClass.cxx                   |   27 +-
 meta/src/TGenericClassInfo.cxx        |    3 +-
 test/TBench.cxx                       | 1130 ++++++++++++++++++++++++-
 test/TBench.h                         |  304 ++++++-
 test/bench.cxx                        |  594 ++++++++++++-
 test/benchLinkDef.h                   |   22 +-
 tree/src/TBranchElement.cxx           |   75 +-
 tree/src/TTree.cxx                    |    7 +-
 utils/src/RStl.cxx                    |    6 +-
 utils/src/rootcint.cxx                |   74 +-
 31 files changed, 7776 insertions(+), 127 deletions(-)
 create mode 100644 cont/inc/TCollectionProxy.h
 create mode 100644 cont/inc/TEmulatedCollectionProxy.h
 create mode 100644 cont/inc/TEmulatedMapProxy.h
 create mode 100644 cont/inc/TGenCollectionProxy.h
 create mode 100644 cont/inc/TGenCollectionStreamer.h
 create mode 100644 cont/src/TCollectionProxy.cxx
 create mode 100644 cont/src/TEmulatedCollectionProxy.cxx
 create mode 100644 cont/src/TEmulatedMapProxy.cxx
 create mode 100644 cont/src/TGenCollectionProxy.cxx
 create mode 100644 cont/src/TGenCollectionStreamer.cxx
 create mode 100644 io/inc/TEmulatedCollectionProxy.h
 create mode 100644 io/inc/TEmulatedMapProxy.h
 create mode 100644 io/inc/TGenCollectionProxy.h
 create mode 100644 io/inc/TGenCollectionStreamer.h
 create mode 100644 io/src/TEmulatedCollectionProxy.cxx
 create mode 100644 io/src/TEmulatedMapProxy.cxx
 create mode 100644 io/src/TGenCollectionProxy.cxx
 create mode 100644 io/src/TGenCollectionStreamer.cxx

diff --git a/cont/inc/TCollectionProxy.h b/cont/inc/TCollectionProxy.h
new file mode 100644
index 00000000000..e4a597af062
--- /dev/null
+++ b/cont/inc/TCollectionProxy.h
@@ -0,0 +1,486 @@
+// @(#)root/cont:$Name:  $:$Id: TCollectionProxy.h,v 1.15 2004/10/13 15:30:22 rdm Exp $
+// Author: Markus Frank  28/10/04
+
+/*************************************************************************
+ * Copyright (C) 1995-2004, Rene Brun and Fons Rademakers.               *
+ * All rights reserved.                                                  *
+ *                                                                       *
+ * For the licensing terms see $ROOTSYS/LICENSE.                         *
+ * For the list of contributors see $ROOTSYS/README/CREDITS.             *
+ *************************************************************************/
+#ifndef ROOT_TCollectionProxy
+#define ROOT_TCollectionProxy
+
+//////////////////////////////////////////////////////////////////////////
+//                                                                      //
+//  Small helper to save proxy environment in the event of
+//  recursive calls.
+//
+//////////////////////////////////////////////////////////////////////////
+
+#ifndef __CINT__
+#include <typeinfo>
+
+// Forward declarations
+class TBuffer;
+class TClassStreamer;
+class TMemberStreamer;
+class TVirtualCollectionProxy;
+
+namespace ROOT {
+  /** @class TCollectionProxy::Environ TCollectionProxy.h TCollectionProxy.h 
+    *
+    * Small helper to save proxy environment in the event of
+    * recursive calls.
+    *
+    * @author  M.Frank
+    * @version 1.0
+    * @date    10/10/2004
+    */
+  template <class T> struct Environ  {
+    typedef T           Iter_t;
+    char                buff[64];
+    size_t              idx;
+    size_t              size;
+    void*               object;
+    void*               start;
+    void*               temp;
+    bool                delete_temp;
+    int                 refCount;
+    T& iter() { return *(T*)buff; }
+  };
+}
+
+/** @class TCollectionProxy TCollectionProxy.h cont/TCollectionProxy.h
+  *
+  * TCollectionProxy
+  * Interface to collection proxy and streamer generator.
+  *
+  * Proxy around an arbitrary container, which implements basic 
+  * functionality and iteration. The purpose of this implementation 
+  * is to shield any generated dictionary implementation from the
+  * underlying streamer/proxy implementation and only expose
+  * the creation fucntions.
+  *
+  * In particular this is used to implement splitting and abstract
+  * element access of any container. Access to compiled code is necessary
+  * to implement the abstract iteration sequence and functionality like
+  * size(), clear(), resize(). resize() may be a void operation.
+  *
+  * @author  M.Frank
+  * @version 1.0
+  */
+class TCollectionProxy  {
+public:
+
+  typedef TVirtualCollectionProxy Proxy_t;
+#ifdef R__HPUX
+  typedef const type_info&      Info_t;
+#else
+  typedef const std::type_info& Info_t;
+#endif
+  template <class T> struct Address {
+    static void* address(T ref) {
+      return (void*)&ref;
+    }
+  };
+
+  /** @class TCollectionProxy::fType TCollectionProxy.h TCollectionProxy.h 
+    *
+    * Small helper to encapsulate basic data accesses for 
+    * all STL continers.
+    *
+    * @author  M.Frank
+    * @version 1.0
+    * @date    10/10/2004
+    */
+  template <class T> struct Type : public Address<typename T::const_reference> {
+    typedef T                      Cont_t;
+    typedef typename T::iterator   Iter_t;
+    typedef typename T::value_type Value_t;
+    typedef ROOT::Environ<Iter_t>  Env_t;
+    typedef Env_t                 *PEnv_t;
+    typedef Cont_t                *PCont_t;
+    typedef Value_t               *PValue_t;
+
+    static inline PCont_t object(void* ptr)   {
+      return PCont_t(PEnv_t(ptr)->object);
+    }
+    static void* size(void* env)  {
+      PEnv_t  e = PEnv_t(env);
+      e->size   = PCont_t(e->object)->size();
+      return &e->size;
+    }
+    static void* clear(void* env)  {
+      object(env)->clear();
+      return 0;
+    }
+    static void* first(void* env)  {
+      PEnv_t  e = PEnv_t(env);
+      PCont_t c = PCont_t(e->object);
+      // Assume iterators do not need destruction
+      ::new(e->buff) Iter_t(c->begin()); 
+      e->size  = c->size();
+      if ( 0 == e->size ) return e->start = 0;
+#ifdef R__KCC
+      typename T::reference ref = *(e->iter());
+#else
+      typename T::const_reference ref = *(e->iter());
+#endif
+      return e->start = address(ref);
+    }
+    static void* next(void* env)  {
+      PEnv_t  e = PEnv_t(env);
+      PCont_t c = PCont_t(e->object);
+      for (; e->idx > 0 && e->iter() != c->end(); ++(e->iter()), --e->idx );
+      // TODO: Need to find something for going backwards....
+      if ( e->iter() == c->end() ) return 0;
+#ifdef R__KCC
+      typename T::reference ref = *(e->iter());
+#else
+      typename T::const_reference ref = *(e->iter());
+#endif
+      return address(ref);
+    }
+    static void* construct(void* env)  {
+      PEnv_t  e = PEnv_t(env);
+      char*   p = (char*)e->start;
+      for (size_t i=0; i<e->size; ++i, p+=sizeof(Value_t))  
+        new(p) Value_t();
+      return 0;
+    }
+    static void* collect(void* env)  {
+      PEnv_t   e = PEnv_t(env);
+      PCont_t  c = PCont_t(e->object);
+      PValue_t m = PValue_t(e->start);
+      for (Iter_t i=c->begin(); i != c->end(); ++i, ++m )
+        ::new(m) Value_t(*i);
+      return 0;
+    }
+    static void* destruct(void* env)  {
+      PEnv_t  e = PEnv_t(env);
+      PValue_t m = PValue_t(e->start);
+      for (size_t i=0; i < e->size; ++i, ++m )
+        m->~Value_t();
+      return 0;
+    }
+  };
+
+  /** @class TCollectionProxy::Map TCollectionProxy.h TCollectionProxy.h 
+    *
+    * Small helper to encapsulate all necessary data accesses for 
+    * containers like vector, list, deque
+    *
+    * @author  M.Frank
+    * @version 1.0
+    * @date    10/10/2004
+    */
+  template <class T> struct Pushback : public Type<T> {
+    typedef T                      Cont_t;
+    typedef typename T::iterator   Iter_t;
+    typedef typename T::value_type Value_t;
+    typedef ROOT::Environ<Iter_t>  Env_t;
+    typedef Env_t                 *PEnv_t;
+    typedef Cont_t                *PCont_t;
+    typedef Value_t               *PValue_t;
+    static void* resize(void* env)  {
+      PEnv_t  e = PEnv_t(env);
+      PCont_t c = PCont_t(e->object);
+      c->resize(e->size);
+      e->idx = 0;
+      return e->start = address(*c->begin());
+    }
+    static void* feed(void* env)  {
+      PEnv_t   e = PEnv_t(env);
+      PCont_t  c = PCont_t(e->object);
+      PValue_t m = PValue_t(e->start);
+      for (size_t i=0; i<e->size; ++i, ++m)
+        c->push_back(*m);
+      return 0;
+    }
+    static int value_offset()  {
+      return 0;
+    }
+  };
+
+  /** @class TCollectionProxy::Map TCollectionProxy.h TCollectionProxy.h 
+    *
+    * Small helper to encapsulate all necessary data accesses for 
+    * containers like set, multiset etc.
+    *
+    * @author  M.Frank
+    * @version 1.0
+    * @date    10/10/2004
+    */
+  template <class T> struct Insert : public Type<T> {
+    typedef T                      Cont_t;
+    typedef typename T::iterator   Iter_t;
+    typedef typename T::value_type Value_t;
+    typedef ROOT::Environ<Iter_t>  Env_t;
+    typedef Env_t                 *PEnv_t;
+    typedef Cont_t                *PCont_t;
+    typedef Value_t               *PValue_t;
+    static void* feed(void* env)  {
+      PEnv_t   e = PEnv_t(env);
+      PCont_t  c = PCont_t(e->object);
+      PValue_t m = PValue_t(e->start);
+      for (size_t i=0; i<e->size; ++i, ++m)
+        c->insert(*m);
+      return 0;
+    }
+    static void* resize(void* /* env */ )  {
+      return 0;
+    }
+    static int value_offset()  {
+      return 0;
+    }
+  };
+
+  /** @class TCollectionProxy::Map TCollectionProxy.h TCollectionProxy.h 
+    *
+    * Small helper to encapsulate all necessary data accesses for 
+    * containers like set, multiset etc.
+    *
+    * @author  M.Frank
+    * @version 1.0
+    * @date    10/10/2004
+    */
+  template <class T> struct MapInsert : public Type<T> {
+    typedef T                      Cont_t;
+    typedef typename T::iterator   Iter_t;
+    typedef typename T::value_type Value_t;
+    typedef ROOT::Environ<Iter_t>  Env_t;
+    typedef Env_t                 *PEnv_t;
+    typedef Cont_t                *PCont_t;
+    typedef Value_t               *PValue_t;
+    static void* feed(void* env)  {
+      PEnv_t   e = PEnv_t(env);
+      PCont_t  c = PCont_t(e->object);
+      PValue_t m = PValue_t(e->start);
+      for (size_t i=0; i<e->size; ++i, ++m)
+        c->insert(*m);
+      return 0;
+    }
+    static void* resize(void* /* env */ )  {
+      return 0;
+    }
+    static int value_offset()  {
+      return ((char*)&((PValue_t(0x1000))->second)) - ((char*)PValue_t(0x1000));
+    }
+  };
+
+  /// Generate emulated collection proxy for a given class
+  static Proxy_t* genEmulatedProxy(const char* class_name);
+
+  /// Generate emulated class streamer for a given collection class
+  static TClassStreamer* genEmulatedClassStreamer(const char* class_name);
+
+  /// Generate emulated member streamer for a given collection class
+  static TMemberStreamer* genEmulatedMemberStreamer(const char* class_name);
+
+  /// Generate proxy from static functions
+  static Proxy_t* genExplicitProxy( Info_t info,
+                                    size_t iter_size,
+                                    size_t value_diff,
+                                    int    value_offset,
+                                    void*  (*size_func)(void*),
+                                    void*  (*resize_func)(void*),
+                                    void*  (*clear_func)(void*),
+                                    void*  (*first_func)(void*),
+                                    void*  (*next_func)(void*),
+                                    void*  (*construct_func)(void*),
+                                    void*  (*destruct_func)(void*),
+                                    void*  (*feed_func)(void*),
+                                    void*  (*collect_func)(void*)
+                                    );
+
+  /// Generate proxy from template
+  template <class T> static Proxy_t* genProxy()  {
+    return genExplicitProxy(typeid(typename T::Cont_t),
+                            sizeof(typename T::Iter_t),
+                            sizeof(typename T::Value_t),
+                            T::value_offset(),
+                            T::size,
+                            T::resize,
+                            T::clear,
+                            T::first,
+                            T::next,
+                            T::construct,
+                            T::destruct,
+                            T::feed,
+                            T::collect);
+  }
+
+  /// Generate streamer from static functions
+  static Proxy_t* 
+    genExplicitStreamer(  Info_t  info,
+                          size_t  iter_size,
+                          size_t  value_diff,
+                          int     value_offset,
+                          void*  (*size_func)(void*),
+                          void*  (*resize_func)(void*),
+                          void*  (*clear_func)(void*),
+                          void*  (*first_func)(void*),
+                          void*  (*next_func)(void*),
+                          void*  (*construct_func)(void*),
+                          void*  (*destruct_func)(void*),
+                          void*  (*feed_func)(void*),
+                          void*  (*collect_func)(void*)
+                          );
+
+  /// Generate class streamer from static functions
+  static TClassStreamer* 
+    genExplicitClassStreamer( Info_t  info,
+                              size_t  iter_size,
+                              size_t  value_diff,
+                              int     value_offset,
+                              void*  (*size_func)(void*),
+                              void*  (*resize_func)(void*),
+                              void*  (*clear_func)(void*),
+                              void*  (*first_func)(void*),
+                              void*  (*next_func)(void*),
+                              void*  (*construct_func)(void*),
+                              void*  (*destruct_func)(void*),
+                              void*  (*feed_func)(void*),
+                              void*  (*collect_func)(void*)
+                              );
+
+  /// Generate class streamer from template
+  template <class T> static TClassStreamer* genClassStreamer()  {
+    return genExplicitClassStreamer(typeid(typename T::Cont_t),
+                                    sizeof(typename T::Iter_t),
+                                    sizeof(typename T::Value_t),
+                                    T::value_offset(),
+                                    T::size,
+                                    T::resize,
+                                    T::clear,
+                                    T::first,
+                                    T::next,
+                                    T::construct,
+                                    T::destruct,
+                                    T::feed,
+                                    T::collect);
+  }
+
+  /// Generate member streamer from static functions
+  static TMemberStreamer* 
+    genExplicitMemberStreamer(Info_t  info,
+                              size_t  iter_size,
+                              size_t  value_diff,
+                              int     value_offset,
+                              void*  (*size_func)(void*),
+                              void*  (*resize_func)(void*),
+                              void*  (*clear_func)(void*),
+                              void*  (*first_func)(void*),
+                              void*  (*next_func)(void*),
+                              void*  (*construct_func)(void*),
+                              void*  (*destruct_func)(void*),
+                              void*  (*feed_func)(void*),
+                              void*  (*collect_func)(void*)
+                              );
+
+  /// Generate member streamer from template
+  template <class T> static TMemberStreamer* genMemberStreamer()  {
+    return genExplicitMemberStreamer( typeid(typename T::Cont_t),
+                                      sizeof(typename T::Iter_t),
+                                      sizeof(typename T::Value_t),
+                                      T::value_offset(),
+                                      T::size,
+                                      T::resize,
+                                      T::clear,
+                                      T::first,
+                                      T::next,
+                                      T::construct,
+                                      T::destruct,
+                                      T::feed,
+                                      T::collect);
+  }
+};
+
+/** @class TCollectionStreamer TEmulatedCollectionProxy.h cont/TEmulatedCollectionProxy.h
+  *
+  * TEmulatedClassStreamer
+  *
+  * Class streamer object to implement TClassStreamr functionality
+  * for I/O emulation.
+  *
+  * @author  M.Frank
+  * @version 1.0
+  */
+class TCollectionStreamer   {
+protected:
+  TVirtualCollectionProxy* fProxy;   /// Pointer to worker proxy
+
+  /// Issue Error about invalid proxy
+  void InvalidProxyError();
+
+public:
+  /// Initializing constructor
+  TCollectionStreamer();
+  /// Copy constructor
+  TCollectionStreamer(const TCollectionStreamer& c);
+  /// Standard destructor
+  virtual ~TCollectionStreamer();
+  /// Attach worker proxy
+  void AdoptProxy(TVirtualCollectionProxy* proxy);
+  /// Streamer for I/O handling
+  void Streamer(TBuffer &refBuffer, void *pObject, int siz);
+};
+
+#include "TClassStreamer.h"
+
+/** @class TEmulatedClassStreamer TEmulatedCollectionProxy.h cont/TEmulatedCollectionProxy.h
+  *
+  * TEmulatedClassStreamer
+  *
+  * Class streamer object to implement TClassStreamr functionality
+  * for I/O emulation.
+  *
+  * @author  M.Frank
+  * @version 1.0
+  */
+class TCollectionClassStreamer : public TClassStreamer, public TCollectionStreamer {
+public:
+  /// Initializing constructor
+  TCollectionClassStreamer() : TClassStreamer(0)     {                        }
+  /// Copy constructor
+  TCollectionClassStreamer(const TCollectionClassStreamer& c) 
+    : TClassStreamer(c), TCollectionStreamer(c)      {                        }
+  /// Standard destructor
+  virtual ~TCollectionClassStreamer()                {                        }
+  /// Streamer for I/O handling
+  virtual void operator()(TBuffer &buff, void *pObj) { Streamer(buff,pObj,0); }
+};
+
+#include "TMemberStreamer.h"
+
+/** @class TCollectionMemberStreamer TEmulatedCollectionProxy.h cont/TEmulatedCollectionProxy.h
+  *
+  * TCollectionMemberStreamer
+  *
+  * Class streamer object to implement TMemberStreamer functionality
+  * for I/O emulation.
+  *
+  * @author  M.Frank
+  * @version 1.0
+  */
+class TCollectionMemberStreamer : public TMemberStreamer, public TCollectionStreamer {
+public:
+  /// Initializing constructor
+  TCollectionMemberStreamer() : TMemberStreamer(0) { }
+  /// Copy constructor
+  TCollectionMemberStreamer(const TCollectionMemberStreamer& c) 
+    : TMemberStreamer(c), TCollectionStreamer(c)   { }
+  /// Standard destructor
+  virtual ~TCollectionMemberStreamer()             { }
+  /// Streamer for I/O handling
+  virtual void operator()(TBuffer &buff,void *pObj,Int_t siz=0)
+  { Streamer(buff, pObj, siz);                       }
+};
+
+// Need specialization for boolean references due to stupid STL vector<bool>
+template<> inline void* TCollectionProxy::Address<std::vector<bool>::const_reference>::address(std::vector<bool>::const_reference ) {
+  return 0;
+}
+#endif
+#endif
diff --git a/cont/inc/TEmulatedCollectionProxy.h b/cont/inc/TEmulatedCollectionProxy.h
new file mode 100644
index 00000000000..6df63a42a23
--- /dev/null
+++ b/cont/inc/TEmulatedCollectionProxy.h
@@ -0,0 +1,110 @@
+// @(#)root/cont:$Name:  $:$Id: TEmulatedCollectionProxy.h,v 1.15 2004/10/13 15:30:22 rdm Exp $
+// Author: Markus Frank  28/10/04
+
+/*************************************************************************
+ * Copyright (C) 1995-2004, Rene Brun and Fons Rademakers.               *
+ * All rights reserved.                                                  *
+ *                                                                       *
+ * For the licensing terms see $ROOTSYS/LICENSE.                         *
+ * For the list of contributors see $ROOTSYS/README/CREDITS.             *
+ *************************************************************************/
+#ifndef ROOT_TEmulatedCollectionProxy
+#define ROOT_TEmulatedCollectionProxy
+
+#ifndef __CINT__
+
+//////////////////////////////////////////////////////////////////////////
+//                                                                      //
+// TEmulatedCollectionProxy
+//
+// Streamer around an arbitrary STL like container, which implements basic 
+// container functionality.
+//
+// Note:
+// Although this class contains all the setup necessary to deal
+// with maps, the map-like functionality is NOT supported.
+// For optimization reasons this functionality is put into
+// the class TEmulatedMapProxy.
+//
+//////////////////////////////////////////////////////////////////////////
+
+#include "TGenCollectionProxy.h"
+
+class TEmulatedCollectionProxy : public TGenCollectionProxy  {
+
+  /// Friend declaration
+  friend class TCollectionProxy;
+
+public:
+  /// Container type definition
+  typedef std::vector<char>  Cont_t;
+  /// Pointer to container type
+  typedef Cont_t            *PCont_t;
+protected:
+
+  /// Some hack to avoid const-ness
+  virtual TGenCollectionProxy* InitializeEx();
+
+  /// Object input streamer
+  void ReadItems(int nElements, TBuffer &b);
+
+  /// Object output streamer
+  void WriteItems(int nElements, TBuffer &b);
+
+  /// Shrink the container
+  void Shrink(UInt_t nCurr, UInt_t left, Bool_t force);
+
+  /// Expand the container
+  void Expand(UInt_t nCurr, UInt_t left);
+
+public:
+  /// Virtual copy constructor
+  virtual TVirtualCollectionProxy* Generate() const;
+
+  /// Copy constructor
+  TEmulatedCollectionProxy(const TEmulatedCollectionProxy& copy);
+
+  /// Initializing constructor
+  TEmulatedCollectionProxy(const char* cl_name);
+
+  /// Standard destructor
+  virtual ~TEmulatedCollectionProxy();
+
+  /// Virtual constructor
+  virtual void* New()   const             {  return new Cont_t;         }
+
+  /// Virtual in-place constructor
+  virtual void* New(void* memory)   const {  return new(memory) Cont_t; }
+
+  /// TVirtualCollectionProxy overload: Return the sizeof the collection object. 
+  virtual UInt_t Sizeof() const           {  return sizeof(Cont_t);     }
+
+  /// Return the address of the value at index 'idx'
+  virtual void *At(UInt_t idx);
+
+  /// Clear the container
+  virtual void Clear(const char *opt = "");
+
+  /// Resize the container
+  virtual void Resize(UInt_t n, Bool_t force_delete);
+
+  /// Return the current size of the container
+  virtual UInt_t Size() const;                        
+
+  /// Block allocation of containees
+  virtual void* Allocate(UInt_t n, Bool_t forceDelete);
+
+  /// Block commit of containees
+  virtual void Commit(void* env);
+
+  /// Streamer for I/O handling
+  virtual void Streamer(TBuffer &refBuffer);
+
+  /// Streamer I/O overload
+  virtual void Streamer(TBuffer &buff, void *pObj, int siz) {
+    TGenCollectionProxy::Streamer(buff,pObj,siz);
+  }
+};
+
+#endif
+#endif
diff --git a/cont/inc/TEmulatedMapProxy.h b/cont/inc/TEmulatedMapProxy.h
new file mode 100644
index 00000000000..43d266525c3
--- /dev/null
+++ b/cont/inc/TEmulatedMapProxy.h
@@ -0,0 +1,66 @@
+// @(#)root/cont:$Name:  $:$Id: TEmulatedMapProxy.h,v 1.15 2004/10/13 15:30:22 rdm Exp $
+// Author: Markus Frank  28/10/04
+
+/*************************************************************************
+ * Copyright (C) 1995-2004, Rene Brun and Fons Rademakers.               *
+ * All rights reserved.                                                  *
+ *                                                                       *
+ * For the licensing terms see $ROOTSYS/LICENSE.                         *
+ * For the list of contributors see $ROOTSYS/README/CREDITS.             *
+ *************************************************************************/
+#ifndef ROOT_TEmulatedMapProxy
+#define ROOT_TEmulatedMapProxy
+#define ROOT_TGenCollectionStreamer
+
+#ifndef __CINT__
+
+//////////////////////////////////////////////////////////////////////////
+//                                                                      //
+// TEmulatedMapProxy
+//
+// Streamer around an arbitrary STL like container, which implements basic 
+// container functionality.
+//
+//////////////////////////////////////////////////////////////////////////
+
+#include "TEmulatedCollectionProxy.h"
+
+class TEmulatedMapProxy : public TEmulatedCollectionProxy  {
+
+protected:
+  /// Map input streamer
+  void ReadMap(int nElements, TBuffer &b);
+
+  /// Map output streamer
+  void WriteMap(int nElements, TBuffer &b);
+
+public:
+  /// Virtual copy constructor
+  virtual TVirtualCollectionProxy* Generate() const;
+
+  /// Copy constructor
+  TEmulatedMapProxy(const TEmulatedMapProxy& copy);
+
+  /// Initializing constructor
+  TEmulatedMapProxy(const char* cl_name);
+
+  /// Standard destructor
+  virtual ~TEmulatedMapProxy();
+
+  /// Return the address of the value at index 'idx'
+  virtual void *At(UInt_t idx);
+
+  /// Return the current size of the container
+  virtual UInt_t Size() const;                        
+
+  /// Streamer for I/O handling
+  virtual void Streamer(TBuffer &refBuffer);
+
+  /// Streamer I/O overload
+  virtual void Streamer(TBuffer &buff, void *pObj, int siz) {
+    TEmulatedCollectionProxy::Streamer(buff,pObj,siz);
+  }
+};
+
+#endif
+#endif
diff --git a/cont/inc/TEmulatedVectorProxy.h b/cont/inc/TEmulatedVectorProxy.h
index dc9a0318ea8..e7e791b21c9 100644
--- a/cont/inc/TEmulatedVectorProxy.h
+++ b/cont/inc/TEmulatedVectorProxy.h
@@ -1,4 +1,4 @@
-// @(#)root/cont:$Name:  $:$Id: TEmulatedVectorProxy.h,v 1.6 2004/10/07 17:08:53 brun Exp $
+// @(#)root/cont:$Name:  $:$Id: TEmulatedVectorProxy.h,v 1.7 2004/10/08 15:19:37 brun Exp $
 // Author: Philippe Canal 20/08/2003
 
 /*************************************************************************
@@ -9,8 +9,8 @@
  * For the list of contributors see $ROOTSYS/README/CREDITS.             *
  *************************************************************************/
 
-#ifndef Root_TEmulatedVectorProxy_h
-#define Root_TEmulatedVectorProxy_h
+#ifndef Root_TEmulatedVectorProxy
+#define Root_TEmulatedVectorProxy
 
 //////////////////////////////////////////////////////////////////////////
 //                                                                      //
@@ -72,9 +72,11 @@ public:
    void    Clear(const char *opt = "");          // Clear the container
    void    Resize(UInt_t n, Bool_t forceDelete); // Resize the container
    UInt_t  Size() const;                         // Return the current size of the container
+   virtual void* Allocate(UInt_t n, Bool_t forceDelete)  { Resize(n,forceDelete); return 0; }
+   virtual void  Commit(void*) {}
 
    void    Streamer(TBuffer &b);
    virtual void operator()(TBuffer &b, void *objp) { PushProxy(objp); Streamer(b); PopProxy(); }
 };
 
-#endif /* Root_TEmulatedVectorProxy_h */
+#endif
diff --git a/cont/inc/TGenCollectionProxy.h b/cont/inc/TGenCollectionProxy.h
new file mode 100644
index 00000000000..595b0ad5282
--- /dev/null
+++ b/cont/inc/TGenCollectionProxy.h
@@ -0,0 +1,311 @@
+// @(#)root/cont:$Name:  $:$Id: TGenCollectionProxy.h,v 1.15 2004/10/13 15:30:22 rdm Exp $
+// Author: Markus Frank  28/10/04
+
+/*************************************************************************
+ * Copyright (C) 1995-2004, Rene Brun and Fons Rademakers.               *
+ * All rights reserved.                                                  *
+ *                                                                       *
+ * For the licensing terms see $ROOTSYS/LICENSE.                         *
+ * For the list of contributors see $ROOTSYS/README/CREDITS.             *
+ *************************************************************************/
+#ifndef ROOT_TGenCollectionProxy
+#define ROOT_TGenCollectionProxy
+#ifndef __CINT__
+
+//////////////////////////////////////////////////////////////////////////
+//                                                                      //
+// TGenCollectionProxy
+//
+// Proxy around an arbitrary container, which implements basic 
+// functionality and iteration.
+//
+// In particular this is used to implement splitting and abstract
+// element access of any container. Access to compiled code is necessary
+// to implement the abstract iteration sequence and functionality like
+// size(), clear(), resize(). resize() may be a void operation.
+//
+//////////////////////////////////////////////////////////////////////////
+
+#include "TVirtualCollectionProxy.h"
+#include "TCollectionProxy.h"
+#include <typeinfo>
+#include <string>
+
+class TGenCollectionProxy 
+  : public TVirtualCollectionProxy,
+    public TCollectionProxy
+{
+
+  /// Friend declaration
+  friend class TCollectionProxy;
+
+public:
+
+  enum {
+    // Those 'bits' are used in conjunction with CINT's bit to store the 'type'
+    // info into one int
+    R__BIT_ISSTRING   = 0x20000000,  // We can optimized a value operation when the content are strings
+    R__BIT_ISTSTRING  = 0x40000000,
+    kBOOL_t = 21
+  };
+
+
+  /** @class TGenCollectionProxy::Value TGenCollectionProxy.h TGenCollectionProxy.h 
+    *
+    * Small helper to describe the Value_type or the key_type
+    * of an STL container.
+    *
+    * @author  M.Frank
+    * @version 1.0
+    * @date    10/10/2004
+    */
+  struct Value  {
+    ROOT::NewFunc_t fCtor;      // Method cache for containee constructor
+    ROOT::DesFunc_t fDtor;      // Method cache for containee destructor
+    ROOT::DelFunc_t fDelete;    // Method cache for containee delete
+    unsigned int    fCase;      // type of data of Value_type
+    TClass*         fType;      // TClass of Value_type in collection
+    EDataType       fKind;      // kind of ROOT-fundamental type 
+    size_t          fSize;      // fSize of the contained object
+    Value(const Value& inside);
+    Value(const std::string& info);
+  };
+
+  /**@class StreamHelper
+    *
+    * Helper class to facilitate I/O
+    *
+    * @author  M.Frank
+    * @version 1.0
+    * @date    10/10/2004
+    */
+  union StreamHelper  {
+    bool         boolean;
+    Char_t       s_char;
+    Short_t      s_short;
+    Int_t        s_int;
+    Long_t       s_long;
+    Long64_t     s_longlong;
+    Float_t      flt;
+    Double_t     dbl;
+    UChar_t      u_char;
+    UShort_t     u_short;
+    UInt_t       u_int;
+    ULong_t      u_long;
+    ULong64_t    u_longlong;
+    void*        p_void;
+    void**       pp_void;
+    char*        kchar;
+    TString*     tstr;
+    void* ptr()  {
+      return *(&this->p_void);
+    }
+    std::string* str()  {
+      return (std::string*)this;
+    }
+    const char* c_str()  {
+      return ((std::string*)this)->c_str();
+    }
+    const char* c_pstr()  {
+      return (*(std::string**)this)->c_str();
+    }
+    void set(void* p)  {
+      *(&this->p_void) = p;
+    }
+    void read_std_string(TBuffer& b) {
+      TString s;
+      s.Streamer(b);
+      ((std::string*)this)->assign(s.Data());
+    }
+    void* read_tstring(TBuffer& b)  {
+      *((TString*)this) = "";
+      ((TString*)this)->Streamer(b);
+      return this;
+    }
+    void read_std_string_pointer(TBuffer& b) {
+      TString s;
+      std::string* str = (std::string*) (ptr() ? ptr() : new std::string());
+      s.Streamer(b);
+      *str = s;
+      set(str);
+    }
+    void write_std_string_pointer(TBuffer& b)  {
+      const char* c = (const char*)(ptr() ? (*(std::string**)this)->c_str() : "");
+      TString(c).Streamer(b);
+    }
+    void read_any_object(Value* v, TBuffer& b)  {
+      void* p = ptr();
+      if ( p )  {
+        if ( v->fDelete )  {    // Compiled content: call Destructor
+          (*v->fDelete)(p);
+        }
+        else if ( v->fType )  { // Emulated content: call TClass::Delete
+          v->fType->Destructor(p);
+        }
+        else if ( v->fDtor )  {
+          (*v->fDtor)(p);
+          ::operator delete(p);
+        }
+        else  {
+          ::operator delete(p);
+        }
+      }
+      set( b.ReadObjectAny(v->fType) );
+    }
+
+    void read_tstring_pointer(bool vsn3, TBuffer& b)  {
+      TString* s = (TString*)ptr();
+      if ( vsn3 )  {
+        if ( !s ) s = new TString();
+        s->Replace(0, s->Length(), 0, 0);
+        s->Streamer(b);
+        set(s);
+        return;
+      }
+      if ( s ) delete s;
+      set( b.ReadObjectAny(TString::Class()) );
+    }
+    void write_tstring_pointer(TBuffer& b)  {
+      b.WriteObjectAny(ptr(), TString::Class());
+    }
+  };
+
+  /** @class TGenCollectionProxy::Method TGenCollectionProxy.h TGenCollectionProxy.h 
+    *
+    * Small helper to execute (compiler) generated function for the
+    * access to STL or other containers.
+    *
+    * @author  M.Frank
+    * @version 1.0
+    * @date    10/10/2004
+    */
+  struct Method  {
+    typedef void* (*Call_t)(void*);
+    Call_t call;
+    Method() : call(0)                       {      }
+    Method(Call_t c) : call(c)               {      }
+    Method(const Method& m) : call(m.call)   {      }
+    void* invoke(void* obj) const { return (*call)(obj); }
+  };
+
+protected:
+  typedef ROOT::Environ<char[64]> Env_t;
+  typedef std::vector<Env_t*>     Proxies_t;
+
+  std::string   fName;      // Name of the class being proxied.    
+  bool          fPointers;  // Flag to indicate if containee has pointers (key or value)
+  Method        fClear;     // Method cache for container accessors: clear container
+  Method        fSize;      // Container accessors: size of container
+  Method        fResize;    // Container accessors: resize container
+  Method        fFirst;     // Container accessors: generic iteration: first
+  Method        fNext;      // Container accessors: generic iteration: next
+  Method        fConstruct; // Container accessors: block construct
+  Method        fDestruct;  // Container accessors: block destruct
+  Method        fFeed;      // Container accessors: block feed
+  Method        fCollect;   // Method to collect objects from container
+  Value*        fValue;     // Descriptor of the container value type
+  Value*        fVal;       // Descriptor of the Value_type
+  Value*        fKey;       // Descriptor of the key_type
+  Env_t*        fEnv;       // Address of the currently proxied object
+  int           fValOffset; // Offset from key to value (in maps)
+  int           fValDiff;   // Offset between two consecutive value_types (memory layout).
+  Proxies_t     fProxyList; // Stack of recursive proxies 
+  int           fSTL_type;  // STL container type
+  Info_t        fTypeinfo;  // Type information
+
+  /// Late initialization of collection proxy
+  virtual TGenCollectionProxy* Initialize() const;
+  /// Some hack to avoid const-ness
+  virtual TGenCollectionProxy* InitializeEx();
+  /// Call to delete/destruct individual contained item
+  virtual void DeleteItem(bool force, void* ptr) const;
+  /// Allow to check function pointers
+  void CheckFunctions()  const;
+
+public:
+
+  /// Virtual copy constructor
+  virtual TVirtualCollectionProxy* Generate() const;
+
+  /// Copy constructor
+  TGenCollectionProxy(const TGenCollectionProxy& copy);
+
+  /// Initializing constructor
+  TGenCollectionProxy(Info_t typ, size_t iter_size);
+
+  /// Standard destructor
+  virtual ~TGenCollectionProxy();
+
+  /// Return a pointer to the TClass representing the container
+  virtual TClass *GetCollectionClass();
+
+  /// Return the sizeof the collection object. 
+  virtual UInt_t Sizeof() const;
+
+  /// Push new proxy environment
+  virtual void PushProxy(void *objstart);
+
+  /// Pop old proxy environment
+  virtual void PopProxy();
+
+  /// Return true if the content is of type 'pointer to'
+  virtual Bool_t HasPointers() const;
+
+  /// Return a pointer to the TClass representing the content.
+  virtual TClass *GetValueClass();
+
+  /// Set pointer to the TClass representing the content.
+  virtual void SetValueClass(TClass *newcl);
+
+  /// If the content is a simple numerical value, return its type (see TDataType)
+  virtual EDataType GetType();
+
+  /// Return the address of the value at index 'idx'
+  virtual void *At(UInt_t idx);
+
+  /// Clear the container
+  virtual void Clear(const char *opt = "");
+
+  /// Resize the container
+  virtual void Resize(UInt_t n, Bool_t force_delete);
+
+  /// Return the current size of the container
+  virtual UInt_t Size() const;                        
+
+  /// Block allocation of containees
+  virtual void* Allocate(UInt_t n, Bool_t forceDelete);
+
+  /// Block commit of containees
+  virtual void Commit(void* env);
+
+  /// Streamer function
+  virtual void Streamer(TBuffer &refBuffer);
+
+  /// Streamer I/O overload
+  virtual void Streamer(TBuffer &refBuffer, void *pObject, int siz);
+
+  /// TClassStreamer I/O overload
+  virtual void operator()(TBuffer &refBuffer, void *pObject);
+};
+
+template <typename T> 
+struct AnyCollectionProxy : public TGenCollectionProxy  {
+  AnyCollectionProxy()
+  : TGenCollectionProxy(typeid(T::Cont_t),sizeof(T::Iter_t))
+  {
+    fValDiff        = sizeof(T::Value_t);
+    fValOffset      = T::value_offset();
+    fSize.call      = T::size;
+    fResize.call    = T::resize;
+    fNext.call      = T::next;
+    fFirst.call     = T::first;
+    fClear.call     = T::clear;
+    fConstruct.call = T::construct;
+    fDestruct.call  = T::destruct;
+    fFeed.call      = T::feed;
+    CheckFunctions();
+  }
+  virtual ~AnyCollectionProxy() {  }
+};
+#endif
+#endif
diff --git a/cont/inc/TGenCollectionStreamer.h b/cont/inc/TGenCollectionStreamer.h
new file mode 100644
index 00000000000..862ffaca353
--- /dev/null
+++ b/cont/inc/TGenCollectionStreamer.h
@@ -0,0 +1,89 @@
+// @(#)root/cont:$Name:  $:$Id: TGenCollectionStreamer.h,v 1.15 2004/10/13 15:30:22 rdm Exp $
+// Author: Markus Frank  28/10/04
+
+/*************************************************************************
+ * Copyright (C) 1995-2004, Rene Brun and Fons Rademakers.               *
+ * All rights reserved.                                                  *
+ *                                                                       *
+ * For the licensing terms see $ROOTSYS/LICENSE.                         *
+ * For the list of contributors see $ROOTSYS/README/CREDITS.             *
+ *************************************************************************/
+#ifndef ROOT_TGenCollectionStreamer
+#define ROOT_TGenCollectionStreamer
+
+#ifndef __CINT__
+
+//////////////////////////////////////////////////////////////////////////
+//                                                                      //
+// TGenCollectionStreamer
+//
+// Streamer around an arbitrary STL like container, which implements basic 
+// container functionality.
+//
+//////////////////////////////////////////////////////////////////////////
+
+#include "TGenCollectionProxy.h"
+
+class TGenCollectionStreamer : public TGenCollectionProxy  {
+
+protected:
+  /// Stream I/O: Map input streamer
+  void ReadMap(int nElements, TBuffer &b);
+  /// Stream I/O: Object input streamer
+  void ReadObjects(int nElements, TBuffer &b);
+  /// Stream I/O: Primitive input streamer
+  void ReadPrimitives(int nElements, TBuffer &b);
+  /// Stream I/O: Map output streamer
+  void WriteMap(int nElements, TBuffer &b);
+  /// Stream I/O: Object output streamer
+  void WriteObjects(int nElements, TBuffer &b);
+  /// Stream I/O: Primitive output streamer
+  void WritePrimitives(int nElements, TBuffer &b);
+
+public:
+  /// Virtual copy constructor
+  virtual TVirtualCollectionProxy* Generate() const;
+
+  /// Copy constructor
+  TGenCollectionStreamer(const TGenCollectionStreamer& copy);
+
+  /// Initializing constructor
+  TGenCollectionStreamer(Info_t typ, size_t iter_size);
+
+  /// Standard destructor
+  virtual ~TGenCollectionStreamer();
+
+  /// Streamer I/O overload
+  virtual void Streamer(TBuffer &refBuffer);
+
+  /// Streamer I/O overload
+  virtual void Streamer(TBuffer &buff, void *pObj, int siz)  {
+    TGenCollectionProxy::Streamer(buff, pObj, siz);
+  }
+};
+
+template <typename T> 
+struct AnyCollectionStreamer : public TGenCollectionStreamer  {
+  AnyCollectionStreamer()
+  : TGenCollectionStreamer(typeid(T::Cont_t),sizeof(T::Iter_t))  {
+    fValDiff        = sizeof(T::Value_t);
+    fValOffset      = T::value_offset();
+    fSize.call      = T::size;
+    fFirst.call     = T::first;
+    fNext.call      = T::next;
+    fClear.call     = T::clear;
+    fResize.call    = T::resize;
+    fCollect.call   = T::collect;
+    fConstruct.call = T::construct;
+    fDestruct.call  = T::destruct;
+    fFeed.call      = T::feed;
+    CheckFunctions();
+  }
+  virtual ~AnyCollectionStreamer() {  }
+};
+
+// Forward declaration in the event of later seperation
+typedef TGenCollectionStreamer TGenMapStreamer;
+
+#endif
+#endif
diff --git a/cont/inc/TVectorProxy.h b/cont/inc/TVectorProxy.h
index 8f58b886fbf..40c89412a55 100644
--- a/cont/inc/TVectorProxy.h
+++ b/cont/inc/TVectorProxy.h
@@ -1,4 +1,4 @@
-// @(#)root/cont:$Name:  $:$Id: TVectorProxy.h,v 1.10 2004/10/07 17:08:53 brun Exp $
+// @(#)root/cont:$Name:  $:$Id: TVectorProxy.h,v 1.11 2004/10/08 15:19:37 brun Exp $
 // Author: Philippe Canal 20/08/2003
 
 /*************************************************************************
@@ -230,9 +230,12 @@ namespace ROOT {
       TClass *GetValueClass() { return 0; }      
       Bool_t HasPointers() const { return 0; }      
       void Resize(UInt_t n, Bool_t ) { fProxied->resize(n); }
+      virtual void* Allocate(UInt_t n, Bool_t forceDelete)  { fProxied->resize(n); return 0; }
+      virtual void  Commit(void*) {}
       
       UInt_t  Size() const { return fProxied ? (*fProxied).size() : 0; }
       void    Streamer(TBuffer &b) { GetCollectionClass()->Streamer( fProxied, b ); }
+
    };
 
 
diff --git a/cont/inc/TVirtualCollectionProxy.h b/cont/inc/TVirtualCollectionProxy.h
index 1bcd15cdd0d..b8bbf86d634 100644
--- a/cont/inc/TVirtualCollectionProxy.h
+++ b/cont/inc/TVirtualCollectionProxy.h
@@ -1,4 +1,4 @@
-// @(#)root/cont:$Name:  $:$Id: TVirtualCollectionProxy.h,v 1.5 2004/10/07 17:15:13 brun Exp $
+// @(#)root/cont:$Name:  $:$Id: TVirtualCollectionProxy.h,v 1.6 2004/10/08 15:19:37 brun Exp $
 // Author: Philippe Canal 20/08/2003
 
 /*************************************************************************
@@ -9,8 +9,8 @@
  * For the list of contributors see $ROOTSYS/README/CREDITS.             *
  *************************************************************************/
 
-#ifndef Root_TVirtualCollectionProxy_h
-#define Root_TVirtualCollectionProxy_h
+#ifndef Root_TVirtualCollectionProxy
+#define Root_TVirtualCollectionProxy
 
 //////////////////////////////////////////////////////////////////////////
 //                                                                      //
@@ -69,9 +69,10 @@ public:
    virtual void      Clear(const char *opt = "") = 0;          // Clear the container
    virtual void      Resize(UInt_t n, Bool_t forceDelete) = 0; // Resize the container
    virtual UInt_t    Size() const = 0;                         // Return the current size of the container
-
+   virtual void*     Allocate(UInt_t n, Bool_t forceDelete) = 0;
+   virtual void      Commit(void*) = 0;
    virtual void      Streamer(TBuffer &b) = 0;                 // Stream the proxied container
            char     *operator[](UInt_t idx) const { return (char*)(const_cast<TVirtualCollectionProxy*>(this))->At(idx); }
 };
 
-#endif // Root_TVirtualCollectionProxy_h
+#endif
diff --git a/cont/src/TCollectionProxy.cxx b/cont/src/TCollectionProxy.cxx
new file mode 100644
index 00000000000..a065b3c4963
--- /dev/null
+++ b/cont/src/TCollectionProxy.cxx
@@ -0,0 +1,273 @@
+// @(#)root/cont:$Name:  $:$Id: TCollectionProxy.cxx,v 1.26 2004/10/13 15:30:22 rdm Exp $
+// Author: Markus Frank 28/10/04
+
+/*************************************************************************
+ * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers.               *
+ * All rights reserved.                                                  *
+ *                                                                       *
+ * For the licensing terms see $ROOTSYS/LICENSE.                         *
+ * For the list of contributors see $ROOTSYS/README/CREDITS.             *
+ *************************************************************************/
+
+//////////////////////////////////////////////////////////////////////////
+//                                                                      //
+// TGenCollectionProxy
+//
+// Proxy around an arbitrary container, which implements basic 
+// functionality and iteration. The purpose of this implementation 
+// is to shield any generated dictionary implementation from the
+// underlying streamer/proxy implementation and only expose
+// the creation fucntions.
+//
+// In particular this is used to implement splitting and abstract
+// element access of any container. Access to compiled code is necessary
+// to implement the abstract iteration sequence and functionality like
+// size(), clear(), resize(). resize() may be a void operation.
+//
+//////////////////////////////////////////////////////////////////////////
+
+#include "TError.h"
+#include "TClassEdit.h"
+#include "TCollectionProxy.h"
+#include "TGenCollectionProxy.h"
+#include "TGenCollectionStreamer.h"
+
+#include "TEmulatedMapProxy.h"
+#include "TEmulatedCollectionProxy.h"
+
+static TClassEdit::ESTLType stl_type(const char* class_name)  {
+  if ( class_name )  {
+    int nested = 0;
+    std::vector<std::string> inside;
+    int num = TClassEdit::GetSplit(class_name,inside,nested);
+    if ( num > 1 )  {
+      return (TClassEdit::ESTLType)TClassEdit::STLKind(inside[0].c_str());
+    }
+  }
+  return TClassEdit::kNotSTL;
+}
+
+/// Generate emulated collection proxy for a given class
+TCollectionProxy::Proxy_t* 
+TCollectionProxy::genEmulatedProxy(const char* class_name)  
+{
+  switch ( stl_type(class_name) )  {
+    case TClassEdit::kNotSTL:
+      return 0;
+    case TClassEdit::kMap:
+    case TClassEdit::kMultiMap:
+      return new TEmulatedMapProxy(class_name);
+    default:
+      return new TEmulatedCollectionProxy(class_name);
+  }
+  return 0;
+}
+
+/// Generate emulated class streamer for a given collection class
+TClassStreamer* 
+TCollectionProxy::genEmulatedClassStreamer(const char* class_name)
+{
+  TCollectionClassStreamer* s = new TCollectionClassStreamer();
+  s->AdoptProxy(genEmulatedProxy(class_name));
+  return s;
+}
+
+/// Generate emulated member streamer for a given collection class
+TMemberStreamer* 
+TCollectionProxy::genEmulatedMemberStreamer(const char* class_name)
+{
+  TCollectionMemberStreamer* s = new TCollectionMemberStreamer();
+  s->AdoptProxy(genEmulatedProxy(class_name));
+  return s;
+}
+
+/// Generate proxy from static functions
+TCollectionProxy::Proxy_t* 
+TCollectionProxy::genExplicitProxy( Info_t info,
+                                    size_t iter_size,
+                                    size_t value_diff,
+                                    int    value_offset,
+                                    void*  (*size_func)(void*),
+                                    void*  (*resize_func)(void*),
+                                    void*  (*clear_func)(void*),
+                                    void*  (*first_func)(void*),
+                                    void*  (*next_func)(void*),
+                                    void*  (*construct_func)(void*),
+                                    void*  (*destruct_func)(void*),
+                                    void*  (*feed_func)(void*),
+                                    void*  (*collect_func)(void*)
+                                    )
+{
+  TGenCollectionProxy* ptr = new TGenCollectionProxy(info, iter_size);
+  ptr->fValDiff        = value_diff;
+  ptr->fValOffset      = value_offset;
+  ptr->fSize.call      = size_func;
+  ptr->fResize.call    = resize_func;
+  ptr->fNext.call      = next_func;
+  ptr->fFirst.call     = first_func;
+  ptr->fClear.call     = clear_func;
+  ptr->fConstruct.call = construct_func;
+  ptr->fDestruct.call  = destruct_func;
+  ptr->fFeed.call      = feed_func;
+  ptr->fCollect.call   = collect_func;
+  ptr->CheckFunctions();
+  return ptr;
+}
+
+/// Generate streamer from static functions
+TCollectionProxy::Proxy_t* 
+TCollectionProxy::genExplicitStreamer(  Info_t  info,
+                                        size_t  iter_size,
+                                        size_t  value_diff,
+                                        int     value_offset,
+                                        void*  (*size_func)(void*),
+                                        void*  (*resize_func)(void*),
+                                        void*  (*clear_func)(void*),
+                                        void*  (*first_func)(void*),
+                                        void*  (*next_func)(void*),
+                                        void*  (*construct_func)(void*),
+                                        void*  (*destruct_func)(void*),
+                                        void*  (*feed_func)(void*),
+                                        void*  (*collect_func)(void*)
+                                        )
+{
+  TGenCollectionStreamer* ptr = new TGenCollectionStreamer(info, iter_size);
+  ptr->fValDiff        = value_diff;
+  ptr->fValOffset      = value_offset;
+  ptr->fSize.call      = size_func;
+  ptr->fResize.call    = resize_func;
+  ptr->fNext.call      = next_func;
+  ptr->fFirst.call     = first_func;
+  ptr->fClear.call     = clear_func;
+  ptr->fConstruct.call = construct_func;
+  ptr->fDestruct.call  = destruct_func;
+  ptr->fFeed.call      = feed_func;
+  ptr->fCollect.call   = collect_func;
+  ptr->CheckFunctions();
+  return ptr;
+}
+
+/// Generate class streamer from static functions
+TClassStreamer* 
+TCollectionProxy::genExplicitClassStreamer( Info_t info,
+                                            size_t iter_size,
+                                            size_t value_diff,
+                                            int    value_offset,
+                                            void*  (*size_func)(void*),
+                                            void*  (*resize_func)(void*),
+                                            void*  (*clear_func)(void*),
+                                            void*  (*first_func)(void*),
+                                            void*  (*next_func)(void*),
+                                            void*  (*construct_func)(void*),
+                                            void*  (*destruct_func)(void*),
+                                            void*  (*feed_func)(void*),
+                                            void*  (*collect_func)(void*)
+                                            )
+{
+  TCollectionClassStreamer* s = new TCollectionClassStreamer();
+  s->AdoptProxy(genExplicitStreamer(info, 
+                                    iter_size,
+                                    value_diff,
+                                    value_offset,
+                                    size_func,
+                                    resize_func,
+                                    clear_func,
+                                    first_func,
+                                    next_func,
+                                    construct_func,
+                                    destruct_func,
+                                    feed_func,
+                                    collect_func));
+  return s;
+}
+
+/// Generate member streamer from static functions
+TMemberStreamer* 
+TCollectionProxy::genExplicitMemberStreamer(Info_t info,
+                                            size_t iter_size,
+                                            size_t value_diff,
+                                            int    value_offset,
+                                            void*  (*size_func)(void*),
+                                            void*  (*resize_func)(void*),
+                                            void*  (*clear_func)(void*),
+                                            void*  (*first_func)(void*),
+                                            void*  (*next_func)(void*),
+                                            void*  (*construct_func)(void*),
+                                            void*  (*destruct_func)(void*),
+                                            void*  (*feed_func)(void*),
+                                            void*  (*collect_func)(void*)
+                                            )
+{
+  TCollectionMemberStreamer* s = new TCollectionMemberStreamer();
+  s->AdoptProxy(genExplicitStreamer(info, 
+                                    iter_size,
+                                    value_diff,
+                                    value_offset,
+                                    size_func,
+                                    resize_func,
+                                    clear_func,
+                                    first_func,
+                                    next_func,
+                                    construct_func,
+                                    destruct_func,
+                                    feed_func,
+                                    collect_func));
+  return s;
+}
+
+/// Issue Error about invalid proxy
+void TCollectionStreamer::InvalidProxyError()   {
+  Fatal("TCollectionStreamer>","No proxy available. Data streaming impossible.");
+}
+
+/// Initializing constructor
+TCollectionStreamer::TCollectionStreamer() : fProxy(0) {       
+}
+
+/// Copy constructor
+TCollectionStreamer::TCollectionStreamer(const TCollectionStreamer& c)  {
+  if ( c.fProxy )  {
+    fProxy = c.fProxy->Generate();
+    return;
+  }
+  InvalidProxyError();
+}
+
+/// Standard destructor
+TCollectionStreamer::~TCollectionStreamer()    {       
+  if ( fProxy )  {
+    delete fProxy;
+  }
+}
+
+/// Attach worker proxy
+void TCollectionStreamer::AdoptProxy(TVirtualCollectionProxy* proxy)  {
+  if ( fProxy )  {
+    delete fProxy;
+  }
+  fProxy = proxy;
+}
+
+/// Streamer for I/O handling
+void TCollectionStreamer::Streamer(TBuffer &buff, void *pObj, int /* siz */ ) {
+  if ( fProxy )  {
+    TVirtualCollectionProxy::TPushPop env(fProxy, pObj);
+    fProxy->Streamer(buff);
+    return;
+  }
+  InvalidProxyError();
+}
+#ifdef _WIN32
+#include <vector>
+#include <list>
+#include <deque>
+#include <set>
+#include <map>
+void __test()  {
+  TCollectionProxy::genProxy<TCollectionProxy::Pushback<std::vector<bool> > >();
+  TCollectionProxy::genProxy<TCollectionProxy::Pushback<std::list<bool> > >();
+  TCollectionProxy::genProxy<TCollectionProxy::Pushback<std::deque<bool> > >();
+  TCollectionProxy::genProxy<TCollectionProxy::Insert<std::set<bool> > >();
+  TCollectionProxy::genProxy<TCollectionProxy::MapInsert<std::map<bool,bool> > >();
+}
+#endif
diff --git a/cont/src/TEmulatedCollectionProxy.cxx b/cont/src/TEmulatedCollectionProxy.cxx
new file mode 100644
index 00000000000..834d5ca9762
--- /dev/null
+++ b/cont/src/TEmulatedCollectionProxy.cxx
@@ -0,0 +1,437 @@
+// @(#)root/cont:$Name:  $:$Id: TEmulatedCollectionProxy.cxx,v 1.26 2004/10/13 15:30:22 rdm Exp $
+// Author: Markus Frank 28/10/04
+
+/*************************************************************************
+ * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers.               *
+ * All rights reserved.                                                  *
+ *                                                                       *
+ * For the licensing terms see $ROOTSYS/LICENSE.                         *
+ * For the list of contributors see $ROOTSYS/README/CREDITS.             *
+ *************************************************************************/
+
+//////////////////////////////////////////////////////////////////////////
+//                                                                      //
+// TEmulatedCollectionProxy
+//
+// Streamer around an arbitrary container, which implements basic 
+// functionality and iteration.
+//
+// In particular this is used to implement splitting and abstract
+// element access of any container. Access to compiled code is necessary
+// to implement the abstract iteration sequence and functionality like
+// size(), clear(), resize(). resize() may be a void operation.
+//
+//////////////////////////////////////////////////////////////////////////
+
+#include "TEmulatedCollectionProxy.h"
+#include "TStreamerInfo.h"
+#include "TClassEdit.h"
+#include "TError.h"
+#include "TROOT.h"
+#include <iostream>
+
+/// Build a Streamer for an emulated vector whose type is 'name'.
+TEmulatedCollectionProxy::TEmulatedCollectionProxy(const TEmulatedCollectionProxy& copy)
+: TGenCollectionProxy(copy)
+{
+}
+
+/// Build a Streamer for a collection whose type is described by 'collectionClass'.
+TEmulatedCollectionProxy::TEmulatedCollectionProxy(const char* cl_name)
+: TGenCollectionProxy(typeid(std::vector<char>), sizeof(std::vector<char>::iterator))
+{
+  fName = cl_name;
+  Initialize();
+}
+
+/// Standard destructor
+TEmulatedCollectionProxy::~TEmulatedCollectionProxy()   {
+}
+
+/// Virtual copy constructor
+TVirtualCollectionProxy* TEmulatedCollectionProxy::Generate() const  { 
+  if ( !fClass ) Initialize();
+  return new TEmulatedCollectionProxy(*this);
+}
+
+/// Proxy initializer
+TGenCollectionProxy *TEmulatedCollectionProxy::InitializeEx() { 
+  fClass = gROOT->GetClass(fName.c_str());
+  fEnv = 0;
+  fKey = 0;
+  if ( fClass )  {
+    int nested = 0;
+    std::vector<std::string> inside;
+    fPointers  = false;
+    int num = TClassEdit::GetSplit(fName.c_str(),inside,nested);
+    if ( num > 1 )  {
+      std::string nam;
+      fSTL_type = TClassEdit::STLKind(inside[0].c_str());
+      // std::cout << "Initialized " << typeid(*this).name() << ":" << fName << std::endl;
+      switch ( fSTL_type )  {
+        case TClassEdit::kMap:
+        case TClassEdit::kMultiMap:
+          fKey   = new Value(inside[1]);
+          fVal   = new Value(inside[2]);
+          fPointers |= 0 != (fKey->fCase&G__BIT_ISPOINTER);
+          if ( 0 == fValDiff )  {
+            fValDiff = fKey->fSize + fVal->fSize;
+          }
+          if ( 0 == fValOffset )  {
+            fValOffset = fKey->fSize;
+          }
+          break;
+        default:
+          fVal   = new Value(inside[1]);
+          if ( 0 == fValDiff )  {
+            fValDiff = fVal->fSize;
+          }
+          break;
+      }
+      fValue = new Value(*fVal);
+      fPointers |= 0 != (fVal->fCase&G__BIT_ISPOINTER);
+      return this;
+    }
+    Fatal("TEmulatedCollectionProxy","Components of %s not analysed!",fClass->GetName());
+  }
+  Fatal("TEmulatedCollectionProxy","Collection class %s not found!",fTypeinfo.name());
+  return 0;
+}
+
+/// Return the current size of the container
+UInt_t TEmulatedCollectionProxy::Size() const   {
+  if ( fEnv && fEnv->object )   {
+    return fEnv->size = PCont_t(fEnv->object)->size()/fValDiff;
+  }
+  Fatal("TEmulatedCollectionProxy","Size> Logic error - no proxy object set.");
+  return 0;
+}
+
+/// Clear the emulated collection.  
+void TEmulatedCollectionProxy::Clear(const char* opt)  {
+  Resize(0, opt && *opt=='f');
+}
+
+/// Shrink the container
+void TEmulatedCollectionProxy::Shrink(UInt_t nCurr, UInt_t left, Bool_t /* force */ )  {
+  typedef std::string  String_t;
+  PCont_t c   = PCont_t(fEnv->object);
+  char* addr  = ((char*)fEnv->start) + fValDiff*left;
+  size_t i;
+
+  switch ( fSTL_type )  {
+    case TClassEdit::kMap:
+    case TClassEdit::kMultiMap:
+      addr = ((char*)fEnv->start) + fValDiff*left;
+      switch(fKey->fCase)  {
+        case G__BIT_ISFUNDAMENTAL:  // Only handle primitives this way
+        case G__BIT_ISENUM:
+          break;
+        case G__BIT_ISCLASS:
+          for( i= fKey->fType ? left : nCurr; i<nCurr; ++i, addr += fValDiff )  {
+            // Call emulation in case non-compiled content
+            fKey->fDtor ? (*fKey->fDtor)(addr) : fKey->fType->Destructor(addr, kTRUE);
+          }
+          break;
+        case R__BIT_ISSTRING:
+          for( i=left; i<nCurr; ++i, addr += fValDiff )
+            ((std::string*)addr)->~String_t();
+          break;
+        case G__BIT_ISPOINTER|G__BIT_ISCLASS:
+          for( i=left; i<nCurr; ++i, addr += fValDiff )  {
+            StreamHelper* i = *(StreamHelper**)addr;
+            void* ptr = i->ptr();
+            if ( fKey->fDelete )  {       // Case of compiled content
+              (*fKey->fDelete)(ptr);
+            }
+            else if ( fKey->fType )  {    // Case of emulated content
+              fKey->fType->Destructor(ptr);
+            }
+            else if ( fKey->fDtor )  {    // Case of compiled content
+              (*fKey->fDtor)(ptr);
+              ::operator delete(ptr);
+            }
+            else {
+              ::operator delete(i->ptr());
+            }
+            i->set(0);
+          }
+        case G__BIT_ISPOINTER|R__BIT_ISSTRING:
+          for( i=nCurr; i<left; ++i, addr += fValDiff )   {
+            StreamHelper* i = *(StreamHelper**)addr;
+            delete (std::string*)i;
+            i->set(0);
+          }
+          break;
+        case G__BIT_ISPOINTER|R__BIT_ISTSTRING|G__BIT_ISCLASS:
+          for( i=nCurr; i<left; ++i, addr += fValDiff )   {
+            StreamHelper* i = *(StreamHelper**)addr;
+            delete i->tstr;
+            i->set(0);
+          }
+          break;
+      }
+      addr = ((char*)fEnv->start)+fKey->fSize+fValDiff*left;
+      // DO NOT break; just continue
+
+    // General case for all values
+    default:
+      switch( fVal->fCase )  {
+        case G__BIT_ISFUNDAMENTAL:  // Only handle primitives this way
+        case G__BIT_ISENUM:
+          break;
+        case G__BIT_ISCLASS:
+          for( i=fVal->fDtor ? left : nCurr; i<nCurr; ++i, addr += fValDiff )  {
+            // Call emulation in case non-compiled content
+            fKey->fDtor ? (*fKey->fDtor)(addr) : fKey->fType->Destructor(addr,kTRUE);
+          }
+          break;
+        case R__BIT_ISSTRING:
+          for( i=left; i<nCurr; ++i, addr += fValDiff )
+            ((std::string*)addr)->~String_t();
+          break;
+        case G__BIT_ISPOINTER|G__BIT_ISCLASS:
+          for( i=left; i<nCurr; ++i, addr += fValDiff )  {
+            StreamHelper* i = *(StreamHelper**)addr;
+            void* p = i->ptr();
+            if ( p )  {
+              if ( fVal->fDelete )  {      // Case of compiled content
+                (*fVal->fDelete)(p);
+              }
+              else if ( fVal->fType )  {  // Case of emultated content
+                fVal->fType->Destructor(p);
+              }
+              else if ( fVal->fDtor )  {   // Case of compiled content
+                (*fVal->fDtor)(p);
+                ::operator delete(p);
+              }
+              else  {
+                ::operator delete(p);
+              }
+            }
+            i->set(0);
+          }
+        case G__BIT_ISPOINTER|R__BIT_ISSTRING:
+          for( i=nCurr; i<left; ++i, addr += fValDiff )   {
+            StreamHelper* i = *(StreamHelper**)addr;
+            delete (std::string*)i;
+            i->set(0);
+          }
+          break;
+        case G__BIT_ISPOINTER|R__BIT_ISTSTRING|G__BIT_ISCLASS:
+          for( i=nCurr; i<left; ++i, addr += fValDiff )   {
+            StreamHelper* i = *(StreamHelper**)addr;
+            delete i->tstr;
+            i->set(0);
+          }
+          break;
+      }
+  }
+  c->resize(left*fValDiff,0);
+  fEnv->start = left>0 ? &(*c->begin()) : 0;
+  return;
+}
+
+/// Expand the container
+void TEmulatedCollectionProxy::Expand(UInt_t nCurr, UInt_t left)  {
+  size_t i;
+  PCont_t c   = PCont_t(fEnv->object);
+  c->resize(left*fValDiff,0);
+  fEnv->start = left>0 ? &(*c->begin()) : 0;
+  char* addr = ((char*)fEnv->start) + fValDiff*nCurr;
+  switch ( fSTL_type )  {
+    case TClassEdit::kMap:
+    case TClassEdit::kMultiMap:
+      switch(fKey->fCase)  {
+        case G__BIT_ISFUNDAMENTAL:  // Only handle primitives this way
+        case G__BIT_ISENUM:
+          break;
+        case G__BIT_ISCLASS:
+          for( i=fVal->fCtor ? nCurr : left; i<left; ++i, addr += fValDiff )
+            (*fKey->fCtor)(addr);
+          break;
+        case R__BIT_ISSTRING:
+          for( i=nCurr; i<left; ++i, addr += fValDiff )
+            ::new(addr) std::string();
+          break;
+        case G__BIT_ISPOINTER|G__BIT_ISCLASS:
+        case G__BIT_ISPOINTER|R__BIT_ISSTRING:
+        case G__BIT_ISPOINTER|R__BIT_ISTSTRING|G__BIT_ISCLASS:
+          for( i=nCurr; i<left; ++i, addr += fValDiff )
+            *(void**)addr = 0;
+          break;
+      }
+      addr = ((char*)fEnv->start)+fKey->fSize+fValDiff*nCurr;
+      // DO NOT break; just continue
+
+    // General case for all values
+    default:
+      switch(fVal->fCase)  {
+        case G__BIT_ISFUNDAMENTAL:  // Only handle primitives this way
+        case G__BIT_ISENUM:
+          break;
+        case G__BIT_ISCLASS:
+          for( i=fVal->fCtor ? nCurr : left; i<left; ++i, addr += fValDiff )
+            (*fVal->fCtor)(addr);
+          break;
+        case R__BIT_ISSTRING:
+          for( i=nCurr; i<left; ++i, addr += fValDiff )
+            ::new(addr) std::string();
+          break;
+        case G__BIT_ISPOINTER|G__BIT_ISCLASS:
+        case G__BIT_ISPOINTER|R__BIT_ISSTRING:
+        case G__BIT_ISPOINTER|R__BIT_ISTSTRING|G__BIT_ISCLASS:
+          for( i=nCurr; i<left; ++i, addr += fValDiff )
+            *(void**)addr = 0;
+          break;
+      }
+      break;
+  }
+}
+/// Resize the container
+void TEmulatedCollectionProxy::Resize(UInt_t left, Bool_t force)  {
+  if ( fEnv && fEnv->object )   {
+    size_t nCurr = Size();
+    PCont_t c = PCont_t(fEnv->object);
+    fEnv->start = left>0 ? &(*c->begin()) : 0;
+    if ( left == nCurr )  {
+      return;
+    }
+    else if ( left < nCurr )  {
+      Shrink(nCurr, left, force);
+      return;
+    }
+    Expand(nCurr, left);
+    return;
+  }
+  Fatal("TEmulatedCollectionProxy","Resize> Logic error - no proxy object set.");
+}
+
+/// Return the address of the value at index 'idx'
+void* TEmulatedCollectionProxy::At(UInt_t idx)   {
+  if ( fEnv && fEnv->object )   {
+    PCont_t c = PCont_t(fEnv->object);
+    return idx<(c->size()/fValDiff) ? ((char*)&(*c->begin()))+idx*fValDiff : 0;
+  }
+  Fatal("TEmulatedCollectionProxy","At> Logic error - no proxy object set.");
+  return 0;
+}
+
+void* TEmulatedCollectionProxy::Allocate(UInt_t n, Bool_t forceDelete)  {
+  Resize(n, forceDelete);
+  return fEnv;
+}
+
+void TEmulatedCollectionProxy::Commit(void* /* env */ )  {
+}
+
+/// Object input streamer
+void TEmulatedCollectionProxy::ReadItems(int nElements, TBuffer &b)  {
+  bool vsn3 = b.GetInfo() && b.GetInfo()->GetOldVersion()<=3;
+  StreamHelper* itm = (StreamHelper*)At(0);
+  switch (fVal->fCase) {
+    case G__BIT_ISFUNDAMENTAL:  // Only handle primitives this way
+    case G__BIT_ISENUM:
+      switch( int(fVal->fKind) )   {
+        case kChar_t:    b.ReadFastArray(&itm->s_char    , nElements); break;
+        case kShort_t:   b.ReadFastArray(&itm->s_short   , nElements); break;
+        case kInt_t:     b.ReadFastArray(&itm->s_int     , nElements); break;
+        case kLong_t:    b.ReadFastArray(&itm->s_long    , nElements); break;
+        case kLong64_t:  b.ReadFastArray(&itm->s_longlong, nElements); break;
+        case kFloat_t:   b.ReadFastArray(&itm->flt       , nElements); break;
+        case kDouble_t:  b.ReadFastArray(&itm->dbl       , nElements); break;
+        case kBOOL_t:    b.ReadFastArray(&itm->boolean   , nElements); break;
+        case kUChar_t:   b.ReadFastArray(&itm->u_char    , nElements); break;
+        case kUShort_t:  b.ReadFastArray(&itm->u_short   , nElements); break;
+        case kUInt_t:    b.ReadFastArray(&itm->u_int     , nElements); break;
+        case kULong_t:   b.ReadFastArray(&itm->u_long    , nElements); break;
+        case kULong64_t: b.ReadFastArray(&itm->u_longlong, nElements); break;
+        case kDouble32_t:b.ReadFastArrayDouble32(&itm->dbl,nElements); break;
+        case kchar:
+        case kNoType_t:
+        case kOther_t:
+          Error("TEmulatedCollectionProxy","fType %d is not supported yet!\n",fVal->fKind);
+      }
+      break;
+#define DOLOOP(x) {int idx=0; while(idx<nElements) {StreamHelper* i=(StreamHelper*)(((char*)itm) + fValDiff*idx); { x ;} ++idx;} break;}
+    case G__BIT_ISCLASS: 
+      DOLOOP( b.StreamObject(i,fVal->fType) );
+    case R__BIT_ISSTRING:
+      DOLOOP( i->read_std_string(b) );
+    case G__BIT_ISPOINTER|G__BIT_ISCLASS:
+      DOLOOP( i->read_any_object(fVal,b) );
+    case G__BIT_ISPOINTER|R__BIT_ISSTRING:
+#ifndef R__AIX
+      DOLOOP( i->read_std_string_pointer(b) );
+#endif
+    case G__BIT_ISPOINTER|R__BIT_ISTSTRING|G__BIT_ISCLASS:  
+      DOLOOP( i->read_tstring_pointer(vsn3,b) );
+  }
+#undef DOLOOP
+}
+
+/// Object output streamer
+void TEmulatedCollectionProxy::WriteItems(int nElements, TBuffer &b)  {
+  StreamHelper* itm = (StreamHelper*)At(0);
+  switch (fVal->fCase) {
+    case G__BIT_ISFUNDAMENTAL:  // Only handle primitives this way
+    case G__BIT_ISENUM:
+      itm = (StreamHelper*)At(0);
+      switch( int(fVal->fKind) )   {
+        case kChar_t:    b.WriteFastArray(&itm->s_char    , nElements); break;
+        case kShort_t:   b.WriteFastArray(&itm->s_short   , nElements); break;
+        case kInt_t:     b.WriteFastArray(&itm->s_int     , nElements); break;
+        case kLong_t:    b.WriteFastArray(&itm->s_long    , nElements); break;
+        case kLong64_t:  b.WriteFastArray(&itm->s_longlong, nElements); break;
+        case kFloat_t:   b.WriteFastArray(&itm->flt       , nElements); break;
+        case kDouble_t:  b.WriteFastArray(&itm->dbl       , nElements); break;
+        case kBOOL_t:    b.WriteFastArray(&itm->boolean   , nElements); break;
+        case kUChar_t:   b.WriteFastArray(&itm->u_char    , nElements); break;
+        case kUShort_t:  b.WriteFastArray(&itm->u_short   , nElements); break;
+        case kUInt_t:    b.WriteFastArray(&itm->u_int     , nElements); break;
+        case kULong_t:   b.WriteFastArray(&itm->u_long    , nElements); break;
+        case kULong64_t: b.WriteFastArray(&itm->u_longlong, nElements); break;
+        case kDouble32_t:b.WriteFastArrayDouble32(&itm->dbl,nElements); break;
+        case kchar:
+        case kNoType_t:
+        case kOther_t:
+          Error("TEmulatedCollectionProxy","fType %d is not supported yet!\n",fVal->fKind);
+      }
+      break;
+#define DOLOOP(x) {int idx=0; while(idx<nElements) {StreamHelper* i=(StreamHelper*)(((char*)itm) + fValDiff*idx); { x ;} ++idx;} break;}
+    case G__BIT_ISCLASS: 
+      DOLOOP( b.StreamObject(i,fVal->fType) );
+    case R__BIT_ISSTRING:
+      DOLOOP( TString(i->c_str()).Streamer(b) );
+    case G__BIT_ISPOINTER|G__BIT_ISCLASS:
+      DOLOOP( b.WriteObjectAny(i->ptr(),fVal->fType) );
+    case R__BIT_ISSTRING|G__BIT_ISPOINTER:
+#ifndef R__AIX
+      DOLOOP( i->write_std_string_pointer(b) );
+#endif
+    case R__BIT_ISTSTRING|G__BIT_ISCLASS|G__BIT_ISPOINTER:
+      DOLOOP( i->write_tstring_pointer(b) );
+  }
+#undef DOLOOP
+}
+
+/// TClassStreamer IO overload
+void TEmulatedCollectionProxy::Streamer(TBuffer &b) {
+  if ( b.IsReading() ) {  //Read mode 
+    int nElements = 0;
+    b >> nElements;
+    if ( fEnv->object )  {
+      Resize(nElements,true);
+    }
+    if ( nElements > 0 )  {
+      ReadItems(nElements, b);
+    }
+  }
+  else {     // Write case
+    int nElements = fEnv->object ? *(size_t*)fSize.invoke(fEnv) : 0;
+    b << nElements;
+    if ( nElements > 0 )  {
+      WriteItems(nElements, b);
+    }
+  }
+}
diff --git a/cont/src/TEmulatedMapProxy.cxx b/cont/src/TEmulatedMapProxy.cxx
new file mode 100644
index 00000000000..e591582e010
--- /dev/null
+++ b/cont/src/TEmulatedMapProxy.cxx
@@ -0,0 +1,221 @@
+// @(#)root/cont:$Name:  $:$Id: TEmulatedMapProxy.cxx,v 1.26 2004/10/13 15:30:22 rdm Exp $
+// Author: Markus Frank 28/10/04
+
+/*************************************************************************
+ * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers.               *
+ * All rights reserved.                                                  *
+ *                                                                       *
+ * For the licensing terms see $ROOTSYS/LICENSE.                         *
+ * For the list of contributors see $ROOTSYS/README/CREDITS.             *
+ *************************************************************************/
+
+//////////////////////////////////////////////////////////////////////////
+//                                                                      //
+// TEmulatedMapProxy
+//
+// Streamer around an arbitrary container, which implements basic 
+// functionality and iteration.
+//
+// In particular this is used to implement splitting and abstract
+// element access of any container. Access to compiled code is necessary
+// to implement the abstract iteration sequence and functionality like
+// size(), clear(), resize(). resize() may be a void operation.
+//
+//////////////////////////////////////////////////////////////////////////
+
+#include "TEmulatedMapProxy.h"
+#include "TStreamerInfo.h"
+#include "TClassEdit.h"
+#include "TError.h"
+
+/// Build a Streamer for an emulated vector whose type is 'name'.
+TEmulatedMapProxy::TEmulatedMapProxy(const TEmulatedMapProxy& copy)
+: TEmulatedCollectionProxy(copy)
+{
+  if ( !(fSTL_type == TClassEdit::kMap || fSTL_type == TClassEdit::kMultiMap) )  {
+    Fatal("TEmulatedMapProxy","Class %s is not a map-type!",fName.c_str());
+  }
+}
+
+/// Build a Streamer for a collection whose type is described by 'collectionClass'.
+TEmulatedMapProxy::TEmulatedMapProxy(const char* cl_name)
+: TEmulatedCollectionProxy(cl_name)
+{
+  fName = cl_name;
+  Initialize();
+  if ( !(fSTL_type == TClassEdit::kMap || fSTL_type == TClassEdit::kMultiMap) )  {
+    Fatal("TEmulatedMapProxy","Class %s is not a map-type!",fName.c_str());
+  }
+}
+
+/// Standard destructor
+TEmulatedMapProxy::~TEmulatedMapProxy()   {
+}
+
+/// Virtual copy constructor
+TVirtualCollectionProxy* TEmulatedMapProxy::Generate() const  { 
+  if ( !fClass ) Initialize();
+  return new TEmulatedMapProxy(*this);
+}
+
+/// Return the address of the value at index 'idx'
+void* TEmulatedMapProxy::At(UInt_t idx)   {
+  if ( fEnv && fEnv->object )   {
+    PCont_t c = PCont_t(fEnv->object);
+    return idx<(c->size()/fValDiff) ? ((char*)&(*c->begin())) + idx*fValDiff : 0;
+  }
+  Fatal("TEmulatedMapProxy","At> Logic error - no proxy object set.");
+  return 0;
+}
+
+/// Return the current size of the container
+UInt_t TEmulatedMapProxy::Size() const   {
+  if ( fEnv && fEnv->object )   {
+    PCont_t c = PCont_t(fEnv->object);
+    return fEnv->size = (c->size()/fValDiff);
+  }
+  Fatal("TEmulatedMapProxy","Size> Logic error - no proxy object set.");
+  return 0;
+}
+
+/// Map input streamer
+void TEmulatedMapProxy::ReadMap(int nElements, TBuffer &b)  {
+  bool   vsn3 = b.GetInfo() && b.GetInfo()->GetOldVersion()<=3;
+  int    idx, loop, off[2] = {0, fKey->fSize };
+  Value  *v, *val[2] = { fKey, fVal };
+  StreamHelper* helper;
+  float f;
+  char* addr = 0; 
+  char* temp = (char*)At(0);
+  for ( idx = 0; idx < nElements; ++idx )  {
+    addr = temp + idx*fValDiff;
+    for ( loop=0; loop<2; loop++)  {
+      addr += off[loop];
+      helper = (StreamHelper*)addr;
+      v = val[loop];
+      switch (v->fCase) {
+        case G__BIT_ISFUNDAMENTAL:  // Only handle primitives this way
+        case G__BIT_ISENUM:
+          switch( int(v->fKind) )   {
+            case kChar_t:    b >> helper->s_char;      break;
+            case kShort_t:   b >> helper->s_short;     break;
+            case kInt_t:     b >> helper->s_int;       break;
+            case kLong_t:    b >> helper->s_long;      break;
+            case kLong64_t:  b >> helper->s_longlong;  break;
+            case kFloat_t:   b >> helper->flt;         break;
+            case kDouble_t:  b >> helper->dbl;         break;
+            case kBOOL_t:    b >> helper->boolean;     break;
+            case kUChar_t:   b >> helper->u_char;      break;
+            case kUShort_t:  b >> helper->u_short;     break;
+            case kUInt_t:    b >> helper->u_int;       break;
+            case kULong_t:   b >> helper->u_long;      break;
+            case kULong64_t: b >> helper->u_longlong;  break;
+            case kDouble32_t:b >> f; 
+                             helper->dbl = double(f);  break;
+            case kchar:
+            case kNoType_t:
+            case kOther_t:
+              Error("TEmulatedMapProxy","fType %d is not supported yet!\n",v->fKind);
+          }
+          break;
+        case G__BIT_ISCLASS:
+          b.StreamObject(helper,v->fType);
+          break;
+        case R__BIT_ISSTRING:
+          helper->read_std_string(b);
+          break;
+        case G__BIT_ISPOINTER|G__BIT_ISCLASS:
+          helper->set(b.ReadObjectAny(v->fType));
+          break;
+        case G__BIT_ISPOINTER|R__BIT_ISSTRING:
+#ifndef R__AIX
+          helper->read_std_string_pointer(b);
+#endif
+          break;
+        case G__BIT_ISPOINTER|R__BIT_ISTSTRING|G__BIT_ISCLASS:
+          helper->read_tstring_pointer(vsn3,b);
+          break;
+      }
+    }
+  }
+}
+
+/// Map output streamer
+void TEmulatedMapProxy::WriteMap(int nElements, TBuffer &b)  {
+  Value  *v, *val[2] = { fKey, fVal };
+  int    off[2]      = { 0, fKey->fSize };
+  StreamHelper* i;
+  char* addr = 0; 
+  char* temp = (char*)At(0);
+  for (int loop, idx = 0; idx < nElements; ++idx )  {
+    addr = temp + idx*fValDiff;
+    for ( loop = 0; loop<2; ++loop )  {
+      addr += off[loop];
+      i = (StreamHelper*)addr;
+      v = val[loop];
+      switch (v->fCase) {
+        case G__BIT_ISFUNDAMENTAL:  // Only handle primitives this way
+        case G__BIT_ISENUM:
+          switch( int(v->fKind) )   {
+            case kChar_t:    b << i->s_char;      break;
+            case kShort_t:   b << i->s_short;     break;
+            case kInt_t:     b << i->s_int;       break;
+            case kLong_t:    b << i->s_long;      break;
+            case kLong64_t:  b << i->s_longlong;  break;
+            case kFloat_t:   b << i->flt;         break;
+            case kDouble_t:  b << i->dbl;         break;
+            case kBOOL_t:    b << i->boolean;     break;
+            case kUChar_t:   b << i->u_char;      break;
+            case kUShort_t:  b << i->u_short;     break;
+            case kUInt_t:    b << i->u_int;       break;
+            case kULong_t:   b << i->u_long;      break;
+            case kULong64_t: b << i->u_longlong;  break;
+            case kDouble32_t:b << float(i->dbl);  break;
+            case kchar:
+            case kNoType_t:
+            case kOther_t:
+              Error("TEmulatedMapProxy","fType %d is not supported yet!\n",v->fKind);
+          }
+          break;
+        case G__BIT_ISCLASS: 
+          b.StreamObject(i,v->fType);
+          break;
+        case R__BIT_ISSTRING:
+          TString(i->c_str()).Streamer(b);
+          break;
+        case G__BIT_ISPOINTER|G__BIT_ISCLASS:
+          b.WriteObjectAny(i->ptr(),v->fType);
+          break;
+        case R__BIT_ISSTRING|G__BIT_ISPOINTER:
+#ifndef R__AIX
+          i->write_std_string_pointer(b);
+#endif
+          break;
+        case R__BIT_ISTSTRING|G__BIT_ISCLASS|G__BIT_ISPOINTER:
+          i->write_tstring_pointer(b);
+          break;
+      }
+    }
+  }
+}
+
+/// TClassStreamer IO overload
+void TEmulatedMapProxy::Streamer(TBuffer &b) {
+  if ( b.IsReading() ) {  //Read mode 
+    int nElements = 0;
+    b >> nElements;
+    if ( fEnv->object )  {
+      Resize(nElements,true);
+    }
+    if ( nElements > 0 )  {
+      ReadMap(nElements, b);
+    }
+  }
+  else {     // Write case
+    int nElements = fEnv->object ? Size() : 0;
+    b << nElements;
+    if ( nElements > 0 )  {
+      WriteMap(nElements, b);
+    }
+  }
+}
diff --git a/cont/src/TGenCollectionProxy.cxx b/cont/src/TGenCollectionProxy.cxx
new file mode 100644
index 00000000000..97e3dfa76b9
--- /dev/null
+++ b/cont/src/TGenCollectionProxy.cxx
@@ -0,0 +1,714 @@
+// @(#)root/cont:$Name:  $:$Id: TGenVectorProxy.cxx,v 1.26 2004/10/13 15:30:22 rdm Exp $
+// Author: Markus Frank 28/10/04
+
+/*************************************************************************
+ * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers.               *
+ * All rights reserved.                                                  *
+ *                                                                       *
+ * For the licensing terms see $ROOTSYS/LICENSE.                         *
+ * For the list of contributors see $ROOTSYS/README/CREDITS.             *
+ *************************************************************************/
+
+//////////////////////////////////////////////////////////////////////////
+//                                                                      //
+// TGenCollectionProxy
+//
+// Proxy around an arbitrary container, which implements basic 
+// functionality and iteration.
+//
+// In particular this is used to implement splitting and abstract
+// element access of any container. Access to compiled code is necessary
+// to implement the abstract iteration sequence and functionality like
+// size(), clear(), resize(). resize() may be a void operation.
+//
+//////////////////////////////////////////////////////////////////////////
+
+#include "TGenCollectionProxy.h"
+#include "TStreamerElement.h"
+#include "TClassEdit.h"
+#include "Property.h"
+#include "TClass.h"
+#include "TError.h"
+#include "TROOT.h"
+#include "Api.h"
+#include <iostream>
+
+#define MESSAGE(which,text)  
+
+/** @class TGenVectorProxy TGenCollectionProxy.cxx cont/TGenCollectionProxy.cxx
+  *
+  * Localoptimization class.
+  *
+  * Collection proxies get copied. On copy we switch the type of the 
+  * proxy to the concrete STL type. The concrete types are optimized 
+  * for element access.
+  *
+  * @author  M.Frank
+  * @version 1.0
+  * @date    10/10/2004
+  */
+class TGenVectorProxy : public TGenCollectionProxy {
+public:
+  /// Standard Destructor
+  TGenVectorProxy(const TGenCollectionProxy& c) : TGenCollectionProxy(c)  {  
+  }
+  /// Standard Destructor
+  virtual ~TGenVectorProxy() {
+  }
+  /// Return the address of the value at index 'idx'
+  virtual void* At(UInt_t idx)   {
+    if ( fEnv && fEnv->object )   {
+      fEnv->idx = idx;
+      switch( idx ) {
+        case 0:
+          return fEnv->start = fFirst.invoke(fEnv);
+        default:
+          return ((char*)fEnv->start) + fValDiff*idx;
+      }
+    }
+    Fatal("TGenVectorProxy","At> Logic error - no proxy object set.");
+    return 0;
+  }
+  /// Call to delete/destruct individual item
+  virtual void DeleteItem(bool force, void* ptr)  const  {
+    if ( force && ptr )  {
+      if ( fValue->fDelete )  {
+        (*fValue->fDelete)(ptr);
+      }
+      else if ( fVal->fType )  {
+        fVal->fType->Destructor(ptr);
+      }
+      else {
+        ::operator delete(ptr);
+      }
+    }
+  }
+};
+
+/** @class TGenListProxy TGenCollectionProxy.cxx cont/TGenCollectionProxy.cxx
+  *
+  * Localoptimization class.
+  *
+  * Collection proxies get copied. On copy we switch the type of the 
+  * proxy to the concrete STL type. The concrete types are optimized 
+  * for element access.
+  *
+  * @author  M.Frank
+  * @version 1.0
+  * @date    10/10/2004
+  */
+class TGenListProxy : public TGenVectorProxy {
+public:
+  /// Standard Destructor
+  TGenListProxy(const TGenCollectionProxy& c) : TGenVectorProxy(c)  {  
+  }
+  /// Standard Destructor
+  virtual ~TGenListProxy() {
+  }
+  /// Return the address of the value at index 'idx'
+  void* At(UInt_t idx)   {
+    if ( fEnv && fEnv->object )   {
+      switch( idx ) {
+        case 0:
+          fEnv->idx = idx;
+          return fEnv->start = fFirst.invoke(fEnv);
+        default:  {
+          fEnv->idx = idx - fEnv->idx;
+          void* result = fNext.invoke(fEnv);
+          fEnv->idx = idx;
+          return result;
+        }
+      }
+    }
+    Fatal("TGenListProxy","At> Logic error - no proxy object set.");
+    return 0;
+  }
+};
+
+/** @class TGenSetProxy TGenCollectionProxy.cxx cont/TGenCollectionProxy.cxx
+  *
+  * Localoptimization class.
+  *
+  * Collection proxies get copied. On copy we switch the type of the 
+  * proxy to the concrete STL type. The concrete types are optimized 
+  * for element access.
+  *
+  * @author  M.Frank
+  * @version 1.0
+  * @date    10/10/2004
+  */
+class TGenSetProxy : public TGenVectorProxy {
+public:
+  /// Standard Destructor
+  TGenSetProxy(const TGenCollectionProxy& c) : TGenVectorProxy(c)  {  
+  }
+  /// Standard Destructor
+  virtual ~TGenSetProxy() {
+  }
+  /// Return the address of the value at index 'idx'
+  void* At(UInt_t idx)   {
+    if ( fEnv && fEnv->object )   {
+      if ( fEnv->temp )  {
+        return (((char*)fEnv->temp)+idx*fValDiff);
+      }
+      switch( idx ) {
+        case 0:
+          fEnv->idx = idx;
+          return fEnv->start = fFirst.invoke(fEnv);
+        default:  {
+          fEnv->idx = idx - fEnv->idx;
+          void* result = fNext.invoke(fEnv);
+          fEnv->idx = idx;
+          return result;
+        }
+      }
+    }
+    Fatal("TGenSetProxy","At> Logic error - no proxy object set.");
+    return 0;
+  }
+};
+
+/** @class TGenMapProxy TGenCollectionProxy.cxx cont/TGenCollectionProxy.cxx
+  *
+  * Localoptimization class.
+  *
+  * Collection proxies get copied. On copy we switch the type of the 
+  * proxy to the concrete STL type. The concrete types are optimized 
+  * for element access.
+  *
+  * @author  M.Frank
+  * @version 1.0
+  * @date    10/10/2004
+  */
+class TGenMapProxy : public TGenSetProxy {
+public:
+  /// Standard Destructor
+  TGenMapProxy(const TGenCollectionProxy& c) : TGenSetProxy(c)  {  
+  }
+  /// Standard Destructor
+  virtual ~TGenMapProxy() {
+  }
+  /// Call to delete/destruct individual item
+  virtual void DeleteItem(bool /* force */, void* ptr)  const  {
+    if ( fKey->fCase&G__BIT_ISPOINTER )  {
+      if ( *(void**)ptr )  {
+        (*fKey->fDelete)(*(void**)ptr);
+      }
+    }
+    if ( fVal->fCase&G__BIT_ISPOINTER )  {
+      char *addr = ((char*)ptr)+fKey->fSize;
+      if ( *(void**)addr ) (*fVal->fDelete)(*(void**)addr);
+    }
+  }
+};
+
+TGenCollectionProxy::Value::Value(const Value& copy)  {
+  fType   = copy.fType;
+  fCase   = copy.fCase;
+  fKind   = copy.fKind;
+  fSize   = copy.fSize;
+  fCtor   = copy.fCtor;
+  fDtor   = copy.fDtor;
+  fDelete = copy.fDelete;
+}
+
+TGenCollectionProxy::Value::Value(const std::string& inside)  {
+  fType = 0;
+  fCase = 0;
+  fCtor = 0;
+  fDtor = 0;
+  fDelete = 0;
+  fSize = std::string::npos;
+  fKind = kNoType_t;
+  std::string intype = TClassEdit::ShortType(inside.c_str(),TClassEdit::kDropTrailStar );
+  if ( inside.substr(0,6) == "string" || inside.substr(0,11) == "std::string" ) {
+    fCase = R__BIT_ISSTRING;
+    fType = gROOT->GetClass("string");
+    fCtor = fType->GetNew();
+    fDtor = fType->GetDestructor();
+    fDelete = fType->GetDelete();
+    switch(inside[inside.length()-1]) {
+      case '*':
+        fCase |= G__BIT_ISPOINTER;
+        fSize = sizeof(void*);
+        break;
+      default:
+        fSize = sizeof(std::string);
+        break;
+    }
+  }
+  else {
+    G__TypeInfo ti(inside.c_str());
+    if ( !ti.IsValid() ) {
+      if (intype != inside) {
+        fCase |= G__BIT_ISPOINTER;
+        fSize = sizeof(void*);
+      }
+      fType = gROOT->GetClass(intype.c_str());
+      if (fType)  {
+        fCase  |= G__BIT_ISCLASS;
+        fCtor   = fType->GetNew();
+        fDtor   = fType->GetDestructor();
+        fDelete = fType->GetDelete();
+      }
+      else {
+        // either we have an Emulated enum or a really unknown class!
+        // let's just claim its an enum :(
+        fCase = G__BIT_ISENUM;
+        fSize = sizeof(Int_t);
+        fKind = kInt_t;
+      }
+    } 
+    else {
+      long P = ti.Property();      
+      if ( P&G__BIT_ISPOINTER ) {
+        fSize = sizeof(void*);
+      }
+      if ( P&G__BIT_ISSTRUCT ) {
+        P |= G__BIT_ISCLASS;
+      }
+      if ( P&G__BIT_ISCLASS ) {
+        fType = gROOT->GetClass(intype.c_str());
+        Assert(fType);
+        fCtor   = fType->GetNew();
+        fDtor   = fType->GetDestructor();
+        fDelete = fType->GetDelete();
+      }
+      else if ( P&G__BIT_ISFUNDAMENTAL ) {
+        TDataType *fundType = gROOT->GetType( intype.c_str() );
+        fKind = (EDataType)fundType->GetType();
+        fSize = ti.Size();
+        Assert(fKind>0 && fKind<20);
+      }
+      else if ( P&G__BIT_ISENUM ) {
+        fSize = sizeof(int);
+        fKind = kInt_t;
+      }
+      fCase = P & (G__BIT_ISPOINTER|G__BIT_ISFUNDAMENTAL|G__BIT_ISENUM|G__BIT_ISCLASS);
+      if (fType == TString::Class() && (fCase&G__BIT_ISPOINTER)) {
+        fCase |= R__BIT_ISTSTRING;
+      }
+    }    
+  }
+  if ( fSize == std::string::npos ) {
+    if ( fType == 0 ) {
+      Fatal("TGenCollectionProxy","Could not find %s!",inside.c_str());
+    }
+    fSize = fType->Size();
+  }
+}
+
+/// Build a proxy for an emulated container.
+TGenCollectionProxy::TGenCollectionProxy(const TGenCollectionProxy& copy)
+: TVirtualCollectionProxy(copy.fClass),
+  fTypeinfo(copy.fTypeinfo)
+{
+  fEnv            = 0;
+  fName           = copy.fName;
+  fPointers       = copy.fPointers;
+  fSTL_type       = copy.fSTL_type;
+  fSize.call      = copy.fSize.call;
+  fNext.call      = copy.fNext.call;
+  fFirst.call     = copy.fFirst.call;
+  fClear.call     = copy.fClear.call;
+  fResize.call    = copy.fResize.call;
+  fDestruct.call  = copy.fDestruct.call;
+  fConstruct.call = copy.fConstruct.call;
+  fFeed.call      = copy.fFeed.call;
+  fCollect.call   = copy.fCollect.call;
+  fValOffset      = copy.fValOffset;
+  fValDiff        = copy.fValDiff;
+  fValue          = copy.fValue ? new Value(*copy.fValue) : 0;
+  fVal            = copy.fVal   ? new Value(*copy.fVal)   : 0;
+  fKey            = copy.fKey   ? new Value(*copy.fKey)   : 0;
+}
+
+/// Build a proxy for a collection whose type is described by 'collectionClass'.
+TGenCollectionProxy::TGenCollectionProxy(Info_t info, size_t iter_size)
+: TVirtualCollectionProxy(0),
+  fTypeinfo(info)
+{
+  fEnv             = 0;
+  fSize.call       = 0;
+  fFirst.call      = 0;
+  fNext.call       = 0;
+  fClear.call      = 0;
+  fResize.call     = 0;
+  fDestruct.call   = 0;
+  fConstruct.call  = 0;
+  fCollect.call    = 0;
+  fFeed.call       = 0;
+  fValue           = 0;
+  fKey             = 0;
+  fVal             = 0;
+  fValOffset       = 0;
+  fValDiff         = 0;
+  fPointers        = false;
+  Env_t e;
+  if ( iter_size > sizeof(e.buff) ) {
+    Fatal("TGenCollectionProxy",
+          "%s %s are too large:%d bytes. Maximum is:%d bytes", 
+          "Iterators for collection", 
+          fClass->GetName(), 
+          iter_size, 
+          sizeof(e.buff));
+  }
+}
+
+/// Standard destructor
+TGenCollectionProxy::~TGenCollectionProxy()   {
+  for(Proxies_t::iterator i=fProxyList.begin(); i != fProxyList.end(); ++i)  {
+    if ( (*i) ) delete (*i);
+  }
+  fProxyList.clear();
+  if ( fValue ) delete fValue;
+  if ( fVal   ) delete fVal;
+  if ( fKey   ) delete fKey;
+}
+
+/// Virtual copy constructor
+TVirtualCollectionProxy* TGenCollectionProxy::Generate() const  { 
+  if ( !fClass ) Initialize();
+  switch(fSTL_type)  {
+    case TClassEdit::kVector:
+      return new TGenVectorProxy(*this);
+    case TClassEdit::kList:
+      return new TGenListProxy(*this);
+    case TClassEdit::kMap:
+    case TClassEdit::kMultiMap:
+      return new TGenMapProxy(*this);
+    case TClassEdit::kSet:
+    case TClassEdit::kMultiSet:
+      return new TGenSetProxy(*this);
+    default:
+      return new TGenCollectionProxy(*this);
+  }
+}
+
+/// Proxy initializer
+TGenCollectionProxy *TGenCollectionProxy::Initialize()  const { 
+  TGenCollectionProxy* p = const_cast<TGenCollectionProxy*>(this);
+  if ( fClass ) return p;
+  return p->InitializeEx();
+}
+
+/// Check existence of function pointers
+void TGenCollectionProxy::CheckFunctions()  const   {
+  if ( 0 == fSize.call )   {
+    Fatal("TGenCollectionProxy","No 'size' function pointer for class %s present.",fName.c_str());
+  }
+  if ( 0 == fResize.call )   {
+    Fatal("TGenCollectionProxy","No 'resize' function for class %s present.",fName.c_str());
+  }
+  if ( 0 == fNext.call  )   {
+    Fatal("TGenCollectionProxy","No 'next' function for class %s present.",fName.c_str());
+  }
+  if ( 0 == fFirst.call )   {
+    Fatal("TGenCollectionProxy","No 'begin' function for class %s present.",fName.c_str());
+  }
+  if ( 0 == fClear.call )   {
+    Fatal("TGenCollectionProxy","No 'clear' function for class %s present.",fName.c_str());
+  }
+  if ( 0 == fConstruct.call )   {
+    Fatal("TGenCollectionProxy","No 'block constructor' function for class %s present.",fName.c_str());
+  }
+  if ( 0 == fDestruct.call )   {
+    Fatal("TGenCollectionProxy","No 'block destructor' function for class %s present.",fName.c_str());
+  }
+  if ( 0 == fFeed.call )   {
+    Fatal("TGenCollectionProxy","No 'data feed' function for class %s present.",fName.c_str());
+  }
+  if ( 0 == fCollect.call )   {
+    Fatal("TGenCollectionProxy","No 'data collect' function for class %s present.",fName.c_str());
+  }
+}
+
+/// Proxy initializer
+TGenCollectionProxy *TGenCollectionProxy::InitializeEx() { 
+  fClass = gROOT->GetClass(fTypeinfo);
+  if ( fClass )  {
+    fEnv    = 0;
+    fName   = fClass->GetName();
+    fPointers  = false;
+    int nested = 0;
+    std::vector<std::string> inside;
+    int num = TClassEdit::GetSplit(fClass->GetName(),inside,nested);
+    if ( num > 1 )  {
+      std::string nam;
+      fSTL_type = TClassEdit::STLKind(inside[0].c_str());
+      switch ( fSTL_type )  {
+        case TClassEdit::kMap:
+        case TClassEdit::kMultiMap:
+          nam = "pair<"+inside[1]+","+inside[2];
+          nam += (nam[nam.length()-1]=='>') ? " >" : ">";
+          fValue = new Value(nam);
+          fVal   = new Value(inside[2]);
+          fKey   = new Value(inside[1]);
+          fPointers = fPointers || (0 != (fKey->fCase&G__BIT_ISPOINTER));
+          if ( 0 == fValDiff )  {
+            fValDiff = fKey->fSize + fVal->fSize;
+          }
+          if ( 0 == fValOffset )  {
+            fValOffset = fKey->fSize;
+          }
+          break;
+        default:
+          fValue = new Value(inside[1]);
+          fVal   = new Value(*fValue);
+          if ( 0 == fValDiff )  {
+            fValDiff = fVal->fSize;
+          }
+          break;
+      }
+      fPointers = fPointers || (0 != (fVal->fCase&G__BIT_ISPOINTER));
+      return this;
+    }
+    Fatal("TGenCollectionProxy","Components of %s not analysed!",fClass->GetName());
+  }
+  Fatal("TGenCollectionProxy","Collection class %s not found!",fTypeinfo.name());
+  return 0;
+}
+
+/// Return a pointer to the TClass representing the container
+TClass *TGenCollectionProxy::GetCollectionClass()  {
+  return fClass ? fClass : Initialize()->fClass;
+}
+
+/// Return the sizeof the collection object. 
+UInt_t TGenCollectionProxy::Sizeof() const  {
+  return fClass->Size();
+}
+
+/// Return true if the content is of type 'pointer to'
+Bool_t TGenCollectionProxy::HasPointers() const   {
+  return fPointers;
+}
+
+/// Return a pointer to the TClass representing the content.
+TClass *TGenCollectionProxy::GetValueClass()  {
+  return fValue->fType;
+}
+
+/// Set pointer to the TClass representing the content.
+void TGenCollectionProxy::SetValueClass(TClass *new_Value_type)  {
+  fValue->fType = new_Value_type;
+}
+
+/// If the content is a simple numerical value, return its type (see TDataType)
+EDataType TGenCollectionProxy::GetType()   {
+  return fValue->fKind;
+}
+
+/// Return the address of the value at index 'idx'
+void* TGenCollectionProxy::At(UInt_t idx)   {
+  if ( fEnv && fEnv->object )   {
+    switch (fSTL_type)  {
+      case TClassEdit::kVector:
+        fEnv->idx = idx;
+        switch( idx ) {
+          case 0:
+            return fEnv->start = fFirst.invoke(fEnv);
+          default:
+            return ((char*)fEnv->start) + fValDiff*idx;
+        }
+      case TClassEdit::kSet:
+      case TClassEdit::kMultiSet:
+      case TClassEdit::kMap:
+      case TClassEdit::kMultiMap:
+        if ( fEnv->temp )  {
+          return (((char*)fEnv->temp)+idx*fValDiff);
+        }
+      default:
+        switch( idx ) {
+          case 0:
+            fEnv->idx = idx;
+            return fEnv->start = fFirst.invoke(fEnv);
+          default:  {
+            fEnv->idx = idx - fEnv->idx;
+            void* result = fNext.invoke(fEnv);
+            fEnv->idx = idx;
+            return result;
+          }
+        }
+    }
+  }
+  Fatal("TGenCollectionProxy","At> Logic error - no proxy object set.");
+  return 0;
+}
+
+/// Clear the emulated collection.  
+void TGenCollectionProxy::Clear(const char* opt)  {
+  if ( fEnv && fEnv->object )   {
+    if ( fPointers && opt && *opt=='f' )  {
+      size_t i, n = *(size_t*)fSize.invoke(fEnv);
+      if ( n > 0 )  {
+        for (i=0; i<n; ++i)
+          DeleteItem(true, TGenCollectionProxy::At(i));
+      }
+    }
+    fClear.invoke(fEnv);
+  }
+}
+
+/// Return the current size of the container
+UInt_t TGenCollectionProxy::Size() const   {
+  if ( fEnv && fEnv->object )   {
+    return *(size_t*)fSize.invoke(fEnv);
+  }
+  Fatal("TGenCollectionProxy","Size> Logic error - no proxy object set.");
+  return 0;
+}
+
+/// Resize the container
+void TGenCollectionProxy::Resize(UInt_t n, Bool_t force)  {
+  if ( fEnv && fEnv->object )   {
+    if ( force && fPointers )  {
+      size_t i, nold = *(size_t*)fSize.invoke(fEnv);
+      if ( n != nold )  {
+        for (i=n; i<nold; ++i)
+          DeleteItem(true, *(void**)TGenCollectionProxy::At(i));
+      }
+    }
+    MESSAGE(3, "Resize(n)" );
+    fEnv->size = n;
+    fResize.invoke(fEnv);
+    return;
+  }
+  Fatal("TGenCollectionProxy","Resize> Logic error - no proxy object set.");
+}
+
+void* TGenCollectionProxy::Allocate(UInt_t n, Bool_t /* forceDelete */ )  {
+  if ( fEnv && fEnv->object )   {
+    switch ( fSTL_type )  {
+      case TClassEdit::kSet:
+      case TClassEdit::kMultiSet:
+      case TClassEdit::kMap:
+      case TClassEdit::kMultiMap:
+        if ( fPointers ) 
+          Clear("force");
+        else
+          fClear.invoke(fEnv);
+        ++fEnv->refCount;
+        fEnv->size  = n;
+        fEnv->start = fEnv->temp = ::operator new(fValDiff*n);
+        fConstruct.invoke(fEnv);
+        return fEnv;
+      case TClassEdit::kVector:
+      case TClassEdit::kList:
+      case TClassEdit::kDeque:
+        if( fPointers )  {
+          Clear("force");
+        }
+        fEnv->size = n;
+        fResize.invoke(fEnv);
+        return fEnv;
+    }
+  }
+  return 0;
+}
+
+void TGenCollectionProxy::Commit(void* env)  {
+  switch (fSTL_type)  {
+    case TClassEdit::kVector:
+    case TClassEdit::kList:
+    case TClassEdit::kDeque:
+      return;
+    case TClassEdit::kMap:
+    case TClassEdit::kMultiMap: 
+    case TClassEdit::kSet:
+    case TClassEdit::kMultiSet: 
+      if ( env )  {
+        Env_t* e = (Env_t*)env;
+        if ( e->object )   {
+          e->start = e->temp;
+          fFeed.invoke(e);
+        }
+        fDestruct.invoke(e);
+        e->start = 0;
+        --e->refCount;
+      }
+      return;
+    default:
+      return;
+  }
+}
+
+void TGenCollectionProxy::PushProxy(void *objstart) {
+  if ( !fClass ) Initialize();
+  if ( !fProxyList.empty() )  {
+    Env_t* back = fProxyList.back();
+    if ( back->object == objstart )  {
+      back->refCount++;
+      fProxyList.push_back(back);
+      fEnv = back;
+      return;
+    }
+  }
+  Env_t* e    = new Env_t();
+  e->size     = 0;
+  e->refCount = 1;
+  e->object   = objstart;
+  e->temp     = e->start = 0;
+  ::memset(e->buff,0,sizeof(e->buff));
+  fProxyList.push_back(e);
+  fEnv = e;
+}
+
+void TGenCollectionProxy::PopProxy() {
+  if ( !fProxyList.empty() )  {
+    Env_t* e = fProxyList.back();
+    if ( --e->refCount <= 0 )  {
+      if ( e->temp ) 
+        ::operator delete(e->temp);
+      delete e;
+    }
+    fProxyList.pop_back();
+  }
+  fEnv = 0;
+}
+
+/// Call to delete/destruct individual item
+void TGenCollectionProxy::DeleteItem(bool force, void* ptr)  const  {
+  // This needs correction in the LCG dict...
+  // Pointers are not initialized to NULL!
+  if ( force && ptr )  {
+    switch (fSTL_type)  {
+      case TClassEdit::kMap:
+      case TClassEdit::kMultiMap:
+        if ( fKey->fCase&G__BIT_ISPOINTER )  {
+          if (*(void**)ptr) (*fKey->fDelete)(*(void**)ptr);
+        }
+        if ( fVal->fCase&G__BIT_ISPOINTER )  {
+          char *addr = ((char*)ptr)+fKey->fSize;
+          if (*(void**)addr) (*fVal->fDelete)(*(void**)addr);
+        }
+        // (*fValue->fDtor)(ptr); No: pair must stay intact !
+        break;
+      default:
+        if ( fVal->fCase&G__BIT_ISPOINTER )  {
+          (*fVal->fDelete)(*(void**)ptr);
+        }
+        break;
+    }
+  }
+}
+
+void TGenCollectionProxy::Streamer(TBuffer &buff)  {
+  if ( fEnv )   {
+    GetCollectionClass()->Streamer( fEnv->object, buff );
+    return;
+  }
+  Fatal("TGenCollectionProxy","Streamer> Logic error - no proxy object set.");
+}
+
+/// Streamer I/O overload
+void TGenCollectionProxy::Streamer(TBuffer &buff, void *objp, int /* siz */ ) {
+  TPushPop env(this, objp);
+  Streamer(buff);
+}
+
+/// TClassStreamer IO overload
+void TGenCollectionProxy::operator()(TBuffer &b, void *objp) {
+  Streamer(b, objp, 0); 
+}
+
diff --git a/cont/src/TGenCollectionStreamer.cxx b/cont/src/TGenCollectionStreamer.cxx
new file mode 100644
index 00000000000..e94b36a4fbe
--- /dev/null
+++ b/cont/src/TGenCollectionStreamer.cxx
@@ -0,0 +1,490 @@
+// @(#)root/cont:$Name:  $:$Id: TGenCollectionStreamer.cxx,v 1.26 2004/10/13 15:30:22 rdm Exp $
+// Author: Markus Frank 28/10/04
+
+/*************************************************************************
+ * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers.               *
+ * All rights reserved.                                                  *
+ *                                                                       *
+ * For the licensing terms see $ROOTSYS/LICENSE.                         *
+ * For the list of contributors see $ROOTSYS/README/CREDITS.             *
+ *************************************************************************/
+
+//////////////////////////////////////////////////////////////////////////
+//                                                                      //
+// TGenCollectionStreamer
+//
+// Streamer around an arbitrary container, which implements basic 
+// functionality and iteration.
+//
+// In particular this is used to implement splitting and abstract
+// element access of any container. Access to compiled code is necessary
+// to implement the abstract iteration sequence and functionality like
+// size(), clear(), resize(). resize() may be a void operation.
+//
+//////////////////////////////////////////////////////////////////////////
+
+#include "TGenCollectionStreamer.h"
+#include "TStreamerInfo.h"
+#include "TClassEdit.h"
+#include "TError.h"
+#include "TROOT.h"
+#include <iostream>
+
+/// Build a Streamer for an emulated vector whose type is 'name'.
+TGenCollectionStreamer::TGenCollectionStreamer(const TGenCollectionStreamer& copy)
+: TGenCollectionProxy(copy)
+{
+}
+
+/// Build a Streamer for a collection whose type is described by 'collectionClass'.
+TGenCollectionStreamer::TGenCollectionStreamer(Info_t info, size_t iter_size)
+: TGenCollectionProxy(info, iter_size)
+{
+}
+
+/// Standard destructor
+TGenCollectionStreamer::~TGenCollectionStreamer()   {
+}
+
+/// Virtual copy constructor
+TVirtualCollectionProxy* TGenCollectionStreamer::Generate() const  { 
+  if ( !fClass ) Initialize();
+  return new TGenCollectionStreamer(*this);
+}
+
+/// Primitive input streamer
+void TGenCollectionStreamer::ReadPrimitives(int nElements, TBuffer &b)  {
+  size_t len = fValDiff*nElements;
+  char   buffer[8096];
+  bool   feed = false;
+  void*  memory = 0;
+  StreamHelper* itm = 0;
+  fEnv->size = nElements;
+  switch ( fSTL_type )  {
+    case TClassEdit::kVector:
+      if ( fVal->fKind != EDataType(kBOOL_t) )  {
+        itm = (StreamHelper*)fResize.invoke(fEnv);
+        break;
+      }
+    default:
+      feed = true;
+      itm = (StreamHelper*)(len<sizeof(buffer) ? buffer : memory=::operator new(len));
+      break;
+  }
+  fEnv->start = itm;
+  switch( int(fValue->fKind) )   {
+    case kChar_t:    b.ReadFastArray(&itm->s_char    , nElements); break;
+    case kShort_t:   b.ReadFastArray(&itm->s_short   , nElements); break;
+    case kInt_t:     b.ReadFastArray(&itm->s_int     , nElements); break;
+    case kLong_t:    b.ReadFastArray(&itm->s_long    , nElements); break;
+    case kLong64_t:  b.ReadFastArray(&itm->s_longlong, nElements); break;
+    case kFloat_t:   b.ReadFastArray(&itm->flt       , nElements); break;
+    case kDouble_t:  b.ReadFastArray(&itm->dbl       , nElements); break;
+    case kBOOL_t:    b.ReadFastArray(&itm->boolean   , nElements); break;
+    case kUChar_t:   b.ReadFastArray(&itm->u_char    , nElements); break;
+    case kUShort_t:  b.ReadFastArray(&itm->u_short   , nElements); break;
+    case kUInt_t:    b.ReadFastArray(&itm->u_int     , nElements); break;
+    case kULong_t:   b.ReadFastArray(&itm->u_long    , nElements); break;
+    case kULong64_t: b.ReadFastArray(&itm->u_longlong, nElements); break;
+    case kDouble32_t:b.ReadFastArrayDouble32(&itm->dbl,nElements); break;
+    case kchar:
+    case kNoType_t:
+    case kOther_t:
+      Error("TGenCollectionStreamer","fType %d is not supported yet!\n",fValue->fKind);
+  }
+  if ( feed )  {    // need to feed in data...
+    fEnv->start = fFeed.invoke(fEnv);
+    if ( memory )  {
+      ::operator delete(memory);
+    }
+  }
+}
+
+/// Object input streamer
+void TGenCollectionStreamer::ReadObjects(int nElements, TBuffer &b)  {
+  bool vsn3 = b.GetInfo() && b.GetInfo()->GetOldVersion()<=3;
+  size_t len = fValDiff*nElements;
+  StreamHelper* itm = 0;
+  char   buffer[8096];
+  void*  memory = 0;
+
+  fEnv->size = nElements;
+  switch ( fSTL_type )  {
+    // Simple case: contiguous memory. get address of first, then jump.
+    case TClassEdit::kVector:
+#define DOLOOP(x) {int idx=0; while(idx<nElements) {StreamHelper* i=(StreamHelper*)(((char*)itm) + fValDiff*idx); { x ;} ++idx;} break;}
+      itm = (StreamHelper*)fResize.invoke(fEnv);
+      switch (fValue->fCase) {
+        case G__BIT_ISCLASS: 
+          DOLOOP( b.StreamObject(i,fValue->fType) );
+        case R__BIT_ISSTRING:
+          DOLOOP( i->read_std_string(b) );
+        case G__BIT_ISPOINTER|G__BIT_ISCLASS:
+          DOLOOP( i->set(b.ReadObjectAny(fValue->fType)) );
+        case G__BIT_ISPOINTER|R__BIT_ISSTRING:
+#ifndef R__AIX
+          DOLOOP( i->read_std_string_pointer(b) );
+#endif
+        case G__BIT_ISPOINTER|R__BIT_ISTSTRING|G__BIT_ISCLASS:  
+          DOLOOP( i->read_tstring_pointer(vsn3,b) );
+      }
+#undef DOLOOP
+      break;
+
+    // No contiguous memory, but resize is possible
+    // Hence accessing objects using At(i) should be not too much an overhead
+    case TClassEdit::kList:
+    case TClassEdit::kDeque:
+#define DOLOOP(x) {int idx=0; while(idx<nElements) {StreamHelper* i=(StreamHelper*)TGenCollectionProxy::At(idx); { x ;} ++idx;} break;}
+      fResize.invoke(fEnv);
+      switch (fValue->fCase) {
+        case G__BIT_ISCLASS:
+          DOLOOP( b.StreamObject(i,fValue->fType) );
+        case R__BIT_ISSTRING:
+          DOLOOP( i->read_std_string(b) );
+        case G__BIT_ISPOINTER|G__BIT_ISCLASS:
+          DOLOOP( i->set( b.ReadObjectAny(fValue->fType) ) );
+        case G__BIT_ISPOINTER|R__BIT_ISSTRING:
+#ifndef R__AIX
+          DOLOOP( i->read_std_string_pointer(b) );
+#endif
+        case G__BIT_ISPOINTER|R__BIT_ISTSTRING|G__BIT_ISCLASS:
+          DOLOOP( i->read_tstring_pointer(vsn3,b) );
+      }
+#undef DOLOOP
+      break;
+
+    // Rather troublesome case: Objects can only be fed into the container
+    // Once they are created. Need to take memory from stack or heap.
+    case TClassEdit::kMultiSet:
+    case TClassEdit::kSet:
+#define DOLOOP(x) {int idx=0; while(idx<nElements) {StreamHelper* i=(StreamHelper*)(((char*)itm) + fValDiff*idx); { x ;} ++idx;}}
+      fEnv->start = itm = (StreamHelper*)(len<sizeof(buffer) ? buffer : memory=::operator new(len));
+      fConstruct.invoke(fEnv);
+      switch ( fValue->fCase ) {
+        case G__BIT_ISCLASS:
+          DOLOOP( b.StreamObject(i,fValue->fType) )
+          fFeed.invoke(fEnv);
+          fDestruct.invoke(fEnv);
+          break;
+        case R__BIT_ISSTRING:
+          DOLOOP( i->read_std_string(b) )
+          fFeed.invoke(fEnv);
+          fDestruct.invoke(fEnv);
+          break;
+        case G__BIT_ISPOINTER|G__BIT_ISCLASS:
+          DOLOOP( i->set(b.ReadObjectAny(fValue->fType)) );
+          fFeed.invoke(fEnv);
+          break;
+        case G__BIT_ISPOINTER|R__BIT_ISSTRING:
+#ifndef R__AIX
+          DOLOOP( i->read_std_string_pointer(b) )
+          fFeed.invoke(fEnv);
+#endif
+          break;
+        case G__BIT_ISPOINTER|R__BIT_ISTSTRING|G__BIT_ISCLASS:
+          DOLOOP( i->read_tstring_pointer(vsn3,b) )
+          fFeed.invoke(fEnv);
+          break;
+      }
+#undef DOLOOP
+      break;
+    default:
+      break;
+  }
+  if ( memory ) {
+    ::operator delete(memory);
+  }
+}
+
+/// Map input streamer
+void TGenCollectionStreamer::ReadMap(int nElements, TBuffer &b)  {
+  bool vsn3 = b.GetInfo() && b.GetInfo()->GetOldVersion()<=3;
+  size_t len = fValDiff*nElements;
+  Value  *v;
+  char buffer[8096], *addr, *temp;
+  void* memory = 0;
+  StreamHelper* i;
+  float f;
+  fEnv->size  = nElements;
+  fEnv->start = (len<sizeof(buffer) ? buffer : memory=::operator new(len));
+  addr = temp = (char*)fEnv->start;
+  fConstruct.invoke(fEnv);
+  for ( int loop, idx = 0; idx < nElements; ++idx )  {
+    addr = temp + fValDiff*idx;
+    v = fKey;
+    for ( loop=0; loop<2; loop++ )  {
+      i = (StreamHelper*)addr;
+      switch (v->fCase) {
+        case G__BIT_ISFUNDAMENTAL:  // Only handle primitives this way
+        case G__BIT_ISENUM:
+          switch( int(v->fKind) )   {
+            case kChar_t:    b >> i->s_char;      break;
+            case kShort_t:   b >> i->s_short;     break;
+            case kInt_t:     b >> i->s_int;       break;
+            case kLong_t:    b >> i->s_long;      break;
+            case kLong64_t:  b >> i->s_longlong;  break;
+            case kFloat_t:   b >> i->flt;         break;
+            case kDouble_t:  b >> i->dbl;         break;
+            case kBOOL_t:    b >> i->boolean;     break;
+            case kUChar_t:   b >> i->u_char;      break;
+            case kUShort_t:  b >> i->u_short;     break;
+            case kUInt_t:    b >> i->u_int;       break;
+            case kULong_t:   b >> i->u_long;      break;
+            case kULong64_t: b >> i->u_longlong;  break;
+            case kDouble32_t:b >> f; 
+                             i->dbl = double(f);  break;
+            case kchar:
+            case kNoType_t:
+            case kOther_t:
+              Error("TGenCollectionStreamer","fType %d is not supported yet!\n",v->fKind);
+          }
+          break;
+        case G__BIT_ISCLASS:
+          b.StreamObject(i,v->fType);
+          break;
+        case R__BIT_ISSTRING:
+          i->read_std_string(b);
+          break;
+        case G__BIT_ISPOINTER|G__BIT_ISCLASS:
+          i->set(b.ReadObjectAny(v->fType));
+          break;
+        case G__BIT_ISPOINTER|R__BIT_ISSTRING:
+#ifndef R__AIX
+          i->read_std_string_pointer(b);
+#endif
+          break;
+        case G__BIT_ISPOINTER|R__BIT_ISTSTRING|G__BIT_ISCLASS:
+          i->read_tstring_pointer(vsn3,b);
+          break;
+      }
+      v = fVal;
+      addr += fValOffset;
+    }
+  }
+  fFeed.invoke(fEnv);
+  fDestruct.invoke(fEnv);
+  if ( memory ) {
+    ::operator delete(memory);
+  }
+}
+
+/// Primitive output streamer
+void TGenCollectionStreamer::WritePrimitives(int nElements, TBuffer &b)  {
+  size_t len = fValDiff*nElements;
+  char   buffer[8192];
+  void*  memory  = 0;
+  StreamHelper* itm = 0;
+
+  switch ( fSTL_type )  {
+    case TClassEdit::kVector:
+      if ( fVal->fKind != EDataType(kBOOL_t) )  {
+        itm = (StreamHelper*)(fEnv->start = fFirst.invoke(fEnv));
+        break;
+      }
+    default:
+      fEnv->start = itm = (StreamHelper*) (len<sizeof(buffer) ? buffer : memory=::operator new(len));
+      fCollect.invoke(fEnv);
+      break;
+  }
+  switch( int(fValue->fKind) )   {
+    case kChar_t:    b.WriteFastArray(&itm->s_char    , nElements); break;
+    case kShort_t:   b.WriteFastArray(&itm->s_short   , nElements); break;
+    case kInt_t:     b.WriteFastArray(&itm->s_int     , nElements); break;
+    case kLong_t:    b.WriteFastArray(&itm->s_long    , nElements); break;
+    case kLong64_t:  b.WriteFastArray(&itm->s_longlong, nElements); break;
+    case kFloat_t:   b.WriteFastArray(&itm->flt       , nElements); break;
+    case kDouble_t:  b.WriteFastArray(&itm->dbl       , nElements); break;
+    case kBOOL_t:    b.WriteFastArray(&itm->boolean   , nElements); break;
+    case kUChar_t:   b.WriteFastArray(&itm->u_char    , nElements); break;
+    case kUShort_t:  b.WriteFastArray(&itm->u_short   , nElements); break;
+    case kUInt_t:    b.WriteFastArray(&itm->u_int     , nElements); break;
+    case kULong_t:   b.WriteFastArray(&itm->u_long    , nElements); break;
+    case kULong64_t: b.WriteFastArray(&itm->u_longlong, nElements); break;
+    case kDouble32_t:b.WriteFastArrayDouble32(&itm->dbl,nElements); break;
+    case kchar:
+    case kNoType_t:
+    case kOther_t:
+      Error("TGenCollectionStreamer","fType %d is not supported yet!\n",fValue->fKind);
+  }
+  if ( memory )  {
+    ::operator delete(memory);
+  }
+}
+
+/// Object output streamer
+void TGenCollectionStreamer::WriteObjects(int nElements, TBuffer &b)  {
+  StreamHelper* itm = 0;
+  switch(fSTL_type)  {
+    // Simple case: contiguous memory. get address of first, then jump.
+    case TClassEdit::kVector:
+#define DOLOOP(x) {int idx=0; while(idx<nElements) {StreamHelper* i=(StreamHelper*)(((char*)itm) + fValDiff*idx); { x ;} ++idx;} break;}
+      itm = (StreamHelper*)fFirst.invoke(fEnv);
+      switch (fValue->fCase) {
+        case G__BIT_ISCLASS: 
+          DOLOOP( b.StreamObject(i,fValue->fType));
+          break;
+        case R__BIT_ISSTRING:
+          DOLOOP( TString(i->c_str()).Streamer(b));
+          break;
+        case G__BIT_ISPOINTER|G__BIT_ISCLASS:
+          DOLOOP( b.WriteObjectAny(i->ptr(),fValue->fType) );
+          break;
+        case R__BIT_ISSTRING|G__BIT_ISPOINTER:
+#ifndef R__AIX
+          DOLOOP( i->write_std_string_pointer(b));
+#endif
+          break;
+        case R__BIT_ISTSTRING|G__BIT_ISCLASS|G__BIT_ISPOINTER:
+          DOLOOP( i->write_tstring_pointer(b));
+          break;
+      }
+#undef DOLOOP
+      break;
+
+    // No contiguous memory, but resize is possible
+    // Hence accessing objects using At(i) should be not too much an overhead
+    case TClassEdit::kList:
+    case TClassEdit::kDeque:
+    case TClassEdit::kMultiSet:
+    case TClassEdit::kSet:
+#define DOLOOP(x) {int idx=0; while(idx<nElements) {StreamHelper* i=(StreamHelper*)TGenCollectionProxy::At(idx); { x ;} ++idx;} break;}
+      switch (fValue->fCase) {
+        case G__BIT_ISCLASS: 
+          DOLOOP( b.StreamObject(i,fValue->fType));
+        case R__BIT_ISSTRING:
+          DOLOOP( TString(i->c_str()).Streamer(b));
+        case G__BIT_ISPOINTER|G__BIT_ISCLASS:
+          DOLOOP( b.WriteObjectAny(i->ptr(),fValue->fType) );
+        case R__BIT_ISSTRING|G__BIT_ISPOINTER:
+#ifndef R__AIX
+          DOLOOP( i->write_std_string_pointer(b));
+#endif
+        case R__BIT_ISTSTRING|G__BIT_ISCLASS|G__BIT_ISPOINTER:
+          DOLOOP( i->write_tstring_pointer(b));
+      }
+#undef DOLOOP
+      break;
+    default:
+      break;
+  }
+}
+
+/// Map output streamer
+void TGenCollectionStreamer::WriteMap(int nElements, TBuffer &b)  {
+  StreamHelper* i;
+  Value  *v;
+
+  for (int loop, idx = 0; idx < nElements; ++idx )  {
+    char* addr = (char*)TGenCollectionProxy::At(idx);
+    v = fKey;
+    for ( loop = 0; loop<2; ++loop )  {
+      i = (StreamHelper*)addr;
+      switch (v->fCase) {
+        case G__BIT_ISFUNDAMENTAL:  // Only handle primitives this way
+        case G__BIT_ISENUM:
+          switch( int(v->fKind) )   {
+            case kChar_t:    b << i->s_char;      break;
+            case kShort_t:   b << i->s_short;     break;
+            case kInt_t:     b << i->s_int;       break;
+            case kLong_t:    b << i->s_long;      break;
+            case kLong64_t:  b << i->s_longlong;  break;
+            case kFloat_t:   b << i->flt;         break;
+            case kDouble_t:  b << i->dbl;         break;
+            case kBOOL_t:    b << i->boolean;     break;
+            case kUChar_t:   b << i->u_char;      break;
+            case kUShort_t:  b << i->u_short;     break;
+            case kUInt_t:    b << i->u_int;       break;
+            case kULong_t:   b << i->u_long;      break;
+            case kULong64_t: b << i->u_longlong;  break;
+            case kDouble32_t:b << float(i->dbl);  break;
+            case kchar:
+            case kNoType_t:
+            case kOther_t:
+              Error("TGenCollectionStreamer","fType %d is not supported yet!\n",v->fKind);
+          }
+          break;
+        case G__BIT_ISCLASS: 
+          b.StreamObject(i,v->fType);
+          break;
+        case R__BIT_ISSTRING:
+          TString(i->c_str()).Streamer(b);
+          break;
+        case G__BIT_ISPOINTER|G__BIT_ISCLASS:
+          b.WriteObjectAny(i->ptr(),v->fType);
+          break;
+        case R__BIT_ISSTRING|G__BIT_ISPOINTER:
+#ifndef R__AIX
+          i->write_std_string_pointer(b);
+#endif
+          break;
+        case R__BIT_ISTSTRING|G__BIT_ISCLASS|G__BIT_ISPOINTER:
+          i->write_tstring_pointer(b);
+          break;
+      }
+      addr += fValOffset;
+      v = fVal;
+    }
+  }
+}
+
+/// TClassStreamer IO overload
+void TGenCollectionStreamer::Streamer(TBuffer &b) {
+  if ( b.IsReading() ) {  //Read mode 
+    int nElements = 0;
+    b >> nElements;
+    if ( fEnv->object )   {
+      TGenCollectionProxy::Clear("force");
+    }
+    if ( nElements > 0 )  {
+      switch(fSTL_type)  {
+        case TClassEdit::kVector:
+        case TClassEdit::kList:
+        case TClassEdit::kDeque:
+        case TClassEdit::kMultiSet:
+        case TClassEdit::kSet:
+          switch (fValue->fCase) {
+            case G__BIT_ISFUNDAMENTAL:  // Only handle primitives this way
+            case G__BIT_ISENUM:
+              ReadPrimitives(nElements, b); 
+              return;
+            default:
+              ReadObjects(nElements, b);
+              return;
+          }
+          break;
+        case TClassEdit::kMap:
+        case TClassEdit::kMultiMap:
+          ReadMap(nElements, b);
+          break;
+      }
+    }
+  }
+  else {     // Write case
+    int nElements = fEnv->object ? *(size_t*)fSize.invoke(fEnv) : 0;
+    b << nElements;
+    if ( nElements > 0 )  {
+      switch(fSTL_type)  {
+        case TClassEdit::kVector:
+        case TClassEdit::kList:
+        case TClassEdit::kDeque:
+        case TClassEdit::kMultiSet:
+        case TClassEdit::kSet:
+          switch (fValue->fCase) {
+            case G__BIT_ISFUNDAMENTAL:  // Only handle primitives this way
+            case G__BIT_ISENUM:
+              WritePrimitives(nElements, b);
+              return;
+            default:
+              WriteObjects(nElements, b);
+              return;
+          }
+          break;
+        case TClassEdit::kMap:
+        case TClassEdit::kMultiMap:
+          WriteMap(nElements, b);
+          break;
+      }
+    }
+  }
+}
diff --git a/io/inc/TEmulatedCollectionProxy.h b/io/inc/TEmulatedCollectionProxy.h
new file mode 100644
index 00000000000..6df63a42a23
--- /dev/null
+++ b/io/inc/TEmulatedCollectionProxy.h
@@ -0,0 +1,110 @@
+// @(#)root/cont:$Name:  $:$Id: TEmulatedCollectionProxy.h,v 1.15 2004/10/13 15:30:22 rdm Exp $
+// Author: Markus Frank  28/10/04
+
+/*************************************************************************
+ * Copyright (C) 1995-2004, Rene Brun and Fons Rademakers.               *
+ * All rights reserved.                                                  *
+ *                                                                       *
+ * For the licensing terms see $ROOTSYS/LICENSE.                         *
+ * For the list of contributors see $ROOTSYS/README/CREDITS.             *
+ *************************************************************************/
+#ifndef ROOT_TEmulatedCollectionProxy
+#define ROOT_TEmulatedCollectionProxy
+
+#ifndef __CINT__
+
+//////////////////////////////////////////////////////////////////////////
+//                                                                      //
+// TEmulatedCollectionProxy
+//
+// Streamer around an arbitrary STL like container, which implements basic 
+// container functionality.
+//
+// Note:
+// Although this class contains all the setup necessary to deal
+// with maps, the map-like functionality is NOT supported.
+// For optimization reasons this functionality is put into
+// the class TEmulatedMapProxy.
+//
+//////////////////////////////////////////////////////////////////////////
+
+#include "TGenCollectionProxy.h"
+
+class TEmulatedCollectionProxy : public TGenCollectionProxy  {
+
+  /// Friend declaration
+  friend class TCollectionProxy;
+
+public:
+  /// Container type definition
+  typedef std::vector<char>  Cont_t;
+  /// Pointer to container type
+  typedef Cont_t            *PCont_t;
+protected:
+
+  /// Some hack to avoid const-ness
+  virtual TGenCollectionProxy* InitializeEx();
+
+  /// Object input streamer
+  void ReadItems(int nElements, TBuffer &b);
+
+  /// Object output streamer
+  void WriteItems(int nElements, TBuffer &b);
+
+  /// Shrink the container
+  void Shrink(UInt_t nCurr, UInt_t left, Bool_t force);
+
+  /// Expand the container
+  void Expand(UInt_t nCurr, UInt_t left);
+
+public:
+  /// Virtual copy constructor
+  virtual TVirtualCollectionProxy* Generate() const;
+
+  /// Copy constructor
+  TEmulatedCollectionProxy(const TEmulatedCollectionProxy& copy);
+
+  /// Initializing constructor
+  TEmulatedCollectionProxy(const char* cl_name);
+
+  /// Standard destructor
+  virtual ~TEmulatedCollectionProxy();
+
+  /// Virtual constructor
+  virtual void* New()   const             {  return new Cont_t;         }
+
+  /// Virtual in-place constructor
+  virtual void* New(void* memory)   const {  return new(memory) Cont_t; }
+
+  /// TVirtualCollectionProxy overload: Return the sizeof the collection object. 
+  virtual UInt_t Sizeof() const           {  return sizeof(Cont_t);     }
+
+  /// Return the address of the value at index 'idx'
+  virtual void *At(UInt_t idx);
+
+  /// Clear the container
+  virtual void Clear(const char *opt = "");
+
+  /// Resize the container
+  virtual void Resize(UInt_t n, Bool_t force_delete);
+
+  /// Return the current size of the container
+  virtual UInt_t Size() const;                        
+
+  /// Block allocation of containees
+  virtual void* Allocate(UInt_t n, Bool_t forceDelete);
+
+  /// Block commit of containees
+  virtual void Commit(void* env);
+
+  /// Streamer for I/O handling
+  virtual void Streamer(TBuffer &refBuffer);
+
+  /// Streamer I/O overload
+  virtual void Streamer(TBuffer &buff, void *pObj, int siz) {
+    TGenCollectionProxy::Streamer(buff,pObj,siz);
+  }
+};
+
+#endif
+#endif
diff --git a/io/inc/TEmulatedMapProxy.h b/io/inc/TEmulatedMapProxy.h
new file mode 100644
index 00000000000..43d266525c3
--- /dev/null
+++ b/io/inc/TEmulatedMapProxy.h
@@ -0,0 +1,66 @@
+// @(#)root/cont:$Name:  $:$Id: TEmulatedMapProxy.h,v 1.15 2004/10/13 15:30:22 rdm Exp $
+// Author: Markus Frank  28/10/04
+
+/*************************************************************************
+ * Copyright (C) 1995-2004, Rene Brun and Fons Rademakers.               *
+ * All rights reserved.                                                  *
+ *                                                                       *
+ * For the licensing terms see $ROOTSYS/LICENSE.                         *
+ * For the list of contributors see $ROOTSYS/README/CREDITS.             *
+ *************************************************************************/
+#ifndef ROOT_TEmulatedMapProxy
+#define ROOT_TEmulatedMapProxy
+#define ROOT_TGenCollectionStreamer
+
+#ifndef __CINT__
+
+//////////////////////////////////////////////////////////////////////////
+//                                                                      //
+// TEmulatedMapProxy
+//
+// Streamer around an arbitrary STL like container, which implements basic 
+// container functionality.
+//
+//////////////////////////////////////////////////////////////////////////
+
+#include "TEmulatedCollectionProxy.h"
+
+class TEmulatedMapProxy : public TEmulatedCollectionProxy  {
+
+protected:
+  /// Map input streamer
+  void ReadMap(int nElements, TBuffer &b);
+
+  /// Map output streamer
+  void WriteMap(int nElements, TBuffer &b);
+
+public:
+  /// Virtual copy constructor
+  virtual TVirtualCollectionProxy* Generate() const;
+
+  /// Copy constructor
+  TEmulatedMapProxy(const TEmulatedMapProxy& copy);
+
+  /// Initializing constructor
+  TEmulatedMapProxy(const char* cl_name);
+
+  /// Standard destructor
+  virtual ~TEmulatedMapProxy();
+
+  /// Return the address of the value at index 'idx'
+  virtual void *At(UInt_t idx);
+
+  /// Return the current size of the container
+  virtual UInt_t Size() const;                        
+
+  /// Streamer for I/O handling
+  virtual void Streamer(TBuffer &refBuffer);
+
+  /// Streamer I/O overload
+  virtual void Streamer(TBuffer &buff, void *pObj, int siz) {
+    TEmulatedCollectionProxy::Streamer(buff,pObj,siz);
+  }
+};
+
+#endif
+#endif
diff --git a/io/inc/TGenCollectionProxy.h b/io/inc/TGenCollectionProxy.h
new file mode 100644
index 00000000000..595b0ad5282
--- /dev/null
+++ b/io/inc/TGenCollectionProxy.h
@@ -0,0 +1,311 @@
+// @(#)root/cont:$Name:  $:$Id: TGenCollectionProxy.h,v 1.15 2004/10/13 15:30:22 rdm Exp $
+// Author: Markus Frank  28/10/04
+
+/*************************************************************************
+ * Copyright (C) 1995-2004, Rene Brun and Fons Rademakers.               *
+ * All rights reserved.                                                  *
+ *                                                                       *
+ * For the licensing terms see $ROOTSYS/LICENSE.                         *
+ * For the list of contributors see $ROOTSYS/README/CREDITS.             *
+ *************************************************************************/
+#ifndef ROOT_TGenCollectionProxy
+#define ROOT_TGenCollectionProxy
+#ifndef __CINT__
+
+//////////////////////////////////////////////////////////////////////////
+//                                                                      //
+// TGenCollectionProxy
+//
+// Proxy around an arbitrary container, which implements basic 
+// functionality and iteration.
+//
+// In particular this is used to implement splitting and abstract
+// element access of any container. Access to compiled code is necessary
+// to implement the abstract iteration sequence and functionality like
+// size(), clear(), resize(). resize() may be a void operation.
+//
+//////////////////////////////////////////////////////////////////////////
+
+#include "TVirtualCollectionProxy.h"
+#include "TCollectionProxy.h"
+#include <typeinfo>
+#include <string>
+
+class TGenCollectionProxy 
+  : public TVirtualCollectionProxy,
+    public TCollectionProxy
+{
+
+  /// Friend declaration
+  friend class TCollectionProxy;
+
+public:
+
+  enum {
+    // Those 'bits' are used in conjunction with CINT's bit to store the 'type'
+    // info into one int
+    R__BIT_ISSTRING   = 0x20000000,  // We can optimized a value operation when the content are strings
+    R__BIT_ISTSTRING  = 0x40000000,
+    kBOOL_t = 21
+  };
+
+
+  /** @class TGenCollectionProxy::Value TGenCollectionProxy.h TGenCollectionProxy.h 
+    *
+    * Small helper to describe the Value_type or the key_type
+    * of an STL container.
+    *
+    * @author  M.Frank
+    * @version 1.0
+    * @date    10/10/2004
+    */
+  struct Value  {
+    ROOT::NewFunc_t fCtor;      // Method cache for containee constructor
+    ROOT::DesFunc_t fDtor;      // Method cache for containee destructor
+    ROOT::DelFunc_t fDelete;    // Method cache for containee delete
+    unsigned int    fCase;      // type of data of Value_type
+    TClass*         fType;      // TClass of Value_type in collection
+    EDataType       fKind;      // kind of ROOT-fundamental type 
+    size_t          fSize;      // fSize of the contained object
+    Value(const Value& inside);
+    Value(const std::string& info);
+  };
+
+  /**@class StreamHelper
+    *
+    * Helper class to facilitate I/O
+    *
+    * @author  M.Frank
+    * @version 1.0
+    * @date    10/10/2004
+    */
+  union StreamHelper  {
+    bool         boolean;
+    Char_t       s_char;
+    Short_t      s_short;
+    Int_t        s_int;
+    Long_t       s_long;
+    Long64_t     s_longlong;
+    Float_t      flt;
+    Double_t     dbl;
+    UChar_t      u_char;
+    UShort_t     u_short;
+    UInt_t       u_int;
+    ULong_t      u_long;
+    ULong64_t    u_longlong;
+    void*        p_void;
+    void**       pp_void;
+    char*        kchar;
+    TString*     tstr;
+    void* ptr()  {
+      return *(&this->p_void);
+    }
+    std::string* str()  {
+      return (std::string*)this;
+    }
+    const char* c_str()  {
+      return ((std::string*)this)->c_str();
+    }
+    const char* c_pstr()  {
+      return (*(std::string**)this)->c_str();
+    }
+    void set(void* p)  {
+      *(&this->p_void) = p;
+    }
+    void read_std_string(TBuffer& b) {
+      TString s;
+      s.Streamer(b);
+      ((std::string*)this)->assign(s.Data());
+    }
+    void* read_tstring(TBuffer& b)  {
+      *((TString*)this) = "";
+      ((TString*)this)->Streamer(b);
+      return this;
+    }
+    void read_std_string_pointer(TBuffer& b) {
+      TString s;
+      std::string* str = (std::string*) (ptr() ? ptr() : new std::string());
+      s.Streamer(b);
+      *str = s;
+      set(str);
+    }
+    void write_std_string_pointer(TBuffer& b)  {
+      const char* c = (const char*)(ptr() ? (*(std::string**)this)->c_str() : "");
+      TString(c).Streamer(b);
+    }
+    void read_any_object(Value* v, TBuffer& b)  {
+      void* p = ptr();
+      if ( p )  {
+        if ( v->fDelete )  {    // Compiled content: call Destructor
+          (*v->fDelete)(p);
+        }
+        else if ( v->fType )  { // Emulated content: call TClass::Delete
+          v->fType->Destructor(p);
+        }
+        else if ( v->fDtor )  {
+          (*v->fDtor)(p);
+          ::operator delete(p);
+        }
+        else  {
+          ::operator delete(p);
+        }
+      }
+      set( b.ReadObjectAny(v->fType) );
+    }
+
+    void read_tstring_pointer(bool vsn3, TBuffer& b)  {
+      TString* s = (TString*)ptr();
+      if ( vsn3 )  {
+        if ( !s ) s = new TString();
+        s->Replace(0, s->Length(), 0, 0);
+        s->Streamer(b);
+        set(s);
+        return;
+      }
+      if ( s ) delete s;
+      set( b.ReadObjectAny(TString::Class()) );
+    }
+    void write_tstring_pointer(TBuffer& b)  {
+      b.WriteObjectAny(ptr(), TString::Class());
+    }
+  };
+
+  /** @class TGenCollectionProxy::Method TGenCollectionProxy.h TGenCollectionProxy.h 
+    *
+    * Small helper to execute (compiler) generated function for the
+    * access to STL or other containers.
+    *
+    * @author  M.Frank
+    * @version 1.0
+    * @date    10/10/2004
+    */
+  struct Method  {
+    typedef void* (*Call_t)(void*);
+    Call_t call;
+    Method() : call(0)                       {      }
+    Method(Call_t c) : call(c)               {      }
+    Method(const Method& m) : call(m.call)   {      }
+    void* invoke(void* obj) const { return (*call)(obj); }
+  };
+
+protected:
+  typedef ROOT::Environ<char[64]> Env_t;
+  typedef std::vector<Env_t*>     Proxies_t;
+
+  std::string   fName;      // Name of the class being proxied.    
+  bool          fPointers;  // Flag to indicate if containee has pointers (key or value)
+  Method        fClear;     // Method cache for container accessors: clear container
+  Method        fSize;      // Container accessors: size of container
+  Method        fResize;    // Container accessors: resize container
+  Method        fFirst;     // Container accessors: generic iteration: first
+  Method        fNext;      // Container accessors: generic iteration: next
+  Method        fConstruct; // Container accessors: block construct
+  Method        fDestruct;  // Container accessors: block destruct
+  Method        fFeed;      // Container accessors: block feed
+  Method        fCollect;   // Method to collect objects from container
+  Value*        fValue;     // Descriptor of the container value type
+  Value*        fVal;       // Descriptor of the Value_type
+  Value*        fKey;       // Descriptor of the key_type
+  Env_t*        fEnv;       // Address of the currently proxied object
+  int           fValOffset; // Offset from key to value (in maps)
+  int           fValDiff;   // Offset between two consecutive value_types (memory layout).
+  Proxies_t     fProxyList; // Stack of recursive proxies 
+  int           fSTL_type;  // STL container type
+  Info_t        fTypeinfo;  // Type information
+
+  /// Late initialization of collection proxy
+  virtual TGenCollectionProxy* Initialize() const;
+  /// Some hack to avoid const-ness
+  virtual TGenCollectionProxy* InitializeEx();
+  /// Call to delete/destruct individual contained item
+  virtual void DeleteItem(bool force, void* ptr) const;
+  /// Allow to check function pointers
+  void CheckFunctions()  const;
+
+public:
+
+  /// Virtual copy constructor
+  virtual TVirtualCollectionProxy* Generate() const;
+
+  /// Copy constructor
+  TGenCollectionProxy(const TGenCollectionProxy& copy);
+
+  /// Initializing constructor
+  TGenCollectionProxy(Info_t typ, size_t iter_size);
+
+  /// Standard destructor
+  virtual ~TGenCollectionProxy();
+
+  /// Return a pointer to the TClass representing the container
+  virtual TClass *GetCollectionClass();
+
+  /// Return the sizeof the collection object. 
+  virtual UInt_t Sizeof() const;
+
+  /// Push new proxy environment
+  virtual void PushProxy(void *objstart);
+
+  /// Pop old proxy environment
+  virtual void PopProxy();
+
+  /// Return true if the content is of type 'pointer to'
+  virtual Bool_t HasPointers() const;
+
+  /// Return a pointer to the TClass representing the content.
+  virtual TClass *GetValueClass();
+
+  /// Set pointer to the TClass representing the content.
+  virtual void SetValueClass(TClass *newcl);
+
+  /// If the content is a simple numerical value, return its type (see TDataType)
+  virtual EDataType GetType();
+
+  /// Return the address of the value at index 'idx'
+  virtual void *At(UInt_t idx);
+
+  /// Clear the container
+  virtual void Clear(const char *opt = "");
+
+  /// Resize the container
+  virtual void Resize(UInt_t n, Bool_t force_delete);
+
+  /// Return the current size of the container
+  virtual UInt_t Size() const;                        
+
+  /// Block allocation of containees
+  virtual void* Allocate(UInt_t n, Bool_t forceDelete);
+
+  /// Block commit of containees
+  virtual void Commit(void* env);
+
+  /// Streamer function
+  virtual void Streamer(TBuffer &refBuffer);
+
+  /// Streamer I/O overload
+  virtual void Streamer(TBuffer &refBuffer, void *pObject, int siz);
+
+  /// TClassStreamer I/O overload
+  virtual void operator()(TBuffer &refBuffer, void *pObject);
+};
+
+template <typename T> 
+struct AnyCollectionProxy : public TGenCollectionProxy  {
+  AnyCollectionProxy()
+  : TGenCollectionProxy(typeid(T::Cont_t),sizeof(T::Iter_t))
+  {
+    fValDiff        = sizeof(T::Value_t);
+    fValOffset      = T::value_offset();
+    fSize.call      = T::size;
+    fResize.call    = T::resize;
+    fNext.call      = T::next;
+    fFirst.call     = T::first;
+    fClear.call     = T::clear;
+    fConstruct.call = T::construct;
+    fDestruct.call  = T::destruct;
+    fFeed.call      = T::feed;
+    CheckFunctions();
+  }
+  virtual ~AnyCollectionProxy() {  }
+};
+#endif
+#endif
diff --git a/io/inc/TGenCollectionStreamer.h b/io/inc/TGenCollectionStreamer.h
new file mode 100644
index 00000000000..862ffaca353
--- /dev/null
+++ b/io/inc/TGenCollectionStreamer.h
@@ -0,0 +1,89 @@
+// @(#)root/cont:$Name:  $:$Id: TGenCollectionStreamer.h,v 1.15 2004/10/13 15:30:22 rdm Exp $
+// Author: Markus Frank  28/10/04
+
+/*************************************************************************
+ * Copyright (C) 1995-2004, Rene Brun and Fons Rademakers.               *
+ * All rights reserved.                                                  *
+ *                                                                       *
+ * For the licensing terms see $ROOTSYS/LICENSE.                         *
+ * For the list of contributors see $ROOTSYS/README/CREDITS.             *
+ *************************************************************************/
+#ifndef ROOT_TGenCollectionStreamer
+#define ROOT_TGenCollectionStreamer
+
+#ifndef __CINT__
+
+//////////////////////////////////////////////////////////////////////////
+//                                                                      //
+// TGenCollectionStreamer
+//
+// Streamer around an arbitrary STL like container, which implements basic 
+// container functionality.
+//
+//////////////////////////////////////////////////////////////////////////
+
+#include "TGenCollectionProxy.h"
+
+class TGenCollectionStreamer : public TGenCollectionProxy  {
+
+protected:
+  /// Stream I/O: Map input streamer
+  void ReadMap(int nElements, TBuffer &b);
+  /// Stream I/O: Object input streamer
+  void ReadObjects(int nElements, TBuffer &b);
+  /// Stream I/O: Primitive input streamer
+  void ReadPrimitives(int nElements, TBuffer &b);
+  /// Stream I/O: Map output streamer
+  void WriteMap(int nElements, TBuffer &b);
+  /// Stream I/O: Object output streamer
+  void WriteObjects(int nElements, TBuffer &b);
+  /// Stream I/O: Primitive output streamer
+  void WritePrimitives(int nElements, TBuffer &b);
+
+public:
+  /// Virtual copy constructor
+  virtual TVirtualCollectionProxy* Generate() const;
+
+  /// Copy constructor
+  TGenCollectionStreamer(const TGenCollectionStreamer& copy);
+
+  /// Initializing constructor
+  TGenCollectionStreamer(Info_t typ, size_t iter_size);
+
+  /// Standard destructor
+  virtual ~TGenCollectionStreamer();
+
+  /// Streamer I/O overload
+  virtual void Streamer(TBuffer &refBuffer);
+
+  /// Streamer I/O overload
+  virtual void Streamer(TBuffer &buff, void *pObj, int siz)  {
+    TGenCollectionProxy::Streamer(buff, pObj, siz);
+  }
+};
+
+template <typename T> 
+struct AnyCollectionStreamer : public TGenCollectionStreamer  {
+  AnyCollectionStreamer()
+  : TGenCollectionStreamer(typeid(T::Cont_t),sizeof(T::Iter_t))  {
+    fValDiff        = sizeof(T::Value_t);
+    fValOffset      = T::value_offset();
+    fSize.call      = T::size;
+    fFirst.call     = T::first;
+    fNext.call      = T::next;
+    fClear.call     = T::clear;
+    fResize.call    = T::resize;
+    fCollect.call   = T::collect;
+    fConstruct.call = T::construct;
+    fDestruct.call  = T::destruct;
+    fFeed.call      = T::feed;
+    CheckFunctions();
+  }
+  virtual ~AnyCollectionStreamer() {  }
+};
+
+// Forward declaration in the event of later seperation
+typedef TGenCollectionStreamer TGenMapStreamer;
+
+#endif
+#endif
diff --git a/io/src/TEmulatedCollectionProxy.cxx b/io/src/TEmulatedCollectionProxy.cxx
new file mode 100644
index 00000000000..834d5ca9762
--- /dev/null
+++ b/io/src/TEmulatedCollectionProxy.cxx
@@ -0,0 +1,437 @@
+// @(#)root/cont:$Name:  $:$Id: TEmulatedCollectionProxy.cxx,v 1.26 2004/10/13 15:30:22 rdm Exp $
+// Author: Markus Frank 28/10/04
+
+/*************************************************************************
+ * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers.               *
+ * All rights reserved.                                                  *
+ *                                                                       *
+ * For the licensing terms see $ROOTSYS/LICENSE.                         *
+ * For the list of contributors see $ROOTSYS/README/CREDITS.             *
+ *************************************************************************/
+
+//////////////////////////////////////////////////////////////////////////
+//                                                                      //
+// TEmulatedCollectionProxy
+//
+// Streamer around an arbitrary container, which implements basic 
+// functionality and iteration.
+//
+// In particular this is used to implement splitting and abstract
+// element access of any container. Access to compiled code is necessary
+// to implement the abstract iteration sequence and functionality like
+// size(), clear(), resize(). resize() may be a void operation.
+//
+//////////////////////////////////////////////////////////////////////////
+
+#include "TEmulatedCollectionProxy.h"
+#include "TStreamerInfo.h"
+#include "TClassEdit.h"
+#include "TError.h"
+#include "TROOT.h"
+#include <iostream>
+
+/// Build a Streamer for an emulated vector whose type is 'name'.
+TEmulatedCollectionProxy::TEmulatedCollectionProxy(const TEmulatedCollectionProxy& copy)
+: TGenCollectionProxy(copy)
+{
+}
+
+/// Build a Streamer for a collection whose type is described by 'collectionClass'.
+TEmulatedCollectionProxy::TEmulatedCollectionProxy(const char* cl_name)
+: TGenCollectionProxy(typeid(std::vector<char>), sizeof(std::vector<char>::iterator))
+{
+  fName = cl_name;
+  Initialize();
+}
+
+/// Standard destructor
+TEmulatedCollectionProxy::~TEmulatedCollectionProxy()   {
+}
+
+/// Virtual copy constructor
+TVirtualCollectionProxy* TEmulatedCollectionProxy::Generate() const  { 
+  if ( !fClass ) Initialize();
+  return new TEmulatedCollectionProxy(*this);
+}
+
+/// Proxy initializer
+TGenCollectionProxy *TEmulatedCollectionProxy::InitializeEx() { 
+  fClass = gROOT->GetClass(fName.c_str());
+  fEnv = 0;
+  fKey = 0;
+  if ( fClass )  {
+    int nested = 0;
+    std::vector<std::string> inside;
+    fPointers  = false;
+    int num = TClassEdit::GetSplit(fName.c_str(),inside,nested);
+    if ( num > 1 )  {
+      std::string nam;
+      fSTL_type = TClassEdit::STLKind(inside[0].c_str());
+      // std::cout << "Initialized " << typeid(*this).name() << ":" << fName << std::endl;
+      switch ( fSTL_type )  {
+        case TClassEdit::kMap:
+        case TClassEdit::kMultiMap:
+          fKey   = new Value(inside[1]);
+          fVal   = new Value(inside[2]);
+          fPointers |= 0 != (fKey->fCase&G__BIT_ISPOINTER);
+          if ( 0 == fValDiff )  {
+            fValDiff = fKey->fSize + fVal->fSize;
+          }
+          if ( 0 == fValOffset )  {
+            fValOffset = fKey->fSize;
+          }
+          break;
+        default:
+          fVal   = new Value(inside[1]);
+          if ( 0 == fValDiff )  {
+            fValDiff = fVal->fSize;
+          }
+          break;
+      }
+      fValue = new Value(*fVal);
+      fPointers |= 0 != (fVal->fCase&G__BIT_ISPOINTER);
+      return this;
+    }
+    Fatal("TEmulatedCollectionProxy","Components of %s not analysed!",fClass->GetName());
+  }
+  Fatal("TEmulatedCollectionProxy","Collection class %s not found!",fTypeinfo.name());
+  return 0;
+}
+
+/// Return the current size of the container
+UInt_t TEmulatedCollectionProxy::Size() const   {
+  if ( fEnv && fEnv->object )   {
+    return fEnv->size = PCont_t(fEnv->object)->size()/fValDiff;
+  }
+  Fatal("TEmulatedCollectionProxy","Size> Logic error - no proxy object set.");
+  return 0;
+}
+
+/// Clear the emulated collection.  
+void TEmulatedCollectionProxy::Clear(const char* opt)  {
+  Resize(0, opt && *opt=='f');
+}
+
+/// Shrink the container
+void TEmulatedCollectionProxy::Shrink(UInt_t nCurr, UInt_t left, Bool_t /* force */ )  {
+  typedef std::string  String_t;
+  PCont_t c   = PCont_t(fEnv->object);
+  char* addr  = ((char*)fEnv->start) + fValDiff*left;
+  size_t i;
+
+  switch ( fSTL_type )  {
+    case TClassEdit::kMap:
+    case TClassEdit::kMultiMap:
+      addr = ((char*)fEnv->start) + fValDiff*left;
+      switch(fKey->fCase)  {
+        case G__BIT_ISFUNDAMENTAL:  // Only handle primitives this way
+        case G__BIT_ISENUM:
+          break;
+        case G__BIT_ISCLASS:
+          for( i= fKey->fType ? left : nCurr; i<nCurr; ++i, addr += fValDiff )  {
+            // Call emulation in case non-compiled content
+            fKey->fDtor ? (*fKey->fDtor)(addr) : fKey->fType->Destructor(addr, kTRUE);
+          }
+          break;
+        case R__BIT_ISSTRING:
+          for( i=left; i<nCurr; ++i, addr += fValDiff )
+            ((std::string*)addr)->~String_t();
+          break;
+        case G__BIT_ISPOINTER|G__BIT_ISCLASS:
+          for( i=left; i<nCurr; ++i, addr += fValDiff )  {
+            StreamHelper* i = *(StreamHelper**)addr;
+            void* ptr = i->ptr();
+            if ( fKey->fDelete )  {       // Case of compiled content
+              (*fKey->fDelete)(ptr);
+            }
+            else if ( fKey->fType )  {    // Case of emulated content
+              fKey->fType->Destructor(ptr);
+            }
+            else if ( fKey->fDtor )  {    // Case of compiled content
+              (*fKey->fDtor)(ptr);
+              ::operator delete(ptr);
+            }
+            else {
+              ::operator delete(i->ptr());
+            }
+            i->set(0);
+          }
+        case G__BIT_ISPOINTER|R__BIT_ISSTRING:
+          for( i=nCurr; i<left; ++i, addr += fValDiff )   {
+            StreamHelper* i = *(StreamHelper**)addr;
+            delete (std::string*)i;
+            i->set(0);
+          }
+          break;
+        case G__BIT_ISPOINTER|R__BIT_ISTSTRING|G__BIT_ISCLASS:
+          for( i=nCurr; i<left; ++i, addr += fValDiff )   {
+            StreamHelper* i = *(StreamHelper**)addr;
+            delete i->tstr;
+            i->set(0);
+          }
+          break;
+      }
+      addr = ((char*)fEnv->start)+fKey->fSize+fValDiff*left;
+      // DO NOT break; just continue
+
+    // General case for all values
+    default:
+      switch( fVal->fCase )  {
+        case G__BIT_ISFUNDAMENTAL:  // Only handle primitives this way
+        case G__BIT_ISENUM:
+          break;
+        case G__BIT_ISCLASS:
+          for( i=fVal->fDtor ? left : nCurr; i<nCurr; ++i, addr += fValDiff )  {
+            // Call emulation in case non-compiled content
+            fKey->fDtor ? (*fKey->fDtor)(addr) : fKey->fType->Destructor(addr,kTRUE);
+          }
+          break;
+        case R__BIT_ISSTRING:
+          for( i=left; i<nCurr; ++i, addr += fValDiff )
+            ((std::string*)addr)->~String_t();
+          break;
+        case G__BIT_ISPOINTER|G__BIT_ISCLASS:
+          for( i=left; i<nCurr; ++i, addr += fValDiff )  {
+            StreamHelper* i = *(StreamHelper**)addr;
+            void* p = i->ptr();
+            if ( p )  {
+              if ( fVal->fDelete )  {      // Case of compiled content
+                (*fVal->fDelete)(p);
+              }
+              else if ( fVal->fType )  {  // Case of emultated content
+                fVal->fType->Destructor(p);
+              }
+              else if ( fVal->fDtor )  {   // Case of compiled content
+                (*fVal->fDtor)(p);
+                ::operator delete(p);
+              }
+              else  {
+                ::operator delete(p);
+              }
+            }
+            i->set(0);
+          }
+        case G__BIT_ISPOINTER|R__BIT_ISSTRING:
+          for( i=nCurr; i<left; ++i, addr += fValDiff )   {
+            StreamHelper* i = *(StreamHelper**)addr;
+            delete (std::string*)i;
+            i->set(0);
+          }
+          break;
+        case G__BIT_ISPOINTER|R__BIT_ISTSTRING|G__BIT_ISCLASS:
+          for( i=nCurr; i<left; ++i, addr += fValDiff )   {
+            StreamHelper* i = *(StreamHelper**)addr;
+            delete i->tstr;
+            i->set(0);
+          }
+          break;
+      }
+  }
+  c->resize(left*fValDiff,0);
+  fEnv->start = left>0 ? &(*c->begin()) : 0;
+  return;
+}
+
+/// Expand the container
+void TEmulatedCollectionProxy::Expand(UInt_t nCurr, UInt_t left)  {
+  size_t i;
+  PCont_t c   = PCont_t(fEnv->object);
+  c->resize(left*fValDiff,0);
+  fEnv->start = left>0 ? &(*c->begin()) : 0;
+  char* addr = ((char*)fEnv->start) + fValDiff*nCurr;
+  switch ( fSTL_type )  {
+    case TClassEdit::kMap:
+    case TClassEdit::kMultiMap:
+      switch(fKey->fCase)  {
+        case G__BIT_ISFUNDAMENTAL:  // Only handle primitives this way
+        case G__BIT_ISENUM:
+          break;
+        case G__BIT_ISCLASS:
+          for( i=fVal->fCtor ? nCurr : left; i<left; ++i, addr += fValDiff )
+            (*fKey->fCtor)(addr);
+          break;
+        case R__BIT_ISSTRING:
+          for( i=nCurr; i<left; ++i, addr += fValDiff )
+            ::new(addr) std::string();
+          break;
+        case G__BIT_ISPOINTER|G__BIT_ISCLASS:
+        case G__BIT_ISPOINTER|R__BIT_ISSTRING:
+        case G__BIT_ISPOINTER|R__BIT_ISTSTRING|G__BIT_ISCLASS:
+          for( i=nCurr; i<left; ++i, addr += fValDiff )
+            *(void**)addr = 0;
+          break;
+      }
+      addr = ((char*)fEnv->start)+fKey->fSize+fValDiff*nCurr;
+      // DO NOT break; just continue
+
+    // General case for all values
+    default:
+      switch(fVal->fCase)  {
+        case G__BIT_ISFUNDAMENTAL:  // Only handle primitives this way
+        case G__BIT_ISENUM:
+          break;
+        case G__BIT_ISCLASS:
+          for( i=fVal->fCtor ? nCurr : left; i<left; ++i, addr += fValDiff )
+            (*fVal->fCtor)(addr);
+          break;
+        case R__BIT_ISSTRING:
+          for( i=nCurr; i<left; ++i, addr += fValDiff )
+            ::new(addr) std::string();
+          break;
+        case G__BIT_ISPOINTER|G__BIT_ISCLASS:
+        case G__BIT_ISPOINTER|R__BIT_ISSTRING:
+        case G__BIT_ISPOINTER|R__BIT_ISTSTRING|G__BIT_ISCLASS:
+          for( i=nCurr; i<left; ++i, addr += fValDiff )
+            *(void**)addr = 0;
+          break;
+      }
+      break;
+  }
+}
+/// Resize the container
+void TEmulatedCollectionProxy::Resize(UInt_t left, Bool_t force)  {
+  if ( fEnv && fEnv->object )   {
+    size_t nCurr = Size();
+    PCont_t c = PCont_t(fEnv->object);
+    fEnv->start = left>0 ? &(*c->begin()) : 0;
+    if ( left == nCurr )  {
+      return;
+    }
+    else if ( left < nCurr )  {
+      Shrink(nCurr, left, force);
+      return;
+    }
+    Expand(nCurr, left);
+    return;
+  }
+  Fatal("TEmulatedCollectionProxy","Resize> Logic error - no proxy object set.");
+}
+
+/// Return the address of the value at index 'idx'
+void* TEmulatedCollectionProxy::At(UInt_t idx)   {
+  if ( fEnv && fEnv->object )   {
+    PCont_t c = PCont_t(fEnv->object);
+    return idx<(c->size()/fValDiff) ? ((char*)&(*c->begin()))+idx*fValDiff : 0;
+  }
+  Fatal("TEmulatedCollectionProxy","At> Logic error - no proxy object set.");
+  return 0;
+}
+
+void* TEmulatedCollectionProxy::Allocate(UInt_t n, Bool_t forceDelete)  {
+  Resize(n, forceDelete);
+  return fEnv;
+}
+
+void TEmulatedCollectionProxy::Commit(void* /* env */ )  {
+}
+
+/// Object input streamer
+void TEmulatedCollectionProxy::ReadItems(int nElements, TBuffer &b)  {
+  bool vsn3 = b.GetInfo() && b.GetInfo()->GetOldVersion()<=3;
+  StreamHelper* itm = (StreamHelper*)At(0);
+  switch (fVal->fCase) {
+    case G__BIT_ISFUNDAMENTAL:  // Only handle primitives this way
+    case G__BIT_ISENUM:
+      switch( int(fVal->fKind) )   {
+        case kChar_t:    b.ReadFastArray(&itm->s_char    , nElements); break;
+        case kShort_t:   b.ReadFastArray(&itm->s_short   , nElements); break;
+        case kInt_t:     b.ReadFastArray(&itm->s_int     , nElements); break;
+        case kLong_t:    b.ReadFastArray(&itm->s_long    , nElements); break;
+        case kLong64_t:  b.ReadFastArray(&itm->s_longlong, nElements); break;
+        case kFloat_t:   b.ReadFastArray(&itm->flt       , nElements); break;
+        case kDouble_t:  b.ReadFastArray(&itm->dbl       , nElements); break;
+        case kBOOL_t:    b.ReadFastArray(&itm->boolean   , nElements); break;
+        case kUChar_t:   b.ReadFastArray(&itm->u_char    , nElements); break;
+        case kUShort_t:  b.ReadFastArray(&itm->u_short   , nElements); break;
+        case kUInt_t:    b.ReadFastArray(&itm->u_int     , nElements); break;
+        case kULong_t:   b.ReadFastArray(&itm->u_long    , nElements); break;
+        case kULong64_t: b.ReadFastArray(&itm->u_longlong, nElements); break;
+        case kDouble32_t:b.ReadFastArrayDouble32(&itm->dbl,nElements); break;
+        case kchar:
+        case kNoType_t:
+        case kOther_t:
+          Error("TEmulatedCollectionProxy","fType %d is not supported yet!\n",fVal->fKind);
+      }
+      break;
+#define DOLOOP(x) {int idx=0; while(idx<nElements) {StreamHelper* i=(StreamHelper*)(((char*)itm) + fValDiff*idx); { x ;} ++idx;} break;}
+    case G__BIT_ISCLASS: 
+      DOLOOP( b.StreamObject(i,fVal->fType) );
+    case R__BIT_ISSTRING:
+      DOLOOP( i->read_std_string(b) );
+    case G__BIT_ISPOINTER|G__BIT_ISCLASS:
+      DOLOOP( i->read_any_object(fVal,b) );
+    case G__BIT_ISPOINTER|R__BIT_ISSTRING:
+#ifndef R__AIX
+      DOLOOP( i->read_std_string_pointer(b) );
+#endif
+    case G__BIT_ISPOINTER|R__BIT_ISTSTRING|G__BIT_ISCLASS:  
+      DOLOOP( i->read_tstring_pointer(vsn3,b) );
+  }
+#undef DOLOOP
+}
+
+/// Object output streamer
+void TEmulatedCollectionProxy::WriteItems(int nElements, TBuffer &b)  {
+  StreamHelper* itm = (StreamHelper*)At(0);
+  switch (fVal->fCase) {
+    case G__BIT_ISFUNDAMENTAL:  // Only handle primitives this way
+    case G__BIT_ISENUM:
+      itm = (StreamHelper*)At(0);
+      switch( int(fVal->fKind) )   {
+        case kChar_t:    b.WriteFastArray(&itm->s_char    , nElements); break;
+        case kShort_t:   b.WriteFastArray(&itm->s_short   , nElements); break;
+        case kInt_t:     b.WriteFastArray(&itm->s_int     , nElements); break;
+        case kLong_t:    b.WriteFastArray(&itm->s_long    , nElements); break;
+        case kLong64_t:  b.WriteFastArray(&itm->s_longlong, nElements); break;
+        case kFloat_t:   b.WriteFastArray(&itm->flt       , nElements); break;
+        case kDouble_t:  b.WriteFastArray(&itm->dbl       , nElements); break;
+        case kBOOL_t:    b.WriteFastArray(&itm->boolean   , nElements); break;
+        case kUChar_t:   b.WriteFastArray(&itm->u_char    , nElements); break;
+        case kUShort_t:  b.WriteFastArray(&itm->u_short   , nElements); break;
+        case kUInt_t:    b.WriteFastArray(&itm->u_int     , nElements); break;
+        case kULong_t:   b.WriteFastArray(&itm->u_long    , nElements); break;
+        case kULong64_t: b.WriteFastArray(&itm->u_longlong, nElements); break;
+        case kDouble32_t:b.WriteFastArrayDouble32(&itm->dbl,nElements); break;
+        case kchar:
+        case kNoType_t:
+        case kOther_t:
+          Error("TEmulatedCollectionProxy","fType %d is not supported yet!\n",fVal->fKind);
+      }
+      break;
+#define DOLOOP(x) {int idx=0; while(idx<nElements) {StreamHelper* i=(StreamHelper*)(((char*)itm) + fValDiff*idx); { x ;} ++idx;} break;}
+    case G__BIT_ISCLASS: 
+      DOLOOP( b.StreamObject(i,fVal->fType) );
+    case R__BIT_ISSTRING:
+      DOLOOP( TString(i->c_str()).Streamer(b) );
+    case G__BIT_ISPOINTER|G__BIT_ISCLASS:
+      DOLOOP( b.WriteObjectAny(i->ptr(),fVal->fType) );
+    case R__BIT_ISSTRING|G__BIT_ISPOINTER:
+#ifndef R__AIX
+      DOLOOP( i->write_std_string_pointer(b) );
+#endif
+    case R__BIT_ISTSTRING|G__BIT_ISCLASS|G__BIT_ISPOINTER:
+      DOLOOP( i->write_tstring_pointer(b) );
+  }
+#undef DOLOOP
+}
+
+/// TClassStreamer IO overload
+void TEmulatedCollectionProxy::Streamer(TBuffer &b) {
+  if ( b.IsReading() ) {  //Read mode 
+    int nElements = 0;
+    b >> nElements;
+    if ( fEnv->object )  {
+      Resize(nElements,true);
+    }
+    if ( nElements > 0 )  {
+      ReadItems(nElements, b);
+    }
+  }
+  else {     // Write case
+    int nElements = fEnv->object ? *(size_t*)fSize.invoke(fEnv) : 0;
+    b << nElements;
+    if ( nElements > 0 )  {
+      WriteItems(nElements, b);
+    }
+  }
+}
diff --git a/io/src/TEmulatedMapProxy.cxx b/io/src/TEmulatedMapProxy.cxx
new file mode 100644
index 00000000000..e591582e010
--- /dev/null
+++ b/io/src/TEmulatedMapProxy.cxx
@@ -0,0 +1,221 @@
+// @(#)root/cont:$Name:  $:$Id: TEmulatedMapProxy.cxx,v 1.26 2004/10/13 15:30:22 rdm Exp $
+// Author: Markus Frank 28/10/04
+
+/*************************************************************************
+ * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers.               *
+ * All rights reserved.                                                  *
+ *                                                                       *
+ * For the licensing terms see $ROOTSYS/LICENSE.                         *
+ * For the list of contributors see $ROOTSYS/README/CREDITS.             *
+ *************************************************************************/
+
+//////////////////////////////////////////////////////////////////////////
+//                                                                      //
+// TEmulatedMapProxy
+//
+// Streamer around an arbitrary container, which implements basic 
+// functionality and iteration.
+//
+// In particular this is used to implement splitting and abstract
+// element access of any container. Access to compiled code is necessary
+// to implement the abstract iteration sequence and functionality like
+// size(), clear(), resize(). resize() may be a void operation.
+//
+//////////////////////////////////////////////////////////////////////////
+
+#include "TEmulatedMapProxy.h"
+#include "TStreamerInfo.h"
+#include "TClassEdit.h"
+#include "TError.h"
+
+/// Build a Streamer for an emulated vector whose type is 'name'.
+TEmulatedMapProxy::TEmulatedMapProxy(const TEmulatedMapProxy& copy)
+: TEmulatedCollectionProxy(copy)
+{
+  if ( !(fSTL_type == TClassEdit::kMap || fSTL_type == TClassEdit::kMultiMap) )  {
+    Fatal("TEmulatedMapProxy","Class %s is not a map-type!",fName.c_str());
+  }
+}
+
+/// Build a Streamer for a collection whose type is described by 'collectionClass'.
+TEmulatedMapProxy::TEmulatedMapProxy(const char* cl_name)
+: TEmulatedCollectionProxy(cl_name)
+{
+  fName = cl_name;
+  Initialize();
+  if ( !(fSTL_type == TClassEdit::kMap || fSTL_type == TClassEdit::kMultiMap) )  {
+    Fatal("TEmulatedMapProxy","Class %s is not a map-type!",fName.c_str());
+  }
+}
+
+/// Standard destructor
+TEmulatedMapProxy::~TEmulatedMapProxy()   {
+}
+
+/// Virtual copy constructor
+TVirtualCollectionProxy* TEmulatedMapProxy::Generate() const  { 
+  if ( !fClass ) Initialize();
+  return new TEmulatedMapProxy(*this);
+}
+
+/// Return the address of the value at index 'idx'
+void* TEmulatedMapProxy::At(UInt_t idx)   {
+  if ( fEnv && fEnv->object )   {
+    PCont_t c = PCont_t(fEnv->object);
+    return idx<(c->size()/fValDiff) ? ((char*)&(*c->begin())) + idx*fValDiff : 0;
+  }
+  Fatal("TEmulatedMapProxy","At> Logic error - no proxy object set.");
+  return 0;
+}
+
+/// Return the current size of the container
+UInt_t TEmulatedMapProxy::Size() const   {
+  if ( fEnv && fEnv->object )   {
+    PCont_t c = PCont_t(fEnv->object);
+    return fEnv->size = (c->size()/fValDiff);
+  }
+  Fatal("TEmulatedMapProxy","Size> Logic error - no proxy object set.");
+  return 0;
+}
+
+/// Map input streamer
+void TEmulatedMapProxy::ReadMap(int nElements, TBuffer &b)  {
+  bool   vsn3 = b.GetInfo() && b.GetInfo()->GetOldVersion()<=3;
+  int    idx, loop, off[2] = {0, fKey->fSize };
+  Value  *v, *val[2] = { fKey, fVal };
+  StreamHelper* helper;
+  float f;
+  char* addr = 0; 
+  char* temp = (char*)At(0);
+  for ( idx = 0; idx < nElements; ++idx )  {
+    addr = temp + idx*fValDiff;
+    for ( loop=0; loop<2; loop++)  {
+      addr += off[loop];
+      helper = (StreamHelper*)addr;
+      v = val[loop];
+      switch (v->fCase) {
+        case G__BIT_ISFUNDAMENTAL:  // Only handle primitives this way
+        case G__BIT_ISENUM:
+          switch( int(v->fKind) )   {
+            case kChar_t:    b >> helper->s_char;      break;
+            case kShort_t:   b >> helper->s_short;     break;
+            case kInt_t:     b >> helper->s_int;       break;
+            case kLong_t:    b >> helper->s_long;      break;
+            case kLong64_t:  b >> helper->s_longlong;  break;
+            case kFloat_t:   b >> helper->flt;         break;
+            case kDouble_t:  b >> helper->dbl;         break;
+            case kBOOL_t:    b >> helper->boolean;     break;
+            case kUChar_t:   b >> helper->u_char;      break;
+            case kUShort_t:  b >> helper->u_short;     break;
+            case kUInt_t:    b >> helper->u_int;       break;
+            case kULong_t:   b >> helper->u_long;      break;
+            case kULong64_t: b >> helper->u_longlong;  break;
+            case kDouble32_t:b >> f; 
+                             helper->dbl = double(f);  break;
+            case kchar:
+            case kNoType_t:
+            case kOther_t:
+              Error("TEmulatedMapProxy","fType %d is not supported yet!\n",v->fKind);
+          }
+          break;
+        case G__BIT_ISCLASS:
+          b.StreamObject(helper,v->fType);
+          break;
+        case R__BIT_ISSTRING:
+          helper->read_std_string(b);
+          break;
+        case G__BIT_ISPOINTER|G__BIT_ISCLASS:
+          helper->set(b.ReadObjectAny(v->fType));
+          break;
+        case G__BIT_ISPOINTER|R__BIT_ISSTRING:
+#ifndef R__AIX
+          helper->read_std_string_pointer(b);
+#endif
+          break;
+        case G__BIT_ISPOINTER|R__BIT_ISTSTRING|G__BIT_ISCLASS:
+          helper->read_tstring_pointer(vsn3,b);
+          break;
+      }
+    }
+  }
+}
+
+/// Map output streamer
+void TEmulatedMapProxy::WriteMap(int nElements, TBuffer &b)  {
+  Value  *v, *val[2] = { fKey, fVal };
+  int    off[2]      = { 0, fKey->fSize };
+  StreamHelper* i;
+  char* addr = 0; 
+  char* temp = (char*)At(0);
+  for (int loop, idx = 0; idx < nElements; ++idx )  {
+    addr = temp + idx*fValDiff;
+    for ( loop = 0; loop<2; ++loop )  {
+      addr += off[loop];
+      i = (StreamHelper*)addr;
+      v = val[loop];
+      switch (v->fCase) {
+        case G__BIT_ISFUNDAMENTAL:  // Only handle primitives this way
+        case G__BIT_ISENUM:
+          switch( int(v->fKind) )   {
+            case kChar_t:    b << i->s_char;      break;
+            case kShort_t:   b << i->s_short;     break;
+            case kInt_t:     b << i->s_int;       break;
+            case kLong_t:    b << i->s_long;      break;
+            case kLong64_t:  b << i->s_longlong;  break;
+            case kFloat_t:   b << i->flt;         break;
+            case kDouble_t:  b << i->dbl;         break;
+            case kBOOL_t:    b << i->boolean;     break;
+            case kUChar_t:   b << i->u_char;      break;
+            case kUShort_t:  b << i->u_short;     break;
+            case kUInt_t:    b << i->u_int;       break;
+            case kULong_t:   b << i->u_long;      break;
+            case kULong64_t: b << i->u_longlong;  break;
+            case kDouble32_t:b << float(i->dbl);  break;
+            case kchar:
+            case kNoType_t:
+            case kOther_t:
+              Error("TEmulatedMapProxy","fType %d is not supported yet!\n",v->fKind);
+          }
+          break;
+        case G__BIT_ISCLASS: 
+          b.StreamObject(i,v->fType);
+          break;
+        case R__BIT_ISSTRING:
+          TString(i->c_str()).Streamer(b);
+          break;
+        case G__BIT_ISPOINTER|G__BIT_ISCLASS:
+          b.WriteObjectAny(i->ptr(),v->fType);
+          break;
+        case R__BIT_ISSTRING|G__BIT_ISPOINTER:
+#ifndef R__AIX
+          i->write_std_string_pointer(b);
+#endif
+          break;
+        case R__BIT_ISTSTRING|G__BIT_ISCLASS|G__BIT_ISPOINTER:
+          i->write_tstring_pointer(b);
+          break;
+      }
+    }
+  }
+}
+
+/// TClassStreamer IO overload
+void TEmulatedMapProxy::Streamer(TBuffer &b) {
+  if ( b.IsReading() ) {  //Read mode 
+    int nElements = 0;
+    b >> nElements;
+    if ( fEnv->object )  {
+      Resize(nElements,true);
+    }
+    if ( nElements > 0 )  {
+      ReadMap(nElements, b);
+    }
+  }
+  else {     // Write case
+    int nElements = fEnv->object ? Size() : 0;
+    b << nElements;
+    if ( nElements > 0 )  {
+      WriteMap(nElements, b);
+    }
+  }
+}
diff --git a/io/src/TGenCollectionProxy.cxx b/io/src/TGenCollectionProxy.cxx
new file mode 100644
index 00000000000..97e3dfa76b9
--- /dev/null
+++ b/io/src/TGenCollectionProxy.cxx
@@ -0,0 +1,714 @@
+// @(#)root/cont:$Name:  $:$Id: TGenVectorProxy.cxx,v 1.26 2004/10/13 15:30:22 rdm Exp $
+// Author: Markus Frank 28/10/04
+
+/*************************************************************************
+ * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers.               *
+ * All rights reserved.                                                  *
+ *                                                                       *
+ * For the licensing terms see $ROOTSYS/LICENSE.                         *
+ * For the list of contributors see $ROOTSYS/README/CREDITS.             *
+ *************************************************************************/
+
+//////////////////////////////////////////////////////////////////////////
+//                                                                      //
+// TGenCollectionProxy
+//
+// Proxy around an arbitrary container, which implements basic 
+// functionality and iteration.
+//
+// In particular this is used to implement splitting and abstract
+// element access of any container. Access to compiled code is necessary
+// to implement the abstract iteration sequence and functionality like
+// size(), clear(), resize(). resize() may be a void operation.
+//
+//////////////////////////////////////////////////////////////////////////
+
+#include "TGenCollectionProxy.h"
+#include "TStreamerElement.h"
+#include "TClassEdit.h"
+#include "Property.h"
+#include "TClass.h"
+#include "TError.h"
+#include "TROOT.h"
+#include "Api.h"
+#include <iostream>
+
+#define MESSAGE(which,text)  
+
+/** @class TGenVectorProxy TGenCollectionProxy.cxx cont/TGenCollectionProxy.cxx
+  *
+  * Localoptimization class.
+  *
+  * Collection proxies get copied. On copy we switch the type of the 
+  * proxy to the concrete STL type. The concrete types are optimized 
+  * for element access.
+  *
+  * @author  M.Frank
+  * @version 1.0
+  * @date    10/10/2004
+  */
+class TGenVectorProxy : public TGenCollectionProxy {
+public:
+  /// Standard Destructor
+  TGenVectorProxy(const TGenCollectionProxy& c) : TGenCollectionProxy(c)  {  
+  }
+  /// Standard Destructor
+  virtual ~TGenVectorProxy() {
+  }
+  /// Return the address of the value at index 'idx'
+  virtual void* At(UInt_t idx)   {
+    if ( fEnv && fEnv->object )   {
+      fEnv->idx = idx;
+      switch( idx ) {
+        case 0:
+          return fEnv->start = fFirst.invoke(fEnv);
+        default:
+          return ((char*)fEnv->start) + fValDiff*idx;
+      }
+    }
+    Fatal("TGenVectorProxy","At> Logic error - no proxy object set.");
+    return 0;
+  }
+  /// Call to delete/destruct individual item
+  virtual void DeleteItem(bool force, void* ptr)  const  {
+    if ( force && ptr )  {
+      if ( fValue->fDelete )  {
+        (*fValue->fDelete)(ptr);
+      }
+      else if ( fVal->fType )  {
+        fVal->fType->Destructor(ptr);
+      }
+      else {
+        ::operator delete(ptr);
+      }
+    }
+  }
+};
+
+/** @class TGenListProxy TGenCollectionProxy.cxx cont/TGenCollectionProxy.cxx
+  *
+  * Localoptimization class.
+  *
+  * Collection proxies get copied. On copy we switch the type of the 
+  * proxy to the concrete STL type. The concrete types are optimized 
+  * for element access.
+  *
+  * @author  M.Frank
+  * @version 1.0
+  * @date    10/10/2004
+  */
+class TGenListProxy : public TGenVectorProxy {
+public:
+  /// Standard Destructor
+  TGenListProxy(const TGenCollectionProxy& c) : TGenVectorProxy(c)  {  
+  }
+  /// Standard Destructor
+  virtual ~TGenListProxy() {
+  }
+  /// Return the address of the value at index 'idx'
+  void* At(UInt_t idx)   {
+    if ( fEnv && fEnv->object )   {
+      switch( idx ) {
+        case 0:
+          fEnv->idx = idx;
+          return fEnv->start = fFirst.invoke(fEnv);
+        default:  {
+          fEnv->idx = idx - fEnv->idx;
+          void* result = fNext.invoke(fEnv);
+          fEnv->idx = idx;
+          return result;
+        }
+      }
+    }
+    Fatal("TGenListProxy","At> Logic error - no proxy object set.");
+    return 0;
+  }
+};
+
+/** @class TGenSetProxy TGenCollectionProxy.cxx cont/TGenCollectionProxy.cxx
+  *
+  * Localoptimization class.
+  *
+  * Collection proxies get copied. On copy we switch the type of the 
+  * proxy to the concrete STL type. The concrete types are optimized 
+  * for element access.
+  *
+  * @author  M.Frank
+  * @version 1.0
+  * @date    10/10/2004
+  */
+class TGenSetProxy : public TGenVectorProxy {
+public:
+  /// Standard Destructor
+  TGenSetProxy(const TGenCollectionProxy& c) : TGenVectorProxy(c)  {  
+  }
+  /// Standard Destructor
+  virtual ~TGenSetProxy() {
+  }
+  /// Return the address of the value at index 'idx'
+  void* At(UInt_t idx)   {
+    if ( fEnv && fEnv->object )   {
+      if ( fEnv->temp )  {
+        return (((char*)fEnv->temp)+idx*fValDiff);
+      }
+      switch( idx ) {
+        case 0:
+          fEnv->idx = idx;
+          return fEnv->start = fFirst.invoke(fEnv);
+        default:  {
+          fEnv->idx = idx - fEnv->idx;
+          void* result = fNext.invoke(fEnv);
+          fEnv->idx = idx;
+          return result;
+        }
+      }
+    }
+    Fatal("TGenSetProxy","At> Logic error - no proxy object set.");
+    return 0;
+  }
+};
+
+/** @class TGenMapProxy TGenCollectionProxy.cxx cont/TGenCollectionProxy.cxx
+  *
+  * Localoptimization class.
+  *
+  * Collection proxies get copied. On copy we switch the type of the 
+  * proxy to the concrete STL type. The concrete types are optimized 
+  * for element access.
+  *
+  * @author  M.Frank
+  * @version 1.0
+  * @date    10/10/2004
+  */
+class TGenMapProxy : public TGenSetProxy {
+public:
+  /// Standard Destructor
+  TGenMapProxy(const TGenCollectionProxy& c) : TGenSetProxy(c)  {  
+  }
+  /// Standard Destructor
+  virtual ~TGenMapProxy() {
+  }
+  /// Call to delete/destruct individual item
+  virtual void DeleteItem(bool /* force */, void* ptr)  const  {
+    if ( fKey->fCase&G__BIT_ISPOINTER )  {
+      if ( *(void**)ptr )  {
+        (*fKey->fDelete)(*(void**)ptr);
+      }
+    }
+    if ( fVal->fCase&G__BIT_ISPOINTER )  {
+      char *addr = ((char*)ptr)+fKey->fSize;
+      if ( *(void**)addr ) (*fVal->fDelete)(*(void**)addr);
+    }
+  }
+};
+
+TGenCollectionProxy::Value::Value(const Value& copy)  {
+  fType   = copy.fType;
+  fCase   = copy.fCase;
+  fKind   = copy.fKind;
+  fSize   = copy.fSize;
+  fCtor   = copy.fCtor;
+  fDtor   = copy.fDtor;
+  fDelete = copy.fDelete;
+}
+
+TGenCollectionProxy::Value::Value(const std::string& inside)  {
+  fType = 0;
+  fCase = 0;
+  fCtor = 0;
+  fDtor = 0;
+  fDelete = 0;
+  fSize = std::string::npos;
+  fKind = kNoType_t;
+  std::string intype = TClassEdit::ShortType(inside.c_str(),TClassEdit::kDropTrailStar );
+  if ( inside.substr(0,6) == "string" || inside.substr(0,11) == "std::string" ) {
+    fCase = R__BIT_ISSTRING;
+    fType = gROOT->GetClass("string");
+    fCtor = fType->GetNew();
+    fDtor = fType->GetDestructor();
+    fDelete = fType->GetDelete();
+    switch(inside[inside.length()-1]) {
+      case '*':
+        fCase |= G__BIT_ISPOINTER;
+        fSize = sizeof(void*);
+        break;
+      default:
+        fSize = sizeof(std::string);
+        break;
+    }
+  }
+  else {
+    G__TypeInfo ti(inside.c_str());
+    if ( !ti.IsValid() ) {
+      if (intype != inside) {
+        fCase |= G__BIT_ISPOINTER;
+        fSize = sizeof(void*);
+      }
+      fType = gROOT->GetClass(intype.c_str());
+      if (fType)  {
+        fCase  |= G__BIT_ISCLASS;
+        fCtor   = fType->GetNew();
+        fDtor   = fType->GetDestructor();
+        fDelete = fType->GetDelete();
+      }
+      else {
+        // either we have an Emulated enum or a really unknown class!
+        // let's just claim its an enum :(
+        fCase = G__BIT_ISENUM;
+        fSize = sizeof(Int_t);
+        fKind = kInt_t;
+      }
+    } 
+    else {
+      long P = ti.Property();      
+      if ( P&G__BIT_ISPOINTER ) {
+        fSize = sizeof(void*);
+      }
+      if ( P&G__BIT_ISSTRUCT ) {
+        P |= G__BIT_ISCLASS;
+      }
+      if ( P&G__BIT_ISCLASS ) {
+        fType = gROOT->GetClass(intype.c_str());
+        Assert(fType);
+        fCtor   = fType->GetNew();
+        fDtor   = fType->GetDestructor();
+        fDelete = fType->GetDelete();
+      }
+      else if ( P&G__BIT_ISFUNDAMENTAL ) {
+        TDataType *fundType = gROOT->GetType( intype.c_str() );
+        fKind = (EDataType)fundType->GetType();
+        fSize = ti.Size();
+        Assert(fKind>0 && fKind<20);
+      }
+      else if ( P&G__BIT_ISENUM ) {
+        fSize = sizeof(int);
+        fKind = kInt_t;
+      }
+      fCase = P & (G__BIT_ISPOINTER|G__BIT_ISFUNDAMENTAL|G__BIT_ISENUM|G__BIT_ISCLASS);
+      if (fType == TString::Class() && (fCase&G__BIT_ISPOINTER)) {
+        fCase |= R__BIT_ISTSTRING;
+      }
+    }    
+  }
+  if ( fSize == std::string::npos ) {
+    if ( fType == 0 ) {
+      Fatal("TGenCollectionProxy","Could not find %s!",inside.c_str());
+    }
+    fSize = fType->Size();
+  }
+}
+
+/// Build a proxy for an emulated container.
+TGenCollectionProxy::TGenCollectionProxy(const TGenCollectionProxy& copy)
+: TVirtualCollectionProxy(copy.fClass),
+  fTypeinfo(copy.fTypeinfo)
+{
+  fEnv            = 0;
+  fName           = copy.fName;
+  fPointers       = copy.fPointers;
+  fSTL_type       = copy.fSTL_type;
+  fSize.call      = copy.fSize.call;
+  fNext.call      = copy.fNext.call;
+  fFirst.call     = copy.fFirst.call;
+  fClear.call     = copy.fClear.call;
+  fResize.call    = copy.fResize.call;
+  fDestruct.call  = copy.fDestruct.call;
+  fConstruct.call = copy.fConstruct.call;
+  fFeed.call      = copy.fFeed.call;
+  fCollect.call   = copy.fCollect.call;
+  fValOffset      = copy.fValOffset;
+  fValDiff        = copy.fValDiff;
+  fValue          = copy.fValue ? new Value(*copy.fValue) : 0;
+  fVal            = copy.fVal   ? new Value(*copy.fVal)   : 0;
+  fKey            = copy.fKey   ? new Value(*copy.fKey)   : 0;
+}
+
+/// Build a proxy for a collection whose type is described by 'collectionClass'.
+TGenCollectionProxy::TGenCollectionProxy(Info_t info, size_t iter_size)
+: TVirtualCollectionProxy(0),
+  fTypeinfo(info)
+{
+  fEnv             = 0;
+  fSize.call       = 0;
+  fFirst.call      = 0;
+  fNext.call       = 0;
+  fClear.call      = 0;
+  fResize.call     = 0;
+  fDestruct.call   = 0;
+  fConstruct.call  = 0;
+  fCollect.call    = 0;
+  fFeed.call       = 0;
+  fValue           = 0;
+  fKey             = 0;
+  fVal             = 0;
+  fValOffset       = 0;
+  fValDiff         = 0;
+  fPointers        = false;
+  Env_t e;
+  if ( iter_size > sizeof(e.buff) ) {
+    Fatal("TGenCollectionProxy",
+          "%s %s are too large:%d bytes. Maximum is:%d bytes", 
+          "Iterators for collection", 
+          fClass->GetName(), 
+          iter_size, 
+          sizeof(e.buff));
+  }
+}
+
+/// Standard destructor
+TGenCollectionProxy::~TGenCollectionProxy()   {
+  for(Proxies_t::iterator i=fProxyList.begin(); i != fProxyList.end(); ++i)  {
+    if ( (*i) ) delete (*i);
+  }
+  fProxyList.clear();
+  if ( fValue ) delete fValue;
+  if ( fVal   ) delete fVal;
+  if ( fKey   ) delete fKey;
+}
+
+/// Virtual copy constructor
+TVirtualCollectionProxy* TGenCollectionProxy::Generate() const  { 
+  if ( !fClass ) Initialize();
+  switch(fSTL_type)  {
+    case TClassEdit::kVector:
+      return new TGenVectorProxy(*this);
+    case TClassEdit::kList:
+      return new TGenListProxy(*this);
+    case TClassEdit::kMap:
+    case TClassEdit::kMultiMap:
+      return new TGenMapProxy(*this);
+    case TClassEdit::kSet:
+    case TClassEdit::kMultiSet:
+      return new TGenSetProxy(*this);
+    default:
+      return new TGenCollectionProxy(*this);
+  }
+}
+
+/// Proxy initializer
+TGenCollectionProxy *TGenCollectionProxy::Initialize()  const { 
+  TGenCollectionProxy* p = const_cast<TGenCollectionProxy*>(this);
+  if ( fClass ) return p;
+  return p->InitializeEx();
+}
+
+/// Check existence of function pointers
+void TGenCollectionProxy::CheckFunctions()  const   {
+  if ( 0 == fSize.call )   {
+    Fatal("TGenCollectionProxy","No 'size' function pointer for class %s present.",fName.c_str());
+  }
+  if ( 0 == fResize.call )   {
+    Fatal("TGenCollectionProxy","No 'resize' function for class %s present.",fName.c_str());
+  }
+  if ( 0 == fNext.call  )   {
+    Fatal("TGenCollectionProxy","No 'next' function for class %s present.",fName.c_str());
+  }
+  if ( 0 == fFirst.call )   {
+    Fatal("TGenCollectionProxy","No 'begin' function for class %s present.",fName.c_str());
+  }
+  if ( 0 == fClear.call )   {
+    Fatal("TGenCollectionProxy","No 'clear' function for class %s present.",fName.c_str());
+  }
+  if ( 0 == fConstruct.call )   {
+    Fatal("TGenCollectionProxy","No 'block constructor' function for class %s present.",fName.c_str());
+  }
+  if ( 0 == fDestruct.call )   {
+    Fatal("TGenCollectionProxy","No 'block destructor' function for class %s present.",fName.c_str());
+  }
+  if ( 0 == fFeed.call )   {
+    Fatal("TGenCollectionProxy","No 'data feed' function for class %s present.",fName.c_str());
+  }
+  if ( 0 == fCollect.call )   {
+    Fatal("TGenCollectionProxy","No 'data collect' function for class %s present.",fName.c_str());
+  }
+}
+
+/// Proxy initializer
+TGenCollectionProxy *TGenCollectionProxy::InitializeEx() { 
+  fClass = gROOT->GetClass(fTypeinfo);
+  if ( fClass )  {
+    fEnv    = 0;
+    fName   = fClass->GetName();
+    fPointers  = false;
+    int nested = 0;
+    std::vector<std::string> inside;
+    int num = TClassEdit::GetSplit(fClass->GetName(),inside,nested);
+    if ( num > 1 )  {
+      std::string nam;
+      fSTL_type = TClassEdit::STLKind(inside[0].c_str());
+      switch ( fSTL_type )  {
+        case TClassEdit::kMap:
+        case TClassEdit::kMultiMap:
+          nam = "pair<"+inside[1]+","+inside[2];
+          nam += (nam[nam.length()-1]=='>') ? " >" : ">";
+          fValue = new Value(nam);
+          fVal   = new Value(inside[2]);
+          fKey   = new Value(inside[1]);
+          fPointers = fPointers || (0 != (fKey->fCase&G__BIT_ISPOINTER));
+          if ( 0 == fValDiff )  {
+            fValDiff = fKey->fSize + fVal->fSize;
+          }
+          if ( 0 == fValOffset )  {
+            fValOffset = fKey->fSize;
+          }
+          break;
+        default:
+          fValue = new Value(inside[1]);
+          fVal   = new Value(*fValue);
+          if ( 0 == fValDiff )  {
+            fValDiff = fVal->fSize;
+          }
+          break;
+      }
+      fPointers = fPointers || (0 != (fVal->fCase&G__BIT_ISPOINTER));
+      return this;
+    }
+    Fatal("TGenCollectionProxy","Components of %s not analysed!",fClass->GetName());
+  }
+  Fatal("TGenCollectionProxy","Collection class %s not found!",fTypeinfo.name());
+  return 0;
+}
+
+/// Return a pointer to the TClass representing the container
+TClass *TGenCollectionProxy::GetCollectionClass()  {
+  return fClass ? fClass : Initialize()->fClass;
+}
+
+/// Return the sizeof the collection object. 
+UInt_t TGenCollectionProxy::Sizeof() const  {
+  return fClass->Size();
+}
+
+/// Return true if the content is of type 'pointer to'
+Bool_t TGenCollectionProxy::HasPointers() const   {
+  return fPointers;
+}
+
+/// Return a pointer to the TClass representing the content.
+TClass *TGenCollectionProxy::GetValueClass()  {
+  return fValue->fType;
+}
+
+/// Set pointer to the TClass representing the content.
+void TGenCollectionProxy::SetValueClass(TClass *new_Value_type)  {
+  fValue->fType = new_Value_type;
+}
+
+/// If the content is a simple numerical value, return its type (see TDataType)
+EDataType TGenCollectionProxy::GetType()   {
+  return fValue->fKind;
+}
+
+/// Return the address of the value at index 'idx'
+void* TGenCollectionProxy::At(UInt_t idx)   {
+  if ( fEnv && fEnv->object )   {
+    switch (fSTL_type)  {
+      case TClassEdit::kVector:
+        fEnv->idx = idx;
+        switch( idx ) {
+          case 0:
+            return fEnv->start = fFirst.invoke(fEnv);
+          default:
+            return ((char*)fEnv->start) + fValDiff*idx;
+        }
+      case TClassEdit::kSet:
+      case TClassEdit::kMultiSet:
+      case TClassEdit::kMap:
+      case TClassEdit::kMultiMap:
+        if ( fEnv->temp )  {
+          return (((char*)fEnv->temp)+idx*fValDiff);
+        }
+      default:
+        switch( idx ) {
+          case 0:
+            fEnv->idx = idx;
+            return fEnv->start = fFirst.invoke(fEnv);
+          default:  {
+            fEnv->idx = idx - fEnv->idx;
+            void* result = fNext.invoke(fEnv);
+            fEnv->idx = idx;
+            return result;
+          }
+        }
+    }
+  }
+  Fatal("TGenCollectionProxy","At> Logic error - no proxy object set.");
+  return 0;
+}
+
+/// Clear the emulated collection.  
+void TGenCollectionProxy::Clear(const char* opt)  {
+  if ( fEnv && fEnv->object )   {
+    if ( fPointers && opt && *opt=='f' )  {
+      size_t i, n = *(size_t*)fSize.invoke(fEnv);
+      if ( n > 0 )  {
+        for (i=0; i<n; ++i)
+          DeleteItem(true, TGenCollectionProxy::At(i));
+      }
+    }
+    fClear.invoke(fEnv);
+  }
+}
+
+/// Return the current size of the container
+UInt_t TGenCollectionProxy::Size() const   {
+  if ( fEnv && fEnv->object )   {
+    return *(size_t*)fSize.invoke(fEnv);
+  }
+  Fatal("TGenCollectionProxy","Size> Logic error - no proxy object set.");
+  return 0;
+}
+
+/// Resize the container
+void TGenCollectionProxy::Resize(UInt_t n, Bool_t force)  {
+  if ( fEnv && fEnv->object )   {
+    if ( force && fPointers )  {
+      size_t i, nold = *(size_t*)fSize.invoke(fEnv);
+      if ( n != nold )  {
+        for (i=n; i<nold; ++i)
+          DeleteItem(true, *(void**)TGenCollectionProxy::At(i));
+      }
+    }
+    MESSAGE(3, "Resize(n)" );
+    fEnv->size = n;
+    fResize.invoke(fEnv);
+    return;
+  }
+  Fatal("TGenCollectionProxy","Resize> Logic error - no proxy object set.");
+}
+
+void* TGenCollectionProxy::Allocate(UInt_t n, Bool_t /* forceDelete */ )  {
+  if ( fEnv && fEnv->object )   {
+    switch ( fSTL_type )  {
+      case TClassEdit::kSet:
+      case TClassEdit::kMultiSet:
+      case TClassEdit::kMap:
+      case TClassEdit::kMultiMap:
+        if ( fPointers ) 
+          Clear("force");
+        else
+          fClear.invoke(fEnv);
+        ++fEnv->refCount;
+        fEnv->size  = n;
+        fEnv->start = fEnv->temp = ::operator new(fValDiff*n);
+        fConstruct.invoke(fEnv);
+        return fEnv;
+      case TClassEdit::kVector:
+      case TClassEdit::kList:
+      case TClassEdit::kDeque:
+        if( fPointers )  {
+          Clear("force");
+        }
+        fEnv->size = n;
+        fResize.invoke(fEnv);
+        return fEnv;
+    }
+  }
+  return 0;
+}
+
+void TGenCollectionProxy::Commit(void* env)  {
+  switch (fSTL_type)  {
+    case TClassEdit::kVector:
+    case TClassEdit::kList:
+    case TClassEdit::kDeque:
+      return;
+    case TClassEdit::kMap:
+    case TClassEdit::kMultiMap: 
+    case TClassEdit::kSet:
+    case TClassEdit::kMultiSet: 
+      if ( env )  {
+        Env_t* e = (Env_t*)env;
+        if ( e->object )   {
+          e->start = e->temp;
+          fFeed.invoke(e);
+        }
+        fDestruct.invoke(e);
+        e->start = 0;
+        --e->refCount;
+      }
+      return;
+    default:
+      return;
+  }
+}
+
+void TGenCollectionProxy::PushProxy(void *objstart) {
+  if ( !fClass ) Initialize();
+  if ( !fProxyList.empty() )  {
+    Env_t* back = fProxyList.back();
+    if ( back->object == objstart )  {
+      back->refCount++;
+      fProxyList.push_back(back);
+      fEnv = back;
+      return;
+    }
+  }
+  Env_t* e    = new Env_t();
+  e->size     = 0;
+  e->refCount = 1;
+  e->object   = objstart;
+  e->temp     = e->start = 0;
+  ::memset(e->buff,0,sizeof(e->buff));
+  fProxyList.push_back(e);
+  fEnv = e;
+}
+
+void TGenCollectionProxy::PopProxy() {
+  if ( !fProxyList.empty() )  {
+    Env_t* e = fProxyList.back();
+    if ( --e->refCount <= 0 )  {
+      if ( e->temp ) 
+        ::operator delete(e->temp);
+      delete e;
+    }
+    fProxyList.pop_back();
+  }
+  fEnv = 0;
+}
+
+/// Call to delete/destruct individual item
+void TGenCollectionProxy::DeleteItem(bool force, void* ptr)  const  {
+  // This needs correction in the LCG dict...
+  // Pointers are not initialized to NULL!
+  if ( force && ptr )  {
+    switch (fSTL_type)  {
+      case TClassEdit::kMap:
+      case TClassEdit::kMultiMap:
+        if ( fKey->fCase&G__BIT_ISPOINTER )  {
+          if (*(void**)ptr) (*fKey->fDelete)(*(void**)ptr);
+        }
+        if ( fVal->fCase&G__BIT_ISPOINTER )  {
+          char *addr = ((char*)ptr)+fKey->fSize;
+          if (*(void**)addr) (*fVal->fDelete)(*(void**)addr);
+        }
+        // (*fValue->fDtor)(ptr); No: pair must stay intact !
+        break;
+      default:
+        if ( fVal->fCase&G__BIT_ISPOINTER )  {
+          (*fVal->fDelete)(*(void**)ptr);
+        }
+        break;
+    }
+  }
+}
+
+void TGenCollectionProxy::Streamer(TBuffer &buff)  {
+  if ( fEnv )   {
+    GetCollectionClass()->Streamer( fEnv->object, buff );
+    return;
+  }
+  Fatal("TGenCollectionProxy","Streamer> Logic error - no proxy object set.");
+}
+
+/// Streamer I/O overload
+void TGenCollectionProxy::Streamer(TBuffer &buff, void *objp, int /* siz */ ) {
+  TPushPop env(this, objp);
+  Streamer(buff);
+}
+
+/// TClassStreamer IO overload
+void TGenCollectionProxy::operator()(TBuffer &b, void *objp) {
+  Streamer(b, objp, 0); 
+}
+
diff --git a/io/src/TGenCollectionStreamer.cxx b/io/src/TGenCollectionStreamer.cxx
new file mode 100644
index 00000000000..e94b36a4fbe
--- /dev/null
+++ b/io/src/TGenCollectionStreamer.cxx
@@ -0,0 +1,490 @@
+// @(#)root/cont:$Name:  $:$Id: TGenCollectionStreamer.cxx,v 1.26 2004/10/13 15:30:22 rdm Exp $
+// Author: Markus Frank 28/10/04
+
+/*************************************************************************
+ * Copyright (C) 1995-2000, Rene Brun and Fons Rademakers.               *
+ * All rights reserved.                                                  *
+ *                                                                       *
+ * For the licensing terms see $ROOTSYS/LICENSE.                         *
+ * For the list of contributors see $ROOTSYS/README/CREDITS.             *
+ *************************************************************************/
+
+//////////////////////////////////////////////////////////////////////////
+//                                                                      //
+// TGenCollectionStreamer
+//
+// Streamer around an arbitrary container, which implements basic 
+// functionality and iteration.
+//
+// In particular this is used to implement splitting and abstract
+// element access of any container. Access to compiled code is necessary
+// to implement the abstract iteration sequence and functionality like
+// size(), clear(), resize(). resize() may be a void operation.
+//
+//////////////////////////////////////////////////////////////////////////
+
+#include "TGenCollectionStreamer.h"
+#include "TStreamerInfo.h"
+#include "TClassEdit.h"
+#include "TError.h"
+#include "TROOT.h"
+#include <iostream>
+
+/// Build a Streamer for an emulated vector whose type is 'name'.
+TGenCollectionStreamer::TGenCollectionStreamer(const TGenCollectionStreamer& copy)
+: TGenCollectionProxy(copy)
+{
+}
+
+/// Build a Streamer for a collection whose type is described by 'collectionClass'.
+TGenCollectionStreamer::TGenCollectionStreamer(Info_t info, size_t iter_size)
+: TGenCollectionProxy(info, iter_size)
+{
+}
+
+/// Standard destructor
+TGenCollectionStreamer::~TGenCollectionStreamer()   {
+}
+
+/// Virtual copy constructor
+TVirtualCollectionProxy* TGenCollectionStreamer::Generate() const  { 
+  if ( !fClass ) Initialize();
+  return new TGenCollectionStreamer(*this);
+}
+
+/// Primitive input streamer
+void TGenCollectionStreamer::ReadPrimitives(int nElements, TBuffer &b)  {
+  size_t len = fValDiff*nElements;
+  char   buffer[8096];
+  bool   feed = false;
+  void*  memory = 0;
+  StreamHelper* itm = 0;
+  fEnv->size = nElements;
+  switch ( fSTL_type )  {
+    case TClassEdit::kVector:
+      if ( fVal->fKind != EDataType(kBOOL_t) )  {
+        itm = (StreamHelper*)fResize.invoke(fEnv);
+        break;
+      }
+    default:
+      feed = true;
+      itm = (StreamHelper*)(len<sizeof(buffer) ? buffer : memory=::operator new(len));
+      break;
+  }
+  fEnv->start = itm;
+  switch( int(fValue->fKind) )   {
+    case kChar_t:    b.ReadFastArray(&itm->s_char    , nElements); break;
+    case kShort_t:   b.ReadFastArray(&itm->s_short   , nElements); break;
+    case kInt_t:     b.ReadFastArray(&itm->s_int     , nElements); break;
+    case kLong_t:    b.ReadFastArray(&itm->s_long    , nElements); break;
+    case kLong64_t:  b.ReadFastArray(&itm->s_longlong, nElements); break;
+    case kFloat_t:   b.ReadFastArray(&itm->flt       , nElements); break;
+    case kDouble_t:  b.ReadFastArray(&itm->dbl       , nElements); break;
+    case kBOOL_t:    b.ReadFastArray(&itm->boolean   , nElements); break;
+    case kUChar_t:   b.ReadFastArray(&itm->u_char    , nElements); break;
+    case kUShort_t:  b.ReadFastArray(&itm->u_short   , nElements); break;
+    case kUInt_t:    b.ReadFastArray(&itm->u_int     , nElements); break;
+    case kULong_t:   b.ReadFastArray(&itm->u_long    , nElements); break;
+    case kULong64_t: b.ReadFastArray(&itm->u_longlong, nElements); break;
+    case kDouble32_t:b.ReadFastArrayDouble32(&itm->dbl,nElements); break;
+    case kchar:
+    case kNoType_t:
+    case kOther_t:
+      Error("TGenCollectionStreamer","fType %d is not supported yet!\n",fValue->fKind);
+  }
+  if ( feed )  {    // need to feed in data...
+    fEnv->start = fFeed.invoke(fEnv);
+    if ( memory )  {
+      ::operator delete(memory);
+    }
+  }
+}
+
+/// Object input streamer
+void TGenCollectionStreamer::ReadObjects(int nElements, TBuffer &b)  {
+  bool vsn3 = b.GetInfo() && b.GetInfo()->GetOldVersion()<=3;
+  size_t len = fValDiff*nElements;
+  StreamHelper* itm = 0;
+  char   buffer[8096];
+  void*  memory = 0;
+
+  fEnv->size = nElements;
+  switch ( fSTL_type )  {
+    // Simple case: contiguous memory. get address of first, then jump.
+    case TClassEdit::kVector:
+#define DOLOOP(x) {int idx=0; while(idx<nElements) {StreamHelper* i=(StreamHelper*)(((char*)itm) + fValDiff*idx); { x ;} ++idx;} break;}
+      itm = (StreamHelper*)fResize.invoke(fEnv);
+      switch (fValue->fCase) {
+        case G__BIT_ISCLASS: 
+          DOLOOP( b.StreamObject(i,fValue->fType) );
+        case R__BIT_ISSTRING:
+          DOLOOP( i->read_std_string(b) );
+        case G__BIT_ISPOINTER|G__BIT_ISCLASS:
+          DOLOOP( i->set(b.ReadObjectAny(fValue->fType)) );
+        case G__BIT_ISPOINTER|R__BIT_ISSTRING:
+#ifndef R__AIX
+          DOLOOP( i->read_std_string_pointer(b) );
+#endif
+        case G__BIT_ISPOINTER|R__BIT_ISTSTRING|G__BIT_ISCLASS:  
+          DOLOOP( i->read_tstring_pointer(vsn3,b) );
+      }
+#undef DOLOOP
+      break;
+
+    // No contiguous memory, but resize is possible
+    // Hence accessing objects using At(i) should be not too much an overhead
+    case TClassEdit::kList:
+    case TClassEdit::kDeque:
+#define DOLOOP(x) {int idx=0; while(idx<nElements) {StreamHelper* i=(StreamHelper*)TGenCollectionProxy::At(idx); { x ;} ++idx;} break;}
+      fResize.invoke(fEnv);
+      switch (fValue->fCase) {
+        case G__BIT_ISCLASS:
+          DOLOOP( b.StreamObject(i,fValue->fType) );
+        case R__BIT_ISSTRING:
+          DOLOOP( i->read_std_string(b) );
+        case G__BIT_ISPOINTER|G__BIT_ISCLASS:
+          DOLOOP( i->set( b.ReadObjectAny(fValue->fType) ) );
+        case G__BIT_ISPOINTER|R__BIT_ISSTRING:
+#ifndef R__AIX
+          DOLOOP( i->read_std_string_pointer(b) );
+#endif
+        case G__BIT_ISPOINTER|R__BIT_ISTSTRING|G__BIT_ISCLASS:
+          DOLOOP( i->read_tstring_pointer(vsn3,b) );
+      }
+#undef DOLOOP
+      break;
+
+    // Rather troublesome case: Objects can only be fed into the container
+    // Once they are created. Need to take memory from stack or heap.
+    case TClassEdit::kMultiSet:
+    case TClassEdit::kSet:
+#define DOLOOP(x) {int idx=0; while(idx<nElements) {StreamHelper* i=(StreamHelper*)(((char*)itm) + fValDiff*idx); { x ;} ++idx;}}
+      fEnv->start = itm = (StreamHelper*)(len<sizeof(buffer) ? buffer : memory=::operator new(len));
+      fConstruct.invoke(fEnv);
+      switch ( fValue->fCase ) {
+        case G__BIT_ISCLASS:
+          DOLOOP( b.StreamObject(i,fValue->fType) )
+          fFeed.invoke(fEnv);
+          fDestruct.invoke(fEnv);
+          break;
+        case R__BIT_ISSTRING:
+          DOLOOP( i->read_std_string(b) )
+          fFeed.invoke(fEnv);
+          fDestruct.invoke(fEnv);
+          break;
+        case G__BIT_ISPOINTER|G__BIT_ISCLASS:
+          DOLOOP( i->set(b.ReadObjectAny(fValue->fType)) );
+          fFeed.invoke(fEnv);
+          break;
+        case G__BIT_ISPOINTER|R__BIT_ISSTRING:
+#ifndef R__AIX
+          DOLOOP( i->read_std_string_pointer(b) )
+          fFeed.invoke(fEnv);
+#endif
+          break;
+        case G__BIT_ISPOINTER|R__BIT_ISTSTRING|G__BIT_ISCLASS:
+          DOLOOP( i->read_tstring_pointer(vsn3,b) )
+          fFeed.invoke(fEnv);
+          break;
+      }
+#undef DOLOOP
+      break;
+    default:
+      break;
+  }
+  if ( memory ) {
+    ::operator delete(memory);
+  }
+}
+
+/// Map input streamer
+void TGenCollectionStreamer::ReadMap(int nElements, TBuffer &b)  {
+  bool vsn3 = b.GetInfo() && b.GetInfo()->GetOldVersion()<=3;
+  size_t len = fValDiff*nElements;
+  Value  *v;
+  char buffer[8096], *addr, *temp;
+  void* memory = 0;
+  StreamHelper* i;
+  float f;
+  fEnv->size  = nElements;
+  fEnv->start = (len<sizeof(buffer) ? buffer : memory=::operator new(len));
+  addr = temp = (char*)fEnv->start;
+  fConstruct.invoke(fEnv);
+  for ( int loop, idx = 0; idx < nElements; ++idx )  {
+    addr = temp + fValDiff*idx;
+    v = fKey;
+    for ( loop=0; loop<2; loop++ )  {
+      i = (StreamHelper*)addr;
+      switch (v->fCase) {
+        case G__BIT_ISFUNDAMENTAL:  // Only handle primitives this way
+        case G__BIT_ISENUM:
+          switch( int(v->fKind) )   {
+            case kChar_t:    b >> i->s_char;      break;
+            case kShort_t:   b >> i->s_short;     break;
+            case kInt_t:     b >> i->s_int;       break;
+            case kLong_t:    b >> i->s_long;      break;
+            case kLong64_t:  b >> i->s_longlong;  break;
+            case kFloat_t:   b >> i->flt;         break;
+            case kDouble_t:  b >> i->dbl;         break;
+            case kBOOL_t:    b >> i->boolean;     break;
+            case kUChar_t:   b >> i->u_char;      break;
+            case kUShort_t:  b >> i->u_short;     break;
+            case kUInt_t:    b >> i->u_int;       break;
+            case kULong_t:   b >> i->u_long;      break;
+            case kULong64_t: b >> i->u_longlong;  break;
+            case kDouble32_t:b >> f; 
+                             i->dbl = double(f);  break;
+            case kchar:
+            case kNoType_t:
+            case kOther_t:
+              Error("TGenCollectionStreamer","fType %d is not supported yet!\n",v->fKind);
+          }
+          break;
+        case G__BIT_ISCLASS:
+          b.StreamObject(i,v->fType);
+          break;
+        case R__BIT_ISSTRING:
+          i->read_std_string(b);
+          break;
+        case G__BIT_ISPOINTER|G__BIT_ISCLASS:
+          i->set(b.ReadObjectAny(v->fType));
+          break;
+        case G__BIT_ISPOINTER|R__BIT_ISSTRING:
+#ifndef R__AIX
+          i->read_std_string_pointer(b);
+#endif
+          break;
+        case G__BIT_ISPOINTER|R__BIT_ISTSTRING|G__BIT_ISCLASS:
+          i->read_tstring_pointer(vsn3,b);
+          break;
+      }
+      v = fVal;
+      addr += fValOffset;
+    }
+  }
+  fFeed.invoke(fEnv);
+  fDestruct.invoke(fEnv);
+  if ( memory ) {
+    ::operator delete(memory);
+  }
+}
+
+/// Primitive output streamer
+void TGenCollectionStreamer::WritePrimitives(int nElements, TBuffer &b)  {
+  size_t len = fValDiff*nElements;
+  char   buffer[8192];
+  void*  memory  = 0;
+  StreamHelper* itm = 0;
+
+  switch ( fSTL_type )  {
+    case TClassEdit::kVector:
+      if ( fVal->fKind != EDataType(kBOOL_t) )  {
+        itm = (StreamHelper*)(fEnv->start = fFirst.invoke(fEnv));
+        break;
+      }
+    default:
+      fEnv->start = itm = (StreamHelper*) (len<sizeof(buffer) ? buffer : memory=::operator new(len));
+      fCollect.invoke(fEnv);
+      break;
+  }
+  switch( int(fValue->fKind) )   {
+    case kChar_t:    b.WriteFastArray(&itm->s_char    , nElements); break;
+    case kShort_t:   b.WriteFastArray(&itm->s_short   , nElements); break;
+    case kInt_t:     b.WriteFastArray(&itm->s_int     , nElements); break;
+    case kLong_t:    b.WriteFastArray(&itm->s_long    , nElements); break;
+    case kLong64_t:  b.WriteFastArray(&itm->s_longlong, nElements); break;
+    case kFloat_t:   b.WriteFastArray(&itm->flt       , nElements); break;
+    case kDouble_t:  b.WriteFastArray(&itm->dbl       , nElements); break;
+    case kBOOL_t:    b.WriteFastArray(&itm->boolean   , nElements); break;
+    case kUChar_t:   b.WriteFastArray(&itm->u_char    , nElements); break;
+    case kUShort_t:  b.WriteFastArray(&itm->u_short   , nElements); break;
+    case kUInt_t:    b.WriteFastArray(&itm->u_int     , nElements); break;
+    case kULong_t:   b.WriteFastArray(&itm->u_long    , nElements); break;
+    case kULong64_t: b.WriteFastArray(&itm->u_longlong, nElements); break;
+    case kDouble32_t:b.WriteFastArrayDouble32(&itm->dbl,nElements); break;
+    case kchar:
+    case kNoType_t:
+    case kOther_t:
+      Error("TGenCollectionStreamer","fType %d is not supported yet!\n",fValue->fKind);
+  }
+  if ( memory )  {
+    ::operator delete(memory);
+  }
+}
+
+/// Object output streamer
+void TGenCollectionStreamer::WriteObjects(int nElements, TBuffer &b)  {
+  StreamHelper* itm = 0;
+  switch(fSTL_type)  {
+    // Simple case: contiguous memory. get address of first, then jump.
+    case TClassEdit::kVector:
+#define DOLOOP(x) {int idx=0; while(idx<nElements) {StreamHelper* i=(StreamHelper*)(((char*)itm) + fValDiff*idx); { x ;} ++idx;} break;}
+      itm = (StreamHelper*)fFirst.invoke(fEnv);
+      switch (fValue->fCase) {
+        case G__BIT_ISCLASS: 
+          DOLOOP( b.StreamObject(i,fValue->fType));
+          break;
+        case R__BIT_ISSTRING:
+          DOLOOP( TString(i->c_str()).Streamer(b));
+          break;
+        case G__BIT_ISPOINTER|G__BIT_ISCLASS:
+          DOLOOP( b.WriteObjectAny(i->ptr(),fValue->fType) );
+          break;
+        case R__BIT_ISSTRING|G__BIT_ISPOINTER:
+#ifndef R__AIX
+          DOLOOP( i->write_std_string_pointer(b));
+#endif
+          break;
+        case R__BIT_ISTSTRING|G__BIT_ISCLASS|G__BIT_ISPOINTER:
+          DOLOOP( i->write_tstring_pointer(b));
+          break;
+      }
+#undef DOLOOP
+      break;
+
+    // No contiguous memory, but resize is possible
+    // Hence accessing objects using At(i) should be not too much an overhead
+    case TClassEdit::kList:
+    case TClassEdit::kDeque:
+    case TClassEdit::kMultiSet:
+    case TClassEdit::kSet:
+#define DOLOOP(x) {int idx=0; while(idx<nElements) {StreamHelper* i=(StreamHelper*)TGenCollectionProxy::At(idx); { x ;} ++idx;} break;}
+      switch (fValue->fCase) {
+        case G__BIT_ISCLASS: 
+          DOLOOP( b.StreamObject(i,fValue->fType));
+        case R__BIT_ISSTRING:
+          DOLOOP( TString(i->c_str()).Streamer(b));
+        case G__BIT_ISPOINTER|G__BIT_ISCLASS:
+          DOLOOP( b.WriteObjectAny(i->ptr(),fValue->fType) );
+        case R__BIT_ISSTRING|G__BIT_ISPOINTER:
+#ifndef R__AIX
+          DOLOOP( i->write_std_string_pointer(b));
+#endif
+        case R__BIT_ISTSTRING|G__BIT_ISCLASS|G__BIT_ISPOINTER:
+          DOLOOP( i->write_tstring_pointer(b));
+      }
+#undef DOLOOP
+      break;
+    default:
+      break;
+  }
+}
+
+/// Map output streamer
+void TGenCollectionStreamer::WriteMap(int nElements, TBuffer &b)  {
+  StreamHelper* i;
+  Value  *v;
+
+  for (int loop, idx = 0; idx < nElements; ++idx )  {
+    char* addr = (char*)TGenCollectionProxy::At(idx);
+    v = fKey;
+    for ( loop = 0; loop<2; ++loop )  {
+      i = (StreamHelper*)addr;
+      switch (v->fCase) {
+        case G__BIT_ISFUNDAMENTAL:  // Only handle primitives this way
+        case G__BIT_ISENUM:
+          switch( int(v->fKind) )   {
+            case kChar_t:    b << i->s_char;      break;
+            case kShort_t:   b << i->s_short;     break;
+            case kInt_t:     b << i->s_int;       break;
+            case kLong_t:    b << i->s_long;      break;
+            case kLong64_t:  b << i->s_longlong;  break;
+            case kFloat_t:   b << i->flt;         break;
+            case kDouble_t:  b << i->dbl;         break;
+            case kBOOL_t:    b << i->boolean;     break;
+            case kUChar_t:   b << i->u_char;      break;
+            case kUShort_t:  b << i->u_short;     break;
+            case kUInt_t:    b << i->u_int;       break;
+            case kULong_t:   b << i->u_long;      break;
+            case kULong64_t: b << i->u_longlong;  break;
+            case kDouble32_t:b << float(i->dbl);  break;
+            case kchar:
+            case kNoType_t:
+            case kOther_t:
+              Error("TGenCollectionStreamer","fType %d is not supported yet!\n",v->fKind);
+          }
+          break;
+        case G__BIT_ISCLASS: 
+          b.StreamObject(i,v->fType);
+          break;
+        case R__BIT_ISSTRING:
+          TString(i->c_str()).Streamer(b);
+          break;
+        case G__BIT_ISPOINTER|G__BIT_ISCLASS:
+          b.WriteObjectAny(i->ptr(),v->fType);
+          break;
+        case R__BIT_ISSTRING|G__BIT_ISPOINTER:
+#ifndef R__AIX
+          i->write_std_string_pointer(b);
+#endif
+          break;
+        case R__BIT_ISTSTRING|G__BIT_ISCLASS|G__BIT_ISPOINTER:
+          i->write_tstring_pointer(b);
+          break;
+      }
+      addr += fValOffset;
+      v = fVal;
+    }
+  }
+}
+
+/// TClassStreamer IO overload
+void TGenCollectionStreamer::Streamer(TBuffer &b) {
+  if ( b.IsReading() ) {  //Read mode 
+    int nElements = 0;
+    b >> nElements;
+    if ( fEnv->object )   {
+      TGenCollectionProxy::Clear("force");
+    }
+    if ( nElements > 0 )  {
+      switch(fSTL_type)  {
+        case TClassEdit::kVector:
+        case TClassEdit::kList:
+        case TClassEdit::kDeque:
+        case TClassEdit::kMultiSet:
+        case TClassEdit::kSet:
+          switch (fValue->fCase) {
+            case G__BIT_ISFUNDAMENTAL:  // Only handle primitives this way
+            case G__BIT_ISENUM:
+              ReadPrimitives(nElements, b); 
+              return;
+            default:
+              ReadObjects(nElements, b);
+              return;
+          }
+          break;
+        case TClassEdit::kMap:
+        case TClassEdit::kMultiMap:
+          ReadMap(nElements, b);
+          break;
+      }
+    }
+  }
+  else {     // Write case
+    int nElements = fEnv->object ? *(size_t*)fSize.invoke(fEnv) : 0;
+    b << nElements;
+    if ( nElements > 0 )  {
+      switch(fSTL_type)  {
+        case TClassEdit::kVector:
+        case TClassEdit::kList:
+        case TClassEdit::kDeque:
+        case TClassEdit::kMultiSet:
+        case TClassEdit::kSet:
+          switch (fValue->fCase) {
+            case G__BIT_ISFUNDAMENTAL:  // Only handle primitives this way
+            case G__BIT_ISENUM:
+              WritePrimitives(nElements, b);
+              return;
+            default:
+              WriteObjects(nElements, b);
+              return;
+          }
+          break;
+        case TClassEdit::kMap:
+        case TClassEdit::kMultiMap:
+          WriteMap(nElements, b);
+          break;
+      }
+    }
+  }
+}
diff --git a/meta/src/TClass.cxx b/meta/src/TClass.cxx
index 5a8df77b44a..4c39f29aa3e 100644
--- a/meta/src/TClass.cxx
+++ b/meta/src/TClass.cxx
@@ -1,4 +1,4 @@
-// @(#)root/meta:$Name:  $:$Id: TClass.cxx,v 1.152 2004/10/07 17:07:56 brun Exp $
+// @(#)root/meta:$Name:  $:$Id: TClass.cxx,v 1.153 2004/10/29 16:07:32 rdm Exp $
 // Author: Rene Brun   07/01/95
 
 /*************************************************************************
@@ -52,8 +52,8 @@
 #include "TVirtualUtilPad.h"
 #include "TPluginManager.h"
 #include "TStreamer.h"
+#include "TCollectionProxy.h"
 #include "TVirtualCollectionProxy.h"
-#include "TEmulatedVectorProxy.h"
 
 #ifndef WIN32
 extern long G__globalvarpointer;
@@ -682,24 +682,11 @@ void TClass::Init(const char *name, Version_t cversion,
    Int_t stl = TClassEdit::IsSTLCont(GetName(), 0);
 
    if ( stl ) {
-
-      // We have a TClass for an STL container.
-      if (fStreamer==0) {
-         // Need a factory!
-         switch ( stl ) {
-            case -1:
-            case  1: {// vector
-               fStreamer =  new TEmulatedVectorProxy( this );
-               fCollectionProxy = new TEmulatedVectorProxy( this );
-               fSizeof = fCollectionProxy->Sizeof();
-               break;
-            }
-            case 2: {// list
-               // fStreamer = new TEmulatedListProxy( this );
-               break;
-            }
-         }
-      }
+     fCollectionProxy = TCollectionProxy::genEmulatedProxy( GetName() );
+     fSizeof = fCollectionProxy->Sizeof();
+     if (fStreamer==0) {
+       fStreamer =  TCollectionProxy::genEmulatedClassStreamer( GetName() );
+     }
    }
 
 }
diff --git a/meta/src/TGenericClassInfo.cxx b/meta/src/TGenericClassInfo.cxx
index 9aa566651aa..2a21d893de0 100644
--- a/meta/src/TGenericClassInfo.cxx
+++ b/meta/src/TGenericClassInfo.cxx
@@ -1,4 +1,4 @@
-// @(#)root/meta:$Name:  $:$Id: TGenericClassInfo.cxx,v 1.5 2004/01/10 10:52:30 brun Exp $
+// @(#)root/meta:$Name:  $:$Id: TGenericClassInfo.cxx,v 1.6 2004/07/30 19:09:51 brun Exp $
 // Author: Philippe Canal 08/05/2002
 
 /*************************************************************************
@@ -127,6 +127,7 @@ namespace ROOT {
          fClass->SetNewArray(fNewArray);
          fClass->SetDelete(fDelete);
          fClass->SetDeleteArray(fDeleteArray);
+         fClass->SetDestructor(fDestructor);
          fClass->AdoptStreamer(fStreamer); fStreamer = 0;
          if (fCollectionProxy) fClass->CopyCollectionProxy(*fCollectionProxy);
          fClass->SetClassSize(fSizeof);
diff --git a/test/TBench.cxx b/test/TBench.cxx
index a2b1c977dfd..a0c2739904a 100644
--- a/test/TBench.cxx
+++ b/test/TBench.cxx
@@ -8,6 +8,7 @@
 #include "TClass.h"
 //the next include must be the last one on systems like Windows/NT
 #include "TBench.h"
+#include "Riostream.h"
 
 THit hit;
 #ifdef R__WIN32
@@ -15,14 +16,42 @@ THit hit;
 #else
  const char *demofile = "/tmp/bench.root";
 #endif
+ const char* demofile_name(const char* tit)  {
+   static std::string fn;
+#ifdef R__WIN32
+   fn = "$TMP/bench.";
+#else
+   fn = "/tmp/bench.";
+#endif
+   fn += tit;
+   fn += ".root";
+   return fn.c_str();
+ }
+namespace {
+  struct Counter  {
+    std::string name;
+    int count;
+    Counter(const std::string& n) : name(n), count(0) {}
+    ~Counter()  {
+      print();
+    }
+    void print(const std::string& msg="")  {
+      cout << msg << " --- Counter: " << name << " " << count << endl;
+    }
+  };
+}
+
+Counter hitCount("THit");
 
 //-------------------------------------------------------------
 ClassImp(THit)
 //-------------------------------------------------------------
 THit::THit() {
   fPulses = 0;
+  hitCount.count++;
 }
 THit::THit(const THit &hit) {
+  hitCount.count++;
   fX = hit.fX;
   fY = hit.fY;
   fZ = hit.fZ;
@@ -35,12 +64,29 @@ THit::THit(const THit &hit) {
   for (int j=0;j<fNpulses;j++) fPulses[j] = hit.fPulses[j];
 }
 
+THit& THit::operator=(const THit& hit)  {
+  fX = hit.fX;
+  fY = hit.fY;
+  fZ = hit.fZ;
+  for (Int_t i=0;i<10;i++) fTime[i] = hit.fTime[i];
+  fPulses = 0;
+  fNpulses = hit.fNpulses;
+  if (fNpulses == 0) return *this;
+  if (hit.fPulses == 0) return *this;
+  if ( fPulses ) delete [] fPulses;
+  fPulses = new int[fNpulses];
+  for (int j=0;j<fNpulses;j++) fPulses[j] = hit.fPulses[j];
+  return *this;
+}
+
 THit::THit(int t) {
+  hitCount.count++;
   fPulses = 0;
   Set(t);
 }
 
 THit::~THit() {
+   hitCount.count--;
    if (fPulses) delete [] fPulses;
    fPulses = 0;
 }
@@ -81,6 +127,7 @@ ClassImp(TObjHit)
 TObjHit::TObjHit() :THit() {}
 TObjHit::TObjHit(int t) :THit(t) {}
 
+
 //-------------------------------------------------------------
 ClassImp(TSTLhit)
 //-------------------------------------------------------------
@@ -95,6 +142,8 @@ TSTLhit::TSTLhit(Int_t nmax)
 }
 
 TSTLhit::~TSTLhit() {
+  Clear();
+  hitCount.print();
 }
 
 void TSTLhit::Clear(Option_t *)
@@ -117,7 +166,7 @@ Int_t TSTLhit::MakeTree(int mode, int nevents, int compression, int split, float
   TTree *T=0;
   TSTLhit *top = this;
   if (mode > 0) {
-     f = new TFile(demofile,"recreate","STLhit",compression);  
+     f = new TFile(demofile_name("TSTLhit"),"recreate","STLhit",compression);  
      T = new TTree("T","Demo tree");
      T->Branch("event","TSTLhit",&top,64000,split);
   }
@@ -129,7 +178,7 @@ Int_t TSTLhit::MakeTree(int mode, int nevents, int compression, int split, float
   if (mode == 0) return 0;
   T->Write();
   delete f;
-  f = new TFile(demofile);
+  f = new TFile(demofile_name("TSTLhit"));
   Int_t nbytes = f->GetEND();
   cx = f->GetCompressionFactor();
   delete f;
@@ -139,7 +188,7 @@ Int_t TSTLhit::MakeTree(int mode, int nevents, int compression, int split, float
 Int_t TSTLhit::ReadTree()
 {
   TSTLhit *top = this;
-  TFile *f = new TFile(demofile);  
+  TFile *f = new TFile(demofile_name("TSTLhit"));  
   TTree *T = (TTree*)f->Get("T");
   T->SetBranchAddress("event",&top);
   Int_t nevents = (Int_t)T->GetEntries();
@@ -154,46 +203,117 @@ Int_t TSTLhit::ReadTree()
 
 
 //-------------------------------------------------------------
-ClassImp(TSTLhitStar)
+ClassImp(TSTLhitList)
 //-------------------------------------------------------------
-TSTLhitStar::TSTLhitStar()
+TSTLhitList::TSTLhitList()
 {
 }
 
-TSTLhitStar::TSTLhitStar(Int_t nmax)
+TSTLhitList::TSTLhitList(Int_t nmax)
 {
    fNhits = nmax;
-   fList2.reserve(nmax);
 }
 
-TSTLhitStar::~TSTLhitStar() {
+TSTLhitList::~TSTLhitList() {
+  Clear();
+  hitCount.print();
 }
 
-void TSTLhitStar::Clear(Option_t *)
+void TSTLhitList::Clear(Option_t *)
 {
-   for (vector<THit*>::iterator it = fList2.begin(); it<fList2.end(); it++) {
-      delete (*it);
+   fList1.erase(fList1.begin(),fList1.end());
+}
+
+void TSTLhitList::MakeEvent(int /*ievent*/)
+{
+   Clear();
+   for (Int_t j=0; j<fNhits; j++) {
+      hit.Set(j);
+      fList1.push_back(hit);
    }
-   fList2.erase(fList2.begin(),fList2.end());
 }
 
-void TSTLhitStar::MakeEvent(int /*ievent*/)
+Int_t TSTLhitList::MakeTree(int mode, int nevents, int compression, int split, float &cx)
+{
+  TFile *f=0;
+  TTree *T=0;
+  TSTLhitList *top = this;
+  if (mode > 0) {
+     f = new TFile(demofile_name("TSTLhitList"),"recreate","STLhit",compression);  
+     T = new TTree("T","Demo tree");
+     T->Branch("event","TSTLhitList",&top,64000,split);
+  }
+  for (int ievent=0; ievent<nevents; ievent++) {
+     MakeEvent(ievent);
+     if (mode > 0) T->Fill();
+  }
+
+  if (mode == 0) return 0;
+  T->Write();
+  delete f;
+  f = new TFile(demofile_name("TSTLhitList"));
+  Int_t nbytes = f->GetEND();
+  cx = f->GetCompressionFactor();
+  delete f;
+  return nbytes;
+}
+
+Int_t TSTLhitList::ReadTree()
+{
+  TSTLhitList *top = this;
+  TFile *f = new TFile(demofile_name("TSTLhitList"));  
+  TTree *T = (TTree*)f->Get("T");
+  T->SetBranchAddress("event",&top);
+  Int_t nevents = (Int_t)T->GetEntries();
+  Int_t nbytes = 0;
+  for (int ievent=0; ievent<nevents; ievent++) {
+     nbytes += T->GetEntry(ievent);
+     Clear();
+  }
+  delete f;
+  return nbytes;
+}
+
+//-------------------------------------------------------------
+ClassImp(TSTLhitDeque)
+//-------------------------------------------------------------
+TSTLhitDeque::TSTLhitDeque()
+{
+}
+
+TSTLhitDeque::TSTLhitDeque(Int_t nmax)
+{
+   fNhits = nmax;
+}
+
+TSTLhitDeque::~TSTLhitDeque() {
+  Clear();
+  hitCount.print();
+}
+
+void TSTLhitDeque::Clear(Option_t *)
+{
+   fList1.erase(fList1.begin(),fList1.end());
+}
+
+void TSTLhitDeque::MakeEvent(int /*ievent*/)
 {
    Clear();
    for (Int_t j=0; j<fNhits; j++) {
-      fList2.push_back(new THit(j));
+      hit.Set(j);
+      fList1.push_back(hit);
    }
 }
 
-Int_t TSTLhitStar::MakeTree(int mode, int nevents, int compression, int split, float &cx)
+Int_t TSTLhitDeque::MakeTree(int mode, int nevents, int compression, int split, float &cx)
 {
   TFile *f=0;
   TTree *T=0;
-  TSTLhitStar *top = this;
+  TSTLhitDeque *top = this;
   if (mode > 0) {
-     f = new TFile(demofile,"recreate","STLhitStar",compression);  
+     f = new TFile(demofile_name("TSTLhitDeque"),"recreate","STLhit",compression);  
      T = new TTree("T","Demo tree");
-     T->Branch("event","TSTLhitStar",&top,64000,split);
+     T->Branch("event","TSTLhitDeque",&top,64000,split);
   }
   for (int ievent=0; ievent<nevents; ievent++) {
      MakeEvent(ievent);
@@ -203,17 +323,163 @@ Int_t TSTLhitStar::MakeTree(int mode, int nevents, int compression, int split, f
   if (mode == 0) return 0;
   T->Write();
   delete f;
-  f = new TFile(demofile);
+  f = new TFile(demofile_name("TSTLhitDeque"));
   Int_t nbytes = f->GetEND();
   cx = f->GetCompressionFactor();
   delete f;
   return nbytes;
 }
 
-Int_t TSTLhitStar::ReadTree()
+Int_t TSTLhitDeque::ReadTree()
 {
-  TSTLhitStar *top = this;
-  TFile *f = new TFile(demofile);  
+  TSTLhitDeque *top = this;
+  TFile *f = new TFile(demofile_name("TSTLhitDeque"));  
+  TTree *T = (TTree*)f->Get("T");
+  T->SetBranchAddress("event",&top);
+  Int_t nevents = (Int_t)T->GetEntries();
+  Int_t nbytes = 0;
+  for (int ievent=0; ievent<nevents; ievent++) {
+     nbytes += T->GetEntry(ievent);
+     Clear();
+  }
+  delete f;
+  return nbytes;
+}
+
+
+//-------------------------------------------------------------
+ClassImp(TSTLhitSet)
+//-------------------------------------------------------------
+TSTLhitSet::TSTLhitSet()
+{
+}
+
+TSTLhitSet::TSTLhitSet(Int_t nmax)
+{
+   fNhits = nmax;
+}
+
+TSTLhitSet::~TSTLhitSet() {
+  Clear();
+  hitCount.print();
+}
+
+void TSTLhitSet::Clear(Option_t *)
+{
+   fList1.erase(fList1.begin(),fList1.end());
+}
+
+void TSTLhitSet::MakeEvent(int /*ievent*/)
+{
+   Clear();
+   for (Int_t j=0; j<fNhits; j++) {
+      hit.Set(j);
+      fList1.insert(hit);
+   }
+}
+
+Int_t TSTLhitSet::MakeTree(int mode, int nevents, int compression, int split, float &cx)
+{
+  TFile *f=0;
+  TTree *T=0;
+  TSTLhitSet *top = this;
+  if (mode > 0) {
+     f = new TFile(demofile_name("TSTLhitSet"),"recreate","STLhit",compression);  
+     T = new TTree("T","Demo tree");
+     T->Branch("event","TSTLhitSet",&top,64000,split);
+  }
+  for (int ievent=0; ievent<nevents; ievent++) {
+     MakeEvent(ievent);
+     if (mode > 0) T->Fill();
+  }
+
+  if (mode == 0) return 0;
+  T->Write();
+  delete f;
+  f = new TFile(demofile_name("TSTLhitSet"));
+  Int_t nbytes = f->GetEND();
+  cx = f->GetCompressionFactor();
+  delete f;
+  return nbytes;
+}
+
+Int_t TSTLhitSet::ReadTree()
+{
+  TSTLhitSet *top = this;
+  TFile *f = new TFile(demofile_name("TSTLhitSet"));  
+  TTree *T = (TTree*)f->Get("T");
+  T->SetBranchAddress("event",&top);
+  Int_t nevents = (Int_t)T->GetEntries();
+  Int_t nbytes = 0;
+  for (int ievent=0; ievent<nevents; ievent++) {
+     nbytes += T->GetEntry(ievent);
+     Clear();
+  }
+  delete f;
+  return nbytes;
+}
+
+
+//-------------------------------------------------------------
+ClassImp(TSTLhitMultiset)
+//-------------------------------------------------------------
+TSTLhitMultiset::TSTLhitMultiset()
+{
+}
+
+TSTLhitMultiset::TSTLhitMultiset(Int_t nmax)
+{
+   fNhits = nmax;
+}
+
+TSTLhitMultiset::~TSTLhitMultiset() {
+  Clear();
+  hitCount.print();
+}
+
+void TSTLhitMultiset::Clear(Option_t *)
+{
+   fList1.erase(fList1.begin(),fList1.end());
+}
+
+void TSTLhitMultiset::MakeEvent(int /*ievent*/)
+{
+   Clear();
+   for (Int_t j=0; j<fNhits; j++) {
+      hit.Set(j);
+      fList1.insert(hit);
+   }
+}
+
+Int_t TSTLhitMultiset::MakeTree(int mode, int nevents, int compression, int split, float &cx)
+{
+  TFile *f=0;
+  TTree *T=0;
+  TSTLhitMultiset *top = this;
+  if (mode > 0) {
+     f = new TFile(demofile_name("TSTLhitMultiset"),"recreate","STLhit",compression);  
+     T = new TTree("T","Demo tree");
+     T->Branch("event","TSTLhitMultiset",&top,64000,split);
+  }
+  for (int ievent=0; ievent<nevents; ievent++) {
+     MakeEvent(ievent);
+     if (mode > 0) T->Fill();
+  }
+
+  if (mode == 0) return 0;
+  T->Write();
+  delete f;
+  f = new TFile(demofile_name("TSTLhitMultiset"));
+  Int_t nbytes = f->GetEND();
+  cx = f->GetCompressionFactor();
+  delete f;
+  return nbytes;
+}
+
+Int_t TSTLhitMultiset::ReadTree()
+{
+  TSTLhitMultiset *top = this;
+  TFile *f = new TFile(demofile_name("TSTLhitMultiset"));  
   TTree *T = (TTree*)f->Get("T");
   T->SetBranchAddress("event",&top);
   Int_t nevents = (Int_t)T->GetEntries();
@@ -227,6 +493,824 @@ Int_t TSTLhitStar::ReadTree()
 }
 
 
+//-------------------------------------------------------------
+ClassImp(TSTLhitMap)
+//-------------------------------------------------------------
+TSTLhitMap::TSTLhitMap()
+{
+}
+
+TSTLhitMap::TSTLhitMap(Int_t nmax)
+{
+   fNhits = nmax;
+}
+
+TSTLhitMap::~TSTLhitMap() {
+  Clear();
+  hitCount.print();
+}
+
+void TSTLhitMap::Clear(Option_t *)
+{
+   fList1.clear();
+}
+
+void TSTLhitMap::MakeEvent(int /*ievent*/)
+{
+   Clear();
+   for (Int_t j=0; j<fNhits; j++) {
+      hit.Set(j);
+      fList1.insert(std::make_pair(j,hit));
+   }
+}
+
+Int_t TSTLhitMap::MakeTree(int mode, int nevents, int compression, int split, float &cx)
+{
+  TFile *f=0;
+  TTree *T=0;
+  TSTLhitMap *top = this;
+  if (mode > 0) {
+     f = new TFile(demofile_name("TSTLhitMap"),"recreate","STLhit",compression);  
+     T = new TTree("T","Demo tree");
+     T->Branch("event","TSTLhitMap",&top,64000,split);
+  }
+  for (int ievent=0; ievent<nevents; ievent++) {
+     MakeEvent(ievent);
+     if (mode > 0) T->Fill();
+  }
+
+  if (mode == 0) return 0;
+  T->Write();
+  delete f;
+  f = new TFile(demofile_name("TSTLhitMap"));
+  Int_t nbytes = f->GetEND();
+  cx = f->GetCompressionFactor();
+  delete f;
+  return nbytes;
+}
+
+Int_t TSTLhitMap::ReadTree()
+{
+  TSTLhitMap *top = this;
+  TFile *f = new TFile(demofile_name("TSTLhitMap"));  
+  TTree *T = (TTree*)f->Get("T");
+  T->SetBranchAddress("event",&top);
+  Int_t nevents = (Int_t)T->GetEntries();
+  Int_t nbytes = 0;
+  for (int ievent=0; ievent<nevents; ievent++) {
+     nbytes += T->GetEntry(ievent);
+     Clear();
+  }
+  delete f;
+  return nbytes;
+}
+
+
+//-------------------------------------------------------------
+ClassImp(TSTLhitMultiMap)
+//-------------------------------------------------------------
+TSTLhitMultiMap::TSTLhitMultiMap()
+{
+}
+
+TSTLhitMultiMap::TSTLhitMultiMap(Int_t nmax)
+{
+   fNhits = nmax;
+}
+
+TSTLhitMultiMap::~TSTLhitMultiMap() {
+  Clear();
+  hitCount.print();
+}
+
+void TSTLhitMultiMap::Clear(Option_t *)
+{
+   fList1.clear();
+}
+
+void TSTLhitMultiMap::MakeEvent(int /*ievent*/)
+{
+   Clear();
+   for (Int_t j=0; j<fNhits; j++) {
+      hit.Set(j);
+      std::pair <const int, THit> temp(j,hit);
+      fList1.insert(temp);
+   }
+}
+
+Int_t TSTLhitMultiMap::MakeTree(int mode, int nevents, int compression, int split, float &cx)
+{
+  TFile *f=0;
+  TTree *T=0;
+  TSTLhitMultiMap *top = this;
+  if (mode > 0) {
+     f = new TFile(demofile_name("TSTLhitMultiMap"),"recreate","STLhit",compression);  
+     T = new TTree("T","Demo tree");
+     T->Branch("event","TSTLhitMultiMap",&top,64000,split);
+  }
+  for (int ievent=0; ievent<nevents; ievent++) {
+     MakeEvent(ievent);
+     if (mode > 0) T->Fill();
+  }
+
+  if (mode == 0) return 0;
+  T->Write();
+  delete f;
+  f = new TFile(demofile_name("TSTLhitMultiMap"));
+  Int_t nbytes = f->GetEND();
+  cx = f->GetCompressionFactor();
+  delete f;
+  return nbytes;
+}
+
+Int_t TSTLhitMultiMap::ReadTree()
+{
+  TSTLhitMultiMap *top = this;
+  TFile *f = new TFile(demofile_name("TSTLhitMultiMap"));  
+  TTree *T = (TTree*)f->Get("T");
+  T->SetBranchAddress("event",&top);
+  Int_t nevents = (Int_t)T->GetEntries();
+  Int_t nbytes = 0;
+  for (int ievent=0; ievent<nevents; ievent++) {
+     nbytes += T->GetEntry(ievent);
+     Clear();
+  }
+  delete f;
+  return nbytes;
+}
+
+#if 0
+//-------------------------------------------------------------
+ClassImp(TSTLhitHashSet)
+//-------------------------------------------------------------
+TSTLhitHashSet::TSTLhitHashSet()
+{
+}
+
+TSTLhitHashSet::TSTLhitHashSet(Int_t nmax)
+{
+   fNhits = nmax;
+}
+
+TSTLhitHashSet::~TSTLhitHashSet() {
+  Clear();
+  hitCount.print();
+}
+
+void TSTLhitHashSet::Clear(Option_t *)
+{
+   fList1.erase(fList1.begin(),fList1.end());
+}
+
+void TSTLhitHashSet::MakeEvent(int /*ievent*/)
+{
+   Clear();
+   for (Int_t j=0; j<fNhits; j++) {
+      hit.Set(j);
+      fList1.insert(hit);
+   }
+}
+
+Int_t TSTLhitHashSet::MakeTree(int mode, int nevents, int compression, int split, float &cx)
+{
+  TFile *f=0;
+  TTree *T=0;
+  TSTLhitHashSet *top = this;
+  if (mode > 0) {
+     f = new TFile(demofile,"recreate","STLhit",compression);  
+     T = new TTree("T","Demo tree");
+     T->Branch("event","TSTLhitHashSet",&top,64000,split);
+  }
+  for (int ievent=0; ievent<nevents; ievent++) {
+     MakeEvent(ievent);
+     if (mode > 0) T->Fill();
+  }
+
+  if (mode == 0) return 0;
+  T->Write();
+  delete f;
+  f = new TFile(demofile);
+  Int_t nbytes = f->GetEND();
+  cx = f->GetCompressionFactor();
+  delete f;
+  return nbytes;
+}
+
+Int_t TSTLhitHashSet::ReadTree()
+{
+  TSTLhitHashSet *top = this;
+  TFile *f = new TFile(demofile);  
+  TTree *T = (TTree*)f->Get("T");
+  T->SetBranchAddress("event",&top);
+  Int_t nevents = (Int_t)T->GetEntries();
+  Int_t nbytes = 0;
+  for (int ievent=0; ievent<nevents; ievent++) {
+     nbytes += T->GetEntry(ievent);
+     Clear();
+  }
+  delete f;
+  return nbytes;
+}
+
+
+//-------------------------------------------------------------
+ClassImp(TSTLhitHashMultiSet)
+//-------------------------------------------------------------
+TSTLhitHashMultiSet::TSTLhitHashMultiSet()
+{
+}
+
+TSTLhitHashMultiSet::TSTLhitHashMultiSet(Int_t nmax)
+{
+   fNhits = nmax;
+}
+
+TSTLhitHashMultiSet::~TSTLhitHashMultiSet() {
+  Clear();
+  hitCount.print();
+}
+
+void TSTLhitHashMultiSet::Clear(Option_t *)
+{
+   fList1.erase(fList1.begin(),fList1.end());
+}
+
+void TSTLhitHashMultiSet::MakeEvent(int /*ievent*/)
+{
+   Clear();
+   for (Int_t j=0; j<fNhits; j++) {
+      hit.Set(j);
+      fList1.insert(hit);
+   }
+}
+
+Int_t TSTLhitHashMultiSet::MakeTree(int mode, int nevents, int compression, int split, float &cx)
+{
+  TFile *f=0;
+  TTree *T=0;
+  TSTLhitHashMultiSet *top = this;
+  if (mode > 0) {
+     f = new TFile(demofile,"recreate","STLhit",compression);  
+     T = new TTree("T","Demo tree");
+     T->Branch("event","TSTLhitHashMultiSet",&top,64000,split);
+  }
+  for (int ievent=0; ievent<nevents; ievent++) {
+     MakeEvent(ievent);
+     if (mode > 0) T->Fill();
+  }
+
+  if (mode == 0) return 0;
+  T->Write();
+  delete f;
+  f = new TFile(demofile);
+  Int_t nbytes = f->GetEND();
+  cx = f->GetCompressionFactor();
+  delete f;
+  return nbytes;
+}
+
+Int_t TSTLhitHashMultiSet::ReadTree()
+{
+  TSTLhitHashMultiSet *top = this;
+  TFile *f = new TFile(demofile);  
+  TTree *T = (TTree*)f->Get("T");
+  T->SetBranchAddress("event",&top);
+  Int_t nevents = (Int_t)T->GetEntries();
+  Int_t nbytes = 0;
+  for (int ievent=0; ievent<nevents; ievent++) {
+     nbytes += T->GetEntry(ievent);
+     Clear();
+  }
+  delete f;
+  return nbytes;
+}
+#endif
+
+//-------------------------------------------------------------
+ClassImp(TSTLhitStar)
+//-------------------------------------------------------------
+TSTLhitStar::TSTLhitStar()
+{
+}
+
+TSTLhitStar::TSTLhitStar(Int_t nmax)
+{
+   fNhits = nmax;
+   fList2.reserve(nmax);
+}
+
+TSTLhitStar::~TSTLhitStar() {
+  Clear();
+  hitCount.print();
+}
+
+void TSTLhitStar::Clear(Option_t *)
+{
+   for (vector<THit*>::iterator it = fList2.begin(); it<fList2.end(); it++) {
+      delete (*it);
+   }
+   fList2.erase(fList2.begin(),fList2.end());
+   //hitCount.print("Clear");
+}
+
+void TSTLhitStar::MakeEvent(int /*ievent*/)
+{
+   Clear();
+   for (Int_t j=0; j<fNhits; j++) {
+      fList2.push_back(new THit(j));
+   }
+}
+
+Int_t TSTLhitStar::MakeTree(int mode, int nevents, int compression, int split, float &cx)
+{
+  TFile *f=0;
+  TTree *T=0;
+  TSTLhitStar *top = this;
+  if (mode > 0) {
+     f = new TFile(demofile_name("TSTLhitStar"),"recreate","STLhitStar",compression);  
+     T = new TTree("T","Demo tree");
+     T->Branch("event","TSTLhitStar",&top,64000,split);
+  }
+  for (int ievent=0; ievent<nevents; ievent++) {
+     MakeEvent(ievent);
+     if (mode > 0) T->Fill();
+  }
+
+  if (mode == 0) return 0;
+  T->Write();
+  delete f;
+  f = new TFile(demofile_name("TSTLhitStar"));
+  Int_t nbytes = f->GetEND();
+  cx = f->GetCompressionFactor();
+  delete f;
+  return nbytes;
+}
+
+Int_t TSTLhitStar::ReadTree()
+{
+  TSTLhitStar *top = this;
+  TFile *f = new TFile(demofile_name("TSTLhitStar"));  
+  TTree *T = (TTree*)f->Get("T");
+  T->SetBranchAddress("event",&top);
+  Int_t nevents = (Int_t)T->GetEntries();
+  Int_t nbytes = 0;
+  for (int ievent=0; ievent<nevents; ievent++) {
+     nbytes += T->GetEntry(ievent);
+     Clear();
+  }
+  delete f;
+  return nbytes;
+}
+
+//-------------------------------------------------------------
+ClassImp(TSTLhitStarList)
+//-------------------------------------------------------------
+TSTLhitStarList::TSTLhitStarList()
+{
+}
+
+TSTLhitStarList::TSTLhitStarList(Int_t nmax)
+{
+   fNhits = nmax;
+}
+
+TSTLhitStarList::~TSTLhitStarList() {
+  Clear();
+  hitCount.print();
+}
+
+void TSTLhitStarList::Clear(Option_t *)
+{
+   for (list<THit*>::iterator it = fList2.begin(); it!=fList2.end(); it++) {
+      delete (*it);
+   }
+   fList2.erase(fList2.begin(),fList2.end());
+}
+
+void TSTLhitStarList::MakeEvent(int /*ievent*/)
+{
+   Clear();
+   for (Int_t j=0; j<fNhits; j++) {
+      fList2.push_back(new THit(j));
+   }
+}
+
+Int_t TSTLhitStarList::MakeTree(int mode, int nevents, int compression, int split, float &cx)
+{
+  TFile *f=0;
+  TTree *T=0;
+  TSTLhitStarList *top = this;
+  if (mode > 0) {
+     f = new TFile(demofile_name("TSTLhitStarList"),"recreate","STLhitStar",compression);  
+     T = new TTree("T","Demo tree");
+     T->Branch("event","TSTLhitStarList",&top,64000,split);
+  }
+  for (int ievent=0; ievent<nevents; ievent++) {
+     MakeEvent(ievent);
+     if (mode > 0) T->Fill();
+  }
+
+  if (mode == 0) return 0;
+  T->Write();
+  delete f;
+  f = new TFile(demofile_name("TSTLhitStarList"));
+  Int_t nbytes = f->GetEND();
+  cx = f->GetCompressionFactor();
+  delete f;
+  return nbytes;
+}
+
+Int_t TSTLhitStarList::ReadTree()
+{
+  TSTLhitStarList *top = this;
+  TFile *f = new TFile(demofile_name("TSTLhitStarList"));  
+  TTree *T = (TTree*)f->Get("T");
+  T->SetBranchAddress("event",&top);
+  Int_t nevents = (Int_t)T->GetEntries();
+  Int_t nbytes = 0;
+  for (int ievent=0; ievent<nevents; ievent++) {
+     nbytes += T->GetEntry(ievent);
+     Clear();
+  }
+  delete f;
+  return nbytes;
+}
+
+//-------------------------------------------------------------
+ClassImp(TSTLhitStarDeque)
+//-------------------------------------------------------------
+TSTLhitStarDeque::TSTLhitStarDeque()
+{
+}
+
+TSTLhitStarDeque::TSTLhitStarDeque(Int_t nmax)
+{
+   fNhits = nmax;
+}
+
+TSTLhitStarDeque::~TSTLhitStarDeque() {
+  Clear();
+  hitCount.print();
+}
+
+void TSTLhitStarDeque::Clear(Option_t *)
+{
+   for (deque<THit*>::iterator it = fList2.begin(); it!=fList2.end(); it++) {
+      delete (*it);
+   }
+   fList2.erase(fList2.begin(),fList2.end());
+}
+
+void TSTLhitStarDeque::MakeEvent(int /*ievent*/)
+{
+   Clear();
+   for (Int_t j=0; j<fNhits; j++) {
+      fList2.push_back(new THit(j));
+   }
+}
+
+Int_t TSTLhitStarDeque::MakeTree(int mode, int nevents, int compression, int split, float &cx)
+{
+  TFile *f=0;
+  TTree *T=0;
+  TSTLhitStarDeque *top = this;
+  if (mode > 0) {
+     f = new TFile(demofile_name("TSTLhitStarDeque"),"recreate","STLhitStar",compression);  
+     T = new TTree("T","Demo tree");
+     T->Branch("event","TSTLhitStarDeque",&top,64000,split);
+  }
+  for (int ievent=0; ievent<nevents; ievent++) {
+     MakeEvent(ievent);
+     if (mode > 0) T->Fill();
+  }
+
+  if (mode == 0) return 0;
+  T->Write();
+  delete f;
+  f = new TFile(demofile_name("TSTLhitStarDeque"));
+  Int_t nbytes = f->GetEND();
+  cx = f->GetCompressionFactor();
+  delete f;
+  return nbytes;
+}
+
+Int_t TSTLhitStarDeque::ReadTree()
+{
+  TSTLhitStarDeque *top = this;
+  TFile *f = new TFile(demofile_name("TSTLhitStarDeque"));  
+  TTree *T = (TTree*)f->Get("T");
+  T->SetBranchAddress("event",&top);
+  Int_t nevents = (Int_t)T->GetEntries();
+  Int_t nbytes = 0;
+  for (int ievent=0; ievent<nevents; ievent++) {
+     nbytes += T->GetEntry(ievent);
+     Clear();
+  }
+  delete f;
+  return nbytes;
+}
+
+//-------------------------------------------------------------
+ClassImp(TSTLhitStarSet)
+//-------------------------------------------------------------
+TSTLhitStarSet::TSTLhitStarSet()
+{
+}
+
+TSTLhitStarSet::TSTLhitStarSet(Int_t nmax)
+{
+   fNhits = nmax;
+}
+
+TSTLhitStarSet::~TSTLhitStarSet() {
+  Clear();
+  hitCount.print();
+}
+
+void TSTLhitStarSet::Clear(Option_t *)
+{
+   for (set<THit*>::iterator it = fList2.begin(); it!=fList2.end(); it++) {
+      delete (*it);
+   }
+   fList2.erase(fList2.begin(),fList2.end());
+}
+
+void TSTLhitStarSet::MakeEvent(int /*ievent*/)
+{
+   Clear();
+   for (Int_t j=0; j<fNhits; j++) {
+      fList2.insert(new THit(j));
+   }
+}
+
+Int_t TSTLhitStarSet::MakeTree(int mode, int nevents, int compression, int split, float &cx)
+{
+  TFile *f=0;
+  TTree *T=0;
+  TSTLhitStarSet *top = this;
+  if (mode > 0) {
+     f = new TFile(demofile_name("TSTLhitStarSet"),"recreate","STLhitStar",compression);  
+     T = new TTree("T","Demo tree");
+     T->Branch("event","TSTLhitStarSet",&top,64000,split);
+  }
+  for (int ievent=0; ievent<nevents; ievent++) {
+     MakeEvent(ievent);
+     if (mode > 0) T->Fill();
+  }
+
+  if (mode == 0) return 0;
+  T->Write();
+  delete f;
+  f = new TFile(demofile_name("TSTLhitStarSet"));
+  Int_t nbytes = f->GetEND();
+  cx = f->GetCompressionFactor();
+  delete f;
+  return nbytes;
+}
+
+Int_t TSTLhitStarSet::ReadTree()
+{
+  TSTLhitStarSet *top = this;
+  TFile *f = new TFile(demofile_name("TSTLhitStarSet"));  
+  TTree *T = (TTree*)f->Get("T");
+  T->SetBranchAddress("event",&top);
+  Int_t nevents = (Int_t)T->GetEntries();
+  Int_t nbytes = 0;
+  for (int ievent=0; ievent<nevents; ievent++) {
+     nbytes += T->GetEntry(ievent);
+     Clear();
+  }
+  delete f;
+  return nbytes;
+}
+
+//-------------------------------------------------------------
+ClassImp(TSTLhitStarMultiSet)
+//-------------------------------------------------------------
+TSTLhitStarMultiSet::TSTLhitStarMultiSet()
+{
+}
+
+TSTLhitStarMultiSet::TSTLhitStarMultiSet(Int_t nmax)
+{
+   fNhits = nmax;
+}
+
+TSTLhitStarMultiSet::~TSTLhitStarMultiSet() {
+  Clear();
+  hitCount.print();
+}
+
+void TSTLhitStarMultiSet::Clear(Option_t *)
+{
+   for (multiset<THit*>::iterator it = fList2.begin(); it!=fList2.end(); it++) {
+      delete (*it);
+   }
+   fList2.erase(fList2.begin(),fList2.end());
+}
+
+void TSTLhitStarMultiSet::MakeEvent(int /*ievent*/)
+{
+   Clear();
+   for (Int_t j=0; j<fNhits; j++) {
+      fList2.insert(new THit(j));
+   }
+}
+
+Int_t TSTLhitStarMultiSet::MakeTree(int mode, int nevents, int compression, int split, float &cx)
+{
+  TFile *f=0;
+  TTree *T=0;
+  TSTLhitStarMultiSet *top = this;
+  if (mode > 0) {
+     f = new TFile(demofile_name("TSTLhitStarMultiSet"),"recreate","STLhitStar",compression);  
+     T = new TTree("T","Demo tree");
+     T->Branch("event","TSTLhitStarMultiSet",&top,64000,split);
+  }
+  for (int ievent=0; ievent<nevents; ievent++) {
+     MakeEvent(ievent);
+     if (mode > 0) T->Fill();
+  }
+
+  if (mode == 0) return 0;
+  T->Write();
+  delete f;
+  f = new TFile(demofile_name("TSTLhitStarMultiSet"));
+  Int_t nbytes = f->GetEND();
+  cx = f->GetCompressionFactor();
+  delete f;
+  return nbytes;
+}
+
+Int_t TSTLhitStarMultiSet::ReadTree()
+{
+  TSTLhitStarMultiSet *top = this;
+  TFile *f = new TFile(demofile_name("TSTLhitStarMultiSet"));  
+  TTree *T = (TTree*)f->Get("T");
+  T->SetBranchAddress("event",&top);
+  Int_t nevents = (Int_t)T->GetEntries();
+  Int_t nbytes = 0;
+  for (int ievent=0; ievent<nevents; ievent++) {
+     nbytes += T->GetEntry(ievent);
+     Clear();
+  }
+  delete f;
+  return nbytes;
+}
+
+
+//-------------------------------------------------------------
+ClassImp(TSTLhitStarMap)
+//-------------------------------------------------------------
+TSTLhitStarMap::TSTLhitStarMap()
+{
+}
+
+TSTLhitStarMap::TSTLhitStarMap(Int_t nmax)
+{
+   fNhits = nmax;
+}
+
+TSTLhitStarMap::~TSTLhitStarMap() {
+  Clear();
+  hitCount.print();
+}
+
+void TSTLhitStarMap::Clear(Option_t *)
+{
+   for (map<int,THit*>::iterator it = fList2.begin(); it!=fList2.end(); it++) {
+      delete (*it).second;
+   }
+   fList2.clear();
+}
+
+void TSTLhitStarMap::MakeEvent(int /*ievent*/)
+{
+//   hitCount.print("1");
+   Clear();
+//   hitCount.print("1.1");
+   for (Int_t j=0; j<fNhits; j++) {
+     fList2.insert(std::make_pair(j,new THit(j)));
+   }
+//   hitCount.print("1.2");
+}
+
+Int_t TSTLhitStarMap::MakeTree(int mode, int nevents, int compression, int split, float &cx)
+{
+  TFile *f=0;
+  TTree *T=0;
+  TSTLhitStarMap *top = this;
+  if (mode > 0) {
+     f = new TFile(demofile_name("TSTLhitStarMap"),"recreate","STLhitStar",compression);  
+     T = new TTree("T","Demo tree");
+     T->Branch("event","TSTLhitStarMap",&top,64000,split);
+  }
+  for (int ievent=0; ievent<nevents; ievent++) {
+     MakeEvent(ievent);
+     if (mode > 0) T->Fill();
+  }
+
+  if (mode == 0) return 0;
+  T->Write();
+  delete f;
+  f = new TFile(demofile_name("TSTLhitStarMap"));
+  Int_t nbytes = f->GetEND();
+  cx = f->GetCompressionFactor();
+  delete f;
+  return nbytes;
+}
+
+Int_t TSTLhitStarMap::ReadTree()
+{
+  TSTLhitStarMap *top = this;
+  TFile *f = new TFile(demofile_name("TSTLhitStarMap"));  
+  TTree *T = (TTree*)f->Get("T");
+  T->SetBranchAddress("event",&top);
+  Int_t nevents = (Int_t)T->GetEntries();
+  Int_t nbytes = 0;
+  for (int ievent=0; ievent<nevents; ievent++) {
+     nbytes += T->GetEntry(ievent);
+     Clear();
+  }
+  delete f;
+  return nbytes;
+}
+
+//-------------------------------------------------------------
+ClassImp(TSTLhitStarMultiMap)
+//-------------------------------------------------------------
+TSTLhitStarMultiMap::TSTLhitStarMultiMap()
+{
+}
+
+TSTLhitStarMultiMap::TSTLhitStarMultiMap(Int_t nmax)
+{
+   fNhits = nmax;
+}
+
+TSTLhitStarMultiMap::~TSTLhitStarMultiMap() {
+  Clear();
+  hitCount.print();
+}
+
+void TSTLhitStarMultiMap::Clear(Option_t *)
+{
+   for (multimap<int,THit*>::iterator it = fList2.begin(); it!=fList2.end(); it++) {
+      delete (*it).second;
+   }
+   fList2.clear();
+}
+
+void TSTLhitStarMultiMap::MakeEvent(int /*ievent*/)
+{
+   Clear();
+   for (Int_t j=0; j<fNhits; j++) {
+     std::pair<const int,THit*> temp(j,new THit(j));
+     fList2.insert(temp);
+   }
+}
+
+Int_t TSTLhitStarMultiMap::MakeTree(int mode, int nevents, int compression, int split, float &cx)
+{
+  TFile *f=0;
+  TTree *T=0;
+  TSTLhitStarMultiMap *top = this;
+  if (mode > 0) {
+     f = new TFile(demofile_name("TSTLhitStarMultiMap"),"recreate","STLhitStar",compression);  
+     T = new TTree("T","Demo tree");
+     T->Branch("event","TSTLhitStarMultiMap",&top,64000,split);
+  }
+  for (int ievent=0; ievent<nevents; ievent++) {
+     MakeEvent(ievent);
+     if (mode > 0) T->Fill();
+  }
+
+  if (mode == 0) return 0;
+  T->Write();
+  delete f;
+  f = new TFile(demofile_name("TSTLhitStarMultiMap"));
+  Int_t nbytes = f->GetEND();
+  cx = f->GetCompressionFactor();
+  delete f;
+  return nbytes;
+}
+
+Int_t TSTLhitStarMultiMap::ReadTree()
+{
+  TSTLhitStarMultiMap *top = this;
+  TFile *f = new TFile(demofile_name("TSTLhitStarMultiMap"));  
+  TTree *T = (TTree*)f->Get("T");
+  T->SetBranchAddress("event",&top);
+  Int_t nevents = (Int_t)T->GetEntries();
+  Int_t nbytes = 0;
+  for (int ievent=0; ievent<nevents; ievent++) {
+     nbytes += T->GetEntry(ievent);
+     Clear();
+  }
+  delete f;
+  return nbytes;
+}
+
 //-------------------------------------------------------------
 ClassImp(TCloneshit)
 //-------------------------------------------------------------
@@ -243,6 +1327,8 @@ TCloneshit::TCloneshit(Int_t nmax)
 }
 
 TCloneshit::~TCloneshit() {
+  Clear();
+  hitCount.print();
 }
 
 void TCloneshit::Clear(Option_t *)
diff --git a/test/TBench.h b/test/TBench.h
index dcf91ef0216..6874aaee93c 100644
--- a/test/TBench.h
+++ b/test/TBench.h
@@ -2,14 +2,36 @@
 #define ROOT_TBENCH
    
 #include "TClonesArray.h"
-
+namespace stdext {};
 #include <vector>
+#include <deque>
+#include <list>
+#include <set>
+#include <map>
+
 #ifndef R__GLOBALSTL
 #ifndef WIN32
 using std::vector;
+using std::list;
+using std::deque;
+using std::set;
+using std::multiset;
+using std::map;
+using std::multimap;
 #else
 using namespace std;
+using namespace stdext;
+#endif
 #endif
+
+#ifdef __CINT__
+template<class a,class b,class c> class hash_map : public map<a,b,c> {};
+template<class a,class b> class hash_set : public set<a,b> {};
+template<class a,class b,class c> class hash_multimap : public multimap<a,b,c> {};
+template<class a,class b> class hash_multiset : public multiset<a,b> {};
+#else
+//#include <hash_map>
+//#include <hash_set>
 #endif
 
 //-------------------------------------------------------------
@@ -30,12 +52,28 @@ public:
 
   void  Set (int time);
   inline int Get(int i) { return fTime[i]; }
-  
+  bool operator==(const THit& c) const { return this==&c;}
+  bool operator<(const THit& c) const { return this<&c;}
+  THit& operator=(const THit& c);
   friend TBuffer &operator<<(TBuffer &b, const THit *hit);
 
   ClassDef(THit,1) // the hit class
 };
 
+namespace stdext {
+  template<class T> static inline size_t __gnu_cxx_hash_obj(const T& __o) {
+    unsigned long __h = 0;
+    const char* s = (const char*)&__o;
+    for (size_t i=0; i<sizeof(T); ++s, ++i)
+      __h = 5*__h + *s;
+    return size_t(__h);
+  }
+
+  template <class _Key> struct hash { };
+  inline size_t hash_value(const THit& s)  {
+    return __gnu_cxx_hash_obj(s);
+  }
+}
 #if defined R__TEMPLATE_OVERLOAD_BUG
 template <> 
 #endif
@@ -62,7 +100,7 @@ public:
 class TSTLhit {
 protected:
   Int_t            fNhits;
-  vector <THit>    fList1; //||
+  vector <THit>    fList1;
 
 public:
 
@@ -76,7 +114,155 @@ public:
 
   ClassDef(TSTLhit,1) // STL vector of THit
 };
+//-------------------------------------------------------------
+class TSTLhitList {
+protected:
+  Int_t            fNhits;
+  list   <THit>    fList1;
+
+public:
+
+  TSTLhitList();
+  TSTLhitList(int nmax);
+  void Clear(Option_t *option="");
+  virtual ~TSTLhitList();
+  void MakeEvent(int ievent);
+  Int_t MakeTree(int mode, int nevents, int compression, int split, float &cx);
+  Int_t ReadTree();
+
+  ClassDef(TSTLhitList,1) // STL vector of THit
+};
+
+//-------------------------------------------------------------
+class TSTLhitDeque {
+protected:
+  Int_t            fNhits;
+  deque  <THit>    fList1;
+
+public:
+
+  TSTLhitDeque();
+  TSTLhitDeque(int nmax);
+  void Clear(Option_t *option="");
+  virtual ~TSTLhitDeque();
+  void MakeEvent(int ievent);
+  Int_t MakeTree(int mode, int nevents, int compression, int split, float &cx);
+  Int_t ReadTree();
+
+  ClassDef(TSTLhitDeque,1) // STL vector of THit
+};
       
+//-------------------------------------------------------------
+class TSTLhitMultiset {
+protected:
+  Int_t            fNhits;
+  multiset  <THit>    fList1;
+
+public:
+
+  TSTLhitMultiset();
+  TSTLhitMultiset(int nmax);
+  void Clear(Option_t *option="");
+  virtual ~TSTLhitMultiset();
+  void MakeEvent(int ievent);
+  Int_t MakeTree(int mode, int nevents, int compression, int split, float &cx);
+  Int_t ReadTree();
+
+  ClassDef(TSTLhitMultiset,1) // STL vector of THit
+};
+
+//-------------------------------------------------------------
+class TSTLhitSet {
+protected:
+  Int_t            fNhits;
+  set  <THit>    fList1;
+
+public:
+
+  TSTLhitSet();
+  TSTLhitSet(int nmax);
+  void Clear(Option_t *option="");
+  virtual ~TSTLhitSet();
+  void MakeEvent(int ievent);
+  Int_t MakeTree(int mode, int nevents, int compression, int split, float &cx);
+  Int_t ReadTree();
+
+  ClassDef(TSTLhitSet,1) // STL vector of THit
+};
+//-------------------------------------------------------------
+class TSTLhitMap {
+protected:
+  Int_t            fNhits;
+  map  <int,THit>    fList1;
+
+public:
+
+  TSTLhitMap();
+  TSTLhitMap(int nmax);
+  void Clear(Option_t *option="");
+  virtual ~TSTLhitMap();
+  void MakeEvent(int ievent);
+  Int_t MakeTree(int mode, int nevents, int compression, int split, float &cx);
+  Int_t ReadTree();
+
+  ClassDef(TSTLhitMap,1) // STL vector of THit
+};
+//-------------------------------------------------------------
+class TSTLhitMultiMap {
+protected:
+  Int_t                fNhits;
+  multimap  <int,THit> fList1;
+
+public:
+
+  TSTLhitMultiMap();
+  TSTLhitMultiMap(int nmax);
+  void Clear(Option_t *option="");
+  virtual ~TSTLhitMultiMap();
+  void MakeEvent(int ievent);
+  Int_t MakeTree(int mode, int nevents, int compression, int split, float &cx);
+  Int_t ReadTree();
+
+  ClassDef(TSTLhitMultiMap,1) // STL vector of THit
+};
+#if 0
+//-------------------------------------------------------------
+class TSTLhitHashSet {
+protected:
+  Int_t            fNhits;
+  hash_set  <THit> fList1;
+
+public:
+
+  TSTLhitHashSet();
+  TSTLhitHashSet(int nmax);
+  void Clear(Option_t *option="");
+  virtual ~TSTLhitHashSet();
+  void MakeEvent(int ievent);
+  Int_t MakeTree(int mode, int nevents, int compression, int split, float &cx);
+  Int_t ReadTree();
+
+  ClassDef(TSTLhitHashSet,1) // STL vector of THit
+};
+//-------------------------------------------------------------
+class TSTLhitHashMultiSet {
+protected:
+  Int_t            fNhits;
+  hash_multiset  <THit>    fList1;
+
+public:
+
+  TSTLhitHashMultiSet();
+  TSTLhitHashMultiSet(int nmax);
+  void Clear(Option_t *option="");
+  virtual ~TSTLhitHashMultiSet();
+  void MakeEvent(int ievent);
+  Int_t MakeTree(int mode, int nevents, int compression, int split, float &cx);
+  Int_t ReadTree();
+
+  ClassDef(TSTLhitHashMultiSet,1) // STL vector of THit
+};
+#endif
 //-------------------------------------------------------------
 class TSTLhitStar {
 protected:
@@ -95,6 +281,118 @@ public:
 
   ClassDef(TSTLhitStar,1) // STL vector of pointers to THit
 };
+//-------------------------------------------------------------
+class TSTLhitStarList {
+protected:
+  Int_t            fNhits;
+  list <THit*>   fList2; //
+
+public:
+
+  TSTLhitStarList();
+  TSTLhitStarList(int nmax);
+  void Clear(Option_t *option="");
+  virtual ~TSTLhitStarList();
+  void MakeEvent(int ievent);
+  Int_t MakeTree(int mode, int nevents, int compression, int split, float &cx);
+  Int_t ReadTree();
+
+  ClassDef(TSTLhitStarList,1) // STL vector of pointers to THit
+};
+//-------------------------------------------------------------
+class TSTLhitStarDeque {
+protected:
+  Int_t            fNhits;
+  deque <THit*>   fList2; //
+
+public:
+
+  TSTLhitStarDeque();
+  TSTLhitStarDeque(int nmax);
+  void Clear(Option_t *option="");
+  virtual ~TSTLhitStarDeque();
+  void MakeEvent(int ievent);
+  Int_t MakeTree(int mode, int nevents, int compression, int split, float &cx);
+  Int_t ReadTree();
+
+  ClassDef(TSTLhitStarDeque,1) // STL vector of pointers to THit
+};
+
+//-------------------------------------------------------------
+class TSTLhitStarSet {
+protected:
+  Int_t            fNhits;
+  set <THit*>   fList2; //
+
+public:
+
+  TSTLhitStarSet();
+  TSTLhitStarSet(int nmax);
+  void Clear(Option_t *option="");
+  virtual ~TSTLhitStarSet();
+  void MakeEvent(int ievent);
+  Int_t MakeTree(int mode, int nevents, int compression, int split, float &cx);
+  Int_t ReadTree();
+
+  ClassDef(TSTLhitStarSet,1) // STL vector of pointers to THit
+};
+      
+//-------------------------------------------------------------
+class TSTLhitStarMultiSet {
+protected:
+  Int_t            fNhits;
+  multiset <THit*>   fList2; //
+
+public:
+
+  TSTLhitStarMultiSet();
+  TSTLhitStarMultiSet(int nmax);
+  void Clear(Option_t *option="");
+  virtual ~TSTLhitStarMultiSet();
+  void MakeEvent(int ievent);
+  Int_t MakeTree(int mode, int nevents, int compression, int split, float &cx);
+  Int_t ReadTree();
+
+  ClassDef(TSTLhitStarMultiSet,1) // STL vector of pointers to THit
+};
+      
+//-------------------------------------------------------------
+class TSTLhitStarMap {
+protected:
+  Int_t            fNhits;
+  map <int,THit*>   fList2; //
+
+public:
+
+  TSTLhitStarMap();
+  TSTLhitStarMap(int nmax);
+  void Clear(Option_t *option="");
+  virtual ~TSTLhitStarMap();
+  void MakeEvent(int ievent);
+  Int_t MakeTree(int mode, int nevents, int compression, int split, float &cx);
+  Int_t ReadTree();
+
+  ClassDef(TSTLhitStarMap,1) // STL vector of pointers to THit
+};
+      
+//-------------------------------------------------------------
+class TSTLhitStarMultiMap {
+protected:
+  Int_t            fNhits;
+  multimap<int,THit*>   fList2; //
+
+public:
+
+  TSTLhitStarMultiMap();
+  TSTLhitStarMultiMap(int nmax);
+  void Clear(Option_t *option="");
+  virtual ~TSTLhitStarMultiMap();
+  void MakeEvent(int ievent);
+  Int_t MakeTree(int mode, int nevents, int compression, int split, float &cx);
+  Int_t ReadTree();
+
+  ClassDef(TSTLhitStarMultiMap,1) // STL vector of pointers to THit
+};
       
 //-------------------------------------------------------------
 class TCloneshit {
diff --git a/test/bench.cxx b/test/bench.cxx
index e7f292d6a21..0eca104fb14 100644
--- a/test/bench.cxx
+++ b/test/bench.cxx
@@ -90,6 +90,7 @@ void showhist(const char *title, const char *ytitle, float a, float b, float c,
    boxd->SetFillStyle(3012);
 }
 
+
 int main(int argc, char** argv)
 {
   TRint *theApp = new TRint("Rint", &argc, argv, 0, 0);
@@ -103,6 +104,10 @@ int main(int argc, char** argv)
   //testing STL vector of THit
   Double_t cptot = 0;
   TStopwatch timer;
+
+  //delete temp file used for the benchmark
+  gSystem->Exec("rm -f /tmp/bench.root");
+  /// STL VECTOR
   timer.Start();
   TSTLhit *STLhit = new TSTLhit(nhits);
   STLhit->MakeTree(0,nevents,0,0,cx);
@@ -110,36 +115,277 @@ int main(int argc, char** argv)
   Double_t rt1 = timer.RealTime();
   Double_t cp1 = timer.CpuTime();
   cptot += cp1;
-  printf("1  STLhit :  RT=%6.2f s  Cpu=%6.2f s\n",rt1,cp1);
+  printf("1 vector    : RT=%6.2f s  Cpu=%6.2f s\n",rt1,cp1);
   timer.Start(kTRUE);
-  Int_t nbytes1 = STLhit->MakeTree(1,nevents,0,0,cx);
+  Int_t nbytes1 = STLhit->MakeTree(1,nevents,0,99,cx);
   timer.Stop();
   Double_t rt2w = timer.RealTime();
   Double_t cp2w = timer.CpuTime();
   cptot += cp2w;
-  printf("2  STLhitw:  RT=%6.2f s  Cpu=%6.2f s, size= %8d bytes, cx=%5.2f\n",rt2w-rt1,cp2w-cp1,nbytes1,cx);
+  printf("2 vector   w: RT=%6.2f s  Cpu=%6.2f s, size= %8d bytes, cx=%5.2f\n",rt2w-rt1,cp2w-cp1,nbytes1,cx);
   timer.Start(kTRUE);
   STLhit->ReadTree();
   timer.Stop();
   Double_t rt2r = timer.RealTime();
   Double_t cp2r = timer.CpuTime();
   cptot += cp2r;
-  printf("3  STLhitr:  RT=%6.2f s  Cpu=%6.2f s\n",rt2r,cp2r);
+  printf("3 vector   r: RT=%6.2f s  Cpu=%6.2f s\n",rt2r,cp2r);
   timer.Start(kTRUE);
   Float_t cx3;
-  Int_t nbytes3 = STLhit->MakeTree(1,nevents,1,0,cx3);
+  Int_t nbytes3 = STLhit->MakeTree(1,nevents,1,99,cx3);
   timer.Stop();
   Double_t rt3w = timer.RealTime();
   Double_t cp3w = timer.CpuTime();
   cptot += cp3w;
-  printf("4  STLhitw:  RT=%6.2f s  Cpu=%6.2f s, size= %8d bytes, cx=%5.2f\n",rt3w-rt1,cp3w-cp1,nbytes3,cx3);
+  printf("4 vector   w: RT=%6.2f s  Cpu=%6.2f s, size= %8d bytes, cx=%5.2f\n",rt3w-rt1,cp3w-cp1,nbytes3,cx3);
   timer.Start(kTRUE);
   STLhit->ReadTree();
   timer.Stop();
   Double_t rt3r = timer.RealTime();
   Double_t cp3r = timer.CpuTime();
   cptot += cp3r;
-  printf("5  STLhitr:  RT=%6.2f s  Cpu=%6.2f s\n",rt3r,cp3r);
+  printf("5 vector   r: RT=%6.2f s  Cpu=%6.2f s\n",rt3r,cp3r);
+  delete STLhit;
+
+  // STL list
+  timer.Start();
+  TSTLhitList *STLhit_list = new TSTLhitList(nhits);
+  STLhit_list->MakeTree(0,nevents,0,0,cx);
+  timer.Stop();
+  Double_t rt1L = timer.RealTime();
+  Double_t cp1L = timer.CpuTime();
+  cptot += cp1L;
+  printf("1 list      : RT=%6.2f s  Cpu=%6.2f s\n",rt1L,cp1L);
+  timer.Start(kTRUE);
+  Int_t nbytes1L = STLhit_list->MakeTree(1,nevents,0,99,cx);
+  timer.Stop();
+  Double_t rt2wL = timer.RealTime();
+  Double_t cp2wL = timer.CpuTime();
+  cptot += cp2wL;
+  printf("2 list     w: RT=%6.2f s  Cpu=%6.2f s, size= %8d bytes, cx=%5.2f\n",rt2wL-rt1L,cp2wL-cp1L,nbytes1L,cx);
+  timer.Start(kTRUE);
+  STLhit_list->ReadTree();
+  timer.Stop();
+  Double_t rt2rL = timer.RealTime();
+  Double_t cp2rL = timer.CpuTime();
+  cptot += cp2rL;
+  printf("3 list     r: RT=%6.2f s  Cpu=%6.2f s\n",rt2rL,cp2rL);
+  timer.Start(kTRUE);
+  Float_t cx3L;
+  Int_t nbytes3L = STLhit_list->MakeTree(1,nevents,1,99,cx3L);
+  timer.Stop();
+  Double_t rt3wL = timer.RealTime();
+  Double_t cp3wL = timer.CpuTime();
+  cptot += cp3wL;
+  printf("4 list     w: RT=%6.2f s  Cpu=%6.2f s, size= %8d bytes, cx=%5.2f\n",rt3wL-rt1L,cp3wL-cp1L,nbytes3L,cx3L);
+  timer.Start(kTRUE);
+  STLhit_list->ReadTree();
+  timer.Stop();
+  Double_t rt3rL = timer.RealTime();
+  Double_t cp3rL = timer.CpuTime();
+  cptot += cp3rL;
+  printf("5 list     r: RT=%6.2f s  Cpu=%6.2f s\n",rt3rL,cp3rL);
+  delete STLhit_list;
+
+  // STL DEQUE
+  timer.Start();
+  TSTLhitDeque *STLhit_deque = new TSTLhitDeque(nhits);
+  STLhit_deque->MakeTree(0,nevents,0,0,cx);
+  timer.Stop();
+  Double_t rt1D = timer.RealTime();
+  Double_t cp1D = timer.CpuTime();
+  cptot += cp1D;
+  printf("1 deque     : RT=%6.2f s  Cpu=%6.2f s\n",rt1D,cp1D);
+  timer.Start(kTRUE);
+  Int_t nbytes1D = STLhit_deque->MakeTree(1,nevents,0,99,cx);
+  timer.Stop();
+  Double_t rt2wD = timer.RealTime();
+  Double_t cp2wD = timer.CpuTime();
+  cptot += cp2wD;
+  printf("2 deque    w: RT=%6.2f s  Cpu=%6.2f s, size= %8d bytes, cx=%5.2f\n",rt2wD-rt1D,cp2wD-cp1D,nbytes1D,cx);
+  timer.Start(kTRUE);
+  STLhit_deque->ReadTree();
+  timer.Stop();
+  Double_t rt2rD = timer.RealTime();
+  Double_t cp2rD = timer.CpuTime();
+  cptot += cp2rD;
+  printf("3 deque    r: RT=%6.2f s  Cpu=%6.2f s\n",rt2rD,cp2rD);
+  timer.Start(kTRUE);
+  Float_t cx3D;
+  Int_t nbytes3D = STLhit_deque->MakeTree(1,nevents,1,99,cx3D);
+  timer.Stop();
+  Double_t rt3wD = timer.RealTime();
+  Double_t cp3wD = timer.CpuTime();
+  cptot += cp3wD;
+  printf("4 deque    w: RT=%6.2f s  Cpu=%6.2f s, size= %8d bytes, cx=%5.2f\n",rt3wD-rt1D,cp3wD-cp1D,nbytes3D,cx3D);
+  timer.Start(kTRUE);
+  STLhit_deque->ReadTree();
+  timer.Stop();
+  Double_t rt3rD = timer.RealTime();
+  Double_t cp3rD = timer.CpuTime();
+  cptot += cp3rD;
+  printf("5 deque    r: RT=%6.2f s  Cpu=%6.2f s\n",rt3rD,cp3rD);
+  delete STLhit_deque;
+
+  // STL SET
+  timer.Start();
+  TSTLhitSet *STLhit_set = new TSTLhitSet(nhits);
+  STLhit_set->MakeTree(0,nevents,0,0,cx);
+  timer.Stop();
+  Double_t rt1S = timer.RealTime();
+  Double_t cp1S = timer.CpuTime();
+  cptot += cp1S;
+  printf("1 set       : RT=%6.2f s  Cpu=%6.2f s\n",rt1S,cp1S);
+  timer.Start(kTRUE);
+  Int_t nbytes1S = STLhit_set->MakeTree(1,nevents,0,99,cx);
+  timer.Stop();
+  Double_t rt2wS = timer.RealTime();
+  Double_t cp2wS = timer.CpuTime();
+  cptot += cp2wS;
+  printf("2 set      w: RT=%6.2f s  Cpu=%6.2f s, size= %8d bytes, cx=%5.2f\n",rt2wS-rt1S,cp2wS-cp1S,nbytes1S,cx);
+  timer.Start(kTRUE);
+  STLhit_set->ReadTree();
+  timer.Stop();
+  Double_t rt2rS = timer.RealTime();
+  Double_t cp2rS = timer.CpuTime();
+  cptot += cp2rS;
+  printf("3 set      r: RT=%6.2f s  Cpu=%6.2f s\n",rt2rS,cp2rS);
+  timer.Start(kTRUE);
+  Float_t cx3S;
+  Int_t nbytes3S = STLhit_set->MakeTree(1,nevents,1,99,cx3S);
+  timer.Stop();
+  Double_t rt3wS = timer.RealTime();
+  Double_t cp3wS = timer.CpuTime();
+  cptot += cp3wS;
+  printf("4 set      w: RT=%6.2f s  Cpu=%6.2f s, size= %8d bytes, cx=%5.2f\n",rt3wS-rt1S,cp3wS-cp1S,nbytes3S,cx3S);
+  timer.Start(kTRUE);
+  STLhit_set->ReadTree();
+  timer.Stop();
+  Double_t rt3rS = timer.RealTime();
+  Double_t cp3rS = timer.CpuTime();
+  cptot += cp3rS;
+  printf("5 set      r: RT=%6.2f s  Cpu=%6.2f s\n",rt3rS,cp3rS);
+  delete STLhit_set;
+
+  // STL MULTI SET
+  timer.Start();
+  TSTLhitMultiset *STLhit_multiset = new TSTLhitMultiset(nhits);
+  STLhit_multiset->MakeTree(0,nevents,0,0,cx);
+  timer.Stop();
+  Double_t rt1M = timer.RealTime();
+  Double_t cp1M = timer.CpuTime();
+  cptot += cp1M;
+  printf("1 multiset  : RT=%6.2f s  Cpu=%6.2f s\n",rt1M,cp1M);
+  timer.Start(kTRUE);
+  Int_t nbytes1M = STLhit_multiset->MakeTree(1,nevents,0,99,cx);
+  timer.Stop();
+  Double_t rt2wM = timer.RealTime();
+  Double_t cp2wM = timer.CpuTime();
+  cptot += cp2wM;
+  printf("2 multiset w: RT=%6.2f s  Cpu=%6.2f s, size= %8d bytes, cx=%5.2f\n",rt2wM-rt1M,cp2wM-cp1M,nbytes1M,cx);
+  timer.Start(kTRUE);
+  STLhit_multiset->ReadTree();
+  timer.Stop();
+  Double_t rt2rM = timer.RealTime();
+  Double_t cp2rM = timer.CpuTime();
+  cptot += cp2rM;
+  printf("3 multiset r: RT=%6.2f s  Cpu=%6.2f s\n",rt2rM,cp2rM);
+  timer.Start(kTRUE);
+  Float_t cx3M;
+  Int_t nbytes3M = STLhit_multiset->MakeTree(1,nevents,1,99,cx3M);
+  timer.Stop();
+  Double_t rt3wM = timer.RealTime();
+  Double_t cp3wM = timer.CpuTime();
+  cptot += cp3wM;
+  printf("4 multiset w: RT=%6.2f s  Cpu=%6.2f s, size= %8d bytes, cx=%5.2f\n",rt3wM-rt1M,cp3wM-cp1M,nbytes3M,cx3M);
+  timer.Start(kTRUE);
+  STLhit_multiset->ReadTree();
+  timer.Stop();
+  Double_t rt3rM = timer.RealTime();
+  Double_t cp3rM = timer.CpuTime();
+  cptot += cp3rM;
+  printf("5 multiset r: RT=%6.2f s  Cpu=%6.2f s\n",rt3rM,cp3rM);
+  delete STLhit_multiset;
+
+  // STL map
+  timer.Start();
+  TSTLhitMap *STLhit_map = new TSTLhitMap(nhits);
+  STLhit_map->MakeTree(0,nevents,0,0,cx);
+  timer.Stop();
+  Double_t rt1MAP = timer.RealTime();
+  Double_t cp1MAP = timer.CpuTime();
+  cptot += cp1MAP;
+  printf("1 map       : RT=%6.2f s  Cpu=%6.2f s\n",rt1MAP,cp1MAP);
+  timer.Start(kTRUE);
+  Int_t nbytes1MAP = STLhit_map->MakeTree(1,nevents,0,99,cx);
+  timer.Stop();
+  Double_t rt2wMAP = timer.RealTime();
+  Double_t cp2wMAP = timer.CpuTime();
+  cptot += cp2wMAP;
+  printf("2 map      w: RT=%6.2f s  Cpu=%6.2f s, size= %8d bytes, cx=%5.2f\n",rt2wMAP-rt1MAP,cp2wMAP-cp1MAP,nbytes1MAP,cx);
+  timer.Start(kTRUE);
+  STLhit_map->ReadTree();
+  timer.Stop();
+  Double_t rt2rMAP = timer.RealTime();
+  Double_t cp2rMAP = timer.CpuTime();
+  cptot += cp2rMAP;
+  printf("3 map      r: RT=%6.2f s  Cpu=%6.2f s\n",rt2rMAP,cp2rMAP);
+  timer.Start(kTRUE);
+  Float_t cx3MAP;
+  Int_t nbytes3MAP = STLhit_map->MakeTree(1,nevents,1,99,cx3MAP);
+  timer.Stop();
+  Double_t rt3wMAP = timer.RealTime();
+  Double_t cp3wMAP = timer.CpuTime();
+  cptot += cp3wMAP;
+  printf("4 map      w: RT=%6.2f s  Cpu=%6.2f s, size= %8d bytes, cx=%5.2f\n",rt3wMAP-rt1MAP,cp3wMAP-cp1MAP,nbytes3MAP,cx3MAP);
+  timer.Start(kTRUE);
+  STLhit_map->ReadTree();
+  timer.Stop();
+  Double_t rt3rMAP = timer.RealTime();
+  Double_t cp3rMAP = timer.CpuTime();
+  cptot += cp3rMAP;
+  printf("5 map      r: RT=%6.2f s  Cpu=%6.2f s\n",rt3rMAP,cp3rMAP);
+  delete STLhit_map;
+
+  // STL multimap
+  timer.Start();
+  TSTLhitMultiMap *STLhit_multimap = new TSTLhitMultiMap(nhits);
+  STLhit_multimap->MakeTree(0,nevents,0,0,cx);
+  timer.Stop();
+  Double_t rt1MMAP = timer.RealTime();
+  Double_t cp1MMAP = timer.CpuTime();
+  cptot += cp1MMAP;
+  printf("1 multimap  : RT=%6.2f s  Cpu=%6.2f s\n",rt1MMAP,cp1MMAP);
+  timer.Start(kTRUE);
+  Int_t nbytes1MMAP = STLhit_multimap->MakeTree(1,nevents,0,99,cx);
+  timer.Stop();
+  Double_t rt2wMMAP = timer.RealTime();
+  Double_t cp2wMMAP = timer.CpuTime();
+  cptot += cp2wMMAP;
+  printf("2 multimap w: RT=%6.2f s  Cpu=%6.2f s, size= %8d bytes, cx=%5.2f\n",rt2wMMAP-rt1MMAP,cp2wMMAP-cp1MMAP,nbytes1MMAP,cx);
+  timer.Start(kTRUE);
+  STLhit_multimap->ReadTree();
+  timer.Stop();
+  Double_t rt2rMMAP = timer.RealTime();
+  Double_t cp2rMMAP = timer.CpuTime();
+  cptot += cp2rMMAP;
+  printf("3 multimap r: RT=%6.2f s  Cpu=%6.2f s\n",rt2rMMAP,cp2rMMAP);
+  timer.Start(kTRUE);
+  Float_t cx3MMAP;
+  Int_t nbytes3MMAP = STLhit_multimap->MakeTree(1,nevents,1,99,cx3MMAP);
+  timer.Stop();
+  Double_t rt3wMMAP = timer.RealTime();
+  Double_t cp3wMMAP = timer.CpuTime();
+  cptot += cp3wMMAP;
+  printf("4 multimap w: RT=%6.2f s  Cpu=%6.2f s, size= %8d bytes, cx=%5.2f\n",rt3wMMAP-rt1MMAP,cp3wMMAP-cp1MMAP,nbytes3MMAP,cx3MMAP);
+  timer.Start(kTRUE);
+  STLhit_multimap->ReadTree();
+  timer.Stop();
+  Double_t rt3rMMAP = timer.RealTime();
+  Double_t cp3rMMAP = timer.CpuTime();
+  cptot += cp3rMMAP;
+  printf("5 multimap r: RT=%6.2f s  Cpu=%6.2f s\n",rt3rMMAP,cp3rMMAP);
+  delete STLhit_multimap;
 
   //testing STL vector of pointers to THit
   timer.Start();
@@ -149,21 +395,21 @@ int main(int argc, char** argv)
   Double_t rt4 = timer.RealTime();
   Double_t cp4 = timer.CpuTime();
   cptot += cp4;
-  printf("6  STLhit* : RT=%6.2f s  Cpu=%6.2f s\n",rt4,cp4);
+  printf("1 vector*   : RT=%6.2f s  Cpu=%6.2f s\n",rt4,cp4);
   timer.Start(kTRUE);
   Int_t nbytes5 = STLhitStar->MakeTree(1,nevents,0,99,cx);
   timer.Stop();
   Double_t rt5w = timer.RealTime();
   Double_t cp5w = timer.CpuTime();
   cptot += cp5w;
-  printf("7  STLhit*w: RT=%6.2f s  Cpu=%6.2f s, size= %8d bytes, cx=%5.2f\n",rt5w-rt4,cp5w-cp4,nbytes5,cx);
+  printf("2 vector*  w: RT=%6.2f s  Cpu=%6.2f s, size= %8d bytes, cx=%5.2f\n",rt5w-rt4,cp5w-cp4,nbytes5,cx);
   timer.Start(kTRUE);
   STLhitStar->ReadTree();
   timer.Stop();
   Double_t rt5r = timer.RealTime();
   Double_t cp5r = timer.CpuTime();
   cptot += cp5r;
-  printf("8  STLhit*r: RT=%6.2f s  Cpu=%6.2f s\n",rt5r,cp5r);
+  printf("3 vector*  r: RT=%6.2f s  Cpu=%6.2f s\n",rt5r,cp5r);
   timer.Start(kTRUE);
   Float_t cx6;
   Int_t nbytes6 = STLhitStar->MakeTree(1,nevents,1,99,cx6);
@@ -171,15 +417,267 @@ int main(int argc, char** argv)
   Double_t rt6w = timer.RealTime();
   Double_t cp6w = timer.CpuTime();
   cptot += cp6w;
-  printf("9  STLhit*w: RT=%6.2f s  Cpu=%6.2f s, size= %8d bytes, cx=%5.2f\n",rt6w-rt4,cp6w-cp4,nbytes6,cx6);
+  printf("4 vector*  w: RT=%6.2f s  Cpu=%6.2f s, size= %8d bytes, cx=%5.2f\n",rt6w-rt4,cp6w-cp4,nbytes6,cx6);
   timer.Start(kTRUE);
   STLhitStar->ReadTree();
   timer.Stop();
   Double_t rt6r = timer.RealTime();
   Double_t cp6r = timer.CpuTime();
   cptot += cp6r;
-  printf("10 STLhit*r: RT=%6.2f s  Cpu=%6.2f s\n",rt6r,cp6r);
+  printf("5 vector*  r: RT=%6.2f s  Cpu=%6.2f s\n",rt6r,cp6r);
+  delete STLhitStar;
 
+  // STL list*
+  timer.Start();
+  TSTLhitStarList *STLhit_liststar = new TSTLhitStarList(nhits);
+  STLhit_liststar->MakeTree(0,nevents,0,0,cx);
+  timer.Stop();
+  Double_t rt1LS = timer.RealTime();
+  Double_t cp1LS = timer.CpuTime();
+  cptot += cp1LS;
+  printf("1 list*     : RT=%6.2f s  Cpu=%6.2f s\n",rt1LS,cp1LS);
+  timer.Start(kTRUE);
+  Int_t nbytes1LS = STLhit_liststar->MakeTree(1,nevents,0,99,cx);
+  timer.Stop();
+  Double_t rt2wLS = timer.RealTime();
+  Double_t cp2wLS = timer.CpuTime();
+  cptot += cp2wLS;
+  printf("2 list*    w: RT=%6.2f s  Cpu=%6.2f s, size= %8d bytes, cx=%5.2f\n",rt2wLS-rt1LS,cp2wLS-cp1LS,nbytes1LS,cx);
+  timer.Start(kTRUE);
+  STLhit_liststar->ReadTree();
+  timer.Stop();
+  Double_t rt2rLS = timer.RealTime();
+  Double_t cp2rLS = timer.CpuTime();
+  cptot += cp2rLS;
+  printf("3 list*    r: RT=%6.2f s  Cpu=%6.2f s\n",rt2rLS,cp2rLS);
+  timer.Start(kTRUE);
+  Float_t cx3LS;
+  Int_t nbytes3LS = STLhit_liststar->MakeTree(1,nevents,1,99,cx3LS);
+  timer.Stop();
+  Double_t rt3wLS = timer.RealTime();
+  Double_t cp3wLS = timer.CpuTime();
+  cptot += cp3wLS;
+  printf("4 list*    w: RT=%6.2f s  Cpu=%6.2f s, size= %8d bytes, cx=%5.2f\n",rt3wLS-rt1LS,cp3wLS-cp1LS,nbytes3LS,cx3LS);
+  timer.Start(kTRUE);
+  STLhit_liststar->ReadTree();
+  timer.Stop();
+  Double_t rt3rLS = timer.RealTime();
+  Double_t cp3rLS = timer.CpuTime();
+  cptot += cp3rLS;
+  printf("5 list*    r: RT=%6.2f s  Cpu=%6.2f s\n",rt3rLS,cp3rLS);
+  delete STLhit_liststar;
+
+  // STL DEQUE*
+  timer.Start();
+  TSTLhitStarDeque *STLhit_dequestar = new TSTLhitStarDeque(nhits);
+  STLhit_dequestar->MakeTree(0,nevents,0,0,cx);
+  timer.Stop();
+  Double_t rt1DS = timer.RealTime();
+  Double_t cp1DS = timer.CpuTime();
+  cptot += cp1DS;
+  printf("1 deque*    : RT=%6.2f s  Cpu=%6.2f s\n",rt1DS,cp1DS);
+  timer.Start(kTRUE);
+  Int_t nbytes1DS = STLhit_dequestar->MakeTree(1,nevents,0,99,cx);
+  timer.Stop();
+  Double_t rt2wDS = timer.RealTime();
+  Double_t cp2wDS = timer.CpuTime();
+  cptot += cp2wDS;
+  printf("2 deque*   w: RT=%6.2f s  Cpu=%6.2f s, size= %8d bytes, cx=%5.2f\n",rt2wDS-rt1DS,cp2wDS-cp1DS,nbytes1DS,cx);
+  timer.Start(kTRUE);
+  STLhit_dequestar->ReadTree();
+  timer.Stop();
+  Double_t rt2rDS = timer.RealTime();
+  Double_t cp2rDS = timer.CpuTime();
+  cptot += cp2rDS;
+  printf("3 deque*   r: RT=%6.2f s  Cpu=%6.2f s\n",rt2rDS,cp2rDS);
+  timer.Start(kTRUE);
+  Float_t cx3DS;
+  Int_t nbytes3DS = STLhit_dequestar->MakeTree(1,nevents,1,99,cx3DS);
+  timer.Stop();
+  Double_t rt3wDS = timer.RealTime();
+  Double_t cp3wDS = timer.CpuTime();
+  cptot += cp3wDS;
+  printf("4 deque*   w: RT=%6.2f s  Cpu=%6.2f s, size= %8d bytes, cx=%5.2f\n",rt3wDS-rt1DS,cp3wDS-cp1DS,nbytes3DS,cx3DS);
+  timer.Start(kTRUE);
+  STLhit_dequestar->ReadTree();
+  timer.Stop();
+  Double_t rt3rDS = timer.RealTime();
+  Double_t cp3rDS = timer.CpuTime();
+  cptot += cp3rDS;
+  printf("5 deque*   r: RT=%6.2f s  Cpu=%6.2f s\n",rt3rDS,cp3rDS);
+  delete STLhit_dequestar;
+
+  // STL SET*
+  timer.Start();
+  TSTLhitStarSet *STLhit_setstar = new TSTLhitStarSet(nhits);
+  STLhit_setstar->MakeTree(0,nevents,0,0,cx);
+  timer.Stop();
+  Double_t rt1SS = timer.RealTime();
+  Double_t cp1SS = timer.CpuTime();
+  cptot += cp1SS;
+  printf("1 set*      : RT=%6.2f s  Cpu=%6.2f s\n",rt1SS,cp1SS);
+  timer.Start(kTRUE);
+  Int_t nbytes1SS = STLhit_setstar->MakeTree(1,nevents,0,99,cx);
+  timer.Stop();
+  Double_t rt2wSS = timer.RealTime();
+  Double_t cp2wSS = timer.CpuTime();
+  cptot += cp2wSS;
+  printf("2 set*     w: RT=%6.2f s  Cpu=%6.2f s, size= %8d bytes, cx=%5.2f\n",rt2wSS-rt1SS,cp2wSS-cp1SS,nbytes1SS,cx);
+  timer.Start(kTRUE);
+  STLhit_setstar->ReadTree();
+  timer.Stop();
+  Double_t rt2rSS = timer.RealTime();
+  Double_t cp2rSS = timer.CpuTime();
+  cptot += cp2rSS;
+  printf("3 set*     r: RT=%6.2f s  Cpu=%6.2f s\n",rt2rSS,cp2rSS);
+  timer.Start(kTRUE);
+  Float_t cx3SS;
+  Int_t nbytes3SS = STLhit_setstar->MakeTree(1,nevents,1,99,cx3SS);
+  timer.Stop();
+  Double_t rt3wSS = timer.RealTime();
+  Double_t cp3wSS = timer.CpuTime();
+  cptot += cp3wSS;
+  printf("4 set*     w: RT=%6.2f s  Cpu=%6.2f s, size= %8d bytes, cx=%5.2f\n",rt3wDS-rt1DS,cp3wSS-cp1SS,nbytes3SS,cx3SS);
+  timer.Start(kTRUE);
+  STLhit_setstar->ReadTree();
+  timer.Stop();
+  Double_t rt3rSS = timer.RealTime();
+  Double_t cp3rSS = timer.CpuTime();
+  cptot += cp3rSS;
+  printf("5 set*      : RT=%6.2f s  Cpu=%6.2f s\n",rt3rSS,cp3rSS);
+  delete STLhit_setstar;
+
+  // STL MULTI SET*
+  timer.Start();
+  TSTLhitStarMultiSet *STLhit_multisetstar = new TSTLhitStarMultiSet(nhits);
+  STLhit_multisetstar->MakeTree(0,nevents,0,0,cx);
+  timer.Stop();
+  Double_t rt1MS = timer.RealTime();
+  Double_t cp1MS = timer.CpuTime();
+  cptot += cp1MS;
+  printf("1 multiset* : RT=%6.2f s  Cpu=%6.2f s\n",rt1MS,cp1MS);
+  timer.Start(kTRUE);
+  Int_t nbytes1MS = STLhit_multisetstar->MakeTree(1,nevents,0,99,cx);
+  timer.Stop();
+  Double_t rt2wMS = timer.RealTime();
+  Double_t cp2wMS = timer.CpuTime();
+  cptot += cp2wMS;
+  printf("2 multiset*w: RT=%6.2f s  Cpu=%6.2f s, size= %8d bytes, cx=%5.2f\n",rt2wMS-rt1MS,cp2wMS-cp1MS,nbytes1MS,cx);
+  timer.Start(kTRUE);
+  STLhit_multisetstar->ReadTree();
+  timer.Stop();
+  Double_t rt2rMS = timer.RealTime();
+  Double_t cp2rMS = timer.CpuTime();
+  cptot += cp2rMS;
+  printf("3 multiset*r: RT=%6.2f s  Cpu=%6.2f s\n",rt2rMS,cp2rMS);
+  timer.Start(kTRUE);
+  Float_t cx3MS;
+  Int_t nbytes3MS = STLhit_multisetstar->MakeTree(1,nevents,1,99,cx3MS);
+  timer.Stop();
+  Double_t rt3wMS = timer.RealTime();
+  Double_t cp3wMS = timer.CpuTime();
+  cptot += cp3wMS;
+  printf("4 multiset*w: RT=%6.2f s  Cpu=%6.2f s, size= %8d bytes, cx=%5.2f\n",rt3wDS-rt1DS,cp3wDS-cp1DS,nbytes3DS,cx3DS);
+  timer.Start(kTRUE);
+  STLhit_multisetstar->ReadTree();
+  timer.Stop();
+  Double_t rt3rMS = timer.RealTime();
+  Double_t cp3rMS = timer.CpuTime();
+  cptot += cp3rMS;
+  printf("5 multiset* : RT=%6.2f s  Cpu=%6.2f s\n",rt3rMS,cp3rMS);
+  delete STLhit_multisetstar;
+
+  // STL MAP*
+  timer.Start();
+  TSTLhitStarMap *STLhit_mapstar = new TSTLhitStarMap(nhits);
+  STLhit_mapstar->MakeTree(0,nevents,0,0,cx);
+  timer.Stop();
+  Double_t rt1MAPS = timer.RealTime();
+  Double_t cp1MAPS = timer.CpuTime();
+  cptot += cp1MAPS;
+  printf("1 map*      : RT=%6.2f s  Cpu=%6.2f s\n",rt1MAPS,cp1MAPS);
+  timer.Start(kTRUE);
+  Int_t nbytes1MAPS = STLhit_mapstar->MakeTree(1,nevents,0,99,cx);
+  timer.Stop();
+  Double_t rt2wMAPS = timer.RealTime();
+  Double_t cp2wMAPS = timer.CpuTime();
+  cptot += cp2wMAPS;
+  printf("2 map*     w: RT=%6.2f s  Cpu=%6.2f s, size= %8d bytes, cx=%5.2f\n",rt2wMAPS-rt1MAPS,cp2wMAPS-cp1MAPS,nbytes1MAPS,cx);
+  timer.Start(kTRUE);
+#ifndef R__ALPHA
+  STLhit_mapstar->ReadTree();
+#endif
+  timer.Stop();
+  Double_t rt2rMAPS = timer.RealTime();
+  Double_t cp2rMAPS = timer.CpuTime();
+  cptot += cp2rMAPS;
+  printf("3 map*     r: RT=%6.2f s  Cpu=%6.2f s\n",rt2rMAPS,cp2rMAPS);
+  timer.Start(kTRUE);
+  Float_t cx3MAPS;
+  Int_t nbytes3MAPS = STLhit_mapstar->MakeTree(1,nevents,1,99,cx3MAPS);
+  timer.Stop();
+  Double_t rt3wMAPS = timer.RealTime();
+  Double_t cp3wMAPS = timer.CpuTime();
+  cptot += cp3wMAPS;
+  printf("4 map*     w: RT=%6.2f s  Cpu=%6.2f s, size= %8d bytes, cx=%5.2f\n",rt3wMAPS-rt1MAPS,cp3wMAPS-cp1MAPS,nbytes3MAPS,cx3MAPS);
+  timer.Start(kTRUE);
+#ifndef R__ALPHA
+  STLhit_mapstar->ReadTree();
+#endif
+  timer.Stop();
+  Double_t rt3rMAPS = timer.RealTime();
+  Double_t cp3rMAPS = timer.CpuTime();
+  cptot += cp3rMAPS;
+  printf("5 map*      : RT=%6.2f s  Cpu=%6.2f s\n",rt3rMAPS,cp3rMAPS);
+  delete STLhit_mapstar;
+
+  // STL MULTIMAP*
+  timer.Start();
+  TSTLhitStarMultiMap *STLhit_multimapstar = new TSTLhitStarMultiMap(nhits);
+  STLhit_multimapstar->MakeTree(0,nevents,0,0,cx);
+  timer.Stop();
+  Double_t rt1MMAPS = timer.RealTime();
+  Double_t cp1MMAPS = timer.CpuTime();
+  cptot += cp1MMAPS;
+  printf("1 multimap* : RT=%6.2f s  Cpu=%6.2f s\n",rt1MMAPS,cp1MMAPS);
+  timer.Start(kTRUE);
+  Int_t nbytes1MMAPS = STLhit_multimapstar->MakeTree(1,nevents,0,99,cx);
+  timer.Stop();
+  Double_t rt2wMMAPS = timer.RealTime();
+  Double_t cp2wMMAPS = timer.CpuTime();
+  cptot += cp2wMMAPS;
+  printf("2 multimap*w: RT=%6.2f s  Cpu=%6.2f s, size= %8d bytes, cx=%5.2f\n",rt2wMMAPS-rt1MMAPS,cp2wMMAPS-cp1MMAPS,nbytes1MMAPS,cx);
+  timer.Start(kTRUE);
+#ifndef R__ALPHA
+  STLhit_multimapstar->ReadTree();
+#endif
+  timer.Stop();
+  Double_t rt2rMMAPS = timer.RealTime();
+  Double_t cp2rMMAPS = timer.CpuTime();
+  cptot += cp2rMMAPS;
+  printf("3 multimap*r: RT=%6.2f s  Cpu=%6.2f s\n",rt2rMMAPS,cp2rMMAPS);
+  timer.Start(kTRUE);
+  Float_t cx3MMAPS;
+  Int_t nbytes3MMAPS = STLhit_multimapstar->MakeTree(1,nevents,1,99,cx3MMAPS);
+  timer.Stop();
+  Double_t rt3wMMAPS = timer.RealTime();
+  Double_t cp3wMMAPS = timer.CpuTime();
+  cptot += cp3wMMAPS;
+  printf("4 multimap*w: RT=%6.2f s  Cpu=%6.2f s, size= %8d bytes, cx=%5.2f\n",rt3wMAPS-rt1MAPS,cp3wMAPS-cp1MAPS,nbytes3MAPS,cx3MAPS);
+  timer.Start(kTRUE);
+#ifndef R__ALPHA
+  STLhit_multimapstar->ReadTree();
+#endif
+  timer.Stop();
+  Double_t rt3rMMAPS = timer.RealTime();
+  Double_t cp3rMMAPS = timer.CpuTime();
+  cptot += cp3rMMAPS;
+  printf("5 multimap* : RT=%6.2f s  Cpu=%6.2f s\n",rt3rMMAPS,cp3rMMAPS);
+  delete STLhit_multimapstar;
+#ifndef R__ALPHA
+  printf("map and multimap do not work on alpha. test is disabled\n");
+#endif
+  
   //testing TClonesArray of TObjHit deriving from THit
   timer.Start();
   TCloneshit *Cloneshit = new TCloneshit(nhits);
@@ -188,21 +686,21 @@ int main(int argc, char** argv)
   Double_t rt7 = timer.RealTime();
   Double_t cp7 = timer.CpuTime();
   cptot += cp7;
-  printf("11 Clones1 : RT=%6.2f s  Cpu=%6.2f s\n",rt7,cp7);
+  printf("1 Clones1   : RT=%6.2f s  Cpu=%6.2f s\n",rt7,cp7);
   timer.Start(kTRUE);
   Int_t nbytes8 = Cloneshit->MakeTree(1,nevents,0,99,cx);
   timer.Stop();
   Double_t rt8w = timer.RealTime();
   Double_t cp8w = timer.CpuTime();
   cptot += cp8w;
-  printf("12 Clones1w: RT=%6.2f s  Cpu=%6.2f s, size= %8d bytes, cx=%5.2f\n",rt8w-rt7,cp8w-cp7,nbytes8,cx);
+  printf("2 Clones1  w: RT=%6.2f s  Cpu=%6.2f s, size= %8d bytes, cx=%5.2f\n",rt8w-rt7,cp8w-cp7,nbytes8,cx);
   timer.Start(kTRUE);
   Cloneshit->ReadTree();
   timer.Stop();
   Double_t rt8r = timer.RealTime();
   Double_t cp8r = timer.CpuTime();
   cptot += cp8r;
-  printf("13 Clones1r: RT=%6.2f s  Cpu=%6.2f s\n",rt8r,cp8r);
+  printf("3 Clones1  r: RT=%6.2f s  Cpu=%6.2f s\n",rt8r,cp8r);
   timer.Start(kTRUE);
   Float_t cx9;
   Int_t nbytes9 = Cloneshit->MakeTree(1,nevents,1,99,cx9);
@@ -210,28 +708,28 @@ int main(int argc, char** argv)
   Double_t rt9w = timer.RealTime();
   Double_t cp9w = timer.CpuTime();
   cptot += cp9w;
-  printf("14 Clones1w: RT=%6.2f s  Cpu=%6.2f s, size= %8d bytes, cx=%5.2f\n",rt9w-rt7,cp9w-cp7,nbytes9,cx9);
+  printf("4 Clones1  w: RT=%6.2f s  Cpu=%6.2f s, size= %8d bytes, cx=%5.2f\n",rt9w-rt7,cp9w-cp7,nbytes9,cx9);
   timer.Start(kTRUE);
   Cloneshit->ReadTree();
   timer.Stop();
   Double_t rt9r = timer.RealTime();
   Double_t cp9r = timer.CpuTime();
   cptot += cp9r;
-  printf("15 Clones1r: RT=%6.2f s  Cpu=%6.2f s\n",rt9r,cp9r);
+  printf("5 Clones1  r: RT=%6.2f s  Cpu=%6.2f s\n",rt9r,cp9r);
   timer.Start(kTRUE);
   Int_t nbytes10 = Cloneshit->MakeTree(1,nevents,0,99,cx);
   timer.Stop();
   Double_t rt10w = timer.RealTime();
   Double_t cp10w = timer.CpuTime();
   cptot += cp10w;
-  printf("16 Clones2w: RT=%6.2f s  Cpu=%6.2f s, size= %8d bytes, cx=%5.2f\n",rt10w-rt7,cp10w-cp7,nbytes10,cx);
+  printf("6 Clones2  w: RT=%6.2f s  Cpu=%6.2f s, size= %8d bytes, cx=%5.2f\n",rt10w-rt7,cp10w-cp7,nbytes10,cx);
   timer.Start(kTRUE);
   Cloneshit->ReadTree();
   timer.Stop();
   Double_t rt10r = timer.RealTime();
   Double_t cp10r = timer.CpuTime();
   cptot += cp10r;
-  printf("17 Clones2r: RT=%6.2f s  Cpu=%6.2f s\n",rt10r,cp10r);
+  printf("7 Clones2  r: RT=%6.2f s  Cpu=%6.2f s\n",rt10r,cp10r);
   timer.Start(kTRUE);
   Float_t cx11;
   Int_t nbytes11 = Cloneshit->MakeTree(1,nevents,1,99,cx11);
@@ -239,20 +737,17 @@ int main(int argc, char** argv)
   Double_t rt11w = timer.RealTime();
   Double_t cp11w = timer.CpuTime();
   cptot += cp11w;
-  printf("18 Clones2w: RT=%6.2f s  Cpu=%6.2f s, size= %8d bytes, cx=%5.2f\n",rt11w-rt7,cp11w-cp7,nbytes11,cx11);
+  printf("8 Clones2  w: RT=%6.2f s  Cpu=%6.2f s, size= %8d bytes, cx=%5.2f\n",rt11w-rt7,cp11w-cp7,nbytes11,cx11);
   timer.Start(kTRUE);
   Cloneshit->ReadTree();
   timer.Stop();
   Double_t rt11r = timer.RealTime();
   Double_t cp11r = timer.CpuTime();
   cptot += cp11r;
-  printf("19 Clones2r: RT=%6.2f s  Cpu=%6.2f s\n",rt11r,cp11r);
+  printf("9 Clones2  r: RT=%6.2f s  Cpu=%6.2f s\n",rt11r,cp11r);
   Double_t cpref = 24.92;
   Double_t rootmarks = cpref*600/cptot;
 
-  //delete temp file used for the benchmark
-  gSystem->Exec("rm -f /tmp/bench.root");
-
   //print all results
   char line1[100], line2[100];
   printf("\n");
@@ -280,28 +775,76 @@ int main(int argc, char** argv)
   printf("* Time to fill the structures (seconds)   Reference      cx      Reference   *\n");
   printf("******************************************************************************\n");
   printf("* vector<THit>                  %6.2f        0.98     %5.2f        3.77     *\n",cp1,cx3);
+  printf("* list<THit>                    %6.2f        xxxx     %5.2f        xxxx     *\n",cp1L,cx3L);
+  printf("* deque<THit>                   %6.2f        xxxx     %5.2f        xxxx     *\n",cp1D,cx3D);
+  printf("* set<THit>                     %6.2f        xxxx     %5.2f        xxxx     *\n",cp1S,cx3S);
+  printf("* multiset<THit>                %6.2f        xxxx     %5.2f        xxxx     *\n",cp1M,cx3M);
+  printf("* map<int,THit>                 %6.2f        xxxx     %5.2f        xxxx     *\n",cp1MAP,cx3MAP);
+  printf("* multimap<int,THit>            %6.2f        xxxx     %5.2f        xxxx     *\n",cp1MMAP,cx3MMAP);
   printf("* vector<THit*>                 %6.2f        0.90     %5.2f        3.78     *\n",cp4,cx6);
+  printf("* list<THit*>                   %6.2f        xxxx     %5.2f        xxxx     *\n",cp1LS,cx3LS);
+  printf("* deque<THit*>                  %6.2f        xxxx     %5.2f        xxxx     *\n",cp1DS,cx3DS);
+  printf("* set<THit*>                    %6.2f        xxxx     %5.2f        xxxx     *\n",cp1SS,cx3SS);
+  printf("* multiset<THit*>               %6.2f        xxxx     %5.2f        xxxx     *\n",cp1MS,cx3MS);
+  printf("* map<int,THit*>                %6.2f        xxxx     %5.2f        xxxx     *\n",cp1MAPS,cx3MAPS);
+  printf("* multimap<int,THit*>           %6.2f        xxxx     %5.2f        xxxx     *\n",cp1MMAPS,cx3MMAPS);
   printf("* TClonesArray(TObjHit)         %6.2f        0.74     %5.2f        5.40     *\n",cp7,cx9);
   printf("* TClonesArray(TObjHit) split   %6.2f        0.74     %5.2f        5.40     *\n",cp7,cx11);
   printf("******************************************************************************\n");
   printf("* Size of file in bytes         comp 0    Reference    comp 1    Reference   *\n");
   printf("******************************************************************************\n");
   printf("* vector<THit>                  %8d   42053619   %8d   11144596    *\n",nbytes1,nbytes3);
+  printf("* list<THit>                    %8d   xxxxxxxx   %8d   xxxxxxxx    *\n",nbytes1L,nbytes3L);
+  printf("* deque<THit>                   %8d   xxxxxxxx   %8d   xxxxxxxx    *\n",nbytes1D,nbytes3D);
+  printf("* set<THit>                     %8d   xxxxxxxx   %8d   xxxxxxxx    *\n",nbytes1S,nbytes3S);
+  printf("* multiset<THit>                %8d   xxxxxxxx   %8d   xxxxxxxx    *\n",nbytes1M,nbytes3M);
+  printf("* map<int,THit>                 %8d   xxxxxxxx   %8d   xxxxxxxx    *\n",nbytes1MAP,nbytes3MAP);
+  printf("* multimap<int,THit>            %8d   xxxxxxxx   %8d   xxxxxxxx    *\n",nbytes1MMAP,nbytes3MMAP);
   printf("* vector<THit*>                 %8d   42078956   %8d   11144412    *\n",nbytes5,nbytes6);
+  printf("* list<THit*>                   %8d   xxxxxxxx   %8d   xxxxxxxx    *\n",nbytes1LS,nbytes3LS);
+  printf("* deque<THit*>                  %8d   xxxxxxxx   %8d   xxxxxxxx    *\n",nbytes1DS,nbytes3DS);
+  printf("* set<THit*>                    %8d   xxxxxxxx   %8d   xxxxxxxx    *\n",nbytes1SS,nbytes3SS);
+  printf("* multiset<THit*>               %8d   xxxxxxxx   %8d   xxxxxxxx    *\n",nbytes1MS,nbytes3MS);
+  printf("* map<int,THit*>                %8d   xxxxxxxx   %8d   xxxxxxxx    *\n",nbytes1MAPS,nbytes3MAPS);
+  printf("* multimap<int,THit*>           %8d   xxxxxxxx   %8d   xxxxxxxx    *\n",nbytes1MMAPS,nbytes3MMAPS);
   printf("* TClonesArray(TObjHit)         %8d   39804763   %8d    7377591    *\n",nbytes8,nbytes9);
   printf("* TClonesArray(TObjHit) split   %8d   39804763   %8d    7377664    *\n",nbytes10,nbytes11);
   printf("******************************************************************************\n");
   printf("* Time to write in seconds      comp 0    Reference    comp 1    Reference   *\n");
   printf("******************************************************************************\n");
   printf("* vector<THit>                  %6.2f        0.44    %6.2f        2.17     *\n",cp2w-cp1, cp3w-cp1);
+  printf("* list<THit>                    %6.2f        xxxx    %6.2f        xxxx     *\n",cp2wL-cp1L,cp3wL-cp1L);
+  printf("* deque<THit>                   %6.2f        xxxx    %6.2f        xxxx     *\n",cp2wD-cp1D,cp3wD-cp1D);
+  printf("* set<THit>                     %6.2f        xxxx    %6.2f        xxxx     *\n",cp2wS-cp1S,cp3wS-cp1S);
+  printf("* multiset<THit>                %6.2f        xxxx    %6.2f        xxxx     *\n",cp2wM-cp1M,cp3wM-cp1M);
+  printf("* map<int,THit>                 %6.2f        xxxx    %6.2f        xxxx     *\n",cp2wMAP-cp1MAP,cp3wMAP-cp1MAP);
+  printf("* multimap<int,THit>            %6.2f        xxxx    %6.2f        xxxx     *\n",cp2wMMAP-cp1MMAP,cp3wMMAP-cp1MMAP);
   printf("* vector<THit*>                 %6.2f        0.38    %6.2f        2.27     *\n",cp5w-cp1, cp6w-cp1);
+  printf("* list<THit*>                   %6.2f        xxxx    %6.2f        xxxx     *\n",cp2wLS-cp1LS,cp3wLS-cp1LS);
+  printf("* deque<THit*>                  %6.2f        xxxx    %6.2f        xxxx     *\n",cp2wDS-cp1DS,cp3wDS-cp1DS);
+  printf("* set<THit*>                    %6.2f        xxxx    %6.2f        xxxx     *\n",cp2wSS-cp1SS,cp3wSS-cp1SS);
+  printf("* multiset<THit*>               %6.2f        xxxx    %6.2f        xxxx     *\n",cp2wMS-cp1MS,cp3wMS-cp1MS);
+  printf("* map<int,THit*>                %6.2f        xxxx    %6.2f        xxxx     *\n",cp2wMAPS-cp1MAPS,cp3wMAPS-cp1MAPS);
+  printf("* multimap<int,THit*>           %6.2f        xxxx    %6.2f        xxxx     *\n",cp2wMMAPS-cp1MMAPS,cp3wMMAPS-cp1MMAPS);
   printf("* TClonesArray(TObjHit)         %6.2f        0.09    %6.2f        1.28     *\n",cp8w-cp1, cp9w-cp1);
   printf("* TClonesArray(TObjHit) split   %6.2f        0.09    %6.2f        1.28     *\n",cp10w-cp1,cp11w-cp1);
   printf("******************************************************************************\n");
   printf("* Time to read in seconds       comp 0    Reference    comp 1    Reference   *\n");
   printf("******************************************************************************\n");
   printf("* vector<THit>                  %6.2f        0.68    %6.2f        1.29     *\n",cp2r,cp3r);
+  printf("* list<THit>                    %6.2f        xxxx    %6.2f        xxxx     *\n",cp2rL,cp3rL);
+  printf("* deque<THit>                   %6.2f        xxxx    %6.2f        xxxx     *\n",cp2rD,cp3rD);
+  printf("* set<THit>                     %6.2f        xxxx    %6.2f        xxxx     *\n",cp2rS,cp3rS);
+  printf("* multiset<THit>                %6.2f        xxxx    %6.2f        xxxx     *\n",cp2rM,cp3rM);
+  printf("* map<int,THit>                 %6.2f        xxxx    %6.2f        xxxx     *\n",cp2rMAP,cp3rMAP);
+  printf("* multimap<int,THit>            %6.2f        xxxx    %6.2f        xxxx     *\n",cp2rMMAP,cp3rMMAP);
   printf("* vector<THit*>                 %6.2f        0.65    %6.2f        1.31     *\n",cp5r,cp6r);
+  printf("* list<THit*>                   %6.2f        xxxx    %6.2f        xxxx     *\n",cp2rLS,cp3rLS);
+  printf("* deque<THit*>                  %6.2f        xxxx    %6.2f        xxxx     *\n",cp2rDS,cp3rDS);
+  printf("* set<THit*>                    %6.2f        xxxx    %6.2f        xxxx     *\n",cp2rSS,cp3rSS);
+  printf("* multiset<THit*>               %6.2f        xxxx    %6.2f        xxxx     *\n",cp2rMS,cp3rMS);
+  printf("* map<int,THit*>                %6.2f        xxxx    %6.2f        xxxx     *\n",cp2rMAPS,cp3rMAPS);
+  printf("* multimap<int,THit*>           %6.2f        xxxx    %6.2f        xxxx     *\n",cp2rMMAPS,cp3rMMAPS);
   printf("* TClonesArray(TObjHit)         %6.2f        0.34    %6.2f        0.76     *\n",cp8r,cp9r);
   printf("* TClonesArray(TObjHit) split   %6.2f        0.33    %6.2f        0.75     *\n",cp10r,cp11r);
   printf("******************************************************************************\n");
@@ -309,6 +852,7 @@ int main(int argc, char** argv)
   printf("* Estimated ROOTMARKS         %8.2f      600.00                           *\n",rootmarks);
   printf("******************************************************************************\n");
 
+#if 0
   // show results with graphics
    gStyle->SetTitleH(0.12);
    gStyle->SetTitleW(0.8);
@@ -379,6 +923,6 @@ int main(int argc, char** argv)
    cbench->Print();
 
    theApp->Run();
-
+#endif
    return 0;
 }
diff --git a/test/benchLinkDef.h b/test/benchLinkDef.h
index 35f43303c00..8f774993bd6 100644
--- a/test/benchLinkDef.h
+++ b/test/benchLinkDef.h
@@ -6,8 +6,26 @@
 
 #pragma link C++ class THit!+;
 #pragma link C++ class TObjHit+;
-#pragma link C++ class TSTLhit+;
-#pragma link C++ class TSTLhitStar+;
+#pragma link C++ class TSTLhit;
+#pragma link C++ class TSTLhitList;
+#pragma link C++ class TSTLhitDeque;
+#pragma link C++ class TSTLhitSet;
+#pragma link C++ class TSTLhitMultiset;
+#pragma link C++ class TSTLhitMap;
+#pragma link C++ class TSTLhitMultiMap;
+//#pragma link C++ class TSTLhitHashSet;
+//#pragma link C++ class TSTLhitHashMultiset;
+#pragma link C++ class pair<int,THit>;
+
+#pragma link C++ class TSTLhitStar;
+#pragma link C++ class TSTLhitStarList;
+#pragma link C++ class TSTLhitStarDeque;
+#pragma link C++ class TSTLhitStarSet;
+#pragma link C++ class TSTLhitStarMultiSet;
+#pragma link C++ class TSTLhitStarMap;
+#pragma link C++ class TSTLhitStarMultiMap;
+#pragma link C++ class pair<int,THit*>;
+
 #pragma link C++ class TCloneshit+;
 
 #endif
diff --git a/tree/src/TBranchElement.cxx b/tree/src/TBranchElement.cxx
index d557906c688..ad0c367e2eb 100644
--- a/tree/src/TBranchElement.cxx
+++ b/tree/src/TBranchElement.cxx
@@ -1,4 +1,4 @@
-// @(#)root/tree:$Name:  $:$Id: TBranchElement.cxx,v 1.148 2004/10/17 11:55:47 brun Exp $
+// @(#)root/tree:$Name:  $:$Id: TBranchElement.cxx,v 1.149 2004/10/17 20:59:58 brun Exp $
 // Author: Rene Brun   14/01/2001
 
 /*************************************************************************
@@ -175,7 +175,8 @@ TBranchElement::TBranchElement(const char *bname, TStreamerInfo *sinfo, Int_t id
    // create sub branches if requested by splitlevel
 
    if (splitlevel > 0) {
-      int stl = TClassEdit::IsSTLCont(element->GetTypeName());
+      const char* elem_type = element->GetTypeName();
+      int stl = TClassEdit::IsSTLCont(elem_type);
       TClass *clm;
       if (element->CannotSplit()) {
          //printf("element: %s/%s will not be split\n",element->GetName(),element->GetTitle());
@@ -196,8 +197,8 @@ TBranchElement::TBranchElement(const char *bname, TStreamerInfo *sinfo, Int_t id
          }
          return;
 
-      } else if (!strcmp(element->GetTypeName(),"TClonesArray") || !strcmp(element->GetTypeName(),"TClonesArray*")) {
-         Bool_t ispointer = !strcmp(element->GetTypeName(),"TClonesArray*");
+      } else if (!strcmp(elem_type,"TClonesArray") || !strcmp(elem_type,"TClonesArray*")) {
+         Bool_t ispointer = !strcmp(elem_type,"TClonesArray*");
          TClonesArray *clones;
          if (ispointer) {
             char **ppointer = (char**)(pointer);
@@ -242,9 +243,11 @@ TBranchElement::TBranchElement(const char *bname, TStreamerInfo *sinfo, Int_t id
          BuildTitle(name);
          return;
 
-      } else if (stl>=1 && stl <=2) { // case of vector<> or list<>
+      } else if ( (stl>= TClassEdit::kVector   && stl<= TClassEdit::kMultiSet) || 
+                  (stl>=-TClassEdit::kMultiSet && stl<=-TClassEdit::kVector) ) {
+         // case of vector<>, list<> deque<>, set<>, multiset<>
 
-         TClass *contCl = gROOT->GetClass(element->GetTypeName());
+         TClass *contCl = gROOT->GetClass(elem_type);
 
          fCollProxy = contCl->GetCollectionProxy()->Generate();
 
@@ -252,25 +255,15 @@ TBranchElement::TBranchElement(const char *bname, TStreamerInfo *sinfo, Int_t id
 
          // See if we can split:
          Bool_t cansplit = kTRUE;
-
          if (clm==0) {
-
             cansplit = kFALSE;
-
          } else if (clm==TString::Class() || clm==gROOT->GetClass("string")) {
-
             cansplit = kFALSE;
-
          } else if (fCollProxy->HasPointers()) {
-
             cansplit = kFALSE;
-
          } else if ( !clm->CanSplit() ) {
-
             cansplit = kFALSE;
-
          } else if ( clm->GetCollectionProxy() != 0 ) {
-
             // A collection was stored in a collection, we do not know how to split it.
             cansplit = kFALSE;
          }
@@ -312,17 +305,17 @@ TBranchElement::TBranchElement(const char *bname, TStreamerInfo *sinfo, Int_t id
             return;
          }
 
-      } else if (!strchr(element->GetTypeName(),'*') &&
+      } else if (!strchr(elem_type,'*') &&
                  (fStreamerType == TStreamerInfo::kObject || fStreamerType == TStreamerInfo::kAny)) {
          // ===> create sub branches for members that are classes
          fType = 2;
-         clm = gROOT->GetClass(element->GetTypeName());
+         clm = gROOT->GetClass(elem_type);
          if (Unroll(name,clm,clm,basketsize,splitlevel,0) >= 0) return;
 
       }
    }
 
-   TLeaf *leaf     = new TLeafElement(GetTitle(),fID, fStreamerType);
+   TLeaf *leaf = new TLeafElement(GetTitle(),fID, fStreamerType);
    leaf->SetTitle(GetTitle());
    leaf->SetBranch(this);
    fNleaves = 1;
@@ -1168,14 +1161,35 @@ Int_t TBranchElement::GetEntry(Long64_t entry, Int_t getall)
       //one must always read the branch counter.
       //In the case when one reads consecutively twice the same entry,
       //the user may have cleared the TClonesArray between the 2 GetEntry
-      if (fType == 3 || fType == 4) nbytes += TBranch::GetEntry(entry, getall);
-
-      Int_t nb;
-      for (Int_t i=0;i<nbranches;i++)  {
-         TBranch *branch = (TBranch*)fBranches[i];
-         nb  = branch->GetEntry(entry, getall);
-         if (nb < 0) return nb;
-         nbytes += nb;
+      if ( fType == 3 || fType == 4 )  {
+        nbytes += TBranch::GetEntry(entry, getall);
+      }
+      if ( fType == 4)   {
+        // Note: Proxy-helper needs to "embrace" the entire
+        //       streaming of this STL container if the container
+        //       is a set/multiset/map/multimap (what we do not
+        //       know here).
+        //       For vector/list/deque Allocate == Resize
+        //                         and Commit   == noop.
+        // TODO: Exception safety a la TPushPop
+        TVirtualCollectionProxy* proxy = GetCollectionProxy();
+        TVirtualCollectionProxy::TPushPop helper(proxy,fAddress);
+        void* env = proxy->Allocate(fNdata,true);
+        for (Int_t i=0;i<nbranches;i++)  {
+          TBranch *branch = (TBranch*)fBranches[i];
+          Int_t    nb = branch->GetEntry(entry, getall);
+          if (nb < 0) return nb;
+          nbytes += nb;
+        }
+        proxy->Commit(env);
+      }
+      else  {
+        for (Int_t i=0;i<nbranches;i++)  {
+          TBranch *branch = (TBranch*)fBranches[i];
+          Int_t    nb = branch->GetEntry(entry, getall);
+          if (nb < 0) return nb;
+          nbytes += nb;
+        }
       }
    } else {
       //terminal branch
@@ -1684,8 +1698,6 @@ void TBranchElement::ReadLeaves(TBuffer &b)
      }
      fNdata = n;
      if (!fObject) return;
-     TVirtualCollectionProxy::TPushPop helper(GetCollectionProxy(),fAddress);
-     fCollProxy->Resize(fNdata,true);
   } else if (fType == 41) {    // sub branch of an STL class
      //Error("ReadLeaves","STL split mode not yet implemented (error 2)\n");
      //char **ppointer = (char**)fAddress;
@@ -2279,13 +2291,12 @@ Int_t TBranchElement::Unroll(const char *name, TClass *cltop, TClass *cl,Int_t b
                fBranches.Add(branch);
             }
          } else if (elem->IsA() == TStreamerSTL::Class() && !elem->IsaPointer()) {
+            // here all STL classes are handled
             Int_t subSplitlevel = splitlevel-1;
-
             if (elem->CannotSplit()) {
                subSplitlevel = 0;
             }
-
-            char *pointer = fBranchPointer + offset;
+            char* pointer = fBranchPointer + offset;
             branch = new TBranchElement(branchname,info,jd,/* 0 */ pointer ,basketsize,subSplitlevel,btype);
             branch->SetParentName(cltop->GetName());
             fBranches.Add(branch);
diff --git a/tree/src/TTree.cxx b/tree/src/TTree.cxx
index 6b202cb8acd..683c6d16eb2 100644
--- a/tree/src/TTree.cxx
+++ b/tree/src/TTree.cxx
@@ -1,4 +1,4 @@
-// @(#)root/tree:$Name:  $:$Id: TTree.cxx,v 1.211 2004/10/14 10:17:03 brun Exp $
+// @(#)root/tree:$Name:  $:$Id: TTree.cxx,v 1.212 2004/10/18 12:32:12 brun Exp $
 // Author: Rene Brun   12/01/96
 
 /*************************************************************************
@@ -1347,7 +1347,7 @@ TBranch *TTree::Bronch(const char *name, const char *classname, void *add, Int_t
    TString inclass;
    int stlcont = TClassEdit::IsSTLCont(classname);
 
-   if (stlcont>=1 && stlcont<=2 ) {
+   if ( (stlcont>=1 && stlcont<=8) || (stlcont>=-8 && stlcont<=-1) ) {
       inclass = TClassEdit::ShortType(classname,1+2+4).c_str();
       TClass *inklass = gROOT->GetClass(inclass.Data());
       if (!inklass) {
@@ -1391,7 +1391,8 @@ TBranch *TTree::Bronch(const char *name, const char *classname, void *add, Int_t
    }
    //====>
    //====> special case of vector<...> or list<...>
-   if(stlcont>=1 && stlcont<=2) {
+   TVirtualCollectionProxy *collProxy = cl->GetCollectionProxy();
+   if( collProxy )  { // MSF: stlcont>=1 && stlcont<=2) {
       TVirtualCollectionProxy *collProxy = cl->GetCollectionProxy()->Generate(); // TSTLCont  *tstl = new TSTLCont(classname,(void*)objadd);
       TBranchElement *branch = new TBranchElement(name,collProxy,bufsize,splitlevel);
       fBranches.Add(branch);
diff --git a/utils/src/RStl.cxx b/utils/src/RStl.cxx
index 4c717924d3f..932eba074d2 100644
--- a/utils/src/RStl.cxx
+++ b/utils/src/RStl.cxx
@@ -1,4 +1,4 @@
-// @(#)root/utils:$Name:  $:$Id: RStl.cxx,v 1.7 2004/04/15 06:41:49 brun Exp $
+// @(#)root/utils:$Name:  $:$Id: RStl.cxx,v 1.8 2004/07/15 23:08:23 rdm Exp $
 // Author: Philippe Canal 27/08/2003
 
 /*************************************************************************
@@ -267,6 +267,10 @@ void ROOT::RStl::WriteStreamer(FILE *file, G__ClassInfo &stlcl) {
    fprintf(file, "} // close namespace ROOT\n\n");
 
    fprintf(file, "// Register the streamer (a typedef is used to avoid problem with macro parameters\n");
+
+   //if ( 0 != ::getenv("MY_ROOT") && ::getenv("MY_ROOT")[0]>'1' )  {
+   //  fprintf(file, "// Disabled due customized build:\n// ");
+   //}
    fprintf(file, "RootStlStreamer(%s,%s)\n", typedefName.c_str(), streamerName.c_str());
    fprintf(file, "\n");
 
diff --git a/utils/src/rootcint.cxx b/utils/src/rootcint.cxx
index 6c0b03fd839..ff0ab040284 100644
--- a/utils/src/rootcint.cxx
+++ b/utils/src/rootcint.cxx
@@ -1,4 +1,4 @@
-// @(#)root/utils:$Name:  $:$Id: rootcint.cxx,v 1.189 2004/10/08 07:39:21 brun Exp $
+// @(#)root/utils:$Name:  $:$Id: rootcint.cxx,v 1.190 2004/10/11 10:30:24 rdm Exp $
 // Author: Fons Rademakers   13/07/96
 
 /*************************************************************************
@@ -293,6 +293,11 @@ char *StrDup(const char *str);
 
 char FunNames[10000] = { 0 };
 
+//const char* root_style()  {
+//  static const char* s = ::getenv("MY_ROOT");
+//  return s;
+//}
+
 // static int check = 0;
 //______________________________________________________________________________
 void SetFun (const char *fname)
@@ -1641,7 +1646,10 @@ int STLContainerStreamer(G__DataMemberInfo &m, int rwmode)
 
          case kMap:
          case kMultiMap:
-            fprintf(fp, "            R__stl.insert(make_pair(R__t,R__t2));\n");
+            fprintf(fp, "            std::pair<const %s,",TemplateArg(m).Name());
+            fprintf(fp, "%s> R__t3(R__t,R__t2);\n",TemplateArg(m,1).Name());
+            fprintf(fp, "            R__stl.insert(R__t3);\n");
+          //fprintf(fp, "            R__stl.insert(%s::value_type(R__t,R__t2));\n",stlType.c_str());
             break;
          case kSet:
          case kMultiSet:
@@ -1756,6 +1764,7 @@ int STLStringStreamer(G__DataMemberInfo &m, int rwmode)
 }
 
 //______________________________________________________________________________
+#ifdef OLDSTREAMER
 int STLBaseStreamer(G__BaseClassInfo &m, int rwmode)
 {
    // Create Streamer code for an STL base class. Returns 1 if base class
@@ -1959,7 +1968,7 @@ int STLBaseStreamer(G__BaseClassInfo &m, int rwmode)
    }
    return 0;
 }
-
+#endif
 //______________________________________________________________________________
 int PointerToPointer(G__DataMemberInfo &m)
 {
@@ -2203,11 +2212,59 @@ void WriteClassInit(G__ClassInfo &cl)
      fprintf(fp, "      instance.SetDeleteArray(&deleteArray_%s);\n",mappedname.c_str());
      fprintf(fp, "      instance.SetDestructor(&destruct_%s);\n",mappedname.c_str());
    }
-   if (stl==1 || stl==-1) {
+   if (stl != 0 && ((stl>0 && stl<8) || (stl<0 && stl>-8)) )  {
+      int idx = classname.find("<");
+      int STL_type = (idx!=(int)std::string::npos) ? TClassEdit::STLKind(classname.substr(0,idx).c_str()) : 0;
+      //if ( root_style() && root_style()[0]>'0' )  {
+        //fprintf(stdout,"// Executing rootcint in customized mode:%s class:%s STL:%d\n",
+          //root_style(), classname.c_str(), stl);
+        switch(STL_type)  {
+          case TClassEdit::kVector:
+          case TClassEdit::kList:
+          case TClassEdit::kDeque:
+            //switch(root_style()[0])  {
+            //  case '3':
+            //    fprintf(fp, "      // Streamer and proxy omitted for class: %s\n",classname.c_str());
+            //    break;
+            //  case '2':
+                fprintf(fp, "      instance.AdoptStreamer(TCollectionProxy::genClassStreamer<TCollectionProxy::Pushback<%s > >());\n",classname.c_str());
+            //  case '1':
+                fprintf(fp, "      instance.AdoptCollectionProxy(TCollectionProxy::genProxy<TCollectionProxy::Pushback<%s > >());\n",classname.c_str());
+            //    break;
+            //}
+            break;
+          case TClassEdit::kMap:
+          case TClassEdit::kMultiMap:
+            //switch(root_style()[0])  {
+            //  case '3':
+            //    break;
+            //  case '2':
+                fprintf(fp, "      instance.AdoptStreamer(TCollectionProxy::genClassStreamer<TCollectionProxy::MapInsert<%s > >());\n",classname.c_str());
+            //  case '1':
+                fprintf(fp, "      instance.AdoptCollectionProxy(TCollectionProxy::genProxy<TCollectionProxy::MapInsert<%s > >());\n",classname.c_str());
+            //    break;
+            //}
+            break;
+          case TClassEdit::kSet:
+          case TClassEdit::kMultiSet:
+            //switch(root_style()[0])  {
+            //  case '3':
+            //    break;
+            //  case '2':
+                fprintf(fp, "      instance.AdoptStreamer(TCollectionProxy::genClassStreamer<TCollectionProxy::Insert<%s > >());\n",classname.c_str());
+            //  case '1':
+                fprintf(fp, "      instance.AdoptCollectionProxy(TCollectionProxy::genProxy<TCollectionProxy::Insert<%s > >());\n",classname.c_str());
+            //    break;
+            //}
+            break;
+        }
+      //}
+   }
+   else if (stl==1 || stl==-1) {
       if (TClassEdit::IsVectorBool(classname.c_str())) {
-         fprintf(fp, "      instance.AdoptCollectionProxy(new ::ROOT::TBoolVectorProxy<%s >);\n",classname.c_str());
+        fprintf(fp, "      instance.AdoptCollectionProxy(new ::ROOT::TBoolVectorProxy<%s >);\n",classname.c_str());
       } else {
-         fprintf(fp, "      instance.AdoptCollectionProxy(new ::ROOT::TVectorProxy<%s >);\n",classname.c_str());
+        fprintf(fp, "      instance.AdoptCollectionProxy(new ::ROOT::TVectorProxy<%s >);\n",classname.c_str());
       }
    }
    fprintf(fp, "      return &instance;\n");
@@ -4315,8 +4372,9 @@ int main(int argc, char **argv)
    fprintf(fp, "#endif\n\n");
    fprintf(fp, "#include \"RtypesImp.h\"\n\n");
    fprintf(fp, "#include \"TVectorProxy.h\"\n\n");
+   fprintf(fp, "#include \"TCollectionProxy.h\"\n\n");
 #ifdef R__SOLARIS
-   fprintf(fp, "// Since CINT ignores the std namespace, we need to do so in this file.\n");
+   fprintf(fp, "// Since CINT ignores the std namespace, we need to do so in this file.\n");
    fprintf(fp, "namespace std {} using namespace std;\n\n");
 #endif
 
@@ -4597,7 +4655,7 @@ int main(int argc, char **argv)
       WriteClassCode(cl);
    }
 
-   RStl::inst().WriteStreamer(fp);
+   //RStl::inst().WriteStreamer(fp); //replaced by new Markus code
    RStl::inst().WriteClassInit(fp);
 
    fclose(fp);
-- 
GitLab