compilerplugins/clang/store/staticvar.cxx    |    1 
 cui/source/tabpages/tabarea.cxx              |   10 
 editeng/source/editeng/impedit4.cxx          |    8 
 include/svl/itempool.hxx                     |   82 +--
 include/svl/itemset.hxx                      |    9 
 include/svl/poolitem.hxx                     |    9 
 sc/inc/fillinfo.hxx                          |    4 
 sc/source/core/data/documen9.cxx             |    7 
 sc/source/core/data/document.cxx             |    4 
 sc/source/core/data/document10.cxx           |    4 
 sc/source/core/data/fillinfo.cxx             |   15 
 sc/source/core/data/poolcach.cxx             |    2 
 sc/source/filter/xml/xmlexprt.cxx            |    4 
 sc/source/filter/xml/xmlfonte.cxx            |    8 
 sc/source/ui/view/cellsh1.cxx                |   14 
 sc/source/ui/view/output.cxx                 |   12 
 sc/source/ui/view/tabvwshc.cxx               |    7 
 sc/source/ui/view/viewfunc.cxx               |   12 
 sd/source/core/drawdoc2.cxx                  |    8 
 sd/source/ui/unoidl/unomodel.cxx             |    7 
 solenv/clang-format/excludelist              |    2 
 svl/CppunitTest_svl_itempool.mk              |   34 -
 svl/Module_svl.mk                            |    1 
 svl/qa/unit/items/test_itempool.cxx          |  108 ---
 svl/source/inc/poolio.hxx                    |   73 --
 svl/source/items/itempool.cxx                |  734 +++++++++------------------
 svl/source/items/itemset.cxx                 |  276 ++++++----
 svl/source/items/poolitem.cxx                |    1 
 svx/source/unodraw/UnoNameItemTable.cxx      |   24 
 svx/source/unodraw/UnoNamespaceMap.cxx       |   14 
 svx/source/unodraw/unomtabl.cxx              |   46 +
 svx/source/unodraw/unoshape.cxx              |    4 
 svx/source/xoutdev/xattr.cxx                 |   50 +
 sw/source/core/crsr/crstrvl.cxx              |   14 
 sw/source/core/doc/DocumentFieldsManager.cxx |    7 
 sw/source/core/doc/doc.cxx                   |   16 
 sw/source/core/doc/docbasic.cxx              |    4 
 sw/source/core/doc/docfld.cxx                |   12 
 sw/source/core/doc/docfmt.cxx                |    8 
 sw/source/core/doc/doctxm.cxx                |    4 
 sw/source/core/doc/visiturl.cxx              |    4 
 sw/source/core/docnode/node.cxx              |    4 
 sw/source/core/edit/edfld.cxx                |    8 
 sw/source/core/fields/docufld.cxx            |    4 
 sw/source/core/layout/trvlfrm.cxx            |    4 
 sw/source/core/table/swnewtable.cxx          |    4 
 sw/source/core/table/swtable.cxx             |    8 
 sw/source/core/undo/unattr.cxx               |    5 
 sw/source/core/unocore/unostyle.cxx          |    4 
 sw/source/core/view/vprint.cxx               |    7 
 sw/source/filter/html/htmlflywriter.cxx      |    7 
 sw/source/filter/writer/writer.cxx           |   31 -
 sw/source/filter/ww8/rtfexport.cxx           |   25 
 sw/source/filter/ww8/wrtw8sty.cxx            |    4 
 sw/source/filter/ww8/wrtww8.cxx              |    7 
 sw/source/filter/xml/xmlexp.cxx              |    4 
 sw/source/filter/xml/xmlfonte.cxx            |    4 
 sw/source/uibase/utlui/content.cxx           |   10 
 vcl/win/gdi/gdiimpl.cxx                      |    2 
 59 files changed, 806 insertions(+), 999 deletions(-)

New commits:
commit ae7807c889c19145f89cec40afac82eee191837c
Author:     Armin Le Grand (allotropia) <armin.le.grand.ext...@allotropia.de>
AuthorDate: Wed Jan 10 20:07:47 2024 +0100
Commit:     Armin Le Grand <armin.le.gr...@me.com>
CommitDate: Fri Jan 12 12:15:54 2024 +0100

    ITEM: No longer register Items at Pool
    
    The issue is that the flag RegisteredAtPool
    at the SfxPoolItem is Pool-dependent: It marks that
    the Item is registeres at *one* Pool/Model. This
    makes it Pool-dependent. Due to this there is no way
    to share Items that need to be registered globally/
    in multiple Pools/Models what is one of the goals
    for optimal sharing.
    
    We can also not live without having access to all
    Items associated with the Pool, due to mechanisms
    in place like the Surrogate stuff.
    
    This again is used for two purposes:
    
    (1) Access all Items associated with one Pool/Model,
    at least that is the assumption. This is not valid
    since it gets corrupted with a single ItemSet/Holder
    used that does not host model data, e.g. an open
    Dialog or the Sidebar (or...). But works in
    principle.
    
    (2) Access extra-Items that are held nowhere and
    are created using DirectPutItemInPool, e.g. infos
    for a Dialog. These would need a instance/place to
    host them, the Pool is (ab)used for that.
    
    Both are 'compromizes' (to not use a more bad word)
    and should not exist. (1) should iterate over the
    Model and do actions. There are even places that
    use (1) to *change* Items, by casting them to
    non-const, even RefCounted ones, so having no control
    over what all might be changed doing so. Since we
    talk about ca. 100+ places there is no way to get
    away from this - I can imagine how this happened:
    The 'poolable' attr traditionally needed for the old
    binary format was one day 'used' to not need to
    iterate over the Model, an API was added to access
    and this usage was copied. Sigh..
    
    It is even used when ODF is loaded: E.g. the
    FillStyle is imported from XML, interpreted, and
    put into an ItemSet. Then it gets set at the
    XShape using UNO API and a *name* -> that name and
    the Surrogate mechanism is used to find and set the
    FillStyle at the Model Object. The FillStyle could
    probably just be set using UNO API and the data
    directly.
    
    The association between Model/Pool and Item is
    created by the object hosting the Item, these are
    ItemSets and ItemHolders. Thus it is possible to
    register these at the Pool. This allows to iterate
    and collect the Items associated with the Pool
    and keep the Surrogate mechanism alive.
    This is the main change done here. It limits
    the registrations to Items for which (at the Pool)
    the NeedsPoolRegistration is set, also
    Item-independent. Speed is okay, I saw no big
    changes in my tests here. The registration is
    just pointers, no ownership or RefCounting needed
    here.
    
    The advantage is that Items get closer to be
    shared office-wide, they can be referenced by
    multiple ItemSets (RefCnt) associated with
    different Pools/Models.
    NOTE: This is not true for SfxSetItems, these are
    and will stay Pool-dependent due to their need
    to a Pool in the contained ItemSet.
    Note that we have ca. six deivations of SfxSetItem,
    but ca. 500+ Item derivations, so not too bad.
    
    For the usages of Surrogates to change existing,
    RefCounted Items: These can now at least be
    changed - if they show up to be problematic - to
    iterate over the registered ItemSets and change
    Items there the correct way: Set a changed one
    at the ItemSet. That also allows Objects to
    *react* on ItemChanges, there is no way to do
    that with the existing 'compromize'...
    
    UnitTests show that this already works well for
    SC and SD, but SW has still some issues. I will
    put this to gerrit now, but there will be
    additional work.
    
    A involved problem is the current DefaultItem
    handling and the state the Pool implementation
    is in. E.g. StaticDefaults are not really static,
    Pools hard-delete the DefaultItems (forcing the
    RefCnt to zero to not have the destructor
    complain) and other quirks. Looking at that
    right now, hoping to get this change done without
    having to change that too much.
    
    I thought about adapting PoolItemTest to this,
    but it is only related to DirectPutItemInPool
    which is mostly gone and hopefully completely
    soon.
    Nonetheless I adapted that mechanism to use a
    list of SfxPoolItemHolder at the Pool. That makes
    it safe and abandons the need for indirect
    garbage collection removal at the Pool.
    
    Change-Id: Ib47f21dafa989202930919eace5f7e9c5632ce96
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/161896
    Tested-by: Jenkins
    Reviewed-by: Armin Le Grand <armin.le.gr...@me.com>

diff --git a/compilerplugins/clang/store/staticvar.cxx 
b/compilerplugins/clang/store/staticvar.cxx
index 21cbd0f08172..774ab92245bb 100644
--- a/compilerplugins/clang/store/staticvar.cxx
+++ b/compilerplugins/clang/store/staticvar.cxx
@@ -53,7 +53,6 @@ public:
             || fn == SRCDIR "/sal/qa/rtl/digest/rtl_digest.cxx"
             || fn == SRCDIR "/sal/qa/rtl/strings/test_oustring_endswith.cxx"
             || fn == SRCDIR "/sal/qa/rtl/strings/test_oustring_convert.cxx"
-            || fn == SRCDIR "/svl/qa/unit/items/test_itempool.cxx"
             // contains mutable state
             || fn == SRCDIR "/vcl/unx/generic/dtrans/X11_selection.cxx"
             || fn == SRCDIR "/sax/qa/cppunit/xmlimport.cxx"
diff --git a/cui/source/tabpages/tabarea.cxx b/cui/source/tabpages/tabarea.cxx
index 4b50b74b8b68..b4ef7edb6791 100644
--- a/cui/source/tabpages/tabarea.cxx
+++ b/cui/source/tabpages/tabarea.cxx
@@ -83,7 +83,7 @@ void SvxAreaTabDialog::SavePalettes()
         if ( pShell )
             pShell->PutItem( aColorListItem );
         else
-            
mpDrawModel->GetItemPool().DirectPutItemInPool(aColorListItem,SID_COLOR_TABLE);
+            mpDrawModel->GetItemPool().DirectPutItemInPool(aColorListItem);
         mpColorList = mpDrawModel->GetColorList();
     }
     if( mpNewGradientList != mpDrawModel->GetGradientList() )
@@ -93,7 +93,7 @@ void SvxAreaTabDialog::SavePalettes()
         if ( pShell )
             pShell->PutItem( aItem );
         else
-            
mpDrawModel->GetItemPool().DirectPutItemInPool(aItem,SID_GRADIENT_LIST);
+            mpDrawModel->GetItemPool().DirectPutItemInPool(aItem);
         mpGradientList = mpDrawModel->GetGradientList();
     }
     if( mpNewHatchingList != mpDrawModel->GetHatchList() )
@@ -103,7 +103,7 @@ void SvxAreaTabDialog::SavePalettes()
         if ( pShell )
             pShell->PutItem( aItem );
         else
-            
mpDrawModel->GetItemPool().DirectPutItemInPool(aItem,SID_HATCH_LIST);
+            mpDrawModel->GetItemPool().DirectPutItemInPool(aItem);
         mpHatchingList = mpDrawModel->GetHatchList();
     }
     if( mpNewBitmapList != mpDrawModel->GetBitmapList() )
@@ -113,7 +113,7 @@ void SvxAreaTabDialog::SavePalettes()
         if ( pShell )
             pShell->PutItem( aItem );
         else
-            
mpDrawModel->GetItemPool().DirectPutItemInPool(aItem,SID_BITMAP_LIST);
+            mpDrawModel->GetItemPool().DirectPutItemInPool(aItem);
         mpBitmapList = mpDrawModel->GetBitmapList();
     }
     if( mpNewPatternList != mpDrawModel->GetPatternList() )
@@ -123,7 +123,7 @@ void SvxAreaTabDialog::SavePalettes()
         if( pShell )
             pShell->PutItem( aItem );
         else
-            
mpDrawModel->GetItemPool().DirectPutItemInPool(aItem,SID_PATTERN_LIST);
+            mpDrawModel->GetItemPool().DirectPutItemInPool(aItem);
         mpPatternList = mpDrawModel->GetPatternList();
     }
 
diff --git a/editeng/source/editeng/impedit4.cxx 
b/editeng/source/editeng/impedit4.cxx
index d63522a555c1..7fa5389475e3 100644
--- a/editeng/source/editeng/impedit4.cxx
+++ b/editeng/source/editeng/impedit4.cxx
@@ -306,7 +306,9 @@ ErrCode ImpEditEngine::WriteRTF( SvStream& rOutput, 
EditSelection aSel )
         else if ( nScriptType == 2 )
             nWhich = EE_CHAR_FONTINFO_CTL;
 
