chart2/source/view/main/ChartItemPool.cxx          |    4 
 cui/source/tabpages/tabarea.cxx                    |   20 
 dbaccess/source/ui/dlg/dbadmin.cxx                 |  123 +--
 dbaccess/source/ui/misc/UITools.cxx                |   11 
 editeng/source/editeng/editdoc.cxx                 |  136 +--
 editeng/source/editeng/editobj.cxx                 |    8 
 editeng/source/editeng/editobj2.hxx                |    4 
 editeng/source/editeng/fieldupdater.cxx            |    2 
 editeng/source/items/textitem.cxx                  |   48 -
 extensions/source/propctrlr/fontdialog.cxx         |   41 -
 include/editeng/fontitem.hxx                       |    1 
 include/editeng/wghtitem.hxx                       |    8 
 include/sal/log-areas.dox                          |    1 
 include/svl/custritm.hxx                           |    2 
 include/svl/itempool.hxx                           |   88 +-
 include/svl/itemset.hxx                            |   21 
 include/svl/poolitem.hxx                           |   81 +-
 include/svx/pageitem.hxx                           |    2 
 include/svx/sdasitm.hxx                            |    2 
 include/svx/xbtmpit.hxx                            |    2 
 reportdesign/source/ui/misc/UITools.cxx            |  117 +-
 reportdesign/source/ui/report/ReportController.cxx |   62 -
 sc/inc/attarray.hxx                                |    2 
 sc/inc/attrib.hxx                                  |    2 
 sc/inc/docpool.hxx                                 |    3 
 sc/inc/patattr.hxx                                 |    9 
 sc/qa/unit/ucalc.cxx                               |    4 
 sc/source/core/data/attarray.cxx                   |   86 +-
 sc/source/core/data/attrib.cxx                     |   15 
 sc/source/core/data/column.cxx                     |    8 
 sc/source/core/data/column2.cxx                    |    8 
 sc/source/core/data/column4.cxx                    |    4 
 sc/source/core/data/dociter.cxx                    |    2 
 sc/source/core/data/docpool.cxx                    |  207 ++---
 sc/source/core/data/document.cxx                   |    2 
 sc/source/core/data/fillinfo.cxx                   |   12 
 sc/source/core/data/global.cxx                     |    2 
 sc/source/core/data/patattr.cxx                    |   45 -
 sc/source/core/data/table2.cxx                     |    2 
 sc/source/core/data/table3.cxx                     |    8 
 sc/source/core/data/table4.cxx                     |    4 
 sc/source/filter/excel/xestyle.cxx                 |    2 
 sc/source/filter/excel/xistyle.cxx                 |    2 
 sc/source/filter/lotus/lotattr.cxx                 |    2 
 sc/source/filter/oox/sheetdatabuffer.cxx           |    2 
 sc/source/filter/oox/stylesbuffer.cxx              |    4 
 sc/source/ui/app/inputhdl.cxx                      |    2 
 sc/source/ui/app/msgpool.cxx                       |   21 
 sc/source/ui/condformat/condformatdlg.cxx          |    4 
 sc/source/ui/inc/editsh.hxx                        |   12 
 sc/source/ui/undo/undoblk3.cxx                     |   12 
 sc/source/ui/undo/undocell.cxx                     |   12 
 sc/source/ui/unoobj/cellsuno.cxx                   |    2 
 sc/source/ui/view/cellsh1.cxx                      |    8 
 sc/source/ui/view/editsh.cxx                       |   27 
 sc/source/ui/view/output.cxx                       |    6 
 sc/source/ui/view/output2.cxx                      |   70 -
 sc/source/ui/view/spelleng.cxx                     |    2 
 sc/source/ui/view/tabvwshc.cxx                     |    2 
 sc/source/ui/view/viewfunc.cxx                     |   10 
 sd/source/ui/func/fupage.cxx                       |    2 
 sd/source/ui/unoidl/unomodel.cxx                   |    5 
 sfx2/source/control/shell.cxx                      |    2 
 sfx2/source/control/statcach.cxx                   |    9 
 sfx2/source/dialog/dinfdlg.cxx                     |    3 
 sfx2/source/explorer/nochaos.cxx                   |    2 
 svl/qa/unit/items/stylepool.cxx                    |    4 
 svl/qa/unit/items/test_itempool.cxx                |   70 -
 svl/source/inc/poolio.hxx                          |  142 ---
 svl/source/items/custritm.cxx                      |    8 
 svl/source/items/itempool.cxx                      |  823 +++++++++++++--------
 svl/source/items/itemset.cxx                       |  334 ++++++--
 svl/source/items/poolcach.cxx                      |   27 
 svl/source/items/poolitem.cxx                      |   88 ++
 svl/source/items/sitem.cxx                         |    3 
 svl/source/items/stylepool.cxx                     |   14 
 svl/source/items/voiditem.cxx                      |    6 
 svx/qa/unit/customshapes.cxx                       |    4 
 svx/source/dialog/framelinkarray.cxx               |   16 
 svx/source/items/customshapeitem.cxx               |   17 
 svx/source/items/pageitem.cxx                      |    8 
 svx/source/sidebar/nbdtmg.cxx                      |    2 
 svx/source/svdraw/svdattr.cxx                      |    6 
 svx/source/unodraw/UnoNamespaceMap.cxx             |   10 
 svx/source/xoutdev/xpool.cxx                       |   16 
 sw/source/core/attr/cellatr.cxx                    |    3 
 sw/source/core/attr/hints.cxx                      |    9 
 sw/source/core/attr/swatrset.cxx                   |   35 
 sw/source/core/bastyp/init.cxx                     |  343 ++++----
 sw/source/core/crsr/crstrvl.cxx                    |   10 
 sw/source/core/doc/docbasic.cxx                    |    2 
 sw/source/core/doc/doctxm.cxx                      |    3 
 sw/source/core/doc/fmtcol.cxx                      |   10 
 sw/source/core/docnode/node.cxx                    |    4 
 sw/source/core/layout/atrfrm.cxx                   |   12 
 sw/source/core/layout/sectfrm.cxx                  |    2 
 sw/source/core/para/paratr.cxx                     |    6 
 sw/source/core/table/swnewtable.cxx                |    2 
 sw/source/core/table/swtable.cxx                   |    6 
 sw/source/core/text/itratr.cxx                     |    6 
 sw/source/core/text/pormulti.cxx                   |    4 
 sw/source/core/text/txtfrm.cxx                     |    4 
 sw/source/core/txtnode/attrcontentcontrol.cxx      |   11 
 sw/source/core/txtnode/fmtatr2.cxx                 |   12 
 sw/source/core/txtnode/thints.cxx                  |   21 
 sw/source/core/txtnode/txatbase.cxx                |    2 
 sw/source/core/undo/rolbck.cxx                     |    4 
 sw/source/core/undo/unattr.cxx                     |    2 
 sw/source/core/undo/undobj1.cxx                    |    2 
 sw/source/core/unocore/unorefmk.cxx                |    6 
 sw/source/filter/basflt/fltshell.cxx               |    2 
 sw/source/filter/writer/writer.cxx                 |    8 
 sw/source/filter/ww8/wrtww8.cxx                    |    2 
 sw/source/filter/xml/xmlfonte.cxx                  |   47 +
 sw/source/ui/index/swuiidxmrk.cxx                  |   34 
 sw/source/uibase/index/toxmgr.cxx                  |    2 
 sw/source/uibase/shells/frmsh.cxx                  |    2 
 sw/source/uibase/uiview/view2.cxx                  |    3 
 sw/source/uibase/utlui/content.cxx                 |    2 
 vcl/source/app/svapp.cxx                           |   17 
 120 files changed, 2043 insertions(+), 1629 deletions(-)

New commits:
commit ab7c81f55621d7b0d1468c63305163016dd78837
Author:     Armin Le Grand (allotropia) <armin.le.grand.ext...@allotropia.de>
AuthorDate: Wed Oct 4 15:42:27 2023 +0200
Commit:     Armin Le Grand <armin.le.gr...@me.com>
CommitDate: Tue Nov 7 18:07:13 2023 +0100

    ITEM: Get away from classic 'poolable' Item flag
    
    To understand this, some look back in history will be needed to see
    why it is as it is today. In some (reworked) comments 'poolable' is
    described as flag to hold Items in the ItemPool, also always having
    only one incarnation of each possible Item.
    This is not the original intention, but a side-effect. The reason is
    what the binary format in the office did: To save a document, the
    Objects & the Pool were saved, *not* individual Items *together*
    with the objects. The Pool was completely (binary) saved (and loaded)
    in one run.
    Temporary IDs were used to represent at the objects in file which
    Items were referenced. This *required* to have only one incarnation
    per item to have a minimal binary file size, thus this high effort
    was put into this. At doc load, the pool was loaded, all Items were
    set to RefCount 5000, the references from the objects were restored
    and then for each Item the RefCount was lowered by 5000 again
    and - if being zero - deleted. Items for UI were marked 'non-poolable'
    to *not* safe them with the document, so poolable was a flag to decide
    if that Info/Item was to be saved with the document - or more direct:
    if it is Model Data.
    Items are small, so if we prefer runtime it is okay to no longer being
    strict with this, anyways does not happen often and has only marginal
    memory effects - compared to runtime effects/savings.
    Other problems which this caused: One example is that objects in the
    UNDO stack were still in the pool, so e.g. deleted pictures were saved
    with the document despite no longer being used (!). That is the reason
    we have an UndoItemPool and a method MigrateItemPool to move stuff to
    that Pool when objects go to the UNDO stack - all of this is also no
    longer needed.
    Cleaning this up means to ideally have all items in the SfxItemSet,
    no longer at the Pool. The Pool should be reduced to a 'Default-Item-
    Holder' and a 'Slot-to-whichId-mapper'.
    
    This needs thorough cleanups/removals, but will be worth it because
    that massive simplification(s) will increase safety an runtime and make
    migrating to the goal of completely type-based ItemSet stuff easier for
    the future. Hopefully only view code in the office working with items
    will have to be changed for this.
    
    In this 1st step I already found that some 'compromizes' will be
    needed:
    - There are still Items that have to be at the pool to make the
    Surrogate-stuff working. This gives back all Items in a Pool of a type
    and is used in ca. 80 cases. Each one looks at these Items *without*
    context (e.g. a SfxItemSet at an Object would be a context), so if e.g.
    a dialog is open that temporarily uses Items of that type you would
    also get these - without knowing about it...
    To make that work there is still a mechanism to have Items at the Pool,
    but now just *registering* (and un-reg) them without any sort/search/
    remove needs. Also only for Items that need that, so I evaluated the
    GetItemSurrogates calls and added some asserts when GetItemSurrogates
    tries to access an unregistered item type which needs to be added.
    
    - Another caveat is that there are about 250 places that directly put
    Items to the Pool (not all remove these, that is done at pool deletion,
    so some kind of silent 'garbage-collection' is in place). To have an
    overview I renamed the accessing methods to separate them from the same
    functionality at the SfxItemSet, which had the same names. An
    implementation does still add these directly to the pool, there is no
    way to cleanup those usages for now. In principle all these should be
    changed to hold the data at an SfxItemSet.
    
    I am still hunting problems. But you can build the office, all apps
    work (including chart) and you can do speed comparisons already.
    
    There are test throwing errors, so I hunt these now. It is hard to
    give an estimation about how much more changes/corrections will be
    needed.
    
    Completed adaptions to new registered Items at Pool, that reduces the
    failing tests. Still many that I need to hunt.
    
    Added stuff to work around that 'compromize' in ScDocumentPool: It
    overloads ::PutImpl of the pool to implement special handling for
    a single Item in SC, the ScPatternAttr. In former code that method
    was used from SfxItemSet and ::PutImpl at the pool directly, so it
    was only used in one place. I am not sure if it was used from
    the SfxItemSet functionality, but better offer it for now. To not
    waste too much runtime the callbacks depend on the boolean
    'NewItemCallback' at the SfxPoolItem, it gets set for that single
    Item in SC and only then the callbacks trigger. I hope to get rid
    of those again, e.g. newItem_UseDirect is only needed since we have
    no 'real' StaticPoolDefaults currently - another thing that needs to
    be cleaned up in a next step.
    
    Since usages of impl(Create|Cleanup)ItemEntry and
    Direct(Put|Remove)ItemInPoolImpl got more and more similar I decided to
    unify that: move impl(Create|Cleanup)ItemEntry to tooling, make it
    globally available in svl and use it also directly for
    Direct(Put|Remove)ItemInPoolImpl. This slightly increases the failing
    tests again, but only since in Direct(Put|Remove)ItemInPoolImpl that
    fallback (e.g. tryToGetEqualItem) was used before, thus this is the
    same class of errors (SfxPoolItem ptr-compare) as the others which I
    will need to find anyways. Also fixed some missing stuff.
    
    Have now idenified and redirected all SfxPoolItem ptr-compares
    to be able to debug these - one cause for the remaining errors is
    probably that before with bPoolable those often were sufficient, but
    are no longer. Used the [loplugin:itemcompare] and a local clang
    build to do so, see https://gerrit.libreoffice.org/c/core/+/157172
    
    Stabilized Direct(Put|Remove)ItemInPoolImpl forwards, added parameter
    to implCreateItemEntry to signal that it gets called from DirectPool
    stuff - currently needed. Hopefully when getting rid of that DirectPool
    stuff we can remove that again
    
    Added two more debug functionalities:
    - Added a SerialNumber to allow targeted debugging for deterministic
      cases
    - Added registering & listing of still-allocated SfxPoolItems at
      office shutdown
    
    Found PtrComp error in thints.cxx - POC, thanks to
    areSfxPoolItemPtrsEqual. Will hopefully help more with other tests
    
    Found some wrong asserts/warnings where I was too careful and not
    finding something/succeeding is OK, fixes some UnitTests for SC
    
    For SC I now just tried to replace all areSfxPoolItemPtrsEqual with
    the full-ptr-content compare SfxPoolItem::areSame. I also needed to
    experiment/adapt the newItem_Callback solution but got it working.
    
    Did that replacement now for SW too, found some places where the
    direct ptr compare is OK.
    
    Continued for the rest of occurrences, now all 160 places evaluated.
    Also done some cleanups.
    
    Massive cleanups of stuff no longer needed with this paradigm change.
    Also decided to keep tryToGetEqualItem/ITEM_CLASSIC_MODE for now.
    It is used for *one* Item (ScPatternAttr/ATTR_PATTERN) in SC that
    already needs many exceptions. Also useful for testing if errors
    come up on this change to test if it is related to this.
    
    Added forwarding of target Pool for ::Clone in SvxSetItem and
    SvxSetItem, simplified SfxStateCache::SetState_Impl and returned
    to simple ptr compares in SfxPoolItem::areSame to not do the test
    in areSfxPoolItemPtrsEqual.
    
    Debugged through UITest_calc_tests9 and found that in tdf133629
    where BoxStyle is applied to fully selected empty calc the Item-
    reuse fallback has to be used not only for ATTR_PATTERN, see
    comment @implCreateItemEntry. Maybe more...
    
    Problem with test_tdf156611_insert_hyperlink_like_excel. Found that
    in ScEditShell::GetFirstURLFieldFromCell the correct SvxURLField
    is found and returned as ptr, but it's usage crashes. That is due to
    the SfxItemSet aEditSet used there gets destroyed at function return
    what again deletes the SvxFieldItem that is holding the SvxURLField
    that gets returned.
    This shows a more general problem: There is no 'SfxPoolItemHolder'
    that safely holds a single SfxPoolItem - like a SfxItemSet for a
    single Item (if Items would be shared_ptrs, that would be a safe
    return value).
    That will be needed in the future, but for now use another solution:
    Since I see no reason why EE_FEATURE_FIELD should not be shareable
    I wil change this for ow in the SfxItemInfo for EditCharAttribField.
    That way the Item returned will be shared (RefCnt > 1) and thus not
    be deleted.
    
    I changed the return value for GetURLField() and
    GetFirstURLFieldFromCell() in ScEditShell: At least for
    GetFirstURLFieldFromCell the return type/value was not safe: The
    SvxFieldItem accessed there and held in the local temporary
    SfxItemSet may be deleted with it, so return value can be
    corrupted/deleted. To avoid that, return a Clone of SvxFieldData
    as a unique_ptr.
    
    With all that UnitTest debugging and hunting and to get the paradigm
    change working to no longer rely on shared/pooled items I lost a
    little bit focus on speed, so I made an optimization round for the
    two central methods implCreateItemEntry/implCleanupItemEntry to
    get back to the speed improvements that I detected when starting this
    change. It was mainly lost due to that 'strange' chained pool stuff
    we have, so I added to detect the target pool (the one at which the
    WhichID is registered) directly and only once. Next thing to cleanup
    will/should be the pool and it's concept, all this is not needed
    and really costs runtime.
    Since implCreateItemEntry/implCleanupItemEntry are executed millions
    of times, each cycle counts here.
    
    Had an error in the last changes: pool::*_Impl methods use index
    instead of WhichID - most of them. Another bad trap, I really need
    to cleanup pool stuff next.
    
    Change-Id: I6295f332325b33268ec396ed46f8d0a1026e2d69
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/157559
    Tested-by: Jenkins
    Reviewed-by: Armin Le Grand <armin.le.gr...@me.com>

