simplify SfxPoolItemArray_Impl (tdf#81765 related)

Since we want to look up items by pointer, just store them in a
std::unordered_set, which allows fast find().
This dramatically simplifies most operations on this data structure.

Fix a dodgy sd test that was relying on items with the same whichid
being in the pool being in a certain order.

Change-Id: I4d79fc718f95e3083a20788be1050fbe9fca7263
Reviewed-on: https://gerrit.libreoffice.org/70881
Tested-by: Jenkins
Reviewed-by: Noel Grandin <noel.grandin@collabora.co.uk>
diff --git a/editeng/source/editeng/impedit4.cxx b/editeng/source/editeng/impedit4.cxx
index b7d9162..1838a06 100644
--- a/editeng/source/editeng/impedit4.cxx
+++ b/editeng/source/editeng/impedit4.cxx
@@ -310,15 +310,9 @@
        else if ( nScriptType == 2 )
            nWhich = EE_CHAR_FONTINFO_CTL;

        auto const nFonts(aEditDoc.GetItemPool().GetItemCount2(nWhich));
        for (sal_uInt32 i = 0; i < nFonts; ++i)
        for (const SfxPoolItem* pItem : aEditDoc.GetItemPool().GetItemSurrogates(nWhich))
        {
            SvxFontItem const*const pFontItem = static_cast<const SvxFontItem*>(
                    aEditDoc.GetItemPool().GetItem2(nWhich, i));
            if (!pFontItem)
            {
                continue;
            }
            SvxFontItem const*const pFontItem = static_cast<const SvxFontItem*>(pItem);
            bool bAlreadyExist = false;
            sal_uLong nTestMax = nScriptType ? aFontTable.size() : 1;
            for ( sal_uLong nTest = 0; !bAlreadyExist && ( nTest < nTestMax ); nTest++ )
@@ -390,10 +384,9 @@
    {
        aColorList.push_back(rDefault.GetValue());
    }
    auto const nColors(aEditDoc.GetItemPool().GetItemCount2(EE_CHAR_COLOR));
    for (sal_uInt32 i = 0; i < nColors; ++i)
    for (const SfxPoolItem* pItem : aEditDoc.GetItemPool().GetItemSurrogates(EE_CHAR_COLOR))
    {
        SvxColorItem const*const pColorItem(aEditDoc.GetItemPool().GetItem2(EE_CHAR_COLOR, i));
        auto pColorItem(dynamic_cast<SvxColorItem const*>(pItem));
        if (pColorItem && pColorItem->GetValue() != COL_AUTO) // may be null!
        {
            aColorList.push_back(pColorItem->GetValue());
diff --git a/include/svl/itempool.hxx b/include/svl/itempool.hxx
index e865c93..f987cf1 100644
--- a/include/svl/itempool.hxx
+++ b/include/svl/itempool.hxx
@@ -25,6 +25,7 @@
#include <svl/typedwhich.hxx>
#include <memory>
#include <vector>
#include <o3tl/sorted_vector.hxx>

class SfxBroadcaster;
struct SfxItemPool_Impl;
@@ -154,15 +155,19 @@

    bool                            CheckItemInPool(const SfxPoolItem *) const;

    const SfxPoolItem *             GetItem2(sal_uInt16 nWhich, sal_uInt32 nSurrogate) const;
    template<class T> const T*      GetItem2( TypedWhichId<T> nWhich, sal_uInt32 nSurrogate ) const
    { return dynamic_cast<const T*>(GetItem2(sal_uInt16(nWhich), nSurrogate)); }

    struct Item2Range
    {
        o3tl::sorted_vector<SfxPoolItem*>::const_iterator m_begin;
        o3tl::sorted_vector<SfxPoolItem*>::const_iterator m_end;
        o3tl::sorted_vector<SfxPoolItem*>::const_iterator begin() { return m_begin; }
        o3tl::sorted_vector<SfxPoolItem*>::const_iterator end() { return m_end; }
    };
    const SfxPoolItem *             GetItem2Default(sal_uInt16 nWhich) const;
    template<class T> const T*      GetItem2Default( TypedWhichId<T> nWhich ) const
    { return static_cast<const T*>(GetItem2Default(sal_uInt16(nWhich))); }

    sal_uInt32                      GetItemCount2(sal_uInt16 nWhich) const;
    Item2Range                      GetItemSurrogates(sal_uInt16 nWhich) const;

    sal_uInt16                      GetFirstWhich() const;
    sal_uInt16                      GetLastWhich() const;
diff --git a/sc/source/core/data/docpool.cxx b/sc/source/core/data/docpool.cxx
index 0f19f85..3c21de8 100644
--- a/sc/source/core/data/docpool.cxx
+++ b/sc/source/core/data/docpool.cxx
@@ -349,10 +349,9 @@

void ScDocumentPool::StyleDeleted( const ScStyleSheet* pStyle )
{
    sal_uInt32 nCount = GetItemCount2(ATTR_PATTERN);
    for (sal_uInt32 i=0; i<nCount; i++)
    for (const SfxPoolItem* pItem : GetItemSurrogates( ATTR_PATTERN ))
    {
        ScPatternAttr* pPattern = const_cast<ScPatternAttr*>(GetItem2(ATTR_PATTERN, i));
        ScPatternAttr* pPattern = const_cast<ScPatternAttr*>(dynamic_cast<const ScPatternAttr*>(pItem));
        if ( pPattern && pPattern->GetStyleSheet() == pStyle )
            pPattern->StyleToName();
    }
@@ -365,11 +364,9 @@
    // Calling StyleSheetChanged isn't enough because the pool may still contain items
    // for undo or clipboard content.

    sal_uInt32 nCount = GetItemCount2(ATTR_PATTERN);
    for (sal_uInt32 i=0; i<nCount; i++)
    for (const SfxPoolItem* pItem : GetItemSurrogates( ATTR_PATTERN ))
    {
        ScPatternAttr *const pPattern =
            const_cast<ScPatternAttr*>(GetItem2(ATTR_PATTERN, i));
        auto pPattern = const_cast<ScPatternAttr*>(dynamic_cast<const ScPatternAttr*>(pItem));
        if ( pPattern && pPattern->GetStyleSheet() == nullptr )
        {
            const OUString* pStyleName = pPattern->GetStyleName();
diff --git a/sc/source/core/data/documen9.cxx b/sc/source/core/data/documen9.cxx
index 8fc38fb..d5146ed 100644
--- a/sc/source/core/data/documen9.cxx
+++ b/sc/source/core/data/documen9.cxx
@@ -553,25 +553,23 @@
    if ( eSrcSet != eSysSet || bUpdateOld )
    {
        ScDocumentPool* pPool = mxPoolHelper->GetDocPool();
        sal_uInt32 nCount = pPool->GetItemCount2(ATTR_FONT);
        for (sal_uInt32 i=0; i<nCount; i++)
        for (const SfxPoolItem* pItem : pPool->GetItemSurrogates(ATTR_FONT))
        {
            SvxFontItem* pItem = const_cast<SvxFontItem*>(pPool->GetItem2(ATTR_FONT, i));
            if ( pItem && ( pItem->GetCharSet() == eSrcSet ||
                            ( bUpdateOld && pItem->GetCharSet() != RTL_TEXTENCODING_SYMBOL ) ) )
                pItem->SetCharSet(eSysSet);
            auto pFontItem = const_cast<SvxFontItem*>(dynamic_cast<const SvxFontItem*>(pItem));
            if ( pFontItem && ( pFontItem->GetCharSet() == eSrcSet ||
                               ( bUpdateOld && pFontItem->GetCharSet() != RTL_TEXTENCODING_SYMBOL ) ) )
                pFontItem->SetCharSet(eSysSet);
        }

        if ( mpDrawLayer )
        {
            SfxItemPool& rDrawPool = mpDrawLayer->GetItemPool();
            nCount = rDrawPool.GetItemCount2(EE_CHAR_FONTINFO);
            for (sal_uInt32 i=0; i<nCount; i++)
            for (const SfxPoolItem* pItem : rDrawPool.GetItemSurrogates(EE_CHAR_FONTINFO))
            {
                SvxFontItem* pItem = const_cast<SvxFontItem*>(rDrawPool.GetItem2(EE_CHAR_FONTINFO, i));
                if ( pItem && ( pItem->GetCharSet() == eSrcSet ||
                                ( bUpdateOld && pItem->GetCharSet() != RTL_TEXTENCODING_SYMBOL ) ) )
                    pItem->SetCharSet( eSysSet );
                SvxFontItem* pFontItem = const_cast<SvxFontItem*>(dynamic_cast<const SvxFontItem*>(pItem));
                if ( pFontItem && ( pFontItem->GetCharSet() == eSrcSet ||
                                   ( bUpdateOld && pFontItem->GetCharSet() != RTL_TEXTENCODING_SYMBOL ) ) )
                    pFontItem->SetCharSet( eSysSet );
            }
        }
    }
diff --git a/sc/source/core/data/document.cxx b/sc/source/core/data/document.cxx
index f41e9e3..b4baa4b 100644
--- a/sc/source/core/data/document.cxx
+++ b/sc/source/core/data/document.cxx
@@ -5181,20 +5181,15 @@
        ScDocumentPool* pPool = mxPoolHelper->GetDocPool();

        bool bAnyItem = false;
        sal_uInt32 nRotCount = pPool->GetItemCount2( ATTR_ROTATE_VALUE );
        for (sal_uInt32 nItem=0; nItem<nRotCount; nItem++)
        for (const SfxPoolItem* pItem : pPool->GetItemSurrogates(ATTR_ROTATE_VALUE))
        {
            const SfxPoolItem* pItem = pPool->GetItem2( ATTR_ROTATE_VALUE, nItem );
            if ( pItem )
            // 90 or 270 degrees is former SvxOrientationItem - only look for other values
            // (see ScPatternAttr::GetCellOrientation)
            sal_Int32 nAngle = static_cast<const SfxInt32Item*>(pItem)->GetValue();
            if ( nAngle != 0 && nAngle != 9000 && nAngle != 27000 )
            {
                // 90 or 270 degrees is former SvxOrientationItem - only look for other values
                // (see ScPatternAttr::GetCellOrientation)
                sal_Int32 nAngle = static_cast<const SfxInt32Item*>(pItem)->GetValue();
                if ( nAngle != 0 && nAngle != 9000 && nAngle != 27000 )
                {
                    bAnyItem = true;
                    break;
                }
                bAnyItem = true;
                break;
            }
        }
        if (!bAnyItem)
@@ -6108,10 +6103,9 @@
{
    ScDocumentPool* pPool = mxPoolHelper->GetDocPool();

    sal_uInt32 nCount = pPool->GetItemCount2(ATTR_PATTERN);
    for (sal_uInt32 i=0; i<nCount; i++)
    for (const SfxPoolItem* pItem : pPool->GetItemSurrogates(ATTR_PATTERN))
    {
        ScPatternAttr* pPattern = const_cast<ScPatternAttr*>(pPool->GetItem2(ATTR_PATTERN, i));
        auto pPattern = const_cast<ScPatternAttr*>(dynamic_cast<const ScPatternAttr*>(pItem));
        if (pPattern)
            pPattern->UpdateStyleSheet(this);
    }
@@ -6122,10 +6116,9 @@
{
    ScDocumentPool* pPool = mxPoolHelper->GetDocPool();

    sal_uInt32 nCount = pPool->GetItemCount2(ATTR_PATTERN);
    for (sal_uInt32 i=0; i<nCount; i++)
    for (const SfxPoolItem* pItem : pPool->GetItemSurrogates(ATTR_PATTERN))
    {
        ScPatternAttr* pPattern = const_cast<ScPatternAttr*>(pPool->GetItem2(ATTR_PATTERN, i));
        auto pPattern = const_cast<ScPatternAttr*>(dynamic_cast<const ScPatternAttr*>(pItem));
        if (pPattern)
            pPattern->StyleToName();
    }
diff --git a/sc/source/core/data/document10.cxx b/sc/source/core/data/document10.cxx
index 429fc33..8778099 100644
--- a/sc/source/core/data/document10.cxx
+++ b/sc/source/core/data/document10.cxx
@@ -185,13 +185,10 @@
    const sal_uInt16 pAttribs[] = {ATTR_BACKGROUND, ATTR_FONT_COLOR};
    for (sal_uInt16 nAttrib : pAttribs)
    {
        const sal_uInt32 nCount = pPool->GetItemCount2(nAttrib);
        for (sal_uInt32 j=0; j<nCount; j++)
        for (const SfxPoolItem* pItem : pPool->GetItemSurrogates(nAttrib))
        {
            const SvxColorItem *pItem = static_cast<const SvxColorItem*>(pPool->GetItem2(nAttrib, j));
            if (pItem == nullptr)
                continue;
            Color aColor( pItem->GetValue() );
            const SvxColorItem *pColorItem = static_cast<const SvxColorItem*>(pItem);
            Color aColor( pColorItem->GetValue() );
            if (COL_AUTO != aColor)
                aDocColors.insert(aColor);
        }
diff --git a/sc/source/core/data/fillinfo.cxx b/sc/source/core/data/fillinfo.cxx
index 6c17020..678709a 100644
--- a/sc/source/core/data/fillinfo.cxx
+++ b/sc/source/core/data/fillinfo.cxx
@@ -181,16 +181,7 @@

bool isRotateItemUsed(const ScDocumentPool *pPool)
{
    sal_uInt32 nRotCount = pPool->GetItemCount2( ATTR_ROTATE_VALUE );
    for (sal_uInt32 nItem=0; nItem<nRotCount; nItem++)
    {
        if (pPool->GetItem2( ATTR_ROTATE_VALUE, nItem ))
        {
            return true;
        }
    }

    return false;
    return pPool->GetItemCount2( ATTR_ROTATE_VALUE ) > 0;
}

void initRowInfo(const ScDocument* pDoc, RowInfo* pRowInfo, const SCSIZE nMaxRow,
diff --git a/sc/source/filter/xml/xmlexprt.cxx b/sc/source/filter/xml/xmlexprt.cxx
index 914a3b7..828849f 100644
--- a/sc/source/filter/xml/xmlexprt.cxx
+++ b/sc/source/filter/xml/xmlexprt.cxx
@@ -5186,29 +5186,24 @@

void ScXMLExport::CollectUserDefinedNamespaces(const SfxItemPool* pPool, sal_uInt16 nAttrib)
{
    sal_uInt32 nItems(pPool->GetItemCount2( nAttrib ));
    for( sal_uInt32 i = 0; i < nItems; ++i )
    for (const SfxPoolItem* pItem : pPool->GetItemSurrogates(nAttrib))
    {
        const SfxPoolItem* pItem;
        if( nullptr != (pItem = pPool->GetItem2( nAttrib, i ) ) )
        const SvXMLAttrContainerItem *pUnknown(static_cast<const SvXMLAttrContainerItem *>(pItem));
        if( pUnknown->GetAttrCount() > 0 )
        {
            const SvXMLAttrContainerItem *pUnknown(static_cast<const SvXMLAttrContainerItem *>(pItem));
            if( pUnknown->GetAttrCount() > 0 )
            sal_uInt16 nIdx(pUnknown->GetFirstNamespaceIndex());
            while( USHRT_MAX != nIdx )
            {
                sal_uInt16 nIdx(pUnknown->GetFirstNamespaceIndex());
                while( USHRT_MAX != nIdx )
                if( (XML_NAMESPACE_UNKNOWN_FLAG & nIdx) != 0 )
                {
                    if( (XML_NAMESPACE_UNKNOWN_FLAG & nIdx) != 0 )
                    {
                        const OUString& rPrefix = pUnknown->GetPrefix( nIdx );
                        // Add namespace declaration for unknown attributes if
                        // there aren't existing ones for the prefix used by the
                        // attributes
                        GetNamespaceMap_().Add( rPrefix,
                                                pUnknown->GetNamespace( nIdx ) );
                    }
                    nIdx = pUnknown->GetNextNamespaceIndex( nIdx );
                    const OUString& rPrefix = pUnknown->GetPrefix( nIdx );
                    // Add namespace declaration for unknown attributes if
                    // there aren't existing ones for the prefix used by the
                    // attributes
                    GetNamespaceMap_().Add( rPrefix,
                                            pUnknown->GetNamespace( nIdx ) );
                }
                nIdx = pUnknown->GetNextNamespaceIndex( nIdx );
            }
        }
    }
diff --git a/sc/source/filter/xml/xmlfonte.cxx b/sc/source/filter/xml/xmlfonte.cxx
index d06a03d..773848b 100644
--- a/sc/source/filter/xml/xmlfonte.cxx
+++ b/sc/source/filter/xml/xmlfonte.cxx
@@ -47,26 +47,21 @@
{
    for( sal_uInt16 i=0; i < nIdCount; ++i )
    {
        const SfxPoolItem* pItem;
        sal_uInt16 nWhichId(pWhichIds[i]);
        if (bExportDefaults)
        {
            pItem = &pItemPool->GetDefaultItem(nWhichId);
            const SfxPoolItem* pItem = &pItemPool->GetDefaultItem(nWhichId);
            const SvxFontItem *pFont(static_cast<const SvxFontItem *>(pItem));
            Add( pFont->GetFamilyName(), pFont->GetStyleName(),
                    pFont->GetFamily(), pFont->GetPitch(),
                    pFont->GetCharSet() );
        }
        sal_uInt32 nItems(pItemPool->GetItemCount2( nWhichId ));
        for( sal_uInt32 j = 0; j < nItems; ++j )
        for (const SfxPoolItem* pItem : pItemPool->GetItemSurrogates( nWhichId ))
        {
            if( nullptr != (pItem = pItemPool->GetItem2( nWhichId, j ) ) )
            {
                const SvxFontItem *pFont(static_cast<const SvxFontItem *>(pItem));
                Add( pFont->GetFamilyName(), pFont->GetStyleName(),
                     pFont->GetFamily(), pFont->GetPitch(),
                     pFont->GetCharSet() );
            }
            const SvxFontItem *pFont(static_cast<const SvxFontItem *>(pItem));
            Add( pFont->GetFamilyName(), pFont->GetStyleName(),
                 pFont->GetFamily(), pFont->GetPitch(),
                 pFont->GetCharSet() );
        }
    }
}
@@ -111,30 +106,26 @@

                for (sal_uInt16 nPageWhichId : aPageWhichIds)
                {
                    sal_uInt32 nPageHFItems(rPagePool.GetItemCount2(nPageWhichId));
                    for (sal_uInt32 k = 0; k < nPageHFItems; ++k)
                    for (const SfxPoolItem* pItem : rPagePool.GetItemSurrogates( nPageWhichId ))
                    {
                        const ScPageHFItem* pPageItem;
                        if (nullptr != (pPageItem = static_cast<const ScPageHFItem*>(rPagePool.GetItem2(nPageWhichId, k))))
                        const ScPageHFItem* pPageItem = static_cast<const ScPageHFItem*>(pItem);
                        const EditTextObject* pLeftArea(pPageItem->GetLeftArea());
                        if (pLeftArea)
                        {
                            const EditTextObject* pLeftArea(pPageItem->GetLeftArea());
                            if (pLeftArea)
                            {
                                aEditEngine.SetText(*pLeftArea);
                                AddFontItems(aEditWhichIds, 3, mpEditEnginePool, false);
                            }
                            const EditTextObject* pCenterArea(pPageItem->GetCenterArea());
                            if (pCenterArea)
                            {
                                aEditEngine.SetText(*pCenterArea);
                                AddFontItems(aEditWhichIds, 3, mpEditEnginePool, false);
                            }
                            const EditTextObject* pRightArea(pPageItem->GetRightArea());
                            if (pRightArea)
                            {
                                aEditEngine.SetText(*pRightArea);
                                AddFontItems(aEditWhichIds, 3, mpEditEnginePool, false);
                            }
                            aEditEngine.SetText(*pLeftArea);
                            AddFontItems(aEditWhichIds, 3, mpEditEnginePool, false);
                        }
                        const EditTextObject* pCenterArea(pPageItem->GetCenterArea());
                        if (pCenterArea)
                        {
                            aEditEngine.SetText(*pCenterArea);
                            AddFontItems(aEditWhichIds, 3, mpEditEnginePool, false);
                        }
                        const EditTextObject* pRightArea(pPageItem->GetRightArea());
                        if (pRightArea)
                        {
                            aEditEngine.SetText(*pRightArea);
                            AddFontItems(aEditWhichIds, 3, mpEditEnginePool, false);
                        }
                    }
                }
diff --git a/sc/source/ui/view/cellsh1.cxx b/sc/source/ui/view/cellsh1.cxx
index a1e19a1..2301430 100644
--- a/sc/source/ui/view/cellsh1.cxx
+++ b/sc/source/ui/view/cellsh1.cxx
@@ -1921,17 +1921,12 @@
                bool        bManaged    = false;

                // Get the pool item stored by Conditional Format Manager Dialog.
                sal_uInt32 nItems(pTabViewShell->GetPool().GetItemCount2( SCITEM_CONDFORMATDLGDATA ));
                for( sal_uInt32 nIter = 0; nIter < nItems; ++nIter )
                auto itemsRange = pTabViewShell->GetPool().GetItemSurrogates(SCITEM_CONDFORMATDLGDATA);
                if (itemsRange.begin() != itemsRange.end())
                {
                    const SfxPoolItem* pItem = pTabViewShell->GetPool().GetItem2( SCITEM_CONDFORMATDLGDATA, nIter );
                    if( pItem != nullptr )
                    {
                        const ScCondFormatDlgItem* pDlgItem = static_cast<const ScCondFormatDlgItem*>(pItem);
                        nIndex = pDlgItem->GetIndex();
                        bManaged = true;
                        break;
                    }
                    const ScCondFormatDlgItem* pDlgItem = static_cast<const ScCondFormatDlgItem*>(*itemsRange.begin());
                    nIndex = pDlgItem->GetIndex();
                    bManaged = true;
                }

                // Check if the Conditional Manager Dialog is editing or adding
@@ -2534,17 +2529,12 @@

                ScConditionalFormatList* pList = nullptr;

                sal_uInt32 nItems(pTabViewShell->GetPool().GetItemCount2( SCITEM_CONDFORMATDLGDATA ));
                const ScCondFormatDlgItem* pDlgItem = nullptr;
                for( sal_uInt32 nIter = 0; nIter < nItems; ++nIter )
                auto itemsRange = pTabViewShell->GetPool().GetItemSurrogates(SCITEM_CONDFORMATDLGDATA);
                if (itemsRange.begin() != itemsRange.end())
                {
                    const SfxPoolItem* pItem = pTabViewShell->GetPool().GetItem2( SCITEM_CONDFORMATDLGDATA, nIter );
                    if( pItem != nullptr )
                    {
                        pDlgItem= static_cast<const ScCondFormatDlgItem*>(pItem);
                        pList = const_cast<ScCondFormatDlgItem*>(pDlgItem)->GetConditionalFormatList();
                        break;
                    }
                    pDlgItem= static_cast<const ScCondFormatDlgItem*>(*itemsRange.begin());
                    pList = const_cast<ScCondFormatDlgItem*>(pDlgItem)->GetConditionalFormatList();
                }

                if (!pList)
diff --git a/sc/source/ui/view/tabvwshc.cxx b/sc/source/ui/view/tabvwshc.cxx
index 18fd810..43b4289 100644
--- a/sc/source/ui/view/tabvwshc.cxx
+++ b/sc/source/ui/view/tabvwshc.cxx
@@ -187,15 +187,12 @@
            const ScCondFormatDlgItem* pDlgItem = nullptr;
            // Get the pool item stored by Conditional Format Manager Dialog.
            const SfxPoolItem* pItem = nullptr;
            sal_uInt32 nItems(GetPool().GetItemCount2( SCITEM_CONDFORMATDLGDATA ));
            for( sal_uInt32 nIter = 0; nIter < nItems; ++nIter )
            auto itemsRange = GetPool().GetItemSurrogates(SCITEM_CONDFORMATDLGDATA);
            if (itemsRange.begin() != itemsRange.end())
            {
                if( nullptr != (pItem = GetPool().GetItem2( SCITEM_CONDFORMATDLGDATA, nIter ) ) )
                {
                    pDlgItem = static_cast<const ScCondFormatDlgItem*>(pItem);
                    bFound = true;
                    break;
                }
                pItem = *itemsRange.begin();
                pDlgItem = static_cast<const ScCondFormatDlgItem*>(pItem);
                bFound = true;
            }

            ScViewData& rViewData = GetViewData();
diff --git a/sd/qa/unit/export-tests-ooxml1.cxx b/sd/qa/unit/export-tests-ooxml1.cxx
index e7080ae..e8ce39d 100644
--- a/sd/qa/unit/export-tests-ooxml1.cxx
+++ b/sd/qa/unit/export-tests-ooxml1.cxx
@@ -297,9 +297,8 @@
        SdrTextObj *pTxtObj = dynamic_cast<SdrTextObj *>( pObj );
        CPPUNIT_ASSERT( pTxtObj );
        const EditTextObject& aEdit = pTxtObj->GetOutlinerParaObject()->GetTextObject();
        const SvxNumBulletItem *pNumFmt = aEdit.GetPool()->GetItem2(EE_PARA_NUMBULLET, 5);
        CPPUNIT_ASSERT( pNumFmt );
        CPPUNIT_ASSERT_EQUAL_MESSAGE( "Bullet's relative size is wrong!", sal_uInt16(75), pNumFmt->GetNumRule()->GetLevel(1).GetBulletRelSize() ); // != 25
        const SvxNumBulletItem& rNumFmt = aEdit.GetParaAttribs(3).Get(EE_PARA_NUMBULLET);
        CPPUNIT_ASSERT_EQUAL_MESSAGE( "Bullet's relative size is wrong!", sal_uInt16(75), rNumFmt.GetNumRule()->GetLevel(1).GetBulletRelSize() ); // != 25
    }

    xDocShRef->DoClose();
diff --git a/sd/source/core/drawdoc2.cxx b/sd/source/core/drawdoc2.cxx
index 7c73d7d..ba420d2 100644
--- a/sd/source/core/drawdoc2.cxx
+++ b/sd/source/core/drawdoc2.cxx
@@ -272,10 +272,8 @@
        return;

    SfxItemPool& rPool(GetPool());
    sal_uInt32 nCount = rPool.GetItemCount2(EE_FEATURE_FIELD);
    for (sal_uInt32 nOff = 0; nOff < nCount; nOff++)
    for (const SfxPoolItem* pItem : rPool.GetItemSurrogates(EE_FEATURE_FIELD))
    {
        const SfxPoolItem *pItem = rPool.GetItem2(EE_FEATURE_FIELD, nOff);
        const SvxFieldItem* pFldItem = dynamic_cast< const SvxFieldItem * > (pItem);

        if(pFldItem)
@@ -316,10 +314,8 @@
    bool bNotes = (pPage->GetPageKind() == PageKind::Notes);

    SfxItemPool& rPool(GetPool());
    sal_uInt32 nCount = rPool.GetItemCount2(EE_FEATURE_FIELD);
    for (sal_uInt32 nOff = 0; nOff < nCount; nOff++)
    for (const SfxPoolItem* pItem : rPool.GetItemSurrogates(EE_FEATURE_FIELD))
    {
        const SfxPoolItem *pItem = rPool.GetItem2(EE_FEATURE_FIELD, nOff);
        const SvxFieldItem* pFldItem;

        if ((pFldItem = dynamic_cast< const SvxFieldItem * > (pItem)) != nullptr)
diff --git a/sd/source/ui/unoidl/unomodel.cxx b/sd/source/ui/unoidl/unomodel.cxx
index 7f61d8b..ed83fd9 100644
--- a/sd/source/ui/unoidl/unomodel.cxx
+++ b/sd/source/ui/unoidl/unomodel.cxx
@@ -1370,7 +1370,6 @@
                                               EE_CHAR_FONTINFO_CTL };

                const SfxItemPool& rPool = mpDoc->GetPool();
                const SfxPoolItem* pItem;

                for(sal_uInt16 nWhichId : aWhichIds)
                {
@@ -1378,18 +1377,15 @@

                    aSeq.realloc( aSeq.getLength() + nItems*5 + 5 );

                    for( sal_uInt32 j = 0; j < nItems; ++j )
                    for (const SfxPoolItem* pItem : rPool.GetItemSurrogates(nWhichId))
                    {
                        if( nullptr != (pItem = rPool.GetItem2( nWhichId, j ) ) )
                        {
                            const SvxFontItem *pFont = static_cast<const SvxFontItem *>(pItem);
                        const SvxFontItem *pFont = static_cast<const SvxFontItem *>(pItem);

                            aSeq[nSeqIndex++] <<= pFont->GetFamilyName();
                            aSeq[nSeqIndex++] <<= pFont->GetStyleName();
                            aSeq[nSeqIndex++] <<= sal_Int16(pFont->GetFamily());
                            aSeq[nSeqIndex++] <<= sal_Int16(pFont->GetPitch());
                            aSeq[nSeqIndex++] <<= sal_Int16(pFont->GetCharSet());
                        }
                        aSeq[nSeqIndex++] <<= pFont->GetFamilyName();
                        aSeq[nSeqIndex++] <<= pFont->GetStyleName();
                        aSeq[nSeqIndex++] <<= sal_Int16(pFont->GetFamily());
                        aSeq[nSeqIndex++] <<= sal_Int16(pFont->GetPitch());
                        aSeq[nSeqIndex++] <<= sal_Int16(pFont->GetCharSet());
                    }

                    const SvxFontItem& rFont = static_cast<const SvxFontItem&>(rPool.GetDefaultItem( nWhichId ));
diff --git a/svl/qa/unit/items/test_itempool.cxx b/svl/qa/unit/items/test_itempool.cxx
index cde5dee..9b55285 100644
--- a/svl/qa/unit/items/test_itempool.cxx
+++ b/svl/qa/unit/items/test_itempool.cxx
@@ -79,24 +79,17 @@
        CPPUNIT_ASSERT(&rVal2 != &rVal);
    }

    // Test rehash
    for (auto & pSlice : pImpl->maPoolItems)
    {
        if (pSlice)
            pSlice->ReHash();
    }

    // Test removal.
    SfxVoidItem aRemoveFour(4);
    SfxVoidItem aNotherFour(4);
    const SfxPoolItem &rKeyFour = pPool->Put(aRemoveFour);
    pPool->Put(aNotherFour);
    CPPUNIT_ASSERT(pImpl->maPoolItems[3]->size() > 0);
    CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(0), pImpl->maPoolItems[3]->maFree.size());
    CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(2), pImpl->maPoolItems[3]->size());
    pPool->Remove(rKeyFour);
    CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), pImpl->maPoolItems[3]->maFree.size());
    CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(1), pImpl->maPoolItems[3]->size());
    pPool->Put(aNotherFour);
    CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(0), pImpl->maPoolItems[3]->maFree.size());
    CPPUNIT_ASSERT_EQUAL(static_cast<size_t>(2), pImpl->maPoolItems[3]->size());
}


diff --git a/svl/source/inc/poolio.hxx b/svl/source/inc/poolio.hxx
index 270b140..eb78be1 100644
--- a/svl/source/inc/poolio.hxx
+++ b/svl/source/inc/poolio.hxx
@@ -25,8 +25,7 @@
#include <tools/debug.hxx>
#include <deque>
#include <memory>
#include <unordered_map>
#include <vector>
#include <o3tl/sorted_vector.hxx>

class SfxPoolItem;
class SfxItemPoolUser;
@@ -41,27 +40,18 @@
 */
struct SfxPoolItemArray_Impl
{
    typedef std::unordered_map<SfxPoolItem*,sal_uInt32> PoolItemPtrToIndexMap;
private:
    std::vector<SfxPoolItem*> maPoolItemVector;
    o3tl::sorted_vector<SfxPoolItem*> maPoolItemSet;
public:
    /// Track list of indices into our array that contain an empty slot
    std::vector<sal_uInt32> maFree;
    /// Hash of SfxPoolItem pointer to index into our array that contains that slot
    PoolItemPtrToIndexMap     maPtrToIndex;

    SfxPoolItemArray_Impl () {}
    SfxPoolItem*& operator[](size_t n) {return maPoolItemVector[n];}
    std::vector<SfxPoolItem*>::iterator begin() {return maPoolItemVector.begin();}
    std::vector<SfxPoolItem*>::iterator end() {return maPoolItemVector.end();}
    o3tl::sorted_vector<SfxPoolItem*>::const_iterator begin() { return maPoolItemSet.begin(); }
    o3tl::sorted_vector<SfxPoolItem*>::const_iterator end() { return maPoolItemSet.end(); }
    /// clear array of PoolItem variants after all PoolItems are deleted
    /// or all ref counts are decreased
    void clear();
    size_t size() const {return maPoolItemVector.size();}
    void push_back(SfxPoolItem* pItem) {maPoolItemVector.push_back(pItem);}

    /// re-build the list of free slots and hash from clean
    void SVL_DLLPUBLIC ReHash();
    size_t size() const {return maPoolItemSet.size();}
    void insert(SfxPoolItem* pItem) { maPoolItemSet.insert(pItem); }
    o3tl::sorted_vector<SfxPoolItem*>::const_iterator find(SfxPoolItem* pItem) { return maPoolItemSet.find(pItem); }
    void erase(o3tl::sorted_vector<SfxPoolItem*>::const_iterator it) { return maPoolItemSet.erase(it); }
};

struct SfxItemPool_Impl
diff --git a/svl/source/items/itempool.cxx b/svl/source/items/itempool.cxx
index 00bc517..3a0babf 100644
--- a/svl/source/items/itempool.cxx
+++ b/svl/source/items/itempool.cxx
@@ -389,16 +389,11 @@
            {
                if (!bOK)
                    break;
                if (rSecArrayPtr)
                if (rSecArrayPtr && rSecArrayPtr->size()>0)
                {
                    for (const SfxPoolItem* pItem : *rSecArrayPtr)
                        if (pItem)
                        {
                            SAL_WARN("svl.items", "old secondary pool: " << pImpl->mpSecondary->pImpl->aName
                                            << " of pool: " << pImpl->aName << " must be empty.");
                            bOK = false;
                            break;
                        }
                    SAL_WARN("svl.items", "old secondary pool: " << pImpl->mpSecondary->pImpl->aName
                                    << " of pool: " << pImpl->aName << " must be empty.");
                    break;
                }
            }
        }
@@ -489,11 +484,10 @@
                if (rArrayPtr)
                {
                    for (auto& rItemPtr : *rArrayPtr)
                        if (rItemPtr)
                        {
                            ReleaseRef(*rItemPtr, rItemPtr->GetRefCount()); // for RefCount check in dtor
                            delete rItemPtr;
                        }
                    {
                        ReleaseRef(*rItemPtr, rItemPtr->GetRefCount()); // for RefCount check in dtor
                        delete rItemPtr;
                    }
                    rArrayPtr->clear();
                    // let pImpl->DeleteItems() delete item arrays in maPoolItems
                }
@@ -516,11 +510,10 @@
        if (rArrayPtr)
        {
            for (auto& rItemPtr : *rArrayPtr)
                if (rItemPtr)
                {
                    ReleaseRef(*rItemPtr, rItemPtr->GetRefCount()); // for RefCount check in dtor
                    delete rItemPtr;
                }
            {
                ReleaseRef(*rItemPtr, rItemPtr->GetRefCount()); // for RefCount check in dtor
                delete rItemPtr;
            }
            rArrayPtr->clear();
            // let pImpl->DeleteItems() delete item arrays in maPoolItems
        }
@@ -627,9 +620,6 @@
        pItemArr = pImpl->maPoolItems[nIndex].get();
    }

    std::vector<SfxPoolItem*>::iterator ppFree;
    bool ppFreeIsSet = false;

    // Is this a 'poolable' item - ie. should we re-use and return
    // the same underlying item for equivalent (==) SfxPoolItems?
    if ( IsItemPoolable_Impl( nIndex ) )
@@ -637,10 +627,10 @@
        // if is already in a pool, then it is worth checking if it is in this one.
        if ( IsPooledItem(&rItem) )
        {
            auto it = pItemArr->maPtrToIndex.find(const_cast<SfxPoolItem *>(&rItem));
            auto it = pItemArr->find(const_cast<SfxPoolItem *>(&rItem));

            // 1. search for an identical pointer in the pool
            if (it != pItemArr->maPtrToIndex.cend())
            if (it != pItemArr->end())
            {
                AddRef(rItem);
                return rItem;
@@ -650,37 +640,11 @@
        // 2. search for an item with matching attributes.
        for (auto itr = pItemArr->begin(); itr != pItemArr->end(); ++itr)
        {
            if (*itr)
            if (**itr == rItem)
            {
                if (**itr == rItem)
                {
                    AddRef(**itr);
                    return **itr;
                }
                AddRef(**itr);
                return **itr;
            }
            else
            {
                if (!ppFreeIsSet)
                {
                    ppFree = itr;
                    ppFreeIsSet = true;
                }
            }
        }
    }
    else
    {
        // Unconditionally insert; check for a recently freed place
        if (!pItemArr->maFree.empty())
        {
            auto itr = pItemArr->begin();
            sal_uInt32 nIdx = pItemArr->maFree.back();
            pItemArr->maFree.pop_back();

            assert(nIdx < pItemArr->size());
            std::advance(itr, nIdx);
            ppFreeIsSet = true;
            ppFree = itr;
        }
    }

@@ -698,20 +662,8 @@
    AddRef( *pNewItem );

    // 4. finally insert into the pointer array
    assert( pItemArr->maPtrToIndex.find(pNewItem) == pItemArr->maPtrToIndex.end() );
    if ( !ppFreeIsSet )
    {
        sal_uInt32 nOffset = pItemArr->size();
        pItemArr->maPtrToIndex.insert(std::make_pair(pNewItem, nOffset));
        pItemArr->push_back( pNewItem );
    }
    else
    {
        sal_uInt32 nOffset = std::distance(pItemArr->begin(), ppFree);
        pItemArr->maPtrToIndex.insert(std::make_pair(pNewItem, nOffset));
        assert(*ppFree == nullptr);
        *ppFree = pNewItem;
    }
    assert( pItemArr->find(pNewItem) == pItemArr->end() );
    pItemArr->insert( pNewItem );
    return *pNewItem;
}

@@ -755,17 +707,11 @@
    SfxPoolItemArray_Impl* pItemArr = pImpl->maPoolItems[nIndex].get();
    assert(pItemArr && "removing Item not in Pool");

    SfxPoolItemArray_Impl::PoolItemPtrToIndexMap::const_iterator it
        = pItemArr->maPtrToIndex.find(const_cast<SfxPoolItem *>(&rItem));
    if (it != pItemArr->maPtrToIndex.end())
    auto it = pItemArr->find(const_cast<SfxPoolItem *>(&rItem));
    if (it != pItemArr->end())
    {
        sal_uInt32 nIdx = it->second;
        assert(nIdx < pItemArr->size());
        SfxPoolItem*& p = (*pItemArr)[nIdx];
        assert(p == &rItem);

        if ( p->GetRefCount() ) //!
            ReleaseRef( *p );
        if ( rItem.GetRefCount() ) //!
            ReleaseRef( rItem );
        else
        {
            assert(false && "removing Item without ref");
@@ -773,15 +719,10 @@

        // FIXME: Hack, for as long as we have problems with the Outliner
        // See other MI-REF
        if ( 0 == p->GetRefCount() && nWhich < 4000 )
        if ( 0 == rItem.GetRefCount() && nWhich < 4000 )
        {
            DELETEZ(p);

            // remove ourselves from the hash
            pItemArr->maPtrToIndex.erase(it);

            // record that this slot is free
            pItemArr->maFree.push_back( nIdx );
            delete &rItem;
            pItemArr->erase(it);
        }

        return;
@@ -859,28 +800,33 @@

const SfxPoolItem *SfxItemPool::GetItem2Default(sal_uInt16 nWhich) const
{
    return GetItem2(nWhich, SFX_ITEMS_DEFAULT);
}

const SfxPoolItem *SfxItemPool::GetItem2(sal_uInt16 nWhich, sal_uInt32 nOfst) const
{
    if ( !IsInRange(nWhich) )
    {
        if ( pImpl->mpSecondary )
            return pImpl->mpSecondary->GetItem2( nWhich, nOfst );
            return pImpl->mpSecondary->GetItem2Default( nWhich );
        assert(false && "unknown WhichId - cannot resolve surrogate");
        return nullptr;
    }
    return (*pImpl->mpStaticDefaults)[ GetIndex_Impl(nWhich) ];
}

    // default attribute?
    if ( nOfst == SFX_ITEMS_DEFAULT )
        return (*pImpl->mpStaticDefaults)[ GetIndex_Impl(nWhich) ];
SfxItemPool::Item2Range SfxItemPool::GetItemSurrogates(sal_uInt16 nWhich) const
{
    static const o3tl::sorted_vector<SfxPoolItem*> EMPTY;

    if ( !IsInRange(nWhich) )
    {
        if ( pImpl->mpSecondary )
            return pImpl->mpSecondary->GetItemSurrogates( nWhich );
        assert(false && "unknown WhichId - cannot resolve surrogate");
        return { EMPTY.end(), EMPTY.end() };
    }

    SfxPoolItemArray_Impl* pItemArr = pImpl->maPoolItems[GetIndex_Impl(nWhich)].get();
    if( pItemArr && nOfst < pItemArr->size() )
        return (*pItemArr)[nOfst];
    if( pItemArr )
        return { pItemArr->begin(), pItemArr->end() };

    return nullptr;
    return { EMPTY.end(), EMPTY.end() };
}

sal_uInt32 SfxItemPool::GetItemCount2(sal_uInt16 nWhich) const
@@ -969,8 +915,7 @@
    for (auto const & rArrayPtr : pImpl->maPoolItems)
        if (rArrayPtr)
            for (auto const & rItem : *rArrayPtr)
                if (rItem)
                    rItem->dumpAsXml(pWriter);
                rItem->dumpAsXml(pWriter);
    xmlTextWriterEndElement(pWriter);
}

diff --git a/svl/source/items/poolio.cxx b/svl/source/items/poolio.cxx
index c73e85c..569f61c 100644
--- a/svl/source/items/poolio.cxx
+++ b/svl/source/items/poolio.cxx
@@ -32,28 +32,7 @@
/// or all ref counts are decreased
void SfxPoolItemArray_Impl::clear()
{
    maPoolItemVector.clear();
    maFree.clear();
    maPtrToIndex.clear();
}

/// Re-build our free list and pointer hash.
void SfxPoolItemArray_Impl::ReHash()
{
    maFree.clear();
    maPtrToIndex.clear();

    for (size_t nIdx = 0; nIdx < size(); ++nIdx)
    {
        SfxPoolItem *pItem = (*this)[nIdx];
        if (!pItem)
            maFree.push_back(nIdx);
        else
        {
            maPtrToIndex.insert(std::make_pair(pItem,nIdx));
            assert(maPtrToIndex.find(pItem) != maPtrToIndex.end());
        }
    }
    maPoolItemSet.clear();
}

sal_uInt16 SfxItemPool::GetFirstWhich() const
@@ -107,9 +86,8 @@
    SfxPoolItemArray_Impl* pItemArr = pImpl->maPoolItems[GetIndex_Impl(pItem->Which())].get();
    DBG_ASSERT(pItemArr, "ItemArr is not available");

    for ( size_t i = 0; i < pItemArr->size(); ++i )
    for ( auto p : *pItemArr )
    {
        const SfxPoolItem *p = (*pItemArr)[i];
        if ( p == pItem )
            return true;
    }
diff --git a/svx/source/unodraw/UnoNameItemTable.cxx b/svx/source/unodraw/UnoNameItemTable.cxx
index 7f72bbe..64c1a354 100644
--- a/svx/source/unodraw/UnoNameItemTable.cxx
+++ b/svx/source/unodraw/UnoNameItemTable.cxx
@@ -157,18 +157,17 @@
    // if it is not in our own sets, modify the pool!
    bool bFound = false;

    sal_uInt32 nSurrogate;
    sal_uInt32 nCount = mpModelPool ? mpModelPool->GetItemCount2( mnWhich ) : 0;
    for( nSurrogate = 0; nSurrogate < nCount; nSurrogate++ )
    {
        NameOrIndex *pItem = const_cast<NameOrIndex*>(static_cast<const NameOrIndex*>(mpModelPool->GetItem2( mnWhich, nSurrogate)));
        if (pItem && aName == pItem->GetName())
    if (mpModelPool)
        for (const SfxPoolItem* pItem : mpModelPool->GetItemSurrogates(mnWhich))
        {
            pItem->PutValue( aElement, mnMemberId );
            bFound = true;
            break;
            NameOrIndex *pNameOrIndex = const_cast<NameOrIndex*>(static_cast<const NameOrIndex*>(pItem));
            if (pNameOrIndex && aName == pNameOrIndex->GetName())
            {
                pNameOrIndex->PutValue( aElement, mnMemberId );
                bFound = true;
                break;
            }
        }
    }

    if( !bFound )
        throw container::NoSuchElementException();
@@ -191,16 +190,13 @@

    if (mpModelPool && !aName.isEmpty())
    {
        sal_uInt32 nSurrogate;

        sal_uInt32 nSurrogateCount = mpModelPool ? mpModelPool->GetItemCount2( mnWhich ) : 0;
        for( nSurrogate = 0; nSurrogate < nSurrogateCount; nSurrogate++ )
        for (const SfxPoolItem* pItem : mpModelPool->GetItemSurrogates(mnWhich))
        {
            const NameOrIndex *pItem = static_cast<const NameOrIndex*>(mpModelPool->GetItem2( mnWhich, nSurrogate ));
            const NameOrIndex *pNameOrIndex = static_cast<const NameOrIndex*>(pItem);

            if (isValid(pItem) && aName == pItem->GetName())
            if (isValid(pNameOrIndex) && aName == pNameOrIndex->GetName())
            {
                pItem->QueryValue( aAny, mnMemberId );
                pNameOrIndex->QueryValue( aAny, mnMemberId );
                return aAny;
            }
        }
@@ -216,18 +212,17 @@
    std::set< OUString > aNameSet;


    const sal_uInt32 nSurrogateCount = mpModelPool ? mpModelPool->GetItemCount2( mnWhich ) : 0;
    sal_uInt32 nSurrogate;
    for( nSurrogate = 0; nSurrogate < nSurrogateCount; nSurrogate++ )
    {
        const NameOrIndex *pItem = static_cast<const NameOrIndex*>(mpModelPool->GetItem2( mnWhich, nSurrogate ));
    if (mpModelPool)
        for (const SfxPoolItem* pItem : mpModelPool->GetItemSurrogates(mnWhich))
        {
            const NameOrIndex *pNameOrIndex = static_cast<const NameOrIndex*>(pItem);

        if( !isValid( pItem ) )
            continue;
            if( !isValid( pNameOrIndex ) )
                continue;

        OUString aApiName = SvxUnogetApiNameForItem(mnWhich, pItem->GetName());
        aNameSet.insert(aApiName);
    }
            OUString aApiName = SvxUnogetApiNameForItem(mnWhich, pNameOrIndex->GetName());
            aNameSet.insert(aApiName);
        }

    return comphelper::containerToSequence(aNameSet);
}
@@ -241,16 +236,13 @@
    if (aName.isEmpty())
        return false;

    sal_uInt32 nSurrogate;


    sal_uInt32 nCount = mpModelPool ? mpModelPool->GetItemCount2( mnWhich ) : 0;
    for( nSurrogate = 0; nSurrogate < nCount; nSurrogate++ )
    {
        const NameOrIndex *pItem = static_cast<const NameOrIndex*>(mpModelPool->GetItem2( mnWhich, nSurrogate ));
        if (isValid(pItem) && aName == pItem->GetName())
            return true;
    }
    if (mpModelPool)
        for (const SfxPoolItem* pItem : mpModelPool->GetItemSurrogates(mnWhich))
        {
            const NameOrIndex *pNameOrIndex = static_cast<const NameOrIndex*>(pItem);
            if (isValid(pNameOrIndex) && aName == pNameOrIndex->GetName())
                return true;
        }

    return false;
}
@@ -259,16 +251,14 @@
{
    SolarMutexGuard aGuard;

    if (mpModelPool)
        for (const SfxPoolItem* pItem : mpModelPool->GetItemSurrogates(mnWhich))
        {
            const NameOrIndex *pNameOrIndex = static_cast<const NameOrIndex*>(pItem);

    sal_uInt32 nSurrogate;
    const sal_uInt32 nSurrogateCount = mpModelPool ? mpModelPool->GetItemCount2( mnWhich ) : 0;
    for( nSurrogate = 0; nSurrogate < nSurrogateCount; nSurrogate++ )
    {
        const NameOrIndex *pItem = static_cast<const NameOrIndex*>(mpModelPool->GetItem2( mnWhich, nSurrogate ));

        if( isValid( pItem ) )
            return true;
    }
            if( isValid( pNameOrIndex ) )
                return true;
        }

    return false;
}
diff --git a/svx/source/unodraw/UnoNamespaceMap.cxx b/svx/source/unodraw/UnoNamespaceMap.cxx
index 88049ce..cc78931 100644
--- a/svx/source/unodraw/UnoNamespaceMap.cxx
+++ b/svx/source/unodraw/UnoNamespaceMap.cxx
@@ -93,8 +93,8 @@

        sal_uInt16* mpWhichId;

        sal_uInt32 mnItemCount;
        sal_uInt32 mnItem;
        std::vector<const SvXMLAttrContainerItem*> mvItems;
        sal_Int32 mnItem;

        const SvXMLAttrContainerItem* mpCurrentAttr;
        sal_uInt16 mnCurrentAttr;
@@ -118,8 +118,13 @@

    mpWhichId = pWhichIds;

    mnItem = 0;
    mnItemCount = (mpWhichId && (0 != *mpWhichId) && mpPool) ? mpPool->GetItemCount2( *mpWhichId ) : 0;
    mnItem = -1;
    if (mpWhichId && (0 != *mpWhichId) && mpPool)
    {
        mvItems.reserve(mpPool->GetItemCount2( *mpWhichId ));
        for (const SfxPoolItem* pItem : mpPool->GetItemSurrogates( *mpWhichId ))
            mvItems.push_back(static_cast<const SvXMLAttrContainerItem*>(pItem));
    }
}

bool NamespaceIteratorImpl::next( OUString& rPrefix, OUString& rURL )
@@ -136,43 +141,36 @@

    // we need the next namespace item
    mpCurrentAttr = nullptr;

    const SfxPoolItem* pItem = nullptr;
    // look for the next available item in the current pool
    while( (mnItem < mnItemCount) && ( nullptr == (pItem = mpPool->GetItem2( *mpWhichId, mnItem ) ) ) )
        mnItem++;
    mnItem++;

    // are we finished with the current whichid?
    if( mnItem == mnItemCount )
    if( mnItem == static_cast<sal_Int32>(mvItems.size()) )
    {
        mpWhichId++;

        // are we finished with the current pool?
        if( 0 != *mpWhichId )
        if( 0 == *mpWhichId )
            return false;

        mnItem = -1;
        mvItems.clear();
        if (mpPool)
        {
            mnItem = 0;
            mnItemCount = mpPool ? mpPool->GetItemCount2( *mpWhichId ) : 0;
            return next( rPrefix, rURL );
        }

        pItem = nullptr;
    }

    if( pItem )
    {
        mnItem++;

        // get that item and see if there namespaces inside
        const SvXMLAttrContainerItem *pUnknown = static_cast<const SvXMLAttrContainerItem *>(pItem);
        if( pUnknown->GetAttrCount() > 0 )
        {
            mpCurrentAttr = pUnknown;
            mnCurrentAttr = pUnknown->GetFirstNamespaceIndex();
            mvItems.reserve(mpPool->GetItemCount2( *mpWhichId ));
            for (const SfxPoolItem* pItem2 : mpPool->GetItemSurrogates( *mpWhichId ))
                mvItems.push_back(static_cast<const SvXMLAttrContainerItem*>(pItem2));
        }
        return next( rPrefix, rURL );
    }

    return false;
    auto pItem = mvItems[mnItem];
    // get that item and see if there namespaces inside
    if( pItem->GetAttrCount() > 0 )
    {
        mpCurrentAttr = pItem;
        mnCurrentAttr = pItem->GetFirstNamespaceIndex();
    }
    return next( rPrefix, rURL );
}


diff --git a/svx/source/unodraw/unomtabl.cxx b/svx/source/unodraw/unomtabl.cxx
index 01d639d..0dc2530 100644
--- a/svx/source/unodraw/unomtabl.cxx
+++ b/svx/source/unodraw/unomtabl.cxx
@@ -231,30 +231,29 @@
    // if it is not in our own sets, modify the pool!
    bool bFound = false;

    sal_uInt32 nSurrogate;
    const sal_uInt32 nStartCount = mpModelPool ? mpModelPool->GetItemCount2( XATTR_LINESTART ) : 0;
    for( nSurrogate = 0; nSurrogate < nStartCount; nSurrogate++ )
    {
        NameOrIndex *pItem = const_cast<NameOrIndex*>(static_cast<const NameOrIndex*>(mpModelPool->GetItem2( XATTR_LINESTART, nSurrogate)));
        if( pItem && pItem->GetName() == aName )
    if (mpModelPool)
        for (const SfxPoolItem* p : mpModelPool->GetItemSurrogates(XATTR_LINESTART))
        {
            pItem->PutValue( aElement, 0 );
            bFound = true;
            break;
            NameOrIndex *pItem = const_cast<NameOrIndex*>(static_cast<const NameOrIndex*>(p));
            if( pItem && pItem->GetName() == aName )
            {
                pItem->PutValue( aElement, 0 );
                bFound = true;
                break;
            }
        }
    }

    const sal_uInt32 nEndCount = mpModelPool ? mpModelPool->GetItemCount2( XATTR_LINEEND ) : 0;
    for( nSurrogate = 0; nSurrogate < nEndCount; nSurrogate++ )
    {
        NameOrIndex *pItem = const_cast<NameOrIndex*>(static_cast<const NameOrIndex*>(mpModelPool->GetItem2( XATTR_LINEEND, nSurrogate)));
        if( pItem && pItem->GetName() == aName )
    if (mpModelPool)
        for (const SfxPoolItem* p : mpModelPool->GetItemSurrogates(XATTR_LINEEND))
        {
            pItem->PutValue( aElement, 0 );
            bFound = true;
            break;
            NameOrIndex *pItem = const_cast<NameOrIndex*>(static_cast<const NameOrIndex*>(p));
            if( pItem && pItem->GetName() == aName )
            {
                pItem->PutValue( aElement, 0 );
                bFound = true;
                break;
            }
        }
    }

    if( !bFound )
        throw container::NoSuchElementException();
@@ -264,17 +263,17 @@

static bool getByNameFromPool( const OUString& rSearchName, SfxItemPool const * pPool, sal_uInt16 nWhich, uno::Any& rAny )
{
    const sal_uInt32 nSurrogateCount = pPool ? pPool->GetItemCount2( nWhich ) : 0;
    for( sal_uInt32 nSurrogate = 0; nSurrogate < nSurrogateCount; nSurrogate++ )
    {
        const NameOrIndex *pItem = static_cast<const NameOrIndex*>(pPool->GetItem2( nWhich, nSurrogate ));

        if( pItem && pItem->GetName() == rSearchName )
    if (pPool)
        for (const SfxPoolItem* p : pPool->GetItemSurrogates(nWhich))
        {
            pItem->QueryValue( rAny );
            return true;
            const NameOrIndex *pItem = static_cast<const NameOrIndex*>(p);

            if( pItem && pItem->GetName() == rSearchName )
            {
                pItem->QueryValue( rAny );
                return true;
            }
        }
    }

    return false;
}
@@ -308,11 +307,9 @@

static void createNamesForPool( SfxItemPool const * pPool, sal_uInt16 nWhich, std::set< OUString >& rNameSet )
{
    const sal_uInt32 nSuroCount = pPool->GetItemCount2( nWhich );

    for(sal_uInt32 nSurrogate = 0; nSurrogate < nSuroCount; ++nSurrogate)
    for (const SfxPoolItem* p : pPool->GetItemSurrogates(nWhich))
    {
        const NameOrIndex* pItem = static_cast<const NameOrIndex*>(pPool->GetItem2( nWhich, nSurrogate ));
        const NameOrIndex* pItem = static_cast<const NameOrIndex*>(p);

        if( pItem == nullptr || pItem->GetName().isEmpty() )
            continue;
@@ -349,23 +346,22 @@
    const NameOrIndex *pItem;

    aSearchName = SvxUnogetInternalNameForItem(XATTR_LINESTART, aName);
    sal_uInt32 nStartCount = mpModelPool ? mpModelPool->GetItemCount2( XATTR_LINESTART ) : 0;
    sal_uInt32 nSurrogate;
    for( nSurrogate = 0; nSurrogate < nStartCount; nSurrogate++ )
    {
        pItem = static_cast<const NameOrIndex*>(mpModelPool->GetItem2( XATTR_LINESTART, nSurrogate));
        if( pItem && pItem->GetName() == aSearchName )
            return true;
    }
    if (mpModelPool)
        for (const SfxPoolItem* p : mpModelPool->GetItemSurrogates(XATTR_LINESTART))
        {
            pItem = static_cast<const NameOrIndex*>(p);
            if( pItem && pItem->GetName() == aSearchName )
                return true;
        }

    aSearchName = SvxUnogetInternalNameForItem(XATTR_LINEEND, aName);
    sal_uInt32 nEndCount = mpModelPool ? mpModelPool->GetItemCount2( XATTR_LINEEND ) : 0;
    for( nSurrogate = 0; nSurrogate < nEndCount; nSurrogate++ )
    {
        pItem = static_cast<const NameOrIndex*>(mpModelPool->GetItem2( XATTR_LINEEND, nSurrogate));
        if( pItem && pItem->GetName() == aSearchName )
            return true;
    }
    if (mpModelPool)
        for (const SfxPoolItem* p : mpModelPool->GetItemSurrogates(XATTR_LINEEND))
        {
            pItem = static_cast<const NameOrIndex*>(p);
            if( pItem && pItem->GetName() == aSearchName )
                return true;
        }

    return false;
}
@@ -382,22 +378,21 @@

    const NameOrIndex *pItem;

    const sal_uInt32 nStartCount = mpModelPool ? mpModelPool->GetItemCount2( XATTR_LINESTART ) : 0;
    sal_uInt32 nSurrogate;
    for( nSurrogate = 0; nSurrogate < nStartCount; nSurrogate++ )
    {
        pItem = static_cast<const NameOrIndex*>(mpModelPool->GetItem2( XATTR_LINESTART, nSurrogate));
        if( pItem && !pItem->GetName().isEmpty() )
            return true;
    }
    if (mpModelPool)
        for (const SfxPoolItem* p : mpModelPool->GetItemSurrogates(XATTR_LINESTART))
        {
            pItem = static_cast<const NameOrIndex*>(p);
            if( pItem && !pItem->GetName().isEmpty() )
                return true;
        }

    const sal_uInt32 nEndCount = mpModelPool ? mpModelPool->GetItemCount2( XATTR_LINEEND ) : 0;
    for( nSurrogate = 0; nSurrogate < nEndCount; nSurrogate++ )
    {
        pItem = static_cast<const NameOrIndex*>(mpModelPool->GetItem2( XATTR_LINEEND, nSurrogate));
        if( pItem && !pItem->GetName().isEmpty() )
            return true;
    }
    if (mpModelPool)
        for (const SfxPoolItem* p : mpModelPool->GetItemSurrogates(XATTR_LINEEND))
        {
            pItem = static_cast<const NameOrIndex*>(p);
            if( pItem && !pItem->GetName().isEmpty() )
                return true;
        }

    return false;
}
diff --git a/svx/source/unodraw/unoshape.cxx b/svx/source/unodraw/unoshape.cxx
index b7790cd1..315503f 100644
--- a/svx/source/unodraw/unoshape.cxx
+++ b/svx/source/unodraw/unoshape.cxx
@@ -1578,14 +1578,10 @@
        return false;
    }

    const SfxItemPool* pPool = rSet.GetPool();

    const sal_uInt32 nCount = pPool->GetItemCount2(nWID);

    for( sal_uInt32 nSurrogate = 0; nSurrogate < nCount; nSurrogate++ )
    for (const SfxPoolItem* p : rSet.GetPool()->GetItemSurrogates(nWID))
    {
        const NameOrIndex* pItem = static_cast<const NameOrIndex*>(pPool->GetItem2(nWID, nSurrogate));
        if( pItem && ( pItem->GetName() == aName ) )
        const NameOrIndex* pItem = static_cast<const NameOrIndex*>(p);
        if( pItem->GetName() == aName )
        {
            rSet.Put( *pItem );
            return true;
diff --git a/svx/source/xoutdev/xattr.cxx b/svx/source/xoutdev/xattr.cxx
index de1717d..0830a90 100644
--- a/svx/source/xoutdev/xattr.cxx
+++ b/svx/source/xoutdev/xattr.cxx
@@ -128,17 +128,15 @@

    if (!aUniqueName.isEmpty() && pPool1)
    {
        const sal_uInt32 nCount = pPool1->GetItemCount2( nWhich );

        for( sal_uInt32 nSurrogate = 0; nSurrogate < nCount; nSurrogate++ )
        for (const SfxPoolItem* pItem : pPool1->GetItemSurrogates(nWhich))
        {
            const NameOrIndex *pItem = static_cast<const NameOrIndex*>(pPool1->GetItem2( nWhich, nSurrogate ));
            const NameOrIndex *pNameOrIndex = static_cast<const NameOrIndex*>(pItem);

            if( pItem && ( pItem->GetName() == pCheckItem->GetName() ) )
            if( pNameOrIndex->GetName() == pCheckItem->GetName() )
            {
                // if there is already an item with the same name and the same
                // value it's ok to set it
                if( !pCompareValueFunc( pItem, pCheckItem ) )
                if( !pCompareValueFunc( pNameOrIndex, pCheckItem ) )
                {
                    // same name but different value, we need a new name for this item
                    aUniqueName.clear();
@@ -215,20 +213,18 @@

        if (aUniqueName.isEmpty() && pPool1)
        {
            const sal_uInt32 nCount = pPool1->GetItemCount2( nWhich );
            const NameOrIndex *pItem;
            for( sal_uInt32 nSurrogate = 0; nSurrogate < nCount; nSurrogate++ )
            for (const SfxPoolItem* pItem : pPool1->GetItemSurrogates(nWhich))
            {
                pItem = static_cast<const NameOrIndex*>(pPool1->GetItem2( nWhich, nSurrogate ));
                const NameOrIndex *pNameOrIndex = static_cast<const NameOrIndex*>(pItem);

                if( pItem && !pItem->GetName().isEmpty() )
                if( !pNameOrIndex->GetName().isEmpty() )
                {
                    if( !bForceNew && pCompareValueFunc( pItem, pCheckItem ) )
                        return pItem->GetName();
                    if( !bForceNew && pCompareValueFunc( pNameOrIndex, pCheckItem ) )
                        return pNameOrIndex->GetName();

                    if( pItem->GetName().startsWith( aUser ) )
                    if( pNameOrIndex->GetName().startsWith( aUser ) )
                    {
                        sal_Int32 nThisIndex = pItem->GetName().copy( aUser.getLength() ).toInt32();
                        sal_Int32 nThisIndex = pNameOrIndex->GetName().copy( aUser.getLength() ).toInt32();
                        if( nThisIndex >= nUserIndex )
                            nUserIndex = nThisIndex + 1;
                    }
@@ -1098,16 +1094,12 @@
        // 2. if we have a name check if there is already an item with the
        // same name in the documents pool with a different line end or start

        sal_uInt32 nCount, nSurrogate;

        const SfxItemPool& rPool1 = pModel->GetItemPool();
        if (!aUniqueName.isEmpty())
        {
            nCount = rPool1.GetItemCount2(XATTR_LINESTART);

            for( nSurrogate = 0; nSurrogate < nCount; nSurrogate++ )
            for (const SfxPoolItem* p : rPool1.GetItemSurrogates(XATTR_LINESTART))
            {
                const XLineStartItem* pItem = rPool1.GetItem2(XATTR_LINESTART, nSurrogate);
                auto pItem = dynamic_cast<const XLineStartItem*>(p);

                if( pItem && ( pItem->GetName() == pLineStartItem->GetName() ) )
                {
@@ -1125,11 +1117,9 @@

            if( !bForceNew )
            {
                nCount = rPool1.GetItemCount2(XATTR_LINEEND);

                for( nSurrogate = 0; nSurrogate < nCount; nSurrogate++ )
                for (const SfxPoolItem* p : rPool1.GetItemSurrogates(XATTR_LINEEND))
                {
                    const XLineEndItem* pItem = rPool1.GetItem2(XATTR_LINEEND, nSurrogate);
                    auto pItem = dynamic_cast<const XLineEndItem*>(p);

                    if( pItem && ( pItem->GetName() == pLineStartItem->GetName() ) )
                    {
@@ -1150,10 +1140,9 @@
        const SfxItemPool* pPool2 = pModel->GetStyleSheetPool() ? &pModel->GetStyleSheetPool()->GetPool() : nullptr;
        if( !aUniqueName.isEmpty() && pPool2)
        {
            nCount = pPool2->GetItemCount2( XATTR_LINESTART );
            for( nSurrogate = 0; nSurrogate < nCount; nSurrogate++ )
            for (const SfxPoolItem* p : pPool2->GetItemSurrogates(XATTR_LINESTART))
            {
                const XLineStartItem* pItem = pPool2->GetItem2( XATTR_LINESTART, nSurrogate );
                auto pItem = dynamic_cast<const XLineStartItem*>(p);

                if( pItem && ( pItem->GetName() == pLineStartItem->GetName() ) )
                {
@@ -1171,10 +1160,9 @@

            if( !bForceNew )
            {
                nCount = pPool2->GetItemCount2( XATTR_LINEEND );
                for( nSurrogate = 0; nSurrogate < nCount; nSurrogate++ )
                for (const SfxPoolItem* p : pPool2->GetItemSurrogates(XATTR_LINEEND))
                {
                    const XLineEndItem* pItem = pPool2->GetItem2( XATTR_LINEEND, nSurrogate );
                    auto pItem = dynamic_cast<const XLineEndItem*>(p);

                    if( pItem && ( pItem->GetName() == pLineStartItem->GetName() ) )
                    {
@@ -1201,12 +1189,9 @@
            sal_Int32 nUserIndex = 1;
            const OUString aUser(SvxResId(RID_SVXSTR_LINEEND));

            nCount = rPool1.GetItemCount2(XATTR_LINESTART);
            sal_uInt32 nSurrogate2;

            for (nSurrogate2 = 0; nSurrogate2 < nCount; nSurrogate2++)
            for (const SfxPoolItem* p : rPool1.GetItemSurrogates(XATTR_LINESTART))
            {
                const XLineStartItem* pItem = rPool1.GetItem2(XATTR_LINESTART, nSurrogate2);
                auto pItem = dynamic_cast<const XLineStartItem*>(p);

                if (pItem && !pItem->GetName().isEmpty())
                {
@@ -1226,10 +1211,9 @@
                }
            }

            nCount = rPool1.GetItemCount2(XATTR_LINEEND);
            for (nSurrogate2 = 0; nSurrogate2 < nCount; nSurrogate2++)
            for (const SfxPoolItem* p : rPool1.GetItemSurrogates(XATTR_LINEEND))
            {
                const XLineEndItem* pItem = rPool1.GetItem2(XATTR_LINEEND, nSurrogate2);
                auto pItem = dynamic_cast<const XLineEndItem*>(p);

                if (pItem && !pItem->GetName().isEmpty())
                {
@@ -1349,16 +1333,12 @@
        // 2. if we have a name check if there is already an item with the
        // same name in the documents pool with a different line end or start

        sal_uInt16 nCount, nSurrogate;

        const SfxItemPool& rPool1 = pModel->GetItemPool();
        if (!aUniqueName.isEmpty())
        {
            nCount = rPool1.GetItemCount2(XATTR_LINESTART);

            for( nSurrogate = 0; nSurrogate < nCount; nSurrogate++ )
            for (const SfxPoolItem* p : rPool1.GetItemSurrogates(XATTR_LINESTART))
            {
                const XLineStartItem* pItem = rPool1.GetItem2(XATTR_LINESTART, nSurrogate);
                auto pItem = dynamic_cast<const XLineStartItem*>(p);

                if( pItem && ( pItem->GetName() == pLineEndItem->GetName() ) )
                {
@@ -1376,11 +1356,9 @@

            if( !bForceNew )
            {
                nCount = rPool1.GetItemCount2(XATTR_LINEEND);

                for( nSurrogate = 0; nSurrogate < nCount; nSurrogate++ )
                for (const SfxPoolItem* p : rPool1.GetItemSurrogates(XATTR_LINEEND))
                {
                    const XLineEndItem* pItem = rPool1.GetItem2(XATTR_LINEEND, nSurrogate);
                    auto pItem = dynamic_cast<const XLineEndItem*>(p);

                    if( pItem && ( pItem->GetName() == pLineEndItem->GetName() ) )
                    {
@@ -1401,10 +1379,9 @@
        const SfxItemPool* pPool2 = pModel->GetStyleSheetPool() ? &pModel->GetStyleSheetPool()->GetPool() : nullptr;
        if( !aUniqueName.isEmpty() && pPool2)
        {
            nCount = pPool2->GetItemCount2( XATTR_LINESTART );
            for( nSurrogate = 0; nSurrogate < nCount; nSurrogate++ )
            for (const SfxPoolItem* p : pPool2->GetItemSurrogates(XATTR_LINESTART))
            {
                const XLineStartItem* pItem = pPool2->GetItem2( XATTR_LINESTART, nSurrogate );
                auto pItem = dynamic_cast<const XLineStartItem*>(p);

                if( pItem && ( pItem->GetName() == pLineEndItem->GetName() ) )
                {
@@ -1422,10 +1399,9 @@

            if( !bForceNew )
            {
                nCount = pPool2->GetItemCount2( XATTR_LINEEND );
                for( nSurrogate = 0; nSurrogate < nCount; nSurrogate++ )
                for (const SfxPoolItem* p : pPool2->GetItemSurrogates(XATTR_LINEEND))
                {
                    const XLineEndItem* pItem = pPool2->GetItem2( XATTR_LINEEND, nSurrogate );
                    auto pItem = dynamic_cast<const XLineEndItem*>(p);

                    if( pItem && ( pItem->GetName() == pLineEndItem->GetName() ) )
                    {
@@ -1452,12 +1428,9 @@
            sal_Int32 nUserIndex = 1;
            const OUString aUser(SvxResId(RID_SVXSTR_LINEEND));

            nCount = rPool1.GetItemCount2(XATTR_LINESTART);
            sal_uInt32 nSurrogate2;

            for (nSurrogate2 = 0; nSurrogate2 < nCount; nSurrogate2++)
            for (const SfxPoolItem* p : rPool1.GetItemSurrogates(XATTR_LINESTART))
            {
                const XLineStartItem* pItem = rPool1.GetItem2(XATTR_LINESTART, nSurrogate2);
                auto pItem = dynamic_cast<const XLineStartItem*>(p);

                if (pItem && !pItem->GetName().isEmpty())
                {
@@ -1477,10 +1450,9 @@
                }
            }

            nCount = rPool1.GetItemCount2(XATTR_LINEEND);
            for (nSurrogate2 = 0; nSurrogate2 < nCount; nSurrogate2++)
            for (const SfxPoolItem* p : rPool1.GetItemSurrogates(XATTR_LINEEND))
            {
                const XLineEndItem* pItem = rPool1.GetItem2(XATTR_LINEEND, nSurrogate2);
                auto pItem = dynamic_cast<const XLineEndItem*>(p);

                if (pItem && !pItem->GetName().isEmpty())
                {
diff --git a/sw/source/core/crsr/crstrvl.cxx b/sw/source/core/crsr/crstrvl.cxx
index 4e190bc..a593db4 100644
--- a/sw/source/core/crsr/crstrvl.cxx
+++ b/sw/source/core/crsr/crstrvl.cxx
@@ -449,23 +449,22 @@
                                &rPos, &tmp) );
    }
    {
        sal_uInt32 n, nMaxItems = GetDoc()->GetAttrPool().GetItemCount2( RES_BOXATR_FORMULA );
        sal_uInt32 nMaxItems = GetDoc()->GetAttrPool().GetItemCount2( RES_BOXATR_FORMULA );

        if( nMaxItems > 0 )
        {
            sal_uInt8 nMaxDo = 2;
            do {
                for( n = 0; n < nMaxItems; ++n )
                for (const SfxPoolItem* pItem : GetDoc()->GetAttrPool().GetItemSurrogates(RES_BOXATR_FORMULA))
                {
                    const SwTableBox* pTBox;
                    const SfxPoolItem* pItem;
                    if( nullptr != (pItem = GetDoc()->GetAttrPool().GetItem2(
                                        RES_BOXATR_FORMULA, n ) ) &&
                            nullptr != (pTBox = static_cast<const SwTableBoxFormula*>(pItem)->GetTableBox() ) &&
                    auto pFormulaItem = dynamic_cast<const SwTableBoxFormula*>(pItem);
                    if( pFormulaItem &&
                            nullptr != (pTBox = pFormulaItem->GetTableBox() ) &&
                            pTBox->GetSttNd() &&
                            pTBox->GetSttNd()->GetNodes().IsDocNodes() &&
                            ( !bOnlyErrors ||
                              !static_cast<const SwTableBoxFormula*>(pItem)->HasValidBoxes() ) )
                              !pFormulaItem->HasValidBoxes() ) )
                    {
                        const SwContentFrame* pCFrame;
                        SwNodeIndex aIdx( *pTBox->GetSttNd() );
@@ -556,20 +555,19 @@
    {
        const SwTextNode* pTextNd;
        const SwTextTOXMark* pTextTOX;
        sal_uInt32 n, nMaxItems = GetDoc()->GetAttrPool().GetItemCount2( RES_TXTATR_TOXMARK );
        sal_uInt32 nMaxItems = GetDoc()->GetAttrPool().GetItemCount2( RES_TXTATR_TOXMARK );

        if( nMaxItems > 0 )
        {
            do {
                for( n = 0; n < nMaxItems; ++n )
                for (const SfxPoolItem* pItem : GetDoc()->GetAttrPool().GetItemSurrogates(RES_TXTATR_TOXMARK))
                {
                    const SfxPoolItem* pItem;
                    auto pToxMarkItem = dynamic_cast<const SwTOXMark*>(pItem);
                    const SwContentFrame* pCFrame;

                    std::pair<Point, bool> const tmp(aPt, false);
                    if( nullptr != (pItem = GetDoc()->GetAttrPool().GetItem2(
                                                RES_TXTATR_TOXMARK, n ) ) &&
                        nullptr != (pTextTOX = static_cast<const SwTOXMark*>(pItem)->GetTextTOXMark() ) &&
                    if( pToxMarkItem &&
                        nullptr != (pTextTOX = pToxMarkItem->GetTextTOXMark() ) &&
                        ( pTextNd = &pTextTOX->GetTextNode())->GetNodes().IsDocNodes() &&
                        nullptr != (pCFrame = pTextNd->getLayoutFrame(GetLayout(), nullptr, &tmp)) &&
                        ( IsReadOnlyAvailable() || !pCFrame->IsProtected() ))
diff --git a/sw/source/core/doc/DocumentFieldsManager.cxx b/sw/source/core/doc/DocumentFieldsManager.cxx
index 4ef15a9..c9c1d34 100644
--- a/sw/source/core/doc/DocumentFieldsManager.cxx
+++ b/sw/source/core/doc/DocumentFieldsManager.cxx
@@ -700,14 +700,12 @@
    }

    // process all table box formulas
    const SfxPoolItem* pItem;
    sal_uInt32 nMaxItems = m_rDoc.GetAttrPool().GetItemCount2( RES_BOXATR_FORMULA );
    for (sal_uInt32 i = 0; i < nMaxItems; ++i)
    for (const SfxPoolItem* pItem : m_rDoc.GetAttrPool().GetItemSurrogates(RES_BOXATR_FORMULA))
    {
        if( nullptr != (pItem = m_rDoc.GetAttrPool().GetItem2( RES_BOXATR_FORMULA, i ) ) &&
            static_cast<const SwTableBoxFormula*>(pItem)->GetDefinedIn() )
        auto pBoxFormula = dynamic_cast<const SwTableBoxFormula*>(pItem);
        if( pBoxFormula && pBoxFormula->GetDefinedIn() )
        {
            const_cast<SwTableBoxFormula*>(static_cast<const SwTableBoxFormula*>(pItem))->ChangeState( pHt );
            const_cast<SwTableBoxFormula*>(pBoxFormula)->ChangeState( pHt );
        }
    }

@@ -807,13 +805,11 @@
    }

    // calculate the formula at the boxes
    for (sal_uInt32 i = 0; i < nMaxItems; ++i )
    for (const SfxPoolItem* pItem : m_rDoc.GetAttrPool().GetItemSurrogates(RES_BOXATR_FORMULA))
    {
        if( nullptr != (pItem = m_rDoc.GetAttrPool().GetItem2( RES_BOXATR_FORMULA, i ) ) &&
            static_cast<const SwTableBoxFormula*>(pItem)->GetDefinedIn() &&
            !static_cast<const SwTableBoxFormula*>(pItem)->IsValid() )
        auto pFormula = const_cast<SwTableBoxFormula*>(dynamic_cast<const SwTableBoxFormula*>(pItem));
        if( pFormula && pFormula->GetDefinedIn() && !pFormula->IsValid() )
        {
            SwTableBoxFormula* pFormula = const_cast<SwTableBoxFormula*>(static_cast<const SwTableBoxFormula*>(pItem));
            SwTableBox* pBox = pFormula->GetTableBox();
            if( pBox && pBox->GetSttNd() &&
                pBox->GetSttNd()->GetNodes().IsDocNodes() )
diff --git a/sw/source/core/doc/doc.cxx b/sw/source/core/doc/doc.cxx
index 77408b4..de810a4 100644
--- a/sw/source/core/doc/doc.cxx
+++ b/sw/source/core/doc/doc.cxx
@@ -1069,14 +1069,12 @@
/// @return the reference in the doc for the name
const SwFormatRefMark* SwDoc::GetRefMark( const OUString& rName ) const
{
    sal_uInt32 nMaxItems = GetAttrPool().GetItemCount2( RES_TXTATR_REFMARK );
    for( sal_uInt32 n = 0; n < nMaxItems; ++n )
    for (const SfxPoolItem* pItem : GetAttrPool().GetItemSurrogates(RES_TXTATR_REFMARK))
    {
        const SfxPoolItem* pItem;
        if( nullptr == (pItem = GetAttrPool().GetItem2( RES_TXTATR_REFMARK, n ) ))
        auto pFormatRef = dynamic_cast<const SwFormatRefMark*>(pItem);
        if(!pFormatRef)
            continue;

        const SwFormatRefMark* pFormatRef = static_cast<const SwFormatRefMark*>(pItem);
        const SwTextRefMark* pTextRef = pFormatRef->GetTextRefMark();
        if( pTextRef && &pTextRef->GetTextNode().GetNodes() == &GetNodes() &&
            rName == pFormatRef->GetRefName() )
@@ -1091,19 +1089,18 @@
    const SwTextRefMark* pTextRef;
    const SwFormatRefMark* pRet = nullptr;

    sal_uInt32 nMaxItems = GetAttrPool().GetItemCount2( RES_TXTATR_REFMARK );
    sal_uInt32 nCount = 0;
    for( sal_uInt32 n = 0; n < nMaxItems; ++n )
    for (const SfxPoolItem* pItem : GetAttrPool().GetItemSurrogates(RES_TXTATR_REFMARK))
    {
        const SfxPoolItem* pItem;
        auto pRefMark = dynamic_cast<const SwFormatRefMark*>(pItem);

        if( nullptr != (pItem = GetAttrPool().GetItem2( RES_TXTATR_REFMARK, n )) &&
            nullptr != (pTextRef = static_cast<const SwFormatRefMark*>(pItem)->GetTextRefMark()) &&
        if( pRefMark &&
            nullptr != (pTextRef = pRefMark->GetTextRefMark()) &&
            &pTextRef->GetTextNode().GetNodes() == &GetNodes() )
        {
            if(nCount == nIndex)
            {
                pRet = static_cast<const SwFormatRefMark*>(pItem);
                pRet = pRefMark;
                break;
            }
            nCount++;
@@ -1119,19 +1116,18 @@
{
    const SwTextRefMark* pTextRef;

    const sal_uInt32 nMaxItems = GetAttrPool().GetItemCount2( RES_TXTATR_REFMARK );
    sal_uInt16 nCount = 0;
    for( sal_uInt32 n = 0; n < nMaxItems; ++n )
    for (const SfxPoolItem* pItem : GetAttrPool().GetItemSurrogates(RES_TXTATR_REFMARK))
    {
        const SfxPoolItem* pItem;
        auto pRefMark = dynamic_cast<const SwFormatRefMark*>(pItem);

        if( nullptr != (pItem = GetAttrPool().GetItem2( RES_TXTATR_REFMARK, n )) &&
            nullptr != (pTextRef = static_cast<const SwFormatRefMark*>(pItem)->GetTextRefMark()) &&
        if( pRefMark &&
            nullptr != (pTextRef = pRefMark->GetTextRefMark()) &&
            &pTextRef->GetTextNode().GetNodes() == &GetNodes() )
        {
            if( pNames )
            {
                OUString aTmp(static_cast<const SwFormatRefMark*>(pItem)->GetRefName());
                OUString aTmp(pRefMark->GetRefName());
                pNames->insert(pNames->begin() + nCount, aTmp);
            }
            ++nCount;
@@ -1233,20 +1229,18 @@

const SwFormatINetFormat* SwDoc::FindINetAttr( const OUString& rName ) const
{
    const SwFormatINetFormat* pItem;
    const SwTextINetFormat* pTextAttr;
    const SwTextNode* pTextNd;
    sal_uInt32 n, nMaxItems = GetAttrPool().GetItemCount2( RES_TXTATR_INETFMT );
    for( n = 0; n < nMaxItems; ++n )
    for (const SfxPoolItem* pItem : GetAttrPool().GetItemSurrogates(RES_TXTATR_INETFMT))
    {
        pItem = GetAttrPool().GetItem2( RES_TXTATR_INETFMT, n );
        if( nullptr != pItem &&
            pItem->GetName() == rName &&
            nullptr != ( pTextAttr = pItem->GetTextINetFormat()) &&
        auto pFormatItem = dynamic_cast<const SwFormatINetFormat*>(pItem);
        if( pFormatItem &&
            pFormatItem->GetName() == rName &&
            nullptr != ( pTextAttr = pFormatItem->GetTextINetFormat()) &&
            nullptr != ( pTextNd = pTextAttr->GetpTextNode() ) &&
            &pTextNd->GetNodes() == &GetNodes() )
        {
            return pItem;
            return pFormatItem;
        }
    }
    return nullptr;
diff --git a/sw/source/core/doc/docbasic.cxx b/sw/source/core/doc/docbasic.cxx
index 8cab339..2f11382 100644
--- a/sw/source/core/doc/docbasic.cxx
+++ b/sw/source/core/doc/docbasic.cxx
@@ -140,12 +140,10 @@
    case EVENT_OBJECT_INETATTR:
        if( bCheckPtr  )
        {
            sal_uInt32 n, nMaxItems = GetAttrPool().GetItemCount2( RES_TXTATR_INETFMT );
            for( n = 0; n < nMaxItems; ++n )
            for (const SfxPoolItem* pItem : GetAttrPool().GetItemSurrogates(RES_TXTATR_INETFMT))
            {
                const SfxPoolItem* pItem;
                if( nullptr != (pItem = GetAttrPool().GetItem2( RES_TXTATR_INETFMT, n ) )
                    && rCallEvent.PTR.pINetAttr == pItem )
                auto pFormatItem = dynamic_cast<const SwFormatINetFormat*>(pItem);
                if( pFormatItem && rCallEvent.PTR.pINetAttr == pFormatItem )
                {
                    bCheckPtr = false;       // misuse as a flag
                    break;
diff --git a/sw/source/core/doc/docfld.cxx b/sw/source/core/doc/docfld.cxx
index a9c3f25..bd62b58 100644
--- a/sw/source/core/doc/docfld.cxx
+++ b/sw/source/core/doc/docfld.cxx
@@ -452,13 +452,8 @@

    for (sal_uInt16 const nWhichHint : { RES_TXTATR_FIELD, RES_TXTATR_INPUTFIELD })
    {
        sal_uInt32 nMaxItems = GetAttrPool().GetItemCount2(nWhichHint);
        for (sal_uInt32 n = 0; n < nMaxItems; ++n)
        for (const SfxPoolItem* pItem : GetAttrPool().GetItemSurrogates(nWhichHint))
        {
            const SfxPoolItem *const pItem(GetAttrPool().GetItem2(nWhichHint, n));
            if (nullptr == pItem)
                continue;

            const SwFormatField* pFormatField = static_cast<const SwFormatField*>(pItem);
            const SwTextField* pTextField = pFormatField->GetTextField();
            if (!pTextField || !pTextField->GetTextNode().GetNodes().IsDocNodes())
@@ -613,14 +608,8 @@

    for (sal_uInt16 const nWhichHint : { RES_TXTATR_FIELD, RES_TXTATR_INPUTFIELD })
    {
        sal_uInt32 nMaxItems = GetAttrPool().GetItemCount2(nWhichHint);

        for (sal_uInt32 n = 0; n < nMaxItems; ++n)
        for (const SfxPoolItem* pItem : GetAttrPool().GetItemSurrogates(nWhichHint))
        {
            const SfxPoolItem* pItem = GetAttrPool().GetItem2(nWhichHint, n);
            if (!pItem)
                continue;

            SwFormatField* pFormatField = const_cast<SwFormatField*>(static_cast<const SwFormatField*>(pItem));
            SwTextField* pTextField = pFormatField->GetTextField();
            if (!pTextField || !pTextField->GetTextNode().GetNodes().IsDocNodes())
@@ -899,13 +888,8 @@

    for (sal_uInt16 const nWhichHint : { RES_TXTATR_FIELD, RES_TXTATR_INPUTFIELD })
    {
        const sal_uInt32 nMaxItems = rDoc.GetAttrPool().GetItemCount2(nWhichHint);
        for (sal_uInt32 n = 0; n < nMaxItems; ++n)
        for (const SfxPoolItem* pItem : rDoc.GetAttrPool().GetItemSurrogates(nWhichHint))
        {
            const SfxPoolItem* pItem = rDoc.GetAttrPool().GetItem2(nWhichHint, n);
            if (!pItem)
                continue;

            const SwFormatField* pFormatField = static_cast<const SwFormatField*>(pItem);
            const SwTextField* pTextField = pFormatField->GetTextField();
            if (!pTextField || !pTextField->GetTextNode().GetNodes().IsDocNodes())
diff --git a/sw/source/core/doc/docfmt.cxx b/sw/source/core/doc/docfmt.cxx
index c870a63..d1e1cb6 100644
--- a/sw/source/core/doc/docfmt.cxx
+++ b/sw/source/core/doc/docfmt.cxx
@@ -644,11 +644,13 @@
                    nOldWidth = aOld.Get(RES_PARATR_TABSTOP)[ 0 ].GetTabPos();

            bool bChg = false;
            sal_uInt32 nMaxItems = GetAttrPool().GetItemCount2( RES_PARATR_TABSTOP );
            for( sal_uInt32 n = 0; n < nMaxItems; ++n )
                if( nullptr != (pTmpItem = GetAttrPool().GetItem2( RES_PARATR_TABSTOP, n ) ))
            for (const SfxPoolItem* pItem2 : GetAttrPool().GetItemSurrogates(RES_PARATR_TABSTOP))
            {
                auto pTabStopItem = dynamic_cast<const SvxTabStopItem*>(pItem2);
                if(pTabStopItem)
                    bChg |= lcl_SetNewDefTabStops( nOldWidth, nNewWidth,
                                                   *const_cast<SvxTabStopItem*>(static_cast<const SvxTabStopItem*>(pTmpItem)) );
                                                   *const_cast<SvxTabStopItem*>(pTabStopItem) );
            }

            aNew.ClearItem( RES_PARATR_TABSTOP );
            aOld.ClearItem( RES_PARATR_TABSTOP );
@@ -2005,13 +2007,10 @@
    const sal_uInt16 pAttribs[] = {RES_CHRATR_COLOR, RES_CHRATR_HIGHLIGHT, RES_BACKGROUND};
    for (sal_uInt16 nAttrib : pAttribs)
    {
        const sal_uInt32 nCount = rPool.GetItemCount2(nAttrib);
        for (sal_uInt32 j=0; j<nCount; j++)
        for (const SfxPoolItem* pItem : rPool.GetItemSurrogates(nAttrib))
        {
            const SvxColorItem *pItem = static_cast<const SvxColorItem*>(rPool.GetItem2(nAttrib, j));
            if (pItem == nullptr)
                continue;
            Color aColor( pItem->GetValue() );
            auto pColorItem = static_cast<const SvxColorItem*>(pItem);
            Color aColor( pColorItem->GetValue() );
            if (COL_AUTO != aColor)
                aDocColors.insert(aColor);
        }
diff --git a/sw/source/core/doc/doctxm.cxx b/sw/source/core/doc/doctxm.cxx
index a116479..6210e4b 100644
--- a/sw/source/core/doc/doctxm.cxx
+++ b/sw/source/core/doc/doctxm.cxx
@@ -93,10 +93,9 @@
    rArr.clear();

    // Look up all Primary and Secondary via the Pool
    const sal_uInt32 nMaxItems = GetAttrPool().GetItemCount2( RES_TXTATR_TOXMARK );
    for( sal_uInt32 i = 0; i < nMaxItems; ++i )
    for (const SfxPoolItem* pPoolItem : GetAttrPool().GetItemSurrogates(RES_TXTATR_TOXMARK))
    {
        const SwTOXMark* pItem = GetAttrPool().GetItem2( RES_TXTATR_TOXMARK, i );
        const SwTOXMark* pItem = dynamic_cast<const SwTOXMark*>(pPoolItem);
        if( !pItem )
            continue;
        const SwTOXType* pTOXType = pItem->GetTOXType();
diff --git a/sw/source/core/doc/visiturl.cxx b/sw/source/core/doc/visiturl.cxx
index 9a17df6..1e284f1 100644
--- a/sw/source/core/doc/visiturl.cxx
+++ b/sw/source/core/doc/visiturl.cxx
@@ -56,14 +56,13 @@
            sBkmk = "#" + pIURL->GetMark();

        bool bAction = false, bUnLockView = false;
        sal_uInt32 nMaxItems = pDoc->GetAttrPool().GetItemCount2( RES_TXTATR_INETFMT );
        for( sal_uInt32 n = 0; n < nMaxItems; ++n )
        for (const SfxPoolItem* pItem : pDoc->GetAttrPool().GetItemSurrogates(RES_TXTATR_INETFMT))
        {
            const SwFormatINetFormat* pItem = pDoc->GetAttrPool().GetItem2(RES_TXTATR_INETFMT, n );
            if( pItem != nullptr &&
                ( pItem->GetValue() == sURL || ( !sBkmk.isEmpty() && pItem->GetValue() == sBkmk )))
            const SwFormatINetFormat* pFormatItem = dynamic_cast<const SwFormatINetFormat*>(pItem);
            if( pFormatItem != nullptr &&
                ( pFormatItem->GetValue() == sURL || ( !sBkmk.isEmpty() && pFormatItem->GetValue() == sBkmk )))
            {
                const SwTextINetFormat* pTextAttr = pItem->GetTextINetFormat();
                const SwTextINetFormat* pTextAttr = pFormatItem->GetTextINetFormat();
                if (pTextAttr != nullptr)
                {
                    const SwTextNode* pTextNd = pTextAttr->GetpTextNode();
diff --git a/sw/source/core/docnode/node.cxx b/sw/source/core/docnode/node.cxx
index 56c20dc..db564ae 100644
--- a/sw/source/core/docnode/node.cxx
+++ b/sw/source/core/docnode/node.cxx
@@ -670,14 +670,12 @@
        {
            SwFindNearestNode aInfo( *pNd );
            // Over all Nodes of all PageDescs
            sal_uInt32 i, nMaxItems = pDoc->GetAttrPool().GetItemCount2( RES_PAGEDESC );
            for( i = 0; i < nMaxItems; ++i )
            for (const SfxPoolItem* pItem : pDoc->GetAttrPool().GetItemSurrogates(RES_PAGEDESC))
            {
                const SfxPoolItem* pItem;
                if( nullptr != (pItem = pDoc->GetAttrPool().GetItem2( RES_PAGEDESC, i ) ) &&
                    static_cast<const SwFormatPageDesc*>(pItem)->GetDefinedIn() )
                auto pPageDescItem = dynamic_cast<const SwFormatPageDesc*>(pItem);
                if( pPageDescItem && pPageDescItem->GetDefinedIn() )
                {
                    const SwModify* pMod = static_cast<const SwFormatPageDesc*>(pItem)->GetDefinedIn();
                    const SwModify* pMod = pPageDescItem->GetDefinedIn();
                    if( auto pContentNode = dynamic_cast<const SwContentNode*>( pMod) )
                        aInfo.CheckNode( *pContentNode );
                    else if( auto pFormat = dynamic_cast<const SwFormat*>( pMod) )
diff --git a/sw/source/core/edit/edfld.cxx b/sw/source/core/edit/edfld.cxx
index 8b744bf..41a69ac 100644
--- a/sw/source/core/edit/edfld.cxx
+++ b/sw/source/core/edit/edfld.cxx
@@ -179,15 +179,12 @@
            && (static_cast<SwSetExpFieldType*>(rField.GetTyp())->GetType()
                & nsSwGetSetExpType::GSE_STRING)))
    {
        const sal_uInt32 nMaxItems =
            pDoc->GetAttrPool().GetItemCount2( RES_TXTATR_INPUTFIELD );
        for( sal_uInt32 n = 0; n < nMaxItems; ++n )
        for (const SfxPoolItem* pItem : pDoc->GetAttrPool().GetItemSurrogates(RES_TXTATR_INPUTFIELD))
        {
            const SfxPoolItem* pItem = nullptr;
            if( nullptr != (pItem = pDoc->GetAttrPool().GetItem2( RES_TXTATR_INPUTFIELD, n ) )
                && static_cast<const SwFormatField*>(pItem)->GetField() == &rField )
            auto pFormatField = dynamic_cast<const SwFormatField*>(pItem);
            if( pFormatField && pFormatField->GetField() == &rField )
            {
                pTField = const_cast<SwFormatField*>(static_cast<const SwFormatField*>(pItem))->GetTextField();
                pTField = const_cast<SwFormatField*>(pFormatField)->GetTextField();
                break;
            }
        }
@@ -195,15 +192,12 @@
    else if( SwFieldIds::SetExp == rField.Which()
        && static_cast<SwSetExpField&>(rField).GetInputFlag() )
    {
        const sal_uInt32 nMaxItems =
            pDoc->GetAttrPool().GetItemCount2( RES_TXTATR_FIELD );
        for( sal_uInt32 n = 0; n < nMaxItems; ++n )
        for (const SfxPoolItem* pItem : pDoc->GetAttrPool().GetItemSurrogates(RES_TXTATR_FIELD))
        {
            const SfxPoolItem* pItem = nullptr;
            if( nullptr != (pItem = pDoc->GetAttrPool().GetItem2( RES_TXTATR_FIELD, n ) )
                && static_cast<const SwFormatField*>(pItem)->GetField() == &rField )
            auto pFormatField = dynamic_cast<const SwFormatField*>(pItem);
            if( pFormatField && pFormatField->GetField() == &rField )
            {
                pTField = const_cast<SwFormatField*>(static_cast<const SwFormatField*>(pItem))->GetTextField();
                pTField = const_cast<SwFormatField*>(pFormatField)->GetTextField();
                break;
            }
        }
diff --git a/sw/source/core/fields/docufld.cxx b/sw/source/core/fields/docufld.cxx
index 04b4f1c..53e90972 100644
--- a/sw/source/core/fields/docufld.cxx
+++ b/sw/source/core/fields/docufld.cxx
@@ -143,12 +143,10 @@
    {
        // check the flag since the layout NEVER sets it back
        const SfxItemPool &rPool = pDoc->GetAttrPool();
        sal_uInt32 nMaxItems = rPool.GetItemCount2( RES_PAGEDESC );
        for( sal_uInt32 n = 0; n < nMaxItems; ++n )
        for (const SfxPoolItem* pItem : rPool.GetItemSurrogates(RES_PAGEDESC))
        {
            const SwFormatPageDesc *pDesc;
            if( nullptr != (pDesc = rPool.GetItem2( RES_PAGEDESC, n ) )
                && pDesc->GetNumOffset() && pDesc->GetDefinedIn() )
            auto pDesc = dynamic_cast<const SwFormatPageDesc*>(pItem);
            if( pDesc && pDesc->GetNumOffset() && pDesc->GetDefinedIn() )
            {
                const SwContentNode* pNd = dynamic_cast<const SwContentNode*>( pDesc->GetDefinedIn()  );
                if( pNd )
diff --git a/sw/source/core/layout/trvlfrm.cxx b/sw/source/core/layout/trvlfrm.cxx
index 3abc027..86747c4 100644
--- a/sw/source/core/layout/trvlfrm.cxx
+++ b/sw/source/core/layout/trvlfrm.cxx
@@ -1818,14 +1818,12 @@
    const SwPageFrame *pVirtPage = nullptr;
    const SwFrame *pFrame = nullptr;
    const SfxItemPool &rPool = pPage->GetFormat()->GetDoc()->GetAttrPool();
    sal_uInt32 nMaxItems = rPool.GetItemCount2( RES_PAGEDESC );
    for( sal_uInt32 n = 0; n < nMaxItems; ++n )
    for (const SfxPoolItem* pItem : rPool.GetItemSurrogates(RES_PAGEDESC))
    {
        const SfxPoolItem* pItem = rPool.GetItem2( RES_PAGEDESC, n );
        if ( nullptr == pItem )
        const SwFormatPageDesc *pDesc = dynamic_cast<const SwFormatPageDesc*>(pItem);
        if ( !pDesc )
            continue;

        const SwFormatPageDesc *pDesc = static_cast<const SwFormatPageDesc*>(pItem);
        if ( pDesc->GetNumOffset() && pDesc->GetDefinedIn() )
        {
            const SwModify *pMod = pDesc->GetDefinedIn();
diff --git a/sw/source/core/unocore/unostyle.cxx b/sw/source/core/unocore/unostyle.cxx
index 95ad63c..2dfc44e 100644
--- a/sw/source/core/unocore/unostyle.cxx
+++ b/sw/source/core/unocore/unostyle.cxx
@@ -3739,20 +3739,23 @@
    {
        std::set< std::pair< sal_uInt16, text::RubyAdjust > > aRubyMap;
        SwAttrPool& rAttrPool = pDoc->GetAttrPool();
        sal_uInt32 nCount = rAttrPool.GetItemCount2( RES_TXTATR_CJK_RUBY );

        for ( sal_uInt32 nI = 0; nI < nCount; ++nI )
        // do this in two phases otherwise we invalidate the iterators when we insert into the pool
        std::vector<const SwFormatRuby*> vRubyItems;
        for (const SfxPoolItem* pItem : rAttrPool.GetItemSurrogates(RES_TXTATR_CJK_RUBY))
        {
            const SwFormatRuby* pItem = rAttrPool.GetItem2( RES_TXTATR_CJK_RUBY, nI );
            if ( pItem && pItem->GetTextRuby() )
            auto pRubyItem = dynamic_cast<const SwFormatRuby*>(pItem);
            if ( pRubyItem && pRubyItem->GetTextRuby() )
                vRubyItems.push_back(pRubyItem);
        }
        for (const SwFormatRuby* pRubyItem : vRubyItems)
        {
            std::pair< sal_uInt16, text::RubyAdjust > aPair( pRubyItem->GetPosition(), pRubyItem->GetAdjustment() );
            if ( aRubyMap.insert( aPair ).second )
            {
                std::pair< sal_uInt16, text::RubyAdjust > aPair( pItem->GetPosition(), pItem->GetAdjustment() );
                if ( aRubyMap.insert( aPair ).second )
                {
                    std::shared_ptr<SfxItemSet> pItemSet( new SfxItemSet( rAttrPool, svl::Items<RES_TXTATR_CJK_RUBY, RES_TXTATR_CJK_RUBY>{} ) );
                    pItemSet->Put( *pItem );
                    mAutoStyles.push_back( pItemSet );
                }
                std::shared_ptr<SfxItemSet> pItemSet( new SfxItemSet( rAttrPool, svl::Items<RES_TXTATR_CJK_RUBY, RES_TXTATR_CJK_RUBY>{} ) );
                pItemSet->Put( *pRubyItem );
                mAutoStyles.push_back( pItemSet );
            }
        }
    }
diff --git a/sw/source/core/view/vprint.cxx b/sw/source/core/view/vprint.cxx
index 4cff1e4..8f0600d 100644
--- a/sw/source/core/view/vprint.cxx
+++ b/sw/source/core/view/vprint.cxx
@@ -632,13 +632,11 @@
/// Check if the DocNodesArray contains fields.
bool SwViewShell::IsAnyFieldInDoc() const
{
    const SfxPoolItem* pItem;
    sal_uInt32 nMaxItems = mxDoc->GetAttrPool().GetItemCount2( RES_TXTATR_FIELD );
    for( sal_uInt32 n = 0; n < nMaxItems; ++n )
    for (const SfxPoolItem* pItem : mxDoc->GetAttrPool().GetItemSurrogates(RES_TXTATR_FIELD))
    {
        if( nullptr != (pItem = mxDoc->GetAttrPool().GetItem2( RES_TXTATR_FIELD, n )))
        auto pFormatField = dynamic_cast<const SwFormatField*>(pItem);
        if(pFormatField)
        {
            const SwFormatField* pFormatField = static_cast<const SwFormatField*>(pItem);
            const SwTextField* pTextField = pFormatField->GetTextField();
            if( pTextField && pTextField->GetTextNode().GetNodes().IsDocNodes() )
            {
@@ -647,12 +645,11 @@
        }
    }

    nMaxItems = mxDoc->GetAttrPool().GetItemCount2( RES_TXTATR_INPUTFIELD );
    for( sal_uInt32 n = 0; n < nMaxItems; ++n )
    for (const SfxPoolItem* pItem : mxDoc->GetAttrPool().GetItemSurrogates(RES_TXTATR_INPUTFIELD))
    {
        if( nullptr != (pItem = mxDoc->GetAttrPool().GetItem2( RES_TXTATR_INPUTFIELD, n )))
        const SwFormatField* pFormatField = dynamic_cast<const SwFormatField*>(pItem);
        if(pFormatField)
        {
            const SwFormatField* pFormatField = static_cast<const SwFormatField*>(pItem);
            const SwTextField* pTextField = pFormatField->GetTextField();
            if( pTextField && pTextField->GetTextNode().GetNodes().IsDocNodes() )
            {
diff --git a/sw/source/filter/html/htmlflywriter.cxx b/sw/source/filter/html/htmlflywriter.cxx
index 3ff39a9..54051a6 100644
--- a/sw/source/filter/html/htmlflywriter.cxx
+++ b/sw/source/filter/html/htmlflywriter.cxx
@@ -2096,15 +2096,14 @@

void SwHTMLWriter::CollectLinkTargets()
{
    const SwFormatINetFormat* pINetFormat;
    const SwTextINetFormat* pTextAttr;

    sal_uInt32 n, nMaxItems = m_pDoc->GetAttrPool().GetItemCount2( RES_TXTATR_INETFMT );
    for( n = 0; n < nMaxItems; ++n )
    for (const SfxPoolItem* pItem : m_pDoc->GetAttrPool().GetItemSurrogates(RES_TXTATR_INETFMT))
    {
        auto pINetFormat = dynamic_cast<const SwFormatINetFormat*>(pItem);
        const SwTextNode* pTextNd;

        if( nullptr != ( pINetFormat = m_pDoc->GetAttrPool().GetItem2( RES_TXTATR_INETFMT, n ) ) &&
        if( pINetFormat &&
            nullptr != ( pTextAttr = pINetFormat->GetTextINetFormat()) &&
            nullptr != ( pTextNd = pTextAttr->GetpTextNode() ) &&
            pTextNd->GetNodes().IsDocNodes() )
@@ -2113,12 +2112,10 @@
        }
    }

    const SwFormatURL *pURL;
    nMaxItems = m_pDoc->GetAttrPool().GetItemCount2( RES_URL );
    for( n = 0; n < nMaxItems; ++n )
    for (const SfxPoolItem* pItem : m_pDoc->GetAttrPool().GetItemSurrogates(RES_URL))
    {
        if( nullptr != (pURL = m_pDoc->GetAttrPool().GetItem2(
            RES_URL, n ) ) )
        auto pURL = dynamic_cast<const SwFormatURL*>(pItem);
        if( pURL )
        {
            AddLinkTarget( pURL->GetURL() );
            const ImageMap *pIMap = pURL->GetMap();
diff --git a/sw/source/filter/writer/writer.cxx b/sw/source/filter/writer/writer.cxx
index cd4c1f1..8b5c240 100644
--- a/sw/source/filter/writer/writer.cxx
+++ b/sw/source/filter/writer/writer.cxx
@@ -409,10 +409,8 @@
    if( nullptr != ( pFont = static_cast<const SvxFontItem*>(rPool.GetPoolDefaultItem( nW ))) )
        AddFontItem( rPool, *pFont );

    sal_uInt32 nMaxItem = rPool.GetItemCount2( nW );
    for( sal_uInt32 nGet = 0; nGet < nMaxItem; ++nGet )
        if( nullptr != (pFont = static_cast<const SvxFontItem*>(rPool.GetItem2( nW, nGet ))) )
            AddFontItem( rPool, *pFont );
    for (const SfxPoolItem* pItem : rPool.GetItemSurrogates(nW))
        AddFontItem( rPool, *static_cast<const SvxFontItem*>(pItem) );
}

void Writer::AddFontItem( SfxItemPool& rPool, const SvxFontItem& rFont )
diff --git a/sw/source/filter/ww8/rtfexport.cxx b/sw/source/filter/ww8/rtfexport.cxx
index 494c26c..b2b06a7 100644
--- a/sw/source/filter/ww8/rtfexport.cxx
+++ b/sw/source/filter/ww8/rtfexport.cxx
@@ -747,10 +747,9 @@
    // protected section in the document.
    {
        const SfxItemPool& rPool = m_pDoc->GetAttrPool();
        sal_uInt32 const nMaxItem = rPool.GetItemCount2(RES_PROTECT);
        for (sal_uInt32 n = 0; n < nMaxItem; ++n)
        for (const SfxPoolItem* pItem2 : rPool.GetItemSurrogates(RES_PROTECT))
        {
            auto pProtect = rPool.GetItem2(RES_PROTECT, n);
            auto pProtect = dynamic_cast<const SvxProtectItem*>(pItem2);
            if (pProtect && pProtect->IsContentProtected())
            {
                Strm().WriteCharPtr(OOO_STRING_SVTOOLS_RTF_FORMPROT);
@@ -1182,7 +1181,6 @@
{
    // Build the table from rPool since the colors provided to
    // RtfAttributeOutput callbacks are too late.
    sal_uInt32 nMaxItem;
    const SfxItemPool& rPool = m_pDoc->GetAttrPool();

    // MSO Word uses a default color table with 16 colors (which is used e.g. for highlighting)
@@ -1209,28 +1207,25 @@
        InsColor(pCol->GetValue());
        if ((pCol = rPool.GetPoolDefaultItem(RES_CHRATR_COLOR)))
            InsColor(pCol->GetValue());
        nMaxItem = rPool.GetItemCount2(RES_CHRATR_COLOR);
        for (sal_uInt32 n = 0; n < nMaxItem; ++n)
        for (const SfxPoolItem* pItem : rPool.GetItemSurrogates(RES_CHRATR_COLOR))
        {
            if ((pCol = rPool.GetItem2(RES_CHRATR_COLOR, n)))
            if ((pCol = dynamic_cast<const SvxColorItem*>(pItem)))
                InsColor(pCol->GetValue());
        }

        auto pUnder = GetDfltAttr(RES_CHRATR_UNDERLINE);
        InsColor(pUnder->GetColor());
        nMaxItem = rPool.GetItemCount2(RES_CHRATR_UNDERLINE);
        for (sal_uInt32 n = 0; n < nMaxItem; ++n)
        for (const SfxPoolItem* pItem : rPool.GetItemSurrogates(RES_CHRATR_UNDERLINE))
        {
            if ((pUnder = rPool.GetItem2(RES_CHRATR_UNDERLINE, n)))
            if ((pUnder = dynamic_cast<const SvxUnderlineItem*>(pItem)))
                InsColor(pUnder->GetColor());
        }

        auto pOver = GetDfltAttr(RES_CHRATR_OVERLINE);
        InsColor(pOver->GetColor());
        nMaxItem = rPool.GetItemCount2(RES_CHRATR_OVERLINE);
        for (sal_uInt32 n = 0; n < nMaxItem; ++n)
        for (const SfxPoolItem* pItem : rPool.GetItemSurrogates(RES_CHRATR_OVERLINE))
        {
            if ((pOver = rPool.GetItem2(RES_CHRATR_OVERLINE, n)))
            if ((pOver = dynamic_cast<const SvxOverlineItem*>(pItem)))
                InsColor(pOver->GetColor());
        }
    }
@@ -1246,10 +1241,9 @@
        {
            InsColor(pBackground->GetColor());
        }
        nMaxItem = rPool.GetItemCount2(*pIds);
        for (sal_uInt32 n = 0; n < nMaxItem; ++n)
        for (const SfxPoolItem* pItem : rPool.GetItemSurrogates(*pIds))
        {
            if ((pBackground = static_cast<const SvxBrushItem*>(rPool.GetItem2(*pIds, n))))
            if ((pBackground = static_cast<const SvxBrushItem*>(pItem)))
            {
                InsColor(pBackground->GetColor());
            }
@@ -1264,10 +1258,9 @@
        {
            InsColor(pShadow->GetColor());
        }
        nMaxItem = rPool.GetItemCount2(RES_SHADOW);
        for (sal_uInt32 n = 0; n < nMaxItem; ++n)
        for (const SfxPoolItem* pItem : rPool.GetItemSurrogates(RES_SHADOW))
        {
            if (nullptr != (pShadow = rPool.GetItem2(RES_SHADOW, n)))
            if ((pShadow = dynamic_cast<const SvxShadowItem*>(pItem)))
            {
                InsColor(pShadow->GetColor());
            }
@@ -1279,10 +1272,9 @@
        const SvxBoxItem* pBox;
        if (nullptr != (pBox = rPool.GetPoolDefaultItem(RES_BOX)))
            InsColorLine(*pBox);
        nMaxItem = rPool.GetItemCount2(RES_BOX);
        for (sal_uInt32 n = 0; n < nMaxItem; ++n)
        for (const SfxPoolItem* pItem : rPool.GetItemSurrogates(RES_BOX))
        {
            if (nullptr != (pBox = rPool.GetItem2(RES_BOX, n)))
            if ((pBox = dynamic_cast<const SvxBoxItem*>(pItem)))
                InsColorLine(*pBox);
        }
    }
@@ -1291,20 +1283,18 @@
        const SvxBoxItem* pCharBox;
        if ((pCharBox = rPool.GetPoolDefaultItem(RES_CHRATR_BOX)))
            InsColorLine(*pCharBox);
        nMaxItem = rPool.GetItemCount2(RES_CHRATR_BOX);
        for (sal_uInt32 n = 0; n < nMaxItem; ++n)
        for (const SfxPoolItem* pItem : rPool.GetItemSurrogates(RES_CHRATR_BOX))
        {
            if ((pCharBox = rPool.GetItem2(RES_CHRATR_BOX, n)))
            if ((pCharBox = dynamic_cast<const SvxBoxItem*>(pItem)))
                InsColorLine(*pCharBox);
        }
    }

    // TextFrame or paragraph background solid fill.
    nMaxItem = rPool.GetItemCount2(XATTR_FILLCOLOR);
    for (sal_uInt32 i = 0; i < nMaxItem; ++i)
    for (const SfxPoolItem* pItem : rPool.GetItemSurrogates(XATTR_FILLCOLOR))
    {
        if (auto pItem = rPool.GetItem2(XATTR_FILLCOLOR, i))
            InsColor(pItem->GetColorValue());
        if (auto pColorItem = dynamic_cast<const XFillColorItem*>(pItem))
            InsColor(pColorItem->GetColorValue());
    }

    for (std::size_t n = 0; n < m_aColTable.size(); ++n)
diff --git a/sw/source/filter/ww8/wrtw8sty.cxx b/sw/source/filter/ww8/wrtw8sty.cxx
index e4e2495..8725e74 100644
--- a/sw/source/filter/ww8/wrtw8sty.cxx
+++ b/sw/source/filter/ww8/wrtw8sty.cxx
@@ -867,15 +867,11 @@
    const sal_uInt16 aTypes[] = { RES_CHRATR_FONT, RES_CHRATR_CJK_FONT, RES_CHRATR_CTL_FONT, 0 };
    for (const sal_uInt16* pId = aTypes; *pId; ++pId)
    {
        sal_uInt32 const nMaxItem = rPool.GetItemCount2( *pId );
        for (sal_uInt32 nGet = 0; nGet < nMaxItem; ++nGet)
        for (const SfxPoolItem* pItem : rPool.GetItemSurrogates(*pId))
        {
            pFont = static_cast<const SvxFontItem*>(rPool.GetItem2( *pId, nGet ));
            if (nullptr != pFont)
            {
                GetId(wwFont(pFont->GetFamilyName(), pFont->GetPitch(),
                            pFont->GetFamily(), pFont->GetCharSet()));
            }
            pFont = static_cast<const SvxFontItem*>(pItem);
            GetId(wwFont(pFont->GetFamilyName(), pFont->GetPitch(),
                         pFont->GetFamily(), pFont->GetCharSet()));
        }
    }
}
diff --git a/sw/source/filter/ww8/wrtww8.cxx b/sw/source/filter/ww8/wrtww8.cxx
index 5b66db6..07ba40b 100644
--- a/sw/source/filter/ww8/wrtww8.cxx
+++ b/sw/source/filter/ww8/wrtww8.cxx
@@ -3086,10 +3086,9 @@

void MSWordExportBase::CollectOutlineBookmarks(const SwDoc &rDoc)
{
    sal_uInt32 nMaxItems = rDoc.GetAttrPool().GetItemCount2(RES_TXTATR_INETFMT);
    for (sal_uInt32 n = 0; n < nMaxItems; ++n)
    for (const SfxPoolItem* pItem : rDoc.GetAttrPool().GetItemSurrogates(RES_TXTATR_INETFMT))
    {
        const SwFormatINetFormat* pINetFormat = rDoc.GetAttrPool().GetItem2(RES_TXTATR_INETFMT, n);
        auto pINetFormat = dynamic_cast<const SwFormatINetFormat*>(pItem);
        if (!pINetFormat)
            continue;

@@ -3107,10 +3106,9 @@
        AddLinkTarget( pINetFormat->GetValue() );
    }

    nMaxItems = rDoc.GetAttrPool().GetItemCount2( RES_URL );
    for (sal_uInt32 n = 0; n < nMaxItems; ++n)
    for (const SfxPoolItem* pItem : rDoc.GetAttrPool().GetItemSurrogates(RES_URL))
    {
        const SwFormatURL *pURL = rDoc.GetAttrPool().GetItem2(RES_URL, n);
        auto pURL = dynamic_cast<const SwFormatURL*>(pItem);
        if (!pURL)
            continue;

diff --git a/sw/source/filter/xml/xmlexp.cxx b/sw/source/filter/xml/xmlexp.cxx
index 5c21ff3..da40200 100644
--- a/sw/source/filter/xml/xmlexp.cxx
+++ b/sw/source/filter/xml/xmlexp.cxx
@@ -154,24 +154,18 @@
        for( int j=0; j < nWhichIds; ++j )
        {
            const sal_uInt16 nWhichId = aWhichIds[j];
            const sal_uInt32 nItems = rPool.GetItemCount2( nWhichId );
            for( sal_uInt32 i = 0; i < nItems; ++i )
            for (const SfxPoolItem* pItem : rPool.GetItemSurrogates(nWhichId))
            {
                const SfxPoolItem* const pItem = rPool.GetItem2( nWhichId , i );
                if( nullptr != pItem )
                auto pUnknown = dynamic_cast<const SvXMLAttrContainerItem*>( pItem  );
                OSL_ENSURE( pUnknown, "illegal attribute container item" );
                if( pUnknown && (pUnknown->GetAttrCount() > 0) )
                {
                    const SvXMLAttrContainerItem *pUnknown =
                                dynamic_cast<const SvXMLAttrContainerItem*>( pItem  );
                    OSL_ENSURE( pUnknown, "illegal attribute container item" );
                    if( pUnknown && (pUnknown->GetAttrCount() > 0) )
                    sal_uInt16 nIdx = pUnknown->GetFirstNamespaceIndex();
                    while( USHRT_MAX != nIdx )
                    {
                        sal_uInt16 nIdx = pUnknown->GetFirstNamespaceIndex();
                        while( USHRT_MAX != nIdx )
                        {
                            GetNamespaceMap_().Add( pUnknown->GetPrefix( nIdx ),
                                                pUnknown->GetNamespace( nIdx ) );
                            nIdx = pUnknown->GetNextNamespaceIndex( nIdx );
                        }
                        GetNamespaceMap_().Add( pUnknown->GetPrefix( nIdx ),
                                            pUnknown->GetNamespace( nIdx ) );
                        nIdx = pUnknown->GetNextNamespaceIndex( nIdx );
                    }
                }
            }
diff --git a/sw/source/filter/xml/xmlfonte.cxx b/sw/source/filter/xml/xmlfonte.cxx
index 8c11072..7b92a8c 100644
--- a/sw/source/filter/xml/xmlfonte.cxx
+++ b/sw/source/filter/xml/xmlfonte.cxx
@@ -43,7 +43,6 @@
                                      RES_CHRATR_CTL_FONT };

    const SfxItemPool& rPool = _rExport.getDoc()->GetAttrPool();
    const SfxPoolItem* pItem;
    for(sal_uInt16 nWhichId : aWhichIds)
    {
        const SvxFontItem& rFont =
@@ -51,17 +50,12 @@
        Add( rFont.GetFamilyName(), rFont.GetStyleName(),
             rFont.GetFamily(), rFont.GetPitch(),
             rFont.GetCharSet() );
        sal_uInt32 nItems = rPool.GetItemCount2( nWhichId );
        for( sal_uInt32 j = 0; j < nItems; ++j )
        for (const SfxPoolItem* pItem : rPool.GetItemSurrogates(nWhichId))
        {
            if( nullptr != (pItem = rPool.GetItem2( nWhichId, j ) ) )
            {
                const SvxFontItem *pFont =
                            static_cast<const SvxFontItem *>(pItem);
                Add( pFont->GetFamilyName(), pFont->GetStyleName(),
                     pFont->GetFamily(), pFont->GetPitch(),
                     pFont->GetCharSet() );
            }
            auto pFont = static_cast<const SvxFontItem *>(pItem);
            Add( pFont->GetFamilyName(), pFont->GetStyleName(),
                 pFont->GetFamily(), pFont->GetPitch(),
                 pFont->GetCharSet() );
        }
    }
    auto const & pDocument = _rExport.getDoc();