-        for (const SfxPoolItem* pItem : 
maEditDoc.GetItemPool().GetItemSurrogates(nWhich))
+        ItemSurrogates aSurrogates;
+        maEditDoc.GetItemPool().GetItemSurrogates(aSurrogates, nWhich);
+        for (const SfxPoolItem* pItem : aSurrogates)
         {
             SvxFontItem const*const pFontItem = static_cast<const 
SvxFontItem*>(pItem);
             bool bAlreadyExist = false;
@@ -390,7 +392,9 @@ ErrCode ImpEditEngine::WriteRTF( SvStream& rOutput, 
EditSelection aSel )
     {
         aColorList.push_back(rDefault.GetValue());
     }
-    for (const SfxPoolItem* pItem : 
maEditDoc.GetItemPool().GetItemSurrogates(EE_CHAR_COLOR))
+    ItemSurrogates aSurrogates;
+    maEditDoc.GetItemPool().GetItemSurrogates(aSurrogates, EE_CHAR_COLOR);
+    for (const SfxPoolItem* pItem : aSurrogates)
     {
         auto pColorItem(dynamic_cast<SvxColorItem const*>(pItem));
         if (pColorItem && pColorItem->GetValue() != COL_AUTO) // may be null!
diff --git a/include/svl/itempool.hxx b/include/svl/itempool.hxx
index 2e6c5a9a38d3..0a2153c33267 100644
--- a/include/svl/itempool.hxx
+++ b/include/svl/itempool.hxx
@@ -29,9 +29,7 @@
 #include <unordered_set>
 #include <o3tl/sorted_vector.hxx>
 #include <salhelper/simplereferenceobject.hxx>
-
-class SfxBroadcaster;
-struct SfxItemPool_Impl;
+#include <svl/SfxBroadcaster.hxx>
 
 struct SfxItemInfo
 {
@@ -52,14 +50,17 @@ struct SfxItemInfo
     bool             _bShareable : 1;
 };
 
-class SfxItemPool;
-typedef std::unordered_set<const SfxPoolItem*> registeredSfxPoolItems;
-
 #ifdef DBG_UTIL
 SVL_DLLPUBLIC size_t getAllDirectlyPooledSfxPoolItemCount();
 SVL_DLLPUBLIC size_t getRemainingDirectlyPooledSfxPoolItemCount();
 #endif
 
+typedef std::unordered_set<const SfxItemSet*> registeredSfxItemSets;
+class SfxPoolItemHolder;
+typedef std::unordered_set<const SfxPoolItemHolder*> 
registeredSfxPoolItemHolders;
+typedef std::unordered_set<SfxPoolItemHolder*> directPutSfxPoolItemHolders;
+typedef std::vector<const SfxPoolItem*> ItemSurrogates;
+
 /** Base class for providers of defaults of SfxPoolItems.
  *
  * The derived classes hold the concrete (const) instances which are 
referenced in several places
@@ -69,21 +70,33 @@ SVL_DLLPUBLIC size_t 
getRemainingDirectlyPooledSfxPoolItemCount();
  */
 class SVL_DLLPUBLIC SfxItemPool : public salhelper::SimpleReferenceObject
 {
-    friend struct SfxItemPool_Impl;
     friend class SfxItemSet;
+    friend class SfxPoolItemHolder;
     friend class SfxAllItemSet;
 
     // allow ItemSetTooling to access
     friend SfxPoolItem const* implCreateItemEntry(SfxItemPool&, SfxPoolItem 
const*, sal_uInt16, bool);
-    friend void implCleanupItemEntry(SfxItemPool&, SfxPoolItem const*);
+    friend void implCleanupItemEntry(SfxPoolItem const*);
 
     // unit testing
     friend class PoolItemTest;
 
     const SfxItemInfo*              pItemInfos;
-    std::unique_ptr<SfxItemPool_Impl>               pImpl;
-
-    registeredSfxPoolItems** ppRegisteredSfxPoolItems;
+    SfxBroadcaster                  aBC;
+    OUString                        aName;
+    std::vector<SfxPoolItem*>       maPoolDefaults;
+    std::vector<SfxPoolItem*>*      mpStaticDefaults;
+    SfxItemPool*                    mpMaster;
+    rtl::Reference<SfxItemPool>     mpSecondary;
+    WhichRangesContainer            mpPoolRanges;
+    sal_uInt16                      mnStart;
+    sal_uInt16                      mnEnd;
+    MapUnit                         eDefMetric;
+
+    registeredSfxItemSets maRegisteredSfxItemSets;
+    registeredSfxPoolItemHolders maRegisteredSfxPoolItemHolders;
+    directPutSfxPoolItemHolders maDirectPutItems;
+    bool mbPreDeleteDone;
 
 private:
     sal_uInt16                      GetIndex_Impl(sal_uInt16 nWhich) const;
@@ -94,6 +107,14 @@ private:
     SVL_DLLPRIVATE bool             Shareable_Impl(sal_uInt16 nPos) const
     { return pItemInfos[nPos]._bShareable; }
 
+    void registerItemSet(SfxItemSet& rSet);
+    void unregisterItemSet(SfxItemSet& rSet);
+
+    void registerPoolItemHolder(SfxPoolItemHolder& rHolder);
+    void unregisterPoolItemHolder(SfxPoolItemHolder& rHolder);
+
+    void CollectSurrogates(std::unordered_set<const SfxPoolItem*>& rTarget, 
sal_uInt16 nWhich) const;
+
 public:
     // for default SfxItemSet::CTOR, set default WhichRanges
     void                            FillItemIdRanges_Impl( 
WhichRangesContainer& pWhichRanges ) const;
@@ -112,7 +133,6 @@ public:
                                                  const SfxItemInfo *pItemInfos,
                                                  std::vector<SfxPoolItem*> 
*pDefaults = nullptr );
 
-public:
     virtual                         ~SfxItemPool();
 
     SfxBroadcaster&                 BC();
@@ -167,34 +187,24 @@ public:
     virtual rtl::Reference<SfxItemPool> Clone() const;
     const OUString&                 GetName() const;
 
-    template<class T> const T&      DirectPutItemInPool( std::unique_ptr<T> 
xItem, sal_uInt16 nWhich = 0 )
-    { return static_cast<const T&>(DirectPutItemInPoolImpl( *xItem.release(), 
nWhich, /*bPassingOwnership*/true)); }
-    template<class T> const T&      DirectPutItemInPool( const T& rItem, 
sal_uInt16 nWhich = 0 )
-    { return static_cast<const T&>(DirectPutItemInPoolImpl( rItem, nWhich, 
/*bPassingOwnership*/false)); }
-    void                            DirectRemoveItemFromPool( const 
SfxPoolItem& );
+    const SfxPoolItem& DirectPutItemInPool(const SfxPoolItem&);
+    void DirectRemoveItemFromPool(const SfxPoolItem&);
 
     const SfxPoolItem&              GetDefaultItem( sal_uInt16 nWhich ) const;
     template<class T> const T&      GetDefaultItem( TypedWhichId<T> nWhich ) 
const
     { return static_cast<const T&>(GetDefaultItem(sal_uInt16(nWhich))); }
-
-    struct Item2Range
-    {
-        o3tl::sorted_vector<SfxPoolItem*>::const_iterator m_begin;
-        o3tl::sorted_vector<SfxPoolItem*>::const_iterator m_end;
-        o3tl::sorted_vector<SfxPoolItem*>::const_iterator const & begin() 
const { return m_begin; }
-        o3tl::sorted_vector<SfxPoolItem*>::const_iterator const & end() const 
{ return m_end; }
-    };
     const SfxPoolItem *             GetItem2Default(sal_uInt16 nWhich) const;
     template<class T> const T*      GetItem2Default( TypedWhichId<T> nWhich ) 
const
     { return static_cast<const T*>(GetItem2Default(sal_uInt16(nWhich))); }
 
-    const registeredSfxPoolItems&   GetItemSurrogates(sal_uInt16 nWhich) const;
+public:
+    void GetItemSurrogates(ItemSurrogates& rTarget, sal_uInt16 nWhich) const;
     /*
         This is only valid for SfxPoolItem that override IsSortable and 
operator<.
         Returns a range of items defined by using operator<.
         @param rNeedle must be the same type or a supertype of the pool items 
for nWhich.
     */
-    std::vector<const SfxPoolItem*> FindItemSurrogate(sal_uInt16 nWhich, 
SfxPoolItem const & rNeedle) const;
+    void FindItemSurrogate(ItemSurrogates& rTarget, sal_uInt16 nWhich, 
SfxPoolItem const & rNeedle) const;
 
     sal_uInt16                      GetFirstWhich() const;
     sal_uInt16                      GetLastWhich() const;
@@ -230,24 +240,6 @@ public:
     static bool                     IsSlot(sal_uInt16 nId) {
                                         return nId && nId > SFX_WHICH_MAX; }
 
-    // This method will try to register the Item at this Pool.
-    void registerSfxPoolItem(const SfxPoolItem& rItem);
-
-    // this method will unregister an Item from this Pool
-    void unregisterSfxPoolItem(const SfxPoolItem& rItem);
-
-    // check if this Item is registered at this Pool, needed to detect
-    // if an Item is to be set at another Pool and needs to be cloned
-    bool isSfxPoolItemRegisteredAtThisPool(const SfxPoolItem& rItem) const;
-
-    // try to find an equal existing Item to given one in pool
-    const SfxPoolItem* tryToGetEqualItem(const SfxPoolItem& rItem, sal_uInt16 
nWhich) const;
-
-    void                            dumpAsXml(xmlTextWriterPtr pWriter) const;
-
-protected:
-    const SfxPoolItem&      DirectPutItemInPoolImpl( const SfxPoolItem&, 
sal_uInt16 nWhich = 0, bool bPassingOwnership = false );
-
 private:
     const SfxItemPool&              operator=(const SfxItemPool &) = delete;
 
diff --git a/include/svl/itemset.hxx b/include/svl/itemset.hxx
index f3470098d42f..ae97ec991445 100644
--- a/include/svl/itemset.hxx
+++ b/include/svl/itemset.hxx
@@ -40,7 +40,7 @@ SVL_DLLPUBLIC size_t getUsedSfxPoolItemHolderCount();
 
 // ItemSet/ItemPool helpers
 SfxPoolItem const* implCreateItemEntry(SfxItemPool& rPool, SfxPoolItem const* 
pSource, sal_uInt16 nWhich, bool bPassingOwnership);
-void implCleanupItemEntry(SfxItemPool& rPool, SfxPoolItem const* pSource);
+void implCleanupItemEntry(SfxPoolItem const* pSource);
 
 class SAL_WARN_UNUSED SVL_DLLPUBLIC SfxPoolItemHolder
 {
@@ -79,11 +79,12 @@ class SAL_WARN_UNUSED SVL_DLLPUBLIC SfxItemSet
 
     // allow ItemSetTooling to access
     friend SfxPoolItem const* implCreateItemEntry(SfxItemPool&, SfxPoolItem 
const*, sal_uInt16, bool);
-    friend void implCleanupItemEntry(SfxItemPool&, SfxPoolItem const*);
+    friend void implCleanupItemEntry(SfxPoolItem const*);
 
     SfxItemPool*      m_pPool;         ///< pool that stores the items
     const SfxItemSet* m_pParent;       ///< derivation
     sal_uInt16        m_nCount;        ///< number of items
+    sal_uInt16        m_nRegister;     ///< number of items with 
NeedsPoolRegistration
     sal_uInt16        m_nTotalCount;   ///< number of WhichIDs, also size of 
m_ppItems array
 
     // bitfield (better packaging if a bool needs to be added)
@@ -95,6 +96,10 @@ class SAL_WARN_UNUSED SVL_DLLPUBLIC SfxItemSet
     // Notification-Callback mechanism for SwAttrSet in SW, functionPtr for 
callback
     std::function<void(const SfxPoolItem*, const SfxPoolItem*)> m_aCallback;
 
+    // helpers to keep m_nRegister up-to-date
+    void checkRemovePoolRegistration(const SfxPoolItem* pItem);
+    void checkAddPoolRegistration(const SfxPoolItem* pItem);
+
 protected:
     // Notification-Callback mechanism for SwAttrSet in SW
     void setCallback(const std::function<void(const SfxPoolItem*, const 
SfxPoolItem*)> &func) { m_aCallback = func; }
diff --git a/include/svl/poolitem.hxx b/include/svl/poolitem.hxx
index ce65d63709cf..d2165a49a446 100644
--- a/include/svl/poolitem.hxx
+++ b/include/svl/poolitem.hxx
@@ -115,7 +115,7 @@ class SVL_DLLPUBLIC SfxPoolItem
 
     // allow ItemSetTooling to access
     friend SfxPoolItem const* implCreateItemEntry(SfxItemPool&, SfxPoolItem 
const*, sal_uInt16, bool);
-    friend void implCleanupItemEntry(SfxItemPool&, SfxPoolItem const*);
+    friend void implCleanupItemEntry(SfxPoolItem const*);
 
     mutable sal_uInt32 m_nRefCount;
     sal_uInt16  m_nWhich;
@@ -133,13 +133,12 @@ class SVL_DLLPUBLIC SfxPoolItem
     bool        m_bIsVoidItem : 1;          // bit 0
     bool        m_bStaticDefault : 1;       // bit 1
     bool        m_bPoolDefault : 1;         // bit 2
-    bool        m_bRegisteredAtPool : 1;    // bit 3
-    bool        m_bIsSetItem : 1;           // bit 5
+    bool        m_bIsSetItem : 1;           // bit 3
 
 protected:
 #ifdef DBG_UTIL
     // this flag will make debugging item stuff much simpler
-    bool        m_bDeleted : 1;             // bit 6
+    bool        m_bDeleted : 1;             // bit 4
 #endif
 
 private:
@@ -153,7 +152,6 @@ protected:
     void setIsVoidItem() { m_bIsVoidItem = true; }
     void setStaticDefault() { m_bStaticDefault = true; }
     void setPoolDefault() { m_bPoolDefault = true; }
-    void setRegisteredAtPool(bool bNew) { m_bRegisteredAtPool = bNew; }
     void setIsSetItem() { m_bIsSetItem = true; }
 
 public:
@@ -171,7 +169,6 @@ public:
     bool isVoidItem() const { return m_bIsVoidItem; }
     bool isStaticDefault() const { return m_bStaticDefault; }
     bool isPoolDefault() const { return m_bPoolDefault; }
-    bool isRegisteredAtPool() const { return m_bRegisteredAtPool; }
     bool isSetItem() const { return m_bIsSetItem; }
 
     // version that allows nullptrs
diff --git a/sc/inc/fillinfo.hxx b/sc/inc/fillinfo.hxx
index 81086ed358ba..7d75defe957a 100644
--- a/sc/inc/fillinfo.hxx
+++ b/sc/inc/fillinfo.hxx
@@ -119,7 +119,7 @@ struct ScCellInfo
         , pConditionSet(nullptr)
         , pDataBar(nullptr)
         , pIconSet(nullptr)
-        , pBackground(nullptr)   // TODO: omit?
+        , maBackground()
         , pLinesAttr(nullptr)
         , mpTLBRLine(nullptr)
         , mpBLTRLine(nullptr)
@@ -156,7 +156,7 @@ struct ScCellInfo
     const ScDataBarInfo*        pDataBar;
     const ScIconSetInfo*        pIconSet;
 
-    const SvxBrushItem*         pBackground;
+    SfxPoolItemHolder           maBackground;
 
     const SvxBoxItem*           pLinesAttr;         /// original item from 
document.
     const SvxLineItem*          mpTLBRLine;         /// original item from 
document.
diff --git a/sc/source/core/data/documen9.cxx b/sc/source/core/data/documen9.cxx
index a9f04943c0d1..c4c569557ffb 100644
--- a/sc/source/core/data/documen9.cxx
+++ b/sc/source/core/data/documen9.cxx
@@ -546,7 +546,9 @@ void ScDocument::UpdateFontCharSet()
         return;
 
     ScDocumentPool* pPool = mxPoolHelper->GetDocPool();
-    for (const SfxPoolItem* pItem : pPool->GetItemSurrogates(ATTR_FONT))
+    ItemSurrogates aSurrogates;
+    pPool->GetItemSurrogates(aSurrogates, ATTR_FONT);
+    for (const SfxPoolItem* pItem : aSurrogates)
     {
         auto pFontItem = const_cast<SvxFontItem*>(dynamic_cast<const 
SvxFontItem*>(pItem));
         if ( pFontItem && ( pFontItem->GetCharSet() == eSrcSet ||
@@ -557,7 +559,8 @@ void ScDocument::UpdateFontCharSet()
     if ( mpDrawLayer )
     {
         SfxItemPool& rDrawPool = mpDrawLayer->GetItemPool();
-        for (const SfxPoolItem* pItem : 
rDrawPool.GetItemSurrogates(EE_CHAR_FONTINFO))
+        rDrawPool.GetItemSurrogates(aSurrogates, EE_CHAR_FONTINFO);
+        for (const SfxPoolItem* pItem : aSurrogates)
         {
             SvxFontItem* pFontItem = 
const_cast<SvxFontItem*>(dynamic_cast<const SvxFontItem*>(pItem));
             if ( pFontItem && ( pFontItem->GetCharSet() == eSrcSet ||
diff --git a/sc/source/core/data/document.cxx b/sc/source/core/data/document.cxx
index 04e20ce4b8ac..c44672048b39 100644
--- a/sc/source/core/data/document.cxx
+++ b/sc/source/core/data/document.cxx
@@ -5175,7 +5175,9 @@ static HasAttrFlags OptimizeHasAttrib( HasAttrFlags 
nMask, const ScDocumentPool*
         //  (as in fillinfo)
 
         bool bAnyItem = false;
-        for (const SfxPoolItem* pItem : 
pPool->GetItemSurrogates(ATTR_ROTATE_VALUE))
+        ItemSurrogates aSurrogates;
+        pPool->GetItemSurrogates(aSurrogates, ATTR_ROTATE_VALUE);
+        for (const SfxPoolItem* pItem : aSurrogates)
         {
             // 90 or 270 degrees is former SvxOrientationItem - only look for 
other values
             // (see ScPatternAttr::GetCellOrientation)
diff --git a/sc/source/core/data/document10.cxx 
b/sc/source/core/data/document10.cxx
index a1aeef5d7e7b..61c75b5e2cc5 100644
--- a/sc/source/core/data/document10.cxx
+++ b/sc/source/core/data/document10.cxx
@@ -191,7 +191,9 @@ std::set<Color> ScDocument::GetDocColors()
     const sal_uInt16 pAttribs[] = {ATTR_BACKGROUND, ATTR_FONT_COLOR};
     for (sal_uInt16 nAttrib : pAttribs)
     {
-        for (const SfxPoolItem* pItem : pPool->GetItemSurrogates(nAttrib))
+        ItemSurrogates aSurrogates;
+        pPool->GetItemSurrogates(aSurrogates, nAttrib);
+        for (const SfxPoolItem* pItem : aSurrogates)
         {
             const SvxColorItem *pColorItem = static_cast<const 
SvxColorItem*>(pItem);
             Color aColor( pColorItem->GetValue() );
diff --git a/sc/source/core/data/fillinfo.cxx b/sc/source/core/data/fillinfo.cxx
index 544c58a65e46..8e84d045ff72 100644
--- a/sc/source/core/data/fillinfo.cxx
+++ b/sc/source/core/data/fillinfo.cxx
@@ -186,7 +186,9 @@ public:
 
 bool isRotateItemUsed(const ScDocumentPool *pPool)
 {
-    return pPool->GetItemSurrogates(ATTR_ROTATE_VALUE).size() > 0;
+    ItemSurrogates aSurrogates;
+    pPool->GetItemSurrogates(aSurrogates, ATTR_ROTATE_VALUE);
+    return aSurrogates.size() > 0;
 }
 
 void initRowInfo(const ScDocument* pDoc, RowInfo* pRowInfo, const SCSIZE 
nMaxRow,
@@ -543,7 +545,7 @@ void ScDocument::FillInfo(
 
                                 ScCellInfo* pInfo = 
&pThisRowInfo->cellInfo(nCol);
                                 ScBasicCellInfo* pBasicInfo = 
&pThisRowInfo->basicCellInfo(nCol);
-                                pInfo->pBackground  = pBackground;
+                                pInfo->maBackground = 
SfxPoolItemHolder(*pPool, pBackground);
                                 pInfo->pPatternAttr = pPattern;
                                 pInfo->bMerged      = bMerged;
                                 pInfo->bHOverlapped = bHOverlapped;
@@ -563,7 +565,7 @@ void ScDocument::FillInfo(
 
                                 if (bScenario)
                                 {
-                                    pInfo->pBackground = 
ScGlobal::GetButtonBrushItem();
+                                    pInfo->maBackground = 
SfxPoolItemHolder(*pPool, ScGlobal::GetButtonBrushItem());
                                     pThisRowInfo->bEmptyBack = false;
                                 }
 
@@ -664,7 +666,7 @@ void ScDocument::FillInfo(
                             // Background
                     if ( const SvxBrushItem* pItem = pCondSet->GetItemIfSet( 
ATTR_BACKGROUND ) )
                     {
-                        pInfo->pBackground = pItem;
+                        pInfo->maBackground = SfxPoolItemHolder(*pPool, pItem);
                         pRowInfo[nArrRow].bEmptyBack = false;
                     }
 
@@ -687,7 +689,8 @@ void ScDocument::FillInfo(
                 if( bAnyCondition && pInfo->mxColorScale)
                 {
                     pRowInfo[nArrRow].bEmptyBack = false;
-                    pInfo->pBackground = 
&pPool->DirectPutItemInPool(SvxBrushItem(*pInfo->mxColorScale, 
ATTR_BACKGROUND));
+                    const SvxBrushItem aBrushItem(*pInfo->mxColorScale, 
ATTR_BACKGROUND);
+                    pInfo->maBackground = SfxPoolItemHolder(*pPool, 
&aBrushItem);
                 }
             }
         }
@@ -725,7 +728,7 @@ void ScDocument::FillInfo(
                     if ( !pStartCond ||
                         !(pBrushItem = 
pStartCond->GetItemIfSet(ATTR_BACKGROUND)) )
                         pBrushItem = &pStartPattern->GetItem(ATTR_BACKGROUND);
-                    pInfo->pBackground = pBrushItem;
+                    pInfo->maBackground = SfxPoolItemHolder(*pPool, 
pBrushItem);
                     pRowInfo[nArrRow].bEmptyBack = false;
 
                     // Shadow
diff --git a/sc/source/core/data/poolcach.cxx b/sc/source/core/data/poolcach.cxx
index 3ab41d416c49..6db714bb7c12 100644
--- a/sc/source/core/data/poolcach.cxx
+++ b/sc/source/core/data/poolcach.cxx
@@ -26,7 +26,7 @@
 ScItemPoolCache::ScItemPoolCache(CellAttributeHelper& _rHelper, const 
SfxPoolItem& rPutItem)
 : rHelper(_rHelper)
 , pSetToPut(nullptr)
-, aItemToPut(_rHelper.GetPool(), &rPutItem)
+, aItemToPut(rHelper.GetPool(), &rPutItem)
 {
 }
 
diff --git a/sc/source/filter/xml/xmlexprt.cxx 
b/sc/source/filter/xml/xmlexprt.cxx
index 9da5da65b7e6..4ec6ab6cdbb6 100644
--- a/sc/source/filter/xml/xmlexprt.cxx
+++ b/sc/source/filter/xml/xmlexprt.cxx
@@ -5329,7 +5329,9 @@ XMLNumberFormatAttributesExportHelper* 
ScXMLExport::GetNumberFormatAttributesExp
 
 void ScXMLExport::CollectUserDefinedNamespaces(const SfxItemPool* pPool, 
sal_uInt16 nAttrib)
 {
-    for (const SfxPoolItem* pItem : pPool->GetItemSurrogates(nAttrib))
+    ItemSurrogates aSurrogates;
+    pPool->GetItemSurrogates(aSurrogates, nAttrib);
+    for (const SfxPoolItem* pItem : aSurrogates)
     {
         const SvXMLAttrContainerItem *pUnknown(static_cast<const 
SvXMLAttrContainerItem *>(pItem));
         if( pUnknown->GetAttrCount() > 0 )
diff --git a/sc/source/filter/xml/xmlfonte.cxx 
b/sc/source/filter/xml/xmlfonte.cxx
index ab8e42f4ce60..f6951eddb0b8 100644
--- a/sc/source/filter/xml/xmlfonte.cxx
+++ b/sc/source/filter/xml/xmlfonte.cxx
@@ -59,7 +59,9 @@ void ScXMLFontAutoStylePool_Impl::AddFontItems(const 
sal_uInt16* pWhichIds, sal_
                     pFont->GetFamily(), pFont->GetPitch(),
                     pFont->GetCharSet() );
         }
-        for (const SfxPoolItem* pItem : pItemPool->GetItemSurrogates( nWhichId 
))
+        ItemSurrogates aSurrogates;
+        pItemPool->GetItemSurrogates( aSurrogates, nWhichId );
+        for (const SfxPoolItem* pItem : aSurrogates)
         {
             const SvxFontItem *pFont(static_cast<const SvxFontItem *>(pItem));
             Add( pFont->GetFamilyName(), pFont->GetStyleName(),
@@ -111,7 +113,9 @@ 
ScXMLFontAutoStylePool_Impl::ScXMLFontAutoStylePool_Impl(ScXMLExport& rExportP,
 
         for (sal_uInt16 nPageWhichId : aPageWhichIds)
         {
-            for (const SfxPoolItem* pItem : rPagePool.GetItemSurrogates( 
nPageWhichId ))
+            ItemSurrogates aSurrogates;
+            rPagePool.GetItemSurrogates( aSurrogates, nPageWhichId );
+            for (const SfxPoolItem* pItem : aSurrogates)
             {
                 const ScPageHFItem* pPageItem = static_cast<const 
ScPageHFItem*>(pItem);
                 const EditTextObject* pLeftArea(pPageItem->GetLeftArea());
diff --git a/sc/source/ui/view/cellsh1.cxx b/sc/source/ui/view/cellsh1.cxx
index 4907b6b50c05..03d93088a54d 100644
--- a/sc/source/ui/view/cellsh1.cxx
+++ b/sc/source/ui/view/cellsh1.cxx
@@ -2161,10 +2161,11 @@ void ScCellShell::ExecuteEdit( SfxRequest& rReq )
                 bool        bManaged    = false;
 
                 // Get the pool item stored by Conditional Format Manager 
Dialog.
-                auto itemsRange = 
pTabViewShell->GetPool().GetItemSurrogates(SCITEM_CONDFORMATDLGDATA);
-                if (itemsRange.begin() != itemsRange.end())
+                ItemSurrogates aSurrogates;
+                pTabViewShell->GetPool().GetItemSurrogates(aSurrogates, 
SCITEM_CONDFORMATDLGDATA);
+                if (aSurrogates.begin() != aSurrogates.end())
                 {
-                    const ScCondFormatDlgItem* pDlgItem = static_cast<const 
ScCondFormatDlgItem*>(*itemsRange.begin());
+                    const ScCondFormatDlgItem* pDlgItem = static_cast<const 
ScCondFormatDlgItem*>(*aSurrogates.begin());
                     nIndex = pDlgItem->GetIndex();
                     bManaged = true;
                 }
@@ -2873,10 +2874,11 @@ void ScCellShell::ExecuteEdit( SfxRequest& rReq )
                 ScConditionalFormatList* pList = nullptr;
 
                 const ScCondFormatDlgItem* pDlgItem = nullptr;
-                auto itemsRange = 
pTabViewShell->GetPool().GetItemSurrogates(SCITEM_CONDFORMATDLGDATA);
-                if (itemsRange.begin() != itemsRange.end())
+                ItemSurrogates aSurrogates;
+                pTabViewShell->GetPool().GetItemSurrogates(aSurrogates, 
SCITEM_CONDFORMATDLGDATA);
+                if (aSurrogates.begin() != aSurrogates.end())
                 {
-                    pDlgItem= static_cast<const 
ScCondFormatDlgItem*>(*itemsRange.begin());
+                    pDlgItem= static_cast<const 
ScCondFormatDlgItem*>(*aSurrogates.begin());
                     pList = 
const_cast<ScCondFormatDlgItem*>(pDlgItem)->GetConditionalFormatList();
                 }
 
diff --git a/sc/source/ui/view/output.cxx b/sc/source/ui/view/output.cxx
index edad3a96f0b6..58b6db5107d3 100644
--- a/sc/source/ui/view/output.cxx
+++ b/sc/source/ui/view/output.cxx
@@ -823,7 +823,7 @@ static bool lcl_EqualBack( const RowInfo& rFirst, const 
RowInfo& rOther,
     else
     {
         for ( nX=nX1; nX<=nX2; nX++ )
-            if ( !SfxPoolItem::areSame(rFirst.cellInfo(nX).pBackground, 
rOther.cellInfo(nX).pBackground ) )
+            if ( 
!SfxPoolItem::areSame(rFirst.cellInfo(nX).maBackground.getItem(), 
rOther.cellInfo(nX).maBackground.getItem() ) )
                 return false;
     }
 
@@ -1204,7 +1204,7 @@ void ScOutputData::DrawBackground(vcl::RenderContext& 
rRenderContext)
                             pBackground = nullptr;
                     }
                     else
-                        pBackground = pInfo->pBackground;
+                        pBackground = static_cast<const 
SvxBrushItem*>(pInfo->maBackground.getItem());
 
                     if ( bPagebreakMode && !pInfo->bPrinted )
                         pBackground = pProtectedBackground.get();
@@ -1723,7 +1723,7 @@ void ScOutputData::DrawRotatedFrame(vcl::RenderContext& 
rRenderContext)
                         aPoints[2] = Point(nBotRight, nBottom);
                         aPoints[3] = Point(nBotLeft, nBottom);
 
-                        const SvxBrushItem* pBackground = pInfo->pBackground;
+                        const SvxBrushItem* pBackground(static_cast<const 
SvxBrushItem*>(pInfo->maBackground.getItem()));
                         if (!pBackground)
                             pBackground = &pPattern->GetItem(ATTR_BACKGROUND, 
pCondSet);
                         if (bCellContrast)
@@ -2494,7 +2494,7 @@ void ScOutputData::DrawNoteMarks(vcl::RenderContext& 
rRenderContext)
                 {
 
                     const bool bIsDarkBackground = 
SC_MOD()->GetColorConfig().GetColorValue(svtools::DOCCOLOR).nColor.IsDark();
-                    const Color aColor = pInfo->pBackground->GetColor();
+                    const Color aColor(static_cast<const 
SvxBrushItem*>(pInfo->maBackground.getItem())->GetColor());
                     if ( aColor == COL_AUTO ? bIsDarkBackground : 
aColor.IsDark() )
                         rRenderContext.SetLineColor(COL_WHITE);
                     else
@@ -2794,7 +2794,9 @@ void ScOutputData::DrawClipMarks()
                     tools::Long nMarkPixel = static_cast<tools::Long>( 
SC_CLIPMARK_SIZE * mnPPTX );
                     Size aMarkSize( nMarkPixel, (nMarkPixel-1)*2 );
 
-                    const Color aColor = pInfo->pBackground ? 
pInfo->pBackground->GetColor() : COL_AUTO;
+                    const Color aColor = pInfo->maBackground ?
+                        static_cast<const 
SvxBrushItem*>(pInfo->maBackground.getItem())->GetColor() :
+                        COL_AUTO;
                     if ( aColor == COL_AUTO ? bIsDarkBackground : 
aColor.IsDark() )
                         mpDev->SetDrawMode( nOldDrawMode | 
DrawModeFlags::WhiteLine );
                     else
diff --git a/sc/source/ui/view/tabvwshc.cxx b/sc/source/ui/view/tabvwshc.cxx
index eeb554454eab..1012f1ceb249 100644
--- a/sc/source/ui/view/tabvwshc.cxx
+++ b/sc/source/ui/view/tabvwshc.cxx
@@ -427,10 +427,11 @@ std::shared_ptr<SfxModelessDialogController> 
ScTabViewShell::CreateRefDialogCont
         {
             const ScCondFormatDlgItem* pDlgItem = nullptr;
             // Get the pool item stored by Conditional Format Manager Dialog.
-            auto itemsRange = 
GetPool().GetItemSurrogates(SCITEM_CONDFORMATDLGDATA);
-            if (itemsRange.begin() != itemsRange.end())
+            ItemSurrogates aSurrogates;
+            GetPool().GetItemSurrogates(aSurrogates, SCITEM_CONDFORMATDLGDATA);
+            if (aSurrogates.begin() != aSurrogates.end())
             {
-                const SfxPoolItem* pItem = *itemsRange.begin();
+                const SfxPoolItem* pItem = *aSurrogates.begin();
                 pDlgItem = static_cast<const ScCondFormatDlgItem*>(pItem);
             }
 
diff --git a/sc/source/ui/view/viewfunc.cxx b/sc/source/ui/view/viewfunc.cxx
index 97d7338ece91..a6d28ecbc37b 100644
--- a/sc/source/ui/view/viewfunc.cxx
+++ b/sc/source/ui/view/viewfunc.cxx
@@ -1049,10 +1049,13 @@ void ScViewFunc::ApplyAttributes( const SfxItemSet& 
rDialogSet,
     const SvxBoxInfoItem& rOldInner = rOldSet.Get(ATTR_BORDER_INNER);
     const SvxBoxInfoItem& rNewInner = rDialogSet.Get(ATTR_BORDER_INNER);
     SfxItemSet&           rNewSet   = aNewAttrs.GetItemSet();
-    SfxItemPool*          pNewPool  = rNewSet.GetPool();
 
-    pNewPool->DirectPutItemInPool(rNewOuter);        // don't delete yet
-    pNewPool->DirectPutItemInPool(rNewInner);
+    // protect referenced Items from disappearing (was: don't delete yet)
+    const SfxPoolItemHolder aHoldOuter(*rDialogSet.GetPool() , &rNewOuter);
+    const SfxPoolItemHolder aHoldInner(*rDialogSet.GetPool() , &rNewInner);
+    (void)aHoldOuter;
+    (void)aHoldInner;
+
     rNewSet.ClearItem( ATTR_BORDER );
     rNewSet.ClearItem( ATTR_BORDER_INNER );
 
@@ -1096,9 +1099,6 @@ void ScViewFunc::ApplyAttributes( const SfxItemSet& 
rDialogSet,
                            bDefNewInner ? &rOldInner : &rNewInner );
     }
 
-    pNewPool->DirectRemoveItemFromPool(rNewOuter);         // release
-    pNewPool->DirectRemoveItemFromPool(rNewInner);
-
     //  adjust height only if needed
     if (bAdjustBlockHeight)
         AdjustBlockHeight();
diff --git a/sd/source/core/drawdoc2.cxx b/sd/source/core/drawdoc2.cxx
index de82a8b95306..328952c577c5 100644
--- a/sd/source/core/drawdoc2.cxx
+++ b/sd/source/core/drawdoc2.cxx
@@ -268,7 +268,9 @@ void 
SdDrawDocument::UpdatePageRelativeURLs(std::u16string_view aOldName, std::u
         return;
 
     SfxItemPool& rPool(GetPool());
-    for (const SfxPoolItem* pItem : rPool.GetItemSurrogates(EE_FEATURE_FIELD))
+    ItemSurrogates aSurrogates;
+    rPool.GetItemSurrogates(aSurrogates, EE_FEATURE_FIELD);
+    for (const SfxPoolItem* pItem : aSurrogates)
     {
         const SvxFieldItem* pFldItem = dynamic_cast< const SvxFieldItem * > 
(pItem);
 
@@ -310,7 +312,9 @@ void SdDrawDocument::UpdatePageRelativeURLs(SdPage const * 
pPage, sal_uInt16 nPo
     bool bNotes = (pPage->GetPageKind() == PageKind::Notes);
 
     SfxItemPool& rPool(GetPool());
-    for (const SfxPoolItem* pItem : rPool.GetItemSurrogates(EE_FEATURE_FIELD))
+    ItemSurrogates aSurrogates;
+    rPool.GetItemSurrogates(aSurrogates, EE_FEATURE_FIELD);
+    for (const SfxPoolItem* pItem : aSurrogates)
     {
         const SvxFieldItem* pFldItem;
 
diff --git a/sd/source/ui/unoidl/unomodel.cxx b/sd/source/ui/unoidl/unomodel.cxx
index 075ee6e383a7..89efc76df232 100644
--- a/sd/source/ui/unoidl/unomodel.cxx
+++ b/sd/source/ui/unoidl/unomodel.cxx
@@ -1391,13 +1391,14 @@ uno::Any SAL_CALL SdXImpressDocument::getPropertyValue( 
const OUString& Property
 
                 for(sal_uInt16 nWhichId : aWhichIds)
                 {
-                    const registeredSfxPoolItems& 
rSurrogates(rPool.GetItemSurrogates(nWhichId));
-                    const sal_uInt32 nItems(rSurrogates.size());
+                    ItemSurrogates aSurrogates;
+                    rPool.GetItemSurrogates(aSurrogates, nWhichId);
+                    const sal_uInt32 nItems(aSurrogates.size());
 
                     aSeq.realloc( aSeq.getLength() + nItems*5 + 5 );
                     auto pSeq = aSeq.getArray();
 
-                    for (const SfxPoolItem* pItem : rSurrogates)
+                    for (const SfxPoolItem* pItem : aSurrogates)
                     {
                         const SvxFontItem *pFont = static_cast<const 
SvxFontItem *>(pItem);
 
diff --git a/solenv/clang-format/excludelist b/solenv/clang-format/excludelist
index a9690468cb89..5581b9486be0 100644
--- a/solenv/clang-format/excludelist
+++ b/solenv/clang-format/excludelist
@@ -10965,7 +10965,6 @@ svgio/source/svgreader/svgtspannode.cxx
 svgio/source/svgreader/svgusenode.cxx
 svgio/source/svguno/xsvgparser.cxx
 svl/qa/unit/items/test_IndexedStyleSheets.cxx
-svl/qa/unit/items/test_itempool.cxx
 svl/qa/unit/svl.cxx
 svl/qa/unit/test_INetContentType.cxx
 svl/qa/unit/test_URIHelper.cxx
@@ -10985,7 +10984,6 @@ svl/source/fsstor/oinputstreamcontainer.hxx
 svl/source/fsstor/ostreamcontainer.cxx
 svl/source/fsstor/ostreamcontainer.hxx
 svl/source/inc/fsfactory.hxx
-svl/source/inc/poolio.hxx
 svl/source/items/IndexedStyleSheets.cxx
 svl/source/items/aeitem.cxx
 svl/source/items/cenumitm.cxx
diff --git a/svl/CppunitTest_svl_itempool.mk b/svl/CppunitTest_svl_itempool.mk
deleted file mode 100644
index 892107e906ca..000000000000
--- a/svl/CppunitTest_svl_itempool.mk
+++ /dev/null
@@ -1,34 +0,0 @@
-# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
-#
-# This file is part of the LibreOffice project.
-#
-# This Source Code Form is subject to the terms of the Mozilla Public
-# License, v. 2.0. If a copy of the MPL was not distributed with this
-# file, You can obtain one at http://mozilla.org/MPL/2.0/.
-#
-
-$(eval $(call gb_CppunitTest_CppunitTest,svl_itempool))
-
-$(eval $(call gb_CppunitTest_use_external,svl_itempool,boost_headers))
-
-$(eval $(call gb_CppunitTest_use_sdk_api,svl_itempool))
-
-$(eval $(call gb_CppunitTest_add_exception_objects,svl_itempool, \
-       svl/qa/unit/items/test_itempool \
-))
-
-$(eval $(call gb_CppunitTest_use_libraries,svl_itempool, \
-       svl \
-       comphelper \
-       sal \
-       salhelper \
-       cppu \
-       cppuhelper \
-))
-
-$(eval $(call gb_CppunitTest_set_include,svl_itempool,\
-       -I$(SRCDIR)/svl/source/inc \
-       $$(INCLUDE) \
-))
-
-# vim: set noet sw=4 ts=4:
diff --git a/svl/Module_svl.mk b/svl/Module_svl.mk
index 45bf74915c14..71fc8d08120f 100644
--- a/svl/Module_svl.mk
+++ b/svl/Module_svl.mk
@@ -32,7 +32,6 @@ $(eval $(call gb_Module_add_l10n_targets,svl,\
 $(eval $(call gb_Module_add_check_targets,svl,\
        CppunitTest_svl_adrparse \
        CppunitTest_svl_inetcontenttype \
-       CppunitTest_svl_itempool \
        CppunitTest_svl_items \
        CppunitTest_svl_lngmisc \
        CppunitTest_svl_lockfiles \
diff --git a/svl/qa/unit/items/test_itempool.cxx 
b/svl/qa/unit/items/test_itempool.cxx
deleted file mode 100644
index 2cb751d4fd77..000000000000
--- a/svl/qa/unit/items/test_itempool.cxx
+++ /dev/null
@@ -1,108 +0,0 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/*
- * This file is part of the LibreOffice project.
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/.
- */
-
-#include <svl/itempool.hxx>
-#include <svl/voiditem.hxx>
-#include <poolio.hxx>
-
-#include <cppunit/TestAssert.h>
-#include <cppunit/TestFixture.h>
-#include <cppunit/extensions/HelperMacros.h>
-#include <cppunit/plugin/TestPlugIn.h>
-
-class PoolItemTest : public CppUnit::TestFixture
-{
-  public:
-             PoolItemTest() {}
-
-    void testPool();
-
-    // Adds code needed to register the test suite
-    CPPUNIT_TEST_SUITE(PoolItemTest);
-
-    CPPUNIT_TEST(testPool);
-
-    // End of test suite definition
-    CPPUNIT_TEST_SUITE_END();
-};
-
-void PoolItemTest::testPool()
-{
-    SfxItemInfo const aItems[] =
-    {
-        // _nSID, _bNeedsPoolRegistration, _bShareable
-        { 4, true,  true },
-        { 3, true,  false /* test NeedsPoolRegistration */ },
-        { 2, false, false },
-        { 1, true,  false /* test NeedsPoolRegistration */}
-    };
-
-    rtl::Reference<SfxItemPool> pPool = new SfxItemPool("testpool", 1, 4, 
aItems);
-
-    // Poolable
-    SfxVoidItem aItemOne( 1 );
-    SfxVoidItem aNotherOne( 1 );
-
-    {
-        CPPUNIT_ASSERT(nullptr == pPool->ppRegisteredSfxPoolItems);
-        const SfxPoolItem &rVal = pPool->DirectPutItemInPool(aItemOne);
-        CPPUNIT_ASSERT(bool(rVal == aItemOne));
-        CPPUNIT_ASSERT(nullptr != pPool->ppRegisteredSfxPoolItems);
-        CPPUNIT_ASSERT(nullptr != pPool->ppRegisteredSfxPoolItems[0]);
-        CPPUNIT_ASSERT(!pPool->ppRegisteredSfxPoolItems[0]->empty());
-        const SfxPoolItem &rVal2 = pPool->DirectPutItemInPool(aNotherOne);
-        CPPUNIT_ASSERT(bool(rVal2 == rVal));
-
-        // ITEM: With leaving the paradigm that internally an already
-        //   existing Item with true = operator==() (which is very
-        //   expensive) the ptr's are no longer required to be equal,
-        //   but the content-compare *is*
-        CPPUNIT_ASSERT(SfxPoolItem::areSame(rVal, rVal2));
-
-        // Clones on Put ...
-        // ptr compare OK, we want to check just the ptrs here
-        CPPUNIT_ASSERT(!areSfxPoolItemPtrsEqual(&rVal2, &aItemOne));
-        CPPUNIT_ASSERT(!areSfxPoolItemPtrsEqual(&rVal2, &aNotherOne));
-        CPPUNIT_ASSERT(!areSfxPoolItemPtrsEqual(&rVal, &aItemOne));
-        CPPUNIT_ASSERT(!areSfxPoolItemPtrsEqual(&rVal, &aNotherOne));
-    }
-
-    // non-poolable
-    SfxVoidItem aItemTwo( 2 );
-    SfxVoidItem aNotherTwo( 2 );
-    {
-        CPPUNIT_ASSERT(nullptr == pPool->ppRegisteredSfxPoolItems[1]);
-        const SfxPoolItem &rVal = pPool->DirectPutItemInPool(aItemTwo);
-        CPPUNIT_ASSERT(bool(rVal == aItemTwo));
-        CPPUNIT_ASSERT(nullptr != pPool->ppRegisteredSfxPoolItems[1]);
-        CPPUNIT_ASSERT(!pPool->ppRegisteredSfxPoolItems[1]->empty());
-        const SfxPoolItem &rVal2 = pPool->DirectPutItemInPool(aNotherTwo);
-        CPPUNIT_ASSERT(bool(rVal2 == rVal));
-        // ptr compare OK, we want to check just the ptrs here
-        CPPUNIT_ASSERT(!areSfxPoolItemPtrsEqual(&rVal2, &rVal));
-    }
-
-    // Test removal.
-    SfxVoidItem aRemoveFour(4);
-    SfxVoidItem aNotherFour(4);
-
-    const SfxPoolItem &rKeyFour = pPool->DirectPutItemInPool(aRemoveFour);
-    pPool->DirectPutItemInPool(aNotherFour);
-    CPPUNIT_ASSERT(pPool->ppRegisteredSfxPoolItems[3]->size() > 0);
-    CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(2), 
pPool->ppRegisteredSfxPoolItems[3]->size());
-    pPool->DirectRemoveItemFromPool(rKeyFour);
-    CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), 
pPool->ppRegisteredSfxPoolItems[3]->size());
-    pPool->DirectPutItemInPool(aNotherFour);
-    CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(2), 
pPool->ppRegisteredSfxPoolItems[3]->size());
-}
-
-
-CPPUNIT_TEST_SUITE_REGISTRATION(PoolItemTest);
-
-CPPUNIT_PLUGIN_IMPLEMENT();
diff --git a/svl/source/inc/poolio.hxx b/svl/source/inc/poolio.hxx
deleted file mode 100644
index 118deaf50e2e..000000000000
--- a/svl/source/inc/poolio.hxx
+++ /dev/null
@@ -1,73 +0,0 @@
-/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
-/*
- * This file is part of the LibreOffice project.
- *
- * This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/.
- *
- * This file incorporates work covered by the following license notice:
- *
- *   Licensed to the Apache Software Foundation (ASF) under one or more
- *   contributor license agreements. See the NOTICE file distributed
- *   with this work for additional information regarding copyright
- *   ownership. The ASF licenses this file to you under the Apache
- *   License, Version 2.0 (the "License"); you may not use this file
- *   except in compliance with the License. You may obtain a copy of
- *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
- */
-
-#ifndef INCLUDED_SVL_SOURCE_INC_POOLIO_HXX
-#define INCLUDED_SVL_SOURCE_INC_POOLIO_HXX
-
-#include <rtl/ref.hxx>
-#include <svl/itempool.hxx>
-#include <svl/SfxBroadcaster.hxx>
-#include <tools/debug.hxx>
-#include <memory>
-#include <o3tl/sorted_vector.hxx>
-#include <utility>
-
-class SfxPoolItem;
-class SfxItemPoolUser;
-
-struct SfxItemPool_Impl
-{
-    SfxBroadcaster                  aBC;
-    OUString                        aName;
-    std::vector<SfxPoolItem*>       maPoolDefaults;
-    std::vector<SfxPoolItem*>*      mpStaticDefaults;
-    SfxItemPool*                    mpMaster;
-    rtl::Reference<SfxItemPool>     mpSecondary;
-    WhichRangesContainer            mpPoolRanges;
-    sal_uInt16                      mnStart;
-    sal_uInt16                      mnEnd;
-    MapUnit                         eDefMetric;
-
-    SfxItemPool_Impl( SfxItemPool* pMaster, OUString _aName, sal_uInt16 
nStart, sal_uInt16 nEnd )
-        : aName(std::move(_aName))
-        , maPoolDefaults(nEnd - nStart + 1)
-        , mpStaticDefaults(nullptr)
-        , mpMaster(pMaster)
-        , mnStart(nStart)
-        , mnEnd(nEnd)
-        , eDefMetric(MapUnit::MapCM)
-    {
-        DBG_ASSERT(mnStart, "Start-Which-Id must be greater 0" );
-    }
-
-    ~SfxItemPool_Impl()
-    {
-        DeleteItems();
-    }
-
-    void DeleteItems()
-    {
-        maPoolDefaults.clear();
-        mpPoolRanges.reset();
-    }
-};
-
-#endif // INCLUDED_SVL_SOURCE_INC_POOLIO_HXX
-
-/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/svl/source/items/itempool.cxx b/svl/source/items/itempool.cxx
index e697a5e9a1f2..0fd59788a711 100644
--- a/svl/source/items/itempool.cxx
+++ b/svl/source/items/itempool.cxx
@@ -28,8 +28,7 @@
 #include <svl/SfxBroadcaster.hxx>
 #include <svl/hint.hxx>
 #include <svl/itemset.hxx>
-
-#include <poolio.hxx>
+#include <tools/debug.hxx>
 
 #include <cassert>
 #include <vector>
@@ -236,7 +235,7 @@ lcl_CheckSlots2(std::map<sal_uInt16, sal_uInt16> & rSlotMap,
 #define CHECK_SLOTS() \
 do { \
     std::map<sal_uInt16, sal_uInt16> slotmap; \
-    for (SfxItemPool * p = pImpl->mpMaster; p; p = 
p->pImpl->mpSecondary.get()) \
+    for (SfxItemPool * p = mpMaster; p; p = p->mpSecondary.get()) \
     { \
         lcl_CheckSlots2(slotmap, *p, p->pItemInfos); \
     } \
@@ -246,43 +245,107 @@ do { \
 #define CHECK_SLOTS() do {} while (false)
 #endif
 
+void SfxItemPool::registerItemSet(SfxItemSet& rSet)
+{
+    registeredSfxItemSets& rTarget(GetMasterPool()->maRegisteredSfxItemSets);
+#ifdef DBG_UTIL
+    const size_t nBefore(rTarget.size());
+#endif
+    rTarget.insert(&rSet);
+#ifdef DBG_UTIL
+    const size_t nAfter(rTarget.size());
+    if (nBefore + 1 != nAfter)
+    {
+        SAL_WARN("svl.items", "SfxItemPool::registerItemSet: ItemSet was 
already registered (!)");
+    }
+#endif
+}
+
+void SfxItemPool::unregisterItemSet(SfxItemSet& rSet)
+{
+    registeredSfxItemSets& rTarget(GetMasterPool()->maRegisteredSfxItemSets);
+#ifdef DBG_UTIL
+    const size_t nBefore(rTarget.size());
+#endif
+    rTarget.erase(&rSet);
+#ifdef DBG_UTIL
+    const size_t nAfter(rTarget.size());
+    if (nBefore != nAfter + 1)
+    {
+        SAL_WARN("svl.items", "SfxItemPool::unregisterItemSet: ItemSet was not 
registered (!)");
+    }
+#endif
+}
+
+void SfxItemPool::registerPoolItemHolder(SfxPoolItemHolder& rHolder)
+{
+    registeredSfxPoolItemHolders& 
rTarget(GetMasterPool()->maRegisteredSfxPoolItemHolders);
+#ifdef DBG_UTIL
+    const size_t nBefore(rTarget.size());
+#endif
+    rTarget.insert(&rHolder);
+#ifdef DBG_UTIL
+    const size_t nAfter(rTarget.size());
+    if (nBefore + 1 != nAfter)
+    {
+        SAL_WARN("svl.items", "SfxItemPool::registerPoolItemHolder: 
SfxPoolItemHolder was already registered (!)");
+    }
+#endif
+}
+
+void SfxItemPool::unregisterPoolItemHolder(SfxPoolItemHolder& rHolder)
+{
+    registeredSfxPoolItemHolders& 
rTarget(GetMasterPool()->maRegisteredSfxPoolItemHolders);
+#ifdef DBG_UTIL
+    const size_t nBefore(rTarget.size());
+#endif
+    rTarget.erase(&rHolder);
+#ifdef DBG_UTIL
+    const size_t nAfter(rTarget.size());
+    if (nBefore != nAfter + 1)
+    {
+        SAL_WARN("svl.items", "SfxItemPool::unregisterPoolItemHolder: 
SfxPoolItemHolder was not registered (!)");
+    }
+#endif
+}
+
 sal_uInt16 SfxItemPool::GetFirstWhich() const
 {
-    return pImpl->mnStart;
+    return mnStart;
 }
 
 sal_uInt16 SfxItemPool::GetLastWhich() const
 {
-    return pImpl->mnEnd;
+    return mnEnd;
 }
 
 bool SfxItemPool::IsInRange( sal_uInt16 nWhich ) const
 {
-    return nWhich >= pImpl->mnStart && nWhich <= pImpl->mnEnd;
+    return nWhich >= mnStart && nWhich <= mnEnd;
 }
 
 sal_uInt16 SfxItemPool::GetIndex_Impl(sal_uInt16 nWhich) const
 {
-    if (nWhich < pImpl->mnStart || nWhich > pImpl->mnEnd)
+    if (nWhich < mnStart || nWhich > mnEnd)
     {
         assert(false && "missing bounds check before use");
         return 0;
     }
-    return nWhich - pImpl->mnStart;
+    return nWhich - mnStart;
 }
 
 sal_uInt16 SfxItemPool::GetSize_Impl() const
 {
-    return pImpl->mnEnd - pImpl->mnStart + 1;
+    return mnEnd - mnStart + 1;
 }
 
 const SfxPoolItem* SfxItemPool::GetPoolDefaultItem( sal_uInt16 nWhich ) const
 {
     const SfxPoolItem* pRet;
     if( IsInRange( nWhich ) )
-        pRet = pImpl->maPoolDefaults[GetIndex_Impl(nWhich)];
-    else if( pImpl->mpSecondary )
-        pRet = pImpl->mpSecondary->GetPoolDefaultItem( nWhich );
+        pRet = maPoolDefaults[GetIndex_Impl(nWhich)];
+    else if( mpSecondary )
+        pRet = mpSecondary->GetPoolDefaultItem( nWhich );
     else
     {
         assert(false && "unknown WhichId - cannot get pool default");
@@ -297,12 +360,12 @@ bool SfxItemPool::NeedsPoolRegistration(sal_uInt16 
nWhich) const
     if (!IsInRange(nWhich))
     {
         // get to correct pool
-        if (pImpl->mpSecondary)
-            return pImpl->mpSecondary->NeedsPoolRegistration(nWhich);
+        if (mpSecondary)
+            return mpSecondary->NeedsPoolRegistration(nWhich);
         return false;
     }
 
-    return NeedsPoolRegistration_Impl(nWhich - pImpl->mnStart);
+    return NeedsPoolRegistration_Impl(nWhich - mnStart);
 }
 
 bool SfxItemPool::Shareable(sal_uInt16 nWhich) const
@@ -310,18 +373,18 @@ bool SfxItemPool::Shareable(sal_uInt16 nWhich) const
     if (!IsInRange(nWhich))
     {
         // get to correct pool
-        if (pImpl->mpSecondary)
-            return pImpl->mpSecondary->Shareable(nWhich);
+        if (mpSecondary)
+            return mpSecondary->Shareable(nWhich);
         return false;
     }
 
-    return Shareable_Impl(nWhich - pImpl->mnStart);
+    return Shareable_Impl(nWhich - mnStart);
 }
 
 
 SfxBroadcaster& SfxItemPool::BC()
 {
-    return pImpl->aBC;
+    return aBC;
 }
 
 
@@ -357,12 +420,22 @@ SfxItemPool::SfxItemPool
                         pDefaults       /* Pointer to static Defaults;
                                            is directly referenced by the Pool,
                                            but no transfer of ownership */
-) :
-    pItemInfos(pInfo),
-    pImpl( new SfxItemPool_Impl( this, rName, nStartWhich, nEndWhich ) ),
-    ppRegisteredSfxPoolItems(nullptr)
-{
-    pImpl->eDefMetric = MapUnit::MapTwip;
+)
+: salhelper::SimpleReferenceObject()
+,pItemInfos(pInfo)
+, aName(rName)
+, maPoolDefaults(nEndWhich - nStartWhich + 1)
+, mpStaticDefaults(nullptr)
+, mpMaster(this)
+, mnStart(nStartWhich)
+, mnEnd(nEndWhich)
+, eDefMetric(MapUnit::MapCM)
+, maRegisteredSfxItemSets()
+, maRegisteredSfxPoolItemHolders()
+, maDirectPutItems()
+, mbPreDeleteDone(false)
+{
+    eDefMetric = MapUnit::MapTwip;
 
     if ( pDefaults )
         SetDefaults(pDefaults);
@@ -400,68 +473,75 @@ SfxItemPool::SfxItemPool
 
                                                     false
                                                     Take over static Defaults 
*/
-) :
-    salhelper::SimpleReferenceObject(),
-    pItemInfos(rPool.pItemInfos),
-    pImpl( new SfxItemPool_Impl( this, rPool.pImpl->aName, 
rPool.pImpl->mnStart, rPool.pImpl->mnEnd ) ),
-    ppRegisteredSfxPoolItems(nullptr)
-{
-    pImpl->eDefMetric = rPool.pImpl->eDefMetric;
+)
+: salhelper::SimpleReferenceObject()
+, pItemInfos(rPool.pItemInfos)
+, aName(rPool.aName)
+, maPoolDefaults(rPool.mnEnd - rPool.mnStart + 1)
+, mpStaticDefaults(nullptr)
+, mpMaster(this)
+, mnStart(rPool.mnStart)
+, mnEnd(rPool.mnEnd)
+, eDefMetric(MapUnit::MapCM)
+, maRegisteredSfxItemSets()
+, maRegisteredSfxPoolItemHolders()
+, maDirectPutItems()
+, mbPreDeleteDone(false)
+{
+    eDefMetric = rPool.eDefMetric;
 
     // Take over static Defaults
     if ( bCloneStaticDefaults )
     {
-        std::vector<SfxPoolItem *>* ppDefaults = new 
std::vector<SfxPoolItem*>(pImpl->mnEnd-pImpl->mnStart+1);
-        for ( sal_uInt16 n = 0; n <= pImpl->mnEnd - pImpl->mnStart; ++n )
+        std::vector<SfxPoolItem *>* ppDefaults = new 
std::vector<SfxPoolItem*>(mnEnd-mnStart+1);
+        for ( sal_uInt16 n = 0; n <= mnEnd - mnStart; ++n )
         {
-            (*ppDefaults)[n] = 
(*rPool.pImpl->mpStaticDefaults)[n]->Clone(this);
+            (*ppDefaults)[n] = (*rPool.mpStaticDefaults)[n]->Clone(this);
             (*ppDefaults)[n]->setStaticDefault();
         }
 
         SetDefaults( ppDefaults );
     }
     else
-        SetDefaults( rPool.pImpl->mpStaticDefaults );
+        SetDefaults( rPool.mpStaticDefaults );
 
     // Copy Pool Defaults
-    for (size_t n = 0; n < pImpl->maPoolDefaults.size(); ++n )
-        if (rPool.pImpl->maPoolDefaults[n])
+    for (size_t n = 0; n < maPoolDefaults.size(); ++n )
+        if (rPool.maPoolDefaults[n])
         {
-            pImpl->maPoolDefaults[n] = 
rPool.pImpl->maPoolDefaults[n]->Clone(this); //resets kind
-            pImpl->maPoolDefaults[n]->setPoolDefault();
+            maPoolDefaults[n] = rPool.maPoolDefaults[n]->Clone(this); //resets 
kind
+            maPoolDefaults[n]->setPoolDefault();
         }
 
     // Repair linkage
-    if ( rPool.pImpl->mpSecondary )
-        SetSecondaryPool( rPool.pImpl->mpSecondary->Clone().get() );
+    if ( rPool.mpSecondary )
+        SetSecondaryPool( rPool.mpSecondary->Clone().get() );
 }
 
 void SfxItemPool::SetDefaults( std::vector<SfxPoolItem*>* pDefaults )
 {
     DBG_ASSERT( pDefaults, "first we ask for it, and then we don't give 
back..." );
-    DBG_ASSERT( !pImpl->mpStaticDefaults, "already have Defaults" );
+    DBG_ASSERT( !mpStaticDefaults, "already have Defaults" );
 
-    pImpl->mpStaticDefaults = pDefaults;
+    mpStaticDefaults = pDefaults;
     //! if ((*mpStaticDefaults)->GetKind() != SfxItemKind::StaticDefault)
     //! FIXME: Probably doesn't work with SetItems at the end
     {
-        DBG_ASSERT( (*pImpl->mpStaticDefaults)[0]->GetRefCount() == 0 ||
-                    IsDefaultItem( (*pImpl->mpStaticDefaults)[0] ),
+        DBG_ASSERT( (*mpStaticDefaults)[0]->GetRefCount() == 0 ||
+                    IsDefaultItem( (*mpStaticDefaults)[0] ),
                     "these are not static" );
-        for ( sal_uInt16 n = 0; n <= pImpl->mnEnd - pImpl->mnStart; ++n )
+        for ( sal_uInt16 n = 0; n <= mnEnd - mnStart; ++n )
         {
-            assert(  ((*pImpl->mpStaticDefaults)[n]->Which() == n + 
pImpl->mnStart)
+            assert(  ((*mpStaticDefaults)[n]->Which() == n + mnStart)
                         && "items ids in pool-ranges and in static-defaults do 
not match" );
-            (*pImpl->mpStaticDefaults)[n]->setStaticDefault();
-            DBG_ASSERT(nullptr == ppRegisteredSfxPoolItems || nullptr == 
ppRegisteredSfxPoolItems[n]
-                || ppRegisteredSfxPoolItems[n]->empty(), "defaults with 
setitems with items?!" );
+            (*mpStaticDefaults)[n]->setStaticDefault();
         }
     }
 }
 
 void SfxItemPool::ClearDefaults()
 {
-    pImpl->mpStaticDefaults = nullptr;
+    mpStaticDefaults = nullptr;
 }
 
 /**
@@ -482,12 +562,12 @@ void SfxItemPool::ReleaseDefaults
 
 
 {
-    DBG_ASSERT( pImpl->mpStaticDefaults, "requirements not met" );
-    ReleaseDefaults( pImpl->mpStaticDefaults, bDelete );
+    DBG_ASSERT( mpStaticDefaults, "requirements not met" );
+    ReleaseDefaults( mpStaticDefaults, bDelete );
 
     // mpStaticDefaults points to deleted memory if bDelete == true.
     if ( bDelete )
-        pImpl->mpStaticDefaults = nullptr;
+        mpStaticDefaults = nullptr;
 }
 
 
@@ -536,73 +616,39 @@ void SfxItemPool::ReleaseDefaults
 SfxItemPool::~SfxItemPool()
 {
     // Need to be deleted?
-    // Caution: ppRegisteredSfxPoolItems is on-demand created and can be 
nullptr
-    if ( nullptr != ppRegisteredSfxPoolItems || !pImpl->maPoolDefaults.empty() 
)
+    if (!mbPreDeleteDone)//maPoolDefaults.empty())
         Delete();
 
-    if (pImpl->mpMaster != nullptr && pImpl->mpMaster != this)
+    if (mpMaster != nullptr && mpMaster != this)
     {
         // This condition indicates an error.
-        // A pImpl->mpMaster->SetSecondaryPool(...) call should have been made
+        // A mpMaster->SetSecondaryPool(...) call should have been made
         // earlier to prevent this. At this point we can only try to
         // prevent a crash later on.
-        DBG_ASSERT( pImpl->mpMaster == this, "destroying active 
Secondary-Pool" );
-        if (pImpl->mpMaster->pImpl->mpSecondary == this)
-            pImpl->mpMaster->pImpl->mpSecondary = nullptr;
+        DBG_ASSERT( mpMaster == this, "destroying active Secondary-Pool" );
+        if (mpMaster->mpSecondary == this)
+            mpMaster->mpSecondary = nullptr;
     }
 }
 
 void SfxItemPool::SetSecondaryPool( SfxItemPool *pPool )
 {
     // Reset Master in attached Pools
-    if ( pImpl->mpSecondary )
+    if ( mpSecondary )
     {
-#ifdef DBG_UTIL
-        if (nullptr != pImpl->mpStaticDefaults
-            && nullptr != ppRegisteredSfxPoolItems
-            && nullptr != pImpl->mpSecondary->ppRegisteredSfxPoolItems)
-            // Delete() did not yet run?
-        {
-            // Does the Master have SetItems?
-            bool bHasSetItems(false);
-
-            for (sal_uInt16 i(0); !bHasSetItems && i < pImpl->mnEnd - 
pImpl->mnStart; ++i)
-            {
-                const SfxPoolItem* 
pStaticDefaultItem((*pImpl->mpStaticDefaults)[i]);
-                bHasSetItems = pStaticDefaultItem->isSetItem();
-            }
-
-            if (bHasSetItems)
-            {
-                // Detached Pools must be empty
-                registeredSfxPoolItems** 
ppSet(pImpl->mpSecondary->ppRegisteredSfxPoolItems);
-
-                for (sal_uInt16 a(0); a < pImpl->mpSecondary->GetSize_Impl(); 
a++, ppSet++)
-                {
-                    if (nullptr != *ppSet && !(*ppSet)->empty())
-                    {
-                        SAL_WARN("svl.items", "old secondary pool: " << 
pImpl->mpSecondary->pImpl->aName
-                                        << " of pool: " << pImpl->aName << " 
must be empty.");
-                        break;
-                    }
-                }
-            }
-        }
-#endif
-
-        pImpl->mpSecondary->pImpl->mpMaster = pImpl->mpSecondary.get();
-        for ( SfxItemPool *p = pImpl->mpSecondary->pImpl->mpSecondary.get(); 
p; p = p->pImpl->mpSecondary.get() )
-            p->pImpl->mpMaster = pImpl->mpSecondary.get();
+        mpSecondary->mpMaster = mpSecondary.get();
+        for ( SfxItemPool *p = mpSecondary->mpSecondary.get(); p; p = 
p->mpSecondary.get() )
+            p->mpMaster = mpSecondary.get();
     }
 
     // Set Master of new Secondary Pools
-    DBG_ASSERT( !pPool || pPool->pImpl->mpMaster == pPool, "Secondary is 
present in two Pools" );
-    SfxItemPool *pNewMaster = GetMasterPool() ? pImpl->mpMaster : this;
-    for ( SfxItemPool *p = pPool; p; p = p->pImpl->mpSecondary.get() )
-        p->pImpl->mpMaster = pNewMaster;
+    DBG_ASSERT( !pPool || pPool->mpMaster == pPool, "Secondary is present in 
two Pools" );
+    SfxItemPool *pNewMaster = GetMasterPool() ? mpMaster : this;
+    for ( SfxItemPool *p = pPool; p; p = p->mpSecondary.get() )
+        p->mpMaster = pNewMaster;
 
     // Remember new Secondary Pool
-    pImpl->mpSecondary = pPool;
+    mpSecondary = pPool;
 
     CHECK_SLOTS();
 }
@@ -616,24 +662,24 @@ void SfxItemPool::SetItemInfos(SfxItemInfo const*const 
pInfo)
 
 MapUnit SfxItemPool::GetMetric( sal_uInt16 ) const
 {
-    return pImpl->eDefMetric;
+    return eDefMetric;
 }
 
 
 void SfxItemPool::SetDefaultMetric( MapUnit eNewMetric )
 {
 //    assert((pImpl->eDefMetric == eNewMetric || !pImpl->mpPoolRanges) && 
"pool already frozen, cannot change metric");
-    pImpl->eDefMetric = eNewMetric;
+    eDefMetric = eNewMetric;
 }
 
 MapUnit SfxItemPool::GetDefaultMetric() const
 {
-    return pImpl->eDefMetric;
+    return eDefMetric;
 }
 
 const OUString& SfxItemPool::GetName() const
 {
-    return pImpl->aName;
+    return aName;
 }
 
 
@@ -659,74 +705,20 @@ rtl::Reference<SfxItemPool> SfxItemPool::Clone() const
 void SfxItemPool::Delete()
 {
     // Already deleted?
-    // Caution: ppRegisteredSfxPoolItems is on-demand created and can be 
nullptr
-    if (nullptr == ppRegisteredSfxPoolItems && pImpl->maPoolDefaults.empty())
+    if (mbPreDeleteDone)//maPoolDefaults.empty())
         return;
+    mbPreDeleteDone = true;
 
     // Inform e.g. running Requests
-    pImpl->aBC.Broadcast( SfxHint( SfxHintId::Dying ) );
+    aBC.Broadcast( SfxHint( SfxHintId::Dying ) );
 
-    // Iterate through twice: first for the SetItems.
-    if (nullptr != pImpl->mpStaticDefaults && nullptr != 
ppRegisteredSfxPoolItems)
-    {
-        for (size_t n = 0; n < GetSize_Impl(); ++n)
-        {
-            // *mpStaticDefaultItem could've already been deleted in a class 
derived
-            // from SfxItemPool
-            // This causes chaos in Itempool!
-            const SfxPoolItem* 
pStaticDefaultItem((*pImpl->mpStaticDefaults)[n]);
-            if (pStaticDefaultItem->isSetItem() && nullptr != 
ppRegisteredSfxPoolItems[n])
-            {
-                // SfxSetItem found, remove PoolItems (and defaults) with same 
ID
-                auto& rArray(*(ppRegisteredSfxPoolItems[n]));
-                for (auto& rItemPtr : rArray)
-                {
-                    ReleaseRef(*rItemPtr, rItemPtr->GetRefCount()); // for 
RefCount check in dtor
-                    delete rItemPtr;
-                }
-                rArray.clear();
-                // let pImpl->DeleteItems() delete item arrays in maPoolItems
-                auto& rItemPtr = pImpl->maPoolDefaults[n];
-                if (rItemPtr)
-                {
-#ifdef DBG_UTIL
-                    ClearRefCount(*rItemPtr);
-#endif
-                    delete rItemPtr;
-                    rItemPtr = nullptr;
-                }
-            }
-        }
-    }
-
-    if (nullptr != ppRegisteredSfxPoolItems)
-    {
-        registeredSfxPoolItems** ppSet(ppRegisteredSfxPoolItems);
-
-        for (sal_uInt16 a(0); a < GetSize_Impl(); a++, ppSet++)
-        {
-            if (nullptr != *ppSet)
-            {
-                for (auto& rCandidate : **ppSet)
-                {
-                    if (nullptr != rCandidate && !IsDefaultItem(rCandidate))
-                    {
-                        ReleaseRef(*rCandidate, rCandidate->GetRefCount()); // 
for RefCount check in dtor
-                        delete rCandidate;
-                    }
-                }
-
-                delete *ppSet;
-                *ppSet = nullptr;
-            }
-        }
-
-        delete[] ppRegisteredSfxPoolItems;
-        ppRegisteredSfxPoolItems = nullptr;
-    }
+    // delete direct put items, may assert here when not empty
+    for (const auto& rCand : maDirectPutItems)
+        delete rCand;
+    maDirectPutItems.clear();
 
     // default items
-    for (auto rItemPtr : pImpl->maPoolDefaults)
+    for (auto rItemPtr : maPoolDefaults)
     {
         if (rItemPtr)
         {
@@ -738,7 +730,8 @@ void SfxItemPool::Delete()
         }
     }
 
-    pImpl->DeleteItems();
+    maPoolDefaults.clear();
+    mpPoolRanges.reset();
 }
 
 
@@ -747,7 +740,7 @@ void SfxItemPool::SetPoolDefaultItem(const SfxPoolItem 
&rItem)
     if ( IsInRange(rItem.Which()) )
     {
         auto& rOldDefault =
-            pImpl->maPoolDefaults[GetIndex_Impl(rItem.Which())];
+            maPoolDefaults[GetIndex_Impl(rItem.Which())];
         SfxPoolItem *pNewDefault = rItem.Clone(this);
         pNewDefault->setPoolDefault();
         if (rOldDefault)
@@ -758,8 +751,8 @@ void SfxItemPool::SetPoolDefaultItem(const SfxPoolItem 
&rItem)
         }
         rOldDefault = pNewDefault;
     }
-    else if ( pImpl->mpSecondary )
-        pImpl->mpSecondary->SetPoolDefaultItem(rItem);
+    else if ( mpSecondary )
+        mpSecondary->SetPoolDefaultItem(rItem);
     else
     {
         assert(false && "unknown WhichId - cannot set pool default");
@@ -775,7 +768,7 @@ void SfxItemPool::ResetPoolDefaultItem( sal_uInt16 nWhichId 
)
     if ( IsInRange(nWhichId) )
     {
         auto& rOldDefault =
-            pImpl->maPoolDefaults[GetIndex_Impl(nWhichId)];
+            maPoolDefaults[GetIndex_Impl(nWhichId)];
         if (rOldDefault)
         {
             rOldDefault->SetRefCount(0);
@@ -783,30 +776,24 @@ void SfxItemPool::ResetPoolDefaultItem( sal_uInt16 
nWhichId )
             rOldDefault = nullptr;
         }
     }
-    else if ( pImpl->mpSecondary )
-        pImpl->mpSecondary->ResetPoolDefaultItem(nWhichId);
+    else if ( mpSecondary )
+        mpSecondary->ResetPoolDefaultItem(nWhichId);
     else
     {
         assert(false && "unknown WhichId - cannot reset pool default");
     }
 }
 
-const SfxPoolItem& SfxItemPool::DirectPutItemInPoolImpl(const SfxPoolItem& 
rItem, sal_uInt16 nWhich, bool bPassingOwnership)
+const SfxPoolItem& SfxItemPool::DirectPutItemInPool(const SfxPoolItem& rItem)
 {
 #ifdef DBG_UTIL
     nAllDirectlyPooledSfxPoolItemCount++;
     nRemainingDirectlyPooledSfxPoolItemCount++;
 #endif
-
-    // make sure to use 'master'-pool, that's the one used by SfxItemSets
-    const SfxPoolItem* pRetval(implCreateItemEntry(*GetMasterPool(), &rItem, 
nWhich, bPassingOwnership));
-
-    // For the moment, as long as DirectPutItemInPoolImpl is used, make sure 
that
-    // the changes in implCreateItemEntry do not change anything, that would
-    // risc memory leaks by not (ab)using the garbage collector aspect of the 
pool.
-    registerSfxPoolItem(*pRetval);
-
-    return *pRetval;
+    // use SfxPoolItemHolder now to secure lifetime
+    SfxPoolItemHolder* pHolder(new SfxPoolItemHolder(*GetMasterPool(), 
&rItem));
+    GetMasterPool()->maDirectPutItems.insert(pHolder);
+    return *pHolder->getItem();
 }
 
 void SfxItemPool::DirectRemoveItemFromPool(const SfxPoolItem& rItem)
@@ -814,31 +801,36 @@ void SfxItemPool::DirectRemoveItemFromPool(const 
SfxPoolItem& rItem)
 #ifdef DBG_UTIL
     nRemainingDirectlyPooledSfxPoolItemCount--;
 #endif
-
-    // make sure to use 'master'-pool, that's the one used by SfxItemSets
-    implCleanupItemEntry(*GetMasterPool(), &rItem);
+    directPutSfxPoolItemHolders& rDirects(GetMasterPool()->maDirectPutItems);
+    for (directPutSfxPoolItemHolders::iterator aIter(rDirects.begin()); aIter 
!= rDirects.end(); aIter++)
+        if ((*aIter)->getItem() == &rItem)
+        {
+            delete *aIter;
+            rDirects.erase(aIter);
+            break;
+        }
 }
 
 const SfxPoolItem& SfxItemPool::GetDefaultItem( sal_uInt16 nWhich ) const
 {
     if ( !IsInRange(nWhich) )
     {
-        if ( pImpl->mpSecondary )
-            return pImpl->mpSecondary->GetDefaultItem( nWhich );
+        if ( mpSecondary )
+            return mpSecondary->GetDefaultItem( nWhich );
         assert(!"unknown which - don't ask me for defaults");
     }
 
-    DBG_ASSERT( pImpl->mpStaticDefaults, "no defaults known - don't ask me for 
defaults" );
+    DBG_ASSERT( mpStaticDefaults, "no defaults known - don't ask me for 
defaults" );
     sal_uInt16 nPos = GetIndex_Impl(nWhich);
-    SfxPoolItem* pDefault = pImpl->maPoolDefaults[nPos];
+    SfxPoolItem* pDefault = maPoolDefaults[nPos];
     if ( pDefault )
         return *pDefault;
-    return *(*pImpl->mpStaticDefaults)[nPos];
+    return *(*mpStaticDefaults)[nPos];
 }
 
 SfxItemPool* SfxItemPool::GetSecondaryPool() const
 {
-    return pImpl->mpSecondary.get();
+    return mpSecondary.get();
 }
 
 /* get the last pool by following the GetSecondaryPool chain */
@@ -852,7 +844,7 @@ SfxItemPool* SfxItemPool::GetLastPoolInChain()
 
 SfxItemPool* SfxItemPool::GetMasterPool() const
 {
-    return pImpl->mpMaster;
+    return mpMaster;
 }
 
 /**
@@ -864,125 +856,95 @@ SfxItemPool* SfxItemPool::GetMasterPool() const
  */
 void SfxItemPool::FreezeIdRanges()
 {
-    assert(pImpl->mpPoolRanges.empty() && "pool already frozen, cannot freeze 
twice");
-    FillItemIdRanges_Impl( pImpl->mpPoolRanges );
+    assert(mpPoolRanges.empty() && "pool already frozen, cannot freeze twice");
+    FillItemIdRanges_Impl( mpPoolRanges );
 }
 
 
 void SfxItemPool::FillItemIdRanges_Impl( WhichRangesContainer& pWhichRanges ) 
const
 {
-    DBG_ASSERT( pImpl->mpPoolRanges.empty(), "GetFrozenRanges() would be 
faster!" );
+    DBG_ASSERT( mpPoolRanges.empty(), "GetFrozenRanges() would be faster!" );
 
     pWhichRanges.reset();
 
     // Merge all ranges, keeping them sorted
-    for (const SfxItemPool* pPool = this; pPool; pPool = 
pPool->pImpl->mpSecondary.get())
-        pWhichRanges = pWhichRanges.MergeRange(pPool->pImpl->mnStart, 
pPool->pImpl->mnEnd);
+    for (const SfxItemPool* pPool = this; pPool; pPool = 
pPool->mpSecondary.get())
+        pWhichRanges = pWhichRanges.MergeRange(pPool->mnStart, pPool->mnEnd);
 }
 
 const WhichRangesContainer& SfxItemPool::GetFrozenIdRanges() const
 {
-    return pImpl->mpPoolRanges;
+    return mpPoolRanges;
 }
 
 const SfxPoolItem *SfxItemPool::GetItem2Default(sal_uInt16 nWhich) const
 {
     if ( !IsInRange(nWhich) )
     {
-        if ( pImpl->mpSecondary )
-            return pImpl->mpSecondary->GetItem2Default( nWhich );
+        if ( mpSecondary )
+            return mpSecondary->GetItem2Default( nWhich );
         assert(false && "unknown WhichId - cannot resolve surrogate");
         return nullptr;
     }
-    return (*pImpl->mpStaticDefaults)[ GetIndex_Impl(nWhich) ];
+    return (*mpStaticDefaults)[ GetIndex_Impl(nWhich) ];
 }
 
-#ifdef DBG_UTIL
-static void warnForMissingPoolRegistration(const SfxItemPool& rPool, 
sal_uInt16 nWhich)
-{
-    if (!rPool.NeedsPoolRegistration(nWhich))
-        SAL_INFO("svl.items", "ITEM: ItemSurrogate requested for WhichID " << 
nWhich <<
-        " class " << typeid(rPool.GetDefaultItem(nWhich)).name() <<
-        ": needs _bNeedsPoolRegistration==true in SfxItemInfo for that slot");
-}
-#endif
-
-const registeredSfxPoolItems& SfxItemPool::GetItemSurrogates(sal_uInt16 
nWhich) const
+void SfxItemPool::CollectSurrogates(std::unordered_set<const SfxPoolItem*>& 
rTarget, sal_uInt16 nWhich) const
 {
-    static const registeredSfxPoolItems EMPTY;
+    rTarget.clear();
 
-    if (!IsInRange(nWhich))
-    {
-        if (pImpl->mpSecondary)
-            return pImpl->mpSecondary->GetItemSurrogates(nWhich);
-        return EMPTY;
-    }
+    if (0 == nWhich)
+        return;
 
-    if (nullptr == ppRegisteredSfxPoolItems)
-    {
+    // 1st source for surrogates
+    const registeredSfxItemSets& 
rSets(GetMasterPool()->maRegisteredSfxItemSets);
+    const SfxPoolItem* pItem(nullptr);
+    for (const auto& rCand : rSets)
+        if (SfxItemState::SET == rCand->GetItemState(nWhich, false, &pItem))
+            rTarget.insert(pItem);
+
+    // 2nd source for surrogates
+    const registeredSfxPoolItemHolders& 
rHolders(GetMasterPool()->maRegisteredSfxPoolItemHolders);
+    for (const auto& rCand : rHolders)
+        if (rCand->Which() == nWhich && nullptr != rCand->getItem())
+            rTarget.insert(rCand->getItem());
+
+    // the 3rd source for surrogates is the list of direct put items
+    // but since these use SfxPoolItemHolder now they are automatically
+    // registered at 2nd source - IF NeedsPoolRegistration is set. So
+    // as long as we have this DirectPutItem stuff, iterate here and
+    // warn if an Item was added
+    const directPutSfxPoolItemHolders& 
rDirects(GetMasterPool()->maDirectPutItems);
 #ifdef DBG_UTIL
-        warnForMissingPoolRegistration(*this, nWhich);
+    const size_t aBefore(rTarget.size());
 #endif
-        return EMPTY;
-    }
-
-    registeredSfxPoolItems* pSet(ppRegisteredSfxPoolItems[nWhich - 
pImpl->mnStart]);
-
-    if (nullptr == pSet)
-    {
+    for (const auto& rCand : rDirects)
+        if (rCand->Which() == nWhich && nullptr != rCand->getItem())
+            rTarget.insert(rCand->getItem());
 #ifdef DBG_UTIL
-        warnForMissingPoolRegistration(*this, nWhich);
-#endif
-        return EMPTY;
-    }
-
-    return *pSet;
-}
-
-std::vector<const SfxPoolItem*> SfxItemPool::FindItemSurrogate(sal_uInt16 
nWhich, SfxPoolItem const & rSample) const
-{
-    static const std::vector<const SfxPoolItem*> EMPTY;
-
-    if (nullptr == ppRegisteredSfxPoolItems)
-        return EMPTY;
-
-    if ( !IsInRange(nWhich) )
+    const size_t aAfter(rTarget.size());
+    if (aBefore != aAfter)
     {
-        if ( pImpl->mpSecondary )
-            return pImpl->mpSecondary->FindItemSurrogate( nWhich, rSample );
-        assert(false && "unknown WhichId - cannot resolve surrogate");
-        return EMPTY;
+        SAL_WARN("svl.items", "SfxItemPool: Found non-automatically registered 
Item for Surrogates in DirectPutItems (!)");
     }
-
-    // get index (must exist due to checks above)
-    const sal_uInt16 nIndex(rSample.Which() - pImpl->mnStart);
-
-    if (nullptr == ppRegisteredSfxPoolItems)
-    {
-#ifdef DBG_UTIL
-        warnForMissingPoolRegistration(*this, nWhich);
 #endif
-        return EMPTY;
-    }
-
-    // get registeredSfxPoolItems container
-    registeredSfxPoolItems* pSet(ppRegisteredSfxPoolItems[nIndex]);
-
-    if (nullptr == pSet)
-    {
-#ifdef DBG_UTIL
-        warnForMissingPoolRegistration(*this, nWhich);
-#endif
-        return EMPTY;
-    }
-
-    std::vector<const SfxPoolItem*> rv;
+}
 
-    for (const SfxPoolItem* p : *pSet)
-        if (rSample == *p)
-            rv.push_back(p);
+void SfxItemPool::GetItemSurrogates(ItemSurrogates& rTarget, sal_uInt16 
nWhich) const
+{
+    std::unordered_set<const SfxPoolItem*> aNewSurrogates;
+    CollectSurrogates(aNewSurrogates, nWhich);
+    rTarget = ItemSurrogates(aNewSurrogates.begin(), aNewSurrogates.end());
+}
 
-    return rv;
+void SfxItemPool::FindItemSurrogate(ItemSurrogates& rTarget, sal_uInt16 
nWhich, SfxPoolItem const & rSample) const
+{
+    std::unordered_set<const SfxPoolItem*> aNewSurrogates;
+    CollectSurrogates(aNewSurrogates, nWhich);
+    rTarget.clear();
+    for (const auto& rCand : aNewSurrogates)
+        if (rSample == *rCand)
+            rTarget.push_back(rCand);
 }
 
 sal_uInt16 SfxItemPool::GetWhich( sal_uInt16 nSlotId, bool bDeep ) const
@@ -990,12 +952,12 @@ sal_uInt16 SfxItemPool::GetWhich( sal_uInt16 nSlotId, 
bool bDeep ) const
     if ( !IsSlot(nSlotId) )
         return nSlotId;
 
-    sal_uInt16 nCount = pImpl->mnEnd - pImpl->mnStart + 1;
+    sal_uInt16 nCount = mnEnd - mnStart + 1;
     for ( sal_uInt16 nOfs = 0; nOfs < nCount; ++nOfs )
         if ( pItemInfos[nOfs]._nSID == nSlotId )
-            return nOfs + pImpl->mnStart;
-    if ( pImpl->mpSecondary && bDeep )
-        return pImpl->mpSecondary->GetWhich(nSlotId);
+            return nOfs + mnStart;
+    if ( mpSecondary && bDeep )
+        return mpSecondary->GetWhich(nSlotId);
     return nSlotId;
 }
 
@@ -1007,13 +969,13 @@ sal_uInt16 SfxItemPool::GetSlotId( sal_uInt16 nWhich ) 
const
 
     if ( !IsInRange( nWhich ) )
     {
-        if ( pImpl->mpSecondary )
-            return pImpl->mpSecondary->GetSlotId(nWhich);
+        if ( mpSecondary )
+            return mpSecondary->GetSlotId(nWhich);
         assert(false && "unknown WhichId - cannot get slot-id");
         return 0;
     }
 
-    sal_uInt16 nSID = pItemInfos[nWhich - pImpl->mnStart]._nSID;
+    sal_uInt16 nSID = pItemInfos[nWhich - mnStart]._nSID;
     return nSID ? nSID : nWhich;
 }
 
@@ -1023,12 +985,12 @@ sal_uInt16 SfxItemPool::GetTrueWhich( sal_uInt16 
nSlotId, bool bDeep ) const
     if ( !IsSlot(nSlotId) )
         return 0;
 
-    sal_uInt16 nCount = pImpl->mnEnd - pImpl->mnStart + 1;
+    sal_uInt16 nCount = mnEnd - mnStart + 1;
     for ( sal_uInt16 nOfs = 0; nOfs < nCount; ++nOfs )
         if ( pItemInfos[nOfs]._nSID == nSlotId )
-            return nOfs + pImpl->mnStart;
-    if ( pImpl->mpSecondary && bDeep )
-        return pImpl->mpSecondary->GetTrueWhich(nSlotId);
+            return nOfs + mnStart;
+    if ( mpSecondary && bDeep )
+        return mpSecondary->GetTrueWhich(nSlotId);
     return 0;
 }
 
@@ -1040,192 +1002,12 @@ sal_uInt16 SfxItemPool::GetTrueSlotId( sal_uInt16 
nWhich ) const
 
     if ( !IsInRange( nWhich ) )
     {
-        if ( pImpl->mpSecondary )
-            return pImpl->mpSecondary->GetTrueSlotId(nWhich);
+        if ( mpSecondary )
+            return mpSecondary->GetTrueSlotId(nWhich);
         assert(false && "unknown WhichId - cannot get slot-id");
         return 0;
     }
-    return pItemInfos[nWhich - pImpl->mnStart]._nSID;
-}
-
-void SfxItemPool::registerSfxPoolItem(const SfxPoolItem& rItem)
-{
-    assert(rItem.Which() != 0);
-
-    if (IsSlot(rItem.Which()))
-        // do not register SlotItems
-        return;
-
-    if (rItem.isRegisteredAtPool())
-        // already registered, done
-        return;
-
-    if (!IsInRange(rItem.Which()))
-    {
-        // get to the right pool
-        if (pImpl->mpSecondary)
-        {
-            pImpl->mpSecondary->registerSfxPoolItem(rItem);
-            return;
-        }
-
-        return;
-    }
-
-    if (nullptr == ppRegisteredSfxPoolItems)
-        // on-demand allocate array of registeredSfxPoolItems and init to 
nullptr
-        ppRegisteredSfxPoolItems = new 
registeredSfxPoolItems*[GetSize_Impl()]{};
-
-    // get correct registeredSfxPoolItems
-    const sal_uInt16 nIndex(rItem.Which() - pImpl->mnStart);
-    registeredSfxPoolItems* pSet(ppRegisteredSfxPoolItems[nIndex]);
-
-    if (nullptr == pSet)
-        // on-demand allocate
-        ppRegisteredSfxPoolItems[nIndex] = pSet = new registeredSfxPoolItems;
-
-    // insert to registeredSfxPoolItems and set flag at Item
-    pSet->insert(&rItem);
-    const_cast<SfxPoolItem&>(rItem).setRegisteredAtPool(true);
-}
-
-void SfxItemPool::unregisterSfxPoolItem(const SfxPoolItem& rItem)
-{
-    if (!rItem.isRegisteredAtPool())
-        // Item is not registered, done
-        return;
-
-    if (!IsInRange(rItem.Which()))
-    {
-        // get to the right pool
-        if (pImpl->mpSecondary)
-        {
-            pImpl->mpSecondary->unregisterSfxPoolItem(rItem);
-            return;
-        }
-
-        assert(false && "unknown WhichId - cannot execute 
unregisterSfxPoolItem");
-        return;
-    }
-
-    // we need a valid WhichID and the array of containers has to exist
-    assert(rItem.Which() != 0);
-    assert(nullptr != ppRegisteredSfxPoolItems);
-
-    // get index (must exist due to checks above)
-    const sal_uInt16 nIndex(rItem.Which() - pImpl->mnStart);
-
-    // a valid registeredSfxPoolItems container has to exist
-    registeredSfxPoolItems* pSet(ppRegisteredSfxPoolItems[nIndex]);
-    assert(nullptr != pSet);
-
-    // remove registered Item and reset flag at Item
-    pSet->erase(&rItem);
-    const_cast<SfxPoolItem&>(rItem).setRegisteredAtPool(false);
-}
-
-bool SfxItemPool::isSfxPoolItemRegisteredAtThisPool(const SfxPoolItem& rItem) 
const
-{
-    if (!rItem.isRegisteredAtPool())
-        // Item is not registered at all, so also not at this Pool
-        return false;
-
-    if (IsSlot(rItem.Which()))
-        // do not check being registered for SlotItems
-        return false;
-
-    if (!IsInRange(rItem.Which()))
-    {
-        // get to the right pool
-        if (pImpl->mpSecondary)
-            return 
pImpl->mpSecondary->isSfxPoolItemRegisteredAtThisPool(rItem);
-        return false;
-    }
-
-    // we need a valid WhichID
-    assert(rItem.Which() != 0);
-
-    if (nullptr == ppRegisteredSfxPoolItems)
-        // when no array of containers exists the Item is not registered
-        return false;
-
-    // get index (must exist due to checks above)
-    const sal_uInt16 nIndex(rItem.Which() - pImpl->mnStart);
-
-    // get registeredSfxPoolItems container
-    registeredSfxPoolItems* pSet(ppRegisteredSfxPoolItems[nIndex]);
-
-    if (nullptr == pSet)
-        // when no registeredSfxPoolItems container exists the Item is not 
registered
-        return false;
-
-    // test if Item is registered
-    return pSet->find(&rItem) != pSet->end();
-}
-
-const SfxPoolItem* SfxItemPool::tryToGetEqualItem(const SfxPoolItem& rItem, 
sal_uInt16 nWhich) const
-{
-    if (IsSlot(nWhich))
-        // SlotItems are not registered @pool and not in any range
-        return nullptr;
-
-    if (!IsInRange(nWhich))
-    {
-        // get to the right pool
-        if (pImpl->mpSecondary)
-            return pImpl->mpSecondary->tryToGetEqualItem(rItem, nWhich);
-        return nullptr;
-    }
-
-    if (nullptr == ppRegisteredSfxPoolItems)
-        // no Items at all
-        return nullptr;
-
-    // get index (must exist due to checks above)
-    const sal_uInt16 nIndex(nWhich - pImpl->mnStart);
-
-    if (!Shareable_Impl(nIndex))
-        // not shareable
-        return nullptr;
-
-    // get registeredSfxPoolItems container
-    registeredSfxPoolItems* pSet(ppRegisteredSfxPoolItems[nIndex]);
-
-    if (nullptr == pSet)
-        // no registeredSfxPoolItems for this WhichID
-        return nullptr;
-
-    for (const auto& rCandidate : *pSet)
-        if (*rCandidate == rItem)
-            return rCandidate;
-
-    return nullptr;
-}
-
-void SfxItemPool::dumpAsXml(xmlTextWriterPtr pWriter) const
-{
-    (void)xmlTextWriterStartElement(pWriter, BAD_CAST("SfxItemPool"));
-
-    if (nullptr != ppRegisteredSfxPoolItems)
-    {
-        registeredSfxPoolItems** ppSet(ppRegisteredSfxPoolItems);
-
-        for (sal_uInt16 a(0); a < GetSize_Impl(); a++, ppSet++)
-        {
-            if (nullptr != *ppSet)
-            {
-                for (auto& rCandidate : **ppSet)
-                {
-                    if (nullptr != rCandidate)
-                    {
-                        rCandidate->dumpAsXml(pWriter);
-                    }
-                }
-            }
-        }
-    }
-
-    (void)xmlTextWriterEndElement(pWriter);
+    return pItemInfos[nWhich - mnStart]._nSID;
 }
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/svl/source/items/itemset.cxx b/svl/source/items/itemset.cxx
index 3b8a77f8186f..41051a981aa4 100644
--- a/svl/source/items/itemset.cxx
+++ b/svl/source/items/itemset.cxx
@@ -50,7 +50,6 @@ size_t getUsedSfxPoolItemHolderCount() { return 
nUsedSfxPoolItemHolderCount; }
 // ScPatternAttr). Still keep it so that when errors
 // come up to this change be able to quickly check using the
 // fallback flag 'ITEM_CLASSIC_MODE'
-static bool g_bItemClassicMode(getenv("ITEM_CLASSIC_MODE"));
 
 // I thought about this constructor a while, but when there is no
 // Item we need no cleanup at destruction (what we would need the
@@ -83,7 +82,9 @@ SfxPoolItemHolder::SfxPoolItemHolder(SfxItemPool& rPool, 
const SfxPoolItem* pIte
     nUsedSfxPoolItemHolderCount++;
 #endif
     if (nullptr != m_pItem)
-        m_pItem = implCreateItemEntry(*m_pPool, m_pItem, m_pItem->Which(), 
bPassingOwnership);
+        m_pItem = implCreateItemEntry(getPool(), m_pItem, m_pItem->Which(), 
bPassingOwnership);
+    if (nullptr != m_pItem && 
getPool().NeedsPoolRegistration(m_pItem->Which()))
+        getPool().registerPoolItemHolder(*this);
 }
 
 SfxPoolItemHolder::SfxPoolItemHolder(const SfxPoolItemHolder& rHolder)
@@ -99,7 +100,9 @@ SfxPoolItemHolder::SfxPoolItemHolder(const 
SfxPoolItemHolder& rHolder)
     nUsedSfxPoolItemHolderCount++;
 #endif
     if (nullptr != m_pItem)
-        m_pItem = implCreateItemEntry(*m_pPool, m_pItem, m_pItem->Which(), 
false);
+        m_pItem = implCreateItemEntry(getPool(), m_pItem, m_pItem->Which(), 
false);
+    if (nullptr != m_pItem && 
getPool().NeedsPoolRegistration(m_pItem->Which()))
+        getPool().registerPoolItemHolder(*this);
 }
 
 SfxPoolItemHolder::~SfxPoolItemHolder()
@@ -108,8 +111,10 @@ SfxPoolItemHolder::~SfxPoolItemHolder()
     assert(!isDeleted() && "Destructed instance used (!)");
     nAllocatedSfxPoolItemHolderCount--;
 #endif
+    if (nullptr != m_pItem && 
getPool().NeedsPoolRegistration(m_pItem->Which()))
+        getPool().unregisterPoolItemHolder(*this);
     if (nullptr != m_pItem)
-        implCleanupItemEntry(*m_pPool, m_pItem);
+        implCleanupItemEntry(m_pItem);
 #ifdef DBG_UTIL
     m_bDeleted = true;
 #endif
@@ -122,14 +127,18 @@ const SfxPoolItemHolder& 
SfxPoolItemHolder::operator=(const SfxPoolItemHolder& r
     if (this == &rHolder || *this == rHolder)
         return *this;
 
+    if (nullptr != m_pItem && 
getPool().NeedsPoolRegistration(m_pItem->Which()))
+        getPool().unregisterPoolItemHolder(*this);
     if (nullptr != m_pItem)
-        implCleanupItemEntry(*m_pPool, m_pItem);
+        implCleanupItemEntry(m_pItem);
 
     m_pPool = rHolder.m_pPool;
     m_pItem = rHolder.m_pItem;
 
     if (nullptr != m_pItem)
-        m_pItem = implCreateItemEntry(*m_pPool, m_pItem, m_pItem->Which(), 
false);
+        m_pItem = implCreateItemEntry(getPool(), m_pItem, m_pItem->Which(), 
false);
+    if (nullptr != m_pItem && 
getPool().NeedsPoolRegistration(m_pItem->Which()))
+        getPool().registerPoolItemHolder(*this);
 
     return *this;
 }
@@ -154,6 +163,7 @@ SfxItemSet::SfxItemSet(SfxItemPool& rPool)
     : m_pPool(&rPool)
     , m_pParent(nullptr)
     , m_nCount(0)
+    , m_nRegister(0)
     , m_nTotalCount(svl::detail::CountRanges(rPool.GetFrozenIdRanges()))
     , m_bItemsFixed(false)
     , m_ppItems(new SfxPoolItem const *[m_nTotalCount]{})
@@ -171,6 +181,7 @@ SfxItemSet::SfxItemSet( SfxItemPool& rPool, 
SfxAllItemSetFlag )
     : m_pPool(&rPool)
     , m_pParent(nullptr)
     , m_nCount(0)
+    , m_nRegister(0)
     , m_nTotalCount(0)
     , m_bItemsFixed(false)
     , m_ppItems(nullptr)
@@ -188,6 +199,7 @@ SfxItemSet::SfxItemSet( SfxItemPool& rPool, 
WhichRangesContainer&& ranges, SfxPo
     : m_pPool(&rPool)
     , m_pParent(nullptr)
     , m_nCount(0)
+    , m_nRegister(0)
     , m_nTotalCount(nTotalCount)
     , m_bItemsFixed(true)
     , m_ppItems(ppItems)
@@ -209,6 +221,7 @@ SfxItemSet::SfxItemSet( const SfxItemSet& rOther,
     : m_pPool(rOther.m_pPool)
     , m_pParent(rOther.m_pParent)
     , m_nCount(rOther.m_nCount)
+    , m_nRegister(rOther.m_nRegister)
     , m_nTotalCount(rOther.m_nTotalCount)
     , m_bItemsFixed(true)
     , m_ppItems(ppMyItems)
@@ -234,12 +247,16 @@ SfxItemSet::SfxItemSet( const SfxItemSet& rOther,
         *ppDst = implCreateItemEntry(*GetPool(), rSource, 0, false);
         ppDst++;
     }
+
+    if (0 != m_nRegister)
+        GetPool()->registerItemSet(*this);
 }
 
 SfxItemSet::SfxItemSet(SfxItemPool& pool, WhichRangesContainer wids)
     : m_pPool(&pool)
     , m_pParent(nullptr)
     , m_nCount(0)
+    , m_nRegister(0)
     , m_nTotalCount(svl::detail::CountRanges(wids))
     , m_bItemsFixed(false)
     , m_ppItems(new SfxPoolItem const *[m_nTotalCount]{})
@@ -278,9 +295,13 @@ SfxPoolItem const* implCreateItemEntry(SfxItemPool& rPool, 
SfxPoolItem const* pS
     //     return pSource;
 
     if (0 == pSource->Which())
+    {
         // These *should* be SfxVoidItem(0) the only Items with 0 == WhichID,
         // these need to be cloned (currently...)
+        if (bPassingOwnership)
+            return pSource;
         return pSource->Clone();
+    }
 
     // get correct target WhichID
     if (0 == nWhich)
@@ -321,6 +342,46 @@ SfxPoolItem const* implCreateItemEntry(SfxItemPool& rPool, 
SfxPoolItem const* pS
         return pSource;
     }
 
+    // // currently need to check if pSource is a default Item and
+    // // avoid it to leave the Pool. This is necessary since Pools
+    // // currently delete their default items hard, resetting RefCnt
+    // // and killing them. This might change after a Pool refinement.
+    // // For now, replace them with the local Pool default. It *might*
+    // // be even necessary to replace with a cloned non-default instance
+    // // if the defaults differ.
+    // // NOTE: Currently even some Pools have no 'real' StaticDefaults,
+    // // but these also get deleted (sigh)
+    // if (IsStaticDefaultItem(pSource))
+    // {
+    //     assert(!bPassingOwnership && "ITEM: PassingOwnership not possible 
combined with StaticDefault (!)");
+    //     const SfxPoolItem* pStatic(pTargetPool->GetItem2Default(nWhich));
+    //     if (nullptr != pStatic)
+    //     {
+    //         if (SfxPoolItem::areSame(pSource, pStatic))
+    //             pSource = pStatic;
+    //         else
+    //         {
+    //             pSource = pSource->Clone(pMasterPool);
+    //             bPassingOwnership = true;
+    //         }
+    //     }
+    // }
+    // else if (IsDefaultItem(pSource))
+    // {
+    //     assert(!bPassingOwnership && "ITEM: PassingOwnership not possible 
combined with DynaimcDefault (!)");
+    //     const SfxPoolItem* 
pDynamic(pTargetPool->GetPoolDefaultItem(nWhich));
+    //     if (nullptr != pDynamic)
+    //     {
+    //         if (SfxPoolItem::areSame(pSource, pDynamic))
+    //             pSource = pDynamic;
+    //         else
+    //         {
+    //             pSource = pSource->Clone(pMasterPool);
+    //             bPassingOwnership = true;
+    //         }
+    //     }
+    // }
+
     // CAUTION: Shareable_Impl and NeedsPoolRegistration_Impl
     // use index, not WhichID (one more reason to change the Pools)
     const sal_uInt16 nIndex(pTargetPool->GetIndex_Impl(nWhich));
@@ -351,49 +412,11 @@ SfxPoolItem const* implCreateItemEntry(SfxItemPool& 
rPool, SfxPoolItem const* pS
         if (pSource->isSetItem() && static_cast<const 
SfxSetItem*>(pSource)->GetItemSet().GetPool() != pMasterPool)
             break;
 
-        // If the Item is registered it is pool-dependent, so do not share when
-        // it is registered but not at this pool
-        if (pSource->isRegisteredAtPool() && 
!pTargetPool->isSfxPoolItemRegisteredAtThisPool(*pSource))
-            break;
-
         // If we get here we can share the Item
         pSource->AddRef();
         return pSource;
     }
 
-    // g_bItemClassicMode: try finding already existing item
-    // NOTE: the UnitTest testIteratorsDefPattern claims that that Item "can be
-    //   edited by the user" which explains why it breaks so many rules for 
Items,
-    //   it behaves like an alien. That Item in the SC Pool claims to be a
-    //   'StaticDefault' and gets changed (..?)
-
-    // only do this if classic mode or required (calls from Pool::Direct*)
-    while(g_bItemClassicMode)
-    {
-        if (!pTargetPool->Shareable_Impl(nIndex))
-            // not shareable, so no need to search for identical item
-            break;
-
-        // try to get equal Item. This is the expensive part...
-        const SfxPoolItem* pExisting(pTargetPool->tryToGetEqualItem(*pSource, 
nWhich));
-
-        if (nullptr == pExisting)
-            // none found, done
-            break;
-
-        if (0 == pExisting->GetRefCount())
-            // do not share not-yet shared Items (should not happen)
-            break;
-
-        if (bPassingOwnership)
-            // need to cleanup if we are offered to own pSource
-            delete pSource;
-
-        // If we get here we can share the found Item
-        pExisting->AddRef();
-        return pExisting;
-    }
-
     // check if the handed over and to be directly used item is a
     // SfxSetItem, that would make it pool-dependent. It then must have
     // the same target-pool, ensure that by the cost of cloning it
@@ -419,30 +442,10 @@ SfxPoolItem const* implCreateItemEntry(SfxItemPool& 
rPool, SfxPoolItem const* pS
     // increase RefCnt 0->1
     pSource->AddRef();
 
-    // try to register @Pool (only needed if not yet registered)
-    if (!pSource->isRegisteredAtPool())
-    {
-        bool bRegisterAtPool(false);
-
-        if (g_bItemClassicMode)
-        {
-            // in classic mode register only/all shareable items
-            bRegisterAtPool = pTargetPool->Shareable_Impl(nIndex);
-        }
-        else
-        {
-            // in new mode register only/all items marked as need to be 
registered
-            bRegisterAtPool = pTargetPool->NeedsPoolRegistration_Impl(nIndex);
-        }
-
-        if (bRegisterAtPool)
-            pTargetPool->registerSfxPoolItem(*pSource);
-    }
-
     return pSource;
 }
 
-void implCleanupItemEntry(SfxItemPool& rPool, SfxPoolItem const* pSource)
+void implCleanupItemEntry(SfxPoolItem const* pSource)
 {
     if (nullptr == pSource)
         // no entry, done
@@ -454,10 +457,6 @@ void implCleanupItemEntry(SfxItemPool& rPool, SfxPoolItem 
const* pSource)
 
     if (0 == pSource->Which())
     {
-        // de-register when registered @pool
-        if (pSource->isRegisteredAtPool())
-            rPool.unregisterSfxPoolItem(*pSource);
-
         // These *should* be SfxVoidItem(0) the only Items with 0 == WhichID
         // and need to be deleted
         delete pSource;
@@ -479,10 +478,6 @@ void implCleanupItemEntry(SfxItemPool& rPool, SfxPoolItem 
const* pSource)
     // good to find other errors)
     pSource->ReleaseRef();
 
-    // de-register before deletion when registered @pool
-    if (pSource->isRegisteredAtPool())
-        rPool.unregisterSfxPoolItem(*pSource);
-
     // delete Item
     delete pSource;
 }
@@ -491,6 +486,7 @@ SfxItemSet::SfxItemSet( const SfxItemSet& rASet )
     : m_pPool( rASet.m_pPool )
     , m_pParent( rASet.m_pParent )
     , m_nCount( rASet.m_nCount )
+    , m_nRegister( rASet.m_nRegister )
     , m_nTotalCount( rASet.m_nTotalCount )
     , m_bItemsFixed(false)
     , m_ppItems(nullptr)
@@ -502,9 +498,7 @@ SfxItemSet::SfxItemSet( const SfxItemSet& rASet )
     nUsedSfxItemSetCount++;
 #endif
     if (rASet.GetRanges().empty())
-    {
         return;
-    }
 
     if (0 == rASet.Count())
     {
@@ -527,12 +521,15 @@ SfxItemSet::SfxItemSet( const SfxItemSet& rASet )
     }
 
     assert(svl::detail::validRanges2(m_pWhichRanges));
+    if (0 != m_nRegister)
+        GetPool()->registerItemSet(*this);
 }
 
 SfxItemSet::SfxItemSet(SfxItemSet&& rASet) noexcept
     : m_pPool( rASet.m_pPool )
     , m_pParent( rASet.m_pParent )
     , m_nCount( rASet.m_nCount )
+    , m_nRegister( rASet.m_nRegister )
     , m_nTotalCount( rASet.m_nTotalCount )
     , m_bItemsFixed(false)
     , m_ppItems( rASet.m_ppItems )
@@ -550,18 +547,27 @@ SfxItemSet::SfxItemSet(SfxItemSet&& rASet) noexcept
 
         // can just copy the pointers, the ones in the original m_ppItems
         // array will no longer be used/referenced (unused mem, but not lost,
-        // it's part of the ItemSet-derived object)
+        // it's part of the ItemSet-derived object).
         std::copy(rASet.m_ppItems, rASet.m_ppItems + TotalCount(), m_ppItems);
     }
-    else
-    {
-        // taking over ownership
-        rASet.m_nTotalCount = 0;
-        rASet.m_ppItems = nullptr;
-    }
+
+    // deregister if rASet is registered before ptrs vanish
+    if (0 != rASet.m_nRegister)
+        rASet.GetPool()->unregisterItemSet(rASet);
+
+    // register if new set needs that
+    if (0 != m_nRegister)
+        GetPool()->registerItemSet(*this);
+
+    // taking over ownership
     rASet.m_pPool = nullptr;
     rASet.m_pParent = nullptr;
     rASet.m_nCount = 0;
+    rASet.m_nRegister = 0;
+    rASet.m_nTotalCount = 0;
+    rASet.m_ppItems = nullptr;
+    rASet.m_pWhichRanges.reset();
+    rASet.m_aCallback = nullptr;
 
     assert(svl::detail::validRanges2(m_pWhichRanges));
 }
@@ -614,6 +620,65 @@ sal_uInt16 SfxItemSet::ClearSingleItem_ForWhichID( 
sal_uInt16 nWhich )
     return 0;
 }
 
+void SfxItemSet::checkRemovePoolRegistration(const SfxPoolItem* pItem)
+{
+    if (nullptr == pItem)
+        // no Item, done
+        return;
+
+    if (IsInvalidItem(pItem) || pItem->isVoidItem() || 0 == pItem->Which())
+        // checks IsInvalidItem/SfxVoidItem(0)
+        return;
+
+    if (SfxItemPool::IsSlot(pItem->Which()))
+        // no slots, these do not support NeedsPoolRegistration
+        return;
+
+    if(!GetPool()->NeedsPoolRegistration(pItem->Which()))
+        // not needed for this item, done
+        return;
+
+    // there must be a registered one
+    assert(0 != m_nRegister);
+
+    // decrement counter
+    m_nRegister--;
+
-e 
... etc. - the rest is truncated

Reply via email to