diff --git a/chart2/source/view/main/ChartItemPool.cxx 
b/chart2/source/view/main/ChartItemPool.cxx
index ed62e57c1a53..8f787cd4bd70 100644
--- a/chart2/source/view/main/ChartItemPool.cxx
+++ b/chart2/source/view/main/ChartItemPool.cxx
@@ -190,8 +190,10 @@ ChartItemPool::ChartItemPool():
     const sal_uInt16 nMax = SCHATTR_END - SCHATTR_START + 1;
     for( sal_uInt16 i = 0; i < nMax; i++ )
     {
+        // _nSID, _bNeedsPoolRegistration, _bShareable
         pItemInfos[i]._nSID = 0;
-        pItemInfos[i]._bPoolable = true;
+        pItemInfos[i]._bNeedsPoolRegistration = false;
+        pItemInfos[i]._bShareable = true;
     }
 
     // slot ids differing from which ids
diff --git a/cui/source/tabpages/tabarea.cxx b/cui/source/tabpages/tabarea.cxx
index 9b082680fcee..4b50b74b8b68 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().Put(aColorListItem,SID_COLOR_TABLE);
+            
mpDrawModel->GetItemPool().DirectPutItemInPool(aColorListItem,SID_COLOR_TABLE);
         mpColorList = mpDrawModel->GetColorList();
     }
     if( mpNewGradientList != mpDrawModel->GetGradientList() )
@@ -93,7 +93,7 @@ void SvxAreaTabDialog::SavePalettes()
         if ( pShell )
             pShell->PutItem( aItem );
         else
-            mpDrawModel->GetItemPool().Put(aItem,SID_GRADIENT_LIST);
+            
mpDrawModel->GetItemPool().DirectPutItemInPool(aItem,SID_GRADIENT_LIST);
         mpGradientList = mpDrawModel->GetGradientList();
     }
     if( mpNewHatchingList != mpDrawModel->GetHatchList() )
@@ -103,7 +103,7 @@ void SvxAreaTabDialog::SavePalettes()
         if ( pShell )
             pShell->PutItem( aItem );
         else
-            mpDrawModel->GetItemPool().Put(aItem,SID_HATCH_LIST);
+            
mpDrawModel->GetItemPool().DirectPutItemInPool(aItem,SID_HATCH_LIST);
         mpHatchingList = mpDrawModel->GetHatchList();
     }
     if( mpNewBitmapList != mpDrawModel->GetBitmapList() )
@@ -113,7 +113,7 @@ void SvxAreaTabDialog::SavePalettes()
         if ( pShell )
             pShell->PutItem( aItem );
         else
-            mpDrawModel->GetItemPool().Put(aItem,SID_BITMAP_LIST);
+            
mpDrawModel->GetItemPool().DirectPutItemInPool(aItem,SID_BITMAP_LIST);
         mpBitmapList = mpDrawModel->GetBitmapList();
     }
     if( mpNewPatternList != mpDrawModel->GetPatternList() )
@@ -123,7 +123,7 @@ void SvxAreaTabDialog::SavePalettes()
         if( pShell )
             pShell->PutItem( aItem );
         else
-            mpDrawModel->GetItemPool().Put(aItem,SID_PATTERN_LIST);
+            
mpDrawModel->GetItemPool().DirectPutItemInPool(aItem,SID_PATTERN_LIST);
         mpPatternList = mpDrawModel->GetPatternList();
     }
 
@@ -148,7 +148,7 @@ void SvxAreaTabDialog::SavePalettes()
         if ( pShell )
             pShell->PutItem( aItem );
         else
-            mpDrawModel->GetItemPool().Put(aItem);
+            mpDrawModel->GetItemPool().DirectPutItemInPool(aItem);
     }
 
     if( mnBitmapListState & ChangeType::MODIFIED )
@@ -162,7 +162,7 @@ void SvxAreaTabDialog::SavePalettes()
             pShell->PutItem( aItem );
         else
         {
-            mpDrawModel->GetItemPool().Put(aItem);
+            mpDrawModel->GetItemPool().DirectPutItemInPool(aItem);
         }
     }
 
@@ -176,7 +176,7 @@ void SvxAreaTabDialog::SavePalettes()
         if( pShell )
             pShell->PutItem( aItem );
         else
-            mpDrawModel->GetItemPool().Put(aItem);
+            mpDrawModel->GetItemPool().DirectPutItemInPool(aItem);
     }
 
     if( mnGradientListState & ChangeType::MODIFIED )
@@ -190,7 +190,7 @@ void SvxAreaTabDialog::SavePalettes()
             pShell->PutItem( aItem );
         else
         {
-            mpDrawModel->GetItemPool().Put(aItem);
+            mpDrawModel->GetItemPool().DirectPutItemInPool(aItem);
         }
     }
 
@@ -202,7 +202,7 @@ void SvxAreaTabDialog::SavePalettes()
             pShell->PutItem( aItem );
         else
         {
-            mpDrawModel->GetItemPool().Put(aItem);
+            mpDrawModel->GetItemPool().DirectPutItemInPool(aItem);
         }
     }
 }
diff --git a/dbaccess/source/ui/dlg/dbadmin.cxx 
b/dbaccess/source/ui/dlg/dbadmin.cxx
index 95bc34e11443..372e72e258a7 100644
--- a/dbaccess/source/ui/dlg/dbadmin.cxx
+++ b/dbaccess/source/ui/dlg/dbadmin.cxx
@@ -340,67 +340,68 @@ void 
ODbAdminDialog::createItemSet(std::unique_ptr<SfxItemSet>& _rpSet, rtl::Ref
     // create the pool
     static SfxItemInfo const aItemInfos[DSID_LAST_ITEM_ID - DSID_FIRST_ITEM_ID 
+ 1] =
     {
-        {0,false},
-        {0,false},
-        {0,false},
-        {0,false},
-        {0,false},
-        {0,false},
-        {0,false},
-        {0,false},
-        {0,false},
-        {0,false},
-        {0,false},
-        {0,false},
-        {0,false},
-        {0,false},
-        {0,false},
-        {0,false},
-        {0,false},
-        {0,false},
-        {0,false},
-        {0,false},
-        {0,false},
-        {0,false},
-        {0,false},
-        {0,false},
-        {0,false},
-        {0,false},
-        {0,false},
-        {0,false},
-        {0,false},
-        {0,false},
-        {0,false},
-        {0,false},
-        {0,false},
-        {0,false},
-        {0,false},
-        {0,false},
-        {0,false},
-        {0,false},
-        {0,false},
-        {0,false},
-        {0,false},
-        {0,false},
-        {0,false},
-        {0,false},
-        {0,false},
-        {0,false},
-        {0,false},
-        {0,false},
-        {0,false},
-        {0,false},
-        {0,false},
-        {0,false},
-        {0,false},
-        {0,false},
-        {0,false},
-        {0,false},
-        {0,false},
-        {0,false},
-        {0,false},
-        {0,false},
-        {0,false},
+        // _nSID, _bNeedsPoolRegistration, _bShareable
+        {0,false,false},
+        {0,false,false},
+        {0,false,false},
+        {0,false,false},
+        {0,false,false},
+        {0,false,false},
+        {0,false,false},
+        {0,false,false},
+        {0,false,false},
+        {0,false,false},
+        {0,false,false},
+        {0,false,false},
+        {0,false,false},
+        {0,false,false},
+        {0,false,false},
+        {0,false,false},
+        {0,false,false},
+        {0,false,false},
+        {0,false,false},
+        {0,false,false},
+        {0,false,false},
+        {0,false,false},
+        {0,false,false},
+        {0,false,false},
+        {0,false,false},
+        {0,false,false},
+        {0,false,false},
+        {0,false,false},
+        {0,false,false},
+        {0,false,false},
+        {0,false,false},
+        {0,false,false},
+        {0,false,false},
+        {0,false,false},
+        {0,false,false},
+        {0,false,false},
+        {0,false,false},
+        {0,false,false},
+        {0,false,false},
+        {0,false,false},
+        {0,false,false},
+        {0,false,false},
+        {0,false,false},
+        {0,false,false},
+        {0,false,false},
+        {0,false,false},
+        {0,false,false},
+        {0,false,false},
+        {0,false,false},
+        {0,false,false},
+        {0,false,false},
+        {0,false,false},
+        {0,false,false},
+        {0,false,false},
+        {0,false,false},
+        {0,false,false},
+        {0,false,false},
+        {0,false,false},
+        {0,false,false},
+        {0,false,false},
+        {0,false,false},
     };
 
     OSL_ENSURE(std::size(aItemInfos) == sal_uInt16(DSID_LAST_ITEM_ID),"Invalid 
Ids!");
diff --git a/dbaccess/source/ui/misc/UITools.cxx 
b/dbaccess/source/ui/misc/UITools.cxx
index ae856a34b35f..a07d588be2a9 100644
--- a/dbaccess/source/ui/misc/UITools.cxx
+++ b/dbaccess/source/ui/misc/UITools.cxx
@@ -763,11 +763,12 @@ bool callColumnFormatDialog(weld::Widget* _pParent,
     // UNO->ItemSet
     static SfxItemInfo aItemInfos[] =
     {
-        { 0, false },
-        { SID_ATTR_NUMBERFORMAT_VALUE,      true },
-        { SID_ATTR_ALIGN_HOR_JUSTIFY,       true },
-        { SID_ATTR_NUMBERFORMAT_INFO,       true },
-        { SID_ATTR_NUMBERFORMAT_ONE_AREA,   true }
+        // _nSID, _bNeedsPoolRegistration, _bShareable
+        { 0,                                false, true },    // 
SBA_DEF_RANGEFORMAT
+        { SID_ATTR_NUMBERFORMAT_VALUE,      false, true },    // 
SBA_DEF_FMTVALUE
+        { SID_ATTR_ALIGN_HOR_JUSTIFY,       false, true },    // 
SBA_ATTR_ALIGN_HOR_JUSTIFY
+        { SID_ATTR_NUMBERFORMAT_INFO,       false, true },    // 
SID_ATTR_NUMBERFORMAT_INFO
+        { SID_ATTR_NUMBERFORMAT_ONE_AREA,   false, true }     // 
SID_ATTR_NUMBERFORMAT_ONE_AREA
     };
     static const auto aAttrMap = svl::Items<
         SBA_DEF_RANGEFORMAT, SBA_ATTR_ALIGN_HOR_JUSTIFY,
diff --git a/editeng/source/editeng/editdoc.cxx 
b/editeng/source/editeng/editdoc.cxx
index 9b0d3948bc13..9841d7854c32 100644
--- a/editeng/source/editeng/editdoc.cxx
+++ b/editeng/source/editeng/editdoc.cxx
@@ -157,70 +157,72 @@ bool IsScriptItemValid( sal_uInt16 nItemId, short 
nScriptType )
     return bValid;
 }
 
-const SfxItemInfo aItemInfos[EDITITEMCOUNT] = {
-        { SID_ATTR_FRAMEDIRECTION, true },         // EE_PARA_WRITINGDIR
-        { 0, true },                               // EE_PARA_XMLATTRIBS
-        { SID_ATTR_PARA_HANGPUNCTUATION, true },   // 
EE_PARA_HANGINGPUNCTUATION
-        { SID_ATTR_PARA_FORBIDDEN_RULES, true },   // EE_PARA_FORBIDDENRULES
-        { SID_ATTR_PARA_SCRIPTSPACE, true },       // EE_PARA_ASIANCJKSPACING
-        { SID_ATTR_NUMBERING_RULE, true },         // EE_PARA_NUMBULL
-        { 0, true },                               // EE_PARA_HYPHENATE
-        { 0, true },                               // EE_PARA_HYPHENATE_NO_CAPS
-        { 0, true },                               // 
EE_PARA_HYPHENATE_NO_LAST_WORD
-        { 0, true },                               // EE_PARA_BULLETSTATE
-        { 0, true },                               // EE_PARA_OUTLLRSPACE
-        { SID_ATTR_PARA_OUTLLEVEL, true },         // EE_PARA_OUTLLEVEL
-        { SID_ATTR_PARA_BULLET, true },            // EE_PARA_BULLET
-        { SID_ATTR_LRSPACE, true },                // EE_PARA_LRSPACE
-        { SID_ATTR_ULSPACE, true },                // EE_PARA_ULSPACE
-        { SID_ATTR_PARA_LINESPACE, true },         // EE_PARA_SBL
-        { SID_ATTR_PARA_ADJUST, true },            // EE_PARA_JUST
-        { SID_ATTR_TABSTOP, true },                // EE_PARA_TABS
-        { SID_ATTR_ALIGN_HOR_JUSTIFY_METHOD, true }, // EE_PARA_JUST_METHOD
-        { SID_ATTR_ALIGN_VER_JUSTIFY, true },      // EE_PARA_VER_JUST
-        { SID_ATTR_CHAR_COLOR, true },         // EE_CHAR_COLOR
-        { SID_ATTR_CHAR_FONT, true },          // EE_CHAR_FONTINFO
-        { SID_ATTR_CHAR_FONTHEIGHT, true },    // EE_CHAR_FONTHEIGHT
-        { SID_ATTR_CHAR_SCALEWIDTH, true },    // EE_CHAR_FONTWIDTH
-        { SID_ATTR_CHAR_WEIGHT, true },        // EE_CHAR_WEIGHT
-        { SID_ATTR_CHAR_UNDERLINE, true },     // EE_CHAR_UNDERLINE
-        { SID_ATTR_CHAR_STRIKEOUT, true },     // EE_CHAR_STRIKEOUT
-        { SID_ATTR_CHAR_POSTURE, true },       // EE_CHAR_ITALIC
-        { SID_ATTR_CHAR_CONTOUR, true },       // EE_CHAR_OUTLINE
-        { SID_ATTR_CHAR_SHADOWED, true },      // EE_CHAR_SHADOW
-        { SID_ATTR_CHAR_ESCAPEMENT, true },    // EE_CHAR_ESCAPEMENT
-        { SID_ATTR_CHAR_AUTOKERN, true },      // EE_CHAR_PAIRKERNING
-        { SID_ATTR_CHAR_KERNING, true },       // EE_CHAR_KERNING
-        { SID_ATTR_CHAR_WORDLINEMODE, true },  // EE_CHAR_WLM
-        { SID_ATTR_CHAR_LANGUAGE, true },      // EE_CHAR_LANGUAGE
-        { SID_ATTR_CHAR_CJK_LANGUAGE, true },  // EE_CHAR_LANGUAGE_CJK
-        { SID_ATTR_CHAR_CTL_LANGUAGE, true },  // EE_CHAR_LANGUAGE_CTL
-        { SID_ATTR_CHAR_CJK_FONT, true },      // EE_CHAR_FONTINFO_CJK
-        { SID_ATTR_CHAR_CTL_FONT, true },      // EE_CHAR_FONTINFO_CTL
-        { SID_ATTR_CHAR_CJK_FONTHEIGHT, true }, // EE_CHAR_FONTHEIGHT_CJK
-        { SID_ATTR_CHAR_CTL_FONTHEIGHT, true }, // EE_CHAR_FONTHEIGHT_CTL
-        { SID_ATTR_CHAR_CJK_WEIGHT, true },    // EE_CHAR_WEIGHT_CJK
-        { SID_ATTR_CHAR_CTL_WEIGHT, true },    // EE_CHAR_WEIGHT_CTL
-        { SID_ATTR_CHAR_CJK_POSTURE, true },   // EE_CHAR_ITALIC_CJK
-        { SID_ATTR_CHAR_CTL_POSTURE, true },   // EE_CHAR_ITALIC_CTL
-        { SID_ATTR_CHAR_EMPHASISMARK, true },  // EE_CHAR_EMPHASISMARK
-        { SID_ATTR_CHAR_RELIEF, true },        // EE_CHAR_RELIEF
-        { 0, true },                           // EE_CHAR_RUBI_DUMMY
-        { 0, true },                           // EE_CHAR_XMLATTRIBS
-        { SID_ATTR_CHAR_OVERLINE, true },      // EE_CHAR_OVERLINE
-        { SID_ATTR_CHAR_CASEMAP, true },       // EE_CHAR_CASEMAP
-        { SID_ATTR_CHAR_GRABBAG, true },       // EE_CHAR_GRABBAG
-        { SID_ATTR_CHAR_BACK_COLOR, true },    // EE_CHAR_BKGCOLOR
-        { 0, true },                           // EE_FEATURE_TAB
-        { 0, true },                           // EE_FEATURE_LINEBR
-        { SID_ATTR_CHAR_CHARSETCOLOR, true },  // EE_FEATURE_NOTCONV
-        { SID_FIELD, false },                  // EE_FEATURE_FIELD
+const SfxItemInfo aItemInfos[EDITITEMCOUNT] =
+{
+        // _nSID, _bNeedsPoolRegistration, _bShareable
+        { SID_ATTR_FRAMEDIRECTION, false, true },         // EE_PARA_WRITINGDIR
+        { 0, true, true },                               // EE_PARA_XMLATTRIBS
+        { SID_ATTR_PARA_HANGPUNCTUATION, false, true },   // 
EE_PARA_HANGINGPUNCTUATION
+        { SID_ATTR_PARA_FORBIDDEN_RULES, false, true },   // 
EE_PARA_FORBIDDENRULES
+        { SID_ATTR_PARA_SCRIPTSPACE, false, true },       // 
EE_PARA_ASIANCJKSPACING
+        { SID_ATTR_NUMBERING_RULE, false, true },         // EE_PARA_NUMBULL
+        { 0, false, true },                               // EE_PARA_HYPHENATE
+        { 0, false, true },                               // 
EE_PARA_HYPHENATE_NO_CAPS
+        { 0, false, true },                               // 
EE_PARA_HYPHENATE_NO_LAST_WORD
+        { 0, false, true },                               // 
EE_PARA_BULLETSTATE
+        { 0, false, true },                               // 
EE_PARA_OUTLLRSPACE
+        { SID_ATTR_PARA_OUTLLEVEL, false, true },         // EE_PARA_OUTLLEVEL
+        { SID_ATTR_PARA_BULLET, false, true },            // EE_PARA_BULLET
+        { SID_ATTR_LRSPACE, false, true },                // EE_PARA_LRSPACE
+        { SID_ATTR_ULSPACE, false, true },                // EE_PARA_ULSPACE
+        { SID_ATTR_PARA_LINESPACE, false, true },         // EE_PARA_SBL
+        { SID_ATTR_PARA_ADJUST, false, true },            // EE_PARA_JUST
+        { SID_ATTR_TABSTOP, false, true },                // EE_PARA_TABS
+        { SID_ATTR_ALIGN_HOR_JUSTIFY_METHOD, false, true }, // 
EE_PARA_JUST_METHOD
+        { SID_ATTR_ALIGN_VER_JUSTIFY, false, true },      // EE_PARA_VER_JUST
+        { SID_ATTR_CHAR_COLOR, true, true },         // EE_CHAR_COLOR
+        { SID_ATTR_CHAR_FONT, true, true },          // EE_CHAR_FONTINFO
+        { SID_ATTR_CHAR_FONTHEIGHT, false, true },    // EE_CHAR_FONTHEIGHT
+        { SID_ATTR_CHAR_SCALEWIDTH, false, true },    // EE_CHAR_FONTWIDTH
+        { SID_ATTR_CHAR_WEIGHT, false, true },        // EE_CHAR_WEIGHT
+        { SID_ATTR_CHAR_UNDERLINE, false, true },     // EE_CHAR_UNDERLINE
+        { SID_ATTR_CHAR_STRIKEOUT, false, true },     // EE_CHAR_STRIKEOUT
+        { SID_ATTR_CHAR_POSTURE, false, true },       // EE_CHAR_ITALIC
+        { SID_ATTR_CHAR_CONTOUR, false, true },       // EE_CHAR_OUTLINE
+        { SID_ATTR_CHAR_SHADOWED, false, true },      // EE_CHAR_SHADOW
+        { SID_ATTR_CHAR_ESCAPEMENT, false, true },    // EE_CHAR_ESCAPEMENT
+        { SID_ATTR_CHAR_AUTOKERN, false, true },      // EE_CHAR_PAIRKERNING
+        { SID_ATTR_CHAR_KERNING, false, true },       // EE_CHAR_KERNING
+        { SID_ATTR_CHAR_WORDLINEMODE, false, true },  // EE_CHAR_WLM
+        { SID_ATTR_CHAR_LANGUAGE, false, true },      // EE_CHAR_LANGUAGE
+        { SID_ATTR_CHAR_CJK_LANGUAGE, false, true },  // EE_CHAR_LANGUAGE_CJK
+        { SID_ATTR_CHAR_CTL_LANGUAGE, false, true },  // EE_CHAR_LANGUAGE_CTL
+        { SID_ATTR_CHAR_CJK_FONT, true, true },      // EE_CHAR_FONTINFO_CJK
+        { SID_ATTR_CHAR_CTL_FONT, true, true },      // EE_CHAR_FONTINFO_CTL
+        { SID_ATTR_CHAR_CJK_FONTHEIGHT, false, true }, // 
EE_CHAR_FONTHEIGHT_CJK
+        { SID_ATTR_CHAR_CTL_FONTHEIGHT, false, true }, // 
EE_CHAR_FONTHEIGHT_CTL
+        { SID_ATTR_CHAR_CJK_WEIGHT, false, true },    // EE_CHAR_WEIGHT_CJK
+        { SID_ATTR_CHAR_CTL_WEIGHT, false, true },    // EE_CHAR_WEIGHT_CTL
+        { SID_ATTR_CHAR_CJK_POSTURE, false, true },   // EE_CHAR_ITALIC_CJK
+        { SID_ATTR_CHAR_CTL_POSTURE, false, true },   // EE_CHAR_ITALIC_CTL
+        { SID_ATTR_CHAR_EMPHASISMARK, false, true },  // EE_CHAR_EMPHASISMARK
+        { SID_ATTR_CHAR_RELIEF, false, true },        // EE_CHAR_RELIEF
+        { 0, false, true },                           // EE_CHAR_RUBI_DUMMY
+        { 0, true, true },                           // EE_CHAR_XMLATTRIBS
+        { SID_ATTR_CHAR_OVERLINE, false, true },      // EE_CHAR_OVERLINE
+        { SID_ATTR_CHAR_CASEMAP, false, true },       // EE_CHAR_CASEMAP
+        { SID_ATTR_CHAR_GRABBAG, false, true },       // EE_CHAR_GRABBAG
+        { SID_ATTR_CHAR_BACK_COLOR, false, true },    // EE_CHAR_BKGCOLOR
+        { 0, false, true },                           // EE_FEATURE_TAB
+        { 0, false, true },                           // EE_FEATURE_LINEBR
+        { SID_ATTR_CHAR_CHARSETCOLOR, false, true },  // EE_FEATURE_NOTCONV
+        { SID_FIELD, true, true },                    // EE_FEATURE_FIELD
 };
 
 EditCharAttrib* MakeCharAttrib( SfxItemPool& rPool, const SfxPoolItem& rAttr, 
sal_Int32 nS, sal_Int32 nE )
 {
     // Create a new attribute in the pool
-    const SfxPoolItem& rNew = rPool.Put( rAttr );
+    const SfxPoolItem& rNew = rPool.DirectPutItemInPool( rAttr );
 
     EditCharAttrib* pNew = nullptr;
     switch( rNew.Which() )
@@ -813,7 +815,7 @@ ContentAttribsInfo::ContentAttribsInfo( SfxItemSet 
aParaAttribs ) :
 void ContentAttribsInfo::RemoveAllCharAttribsFromPool(SfxItemPool& rPool) const
 {
     for (const std::unique_ptr<EditCharAttrib>& rAttrib : aPrevCharAttribs)
-        rPool.Remove(*rAttrib->GetItem());
+        rPool.DirectRemoveItemFromPool(*rAttrib->GetItem());
 }
 
 void ContentAttribsInfo::AppendCharAttrib(EditCharAttrib* pNew)
@@ -1328,7 +1330,7 @@ void ContentNode::ExpandAttribs( sal_Int32 nIndex, 
sal_Int32 nNew, SfxItemPool&
         {
             OSL_FAIL( "Empty Attribute after ExpandAttribs?" );
             bResort = true;
-            rItemPool.Remove( *pAttrib->GetItem() );
+            rItemPool.DirectRemoveItemFromPool( *pAttrib->GetItem() );
             rAttribs.erase(rAttribs.begin()+nAttr);
         }
         else
@@ -1424,7 +1426,7 @@ void ContentNode::CollapseAttribs( sal_Int32 nIndex, 
sal_Int32 nDeleted, SfxItem
         if ( bDelAttr )
         {
             bResort = true;
-            rItemPool.Remove( *pAttrib->GetItem() );
+            rItemPool.DirectRemoveItemFromPool( *pAttrib->GetItem() );
             rAttribs.erase(rAttribs.begin()+nAttr);
         }
         else
@@ -1969,7 +1971,7 @@ void EditDoc::RemoveItemsFromPool(const ContentNode& 
rNode)
     for (sal_Int32 nAttr = 0; nAttr < rNode.GetCharAttribs().Count(); ++nAttr)
     {
         const EditCharAttrib& rAttr = 
*rNode.GetCharAttribs().GetAttribs()[nAttr];
-        GetItemPool().Remove(*rAttr.GetItem());
+        GetItemPool().DirectRemoveItemFromPool(*rAttr.GetItem());
     }
 }
 
@@ -2403,7 +2405,7 @@ void EditDoc::InsertAttribInSelection( ContentNode* 
pNode, sal_Int32 nStart, sal
     {
         // Will become a large Attribute.
         pEndingAttrib->GetEnd() = pStartingAttrib->GetEnd();
-        GetItemPool().Remove( *(pStartingAttrib->GetItem()) );
+        GetItemPool().DirectRemoveItemFromPool( *(pStartingAttrib->GetItem()) 
);
         pNode->GetCharAttribs().Remove(pStartingAttrib);
     }
     else if ( pStartingAttrib && ( *(pStartingAttrib->GetItem()) == rPoolItem 
) )
@@ -2525,7 +2527,7 @@ bool EditDoc::RemoveAttribs( ContentNode* pNode, 
sal_Int32 nStart, sal_Int32 nEn
         {
             DBG_ASSERT( ( pAttr != rpStarting ) && ( pAttr != rpEnding ), 
"Delete and retain the same attribute?" );
             DBG_ASSERT( !pAttr->IsFeature(), "RemoveAttribs: Remove a 
feature?!" );
-            GetItemPool().Remove( *pAttr->GetItem() );
+            GetItemPool().DirectRemoveItemFromPool( *pAttr->GetItem() );
             rAttribs.erase(rAttribs.begin()+nAttr);
         }
         else
@@ -2822,7 +2824,7 @@ void CharAttribList::OptimizeRanges( SfxItemPool& 
rItemPool )
                 if (*rNext.GetItem() == *rAttr.GetItem())
                 {
                     rAttr.GetEnd() = rNext.GetEnd();
-                    rItemPool.Remove(*rNext.GetItem());
+                    rItemPool.DirectRemoveItemFromPool(*rNext.GetItem());
                     aAttribs.erase(aAttribs.begin()+nNext);
                 }
                 break;  // only 1 attr with same which can start here.
@@ -2998,7 +3000,7 @@ public:
     void operator() (const std::unique_ptr<EditCharAttrib>& r)
     {
         if (r->IsEmpty())
-            mrItemPool.Remove(*r->GetItem());
+            mrItemPool.DirectRemoveItemFromPool(*r->GetItem());
     }
 };
 
diff --git a/editeng/source/editeng/editobj.cxx 
b/editeng/source/editeng/editobj.cxx
index d0ec8632f134..ba3aac6990e2 100644
--- a/editeng/source/editeng/editobj.cxx
+++ b/editeng/source/editeng/editobj.cxx
@@ -47,7 +47,7 @@ using namespace com::sun::star;
 static XEditAttribute MakeXEditAttribute( SfxItemPool& rPool, const 
SfxPoolItem& rItem, sal_Int32 nStart, sal_Int32 nEnd )
 {
     // Create the new attribute in the pool
-    const SfxPoolItem& rNew = rPool.Put( rItem );
+    const SfxPoolItem& rNew = rPool.DirectPutItemInPool( rItem );
 
     return XEditAttribute( rNew, nStart, nEnd );
 }
@@ -122,7 +122,7 @@ ContentInfo::ContentInfo( const ContentInfo& rCopyFrom, 
SfxItemPool& rPoolToUse
 ContentInfo::~ContentInfo()
 {
     for (auto const& charAttrib : maCharAttribs)
-        aParaAttribs.GetPool()->Remove(*charAttrib.GetItem());
+        
aParaAttribs.GetPool()->DirectRemoveItemFromPool(*charAttrib.GetItem());
     maCharAttribs.clear();
 }
 
@@ -381,7 +381,7 @@ XEditAttribute EditTextObjectImpl::CreateAttrib( const 
SfxPoolItem& rItem, sal_I
 
 void EditTextObjectImpl::DestroyAttrib( const XEditAttribute& rAttr )
 {
-    mpPool->Remove( *rAttr.GetItem() );
+    mpPool->DirectRemoveItemFromPool( *rAttr.GetItem() );
 }
 
 
@@ -540,7 +540,7 @@ bool EditTextObjectImpl::RemoveCharAttribs( sal_uInt16 
_nWhich )
             XEditAttribute& rAttr = rC.maCharAttribs[--nAttr];
             if ( !_nWhich || (rAttr.GetItem()->Which() == _nWhich) )
             {
-                mpPool->Remove(*rAttr.GetItem());
+                mpPool->DirectRemoveItemFromPool(*rAttr.GetItem());
                 rC.maCharAttribs.erase(rC.maCharAttribs.begin()+nAttr);
                 bChanged = true;
             }
diff --git a/editeng/source/editeng/editobj2.hxx 
b/editeng/source/editeng/editobj2.hxx
index 86c81e23f94e..8a714741ebb4 100644
--- a/editeng/source/editeng/editobj2.hxx
+++ b/editeng/source/editeng/editobj2.hxx
@@ -74,9 +74,7 @@ inline bool XEditAttribute::operator==( const XEditAttribute& 
rCompare ) const
 {
     return  (nStart == rCompare.nStart) &&
             (nEnd == rCompare.nEnd) &&
-            ((pItem == rCompare.pItem) ||
-             ((pItem->Which() == rCompare.pItem->Which()) &&
-              (*pItem == *rCompare.pItem)));
+            SfxPoolItem::areSame(pItem, rCompare.pItem);
 }
 
 struct XParaPortion
diff --git a/editeng/source/editeng/fieldupdater.cxx 
b/editeng/source/editeng/fieldupdater.cxx
index 41d9be7aeee7..008793a04ffd 100644
--- a/editeng/source/editeng/fieldupdater.cxx
+++ b/editeng/source/editeng/fieldupdater.cxx
@@ -47,7 +47,7 @@ public:
                 // Create a new table field with the new ID, and set it to the
                 // attribute object.
                 SvxFieldItem aNewItem(SvxTableField(nTab), EE_FEATURE_FIELD);
-                rAttr.SetItem(pPool->Put(aNewItem));
+                rAttr.SetItem(pPool->DirectPutItemInPool(aNewItem));
             }
         }
     }
diff --git a/editeng/source/items/textitem.cxx 
b/editeng/source/items/textitem.cxx
index cac394c119c4..e242566bd36f 100644
--- a/editeng/source/items/textitem.cxx
+++ b/editeng/source/items/textitem.cxx
@@ -159,24 +159,6 @@ bool SvxFontListItem::GetPresentation
 
 // class SvxFontItem -----------------------------------------------------
 
-namespace
-{
-sal_Int32 CompareTo(sal_Int32 nA, sal_Int32 nB)
-{
-    if (nA < nB)
-    {
-        return -1;
-    }
-
-    if (nA > nB)
-    {
-        return 1;
-    }
-
-    return 0;
-}
-}
-
 SvxFontItem::SvxFontItem( const sal_uInt16 nId ) :
     SfxPoolItem( nId )
 {
@@ -314,36 +296,6 @@ bool SvxFontItem::operator==( const SfxPoolItem& rAttr ) 
const
     return bRet;
 }
 
-bool SvxFontItem::operator<(const SfxPoolItem& rCmp) const
-{
-    const auto& rOther = static_cast<const SvxFontItem&>(rCmp);
-    sal_Int32 nRet = GetFamilyName().compareTo(rOther.GetFamilyName());
-    if (nRet != 0)
-    {
-        return nRet < 0;
-    }
-
-    nRet = GetStyleName().compareTo(rOther.GetStyleName());
-    if (nRet != 0)
-    {
-        return nRet < 0;
-    }
-
-    nRet = CompareTo(GetFamily(), rOther.GetFamily());
-    if (nRet != 0)
-    {
-        return nRet < 0;
-    }
-
-    nRet = CompareTo(GetPitch(), rOther.GetPitch());
-    if (nRet != 0)
-    {
-        return nRet < 0;
-    }
-
-    return GetCharSet() < rOther.GetCharSet();
-}
-
 SvxFontItem* SvxFontItem::Clone( SfxItemPool * ) const
 {
     return new SvxFontItem( *this );
diff --git a/extensions/source/propctrlr/fontdialog.cxx 
b/extensions/source/propctrlr/fontdialog.cxx
index 1a101876ffda..59757421a06e 100644
--- a/extensions/source/propctrlr/fontdialog.cxx
+++ b/extensions/source/propctrlr/fontdialog.cxx
@@ -532,26 +532,27 @@ namespace pcr
         // create the pool
         static SfxItemInfo const aItemInfos[FontItemIds::CFID_LAST_ITEM_ID - 
FontItemIds::CFID_FIRST_ITEM_ID + 1] =
         {
-            { SID_ATTR_CHAR_FONT,               false },
-            { SID_ATTR_CHAR_FONTHEIGHT,         false },
-            { SID_ATTR_CHAR_WEIGHT,             false },
-            { SID_ATTR_CHAR_POSTURE,            false },
-            { SID_ATTR_CHAR_LANGUAGE,           false },
-            { SID_ATTR_CHAR_UNDERLINE,          false },
-            { SID_ATTR_CHAR_STRIKEOUT,          false },
-            { SID_ATTR_CHAR_WORDLINEMODE,       false },
-            { SID_ATTR_CHAR_COLOR,              false },
-            { SID_ATTR_CHAR_RELIEF,             false },
-            { SID_ATTR_CHAR_EMPHASISMARK,       false },
-            { 0,                                false },
-            { 0,                                false },
-            { 0,                                false },
-            { 0,                                false },
-            { 0,                                false },
-            { 0,                                false },
-            { 0,                                false },
-            { 0,                                false },
-            { SID_ATTR_CHAR_FONTLIST,           false }
+            // _nSID, _bNeedsPoolRegistration, _bShareable
+            { SID_ATTR_CHAR_FONT,               false, false },
+            { SID_ATTR_CHAR_FONTHEIGHT,         false, false },
+            { SID_ATTR_CHAR_WEIGHT,             false, false },
+            { SID_ATTR_CHAR_POSTURE,            false, false },
+            { SID_ATTR_CHAR_LANGUAGE,           false, false },
+            { SID_ATTR_CHAR_UNDERLINE,          false, false },
+            { SID_ATTR_CHAR_STRIKEOUT,          false, false },
+            { SID_ATTR_CHAR_WORDLINEMODE,       false, false },
+            { SID_ATTR_CHAR_COLOR,              false, false },
+            { SID_ATTR_CHAR_RELIEF,             false, false },
+            { SID_ATTR_CHAR_EMPHASISMARK,       false, false },
+            { 0,                                false, false },
+            { 0,                                false, false },
+            { 0,                                false, false },
+            { 0,                                false, false },
+            { 0,                                false, false },
+            { 0,                                false, false },
+            { 0,                                false, false },
+            { 0,                                false, false },
+            { SID_ATTR_CHAR_FONTLIST,           false, false }
         };
 
         _rpPool = new SfxItemPool("PCRControlFontItemPool", 
FontItemIds::CFID_FIRST_ITEM_ID, FontItemIds::CFID_LAST_ITEM_ID,
diff --git a/include/editeng/fontitem.hxx b/include/editeng/fontitem.hxx
index deabf3101f44..7cab5f462e4e 100644
--- a/include/editeng/fontitem.hxx
+++ b/include/editeng/fontitem.hxx
@@ -46,7 +46,6 @@ public:
 
     // "pure virtual Methods" from SfxPoolItem
     virtual bool operator==(const SfxPoolItem& rItem) const override;
-    bool operator<(const SfxPoolItem& rCmp) const override;
     virtual SvxFontItem* Clone(SfxItemPool *pPool = nullptr) const override;
     virtual bool QueryValue(css::uno::Any& rVal, sal_uInt8 nMemberId = 0) 
const override;
     virtual bool PutValue(const css::uno::Any& rVal, sal_uInt8 nMemberId) 
override;
diff --git a/include/editeng/wghtitem.hxx b/include/editeng/wghtitem.hxx
index 6f5f4b31ccc3..121cfcf318a6 100644
--- a/include/editeng/wghtitem.hxx
+++ b/include/editeng/wghtitem.hxx
@@ -59,14 +59,6 @@ public:
     FontWeight              GetWeight() const { return GetValue(); }
 
     void dumpAsXml(xmlTextWriterPtr pWriter) const override;
-
-    virtual bool IsSortable() const override { return true; }
-
-    virtual bool operator<(const SfxPoolItem& rCmp) const override
-    {
-        auto const & other = static_cast<const SvxWeightItem&>(rCmp);
-        return GetValue() < other.GetValue();
-    }
 };
 
 #endif // INCLUDED_EDITENG_WGHTITEM_HXX
diff --git a/include/sal/log-areas.dox b/include/sal/log-areas.dox
index 8e6d5d81f1ae..0b3907e08610 100644
--- a/include/sal/log-areas.dox
+++ b/include/sal/log-areas.dox
@@ -499,6 +499,7 @@ certain functionality.
 @li @c vcl.helper
 @li @c vcl.icontest
 @li @c vcl.ios.clipboard
+@li @c vcl.items
 @li @c vcl.kf5 - KF5
 @li @c vcl.layout - Widget layout
 @li @c vcl.lazydelete
diff --git a/include/svl/custritm.hxx b/include/svl/custritm.hxx
index 90215aff45d3..3159c41dfc96 100644
--- a/include/svl/custritm.hxx
+++ b/include/svl/custritm.hxx
@@ -39,8 +39,6 @@ public:
     {}
 
     virtual bool operator ==(const SfxPoolItem & rItem) const override;
-    virtual bool operator <(const SfxPoolItem & rItem) const override;
-    virtual bool IsSortable() const override { return true; }
 
     virtual bool GetPresentation(SfxItemPresentation,
                                  MapUnit, MapUnit,
diff --git a/include/svl/itempool.hxx b/include/svl/itempool.hxx
index e85451ecb738..8dfac4766ffb 100644
--- a/include/svl/itempool.hxx
+++ b/include/svl/itempool.hxx
@@ -26,6 +26,7 @@
 #include <svl/whichranges.hxx>
 #include <memory>
 #include <vector>
+#include <unordered_set>
 #include <o3tl/sorted_vector.hxx>
 #include <salhelper/simplereferenceobject.hxx>
 
@@ -34,11 +35,30 @@ struct SfxItemPool_Impl;
 
 struct SfxItemInfo
 {
+    // Defines a mapping between WhichID <-> SlotID
     sal_uInt16       _nSID;
-    bool            _bPoolable;
+
+    // Defines if this Item needs to be registered at the pool
+    // to make it accessible for the GetItemSurrogates call. It
+    // will not be included when this flag is not set, but also
+    // needs no registration. There are SAL_INFO calls in the
+    // GetItemSurrogates impl that will mention that
+    bool             _bNeedsPoolRegistration : 1;
+
+    // Defines if the Item can be shared/RefCounted else it will be cloned.
+    // Default is true - as it should be for all Items. It is needed by some
+    // SW items, so protected to let them set it in constructor. If this could
+    // be fixed at that Items we may remove this again.
+    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
 
 /** Base class for providers of defaults of SfxPoolItems.
  *
@@ -53,14 +73,26 @@ class SVL_DLLPUBLIC SfxItemPool : public 
salhelper::SimpleReferenceObject
     friend class SfxItemSet;
     friend class SfxAllItemSet;
 
+    // allow ItemSetTooling to access
+    friend SfxPoolItem const* implCreateItemEntry(SfxItemPool&, SfxPoolItem 
const*, sal_uInt16, bool, bool);
+    friend void implCleanupItemEntry(SfxItemPool&, SfxPoolItem const*);
+
+    // unit testing
+    friend class PoolItemTest;
+
     const SfxItemInfo*              pItemInfos;
     std::unique_ptr<SfxItemPool_Impl>               pImpl;
 
+    registeredSfxPoolItems** ppRegisteredSfxPoolItems;
+
 private:
     sal_uInt16                      GetIndex_Impl(sal_uInt16 nWhich) const;
     sal_uInt16                      GetSize_Impl() const;
 
-    SVL_DLLPRIVATE bool             IsItemPoolable_Impl( sal_uInt16 nWhich ) 
const;
+    SVL_DLLPRIVATE bool             NeedsPoolRegistration_Impl(sal_uInt16 
nPos) const
+    { return pItemInfos[nPos]._bNeedsPoolRegistration; }
+    SVL_DLLPRIVATE bool             Shareable_Impl(sal_uInt16 nPos) const
+    { return pItemInfos[nPos]._bShareable; }
 
 public:
     // for default SfxItemSet::CTOR, set default WhichRanges
@@ -135,18 +167,16 @@ public:
     virtual rtl::Reference<SfxItemPool> Clone() const;
     const OUString&                 GetName() const;
 
-    template<class T> const T&      Put( std::unique_ptr<T> xItem, sal_uInt16 
nWhich = 0 )
-    { return static_cast<const T&>(PutImpl( *xItem.release(), nWhich, 
/*bPassingOwnership*/true)); }
-    template<class T> const T&      Put( const T& rItem, sal_uInt16 nWhich = 0 
)
-    { return static_cast<const T&>(PutImpl( rItem, nWhich, 
/*bPassingOwnership*/false)); }
-    void                            Remove( const SfxPoolItem& );
+    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&              GetDefaultItem( sal_uInt16 nWhich ) const;
     template<class T> const T&      GetDefaultItem( TypedWhichId<T> nWhich ) 
const
     { return static_cast<const T&>(GetDefaultItem(sal_uInt16(nWhich))); }
 
-    bool                            CheckItemInPool(const SfxPoolItem *) const;
-
     struct Item2Range
     {
         o3tl::sorted_vector<SfxPoolItem*>::const_iterator m_begin;
@@ -158,8 +188,7 @@ public:
     template<class T> const T*      GetItem2Default( TypedWhichId<T> nWhich ) 
const
     { return static_cast<const T*>(GetItem2Default(sal_uInt16(nWhich))); }
 
-    sal_uInt32                      GetItemCount2(sal_uInt16 nWhich) const;
-    Item2Range                      GetItemSurrogates(sal_uInt16 nWhich) const;
+    const registeredSfxPoolItems&   GetItemSurrogates(sal_uInt16 nWhich) const;
     /*
         This is only valid for SfxPoolItem that override IsSortable and 
operator<.
         Returns a range of items defined by using operator<.
@@ -179,9 +208,14 @@ public:
 
     void                            Delete();
 
-    bool                            IsItemPoolable( sal_uInt16 nWhich ) const;
-    bool                            IsItemPoolable( const SfxPoolItem &rItem ) 
const
-                                    { return IsItemPoolable( rItem.Which() ); }
+    bool                            NeedsPoolRegistration(sal_uInt16 nWhich) 
const;
+    bool                            NeedsPoolRegistration(const SfxPoolItem 
&rItem) const
+                                    { return 
NeedsPoolRegistration(rItem.Which()); }
+
+    bool                            Shareable(sal_uInt16 nWhich) const;
+    bool                            Shareable(const SfxPoolItem &rItem) const
+                                    { return Shareable(rItem.Which()); }
+
     void                            SetItemInfos( const SfxItemInfo *pInfos );
     sal_uInt16                      GetWhich( sal_uInt16 nSlot, bool bDeep = 
true ) const;
     template<class T>
@@ -196,10 +230,34 @@ public:
     static bool                     IsSlot(sal_uInt16 nId) {
                                         return nId && nId > SFX_WHICH_MAX; }
 
+    // this method tries to register an Item at this Pool. If this
+    // is done depends on the SfxItemInfo-flag _bNeedsPoolRegistration
+    // which needs to be set for Items that are acessed using
+    // GetItemSurrogates, else the Item will not be returned/accessed
+    void tryRegisterSfxPoolItem(const SfxPoolItem& rItem, bool bPoolDirect);
+
+    // this method will register the Item at this Pool, no matter what.
+    // It is needed for all calls that directly register Items at the
+    // Pool, so the DirectPutItemInPool-methods
+    void doRegisterSfxPoolItem(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:
-    virtual const SfxPoolItem&      PutImpl( const SfxPoolItem&, sal_uInt16 
nWhich = 0, bool bPassingOwnership = false );
+    const SfxPoolItem&      DirectPutItemInPoolImpl( const SfxPoolItem&, 
sal_uInt16 nWhich = 0, bool bPassingOwnership = false );
+    virtual void newItem_Callback(const SfxPoolItem& rItem) const;
+    virtual bool newItem_UseDirect(const SfxPoolItem& rItem) const;
+
 private:
     const SfxItemPool&              operator=(const SfxItemPool &) = delete;
 
diff --git a/include/svl/itemset.hxx b/include/svl/itemset.hxx
index 01d9d5058b14..06e82b87e054 100644
--- a/include/svl/itemset.hxx
+++ b/include/svl/itemset.hxx
@@ -36,11 +36,19 @@ SVL_DLLPUBLIC size_t getAllocatedSfxItemSetCount();
 SVL_DLLPUBLIC size_t getUsedSfxItemSetCount();
 #endif
 
+// ItemSet/ItemPool helpers
+SfxPoolItem const* implCreateItemEntry(SfxItemPool& rPool, SfxPoolItem const* 
pSource, sal_uInt16 nWhich, bool bPassingOwnership, bool bPoolDirect);
+void implCleanupItemEntry(SfxItemPool& rPool, SfxPoolItem const* pSource);
+
 class SAL_WARN_UNUSED SVL_DLLPUBLIC SfxItemSet
 {
     friend class SfxItemIter;
     friend class SfxWhichIter;
 
+    // allow ItemSetTooling to access
+    friend SfxPoolItem const* implCreateItemEntry(SfxItemPool&, SfxPoolItem 
const*, sal_uInt16, bool, bool);
+    friend void implCleanupItemEntry(SfxItemPool&, SfxPoolItem const*);
+
     SfxItemPool*      m_pPool;         ///< pool that stores the items
     const SfxItemSet* m_pParent;       ///< derivation
     sal_uInt16        m_nCount;        ///< number of items
@@ -88,7 +96,7 @@ private:
     const SfxItemSet&           operator=(const SfxItemSet &) = delete;
 
 protected:
-    virtual const SfxPoolItem*  PutImpl( const SfxPoolItem&, sal_uInt16 
nWhich, bool bItemIsSetMember, bool bPassingOwnership );
+    virtual const SfxPoolItem*  PutImpl( const SfxPoolItem&, sal_uInt16 
nWhich, bool bPassingOwnership );
 
     /** special constructor for SfxAllItemSet */
     enum class SfxAllItemSetFlag { Flag };
@@ -207,9 +215,9 @@ public:
     // add, delete items, work on items
 public:
     const SfxPoolItem*          Put( const SfxPoolItem& rItem, sal_uInt16 
nWhich )
-    { return PutImpl(rItem, nWhich, /*bItemIsSetMember*/false, 
/*bPassingOwnership*/false); }
+    { return PutImpl(rItem, nWhich, /*bPassingOwnership*/false); }
     const SfxPoolItem*          Put( std::unique_ptr<SfxPoolItem> xItem, 
sal_uInt16 nWhich )
-    { return PutImpl(*xItem.release(), nWhich, /*bItemIsSetMember*/false, 
/*bPassingOwnership*/true); }
+    { return PutImpl(*xItem.release(), nWhich, /*bPassingOwnership*/true); }
     const SfxPoolItem*          Put( const SfxPoolItem& rItem )
                                 { return Put(rItem, rItem.Which()); }
     const SfxPoolItem*          Put( std::unique_ptr<SfxPoolItem> xItem )
@@ -261,7 +269,7 @@ private:
     sal_uInt16 ClearAllItemsImpl();
 
     // Merge two given Item(entries)
-    void MergeItem_Impl(const SfxPoolItem **ppFnd1, const SfxPoolItem *pFnd2, 
bool bItemIsSetMember, bool bIgnoreDefaults);
+    void MergeItem_Impl(const SfxPoolItem **ppFnd1, const SfxPoolItem *pFnd2, 
bool bIgnoreDefaults);
 
     // split version(s) of InvalidateItem for input types WhichID and Offset
     void InvalidateItem_ForWhichID(sal_uInt16 nWhich);
@@ -270,9 +278,6 @@ private:
     // split version(s) of GetItemStateImpl for input types WhichID and Offset
     SfxItemState GetItemState_ForWhichID( SfxItemState eState, sal_uInt16 
nWhich, bool bSrchInParent, const SfxPoolItem **ppItem) const;
     SfxItemState GetItemState_ForOffset( sal_uInt16 nOffset, const SfxPoolItem 
**ppItem) const;
-
-    SfxPoolItem const* implCreateItemEntry(SfxPoolItem const* pSource, 
sal_uInt16 nWhich, bool bItemIsSetMember, bool bPassingOwnership);
-    void implCleanupItemEntry(SfxPoolItem const* pSource);
 };
 
 inline void SfxItemSet::SetParent( const SfxItemSet* pNew )
@@ -292,7 +297,7 @@ public:
 
     virtual std::unique_ptr<SfxItemSet> Clone( bool bItems = true, SfxItemPool 
*pToPool = nullptr ) const override;
 private:
-    virtual const SfxPoolItem*  PutImpl( const SfxPoolItem&, sal_uInt16 
nWhich, bool bItemIsSetMember,bool bPassingOwnership ) override;
+    virtual const SfxPoolItem*  PutImpl( const SfxPoolItem&, sal_uInt16 
nWhich, bool bPassingOwnership ) override;
 };
 
 
diff --git a/include/svl/poolitem.hxx b/include/svl/poolitem.hxx
index 4714e2f44be6..b434302a2f85 100644
--- a/include/svl/poolitem.hxx
+++ b/include/svl/poolitem.hxx
@@ -100,6 +100,7 @@ enum class SfxItemState {
 #ifdef DBG_UTIL
 SVL_DLLPUBLIC size_t getAllocatedSfxPoolItemCount();
 SVL_DLLPUBLIC size_t getUsedSfxPoolItemCount();
+SVL_DLLPUBLIC void listAllocatedSfxPoolItems();
 #endif
 
 class SfxItemPool;
@@ -108,31 +109,40 @@ typedef struct _xmlTextWriter* xmlTextWriterPtr;
 
 class SVL_DLLPUBLIC SfxPoolItem
 {
-friend class SfxItemPool;
-friend class SfxItemDisruptor_Impl;
-friend class SfxItemPoolCache;
-friend class SfxItemSet;
+    friend class SfxItemPool;
+    friend class SfxItemDisruptor_Impl;
+    friend class SfxItemPoolCache;
+    friend class SfxItemSet;
+
+    // allow ItemSetTooling to access
+    friend SfxPoolItem const* implCreateItemEntry(SfxItemPool&, SfxPoolItem 
const*, sal_uInt16, bool, bool);
+    friend void implCleanupItemEntry(SfxItemPool&, SfxPoolItem const*);
 
     mutable sal_uInt32 m_nRefCount;
     sal_uInt16  m_nWhich;
 
+#ifdef DBG_UTIL
+    // for debugging add a serial number, will be set in the constructor
+    // and count up from zero. If you have a deterministic error case and
+    // see the Item involved in the debugger you can  use that number in
+    // the next run to see where that Item gets constructed and how it is
+    // involved/ processed
+    sal_uInt32  m_nSerialNumber;
+#endif
+
     // bitfield for flags (instead of SfxItemKind)
-    bool        m_bIsVoidItem : 1;
-    bool        m_bDeleteOnIdle : 1;
-    bool        m_bStaticDefault : 1;
-    bool        m_bPoolDefault : 1;
+    bool        m_bIsVoidItem : 1;          // bit 0
+    bool        m_bDeleteOnIdle : 1;        // bit 1
+    bool        m_bStaticDefault : 1;       // bit 2
+    bool        m_bPoolDefault : 1;         // bit 3
+    bool        m_bRegisteredAtPool : 1;    // bit 4
+    bool        m_bNewItemCallback : 1;     // bit 5
+    bool        m_bIsSetItem : 1;           // bit 6
 
 protected:
-    // Defines if the Item can be shared/RefCounted else it will be cloned.
-    // Default is true - as it should be for all Items. It is needed by some
-    // SW items, so protected to let them set it in constructor. If this could
-    // be fixed at that Items we may remove this again.
-    bool        m_bShareable : 1;
-
-private:
 #ifdef DBG_UTIL
     // this flag will make debugging item stuff much simpler
-    bool        m_bDeleted : 1;
+    bool        m_bDeleted : 1;             // bit 7
 #endif
 
 private:
@@ -143,10 +153,13 @@ private:
     }
 
 protected:
-    void setVoidItem() { m_bIsVoidItem = true; }
+    void setIsVoidItem() { m_bIsVoidItem = true; }
     void setDeleteOnIdle() { m_bDeleteOnIdle = true; }
     void setStaticDefault() { m_bStaticDefault = true; }
     void setPoolDefault() { m_bPoolDefault = true; }
+    void setRegisteredAtPool(bool bNew) { m_bRegisteredAtPool = bNew; }
+    void setNewItemCallback() { m_bNewItemCallback = true; }
+    void setIsSetItem() { m_bIsSetItem = true; }
 
 public:
     inline void AddRef(sal_uInt32 n = 1) const
@@ -156,11 +169,23 @@ public:
         m_nRefCount += n;
     }
 
+#ifdef DBG_UTIL
+    sal_uInt32 getSerialNumber() const { return m_nSerialNumber; }
+#endif
+
     bool isVoidItem() const { return m_bIsVoidItem; }
     bool isDeleteOnIdle() const { return m_bDeleteOnIdle; }
     bool isStaticDefault() const { return m_bStaticDefault; }
     bool isPoolDefault() const { return m_bPoolDefault; }
-    bool isShareable() const { return m_bShareable; }
+    bool isRegisteredAtPool() const { return m_bRegisteredAtPool; }
+    bool isNewItemCallback() const { return m_bNewItemCallback; }
+    bool isSetItem() const { return m_bIsSetItem; }
+
+    // version that allows nullptrs
+    static bool areSame(const SfxPoolItem* pItem1, const SfxPoolItem* pItem2);
+
+    // if you have the items (not nullptrs) use this version
+    static bool areSame(const SfxPoolItem& rItem1, const SfxPoolItem& rItem2);
 
 private:
     inline sal_uInt32 ReleaseRef(sal_uInt32 n = 1) const
@@ -223,24 +248,6 @@ public:
     bool                     operator!=( const SfxPoolItem& rItem ) const
                              { return !(*this == rItem); }
 
-    // Sorting is only used for faster searching in a pool which contains 
large quantities
-    // of a single kind of pool item.
-    virtual bool             operator<( const SfxPoolItem& ) const { 
assert(false); return false; }
-    virtual bool             IsSortable() const { return false; }
-
-    // Some item types cannot be IsSortable() (such as because they are 
modified while stored
-    // in a pool, which would change the ordering position, see e.g. 
585e0ac43b9bd8a2f714903034).
-    // To improve performance in such cases it is possible to reimplement 
Lookup() to do a linear
-    // lookup optimized for the specific class (avoiding virtual functions may 
allow the compiler
-    // to generate better code and class-specific optimizations such as 
hashing or caching may
-    // be used.)
-    // If reimplemented, the Lookup() function should search [begin,end) for 
an item matching
-    // this object and return an iterator pointing to the item or the end 
iterator.
-    virtual bool             HasLookup() const { return false; }
-    typedef std::vector<SfxPoolItem*>::const_iterator lookup_iterator;
-    virtual lookup_iterator  Lookup(lookup_iterator /*begin*/, lookup_iterator 
end ) const
-                             { assert( false ); return end; }
-
     /**  @return true if it has a valid string representation */
     virtual bool             GetPresentation( SfxItemPresentation 
ePresentation,
                                     MapUnit eCoreMetric,
@@ -299,6 +306,8 @@ inline bool IsInvalidItem(const SfxPoolItem *pItem)
     return pItem == INVALID_POOL_ITEM;
 }
 
+SVL_DLLPUBLIC bool areSfxPoolItemPtrsEqual(const SfxPoolItem* pItem1, const 
SfxPoolItem* pItem2);
+
 class SVL_DLLPUBLIC SfxPoolItemHint final : public SfxHint
 {
     SfxPoolItem* pObj;
diff --git a/include/svx/pageitem.hxx b/include/svx/pageitem.hxx
index 32702fe8089f..de93730731d2 100644
--- a/include/svx/pageitem.hxx
+++ b/include/svx/pageitem.hxx
@@ -98,7 +98,7 @@ class SVX_DLLPUBLIC SvxSetItem final : public SfxSetItem
 {
 public:
     SvxSetItem( const TypedWhichId<SvxSetItem> nId, const SfxItemSet& rSet );
-    SvxSetItem( const SvxSetItem& rItem );
+    SvxSetItem( const SvxSetItem& rItem, SfxItemPool* pPool = nullptr );
     SvxSetItem( const TypedWhichId<SvxSetItem> nId, SfxItemSet&& pSet );
 
     virtual SvxSetItem* Clone( SfxItemPool *pPool = nullptr ) const override;
diff --git a/include/svx/sdasitm.hxx b/include/svx/sdasitm.hxx
index e53e9c3604a2..cb7230afe703 100644
--- a/include/svx/sdasitm.hxx
+++ b/include/svx/sdasitm.hxx
@@ -70,8 +70,6 @@ private:
             SdrCustomShapeGeometryItem & operator =(SdrCustomShapeGeometryItem 
&&) = delete; // due to SfxPoolItem
 
             virtual bool                operator==( const SfxPoolItem& ) const 
override;
-            virtual bool                operator<( const SfxPoolItem& ) const 
override;
-            virtual bool                IsSortable() const override { return 
true; }
 
             virtual bool GetPresentation(SfxItemPresentation ePresentation,
                                          MapUnit eCoreMetric, MapUnit 
ePresentationMetric,
diff --git a/include/svx/xbtmpit.hxx b/include/svx/xbtmpit.hxx
index 0882081fb7ca..6d7d75f3de7c 100644
--- a/include/svx/xbtmpit.hxx
+++ b/include/svx/xbtmpit.hxx
@@ -41,8 +41,6 @@ public:
             XFillBitmapItem( const XFillBitmapItem& rItem );
 
     virtual bool            operator==( const SfxPoolItem& rItem ) const 
override;
-    // no idea why, but this item does not play nice with the sorting 
optimisation, get failures in sd_import_tests
-    virtual bool            IsSortable() const override { return false; }
     virtual XFillBitmapItem* Clone( SfxItemPool* pPool = nullptr ) const 
override;
 
     virtual bool            QueryValue( css::uno::Any& rVal, sal_uInt8 
nMemberId = 0 ) const override;
diff --git a/reportdesign/source/ui/misc/UITools.cxx 
b/reportdesign/source/ui/misc/UITools.cxx
index 8d32c4ec1a2b..9ac14c4bc10e 100644
--- a/reportdesign/source/ui/misc/UITools.cxx
+++ b/reportdesign/source/ui/misc/UITools.cxx
@@ -559,67 +559,68 @@ bool openCharDialog( const 
uno::Reference<report::XReportControlFormat >& _rxRep
     // UNO->ItemSet
     static SfxItemInfo aItemInfos[] =
     {
-        { 0,      true }, // XATTR_FILLSTYLE
-        { 0,      true }, // XATTR_FILLCOLOR
-        { 0,       true }, // XATTR_FILLGRADIENT
-        { 0,      true }, // XATTR_FILLHATCH
-        { 0,     true }, // XATTR_FILLBITMAP
-        { 0,       true }, // XATTR_FILLTRANSPARENCE
-        { 0,      true }, // XATTR_GRADIENTSTEPCOUNT
-        { 0,       true }, // XATTR_FILLBMP_TILE
-        { 0,        true }, // XATTR_FILLBMP_POS
-        { 0,      true }, // XATTR_FILLBMP_SIZEX
-        { 0,      true }, // XATTR_FILLBMP_SIZEY
-        { 0,  true }, // XATTR_FILLFLOATTRANSPARENCE
-        { 0,     true }, // XATTR_SECONDARYFILLCOLOR
-        { 0,        true }, // XATTR_FILLBMP_SIZELOG
-        { 0,    true }, // XATTR_FILLBMP_TILEOFFSETX
-        { 0,    true }, // XATTR_FILLBMP_TILEOFFSETY
-        { 0,        true }, // XATTR_FILLBMP_STRETCH
-        { 0,     true }, // XATTR_FILLBMP_POSOFFSETX
-        { 0,     true }, // XATTR_FILLBMP_POSOFFSETY
-        { 0,     true }, // XATTR_FILLBACKGROUND
-
-        { SID_ATTR_CHAR_FONT, true },
-        { SID_ATTR_CHAR_FONTHEIGHT, true },
-        { SID_ATTR_CHAR_LANGUAGE, true },
-        { SID_ATTR_CHAR_POSTURE, true },
-        { SID_ATTR_CHAR_WEIGHT, true },
-        { SID_ATTR_CHAR_SHADOWED, true },
-        { SID_ATTR_CHAR_WORDLINEMODE, true },
-        { SID_ATTR_CHAR_CONTOUR, true },
-        { SID_ATTR_CHAR_STRIKEOUT, true },
-        { SID_ATTR_CHAR_UNDERLINE, true },
-        { SID_ATTR_CHAR_COLOR, true },
-        { SID_ATTR_CHAR_KERNING, true },
-        { SID_ATTR_CHAR_CASEMAP, true },
-        { SID_ATTR_CHAR_ESCAPEMENT, true },
-        { SID_ATTR_CHAR_FONTLIST, true },
-        { SID_ATTR_CHAR_AUTOKERN, true },
-        { SID_COLOR_TABLE, true },
-        { SID_ATTR_FLASH, true },
-        { SID_ATTR_CHAR_EMPHASISMARK, true },
-        { SID_ATTR_CHAR_TWO_LINES, true },
-        { SID_ATTR_CHAR_ROTATED, true },
-        { SID_ATTR_CHAR_SCALEWIDTH, true },
-        { SID_ATTR_CHAR_RELIEF, true },
-        { SID_ATTR_CHAR_HIDDEN, true },
-        { SID_ATTR_BRUSH, true },
-        { SID_ATTR_ALIGN_HOR_JUSTIFY, true },
-        { SID_ATTR_ALIGN_VER_JUSTIFY, true },
+        // _nSID, _bNeedsPoolRegistration, _bShareable
+        { 0, false, true }, // XATTR_FILLSTYLE
+        { 0, true,  true }, // XATTR_FILLCOLOR
+        { 0, false, true }, // XATTR_FILLGRADIENT
+        { 0, false, true }, // XATTR_FILLHATCH
+        { 0, false, true }, // XATTR_FILLBITMAP
+        { 0, false, true }, // XATTR_FILLTRANSPARENCE
+        { 0, false, true }, // XATTR_GRADIENTSTEPCOUNT
+        { 0, false, true }, // XATTR_FILLBMP_TILE
+        { 0, false, true }, // XATTR_FILLBMP_POS
+        { 0, false, true }, // XATTR_FILLBMP_SIZEX
+        { 0, false, true }, // XATTR_FILLBMP_SIZEY
+        { 0, false, true }, // XATTR_FILLFLOATTRANSPARENCE
+        { 0, false, true }, // XATTR_SECONDARYFILLCOLOR
+        { 0, false, true }, // XATTR_FILLBMP_SIZELOG
+        { 0, false, true }, // XATTR_FILLBMP_TILEOFFSETX
+        { 0, false, true }, // XATTR_FILLBMP_TILEOFFSETY
+        { 0, false, true }, // XATTR_FILLBMP_STRETCH
+        { 0, false, true }, // XATTR_FILLBMP_POSOFFSETX
+        { 0, false, true }, // XATTR_FILLBMP_POSOFFSETY
+        { 0, false, true }, // XATTR_FILLBACKGROUND
+
+        { SID_ATTR_CHAR_FONT,           false, true },
+        { SID_ATTR_CHAR_FONTHEIGHT,     false, true },
+        { SID_ATTR_CHAR_LANGUAGE,       false, true },
+        { SID_ATTR_CHAR_POSTURE,        false, true },
+        { SID_ATTR_CHAR_WEIGHT,         false, true },
+        { SID_ATTR_CHAR_SHADOWED,       false, true },
+        { SID_ATTR_CHAR_WORDLINEMODE,   false, true },
+        { SID_ATTR_CHAR_CONTOUR,        false, true },
+        { SID_ATTR_CHAR_STRIKEOUT,      false, true },
+        { SID_ATTR_CHAR_UNDERLINE,      false, true },
+        { SID_ATTR_CHAR_COLOR,          false, true },
+        { SID_ATTR_CHAR_KERNING,        false, true },
+        { SID_ATTR_CHAR_CASEMAP,        false, true },
+        { SID_ATTR_CHAR_ESCAPEMENT,     false, true },
+        { SID_ATTR_CHAR_FONTLIST,       false, true },
+        { SID_ATTR_CHAR_AUTOKERN,       false, true },
+        { SID_COLOR_TABLE,              false, true },
+        { SID_ATTR_FLASH,               false, true },
+        { SID_ATTR_CHAR_EMPHASISMARK,   false, true },
+        { SID_ATTR_CHAR_TWO_LINES,      false, true },
+        { SID_ATTR_CHAR_ROTATED,        false, true },
+        { SID_ATTR_CHAR_SCALEWIDTH,     false, true },
+        { SID_ATTR_CHAR_RELIEF,         false, true },
+        { SID_ATTR_CHAR_HIDDEN,         false, true },
+        { SID_ATTR_BRUSH,               false, true },
+        { SID_ATTR_ALIGN_HOR_JUSTIFY,   false, true },
+        { SID_ATTR_ALIGN_VER_JUSTIFY,   false, true },
 
         // Asian
-        { SID_ATTR_CHAR_CJK_FONT, true },
-        { SID_ATTR_CHAR_CJK_FONTHEIGHT, true },
-        { SID_ATTR_CHAR_CJK_LANGUAGE, true },
-        { SID_ATTR_CHAR_CJK_POSTURE, true },
-        { SID_ATTR_CHAR_CJK_WEIGHT, true },
+        { SID_ATTR_CHAR_CJK_FONT,       false, true },
+        { SID_ATTR_CHAR_CJK_FONTHEIGHT, false, true },
+        { SID_ATTR_CHAR_CJK_LANGUAGE,   false, true },
+        { SID_ATTR_CHAR_CJK_POSTURE,    false, true },
+        { SID_ATTR_CHAR_CJK_WEIGHT,     false, true },
         // Complex
-        { SID_ATTR_CHAR_CTL_FONT, true },
-        { SID_ATTR_CHAR_CTL_FONTHEIGHT, true },
-        { SID_ATTR_CHAR_CTL_LANGUAGE, true },
-        { SID_ATTR_CHAR_CTL_POSTURE, true },
-        { SID_ATTR_CHAR_CTL_WEIGHT, true }
+        { SID_ATTR_CHAR_CTL_FONT,       false, true },
+        { SID_ATTR_CHAR_CTL_FONTHEIGHT, false, true },
+        { SID_ATTR_CHAR_CTL_LANGUAGE,   false, true },
+        { SID_ATTR_CHAR_CTL_POSTURE,    false, true },
+        { SID_ATTR_CHAR_CTL_WEIGHT,     false, true }
     };
     FontList aFontList(Application::GetDefaultDevice());
     XColorListRef pColorList( XColorList::CreateStdColorList() );
diff --git a/reportdesign/source/ui/report/ReportController.cxx 
b/reportdesign/source/ui/report/ReportController.cxx
index 69929a2d1656..351d28fc9e71 100644
--- a/reportdesign/source/ui/report/ReportController.cxx
+++ b/reportdesign/source/ui/report/ReportController.cxx
@@ -2331,35 +2331,36 @@ void OReportController::openPageDialog(const 
uno::Reference<report::XSection>& _
     // UNO->ItemSet
     static SfxItemInfo aItemInfos[] =
     {
-        { SID_ATTR_LRSPACE,     true },
-        { SID_ATTR_ULSPACE,     true },
-        { SID_ATTR_PAGE,        true },
-        { SID_ATTR_PAGE_SIZE,   true },
-        { SID_ENUM_PAGE_MODE,   true },
-        { SID_PAPER_START,      true },
-        { SID_PAPER_END,        true },
-        { SID_ATTR_BRUSH,       true },
-        { 0,      true }, // XATTR_FILLSTYLE
-        { 0,      true }, // XATTR_FILLCOLOR
-        { 0,       true }, // XATTR_FILLGRADIENT
-        { 0,      true }, // XATTR_FILLHATCH
-        { 0,     true }, // XATTR_FILLBITMAP
-        { 0,       true }, // XATTR_FILLTRANSPARENCE
-        { 0,      true }, // XATTR_GRADIENTSTEPCOUNT
-        { 0,       true }, // XATTR_FILLBMP_TILE
-        { 0,        true }, // XATTR_FILLBMP_POS
-        { 0,      true }, // XATTR_FILLBMP_SIZEX
-        { 0,      true }, // XATTR_FILLBMP_SIZEY
-        { 0,  true }, // XATTR_FILLFLOATTRANSPARENCE
-        { 0,     true }, // XATTR_SECONDARYFILLCOLOR
-        { 0,        true }, // XATTR_FILLBMP_SIZELOG
-        { 0,    true }, // XATTR_FILLBMP_TILEOFFSETX
-        { 0,    true }, // XATTR_FILLBMP_TILEOFFSETY
-        { 0,        true }, // XATTR_FILLBMP_STRETCH
-        { 0,     true }, // XATTR_FILLBMP_POSOFFSETX
-        { 0,     true }, // XATTR_FILLBMP_POSOFFSETY
-        { 0,     true }, // XATTR_FILLBACKGROUND
-        { SID_ATTR_METRIC,      true }
+        // _nSID, _bNeedsPoolRegistration, _bShareable
+        { SID_ATTR_LRSPACE,     false, true },
+        { SID_ATTR_ULSPACE,     false, true },
+        { SID_ATTR_PAGE,        false, true },
+        { SID_ATTR_PAGE_SIZE,   false, true },
+        { SID_ENUM_PAGE_MODE,   false, true },
+        { SID_PAPER_START,      false, true },
+        { SID_PAPER_END,        false, true },
+        { SID_ATTR_BRUSH,       false, true },
+        { 0,                    false, true }, // XATTR_FILLSTYLE
+        { 0,                    true,  true }, // XATTR_FILLCOLOR
+        { 0,                    false, true }, // XATTR_FILLGRADIENT
+        { 0,                    false, true }, // XATTR_FILLHATCH
+        { 0,                    false, true }, // XATTR_FILLBITMAP
+        { 0,                    false, true }, // XATTR_FILLTRANSPARENCE
+        { 0,                    false, true }, // XATTR_GRADIENTSTEPCOUNT
+        { 0,                    false, true }, // XATTR_FILLBMP_TILE
+        { 0,                    false, true }, // XATTR_FILLBMP_POS
+        { 0,                    false, true }, // XATTR_FILLBMP_SIZEX
+        { 0,                    false, true }, // XATTR_FILLBMP_SIZEY
+        { 0,                    false, true }, // XATTR_FILLFLOATTRANSPARENCE
+        { 0,                    false, true }, // XATTR_SECONDARYFILLCOLOR
+        { 0,                    false, true }, // XATTR_FILLBMP_SIZELOG
+        { 0,                    false, true }, // XATTR_FILLBMP_TILEOFFSETX
+        { 0,                    false, true }, // XATTR_FILLBMP_TILEOFFSETY
+        { 0,                    false, true }, // XATTR_FILLBMP_STRETCH
+        { 0,                    false, true }, // XATTR_FILLBMP_POSOFFSETX
+        { 0,                    false, true }, // XATTR_FILLBMP_POSOFFSETY
+        { 0,                    false, true }, // XATTR_FILLBACKGROUND
+        { SID_ATTR_METRIC,      false, true }
     };
 
     MeasurementSystem eSystem = 
SvtSysLocale().GetLocaleData().getMeasurementSystemEnum();
@@ -4189,7 +4190,8 @@ void OReportController::openZoomDialog()
 
     static SfxItemInfo aItemInfos[] =
     {
-        { SID_ATTR_ZOOM, true }
+        // _nSID, _bNeedsPoolRegistration, _bShareable
+        { SID_ATTR_ZOOM, false, true }
     };
     std::vector<SfxPoolItem*> pDefaults
     {
diff --git a/sc/inc/attarray.hxx b/sc/inc/attarray.hxx
index 521f3b7bb1d6..0d2457c0db25 100644
--- a/sc/inc/attarray.hxx
+++ b/sc/inc/attarray.hxx
@@ -84,7 +84,7 @@ struct ScAttrEntry
     const ScPatternAttr*    pPattern;
     bool operator==( const ScAttrEntry& other ) const
     {
-        return nEndRow == other.nEndRow && pPattern == other.pPattern;
+        return nEndRow == other.nEndRow && SfxPoolItem::areSame(pPattern, 
other.pPattern);
     }
 };
 
diff --git a/sc/inc/attrib.hxx b/sc/inc/attrib.hxx
index dc394dfb1c08..ec004f37d8b6 100644
--- a/sc/inc/attrib.hxx
+++ b/sc/inc/attrib.hxx
@@ -280,8 +280,6 @@ public:
     virtual ~ScCondFormatItem() override;
 
     virtual bool operator==(const SfxPoolItem& rCmp ) const override;
-    virtual bool            operator<(const SfxPoolItem& rCmp) const override;
-    virtual bool            IsSortable() const override { return true; }
     virtual ScCondFormatItem*  Clone( SfxItemPool* = nullptr ) const override;
 
     const ScCondFormatIndexes& GetCondFormatData() const { return maIndex;}
diff --git a/sc/inc/docpool.hxx b/sc/inc/docpool.hxx
index 9280fb3602b0..c73d034f2fb2 100644
--- a/sc/inc/docpool.hxx
+++ b/sc/inc/docpool.hxx
@@ -47,7 +47,8 @@ public:
                                   OUString&           rText,
                                   const IntlWrapper& rIntl ) const override;
 private:
-    virtual const SfxPoolItem&  PutImpl( const SfxPoolItem&, sal_uInt16 nWhich 
= 0, bool bPassingOwnership = false ) override;
+    virtual void newItem_Callback(const SfxPoolItem& rItem) const override;
+    virtual bool newItem_UseDirect(const SfxPoolItem& rItem) const override;
 };
 
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sc/inc/patattr.hxx b/sc/inc/patattr.hxx
index eacb69fd640b..b5deb19826d9 100644
--- a/sc/inc/patattr.hxx
+++ b/sc/inc/patattr.hxx
@@ -56,7 +56,7 @@ class SC_DLLPUBLIC ScPatternAttr final : public SfxSetItem
     mutable std::optional<sal_uInt32> mxHashCode;
     mutable std::optional<bool> mxVisible;
     ScStyleSheet*              pStyle;
-    sal_uInt64                 mnKey;
+    sal_uInt64                 mnPAKey;
 public:
                             ScPatternAttr(SfxItemSet&& pItemSet, const 
OUString& rStyleName);
                             ScPatternAttr(SfxItemSet&& pItemSet);
@@ -66,9 +66,6 @@ public:
     virtual ScPatternAttr*  Clone( SfxItemPool *pPool = nullptr ) const 
override;
 
     virtual bool            operator==(const SfxPoolItem& rCmp) const override;
-    // Class cannot be IsSortable() because it's mutable, implement at least 
Lookup().
-    virtual bool            HasLookup() const override { return true; }
-    virtual lookup_iterator Lookup(lookup_iterator begin, lookup_iterator end 
) const override;
 
     const SfxPoolItem&      GetItem( sal_uInt16 nWhichP ) const
                                         { return GetItemSet().Get(nWhichP); }
@@ -181,8 +178,8 @@ public:
     Degree100               GetRotateVal( const SfxItemSet* pCondSet ) const;
     ScRotateDir             GetRotateDir( const SfxItemSet* pCondSet ) const;
 
-    void                    SetKey(sal_uInt64 nKey);
-    sal_uInt64              GetKey() const;
+    void                    SetPAKey(sal_uInt64 nKey);
+    sal_uInt64              GetPAKey() const;
 
     static std::optional<bool> FastEqualPatternSets( const SfxItemSet& rSet1, 
const SfxItemSet& rSet2 );
 
diff --git a/sc/qa/unit/ucalc.cxx b/sc/qa/unit/ucalc.cxx
index c7bfc3eb8198..a3e2d2ddd567 100644
--- a/sc/qa/unit/ucalc.cxx
+++ b/sc/qa/unit/ucalc.cxx
@@ -1211,7 +1211,7 @@ CPPUNIT_TEST_FIXTURE(Test, testHorizontalAttrIterator)
         size_t nCheckPos = 0;
         for (const ScPatternAttr* pAttr = aIter.GetNext(nCol1, nCol2, nRow); 
pAttr; pAttr = aIter.GetNext(nCol1, nCol2, nRow))
         {
-            if( pAttr == m_pDoc->GetDefPattern())
+            if (SfxPoolItem::areSame( pAttr, m_pDoc->GetDefPattern()))
                 continue;
             CPPUNIT_ASSERT_MESSAGE("Iteration longer than expected.", 
nCheckPos < nCheckLen);
             CPPUNIT_ASSERT_EQUAL(aChecks[nCheckPos][0], 
static_cast<int>(nCol1));
@@ -1302,7 +1302,7 @@ CPPUNIT_TEST_FIXTURE(Test, testIteratorsDefPattern)
     CPPUNIT_ASSERT_EQUAL(SCCOL(102 + 1), m_pDoc->GetAllocatedColumnsCount(0));
     const ScPatternAttr* pattern = m_pDoc->GetPattern(100, 0, 0);
     const ScPatternAttr* defPattern = m_pDoc->GetDefPattern();
-    CPPUNIT_ASSERT(pattern != defPattern);
+    CPPUNIT_ASSERT(!SfxPoolItem::areSame(pattern, defPattern));
     CPPUNIT_ASSERT_EQUAL(pattern, m_pDoc->GetPattern(102, 0, 0));
     CPPUNIT_ASSERT_EQUAL(defPattern, m_pDoc->GetPattern(101, 0, 0));
     CPPUNIT_ASSERT_EQUAL(defPattern, m_pDoc->GetPattern(103, 0, 0));
diff --git a/sc/source/core/data/attarray.cxx b/sc/source/core/data/attarray.cxx
index b6d062b93d66..3e56226f3704 100644
--- a/sc/source/core/data/attarray.cxx
+++ b/sc/source/core/data/attarray.cxx
@@ -63,7 +63,7 @@ ScAttrArray::ScAttrArray( SCCOL nNewCol, SCTAB nNewTab, 
ScDocument& rDoc, ScAttr
     {
         mvData[nIdx].nEndRow = pDefaultColAttrArray->mvData[nIdx].nEndRow;
         ScPatternAttr aNewPattern( 
*(pDefaultColAttrArray->mvData[nIdx].pPattern) );
-        mvData[nIdx].pPattern = &rDocument.GetPool()->Put( aNewPattern );
+        mvData[nIdx].pPattern = &rDocument.GetPool()->DirectPutItemInPool( 
aNewPattern );
         bool bNumFormatChanged = false;
         if ( ScGlobal::CheckWidthInvalidate( bNumFormatChanged,
              mvData[nIdx].pPattern->GetItemSet(), 
rDocument.GetDefPattern()->GetItemSet() ) )
@@ -83,7 +83,7 @@ ScAttrArray::~ScAttrArray()
 
     ScDocumentPool* pDocPool = rDocument.GetPool();
     for (auto const & rEntry : mvData)
-        pDocPool->Remove(*rEntry.pPattern);
+        pDocPool->DirectRemoveItemFromPool(*rEntry.pPattern);
 }
 
 #if DEBUG_SC_TESTATTRARRAY
@@ -140,14 +140,14 @@ void ScAttrArray::Reset( const ScPatternAttr* pPattern )
                 rDocument.InvalidateTextWidth( &aAdrStart, &aAdrEnd, 
bNumFormatChanged );
             }
         }
-        pDocPool->Remove(*pOldPattern);
+        pDocPool->DirectRemoveItemFromPool(*pOldPattern);
     }
     mvData.resize(0);
 
     rDocument.SetStreamValid(nTab, false);
 
     mvData.resize(1);
-    const ScPatternAttr* pNewPattern = &pDocPool->Put(*pPattern);
+    const ScPatternAttr* pNewPattern = 
&pDocPool->DirectPutItemInPool(*pPattern);
     mvData[0].nEndRow = rDocument.MaxRow();
     mvData[0].pPattern = pNewPattern;
 }
@@ -159,10 +159,10 @@ bool ScAttrArray::Concat(SCSIZE nPos)
     {
         if (nPos > 0)
         {
-            if (mvData[nPos - 1].pPattern == mvData[nPos].pPattern)
+            if (SfxPoolItem::areSame(mvData[nPos - 1].pPattern, 
mvData[nPos].pPattern))
             {
                 mvData[nPos - 1].nEndRow = mvData[nPos].nEndRow;
-                rDocument.GetPool()->Remove(*mvData[nPos].pPattern);
+                
rDocument.GetPool()->DirectRemoveItemFromPool(*mvData[nPos].pPattern);
                 mvData.erase(mvData.begin() + nPos);
                 nPos--;
                 bRet = true;
@@ -170,10 +170,10 @@ bool ScAttrArray::Concat(SCSIZE nPos)
         }
         if (nPos + 1 < mvData.size())
         {
-            if (mvData[nPos + 1].pPattern == mvData[nPos].pPattern)
+            if (SfxPoolItem::areSame(mvData[nPos + 1].pPattern, 
mvData[nPos].pPattern))
             {
                 mvData[nPos].nEndRow = mvData[nPos + 1].nEndRow;
-                rDocument.GetPool()->Remove(*mvData[nPos].pPattern);
+                
rDocument.GetPool()->DirectRemoveItemFromPool(*mvData[nPos].pPattern);
                 mvData.erase(mvData.begin() + nPos + 1);
                 bRet = true;
             }
@@ -459,9 +459,9 @@ const ScPatternAttr* ScAttrArray::SetPatternAreaImpl(SCROW 
nStartRow, SCROW nEnd
         if (bPutToPool)
         {
             if (bPassingOwnership)
-                pPattern = 
&rDocument.GetPool()->Put(std::unique_ptr<ScPatternAttr>(const_cast<ScPatternAttr*>(pPattern)));
+                pPattern = 
&rDocument.GetPool()->DirectPutItemInPool(std::unique_ptr<ScPatternAttr>(const_cast<ScPatternAttr*>(pPattern)));
             else
-                pPattern = &rDocument.GetPool()->Put(*pPattern);
+                pPattern = 
&rDocument.GetPool()->DirectPutItemInPool(*pPattern);
         }
         if ((nStartRow == 0) && (nEndRow == rDocument.MaxRow()))
             Reset(pPattern);
@@ -520,7 +520,7 @@ const ScPatternAttr* ScAttrArray::SetPatternAreaImpl(SCROW 
nStartRow, SCROW nEnd
             if ( nStartRow > 0 )
             {
                 nInsert = rDocument.MaxRow() + 1;
-                if ( mvData[ni].pPattern != pPattern )
+                if ( !SfxPoolItem::areSame(mvData[ni].pPattern, pPattern ) )
                 {
                     if ( ni == 0 || (mvData[ni-1].nEndRow < nStartRow - 1) )
                     {   // may be a split or a simple insert or just a shrink,
@@ -533,7 +533,7 @@ const ScPatternAttr* ScAttrArray::SetPatternAreaImpl(SCROW 
nStartRow, SCROW nEnd
                     else if (mvData[ni - 1].nEndRow == nStartRow - 1)
                         nInsert = ni;
                 }
-                if ( ni > 0 && mvData[ni-1].pPattern == pPattern )
+                if ( ni > 0 && SfxPoolItem::areSame(mvData[ni-1].pPattern, 
pPattern) )
                 {   // combine
                     mvData[ni-1].nEndRow = nEndRow;
                     nInsert = rDocument.MaxRow() + 1;
@@ -548,11 +548,11 @@ const ScPatternAttr* 
ScAttrArray::SetPatternAreaImpl(SCROW nStartRow, SCROW nEnd
                 nj++;
             if ( !bSplit )
             {
-                if ( nj < mvData.size() && mvData[nj].pPattern == pPattern )
+                if ( nj < mvData.size() && 
SfxPoolItem::areSame(mvData[nj].pPattern, pPattern ) )
                 {   // combine
                     if ( ni > 0 )
                     {
-                        if ( mvData[ni-1].pPattern == pPattern )
+                        if ( SfxPoolItem::areSame(mvData[ni-1].pPattern, 
pPattern ) )
                         {   // adjacent entries
                             mvData[ni-1].nEndRow = mvData[nj].nEndRow;
                             nj++;
@@ -569,13 +569,13 @@ const ScPatternAttr* 
ScAttrArray::SetPatternAreaImpl(SCROW nStartRow, SCROW nEnd
             ScDocumentPool* pDocPool = rDocument.GetPool();
             if ( bSplit )
             {   // duplicate split entry in pool
-                pDocPool->Put( *mvData[ni-1].pPattern );
+                pDocPool->DirectPutItemInPool( *mvData[ni-1].pPattern );
             }
             if ( ni < nj )
             {   // remove middle entries
                 for ( SCSIZE nk=ni; nk<nj; nk++)
                 {   // remove entries from pool
-                    pDocPool->Remove( *mvData[nk].pPattern );
+                    pDocPool->DirectRemoveItemFromPool( *mvData[nk].pPattern );
                 }
                 if ( !bCombined )
                 {   // replace one entry
@@ -681,8 +681,8 @@ void ScAttrArray::ApplyStyleArea( SCROW nStartRow, SCROW 
nEndRow, const ScStyleS
                 }
             }
 
-            rDocument.GetPool()->Remove(*mvData[nPos].pPattern);
-            mvData[nPos].pPattern = &rDocument.GetPool()->Put(*pNewPattern);
+            
rDocument.GetPool()->DirectRemoveItemFromPool(*mvData[nPos].pPattern);
+            mvData[nPos].pPattern = 
&rDocument.GetPool()->DirectPutItemInPool(*pNewPattern);
             if (Concat(nPos))
                 Search(nStart, nPos);
             else
@@ -818,9 +818,9 @@ void ScAttrArray::ApplyLineStyleArea( SCROW nStartRow, 
SCROW nEndRow,
             else
             {
                 // remove from pool ?
-                rDocument.GetPool()->Remove(*mvData[nPos].pPattern);
+                
rDocument.GetPool()->DirectRemoveItemFromPool(*mvData[nPos].pPattern);
                 mvData[nPos].pPattern =
-                            &rDocument.GetPool()->Put(std::move(pNewPattern));
+                            
&rDocument.GetPool()->DirectPutItemInPool(std::move(pNewPattern));
 
                 if (Concat(nPos))
                     Search(nStart, nPos);
@@ -862,7 +862,7 @@ void ScAttrArray::ApplyCacheArea( SCROW nStartRow, SCROW 
nEndRow, SfxItemPoolCac
     {
         const ScPatternAttr* pOldPattern = mvData[nPos].pPattern;
         const ScPatternAttr* pNewPattern = static_cast<const ScPatternAttr*>( 
&pCache->ApplyTo( *pOldPattern ) );
-        if (pNewPattern != pOldPattern)
+        if (!SfxPoolItem::areSame(pNewPattern, pOldPattern))
         {
             SCROW nY1 = nStart;
             SCROW nY2 = mvData[nPos].nEndRow;
@@ -897,7 +897,7 @@ void ScAttrArray::ApplyCacheArea( SCROW nStartRow, SCROW 
nEndRow, SfxItemPoolCac
                     }
                 }
 
-                rDocument.GetPool()->Remove(*mvData[nPos].pPattern);
+                
rDocument.GetPool()->DirectRemoveItemFromPool(*mvData[nPos].pPattern);
                 mvData[nPos].pPattern = pNewPattern;
                 if (Concat(nPos))
                     Search(nStart, nPos);
@@ -924,7 +924,7 @@ void ScAttrArray::SetAttrEntries(std::vector<ScAttrEntry> 
&& vNewData)
 {
     ScDocumentPool* pDocPool = rDocument.GetPool();
     for (auto const & rEntry : mvData)
-        pDocPool->Remove(*rEntry.pPattern);
+        pDocPool->DirectRemoveItemFromPool(*rEntry.pPattern);
 
     mvData = std::move(vNewData);
 
@@ -961,7 +961,7 @@ static void lcl_MergeDeep( SfxItemSet& rMergeSet, const 
SfxItemSet& rSource )
             SfxItemState eNewState = rSource.GetItemState( nId, true, 
&pNewItem );
             if ( eNewState == SfxItemState::SET )
             {
-                if ( pNewItem != pOldItem ) // Both pulled
+                if ( !SfxPoolItem::areSame(pNewItem, pOldItem) ) // Both pulled
                     rMergeSet.InvalidateItem( nId );
             }
             else // Default
@@ -996,7 +996,7 @@ void ScAttrArray::MergePatternArea( SCROW nStartRow, SCROW 
nEndRow,
             pPattern = mvData[nPos].pPattern;
         else
             pPattern = rDocument.GetDefPattern();
-        if ( pPattern != rState.pOld1 && pPattern != rState.pOld2 )
+        if ( !SfxPoolItem::areSame(pPattern, rState.pOld1) && 
!SfxPoolItem::areSame(pPattern, rState.pOld2) )
         {
             const SfxItemSet& rThisSet = pPattern->GetItemSet();
             if (rState.pItemSet)
@@ -1012,7 +1012,7 @@ void ScAttrArray::MergePatternArea( SCROW nStartRow, 
SCROW nEndRow,
                 // first pattern - copied from parent
                 rState.pItemSet.emplace( *rThisSet.GetPool(), 
rThisSet.GetRanges() );
                 rState.pItemSet->Set( rThisSet, bDeep );
-                rState.mnPatternId = pPattern->GetKey();
+                rState.mnPatternId = pPattern->GetPAKey();
             }
 
             rState.pOld2 = rState.pOld1;
@@ -1585,7 +1585,7 @@ void ScAttrArray::SetPatternAreaSafe( SCROW nStartRow, 
SCROW nEndRow,
     while ( nThisRow <= nEndRow )
     {
         pOldPattern = mvData[nIndex].pPattern;
-        if (pOldPattern != pWantedPattern) // FIXME: else-branch?
+        if (!SfxPoolItem::areSame(pOldPattern, pWantedPattern)) // FIXME: 
else-branch?
         {
             if (nThisRow < nStartRow) nThisRow = nStartRow;
             nRow = mvData[nIndex].nEndRow;
@@ -1610,7 +1610,7 @@ void ScAttrArray::SetPatternAreaSafe( SCROW nStartRow, 
SCROW nEndRow,
                         bFirstUse = false;
                     else
                         // it's in the pool
-                        rDocument.GetPool()->Put( *pWantedPattern );
+                        rDocument.GetPool()->DirectPutItemInPool( 
*pWantedPattern );
                 }
                 SetPatternArea( nThisRow, nAttrRow, pWantedPattern );
             }
@@ -1843,13 +1843,13 @@ void ScAttrArray::FindStyleSheet( const 
SfxStyleSheetBase* pStyleSheet, ScFlatBo
             if (bReset)
             {
                 ScPatternAttr aNewPattern(*mvData[nPos].pPattern);
-                rDocument.GetPool()->Remove(*mvData[nPos].pPattern);
+                
rDocument.GetPool()->DirectRemoveItemFromPool(*mvData[nPos].pPattern);
                 aNewPattern.SetStyleSheet( static_cast<ScStyleSheet*>(
                     rDocument.GetStyleSheetPool()->
                         Find( ScResId(STR_STYLENAME_STANDARD),
                               SfxStyleFamily::Para,
                               SfxStyleSearchBits::Auto | 
SfxStyleSearchBits::ScStandard ) ) );
-                mvData[nPos].pPattern = &rDocument.GetPool()->Put(aNewPattern);
+                mvData[nPos].pPattern = 
&rDocument.GetPool()->DirectPutItemInPool(aNewPattern);
 
                 if (Concat(nPos))
                 {
@@ -1904,7 +1904,7 @@ bool ScAttrArray::IsEmpty() const
 
     if (mvData.size() == 1)
     {
-        return mvData[0].pPattern == rDocument.GetDefPattern();
+        return SfxPoolItem::areSame(mvData[0].pPattern, 
rDocument.GetDefPattern());
     }
     else
         return false;
@@ -2043,7 +2043,7 @@ bool ScAttrArray::IsVisibleEqual( const ScAttrArray& 
rOther,
     {
         const ScPatternAttr* pDefPattern1 = rDocument.GetDefPattern();
         const ScPatternAttr* pDefPattern2 = rOther.rDocument.GetDefPattern();
-        return ( pDefPattern1 == pDefPattern2 || pDefPattern1->IsVisibleEqual( 
*pDefPattern2 ) );
+        return ( SfxPoolItem::areSame(pDefPattern1, pDefPattern2) || 
pDefPattern1->IsVisibleEqual( *pDefPattern2 ) );
     }
 
     {
@@ -2073,7 +2073,7 @@ bool ScAttrArray::IsVisibleEqual( const ScAttrArray& 
rOther,
             while ( nPos < pNonDefault->Count() && bEqual )
             {
                 const ScPatternAttr* pNonDefPattern = 
pNonDefault->mvData[nPos].pPattern;
-                bEqual = ( pNonDefPattern == pDefPattern ||
+                bEqual = ( SfxPoolItem::areSame(pNonDefPattern, pDefPattern) ||
                            pNonDefPattern->IsVisibleEqual( *pDefPattern ) );
 
                 if ( pNonDefault->mvData[nPos].nEndRow >= nEndRow ) break;
@@ -2098,7 +2098,7 @@ bool ScAttrArray::IsVisibleEqual( const ScAttrArray& 
rOther,
         SCROW nOtherRow = rOther.mvData[nOtherPos].nEndRow;
         const ScPatternAttr* pThisPattern = mvData[nThisPos].pPattern;
         const ScPatternAttr* pOtherPattern = rOther.mvData[nOtherPos].pPattern;
-        bEqual = ( pThisPattern == pOtherPattern ||
+        bEqual = ( SfxPoolItem::areSame(pThisPattern, pOtherPattern) ||
                     pThisPattern->IsVisibleEqual(*pOtherPattern) );
 
         if ( nThisRow >= nOtherRow )
@@ -2123,7 +2123,7 @@ bool ScAttrArray::IsAllEqual( const ScAttrArray& rOther, 
SCROW nStartRow, SCROW
     {
         const ScPatternAttr* pDefPattern1 = rDocument.GetDefPattern();
         const ScPatternAttr* pDefPattern2 = rOther.rDocument.GetDefPattern();
-        return ( pDefPattern1 == pDefPattern2 );
+        return SfxPoolItem::areSame(pDefPattern1, pDefPattern2);
     }
 
     {
@@ -2153,7 +2153,7 @@ bool ScAttrArray::IsAllEqual( const ScAttrArray& rOther, 
SCROW nStartRow, SCROW
             while ( nPos < pNonDefault->Count() && bEqual )
             {
                 const ScPatternAttr* pNonDefPattern = 
pNonDefault->mvData[nPos].pPattern;
-                bEqual = ( pNonDefPattern == pDefPattern );
+                bEqual = SfxPoolItem::areSame( pNonDefPattern, pDefPattern );
 
                 if ( pNonDefault->mvData[nPos].nEndRow >= nEndRow ) break;
                 ++nPos;
@@ -2177,7 +2177,7 @@ bool ScAttrArray::IsAllEqual( const ScAttrArray& rOther, 
SCROW nStartRow, SCROW
         SCROW nOtherRow = rOther.mvData[nOtherPos].nEndRow;
         const ScPatternAttr* pThisPattern = mvData[nThisPos].pPattern;
         const ScPatternAttr* pOtherPattern = rOther.mvData[nOtherPos].pPattern;
-        bEqual = ( pThisPattern == pOtherPattern );
+        bEqual = SfxPoolItem::areSame( pThisPattern, pOtherPattern );
 
         if ( nThisRow >= nOtherRow )
         {
@@ -2323,7 +2323,7 @@ void ScAttrArray::DeleteRow( SCROW nStartRow, SCSIZE 
nSize )
         {
             DeleteRange( nStartIndex, nEndIndex );
             if (nStartIndex > 0)
-                if ( mvData[nStartIndex-1].pPattern == 
mvData[nStartIndex].pPattern )
+                if ( SfxPoolItem::areSame( mvData[nStartIndex-1].pPattern, 
mvData[nStartIndex].pPattern ) )
                     DeleteRange( nStartIndex-1, nStartIndex-1 );
         }
     }
@@ -2341,7 +2341,7 @@ void ScAttrArray::DeleteRange( SCSIZE nStartIndex, SCSIZE 
nEndIndex )
     SetDefaultIfNotInit();
     ScDocumentPool* pDocPool = rDocument.GetPool();
     for (SCSIZE i = nStartIndex; i <= nEndIndex; i++)
-        pDocPool->Remove(*mvData[i].pPattern);
+        pDocPool->DirectRemoveItemFromPool(*mvData[i].pPattern);
 
     mvData.erase(mvData.begin() + nStartIndex, mvData.begin() + nEndIndex + 1);
 }
@@ -2468,14 +2468,14 @@ void ScAttrArray::CopyArea(
                     aTmpPattern.GetItemSet().ClearItem( ATTR_MERGE_FLAG );
 
                 if (bSamePool)
-                    pNewPattern = &pDestDocPool->Put(aTmpPattern);
+                    pNewPattern = 
&pDestDocPool->DirectPutItemInPool(aTmpPattern);
                 else
                     pNewPattern = aTmpPattern.PutInPool( 
&rAttrArray.rDocument, &rDocument );
             }
             else
             {
                 if (bSamePool)
-                    pNewPattern = &pDestDocPool->Put(*pOldPattern);
+                    pNewPattern = 
&pDestDocPool->DirectPutItemInPool(*pOldPattern);
                 else
                     pNewPattern = pOldPattern->PutInPool( 
&rAttrArray.rDocument, &rDocument );
             }
@@ -2516,7 +2516,7 @@ void ScAttrArray::CopyAreaSafe( SCROW nStartRow, SCROW 
nEndRow, tools::Long nDy,
     {
         const ScPatternAttr* pNewPattern;
         if (bSamePool)
-            pNewPattern = &pDestDocPool->Put(*rDocument.GetDefPattern());
+            pNewPattern = 
&pDestDocPool->DirectPutItemInPool(*rDocument.GetDefPattern());
         else
             pNewPattern = rDocument.GetDefPattern()->PutInPool( 
&rAttrArray.rDocument, &rDocument );
 
@@ -2533,7 +2533,7 @@ void ScAttrArray::CopyAreaSafe( SCROW nStartRow, SCROW 
nEndRow, tools::Long nDy,
             const ScPatternAttr* pNewPattern;
 
             if (bSamePool)
-                pNewPattern = &pDestDocPool->Put(*pOldPattern);
+                pNewPattern = &pDestDocPool->DirectPutItemInPool(*pOldPattern);
             else
                 pNewPattern = pOldPattern->PutInPool( &rAttrArray.rDocument, 
&rDocument );
 
diff --git a/sc/source/core/data/attrib.cxx b/sc/source/core/data/attrib.cxx
index efe494c316a5..1a587d2b6572 100644
--- a/sc/source/core/data/attrib.cxx
+++ b/sc/source/core/data/attrib.cxx
@@ -733,21 +733,6 @@ bool ScCondFormatItem::operator==( const SfxPoolItem& rCmp 
) const
         && memcmp(&maIndex.front(), &other.maIndex.front(), maIndex.size() * 
sizeof(sal_uInt32)) == 0;
 }
 
-bool ScCondFormatItem::operator<( const SfxPoolItem& rCmp ) const
-{
-    auto const & other = static_cast<const ScCondFormatItem&>(rCmp);
-    if ( maIndex.size() < other.maIndex.size() )
-        return true;
-    if ( maIndex.size() > other.maIndex.size() )
-        return false;
-    if (maIndex.empty() && other.maIndex.empty())
-        return false;
-    // memcmp is faster than operator< on std::vector
-    // Note that on little-endian this results in a confusing ordering (256 < 
1),
-    // which technically doesn't matter as the ordering may be arbitrary.
-    return memcmp(&maIndex.front(), &other.maIndex.front(), maIndex.size() * 
sizeof(sal_uInt32)) < 0;
-}
-
 ScCondFormatItem* ScCondFormatItem::Clone(SfxItemPool*) const
 {
     return new ScCondFormatItem(maIndex);
diff --git a/sc/source/core/data/column.cxx b/sc/source/core/data/column.cxx
index 7ffd5ae9c735..c448f79ae996 100644
--- a/sc/source/core/data/column.cxx
+++ b/sc/source/core/data/column.cxx
@@ -476,7 +476,7 @@ void ScColumn::ApplyPattern( SCROW nRow, const 
ScPatternAttr& rPatAttr )
 
     const ScPatternAttr* pNewPattern = static_cast<const ScPatternAttr*>( 
&aCache.ApplyTo( *pPattern ) );
 
-    if (pNewPattern != pPattern)
+    if (!SfxPoolItem::areSame(pNewPattern, pPattern))
       pAttrArray->SetPattern( nRow, pNewPattern );
 }
 
@@ -628,12 +628,12 @@ void ScColumn::ApplyAttr( SCROW nRow, const SfxPoolItem& 
rAttr )
     const ScPatternAttr* pOldPattern = pAttrArray->GetPattern( nRow );
     ScPatternAttr aTemp(*pOldPattern);
     aTemp.GetItemSet().Put(rAttr);
-    const ScPatternAttr* pNewPattern = &pDocPool->Put( aTemp );
+    const ScPatternAttr* pNewPattern = &pDocPool->DirectPutItemInPool( aTemp );
 
-    if ( pNewPattern != pOldPattern )
+    if (!SfxPoolItem::areSame( pNewPattern, pOldPattern ))
         pAttrArray->SetPattern( nRow, pNewPattern );
     else
-        pDocPool->Remove( *pNewPattern );       // free up resources
+        pDocPool->DirectRemoveItemFromPool( *pNewPattern );       // free up 
resources
 }
 
 ScRefCellValue ScColumn::GetCellValue( SCROW nRow ) const
diff --git a/sc/source/core/data/column2.cxx b/sc/source/core/data/column2.cxx
index e7ca588a0b34..28d928cacea1 100644
--- a/sc/source/core/data/column2.cxx
+++ b/sc/source/core/data/column2.cxx
@@ -203,7 +203,7 @@ tools::Long ScColumn::GetNeededSize(
         }
         if (bNumeric)
         {
-            if (!bMayInvalidatePattern || pPattern == pOldPattern)
+            if (!bMayInvalidatePattern || SfxPoolItem::areSame(pPattern, 
pOldPattern))
                 bBreak = false;
             else
             {
@@ -772,7 +772,7 @@ sal_uInt16 ScColumn::GetOptimalColWidth(
             // Or again in case there was a leading sep=";" row or two header
             // rows..
             const ScPatternAttr* pNextPattern = GetPattern( ++nRow );
-            if (pNextPattern != pPattern)
+            if (!SfxPoolItem::areSame(pNextPattern, pPattern))
                 nFormat = pNextPattern->GetNumberFormat( pFormatter );
         }
         OUString aLongStr;
@@ -830,7 +830,7 @@ sal_uInt16 ScColumn::GetOptimalColWidth(
 
                     const ScPatternAttr* pPattern = GetPattern(nRow);
                     aOptions.pPattern = pPattern;
-                    aOptions.bGetFont = (pPattern != pOldPattern || nScript != 
SvtScriptType::NONE);
+                    aOptions.bGetFont = (!SfxPoolItem::areSame(pPattern, 
pOldPattern) || nScript != SvtScriptType::NONE);
                     pOldPattern = pPattern;
                     sal_uInt16 nThis = static_cast<sal_uInt16>(GetNeededSize(
                         nRow, pDev, nPPTX, nPPTY, rZoomX, rZoomY, true, 
aOptions, &pOldPattern));
@@ -1079,7 +1079,7 @@ void ScColumn::GetOptimalHeight(
                             if (nHeight > rHeights.GetValue(nRow))
                                 rHeights.SetValue(nRow, nRow, nHeight);
                             // Pattern changed due to calculation? => sync.
-                            if (pPattern != pOldPattern)
+                            if (!SfxPoolItem::areSame(pPattern, pOldPattern))
                             {
                                 pPattern = aIter.Resync( nRow, nStart, nEnd);
                                 nNextEnd = 0;
diff --git a/sc/source/core/data/column4.cxx b/sc/source/core/data/column4.cxx
index 8e22b13a8e1e..324e54be2a92 100644
--- a/sc/source/core/data/column4.cxx
+++ b/sc/source/core/data/column4.cxx
@@ -1248,10 +1248,10 @@ void ScColumn::Swap( ScColumn& rOther, SCROW nRow1, 
SCROW nRow2, bool bPattern )
         {

... etc. - the rest is truncated

Reply via email to