CWS-TOOLING: integrate CWS swrefactormarks2
2009-04-09 12:51:41 +0200 b_michaelsen  r270689 : #i94949# cleaned up assertions after rebasing
2009-04-08 17:37:08 +0200 b_michaelsen  r270658 : fixing sw/source/ui/utlui/makefile.mk
2009-04-07 17:56:54 +0200 b_michaelsen  r270606 : added bookctrl.cxx to EXCEPTIONFILES, because this is needed for stl on unxsols4
2009-04-07 17:05:20 +0200 b_michaelsen  r270603 : added crbm.cxx to EXCEPTIONFILES, because this is needed for stl on unxsols4
2009-04-02 23:44:38 +0200 b_michaelsen  r270436 : CWS-TOOLING: rebase CWS swrefactormarks2 to trunk@270033 (milestone: DEV300:m45)
2009-02-27 16:25:31 +0100 b_michaelsen  r268606 : #i94949# fixed Windows buildbreaker
2009-02-25 18:01:13 +0100 b_michaelsen  r268464 : #i94949# Bookmarktest document filter roundtrips
2009-02-24 18:23:55 +0100 b_michaelsen  r268404 : #i94949# Bookmark unittests
2009-02-23 19:47:44 +0100 b_michaelsen  r268370 : #i94949# added unittest for bookmarks
2009-02-23 12:22:07 +0100 b_michaelsen  r268348 : #i94949# fixing CheckCrossReferences testcase
2009-02-20 18:12:50 +0100 b_michaelsen  r268335 : #i94949# fixing SwXTextRange
2009-02-18 18:32:57 +0100 b_michaelsen  r268252 : #i94949# deregistering DdeBookmarks on delete
2009-02-18 18:29:08 +0100 b_michaelsen  r268251 : fixing dbgoutsw.cxx for debug builds
2009-02-16 18:42:43 +0100 b_michaelsen  r267834 : CWS-TOOLING: rebase CWS swrefactormarks2 to trunk@267171 (milestone: DEV300:m41)
2009-02-12 15:32:02 +0100 b_michaelsen  r267667 : #i94949 fixed crossrefbookmark naming
2009-02-11 18:30:08 +0100 b_michaelsen  r267624 : #94949# fixing bookmark navigation
2009-02-11 13:55:26 +0100 b_michaelsen  r267599 : #i94949# fixed bookmark naming
2009-02-10 17:53:05 +0100 b_michaelsen  r267571 : #i94949# renamed HasOtherMarkPos to IsExpanded
2009-02-10 17:23:01 +0100 b_michaelsen  r267564 : #i94949# renamed ::sw::bookmark namespace to more fitting ::sw::mark
2009-02-10 16:16:32 +0100 b_michaelsen  r267553 : #i94949# creating only CrossRefBookmark per Txtnode
2009-02-10 12:14:05 +0100 b_michaelsen  r267547 : #i94949# fixed bookmark count in navigator
2009-02-09 19:12:18 +0100 b_michaelsen  r267532 : #i94949# lcl_CopyBookmarks(..) - handle marks on boundaries correctly
2009-02-09 17:32:45 +0100 b_michaelsen  r267524 : #i94949# setting the refobject of the DdeBookmark in Sin SwServerObject::SetDdeBookmark(..)
2009-02-09 17:22:15 +0100 b_michaelsen  r267523 : #i94949# trying to harden SwServerObject
2009-02-09 16:47:32 +0100 b_michaelsen  r267521 : #i94949# lcl_CopyBookmarks(..): try to get the source mark name, if possible
2009-02-09 16:05:42 +0100 b_michaelsen  r267519 : #i94949# clearing the OtherMarkPos if PaM has no mark in repositionMark(..), swapping inverted bookmarks without hissing an assertion
2009-02-09 15:55:38 +0100 b_michaelsen  r267518 : #i94949# checking for out-of-bounds in SwView::ExecuteStatusLine(..)
2009-02-09 15:23:47 +0100 b_michaelsen  r267517 : #i94949# using an UNO_BOOKMARK in ui/dbui/dbinsdlg.cxx
2009-02-09 14:14:47 +0100 b_michaelsen  r267514 : #i94949# IDocumentMarkAccess::GetType(..) asserts on unknown type
2009-02-09 14:04:25 +0100 b_michaelsen  r267513 : #i94949# using rtl strings instead of tools-strings in CrossRefBookmarks
2009-02-09 13:55:01 +0100 b_michaelsen  r267510 : #i94949# using empty string for UnoMark construction
2009-02-09 13:46:46 +0100 b_michaelsen  r267509 : #i94949# removed superfluous #includes, removed superfluous member DdeBookmark::bGenerateName, initialized DdeBookmark::m_aRefObj removed superfluous local _FindItem::ClearObj
2009-02-06 14:38:37 +0100 b_michaelsen  r267462 : #i94949# fixing FN_STAT_BOOKMARK dispatches
2009-02-05 18:05:07 +0100 b_michaelsen  r267436 : #i94949# removing superfluous #includes
2009-02-04 15:51:31 +0100 b_michaelsen  r267391 : fixing resync merge error
2009-02-02 19:39:55 +0100 b_michaelsen  r267294 : #i94949# bookmark performance
2009-01-30 19:30:51 +0100 b_michaelsen  r267229 : #i94949# throwing IllegalArgumentException, if appropriate
2009-01-30 19:29:56 +0100 b_michaelsen  r267228 : #i94949# refactored lcl_FillBookmarkArray, comments, constness
2009-01-30 19:23:49 +0100 b_michaelsen  r267227 : #i94949# refactored lcl_FillBookmarkArray, comments, constness
2009-01-30 19:16:06 +0100 b_michaelsen  r267226 : #i94949# refactored lcl_FillBookmarkArray
2009-01-30 17:59:27 +0100 b_michaelsen  r267222 : #i94949# removed superficial #include
2009-01-30 17:50:02 +0100 b_michaelsen  r267220 : #i94949# SwXTextRange remembers its UNO bookmark
2009-01-29 20:19:58 +0100 b_michaelsen  r267168 : #i94949# implemented IDocumentMarkAccess::findBookmark
2009-01-29 17:22:17 +0100 b_michaelsen  r267162 : #i94949# implemented renameMark in Markmanager
2009-01-29 14:17:10 +0100 b_michaelsen  r267134 : #i94949# cleanup in SwXBookmark, whitespace
2009-01-29 13:21:54 +0100 b_michaelsen  r267125 : #i94949# cleanup in SwXBookmark, whitespace
2009-01-29 13:06:10 +0100 b_michaelsen  r267120 : #i94949# cleanup in SwXBookmark, whitespace
2009-01-29 13:00:09 +0100 b_michaelsen  r267118 : #i94949# cleanup in SwXBookmark, whitespace
2009-01-29 10:35:10 +0100 b_michaelsen  r267101 : #i94949# renamed SetCrsrToBkmk to SetCrsrToMark, moving to start/end of doc if no more bookmarks can be found
2009-01-28 17:05:36 +0100 b_michaelsen  r267070 : #i94949# fixed order in aProvNamesId in unocoll.cxx
2009-01-28 15:46:13 +0100 b_michaelsen  r267063 : #i94949# documentation
2009-01-28 15:36:59 +0100 b_michaelsen  r267062 : #i94949# removing superficial #include
2009-01-28 15:30:36 +0100 b_michaelsen  r267061 : #i94949# basic code conventions
2009-01-28 11:14:30 +0100 b_michaelsen  r267039 : #i94949# comparing to the actual name of the new mark
2009-01-26 15:22:25 +0100 b_michaelsen  r266927 : #i94949# performance fixes
2009-01-14 21:16:56 +0100 b_michaelsen  r266332 : #i94949# fixing linux x86-64 compiler warnings
2009-01-14 19:52:06 +0100 b_michaelsen  r266331 : #i94949# fixing some compiler warnings
2008-12-15 13:04:49 +0100 b_michaelsen  r265474 : #i94949# fixed microsoft compiler warnings
2008-12-12 18:26:02 +0100 b_michaelsen  r265434 : #i94949# fixed pro platform buildbreakers
2008-12-11 17:51:24 +0100 b_michaelsen  r265342 : CWS-TOOLING: rebase CWS swrefactormarks2 to trunk@264807 (milestone: DEV300:m37)
2008-12-09 18:30:59 +0100 b_michaelsen  r265134 : #i94949# fixed IDocumentMarkAccess::GetType for new mark inheritance tree
2008-12-09 16:56:26 +0100 b_michaelsen  r265118 : #i94949# fixed deleteMark optimization
2008-12-09 14:55:58 +0100 b_michaelsen  r265092 : #i94949# DdeLink and DdeBookmark
2008-12-05 18:28:05 +0100 b_michaelsen  r264914 : #i94949# fixed InitDoc in bookmarks
2008-12-02 02:23:51 +0100 b_michaelsen  r264649 : #i94949# removed obsolete naming proposal code in SwXTextRange, fixed navigator reminders to forget the oldest reminder when the pool is empty
2008-12-02 02:05:19 +0100 b_michaelsen  r264648 : #i94949# using bisect search for delete
2008-12-02 01:58:16 +0100 b_michaelsen  r264647 : #i94949# using bisect search for delete
2008-12-02 01:37:33 +0100 b_michaelsen  r264646 : #i94949# using bisect search for delete
2008-12-02 01:03:29 +0100 b_michaelsen  r264645 : #i94949# fixed deleteMark crash
2008-12-01 20:55:00 +0100 b_michaelsen  r264638 : #i94949# removed crossrefs from ui enumerations
2008-12-01 15:48:12 +0100 b_michaelsen  r264613 : #i94949# removed superfluous local functions
2008-12-01 15:01:19 +0100 b_michaelsen  r264608 : #i94949# optimized insertion of new marks
2008-12-01 14:33:21 +0100 b_michaelsen  r264603 : #i94949# simplified code finding Fieldmark for a position
2008-12-01 14:05:55 +0100 b_michaelsen  r264598 : #i94949# fixed reverse travelling through marks, removed obsolete getUniqueMarkName()
2008-11-27 18:48:15 +0100 b_michaelsen  r264515 : #i94949# fixed _SaveCntntIdx and friends
2008-11-27 15:59:49 +0100 b_michaelsen  r264500 : #i94949# fix Mark position only in ctor
2008-11-27 15:52:28 +0100 b_michaelsen  r264497 : #i94949# fixed Bug in SwXBookmark, was using pDoc too early
2008-11-26 14:54:22 +0100 b_michaelsen  r264396 : #i94949# fixed documentation, simplified  navigator reminder code
2008-11-24 20:45:51 +0100 b_michaelsen  r264266 : #i94949# removed last obsolete getUniqueMarkName calls
2008-11-24 20:21:35 +0100 b_michaelsen  r264265 : #i94949# fixed typo in IDocumentMarkAccess, removed obsolete getUniqueMarkName calls
2008-11-24 18:34:32 +0100 b_michaelsen  r264264 : #i94949# repositioning of Marks, removed possibility to delete marks by name in the core, refactoring of navigator reminder generation
2008-11-21 14:08:49 +0100 b_michaelsen  r264137 : #i94949# simplified makeMark
2008-11-21 12:07:09 +0100 b_michaelsen  r264120 : #i94949# moved ShortName and KeyCode from IMark to IBookmark
2008-11-19 12:50:49 +0100 b_michaelsen  r263981 : #i94949# starting refactoring of bookmark naming
2008-11-19 11:31:08 +0100 b_michaelsen  r263972 : #i94949# getting rid of obsolete dynamic casts
2008-11-18 19:06:09 +0100 b_michaelsen  r263795 : #i94949# getting rid of index based mark access, IDocumentMarkAccess already provides iterators
2008-11-18 17:50:18 +0100 b_michaelsen  r263792 : #i94949# getting rid of index based mark access, IDocumentMarkAccess already provides iterators
2008-11-18 16:48:20 +0100 b_michaelsen  r263783 : #i94949# removed methods from crsrsh which are already available directly via IDocumentMarkAccess
2008-11-18 11:31:35 +0100 b_michaelsen  r263753 : #i94949# cleaning up mark code in crsrsh
2008-11-17 10:15:25 +0100 b_michaelsen  r263705 : #i94949# removed possible integer overflow
2008-11-14 18:48:45 +0100 b_michaelsen  r263695 : #i94949# management of mark names in MarkManager
2008-11-14 18:23:40 +0100 b_michaelsen  r263693 : #i94949# using polymorphism to do mark-specific setup in SwDoc
2008-11-14 16:27:09 +0100 b_michaelsen  r263684 : #i94949# got rid of makeCrossRefBookmark
2008-11-14 13:03:32 +0100 b_michaelsen  r263674 : #i94949# refactored Correction methods
2008-11-13 12:27:55 +0100 b_michaelsen  r263631 : #i94949# got rid of old-style tools assertions in new code
2008-11-12 16:58:16 +0100 b_michaelsen  r263608 : #i94949# added assertion for unique names
2008-11-12 16:55:18 +0100 b_michaelsen  r263607 : #i94949# maked XFormField deprecated
2008-11-12 13:04:29 +0100 b_michaelsen  r263587 : #i94949# replaced IDocumentMarkAccess::GetType with simple dynamic_cast where possible
2008-11-11 18:45:53 +0100 b_michaelsen  r263572 : #i94949# cleaned up SwHstryBookmark
2008-11-11 13:48:18 +0100 b_michaelsen  r263557 : #i94949# removed dynamic_casts to SwModify by inheriting IMark from it
2008-11-11 11:26:28 +0100 b_michaelsen  r263548 : #i94949# fixed SwXBookmark
2008-11-10 17:01:19 +0100 b_michaelsen  r263529 : #i94949# fixed DdeBookmarks in clipboard
2008-11-10 16:44:52 +0100 b_michaelsen  r263527 : #i94949# formatting
2008-11-10 16:29:16 +0100 b_michaelsen  r263526 : #i94949# fixing unoobj.cxx
2008-11-10 16:23:50 +0100 b_michaelsen  r263525 : #i94949# cleaning up crossrefbookmark.cxx/.hxx
2008-11-10 16:02:08 +0100 b_michaelsen  r263524 : #i94949# Pdf Export should only generate 'real' bookmarks
2008-11-10 15:33:58 +0100 b_michaelsen  r263521 : #i94949# removed const_casts
2008-11-10 15:12:06 +0100 b_michaelsen  r263520 : #i94949# moved _DelBookmarks into MarksManager
2008-11-07 18:48:38 +0100 b_michaelsen  r263480 : #i94949# using iterator interface
2008-11-07 18:41:46 +0100 b_michaelsen  r263478 : #i94949# using iterator interface
2008-11-07 18:07:41 +0100 b_michaelsen  r263477 : #i94949# using iterator interface
2008-11-07 17:54:41 +0100 b_michaelsen  r263476 : #i94949# using iterator interface
2008-11-07 17:44:41 +0100 b_michaelsen  r263475 : #i94949# moved correction methods into MarkManager
2008-11-06 18:47:28 +0100 b_michaelsen  r263404 : #i94949# getting rid of superfluous const_casts
2008-11-06 17:58:01 +0100 b_michaelsen  r263403 : #i94949# no more setting of mark positions outside of the core
2008-11-06 17:08:37 +0100 b_michaelsen  r263401 : #i94949# removed setters from IMark
2008-11-06 13:55:25 +0100 b_michaelsen  r263383 : #i94949 SwDoc does not implement IDocumentMarkAccess anymore
2008-11-04 18:17:03 +0100 b_michaelsen  r263333 : #i94949# began removing IDocumentMarkAccess from SwDoc
2008-11-04 16:48:34 +0100 b_michaelsen  r263330 : removing dead code (SwBitArray) found by mst
2008-11-04 16:29:32 +0100 b_michaelsen  r263329 : removing dead code (SwBitArray) found by mst
2008-11-04 14:57:48 +0100 b_michaelsen  r263326 : removing dead code (SwBitArray) found by mst
2008-11-04 14:50:18 +0100 b_michaelsen  r263325 : #i94949# stricter typing in IDocumentMarkAccess
2008-10-24 15:16:27 +0200 b_michaelsen  r262647 : #i94949# renamed ::sw::bookmark::SimpleMark to NavigatorReminder to fit the IDocumentMarkAccess enum
2008-10-24 15:10:10 +0200 b_michaelsen  r262646 : #i94949# only 'real' bookmark implement IBookmark, Marks also get removed from m_vFieldmarks on delete/clear
2008-10-24 13:06:23 +0200 b_michaelsen  r262636 : #i94949# Fieldmark tabnavigation
2008-10-23 12:16:36 +0200 b_michaelsen  r262619 : #i94949# Fieldmark classes and filters
2008-10-22 13:17:18 +0200 b_michaelsen  r262597 : #i94949# writer import fixes
2008-10-21 11:30:38 +0200 b_michaelsen  r262565 : #i94949# renamed methods containing Bookmark in the generic IMark interface
2008-10-20 14:09:02 +0200 b_michaelsen  r262318 : #i94949# fixed SwDoc::CorrRel
2008-10-16 22:45:13 +0200 b_michaelsen  r262273 : #i94949 simplified Before/After methods
2008-10-16 21:40:57 +0200 b_michaelsen  r262271 : #i94949 renamed SimpleMark to NavigatorReminder
2008-10-16 21:15:23 +0200 b_michaelsen  r262270 : #i94949 using shared_ptr only in MarkManager
2008-10-16 17:46:37 +0200 b_michaelsen  r262269 : #i94949# getFieldmarkBefore and getFieldmarkAfter
2008-10-16 17:12:13 +0200 b_michaelsen  r262265 : #i94949# cleanup in crbm.cxx
2008-10-16 12:49:01 +0200 b_michaelsen  r262257 : #i94949# fixed usage of invalid iterator, fixed invalid cast
2008-10-15 15:34:20 +0200 b_michaelsen  r262239 : #i94949# added moved files
2008-10-15 15:26:45 +0200 b_michaelsen  r262237 : #i94949# initial reimplementation of Bookmarks
diff --git a/sw/inc/IDocumentBookmarkAccess.hxx b/sw/inc/IDocumentBookmarkAccess.hxx
deleted file mode 100644
index 539fb59..0000000
--- a/sw/inc/IDocumentBookmarkAccess.hxx
+++ /dev/null
@@ -1,282 +0,0 @@
/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: IDocumentBookmarkAccess.hxx,v $
 * $Revision: 1.6 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

#ifndef IDOCUMENTBOOKMARKACCESS_HXX_INCLUDED
#define IDOCUMENTBOOKMARKACCESS_HXX_INCLUDED

#include <sal/types.h>

class SwBookmark;
class SwFieldBookmark;
class SwBookmarks;
class SwPaM;
class KeyCode;
class String;
struct SwPosition;
class SwTxtNode;

/** Provides access to the bookmarks of a document.
*/
class IDocumentBookmarkAccess
{
public:
    enum BookmarkType
    {
        BOOKMARK,
        MARK,
        DDE_BOOKMARK,
        UNO_BOOKMARK,
        // --> OD 2007-10-11 #i81002# - bookmark type for cross-references
        CROSSREF_BOOKMARK,
        // <--
 //     FIELDMARK, // for future use...
         FORM_FIELDMARK_TEXT,
         FORM_FIELDMARK_NO_TEXT
    };

    // --> OD 2007-11-16 #i83479#
    enum CrossReferenceBookmarkSubType
    {
        HEADING,
        NUMITEM
    };
    // <--

public:
    /** Returns all bookmarks set at the document.

       @returns
       the bookmarks set at the document.
    */
    virtual const SwBookmarks& getBookmarks() const = 0;

    /** Generates a new bookmark in the document.

       @param rPaM
       [in] the location of the new bookmark.

       @param rKC
       [in] ???

       @param rName
       [in] the name of the new bookmark.

       @param rShortName
       [in] the short name of the new bookmark.

       @param eMark
       [in] the type of the new bookmark.

       @returns
       a pointer to the new bookmark.
    */
    virtual SwBookmark* makeBookmark( /*[in]*/const SwPaM& rPaM, /*[in]*/const KeyCode& rKC,
                                      /*[in]*/const String& rName, /*[in]*/const String& rShortName,
                                      /*[in]*/BookmarkType eMark ) = 0;

    /** Deletes a bookmark.

       @param nPos
       [in] the position of the bookmark to be deleted.
    */
    virtual void deleteBookmark( /*[in]*/sal_uInt16 nPos ) = 0;

    /** Deletes a bookmark.

       @param rName
       [in] the name of the bookmark to be deleted.
    */
    virtual void deleteBookmark( /*[in]*/const String& rName ) = 0;

    /** Checks, if the given name fits to the cross-reference bookmark
        name schema

        OD 2007-10-24 #i81002#

        @author OD

        @param rName
        [in] the name to be checked.

        @returns
        boolean indicating , if the name fits or not
    */
    virtual bool isCrossRefBookmarkName( /*[in]*/const String& rName ) = 0;

    /** Find a bookmark.

       @param rName
       [in] the name of the bookmark to be found.

       @returns
       the position of the bookmark in the bookmark container.
    */
    virtual sal_uInt16 findBookmark(  /*[in]*/const String& rName ) = 0;

    /** Generates a unique bookmark name. The name has to be passed to the
        function, a number will be added to the name if the name is already
        used.

       @param rName
       [in/out] the name of the bookmark.
    */
    virtual void makeUniqueBookmarkName( /*[in/out]*/String& rName ) = 0;

    /** Get the number of ::com::sun::star::text::Bookmarks.

       @param bBkmrk
       [in] if set, only "real" bookmarks are considered.

       @returns
       the number of bookmarks.
    */
    virtual sal_uInt16 getBookmarkCount( /*[in]*/bool bBkmrk) const = 0;

    /** Get a bookmark.

       @param nPos
       [in] the position of the bookmark in the bookmark container.

       @param bBkmrk
       [in] if set, only "real" bookmarks are considered.

       @returns
       the bookmark.
    */
    virtual SwBookmark& getBookmark(  /*[in]*/sal_uInt16 nPos, /*[in]*/bool bBkmrk) = 0;

    /** Get cross-reference bookmark name for certain text node

        OD 2007-11-16 #i83479#

        @author OD

        @param rTxtNode
        [in] reference to text node, whose cross-reference bookmark name has to be returned.

        @param nCrossRefType
        [in] sub type of cross-reference bookmark, whose name has to be returned.

        @returns
        name of cross-reference bookmark of given cross-reference sub type,
        if such a cross-reference bookmark exists at given textnode.
        otherwise, empty string
    */
    virtual String getCrossRefBookmarkName(
            /*[in]*/const SwTxtNode& rTxtNode,
            /*[in]*/const CrossReferenceBookmarkSubType nCrossRefType ) const = 0;

    /** Generates new cross-reference bookmark for given text node of given sub type

        OD 2007-11-16 #i83479#

        @author OD

        @param rTxtNode
        [in] reference to text node, at which the cross-reference bookmark has to be generated.

        @param nCrossRefType
        [in] sub type of cross-reference bookmark.

        @returns
        name of generated cross-reference bookmark.
        If empty, cross-reference bookmark is not generated.
    */
    virtual String makeCrossRefBookmark(
                /*[in]*/const SwTxtNode& rTxtNode,
                /*[in]*/const CrossReferenceBookmarkSubType nCrossRefType ) = 0;

    virtual SwBookmark* getFieldBookmarkFor(const SwPosition &pos) const = 0;
    virtual SwFieldBookmark* getFormFieldBookmarkFor(const SwPosition &pos) const = 0;
    virtual SwBookmark* getNextFieldBookmarkFor(const SwPosition &pos) const = 0;
    virtual SwBookmark* getPrevFieldBookmarkFor(const SwPosition &pos) const = 0;

protected:
    virtual ~IDocumentBookmarkAccess() {};
};

namespace bookmarkfunc
{
    /** return the prefix used for cross-reference bookmark for headings

        OD 2007-11-16 #i83479#

        @author OD
    */
    const String getHeadingCrossRefBookmarkNamePrefix();

    /** return the prefix used for cross-reference bookmark for numbered items

        OD 2007-11-16 #i83479#

        @author OD
    */
    const String getNumItemCrossRefBookmarkNamePrefix();

    /** Checks, if the given name fits to the heading cross-reference bookmark
        name schema

        OD 2007-11-09 #i81002#

        @author OD

        @param rName
        [in] the name to be checked.

        @returns
        boolean indicating , if the name fits or not
    */
    bool isHeadingCrossRefBookmarkName( /*[in]*/const String& rName );

    /** Checks, if the given name fits to the numbered item cross-reference
        bookmark name schema

        OD 2007-11-09 #i81002#

        @author OD

        @param rName
        [in] the name to be checked.

        @returns
        boolean indicating , if the name fits or not
    */
    bool isNumItemCrossRefBookmarkName( /*[in]*/const String& rName );

    /** generate new name for a cross-reference bookmark of given sub type

        OD 2007-11-16 #i83479#

        @author OD
    */
    String generateNewCrossRefBookmarkName(
            /*[in]*/const IDocumentBookmarkAccess::CrossReferenceBookmarkSubType nSubType );
}
#endif // IDOCUMENTBOOKMARKACCESS_HXX_INCLUDED
diff --git a/sw/inc/IDocumentMarkAccess.hxx b/sw/inc/IDocumentMarkAccess.hxx
new file mode 100644
index 0000000..56a6050
--- /dev/null
+++ b/sw/inc/IDocumentMarkAccess.hxx
@@ -0,0 +1,247 @@
/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: IDocumentMarkAccess.hxx,v $
 * $Revision: 1.4.42.3 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

#ifndef IDOCUMENTMARKACCESS_HXX_INCLUDED
#define IDOCUMENTMARKACCESS_HXX_INCLUDED

#include <sal/types.h>
#include <IMark.hxx>
#include <boost/shared_ptr.hpp>

class SwPaM;
class KeyCode;
class String;
struct SwPosition;
class SwTxtNode;

namespace sw { namespace mark {
    class SaveBookmark; // FIXME: Ugly: SaveBookmark is a core-internal class, and should not be used in the interface
}}

/** Provides access to the marks of a document.
*/
class IDocumentMarkAccess
{
    public:
        enum MarkType
        {
            UNO_BOOKMARK,
            DDE_BOOKMARK,
            BOOKMARK,
            CROSSREF_HEADING_BOOKMARK,
            CROSSREF_NUMITEM_BOOKMARK,
            TEXT_FIELDMARK,
            CHECKBOX_FIELDMARK,
            NAVIGATOR_REMINDER
        };

        typedef ::boost::shared_ptr< ::sw::mark::IMark> pMark_t;
        typedef ::std::vector< pMark_t > container_t;
        typedef container_t::iterator iterator_t;
        typedef container_t::const_iterator const_iterator_t;
        typedef container_t::const_reverse_iterator const_reverse_iterator_t;

        /** Generates a new mark in the document for a certain selection.

           @param rPaM
           [in] the selection being marked.

           @param rProposedName
           [in] the proposed name of the new mark.

           @param eMark
           [in] the type of the new mark.

           @returns
           a pointer to the new mark (name might have changed).
        */
        virtual ::sw::mark::IMark* makeMark(const SwPaM& rPaM,
            const ::rtl::OUString& rProposedName,
            MarkType eMark) =0;

        /** Returns a mark in the document for a paragraph.
            If there is none, a mark will be created.

           @param rTxtNode
           [in] the paragraph being marked (a selection over the paragraph is marked)

           @param eMark
           [in] the type of the new mark.

           @returns
           a pointer to the new mark (name might have changed).
        */
        virtual ::sw::mark::IMark* getMarkForTxtNode(const SwTxtNode& rTxtNode,
            MarkType eMark) =0;

        /** Moves an existing mark to a new selection and performs needed updates.
            @param io_pMark
            [in/out] the mark to be moved

            @param rPaM
            [in] new selection to be marked
        */

        virtual void repositionMark(::sw::mark::IMark* io_pMark,
            const SwPaM& rPaM) =0;

        /** Renames an existing Mark, if possible.
            @param io_pMark
            [in/out] the mark to be renamed

            @param rNewName
            [in] new name for the mark

            @returns false, if renaming failed (because the name is already in use)
        */
            virtual bool renameMark(::sw::mark::IMark* io_pMark,
                const ::rtl::OUString& rNewName) =0;

        /** Corrects marks (absolute)
            This method ignores the previous position of the mark in the paragraph

            @param rOldNode
            [in] the node from which nodes should be moved

            @param rNewPos
            [in] new position to which marks will be moved, if nOffset == 0

            @param nOffset
            [in] the offset by which the mark gets positioned of rNewPos
        */
        virtual void correctMarksAbsolute(const SwNodeIndex& rOldNode,
            const SwPosition& rNewPos,
            const xub_StrLen nOffset) =0;

        /** Corrects marks (relative)
            This method uses the previous position of the mark in the paragraph as offset

            @param rOldNode
            [in] the node from which nodes should be moved

            @param rNewPos
            [in] new position to which marks from the start of the paragraph will be
                 moved, if nOffset == 0

            @param nOffset
            [in] the offset by which the mark gets positioned of rNewPos in addition to
                 its old position in the paragraph
        */
        virtual void correctMarksRelative(const SwNodeIndex& rOldNode,
            const SwPosition& rNewPos,
            const xub_StrLen nOffset) =0;

        /** Deletes marks in a range
        */
        virtual void deleteMarks(
            const SwNodeIndex& rStt,
            const SwNodeIndex& rEnd,
            ::std::vector< ::sw::mark::SaveBookmark>* pSaveBkmk, // Ugly: SaveBookmark is core-internal
            const SwIndex* pSttIdx,
            const SwIndex* pEndIdx) =0;

        /** Deletes a mark.

            @param ppMark
            [in] an iterator pointing to the Mark to be deleted.
        */
        virtual void deleteMark(const IDocumentMarkAccess::const_iterator_t ppMark) =0;

        /** Deletes a mark.

            @param ppMark
            [in] the name of the mark to be deleted.
        */
        virtual void deleteMark(const ::sw::mark::IMark* const pMark) =0;

        /** Clear (deletes) all marks.
        */
        virtual void clearAllMarks() =0;

        /** returns a STL-like random access iterator to the begin of the sequence of marks.
        */
        virtual const_iterator_t getMarksBegin() const =0;

        /** returns a STL-like random access iterator to the end of the sequence of marks.
        */
        virtual const_iterator_t getMarksEnd() const =0;

        /** returns the number of marks.
        */
        virtual sal_Int32 getMarksCount() const =0;

        /** Finds a mark by name.

            @param rName
            [in] the name of the mark to find.

            @returns
            an iterator pointing to the mark, or pointing to getMarksEnd() if nothing was found.
        */
        virtual const_iterator_t findMark(const ::rtl::OUString& rMark) const =0;


        // interface IBookmarks (BOOKMARK, CROSSREF_NUMITEM_BOOKMARK, CROSSREF_HEADING_BOOKMARK)

        /** returns a STL-like random access iterator to the begin of the sequence the IBookmarks.
        */
        virtual const_iterator_t getBookmarksBegin() const =0;

        /** returns a STL-like random access iterator to the end of the sequence of IBookmarks.
        */
        virtual const_iterator_t getBookmarksEnd() const =0;

        /** returns the number of IBookmarks.
        */
        virtual sal_Int32 getBookmarksCount() const =0;

        /** Finds a bookmark by name.

            @param rName
            [in] the name of the bookmark to find.

            @returns
            an iterator pointing to the bookmark, or getBookmarksEnd() if nothing was found.
        */
        virtual const_iterator_t findBookmark(const ::rtl::OUString& rMark) const =0;


        // Fieldmarks
        virtual ::sw::mark::IFieldmark* getFieldmarkFor(const SwPosition& pos) const =0;
        virtual ::sw::mark::IFieldmark* getFieldmarkBefore(const SwPosition& pos) const =0;
        virtual ::sw::mark::IFieldmark* getFieldmarkAfter(const SwPosition& pos) const =0;

        // Returns the MarkType used to create the mark
        static MarkType SAL_DLLPUBLIC_EXPORT GetType(const ::sw::mark::IMark& rMark);
    protected:
        virtual ~IDocumentMarkAccess() {};
};

#endif // IDOCUMENTBOOKMARKACCESS_HXX_INCLUDED
diff --git a/sw/inc/IMark.hxx b/sw/inc/IMark.hxx
new file mode 100644
index 0000000..81317d6
--- /dev/null
+++ b/sw/inc/IMark.hxx
@@ -0,0 +1,115 @@
/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: bookmrk.hxx,v $
 * $Revision: 1.11 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/
#ifndef _IMARK_HXX
#define _IMARK_HXX

#include <vcl/keycod.hxx>
#include <calbck.hxx>
#include <pam.hxx>
#include <boost/operators.hpp>

#ifndef SW_DECL_SWSERVEROBJECT_DEFINED
#define SW_DECL_SWSERVEROBJECT_DEFINED
SV_DECL_REF( SwServerObject )
#endif


struct SwPosition;

namespace sw { namespace mark
{
    class IMark
        : virtual public SwModify // inherited as interface
        , public ::boost::totally_ordered<IMark>
    {
        public:
            //getters
            virtual const SwPosition& GetMarkPos() const =0;
            // GetOtherMarkPos() is only guaranteed to return a valid
            // reference if IsExpanded() returned true
            virtual const SwPosition& GetOtherMarkPos() const =0;
            virtual const SwPosition& GetMarkStart() const =0;
            virtual const SwPosition& GetMarkEnd() const =0;
            virtual const ::rtl::OUString& GetName() const =0;
            virtual bool IsExpanded() const =0;
            virtual bool IsCoveringPosition(const SwPosition& rPos) const =0;

            //setters
            // not available in IMark
            // inside core, you can cast to MarkBase and use its setters,
            // make sure to update the sortings in Markmanager in this case

            //operators and comparisons (non-virtual)
            bool operator<(const IMark& rOther) const
                { return GetMarkStart() < rOther.GetMarkStart(); }
            bool operator==(const IMark& rOther) const
                { return GetMarkStart() == rOther.GetMarkStart(); }
            bool StartsBefore(const SwPosition& rPos) const
                { return GetMarkStart() < rPos; }
            bool StartsAfter(const SwPosition& rPos) const
                { return GetMarkStart() > rPos; }
            bool EndsBefore(const SwPosition& rPos) const
                { return GetMarkEnd() < rPos; }
            bool EndsAfter(const SwPosition& rPos) const
                { return GetMarkEnd() > rPos; }
    };

    class IBookmark
        : virtual public IMark
    {
        public:
            virtual const ::rtl::OUString& GetShortName() const =0;
            virtual const KeyCode& GetKeyCode() const =0;
            virtual void SetShortName(const ::rtl::OUString&) =0;
            virtual void SetKeyCode(const KeyCode&) =0;
    };

    class IFieldmark
        : virtual public IMark
    {
        public:
            //getters
            virtual ::rtl::OUString GetFieldname() const =0;
            virtual ::rtl::OUString GetFieldHelptext() const =0;

            //setters
            virtual void SetFieldname(const ::rtl::OUString& rFieldname) =0;
            virtual void SetFieldHelptext(const ::rtl::OUString& rFieldHelptext) =0;
    };

    class ICheckboxFieldmark
        : virtual public IFieldmark
    {
        public:
            virtual bool IsChecked() const =0;
            virtual void SetChecked(bool checked) =0;
    };
}}
#endif
diff --git a/sw/inc/SwBitArray.hxx b/sw/inc/SwBitArray.hxx
deleted file mode 100644
index f564701..0000000
--- a/sw/inc/SwBitArray.hxx
+++ /dev/null
@@ -1,185 +0,0 @@
/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: SwBitArray.hxx,v $
 * $Revision: 1.6 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/
#ifndef _SW_BIT_ARRAY_HXX
#define _SW_BIT_ARRAY_HXX

#include <swtypes.hxx>
#if OSL_DEBUG_LEVEL > 1
#include <iostream>
#endif

/**
    a bit array
*/
class SwBitArray
{
    /**
       size of a group of bits
    */
    static const size_t mGroupSize = sizeof(sal_uInt32);

    /**
       Returns number of groups.

       @return number of groups
    */
    size_t calcSize() const { return (nSize - 1)/ mGroupSize + 1; }

    /**
       array of group of bits
    */
    sal_uInt32 * mArray;

    /**
       number of groups
    */
    sal_uInt32 nSize;

    /**
       Returns group of bits according to an index.

       @param n     index to search for

       @return group of bits according to given index
     */
    sal_uInt32 * GetGroup(sal_uInt32 n) const { return &mArray[n/mGroupSize]; }

public:
    SwBitArray(sal_uInt32 _nSize);
    SwBitArray(const SwBitArray & rArray);
    ~SwBitArray();

    /**
       Returns if an index is valid.

       @retval TRUE    the index is valid
       @retval FALSE   else
    */
    BOOL IsValid(sal_uInt32 n) const;

    /**
       Returns the number of bits stored in the array.

       @return number of bits in the array
    */
    sal_uInt32 Size() const { return nSize; }

    /**
       Sets/unsets a bit.

       @param n     index of bit to set/unset
       @param nValue   -TRUE   set the bit
                       -FALSE  unset the bit
     */
    void Set(sal_uInt32 n, BOOL nValue);

    /**
       Unsets all bits of the array.
     */
    void Reset();

    /**
       Returns if a certain bit in the array is set.

       @param n     index of the bit in question

       @retval TRUE    the bit is set
       @retval FALSE   else
    */
    BOOL Get(sal_uInt32 n) const;

    /**
       Assigns a bit array to this bit array.

       @param rArray    array to assign

       rArray must have the same size as this array. Otherwise this
       array will not be altered.
     */
    SwBitArray & operator = (const SwBitArray & rArray);

    /**
       Returns the bitwise AND of two bit arrays.

       @param rA
       @param rB      the arrays to combine

       @return bitwise AND of rA and rB
     */
    friend SwBitArray operator & (const SwBitArray & rA,
                                  const SwBitArray & rB);

    /**
       Returns the bitwise OR of two bit arrays.

       @param rA
       @param rB      the arrays to combine

       @return bitwise OR of rA and rB
     */
    friend SwBitArray operator | (const SwBitArray & rA,
                                  const SwBitArray & rB);

    /**
       Returns the bitwise XOR of two bit arrays.

       @param rA
       @param rB      the arrays to combine

       @return bitwise XOR of rA and rB
     */
    friend SwBitArray operator ^ (const SwBitArray & rA,
                                  const SwBitArray & rB);

    /**
       Returns the bitwise NOT of an arrays.

       @param rA     the array to negate

       @return bitwise NOT of rA
     */
    friend SwBitArray operator ~ (const SwBitArray & rA);

#if OSL_DEBUG_LEVEL > 1
    /**
       output operator

       @param o      output stream
       @param rBitArray      bit array to output

       @return o after the output
    */
    friend std::ostream & operator <<
        (std::ostream & o, const SwBitArray & rBitArray);
#endif
};


#endif  // _SW_BIT_ARRAY_HXX
diff --git a/sw/inc/bookmrk.hxx b/sw/inc/bookmrk.hxx
deleted file mode 100644
index 3b459f61..0000000
--- a/sw/inc/bookmrk.hxx
+++ /dev/null
@@ -1,218 +0,0 @@
/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: bookmrk.hxx,v $
 * $Revision: 1.11 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/
#ifndef _BOOKMRK_HXX
#define _BOOKMRK_HXX

#include "hintids.hxx"      //die Ids der Attribute, vor macitem damit die
                            //die Attribut richtig angezogen werden.
#include <svtools/macitem.hxx>

#ifndef _KEYCOD_HXX //autogen
#include <vcl/keycod.hxx>
#endif
#ifndef _TOOLS_REF_HXX
#include <tools/ref.hxx>
#endif
#include <IDocumentBookmarkAccess.hxx>
#include <calbck.hxx>
#include <pam.hxx>

#ifndef SW_DECL_SWSERVEROBJECT_DEFINED
#define SW_DECL_SWSERVEROBJECT_DEFINED
SV_DECL_REF( SwServerObject )
#endif


struct SwPosition;  // fwd Decl. wg. UI

class SwBookmark : public SwModify
{
    SwPosition *pPos1, *pPos2;  // wird im CTOR gesetzt, im DTOR geloescht
                                // pPos1 is always != 0, pPos2 may be 0
    SwServerObjectRef refObj;   // falls DataServer -> Pointer gesetzt

protected:
    String      aName;
    String      aShortName;
    KeyCode     aCode;
    IDocumentBookmarkAccess::BookmarkType eMarkType;

    SwBookmark( const SwPosition& aPos,
                const KeyCode& rCode,
                const String& rName, const String& rShortName);

public:
    TYPEINFO();

    SwBookmark( const SwPosition& aPos );
    // --> OD 2007-09-26 #i81002#
    SwBookmark( const SwPaM& aPaM,
                const KeyCode& rCode,
                const String& rName, const String& rShortName);
    // <--

    // Beim Loeschen von Text werden Bookmarks mitgeloescht!
    virtual ~SwBookmark();

    // --> OD 2007-10-10 #i81002#
    // made virtual and thus no longer inline
    virtual const SwPosition& GetBookmarkPos() const;
    virtual const SwPosition* GetOtherBookmarkPos() const;
    // <--

    // nicht undofaehig
    const String& GetName() const { return aName; }
    // nicht undofaehig
    const String& GetShortName() const { return aShortName; }
    // nicht undofaehig
    const KeyCode& GetKeyCode() const { return aCode; }

    // Vergleiche auf Basis der Dokumentposition
    BOOL operator < (const SwBookmark &) const;
    BOOL operator ==(const SwBookmark &) const;
    // falls man wirklich auf gleiche Position abfragen will.
    BOOL IsEqualPos( const SwBookmark &rBM ) const;

    BOOL IsFormFieldMark() const    { return IDocumentBookmarkAccess::FORM_FIELDMARK_TEXT == eMarkType || IDocumentBookmarkAccess::FORM_FIELDMARK_NO_TEXT == eMarkType; }
    BOOL IsBookMark() const     { return IDocumentBookmarkAccess::BOOKMARK == eMarkType || IDocumentBookmarkAccess::FORM_FIELDMARK_TEXT == eMarkType || IDocumentBookmarkAccess::FORM_FIELDMARK_NO_TEXT == eMarkType; }
//    // --> OD 2007-10-17 #TESTING#
//    BOOL IsBookMark() const
//    {
//        return IDocumentBookmarkAccess::BOOKMARK == eMarkType ||
//               IsCrossRefMark();
//    }
//    // <--
    BOOL IsMark() const         { return IDocumentBookmarkAccess::MARK == eMarkType; }
    BOOL IsUNOMark() const      { return IDocumentBookmarkAccess::UNO_BOOKMARK == eMarkType; }
    // --> OD 2007-10-11 #i81002# - bookmark type for cross-references
    BOOL IsCrossRefMark() const { return IDocumentBookmarkAccess::CROSSREF_BOOKMARK == eMarkType; }
    // <--
    void SetType( IDocumentBookmarkAccess::BookmarkType eNewType )  { eMarkType = eNewType; }
    IDocumentBookmarkAccess::BookmarkType GetType() const   { return eMarkType; }

        // Daten Server-Methoden
    void SetRefObject( SwServerObject* pObj );
    const SwServerObject* GetObject() const     {  return &refObj; }
          SwServerObject* GetObject()           {  return &refObj; }
    BOOL IsServer() const                       {  return refObj.Is(); }

    // --> OD 2007-10-10 #i81002#
    // made virtual and thus no longer inline
    // to access start and end of a bookmark.
    // start and end may be the same
    virtual const SwPosition* BookmarkStart() const;
    virtual const SwPosition* BookmarkEnd() const;
    // <--

    // --> OD 2007-09-26 #i81002#
    virtual void SetBookmarkPos( const SwPosition* pNewPos1 );
    virtual void SetOtherBookmarkPos( const SwPosition* pNewPos2 );
    // <--

private:
    // fuer METWARE:
    // es wird (vorerst) nicht kopiert und nicht zugewiesen
    SwBookmark(const SwBookmark &);
    SwBookmark &operator=(const SwBookmark &);
};

class SwMark: public SwBookmark
{
public:
    SwMark( const SwPosition& aPos,
            const KeyCode& rCode,
            const String& rName, const String& rShortName);
};

class SW_DLLPUBLIC SwFieldBookmark : public SwBookmark
{
private:
    int fftype; // Type: 0 = Text, 1 = Check Box, 2 = List
    int ffres;
    bool ffprot;
    bool ffsize; // 0 = Auto, 1=Exact (see ffhps)
    int fftypetxt; // Type of text field: 0 = Regular text, 1 = Number, 2 = Date, 3 = Current date, 4 = Current time, 5 = Calculation
    bool ffrecalc;
    int ffmaxlen; // Number of characters for text field. Zero means unlimited.
    int ffhps; // Check box size (half-point sizes).

    String ffname;
    String ffhelptext;

public:
    SwFieldBookmark(const SwPosition& aPos,
           const KeyCode& rCode,
           const String& rName, const String& rShortName,
           IDocumentBookmarkAccess::BookmarkType eMark);

    void SetFieldType(int fftype);
    int GetFieldType();

    void SetChecked(bool checked);
    bool IsChecked();

    void SetFFName(String aNewName) {
        this->ffname=aNewName;
    }

    String GetFFName()
    {
        return ffname;
    }

    int GetFFRes() {
        return ffres;
    }

    void SetFFRes(int nNew) {
        this->ffres=nNew;
    }

    void SetFFHelpText(String newffhelptext) {
        this->ffhelptext=newffhelptext;
    }

    String GetFFHelpText() {
        return ffhelptext;
    }
};

class SwUNOMark: public SwBookmark
{
public:
    // --> OD 2007-09-26 #i81002#
    SwUNOMark( const SwPaM& aPaM,
               const KeyCode& rCode,
               const String& rName, const String& rShortName);
    // <--
};


#endif
diff --git a/sw/inc/crossrefbookmark.hxx b/sw/inc/crossrefbookmark.hxx
deleted file mode 100644
index a8b1f78..0000000
--- a/sw/inc/crossrefbookmark.hxx
+++ /dev/null
@@ -1,72 +0,0 @@
/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: crossrefbookmark.hxx,v $
 * $Revision: 1.3 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/
#ifndef _CROSSREFBOOKMRK_HXX
#define _CROSSREFBOOKMRK_HXX

#include <bookmrk.hxx>

/** Bookmark for cross-references

    OD 2007-10-11 #i81002#
    Bookmark, which bookmarks a complete text node (heading or numbered paragraph)
    for cross-referencing.
    <GetBookmarkPos()> is always at the beginning of this text node and
    <GetOtherBookmarkPos()> is always NULL.

    @author OD
*/
class SwCrossRefBookmark : public SwBookmark
{
public:
    TYPEINFO();

    SwCrossRefBookmark( const SwPosition& aPos,
                        const KeyCode& rCode,
                        const String& rName,
                        const String& rShortName );

    virtual ~SwCrossRefBookmark();

    virtual const SwPosition* GetOtherBookmarkPos() const;

    virtual void SetBookmarkPos( const SwPosition* pNewPos1 );
    virtual void SetOtherBookmarkPos( const SwPosition* /*pNewPos2*/ );

    IDocumentBookmarkAccess::CrossReferenceBookmarkSubType GetSubType() const;
private:
    // --> OD 2007-11-16 #i83479#
    IDocumentBookmarkAccess::CrossReferenceBookmarkSubType mnSubType;
    // <--

    // no copy-constructor and no assignment-operator
    SwCrossRefBookmark(const SwCrossRefBookmark &);
    SwCrossRefBookmark &operator=(const SwCrossRefBookmark &);
};
#endif
diff --git a/sw/inc/crsrsh.hxx b/sw/inc/crsrsh.hxx
index 2a66b9a..4fae1ca 100644
--- a/sw/inc/crsrsh.hxx
+++ b/sw/inc/crsrsh.hxx
@@ -44,7 +44,7 @@
#include <viscrs.hxx>
#include <node.hxx>
#include <tblsel.hxx>
#include <IDocumentBookmarkAccess.hxx>
#include <IDocumentMarkAccess.hxx>


// einige Forward Deklarationen
@@ -52,8 +52,6 @@
class KeyCode;
class SfxItemSet;
class SfxPoolItem;
class SwBookmark;
class SwFieldBookmark;
class SwCntntFrm;
class SwCrsrShell;
class SwCursor;
@@ -583,28 +581,22 @@ public:
    // gehe zur vorherigen Selection
    BOOL GoPrevCrsr();

    // am CurCrsr.SPoint
    BOOL SetBookmark( const KeyCode&, const String& rName,
                const String& rShortName, IDocumentBookmarkAccess::BookmarkType eMark = IDocumentBookmarkAccess::BOOKMARK);
    BOOL GotoBookmark( USHORT );    // setzt CurCrsr.SPoint
    BOOL GotoBookmark( USHORT nPos, BOOL bAtStart ); //
    BOOL GoNextBookmark(); // TRUE, wenn's noch eine gab
    BOOL GoPrevBookmark();
    USHORT GetBookmarkCnt(BOOL bBkmrk = FALSE) const;
    SwBookmark& GetBookmark( USHORT, BOOL bBkmrk = FALSE );
    void DelBookmark( USHORT );
    void DelBookmark( const String& rName );
    USHORT FindBookmark( const String& rName );
        // erzeugt einen eindeutigen Namen. Der Name selbst muss vorgegeben
        // werden, es wird dann bei gleichen Namen nur durchnumeriert.
    void MakeUniqueBookmarkName( String& rNm );
    // at CurCrsr.SPoint
    ::sw::mark::IMark* SetBookmark(
        const KeyCode&,
        const ::rtl::OUString& rName,
        const ::rtl::OUString& rShortName,
        IDocumentMarkAccess::MarkType eMark = IDocumentMarkAccess::BOOKMARK);
    bool GotoMark( const ::sw::mark::IMark* const pMark );    // sets CurCrsr.SPoint
    bool GotoMark( const ::sw::mark::IMark* const pMark, bool bAtStart );
    bool GoNextBookmark(); // true, if there was one
    bool GoPrevBookmark();

        bool IsFormProtected();
        SwBookmark* IsInFieldBookmark();
        SwFieldBookmark* IsInFormFieldBookmark();
        SwBookmark* GetNextFieldBookmark();
        SwBookmark* GetPrevFieldBookmark();
        bool GotoFieldBookmark(SwBookmark *pBkmk);
    bool IsFormProtected();
    ::sw::mark::IFieldmark* GetCurrentFieldmark();
    ::sw::mark::IFieldmark* GetFieldmarkAfter();
    ::sw::mark::IFieldmark* GetFieldmarkBefore();
    bool GotoFieldmark( const ::sw::mark::IFieldmark* const pMark );

    // aktualisiere den Crsrs, d.H. setze ihn wieder in den Content.
    // Das sollte nur aufgerufen werden, wenn der Cursor z.B. beim
diff --git a/sw/inc/doc.hxx b/sw/inc/doc.hxx
index 8fe60d0..96d1ce6 100644
--- a/sw/inc/doc.hxx
+++ b/sw/inc/doc.hxx
@@ -39,7 +39,7 @@
#ifndef IDOCUMENTDEVICEACCESS_HXX_INCLUDED
#include <IDocumentDeviceAccess.hxx>
#endif
#include <IDocumentBookmarkAccess.hxx>
#include <IDocumentMarkAccess.hxx>
#ifndef IREDLINEACCESS_HXX_INCLUDED
#include <IDocumentRedlineAccess.hxx>
#endif
@@ -114,6 +114,8 @@ class SwList;
#include <svtools/embedhlp.hxx>
#include <vector>

#include <boost/scoped_ptr.hpp>

class SfxObjectShell;
class SfxObjectShellRef;
class SvxForbiddenCharactersTable;
@@ -142,8 +144,6 @@ class SvxMacroTableDtor;
class SvxBorderLine;
class SwAutoCompleteWord;
class SwAutoCorrExceptWord;
class SwBookmark;
class SwBookmarks;
class SwCalc;
class SwCellFrm;
class SwCharFmt;
@@ -240,6 +240,9 @@ class SwChartDataProvider;
class SwChartLockController_Helper;
class IGrammarContact;

namespace sw { namespace mark {
    class MarkManager;
}}

namespace com { namespace sun { namespace star {
namespace i18n {
@@ -272,7 +275,6 @@ class SW_DLLPUBLIC SwDoc :
    public IDocumentSettingAccess,
    public IDocumentDeviceAccess,
    public IDocumentRedlineAccess,
    public IDocumentBookmarkAccess,
    public IDocumentUndoRedo,
    public IDocumentLinksAdministration,
    public IDocumentFieldsAccess,
@@ -319,6 +321,8 @@ class SW_DLLPUBLIC SwDoc :
        xXForms;                        // container with XForms models
    mutable com::sun::star::uno::Reference< com::sun::star::linguistic2::XProofreadingIterator > m_xGCIterator;

    const ::boost::scoped_ptr< ::sw::mark::MarkManager> pMarkManager;

    // -------------------------------------------------------------------
    // die Pointer
                                //Defaultformate
@@ -337,8 +341,6 @@ class SW_DLLPUBLIC SwDoc :
    SwTxtFmtColls   *pTxtFmtCollTbl;    // FormatCollections
    SwGrfFmtColls   *pGrfFmtCollTbl;

    SwBookmarks     *pBookmarkTbl;      //Bookmarks

    SwTOXTypes      *pTOXTypes;         // Verzeichnisse
    SwDefTOXBase_Impl * pDefTOXBases;   // defaults of SwTOXBase's

@@ -755,10 +757,6 @@ public:
    virtual void setFieldUpdateFlags( /*[in]*/ SwFldUpdateFlags eMode );
    virtual SwCharCompressType getCharacterCompressionType() const;
    virtual void setCharacterCompressionType( /*[in]*/SwCharCompressType nType );
    SwBookmark* getFieldBookmarkFor(const SwPosition &pos) const;
    SwBookmark* getNextFieldBookmarkFor(const SwPosition &pos) const;
    SwBookmark* getPrevFieldBookmarkFor(const SwPosition &pos) const;
    SwFieldBookmark* getFormFieldBookmarkFor(const SwPosition &pos) const;

    /** IDocumentDeviceAccess
    */
@@ -773,25 +771,10 @@ public:
    virtual SwPrintData* getPrintData() const;
    virtual void setPrintData(/*[in]*/ const SwPrintData& rPrtData);

    /** IDocumentBookmarkAccess
    /** IDocumentMarkAccess
    */
    virtual const SwBookmarks& getBookmarks() const;
    virtual SwBookmark* makeBookmark( /*[in]*/const SwPaM& rPaM, /*[in]*/const KeyCode& rKC,
                                      /*[in]*/ const String& rName, /*[in]*/const String& rShortName,
                                      /*[in]*/BookmarkType eMark );
    virtual void deleteBookmark( /*[in]*/sal_uInt16 nPos );
    virtual void deleteBookmark( /*[in]*/const String& rName );
    virtual bool isCrossRefBookmarkName( /*[in]*/const String& rName );
    virtual sal_uInt16 findBookmark( /*[in]*/const String& rName );
    virtual void makeUniqueBookmarkName( /*[in/out]*/String& rName );
    virtual sal_uInt16 getBookmarkCount( /*[in]*/ bool bBkmrk ) const;
    virtual SwBookmark& getBookmark( /*[in]*/sal_uInt16 nPos, /*[in]*/bool bBkmrk );
    virtual String getCrossRefBookmarkName(
            /*[in]*/const SwTxtNode& rTxtNode,
            /*[in]*/const CrossReferenceBookmarkSubType nCrossRefType ) const;
    virtual String makeCrossRefBookmark(
            /*[in]*/const SwTxtNode& rTxtNode,
            /*[in]*/const CrossReferenceBookmarkSubType nCrossRefType );
    IDocumentMarkAccess* getIDocumentMarkAccess();
    const IDocumentMarkAccess* getIDocumentMarkAccess() const;

    /** IDocumentRedlineAccess
    */
diff --git a/sw/inc/docary.hxx b/sw/inc/docary.hxx
index 649d7b4..c8ffcba 100644
--- a/sw/inc/docary.hxx
+++ b/sw/inc/docary.hxx
@@ -35,7 +35,6 @@
class SwFieldType;
class SwFrmFmt;
class SwCharFmt;
class SwBookmark;
class SwTOXType;
class SwUndo;
class SwSectionFmt;
@@ -72,10 +71,6 @@ SV_DECL_PTRARR_DEL(SwCharFmts,SwCharFmtPtr,4,4)

SV_DECL_PTRARR_DEL( SwFldTypes, SwFldTypePtr, INIT_FLDTYPES, GROW_FLDTYPES )

//Bookmarks (nach Dokumentpositionen sortiertes Array)
typedef SwBookmark* SwBookmarkPtr;
SV_DECL_PTRARR_SORT(SwBookmarks, SwBookmarkPtr,0,1)

typedef SwTOXType* SwTOXTypePtr;
SV_DECL_PTRARR_DEL( SwTOXTypes, SwTOXTypePtr, 0, 1 )

diff --git a/sw/inc/node.hxx b/sw/inc/node.hxx
index 6bbce69..5aa259b6 100644
--- a/sw/inc/node.hxx
+++ b/sw/inc/node.hxx
@@ -71,7 +71,7 @@ struct SwPosition;
class IStyleAccess;
class IDocumentSettingAccess;
class IDocumentDeviceAccess;
class IDocumentBookmarkAccess;
class IDocumentMarkAccess;
class IDocumentRedlineAccess;
class IDocumentStylePoolAccess;
class IDocumentLineNumberAccess;
@@ -223,7 +223,7 @@ public:

    /** Provides access to the document bookmark interface
     */
    const IDocumentBookmarkAccess* getIDocumentBookmarkAccess() const;
    const IDocumentMarkAccess* getIDocumentMarkAccess() const;

    /** Provides access to the document redline interface
     */
diff --git a/sw/inc/rolbck.hxx b/sw/inc/rolbck.hxx
index 84d89d4..f137b8b 100644
--- a/sw/inc/rolbck.hxx
+++ b/sw/inc/rolbck.hxx
@@ -44,7 +44,6 @@ class SwDoc;
class SwFmt;
class SwFmtColl;
class SwHstryHint;
class SwBookmark;
class SwTxtAttr;
class SfxPoolItem;
class SwTxtNode;
@@ -70,7 +69,7 @@ class SwCharFmt;

#include <SwNumberTreeTypes.hxx>
// --> OD 2007-10-17 #i81002#
#include <IDocumentBookmarkAccess.hxx>
#include <IDocumentMarkAccess.hxx>
// <--

#ifndef PRODUCT
@@ -256,22 +255,25 @@ public:

class SwHstryBookmark : public SwHstryHint
{
    String aName, aShortName;
    ULONG nNode1, nNode2;
    xub_StrLen nCntnt1, nCntnt2;
    USHORT nKeyCode;
    BYTE nTyp;
    // --> OD 2007-10-17 #i81002#
    const IDocumentBookmarkAccess::BookmarkType eBkmkType;
    // <--
public:
    enum { BKMK_POS = 1, BKMK_OTHERPOS = 2 };
    SwHstryBookmark( const SwBookmark&, BYTE nTyp );
    virtual void SetInDoc( SwDoc* pDoc, BOOL bTmpSet );
    OUT_HSTR_HINT(Bookmark)
    public:
        SwHstryBookmark(const ::sw::mark::IMark& rBkmk, bool bSavePos, bool bSaveOtherPos);
        virtual void SetInDoc(SwDoc * pDoc, BOOL);
        OUT_HSTR_HINT(Bookmark)

    BOOL IsEqualBookmark( const SwBookmark& );
    const String & GetName() const;
        BOOL IsEqualBookmark(const ::sw::mark::IMark& rBkmk);
        const ::rtl::OUString& GetName() const;
    private:
        const ::rtl::OUString m_aName;
        ::rtl::OUString m_aShortName;
        KeyCode m_aKeycode;
        const ULONG m_nNode;
        const ULONG m_nOtherNode;
        const xub_StrLen m_nCntnt;
        const xub_StrLen m_nOtherCntnt;
        const bool m_bSavePos;
        const bool m_bSaveOtherPos;
        const bool m_bHadOtherPos;
        const IDocumentMarkAccess::MarkType m_eBkmkType;
};

class SwHstrySetAttrSet : public SwHstryHint
@@ -371,7 +373,7 @@ public:
    void Add( const SwTxtAttr* pTxtHt, ULONG nNodeIdx,
                BOOL bNewAttr = TRUE );
    void Add( const SwFmtColl*, ULONG nNodeIdx, BYTE nWhichNd );
    void Add( const SwBookmark&, BYTE );
    void Add( const ::sw::mark::IMark&, bool bSavePos, bool bSaveOtherPos );
    void Add( const SwFrmFmt& rFmt );
    void Add( const SwFlyFrmFmt&, USHORT& rSetPos );
    void Add( const SwTxtFtn& );
diff --git a/sw/inc/shellio.hxx b/sw/inc/shellio.hxx
index bc1453b..497426e 100644
--- a/sw/inc/shellio.hxx
+++ b/sw/inc/shellio.hxx
@@ -504,7 +504,7 @@ public:
    const String&       GetBaseURL() const { return sBaseURL;}

    // suche die naechste Bookmark-Position aus der Bookmark-Tabelle
    USHORT FindPos_Bkmk( const SwPosition& rPos ) const;
    sal_Int32 FindPos_Bkmk( const SwPosition& rPos ) const;
    // build a bookmark table, which is sort by the node position. The
    // OtherPos of the bookmarks also inserted.
    void CreateBookmarkTbl();
diff --git a/sw/inc/swserv.hxx b/sw/inc/swserv.hxx
index 2f410ac..b421bee 100644
--- a/sw/inc/swserv.hxx
+++ b/sw/inc/swserv.hxx
@@ -31,8 +31,8 @@
#define _SWSERV_HXX

#include <sfx2/linksrc.hxx>
#include <IMark.hxx>

class SwBookmark;
class SwSectionNode;
class SwBaseLink;
class SwTableNode;
@@ -46,7 +46,7 @@ class SwServerObject : public ::sfx2::SvLinkSource
protected:
    enum ServerModes { BOOKMARK_SERVER, TABLE_SERVER, SECTION_SERVER, NONE_SERVER } eType;
    union {
        SwBookmark* pBkmk;
        ::sw::mark::IMark* pBkmk;
        SwTableNode* pTblNd;
        SwSectionNode* pSectNd;
    } CNTNT_TYPE;
@@ -54,7 +54,7 @@ protected:
    SwServerObject();

public:
    SwServerObject( SwBookmark& rBookmark )
    SwServerObject( ::sw::mark::IMark& rBookmark )
        : eType( BOOKMARK_SERVER )
    {
        CNTNT_TYPE.pBkmk = &rBookmark;
@@ -72,8 +72,8 @@ public:
    virtual ~SwServerObject();

    virtual BOOL GetData( ::com::sun::star::uno::Any & rData,
                             const String & rMimeType,
                             BOOL bSynchron = FALSE );
                            const String & rMimeType,
                            BOOL bSynchron = FALSE );

    BOOL SetData( const String & rMimeType,
                    const ::com::sun::star::uno::Any& rData );
@@ -83,7 +83,8 @@ public:

    BOOL IsLinkInServer( const SwBaseLink* ) const;

    void SetNoServer() {  CNTNT_TYPE.pBkmk = 0, eType = NONE_SERVER; }
    void SetNoServer();
    void SetDdeBookmark( ::sw::mark::IMark& rBookmark);
};

#ifndef SW_DECL_SWSERVEROBJECT_DEFINED
diff --git a/sw/inc/undobj.hxx b/sw/inc/undobj.hxx
index f1490ee..0005321 100644
--- a/sw/inc/undobj.hxx
+++ b/sw/inc/undobj.hxx
@@ -48,7 +48,7 @@

#include <swundo.hxx>


#include <IMark.hxx>
// --> OD 2006-11-01 #130889#
#include <vector>
// <--
@@ -63,7 +63,6 @@ class SwFmt;
class SwFmtColl;
class SwTxtFmtColl;
class SwTxtNode;
class SwBookmark;
class SwTableNode;
class SwTable;
class SwTableBox;
@@ -1084,7 +1083,7 @@ class SwUndoBookmark : public SwUndo
{
    SwHstryBookmark* pHBookmark;
protected:
    SwUndoBookmark( SwUndoId nUndoId, const SwBookmark& );
    SwUndoBookmark( SwUndoId nUndoId, const ::sw::mark::IMark& );

    void SetInDoc( SwDoc* );
    void ResetInDoc( SwDoc* );
@@ -1112,7 +1111,7 @@ public:
class SwUndoDelBookmark : public SwUndoBookmark
{
public:
    SwUndoDelBookmark( const SwBookmark& );
    SwUndoDelBookmark( const ::sw::mark::IMark& );
    virtual void Undo( SwUndoIter& );
    virtual void Redo( SwUndoIter& );
    OUT_UNDOBJ( DelBookmark )
@@ -1121,7 +1120,7 @@ public:
class SwUndoInsBookmark : public SwUndoBookmark
{
public:
    SwUndoInsBookmark( const SwBookmark& );
    SwUndoInsBookmark( const ::sw::mark::IMark& );
    virtual void Undo( SwUndoIter& );
    virtual void Redo( SwUndoIter& );
    OUT_UNDOBJ( InsBookmark )
diff --git a/sw/inc/unocoll.hxx b/sw/inc/unocoll.hxx
index 596b8e6..8363dcd 100644
--- a/sw/inc/unocoll.hxx
+++ b/sw/inc/unocoll.hxx
@@ -40,6 +40,7 @@
#include <cppuhelper/implbase2.hxx> // helper for implementations
#include <cppuhelper/implbase3.hxx> // helper for implementations
#include <cppuhelper/implbase4.hxx> // helper for implementations
#include <IMark.hxx>
/***************************************************
 ***************************************************
 *
@@ -58,7 +59,6 @@ class SwFmtFtn;
class XBookmark;
class SwXReferenceMark;
class SwSectionFmt;
class SwBookmark;
class SwFmtRefMark;
class SwXReferenceMark;
class SwXBookmark;
@@ -444,31 +444,31 @@ public:
class SwXBookmarks : public SwCollectionBaseClass,
    public SwUnoCollection
{
protected:
    virtual ~SwXBookmarks();
public:
    SwXBookmarks(SwDoc* pDoc);
    protected:
        virtual ~SwXBookmarks();
    public:
        SwXBookmarks(SwDoc* pDoc);


    //XIndexAccess
    virtual sal_Int32 SAL_CALL getCount(void) throw( ::com::sun::star::uno::RuntimeException );
    virtual ::com::sun::star::uno::Any SAL_CALL getByIndex(sal_Int32 nIndex) throw( ::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException );
        //XIndexAccess
        virtual sal_Int32 SAL_CALL getCount(void) throw( ::com::sun::star::uno::RuntimeException );
        virtual ::com::sun::star::uno::Any SAL_CALL getByIndex(sal_Int32 nIndex) throw( ::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException );

    //XNameAccess
    virtual ::com::sun::star::uno::Any SAL_CALL getByName(const rtl::OUString& Name) throw( ::com::sun::star::container::NoSuchElementException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException );
    virtual ::com::sun::star::uno::Sequence< rtl::OUString > SAL_CALL getElementNames(void) throw( ::com::sun::star::uno::RuntimeException );
    virtual sal_Bool SAL_CALL hasByName(const rtl::OUString& Name) throw( ::com::sun::star::uno::RuntimeException );
        //XNameAccess
        virtual ::com::sun::star::uno::Any SAL_CALL getByName(const rtl::OUString& Name) throw( ::com::sun::star::container::NoSuchElementException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException );
        virtual ::com::sun::star::uno::Sequence< rtl::OUString > SAL_CALL getElementNames(void) throw( ::com::sun::star::uno::RuntimeException );
        virtual sal_Bool SAL_CALL hasByName(const rtl::OUString& Name) throw( ::com::sun::star::uno::RuntimeException );

    //XElementAccess
    virtual ::com::sun::star::uno::Type SAL_CALL getElementType(  ) throw(::com::sun::star::uno::RuntimeException);
    virtual sal_Bool SAL_CALL hasElements(  ) throw(::com::sun::star::uno::RuntimeException);
        //XElementAccess
        virtual ::com::sun::star::uno::Type SAL_CALL getElementType(  ) throw(::com::sun::star::uno::RuntimeException);
        virtual sal_Bool SAL_CALL hasElements(  ) throw(::com::sun::star::uno::RuntimeException);

    //XServiceInfo
    virtual rtl::OUString SAL_CALL getImplementationName(void) throw( ::com::sun::star::uno::RuntimeException );
    virtual BOOL SAL_CALL supportsService(const rtl::OUString& ServiceName) throw( ::com::sun::star::uno::RuntimeException );
    virtual ::com::sun::star::uno::Sequence< rtl::OUString > SAL_CALL getSupportedServiceNames(void) throw( ::com::sun::star::uno::RuntimeException );
        //XServiceInfo
        virtual rtl::OUString SAL_CALL getImplementationName(void) throw( ::com::sun::star::uno::RuntimeException );
        virtual BOOL SAL_CALL supportsService(const rtl::OUString& ServiceName) throw( ::com::sun::star::uno::RuntimeException );
        virtual ::com::sun::star::uno::Sequence< rtl::OUString > SAL_CALL getSupportedServiceNames(void) throw( ::com::sun::star::uno::RuntimeException );

    static SwXBookmark*     GetObject( SwBookmark& rBkm, SwDoc* pDoc );
        static SwXBookmark* GetObject( ::sw::mark::IMark& rBkm, SwDoc* pDoc);
};

class SwXNumberingRulesCollection : public cppu::WeakImplHelper1
diff --git a/sw/inc/unoobj.hxx b/sw/inc/unoobj.hxx
index 7893d19..fa34559 100644
--- a/sw/inc/unoobj.hxx
+++ b/sw/inc/unoobj.hxx
@@ -91,11 +91,10 @@
#include <unomid.h>
#include <tools/link.hxx>

#include <IDocumentBookmarkAccess.hxx>
#include <IDocumentMarkAccess.hxx>

class SwUnoCrsr;
class SwCursor;
class SwBookmark;
class SwFmtFtn;
class SwFmtRefMark;
class GetCurTxtFmtColl;
@@ -568,11 +567,7 @@ public:
};
*/

/*-----------------20.02.98 08:45-------------------

--------------------------------------------------*/
typedef
cppu::WeakImplHelper5
typedef cppu::WeakImplHelper5
<
    ::com::sun::star::text::XTextContent,
    ::com::sun::star::beans::XPropertySet,
@@ -580,84 +575,98 @@ cppu::WeakImplHelper5
    ::com::sun::star::container::XNamed,
    ::com::sun::star::lang::XUnoTunnel
>
SwRefBookmarkBaseClass;
class SwXBookmark : public SwRefBookmarkBaseClass,
    public SwClient
SwRefMarkBaseClass;

class SwXBookmark
    : public SwRefMarkBaseClass
    , private SwClient
{
protected:
    SwEventListenerContainer    aLstnrCntnr;
    SwDoc*                      pDoc;
    String                      m_aName;
    BOOL                        bIsDescriptor;
protected:
    virtual ~SwXBookmark();
public:
        SwXBookmark(SwBookmark* pBkm = 0, SwDoc* pDoc = 0);
    private:
        SwEventListenerContainer m_aLstnrCntnr;
        SwDoc* m_pDoc;
        String m_aName;
        ::sw::mark::IMark* m_pRegisteredBookmark;

    TYPEINFO();
        void registerInMark(::sw::mark::IMark* const pBkmk)
        {
            if(pBkmk)
                pBkmk->Add(this);
            else if(m_pRegisteredBookmark)
            {
                m_aName = m_pRegisteredBookmark->GetName();
                m_pRegisteredBookmark->Remove(this);
            }
            m_pRegisteredBookmark = pBkmk;
        }

    static const ::com::sun::star::uno::Sequence< sal_Int8 > & getUnoTunnelId();
    protected:
        virtual ~SwXBookmark();
    public:
        SwXBookmark(::sw::mark::IMark* pMark = 0, SwDoc* pDoc = 0);

    //XUnoTunnel
    virtual sal_Int64 SAL_CALL getSomething( const ::com::sun::star::uno::Sequence< sal_Int8 >& aIdentifier ) throw(::com::sun::star::uno::RuntimeException);
        TYPEINFO();

    //XTextContent
    virtual void SAL_CALL attach(const ::com::sun::star::uno::Reference< ::com::sun::star::text::XTextRange > & xTextRange) throw( ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException );
    virtual ::com::sun::star::uno::Reference< ::com::sun::star::text::XTextRange > SAL_CALL getAnchor(  ) throw(::com::sun::star::uno::RuntimeException);
        static const ::com::sun::star::uno::Sequence< sal_Int8 > & getUnoTunnelId();

    //XComponent
    virtual void SAL_CALL dispose(void) throw( ::com::sun::star::uno::RuntimeException );
    virtual void SAL_CALL addEventListener(const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XEventListener > & aListener) throw( ::com::sun::star::uno::RuntimeException );
    virtual void SAL_CALL removeEventListener(const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XEventListener > & aListener) throw( ::com::sun::star::uno::RuntimeException );
        //XUnoTunnel
        virtual sal_Int64 SAL_CALL getSomething( const ::com::sun::star::uno::Sequence< sal_Int8 >& aIdentifier ) throw(::com::sun::star::uno::RuntimeException);

    //XNamed
    virtual rtl::OUString SAL_CALL getName(void) throw( ::com::sun::star::uno::RuntimeException );
    virtual void SAL_CALL setName(const rtl::OUString& Name_) throw( ::com::sun::star::uno::RuntimeException );
        //XTextContent
        virtual void SAL_CALL attach(const ::com::sun::star::uno::Reference< ::com::sun::star::text::XTextRange > & xTextRange) throw( ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException );
        virtual ::com::sun::star::uno::Reference< ::com::sun::star::text::XTextRange > SAL_CALL getAnchor(  ) throw(::com::sun::star::uno::RuntimeException);

    //XServiceInfo
    virtual rtl::OUString SAL_CALL getImplementationName(void) throw( ::com::sun::star::uno::RuntimeException );
    virtual BOOL SAL_CALL supportsService(const rtl::OUString& ServiceName) throw( ::com::sun::star::uno::RuntimeException );
    virtual ::com::sun::star::uno::Sequence< rtl::OUString > SAL_CALL getSupportedServiceNames(void) throw( ::com::sun::star::uno::RuntimeException );
        //XComponent
        virtual void SAL_CALL dispose(void) throw( ::com::sun::star::uno::RuntimeException );
        virtual void SAL_CALL addEventListener(const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XEventListener > & aListener) throw( ::com::sun::star::uno::RuntimeException );
        virtual void SAL_CALL removeEventListener(const ::com::sun::star::uno::Reference< ::com::sun::star::lang::XEventListener > & aListener) throw( ::com::sun::star::uno::RuntimeException );

    //XPropertySet
    virtual ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySetInfo > SAL_CALL getPropertySetInfo(  ) throw(::com::sun::star::uno::RuntimeException);
    virtual void SAL_CALL setPropertyValue( const ::rtl::OUString& aPropertyName, const ::com::sun::star::uno::Any& aValue ) throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::beans::PropertyVetoException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
    virtual ::com::sun::star::uno::Any SAL_CALL getPropertyValue( const ::rtl::OUString& PropertyName ) throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
    virtual void SAL_CALL addPropertyChangeListener( const ::rtl::OUString& aPropertyName, const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertyChangeListener >& xListener ) throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
    virtual void SAL_CALL removePropertyChangeListener( const ::rtl::OUString& aPropertyName, const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertyChangeListener >& aListener ) throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
    virtual void SAL_CALL addVetoableChangeListener( const ::rtl::OUString& PropertyName, const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XVetoableChangeListener >& aListener ) throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
    virtual void SAL_CALL removeVetoableChangeListener( const ::rtl::OUString& PropertyName, const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XVetoableChangeListener >& aListener ) throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
        //XNamed
        virtual rtl::OUString SAL_CALL getName(void) throw( ::com::sun::star::uno::RuntimeException );
        virtual void SAL_CALL setName(const rtl::OUString& rName) throw( ::com::sun::star::uno::RuntimeException );

    void attachToRangeEx(const ::com::sun::star::uno::Reference< ::com::sun::star::text::XTextRange > & xTextRange, IDocumentBookmarkAccess::BookmarkType eMark)throw( ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException );
    virtual void attachToRange(const ::com::sun::star::uno::Reference< ::com::sun::star::text::XTextRange > & xTextRange)throw( ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException );
        //XServiceInfo
        virtual rtl::OUString SAL_CALL getImplementationName(void) throw( ::com::sun::star::uno::RuntimeException );
        virtual BOOL SAL_CALL supportsService(const rtl::OUString& ServiceName) throw( ::com::sun::star::uno::RuntimeException );
        virtual ::com::sun::star::uno::Sequence< rtl::OUString > SAL_CALL getSupportedServiceNames(void) throw( ::com::sun::star::uno::RuntimeException );

    //SwClient
    virtual void    Modify( SfxPoolItem *pOld, SfxPoolItem *pNew);
        //XPropertySet
        virtual ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertySetInfo > SAL_CALL getPropertySetInfo(  ) throw(::com::sun::star::uno::RuntimeException);
        virtual void SAL_CALL setPropertyValue( const ::rtl::OUString& aPropertyName, const ::com::sun::star::uno::Any& aValue ) throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::beans::PropertyVetoException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
        virtual ::com::sun::star::uno::Any SAL_CALL getPropertyValue( const ::rtl::OUString& PropertyName ) throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
        virtual void SAL_CALL addPropertyChangeListener( const ::rtl::OUString& aPropertyName, const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertyChangeListener >& xListener ) throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
        virtual void SAL_CALL removePropertyChangeListener( const ::rtl::OUString& aPropertyName, const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XPropertyChangeListener >& aListener ) throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
        virtual void SAL_CALL addVetoableChangeListener( const ::rtl::OUString& PropertyName, const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XVetoableChangeListener >& aListener ) throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);
        virtual void SAL_CALL removeVetoableChangeListener( const ::rtl::OUString& PropertyName, const ::com::sun::star::uno::Reference< ::com::sun::star::beans::XVetoableChangeListener >& aListener ) throw(::com::sun::star::beans::UnknownPropertyException, ::com::sun::star::lang::WrappedTargetException, ::com::sun::star::uno::RuntimeException);

    SwBookmark*     GetBookmark() const { return (SwBookmark*)GetRegisteredIn(); }
    SwDoc*          GetDoc(){return pDoc;}
        void attachToRangeEx(const ::com::sun::star::uno::Reference< ::com::sun::star::text::XTextRange > & xTextRange, IDocumentMarkAccess::MarkType eType) throw( ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException );
        virtual void attachToRange(const ::com::sun::star::uno::Reference< ::com::sun::star::text::XTextRange > & xTextRange) throw( ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException );

        //SwClient
        virtual void Modify( SfxPoolItem *pOld, SfxPoolItem *pNew );

        const ::sw::mark::IMark* GetBookmark() const
            { return m_pRegisteredBookmark; }
        SwDoc* GetDoc()
            { return m_pDoc; }
};

typedef cppu::ImplInheritanceHelper1< SwXBookmark, ::com::sun::star::text::XFormField > SwXFieldmark_BASE;

class SwXFieldmark : public SwXFieldmark_BASE
{
private:
    bool isReplacementObject;
public:
    SwXFieldmark(bool isReplacementObject, SwBookmark* pBkm = 0, SwDoc* pDoc = 0);
    private:
        bool isReplacementObject;
    public:
        SwXFieldmark(bool isReplacementObject, ::sw::mark::IMark* pBkm = 0, SwDoc* pDoc = 0);

    virtual void attachToRange(const ::com::sun::star::uno::Reference< ::com::sun::star::text::XTextRange > & xTextRange)throw( ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException );
    virtual ::rtl::OUString SAL_CALL getDescription(void)  throw( ::com::sun::star::uno::RuntimeException );
    virtual ::sal_Int16 SAL_CALL getType(  ) throw (::com::sun::star::uno::RuntimeException);
    virtual ::sal_Int16 SAL_CALL getRes(  ) throw (::com::sun::star::uno::RuntimeException);
        virtual void attachToRange(const ::com::sun::star::uno::Reference< ::com::sun::star::text::XTextRange > & xTextRange) throw( ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException );
        virtual ::rtl::OUString SAL_CALL getDescription(void) throw( ::com::sun::star::uno::RuntimeException );
        virtual ::sal_Int16 SAL_CALL getType(  ) throw (::com::sun::star::uno::RuntimeException);
        virtual ::sal_Int16 SAL_CALL getRes(  ) throw (::com::sun::star::uno::RuntimeException);

    virtual void SAL_CALL setType( ::sal_Int16 fieldType ) throw (::com::sun::star::uno::RuntimeException);
    virtual void SAL_CALL setRes( ::sal_Int16 res ) throw (::com::sun::star::uno::RuntimeException);
    virtual void SAL_CALL setDescription( const ::rtl::OUString& description ) throw (::com::sun::star::uno::RuntimeException);

//    virtual ::com::sun::star::uno::Any SAL_CALL queryInterface( ::com::sun::star::uno::Type const & rType ) throw (::com::sun::star::uno::RuntimeException);

        virtual void SAL_CALL setType( ::sal_Int16 fieldType ) throw (::com::sun::star::uno::RuntimeException);
        virtual void SAL_CALL setRes( ::sal_Int16 res ) throw (::com::sun::star::uno::RuntimeException);
        virtual void SAL_CALL setDescription( const ::rtl::OUString& description ) throw (::com::sun::star::uno::RuntimeException);
};

/*-----------------23.02.98 10:45-------------------
@@ -707,9 +716,7 @@ public:

    ::com::sun::star::uno::Reference< ::com::sun::star::text::XTextCursor >  CreateTextCursor(BOOL bIgnoreTables = sal_False);
};
/*-----------------23.02.98 12:05-------------------

--------------------------------------------------*/
class SW_DLLPUBLIC SwXTextRange : public cppu::WeakImplHelper8
<
    ::com::sun::star::text::XTextRange,
@@ -720,7 +727,7 @@ class SW_DLLPUBLIC SwXTextRange : public cppu::WeakImplHelper8
    ::com::sun::star::beans::XPropertyState,
    ::com::sun::star::container::XEnumerationAccess,
    ::com::sun::star::text::XRedline
>,  public SwClient
>,  private SwClient
{
    friend class SwXText;
    enum RangePosition
@@ -732,14 +739,14 @@ class SW_DLLPUBLIC SwXTextRange : public cppu::WeakImplHelper8
        RANGE_INVALID  // von NewInstance erzeugt
    } eRangePosition;

    SwDoc*              pDoc;
    SwTableBox*         pBox;
    const SwStartNode*  pBoxStartNode;
    SwDepend            aObjectDepend; //Format der Tabelle oder des Rahmens anmelden
    SfxItemPropertySet  aPropSet;
    SwDoc* pDoc;
    SwTableBox* pBox;
    const SwStartNode* pBoxStartNode;
    SwDepend aObjectDepend; //Format der Tabelle oder des Rahmens anmelden
    SfxItemPropertySet aPropSet;
    //SwDepend  aFrameDepend;
    ::com::sun::star::uno::Reference< ::com::sun::star::text::XText >   xParentText;

    ::com::sun::star::uno::Reference< ::com::sun::star::text::XText > xParentText;
    ::sw::mark::IMark* pMark;

    void    _CreateNewBookmark(SwPaM& rPam);
    //TODO: new exception type for protected content
@@ -803,18 +810,20 @@ public:
    virtual void SAL_CALL makeRedline( const ::rtl::OUString& RedlineType, const ::com::sun::star::uno::Sequence< ::com::sun::star::beans::PropertyValue >& RedlineProperties ) throw (::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException);

    //SwClient
    virtual void        Modify( SfxPoolItem *pOld, SfxPoolItem *pNew);
    virtual void Modify(SfxPoolItem *pOld, SfxPoolItem *pNew);
    BOOL GetPositions(SwPaM& rToFill) const;
    const SwDoc* GetDoc() const
        { return pDoc; }
    SwDoc* GetDoc()
        { return pDoc; }
    const ::sw::mark::IMark * const GetBookmark() const
        { return pMark; }

    BOOL                GetPositions(SwPaM& rToFill) const;
    const SwDoc*        GetDoc()const {return pDoc;}
    SwDoc*              GetDoc(){return pDoc;}

    SwBookmark* GetBookmark() const { return (SwBookmark*)GetRegisteredIn(); }

    static  BOOL        XTextRangeToSwPaM( SwUnoInternalPaM& rToFill,
                                const ::com::sun::star::uno::Reference< ::com::sun::star::text::XTextRange > & xTextRange);
    static ::com::sun::star::uno::Reference< ::com::sun::star::text::XTextRange >  CreateTextRangeFromPosition(SwDoc* pDoc,
                        const SwPosition& rPos, const SwPosition* pMark);
    static BOOL XTextRangeToSwPaM(SwUnoInternalPaM& rToFill,
        const ::com::sun::star::uno::Reference< ::com::sun::star::text::XTextRange > & xTextRange);
    static ::com::sun::star::uno::Reference< ::com::sun::star::text::XTextRange > CreateTextRangeFromPosition(
        SwDoc* pDoc,
        const SwPosition& rPos, const SwPosition* pMark);
};

/* -----------------15.05.98 08:29-------------------
@@ -1428,7 +1437,7 @@ public:
/* -----------------27.08.98 15:11-------------------
 *
 * --------------------------------------------------*/
class SwXReferenceMark : public SwRefBookmarkBaseClass,
class SwXReferenceMark : public SwRefMarkBaseClass,
    public SwClient
{
    SwEventListenerContainer    aLstnrCntnr;
diff --git a/sw/inc/viewsh.hxx b/sw/inc/viewsh.hxx
index d73db5d..7a8d0eb 100644
--- a/sw/inc/viewsh.hxx
+++ b/sw/inc/viewsh.hxx
@@ -47,7 +47,7 @@ class SfxObjectShellRef;
class SwDoc;
class IDocumentSettingAccess;
class IDocumentDeviceAccess;
class IDocumentBookmarkAccess;
class IDocumentMarkAccess;
class IDocumentDrawModelAccess;
class IDocumentRedlineAccess;
class IDocumentLayoutAccess;
@@ -305,8 +305,8 @@ public:

    /** Provides access to the document bookmark interface
     */
    const IDocumentBookmarkAccess* getIDocumentBookmarkAccess() const;
          IDocumentBookmarkAccess* getIDocumentBookmarkAccess();
    const IDocumentMarkAccess* getIDocumentMarkAccess() const;
          IDocumentMarkAccess* getIDocumentMarkAccess();

    /** Provides access to the document draw model interface
     */
diff --git a/sw/qa/complex/writer/CheckBookmarks.java b/sw/qa/complex/writer/CheckBookmarks.java
new file mode 100644
index 0000000..c8f4a035
--- /dev/null
+++ b/sw/qa/complex/writer/CheckBookmarks.java
@@ -0,0 +1,280 @@
/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: $
 * $Revision: $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

package complex.writer;

import com.sun.star.beans.PropertyValue;
import com.sun.star.container.XNamed;
import com.sun.star.container.XNameAccess;
import com.sun.star.frame.XStorable;
import com.sun.star.lang.XComponent;
import com.sun.star.lang.XMultiServiceFactory;
import com.sun.star.text.XBookmarksSupplier;
import com.sun.star.text.XSimpleText;
import com.sun.star.text.XText;
import com.sun.star.text.XTextContent;
import com.sun.star.text.XTextCursor;
import com.sun.star.text.XTextDocument;
import com.sun.star.text.XTextRange;
import com.sun.star.uno.UnoRuntime;
import complexlib.ComplexTestCase;
import java.math.BigInteger;

class BookmarkHashes {
    public String m_sName;
    public BigInteger m_nSetupHash;
    public BigInteger m_nInsertRandomHash;
    public BigInteger m_nDeleteRandomHash;
    public BigInteger m_nLinebreakHash;
    public BigInteger m_nOdfReloadHash;
    public BigInteger m_nMsWordReloadHash;

    public BookmarkHashes(String sName) {
        m_sName = sName;
    }

    public String checkExpectationString(BookmarkHashes aExpectation) {
        StringBuffer buffer = new StringBuffer();
        buffer.append("Comparing " + m_sName + " to expectations from " + aExpectation.m_sName + "\n");
        buffer.append(compareHashString("after setup", m_nSetupHash, aExpectation.m_nSetupHash));
        buffer.append(compareHashString("after insert random", m_nInsertRandomHash, aExpectation.m_nInsertRandomHash));
        buffer.append(compareHashString("after delete random", m_nDeleteRandomHash, aExpectation.m_nDeleteRandomHash));
        buffer.append(compareHashString("after line breaks", m_nLinebreakHash, aExpectation.m_nLinebreakHash));
        buffer.append(compareHashString("after ODF roundtrip", m_nOdfReloadHash, aExpectation.m_nOdfReloadHash));
        buffer.append(compareHashString("after MsWord roundtrip", m_nMsWordReloadHash, aExpectation.m_nMsWordReloadHash));
        return buffer.toString();
    };

    public boolean meetsExpectation(BookmarkHashes aExpectation) {
        return m_nSetupHash.equals(aExpectation.m_nSetupHash)
            && m_nInsertRandomHash.equals(aExpectation.m_nInsertRandomHash)
            && m_nDeleteRandomHash.equals(aExpectation.m_nDeleteRandomHash)
            && m_nLinebreakHash.equals(aExpectation.m_nLinebreakHash)
            && m_nOdfReloadHash.equals(aExpectation.m_nOdfReloadHash)
            && m_nMsWordReloadHash.equals(aExpectation.m_nMsWordReloadHash);
    }

    private String compareHashString(String sCheckName, BigInteger nActual, BigInteger nExpectation) {
        StringBuffer buffer = new StringBuffer(sCheckName);
        buffer.append(": ");
        if(nActual.equals(nExpectation))
            buffer.append("good (" + nActual.toString(16) + ")");
        else
            buffer.append("bad (actual:" + nActual.toString(16) + ", expected: " + nExpectation.toString(16) + ")");
        buffer.append("\n");
        return buffer.toString();
    }

    static public java.math.BigInteger getBookmarksHash(XTextDocument xDoc)
        throws com.sun.star.uno.Exception, java.security.NoSuchAlgorithmException
    {
        StringBuffer buffer = new StringBuffer("");
        XBookmarksSupplier xBookmarksSupplier = (XBookmarksSupplier)UnoRuntime.queryInterface(
            XBookmarksSupplier.class,
            xDoc);
        XNameAccess xBookmarks = xBookmarksSupplier.getBookmarks();
        for(String sBookmarkname : xBookmarks.getElementNames()) {
            Object xBookmark = xBookmarks.getByName(sBookmarkname);
            XTextContent xBookmarkAsContent = (XTextContent)UnoRuntime.queryInterface(
                XTextContent.class,
                xBookmark);
            buffer.append(sBookmarkname);
            buffer.append(":");
            buffer.append(xBookmarkAsContent.getAnchor().getString());
            buffer.append(";");
        }
        java.security.MessageDigest sha1 = java.security.MessageDigest.getInstance("SHA-1");
        sha1.reset();
        sha1.update(buffer.toString().getBytes());
        return new java.math.BigInteger(sha1.digest());
    }
}

public class CheckBookmarks extends ComplexTestCase {
    private XMultiServiceFactory m_xMsf = null;
    private XTextDocument m_xDoc = null;
    private XTextDocument m_xOdfReloadedDoc = null;
    private XTextDocument m_xMsWordReloadedDoc = null;

    public String[] getTestMethodNames() {
        return new String[]{"checkBookmarks"};
    }

    private BookmarkHashes getDEV300m41Expectations() {
        BookmarkHashes result = new BookmarkHashes("DEV300m41");
        result.m_nSetupHash = new BigInteger("-4b0706744e8452fe1ae9d5e1c28cf70fb6194795",16);
        result.m_nInsertRandomHash = new BigInteger("25aa0fad3f4881832dcdfe658ec2efa8a1a02bc5",16);
        result.m_nDeleteRandomHash = new BigInteger("-3ec87e810b46d734677c351ad893bbbf9ea10f55",16);
        result.m_nLinebreakHash = new BigInteger("3ae08c284ea0d6e738cb43c0a8105e718a633550",16);
        result.m_nOdfReloadHash = new BigInteger("3ae08c284ea0d6e738cb43c0a8105e718a633550",16);
        result.m_nMsWordReloadHash = new BigInteger("3ae08c284ea0d6e738cb43c0a8105e718a633550",16);
        return result;
    }

    public void checkBookmarks()
        throws com.sun.star.uno.Exception,
            com.sun.star.io.IOException,
            java.security.NoSuchAlgorithmException
    {
        try {
            m_xMsf = (XMultiServiceFactory)param.getMSF();
            m_xDoc = util.WriterTools.createTextDoc(m_xMsf);
            BookmarkHashes actualHashes = new BookmarkHashes("actual");
            BookmarkHashes expectedHashes = getDEV300m41Expectations();
            setupBookmarks();
            actualHashes.m_nSetupHash = BookmarkHashes.getBookmarksHash(m_xDoc);
            insertRandomParts(200177);
            actualHashes.m_nInsertRandomHash = BookmarkHashes.getBookmarksHash(m_xDoc);
            deleteRandomParts(4711);
            actualHashes.m_nDeleteRandomHash = BookmarkHashes.getBookmarksHash(m_xDoc);
            insertLinebreaks(007);
            actualHashes.m_nLinebreakHash = BookmarkHashes.getBookmarksHash(m_xDoc);
            m_xOdfReloadedDoc = reloadFrom("StarOffice XML (Writer)", "odf");
            actualHashes.m_nOdfReloadHash = BookmarkHashes.getBookmarksHash(m_xOdfReloadedDoc);
            m_xMsWordReloadedDoc = reloadFrom("MS Word 97", "doc");
            actualHashes.m_nMsWordReloadHash = BookmarkHashes.getBookmarksHash(m_xMsWordReloadedDoc);
            log.println(actualHashes.checkExpectationString(expectedHashes));
            if(!actualHashes.meetsExpectation(expectedHashes))
                failed("CheckBookmark did not meet expectations (" + expectedHashes.m_sName + ").");
        } finally {
            // closing test document
            if(m_xDoc != null)
                util.DesktopTools.closeDoc(m_xDoc);
            if(m_xOdfReloadedDoc!= null)
                util.DesktopTools.closeDoc(m_xOdfReloadedDoc);
            if(m_xMsWordReloadedDoc!= null)
                util.DesktopTools.closeDoc(m_xMsWordReloadedDoc);
        }
    }

    private void setupBookmarks()
        throws com.sun.star.uno.Exception
    {
        XText xText = m_xDoc.getText();
        XSimpleText xSimpleText = (XSimpleText)UnoRuntime.queryInterface(
            XSimpleText.class,
            xText);
        for(int nPara=0; nPara<10; ++nPara) {
            for(int nBookmark=0; nBookmark<100; ++nBookmark){
                insertBookmark(
                    xText.createTextCursor(),
                    "P" + nPara + "word" + nBookmark,
                    "P" + nPara + "word" + nBookmark);
                XTextCursor xWordCrsr = xText.createTextCursor();
                xWordCrsr.setString(" ");
            }
            XTextCursor xParaCrsr = xText.createTextCursor();
            XTextRange xParaCrsrAsRange = (XTextRange)UnoRuntime.queryInterface(
                XTextRange.class,
                xParaCrsr);
            xText.insertControlCharacter(xParaCrsrAsRange, com.sun.star.text.ControlCharacter.PARAGRAPH_BREAK, false);
        }
    }

    private void insertRandomParts(long seed)
        throws com.sun.star.uno.Exception
    {
        java.util.Random rnd = new java.util.Random(seed);
        XTextCursor xCrsr = m_xDoc.getText().createTextCursor();
        for(int i=0; i<600; i++) {
            xCrsr.goRight((short)rnd.nextInt(100), false);
            xCrsr.setString(Long.toString(rnd.nextLong()));
        }
    }

    private void deleteRandomParts(long seed)
        throws com.sun.star.uno.Exception
    {
        java.util.Random rnd = new java.util.Random(seed);
        XTextCursor xCrsr = m_xDoc.getText().createTextCursor();
        for(int i=0; i<600; i++) {
            xCrsr.goRight((short)rnd.nextInt(100), false);
            xCrsr.goRight((short)rnd.nextInt(20), true);
            xCrsr.setString("");
        }
    }

    private void insertLinebreaks(long seed)
        throws com.sun.star.uno.Exception
    {
        XText xText = m_xDoc.getText();
        java.util.Random rnd = new java.util.Random(seed);
        XTextCursor xCrsr = m_xDoc.getText().createTextCursor();
        for(int i=0; i<30; i++) {
            xCrsr.goRight((short)rnd.nextInt(300), false);
            XTextRange xCrsrAsRange = (XTextRange)UnoRuntime.queryInterface(
                XTextRange.class,
                xCrsr);
            xText.insertControlCharacter(xCrsrAsRange, com.sun.star.text.ControlCharacter.PARAGRAPH_BREAK, false);
        }
    }

    private void insertBookmark(XTextCursor crsr, String name, String content)
        throws com.sun.star.uno.Exception
    {
        XMultiServiceFactory xDocFactory = (XMultiServiceFactory)UnoRuntime.queryInterface(
            XMultiServiceFactory.class,
            m_xDoc);

        Object xBookmark = xDocFactory.createInstance("com.sun.star.text.Bookmark");
        XTextContent xBookmarkAsTextContent = (XTextContent)UnoRuntime.queryInterface(
            XTextContent.class,
            xBookmark);
        crsr.setString(content);
        XNamed xBookmarkAsNamed = (XNamed)UnoRuntime.queryInterface(
            XNamed.class,
            xBookmark);
        xBookmarkAsNamed.setName(name);
        m_xDoc.getText().insertTextContent(crsr, xBookmarkAsTextContent, true);
    }

    private XTextDocument reloadFrom(String sFilter, String sExtension)
        throws com.sun.star.io.IOException
    {
        String sFileUrl = util.utils.getOfficeTemp(m_xMsf) + "/Bookmarktest." + sExtension;
        try {
            PropertyValue[] aStoreProperties = new PropertyValue[2];
            aStoreProperties[0] = new PropertyValue();
            aStoreProperties[1] = new PropertyValue();
            aStoreProperties[0].Name = "Override";
            aStoreProperties[0].Value = true;
            aStoreProperties[1].Name = "FilterName";
            aStoreProperties[1].Value = sFilter;
            XStorable xStorable = (XStorable)UnoRuntime.queryInterface(
                XStorable.class,
                m_xDoc);
            xStorable.storeToURL(sFileUrl, aStoreProperties);
            return util.WriterTools.loadTextDoc(m_xMsf, sFileUrl);
        } finally {
            if(util.utils.fileExists(m_xMsf, sFileUrl))
                util.utils.deleteFile(m_xMsf, sFileUrl);
        }
    }
}
diff --git a/sw/qa/complex/writer/CheckCrossReferences.java b/sw/qa/complex/writer/CheckCrossReferences.java
index f740155..7b469c0 100644
--- a/sw/qa/complex/writer/CheckCrossReferences.java
+++ b/sw/qa/complex/writer/CheckCrossReferences.java
@@ -267,9 +267,12 @@ public class CheckCrossReferences extends ComplexTestCase {
                try {
                    xParaTextRange = (com.sun.star.text.XTextRange)UnoRuntime.queryInterface(
                            com.sun.star.text.XTextRange.class, xParaEnum.nextElement());
                    if ( xParaTextRange.getString().equals( "*i*J" ) ) {
                    if ( xParaTextRange.getString().equals( "J" ) ) {
                        break;
                    }
                    else {
                        xParaTextRange = null;
                    }
                } catch (com.sun.star.container.NoSuchElementException e) {
                    System.out.println("Cannot find paragraph to insert cross-reference bookmark.");
                    e.printStackTrace();
diff --git a/sw/qa/complex/writer/makefile.mk b/sw/qa/complex/writer/makefile.mk
index 3146655..88ceec0 100755
--- a/sw/qa/complex/writer/makefile.mk
+++ b/sw/qa/complex/writer/makefile.mk
@@ -41,8 +41,8 @@ PACKAGE = complex$/writer
#----- compile .java files -----------------------------------------

JARFILES = mysql.jar sandbox.jar ridl.jar unoil.jar jurt.jar juh.jar java_uno.jar OOoRunner.jar
JAVAFILES       = CheckIndexedPropertyValues.java CheckNamedPropertyValues.java CheckCrossReferences.java
JAVACLASSFILES	= $(foreach,i,$(JAVAFILES) $(CLASSDIR)$/$(PACKAGE)$/$(i:b).class)
JAVAFILES       = CheckIndexedPropertyValues.java CheckNamedPropertyValues.java CheckCrossReferences.java CheckBookmarks.java
JAVACLASSFILES  = $(foreach,i,$(JAVAFILES) $(CLASSDIR)$/$(PACKAGE)$/$(i:b).class)

#----- make a jar from compiled files ------------------------------

@@ -50,7 +50,7 @@ MAXLINELENGTH = 100000

JARCLASSDIRS    = $(PACKAGE)
JARTARGET       = $(TARGET).jar
JARCOMPRESS 	= TRUE
JARCOMPRESS     = TRUE

# --- Parameters for the test --------------------------------------

@@ -81,9 +81,10 @@ ALL: ALLDEP
.INCLUDE :  target.mk

run: \
    CheckBookmarks \
    CheckCrossReferences \
    CheckIndexedPropertyValues \
    CheckNamedPropertyValues \
    CheckCrossReferences

RUN: run

@@ -97,3 +98,6 @@ CheckNamedPropertyValues:
CheckCrossReferences:
    +java -cp $(CLASSPATH) $(CT_APP) $(CT_APPEXECCOMMAND) $(CT_TESTBASE) -tdoc $(PWD)$/testdocuments $(CT_PACKAGE).CheckCrossReferences

CheckBookmarks:
    +java -cp $(CLASSPATH) $(CT_APP) $(CT_APPEXECCOMMAND) $(CT_TESTBASE) -tdoc $(PWD)$/testdocuments $(CT_PACKAGE).CheckBookmarks

diff --git a/sw/source/core/bastyp/SwBitArray.cxx b/sw/source/core/bastyp/SwBitArray.cxx
deleted file mode 100644
index 8c3cd8f..0000000
--- a/sw/source/core/bastyp/SwBitArray.cxx
+++ /dev/null
@@ -1,175 +0,0 @@
/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: SwBitArray.cxx,v $
 * $Revision: 1.7 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_sw.hxx"

#include <string.h>
#include "SwBitArray.hxx"

using namespace std;

SwBitArray::SwBitArray(sal_uInt32 _nSize)
{
    nSize = _nSize;
    mArray = new sal_uInt32[(nSize - 1)/ mGroupSize + 1];
    Reset();
}

SwBitArray::SwBitArray(const SwBitArray & rArray)
    : nSize(rArray.nSize)
{
    mArray = new sal_uInt32[calcSize()];
    memcpy(mArray, rArray.mArray, calcSize());
}

SwBitArray::~SwBitArray()
{
    delete [] mArray;
}

BOOL SwBitArray::IsValid(sal_uInt32 n) const
{
    return n < nSize;
}

void SwBitArray::Set(sal_uInt32 n, BOOL nValue)
{
    sal_uInt32 * pGroup = NULL;

    if (IsValid(n))
    {
        pGroup = GetGroup(n);

        if (nValue)
            *pGroup |= 1 << (n % mGroupSize);
        else
            *pGroup &= ~(1 << (n % mGroupSize));
    }
}

void SwBitArray::Reset()
{
    memset(mArray, 0, mGroupSize * (nSize / mGroupSize + 1));
}

BOOL SwBitArray::Get(sal_uInt32 n) const
{
    BOOL bResult = FALSE;
    sal_uInt32 * pGroup = NULL;

    if (IsValid(n))
    {
        pGroup = GetGroup(n);

        bResult = 0 != (*pGroup & (1 << (n % mGroupSize)));
    }

    return bResult;
}

SwBitArray & SwBitArray::operator = (const SwBitArray & rArray)
{
    if (Size() == rArray.Size())
    {
        memcpy(mArray, rArray.mArray, calcSize());
    }

    return *this;
}

SwBitArray operator & (const SwBitArray & rA, const SwBitArray & rB)
{
    SwBitArray aResult(rA);

    if (rA.Size() == rB.Size())
    {
        for (size_t i = 0; i < rA.calcSize(); i++)
            aResult.mArray[i] &= rB.mArray[i];
    }

    return aResult;
}

SwBitArray operator | (const SwBitArray & rA, const SwBitArray & rB)
{
    SwBitArray aResult(rA);

    if (rA.Size() == rB.Size())
    {
        for (size_t i = 0; i < rA.calcSize(); i++)
            aResult.mArray[i] |= rB.mArray[i];
    }

    return aResult;
}

SwBitArray operator ^ (const SwBitArray & rA, const SwBitArray & rB)
{
    SwBitArray aResult(rA);

    if (rA.Size() == rB.Size())
    {
        for (size_t i = 0; i < rA.calcSize(); i++)
            aResult.mArray[i] ^= rB.mArray[i];
    }

    return aResult;
}

SwBitArray operator ~ (const SwBitArray & rA)
{
    SwBitArray aResult(rA);

    for (size_t i = 0; i < rA.calcSize(); i++)
        aResult.mArray[i] = ~ rA.mArray[i];

    return aResult;
}

#if OSL_DEBUG_LEVEL > 1
ostream & operator << (ostream & o, const SwBitArray & rBitArray)
{
    char buffer[256];

    sprintf(buffer, "%p", &rBitArray);
    o << "[ " << buffer << " ";
    for (sal_uInt32 n = 0; n < rBitArray.Size(); n++)
    {
        if (rBitArray.Get(n))
            o << "1";
        else
            o << "0";
    }
    o << " ]";

    return o;
}
#endif
diff --git a/sw/source/core/bastyp/makefile.mk b/sw/source/core/bastyp/makefile.mk
index 0fb79b9..ab4fcbd 100644
--- a/sw/source/core/bastyp/makefile.mk
+++ b/sw/source/core/bastyp/makefile.mk
@@ -45,11 +45,10 @@ AUTOSEG=true
# --- Files --------------------------------------------------------

CXXFILES = \
        SwBitArray.cxx \
        bparr.cxx \
        breakit.cxx \
        calc.cxx \
                checkit.cxx \
        checkit.cxx \
        index.cxx \
        init.cxx \
        ring.cxx \
@@ -60,12 +59,11 @@ CXXFILES = \
        tabcol.cxx \
        SwSmartTagMgr.cxx

SLOFILES =  \
        $(SLO)$/SwBitArray.obj \
SLOFILES =	\
        $(SLO)$/bparr.obj \
        $(SLO)$/breakit.obj \
        $(SLO)$/calc.obj \
                $(SLO)$/checkit.obj \
        $(SLO)$/checkit.obj \
        $(SLO)$/index.obj \
        $(SLO)$/init.obj \
        $(SLO)$/ring.obj \
@@ -77,7 +75,6 @@ SLOFILES =  \
        $(SLO)$/SwSmartTagMgr.obj

EXCEPTIONSFILES = \
        $(SLO)$/SwBitArray.obj \
        $(SLO)$/tabcol.obj

# --- Tagets -------------------------------------------------------
diff --git a/sw/source/core/crsr/bookmrk.cxx b/sw/source/core/crsr/bookmrk.cxx
index cb197d8..3179e3f 100644
--- a/sw/source/core/crsr/bookmrk.cxx
+++ b/sw/source/core/crsr/bookmrk.cxx
@@ -33,205 +33,209 @@


#include <bookmrk.hxx>
#include <swtypes.hxx>
#include <IDocumentMarkAccess.hxx>
#include <doc.hxx>
#include <errhdl.hxx>
#include <ndtxt.hxx>
#include <pam.hxx>
#include <swserv.hxx>
#include <errhdl.hxx>
#include <IDocumentBookmarkAccess.hxx>
#include "ndtxt.hxx"
#include <svx/linkmgr.hxx>
#include <swtypes.hxx>
#include <undobj.hxx>
#include <rtl/random.h>

SV_IMPL_REF( SwServerObject )

TYPEINIT1( SwBookmark, SwModify );  //rtti
using namespace ::sw::mark;

void lcl_FixPosition( SwPosition& rPos )
namespace
{
    // make sure the position has 1) the proper node, and 2) a proper index
    SwTxtNode* pTxtNode = rPos.nNode.GetNode().GetTxtNode();

    if( rPos.nContent.GetIndex() > ( pTxtNode == NULL ? 0 : pTxtNode->Len() ) )
    static void lcl_FixPosition(SwPosition& rPos)
    {
        DBG_ERROR( "illegal position" );
        xub_StrLen nLen = rPos.nContent.GetIndex();
        if( pTxtNode == NULL )
            nLen = 0;
        else if( nLen >= pTxtNode->Len() )
            nLen = pTxtNode->Len();
        rPos.nContent.Assign( pTxtNode, nLen );
    }
}

SwBookmark::SwBookmark(const SwPosition& aPos )
    : SwModify( 0 ),
    pPos2( 0 ),
    eMarkType( IDocumentBookmarkAccess::BOOKMARK )
{
    pPos1 = new SwPosition( aPos );
}


SwBookmark::SwBookmark(const SwPosition& aPos, const KeyCode& rCode,
                        const String& rName, const String& rShortName )
    : SwModify( 0 ),
    pPos2( 0 ),
    aName(rName),
    aShortName(rShortName),
    aCode(rCode),
    eMarkType( IDocumentBookmarkAccess::BOOKMARK )
{
    pPos1 = new SwPosition(aPos);
    // --> OD 2007-09-26 #i81002#
    lcl_FixPosition( *pPos1 );
    // <--
}

SwBookmark::SwBookmark( const SwPaM& aPaM,
                        const KeyCode& rCode,
                        const String& rName, const String& rShortName)
    : SwModify( 0 ),
      pPos1( 0 ),
      pPos2( 0 ),
      refObj(),
      aName(rName),
      aShortName(rShortName),
      aCode(rCode),
      eMarkType( IDocumentBookmarkAccess::BOOKMARK )
{
    pPos1 = new SwPosition( *(aPaM.GetPoint()) );
    lcl_FixPosition( *pPos1 );
    if ( aPaM.HasMark() )
    {
        pPos2 = new SwPosition( *(aPaM.GetMark()) );
        lcl_FixPosition( *pPos2 );
    }
}

// Beim Loeschen von Text werden Bookmarks mitgeloescht!


SwBookmark::~SwBookmark()
{
    // falls wir noch der DDE-Bookmark sind, dann muss der aus dem
    // Clipboard ausgetragen werden. Wird automatisch ueber DataChanged
    // ausgeloest.
    if( refObj.Is() )
    {
        if( IDocumentBookmarkAccess::DDE_BOOKMARK == eMarkType && refObj->HasDataLinks() )
        // make sure the position has 1) the proper node, and 2) a proper index
        SwTxtNode* pTxtNode = rPos.nNode.GetNode().GetTxtNode();
        if(pTxtNode == NULL && rPos.nContent.GetIndex() > 0)
        {
            ::sfx2::SvLinkSource* p = &refObj;
            p->SendDataChanged();
            OSL_TRACE(
                "bookmrk.cxx::lcl_FixPosition"
                " - illegal position: %d without proper TxtNode", rPos.nContent.GetIndex());
            rPos.nContent.Assign(NULL, 0);
        }
        refObj->SetNoServer();
    }

    delete pPos1;
    if( pPos2 )
        delete pPos2;
}

// Vergleiche auf Basis der Dokumentposition

BOOL SwBookmark::operator<(const SwBookmark &rBM) const
{
    // --> OD 2007-10-11 #i81002# - refactoring
    // simplification by using <BookmarkStart()>
//    const SwPosition* pThisPos = ( !pPos2 || *pPos1 <= *pPos2 ) ? pPos1 : pPos2;
//    const SwPosition* pBMPos = ( !rBM.pPos2 || *rBM.pPos1 <= *rBM.pPos2 )
//                                        ? rBM.pPos1 : rBM.pPos2;

//    return *pThisPos < *pBMPos;
    return *(BookmarkStart()) < *(rBM.BookmarkStart());
}

BOOL SwBookmark::operator==(const SwBookmark &rBM) const
{
    return (this == &rBM);
}

BOOL SwBookmark::IsEqualPos( const SwBookmark &rBM ) const
{
    // --> OD 2007-10-11 #i81002# - refactoring
    // simplification by using <BookmarkStart()>
//    const SwPosition* pThisPos = ( !pPos2 || *pPos1 <= *pPos2 ) ? pPos1 : pPos2;
//    const SwPosition* pBMPos = ( !rBM.pPos2 || *rBM.pPos1 <= *rBM.pPos2 )
//                                        ? rBM.pPos1 : rBM.pPos2;

//    return *pThisPos == *pBMPos;
    return *(BookmarkStart()) == *(rBM.BookmarkStart());
}

void SwBookmark::SetRefObject( SwServerObject* pObj )
{
    refObj = pObj;
}

// --> OD 2007-10-10 #i81002#
const SwPosition& SwBookmark::GetBookmarkPos() const
{
    return *pPos1;
}

const SwPosition* SwBookmark::GetOtherBookmarkPos() const
{
    return pPos2;
}

const SwPosition* SwBookmark::BookmarkStart() const
{
    return pPos2 ? (*pPos1 <= *pPos2 ? pPos1 : pPos2) : pPos1;
}

const SwPosition* SwBookmark::BookmarkEnd() const
{
    return pPos2 ? (*pPos1 >= *pPos2 ? pPos1 : pPos2) : pPos1;
}
// <--

// --> OD 2007-09-26 #i81002#
void SwBookmark::SetBookmarkPos( const SwPosition* pNewPos1 )
{
    ASSERT( pNewPos1 != 0,
            "<SwBookmark::SetBookmarkPos(..)> - Bookmark position 1 can't be NULL --> crash." );
    *pPos1 = *pNewPos1;
}
void SwBookmark::SetOtherBookmarkPos( const SwPosition* pNewPos2 )
{
    if ( pNewPos2 != 0 )
    {
        if ( pPos2 != 0 )
        else if(pTxtNode != NULL && rPos.nContent.GetIndex() > pTxtNode->Len())
        {
            *pPos2 = *pNewPos2;
            OSL_TRACE(
                "bookmrk.cxx::lcl_FixPosition"
                " - illegal position: %d is beyond %d", rPos.nContent.GetIndex(), pTxtNode->Len());
            rPos.nContent.Assign(pTxtNode, pTxtNode->Len());
        }
        else
    };

    static void lcl_AssureFieldMarksSet(Fieldmark* const pField,
        SwDoc* const io_pDoc,
        const sal_Unicode aStartMark,
        const sal_Unicode aEndMark)
    {
        const SwPosition& rStart = pField->GetMarkStart();
        const SwPosition& rEnd = pField->GetMarkEnd();
        SwTxtNode const * const pStartTxtNode = io_pDoc->GetNodes()[rStart.nNode]->GetTxtNode();
        SwTxtNode const * const pEndTxtNode = io_pDoc->GetNodes()[rEnd.nNode]->GetTxtNode();
        const sal_Unicode ch_start=pStartTxtNode->GetTxt().GetChar(rStart.nContent.GetIndex());
        const sal_Unicode ch_end=pEndTxtNode->GetTxt().GetChar(rEnd.nContent.GetIndex()-1);
        const SwPaM aStartPaM(rStart);
        const SwPaM aEndPaM(rEnd);
        io_pDoc->StartUndo(UNDO_UI_REPLACE, NULL);
        if(ch_start != aStartMark)
            io_pDoc->Insert(aStartPaM, aStartMark);
        if(aEndMark && ch_end != aEndMark)
            io_pDoc->Insert(aEndPaM, aEndMark);
        io_pDoc->EndUndo(UNDO_UI_REPLACE, NULL);
    };
}

namespace sw { namespace mark
{
    MarkBase::MarkBase(const SwPaM& aPaM,
        const ::rtl::OUString& rName)
        : SwModify(0)
        , m_pPos1(new SwPosition(*(aPaM.GetPoint())))
        , m_aName(rName)
    {
        lcl_FixPosition(*m_pPos1);
        if(aPaM.HasMark())
        {
            pPos2 = new SwPosition( *pNewPos2 );
            MarkBase::SetOtherMarkPos(*(aPaM.GetMark()));
            lcl_FixPosition(*m_pPos2);
        }
    }
    else

    void MarkBase::SetMarkPos(const SwPosition& rNewPos)
    {
        delete pPos2;
        pPos2 = 0;
        ::boost::scoped_ptr<SwPosition>(new SwPosition(rNewPos)).swap(m_pPos1);
        //lcl_FixPosition(*m_pPos1);
    }
}
// <--

SwMark::SwMark( const SwPosition& aPos,
                const KeyCode& rCode,
                const String& rName,
                const String& rShortName )
    : SwBookmark( aPos, rCode, rName, rShortName )
{
    eMarkType = IDocumentBookmarkAccess::MARK;
}
    void MarkBase::SetOtherMarkPos(const SwPosition& rNewPos)
    {
        ::boost::scoped_ptr<SwPosition>(new SwPosition(rNewPos)).swap(m_pPos2);
        //lcl_FixPosition(*m_pPos2);
    }

// --> OD 2007-09-26 #i81002#
SwUNOMark::SwUNOMark( const SwPaM& aPaM,
                const KeyCode& rCode,
                const String& rName,
                const String& rShortName )
    : SwBookmark( aPaM, rCode, rName, rShortName )
{
    eMarkType = IDocumentBookmarkAccess::UNO_BOOKMARK;
}
// <--
    MarkBase::~MarkBase()
    { }

    ::rtl::OUString MarkBase::GenerateNewName(const ::rtl::OUString& rPrefix)
    {
        static rtlRandomPool aPool = rtl_random_createPool();
        static ::rtl::OUString sUniquePostfix;
        static sal_Int32 nCount = SAL_MAX_INT32;
        ::rtl::OUStringBuffer aResult(rPrefix);
        if(nCount == SAL_MAX_INT32)
        {
            sal_Int32 nRandom;
            ::rtl::OUStringBuffer sUniquePostfixBuffer;
            rtl_random_getBytes(aPool, &nRandom, sizeof(nRandom));
            sUniquePostfix = ::rtl::OUStringBuffer(13).appendAscii("_").append(static_cast<sal_Int32>(abs(nRandom))).makeStringAndClear();
            nCount = 0;
        }
        // putting the counter in front of the random parts will speed up string comparisons
        return aResult.append(nCount++).append(sUniquePostfix).makeStringAndClear();
    }


    NavigatorReminder::NavigatorReminder(const SwPaM& rPaM)
        : MarkBase(rPaM, our_sNamePrefix)
    { }

    const ::rtl::OUString NavigatorReminder::our_sNamePrefix = ::rtl::OUString::createFromAscii("__NavigatorReminder__");

    UnoMark::UnoMark(const SwPaM& aPaM)
        : MarkBase(aPaM, MarkBase::GenerateNewName(our_sNamePrefix))
    { }

    const ::rtl::OUString UnoMark::our_sNamePrefix = ::rtl::OUString::createFromAscii("__UnoMark__");

    DdeBookmark::DdeBookmark(const SwPaM& aPaM)
        : MarkBase(aPaM, MarkBase::GenerateNewName(our_sNamePrefix))
        , m_aRefObj(NULL)
    { }

    void DdeBookmark::SetRefObject(SwServerObject* pObj)
    {
        m_aRefObj = pObj;
    }

    const ::rtl::OUString DdeBookmark::our_sNamePrefix = ::rtl::OUString::createFromAscii("__DdeLink__");

    void DdeBookmark::DeregisterFromDoc(SwDoc* const pDoc)
    {
        if(m_aRefObj.Is())
            pDoc->GetLinkManager().RemoveServer(m_aRefObj);
    }

    DdeBookmark::~DdeBookmark()
    {
        if( m_aRefObj.Is() )
        {
            if(m_aRefObj->HasDataLinks())
            {
                ::sfx2::SvLinkSource* p = &m_aRefObj;
                p->SendDataChanged();
            }
            m_aRefObj->SetNoServer();
        }
    }

    Bookmark::Bookmark(const SwPaM& aPaM,
        const KeyCode& rCode,
        const ::rtl::OUString& rName,
        const ::rtl::OUString& rShortName)
        : DdeBookmark(aPaM)
        , m_aCode(rCode)
        , m_sShortName(rShortName)
    {
        m_aName = rName;
    }

    void Bookmark::InitDoc(SwDoc* const io_pDoc)
    {
        if(io_pDoc->DoesUndo())
        {
            io_pDoc->ClearRedo();
            io_pDoc->AppendUndo(new SwUndoInsBookmark(*this));
        }
        io_pDoc->SetModified();
    }

    Fieldmark::Fieldmark(const SwPaM& rPaM)
        : MarkBase(rPaM, MarkBase::GenerateNewName(our_sNamePrefix))
    {
        if(!IsExpanded())
            SetOtherMarkPos(GetMarkPos());
    }

    const ::rtl::OUString Fieldmark::our_sNamePrefix = ::rtl::OUString::createFromAscii("__Fieldmark__");

    TextFieldmark::TextFieldmark(const SwPaM& rPaM)
        : Fieldmark(rPaM)
    { }

    void TextFieldmark::InitDoc(SwDoc* const io_pDoc)
    {
        lcl_AssureFieldMarksSet(this, io_pDoc, CH_TXT_ATR_FIELDSTART, CH_TXT_ATR_FIELDEND);
    }

    CheckboxFieldmark::CheckboxFieldmark(const SwPaM& rPaM)
        : Fieldmark(rPaM)
    { }

    void CheckboxFieldmark::InitDoc(SwDoc* const io_pDoc)
    {
        lcl_AssureFieldMarksSet(this, io_pDoc, CH_TXT_ATR_FIELDSTART, CH_TXT_ATR_FIELDEND);
    }

    void CheckboxFieldmark::SetChecked(bool checked)
        { m_isChecked = checked; }

    bool CheckboxFieldmark::IsChecked() const
        { return m_isChecked; }
}}
diff --git a/sw/source/core/crsr/crbm.cxx b/sw/source/core/crsr/crbm.cxx
index 0714701..1d7f019 100644
--- a/sw/source/core/crsr/crbm.cxx
+++ b/sw/source/core/crsr/crbm.cxx
@@ -35,299 +35,229 @@
#include "crsrsh.hxx"
#include "ndtxt.hxx"
#include <docary.hxx>
#include <boost/bind.hpp>

#include "bookmrk.hxx"
#include "IMark.hxx"
#include "callnk.hxx"
#include "swcrsr.hxx"
#include <IDocumentBookmarkAccess.hxx>
#include <IDocumentMarkAccess.hxx>
#include <IDocumentSettingAccess.hxx>

/*
 * Methoden der SwCrsrShell fuer Bookmark
 */
using namespace std;

namespace
{
    struct CrsrStateHelper
    {
        CrsrStateHelper(SwCrsrShell& rShell)
            : m_aLink(rShell)
            , m_pCrsr(rShell.GetSwCrsr())
            , m_aSaveState(*m_pCrsr)
        { }

        void SetCrsrToMark(::sw::mark::IMark const * const pMark)
        {
            *(m_pCrsr->GetPoint()) = pMark->GetMarkStart();
            if(pMark->IsExpanded())
            {
                m_pCrsr->SetMark();
                *(m_pCrsr->GetMark()) = pMark->GetMarkEnd();
            }
        }

        // returns true if the Cursor had been rolled back
        bool RollbackIfIllegal()
        {
            if(m_pCrsr->IsSelOvr(nsSwCursorSelOverFlags::SELOVER_CHECKNODESSECTION
                | nsSwCursorSelOverFlags::SELOVER_TOGGLE))
            {
                m_pCrsr->DeleteMark();
                m_pCrsr->RestoreSavePos();
                return true;
            }
            return false;
        }

        SwCallLink m_aLink;
        SwCursor* m_pCrsr;
        SwCrsrSaveState m_aSaveState;
    };


// am CurCrsr.SPoint
BOOL SwCrsrShell::SetBookmark( const KeyCode& rCode, const String& rName,
                                const String& rShortName, IDocumentBookmarkAccess::BookmarkType eMark )
    static bool lcl_ReverseMarkOrderingByEnd(const IDocumentMarkAccess::pMark_t& rpFirst,
        const IDocumentMarkAccess::pMark_t& rpSecond)
    {
        return rpFirst->GetMarkEnd() > rpSecond->GetMarkEnd();
    }

    static bool lcl_IsInvisibleBookmark(IDocumentMarkAccess::pMark_t pMark)
    {
        return IDocumentMarkAccess::GetType(*pMark) != IDocumentMarkAccess::BOOKMARK;
    }
}

// at CurCrsr.SPoint
::sw::mark::IMark* SwCrsrShell::SetBookmark(
    const KeyCode& rCode,
    const ::rtl::OUString& rName,
    const ::rtl::OUString& rShortName,
    IDocumentMarkAccess::MarkType eMark)
{
    StartAction();
    BOOL bRet = 0 != getIDocumentBookmarkAccess()->makeBookmark( *GetCrsr(), rCode, rName,
                                                                    rShortName, eMark);
    ::sw::mark::IMark* pMark = getIDocumentMarkAccess()->makeMark(
        *GetCrsr(),
        rName,
        eMark);
    ::sw::mark::IBookmark* pBookmark = dynamic_cast< ::sw::mark::IBookmark* >(pMark);
    if(pBookmark)
    {
        pBookmark->SetKeyCode(rCode);
        pBookmark->SetShortName(rShortName);
    }
    EndAction();
    return bRet;
    return pMark;
}
// setzt CurCrsr.SPoint


BOOL SwCrsrShell::GotoBookmark(USHORT nPos, BOOL bAtStart)
bool SwCrsrShell::GotoMark(const ::sw::mark::IMark* const pMark, bool bAtStart)
{
    // Crsr-Moves ueberwachen, evt. Link callen
    BOOL bRet = TRUE;
    SwCallLink aLk( *this );

    SwBookmark* pBkmk = getIDocumentBookmarkAccess()->getBookmarks()[ nPos ];
    SwCursor* pCrsr = GetSwCrsr();
    SwCrsrSaveState aSaveState( *pCrsr );

    // --> OD 2007-09-27 #i81002# - refactoring
    // simplify by using <SwBookmark::BookmarkStart()/BookmarkEnd()>
//    if( pBkmk->GetOtherBookmarkPos() )
//  {
//      if( bAtStart )
//            *pCrsr->GetPoint() = *pBkmk->GetOtherBookmarkPos() < pBkmk->GetBookmarkPos()
//                                    ? *pBkmk->GetOtherBookmarkPos()
//                                    : pBkmk->GetBookmarkPos();
//      else
//            *pCrsr->GetPoint() = *pBkmk->GetOtherBookmarkPos() > pBkmk->GetBookmarkPos()
//                                    ? *pBkmk->GetOtherBookmarkPos()
//                                    : pBkmk->GetBookmarkPos();
//  }
//  else
//        *pCrsr->GetPoint() = pBkmk->GetBookmarkPos();
    // watch Crsr-Moves
    CrsrStateHelper aCrsrSt(*this);
    if ( bAtStart )
    {
        *pCrsr->GetPoint() = *pBkmk->BookmarkStart();
    }
        *(aCrsrSt.m_pCrsr)->GetPoint() = pMark->GetMarkStart();
    else
    {
        *pCrsr->GetPoint() = *pBkmk->BookmarkEnd();
    }
    // <--
        *(aCrsrSt.m_pCrsr)->GetPoint() = pMark->GetMarkEnd();
    if(aCrsrSt.RollbackIfIllegal()) return false;

    if( pCrsr->IsSelOvr( nsSwCursorSelOverFlags::SELOVER_CHECKNODESSECTION |
                         nsSwCursorSelOverFlags::SELOVER_TOGGLE ) )
    {
        pCrsr->DeleteMark();
        pCrsr->RestoreSavePos();
        bRet = FALSE;
    }
    else
        UpdateCrsr(SwCrsrShell::SCROLLWIN|SwCrsrShell::CHKRANGE|SwCrsrShell::READONLY);
    return bRet;
    UpdateCrsr(SwCrsrShell::SCROLLWIN|SwCrsrShell::CHKRANGE|SwCrsrShell::READONLY);
    return true;
}


BOOL SwCrsrShell::GotoBookmark(USHORT nPos)
bool SwCrsrShell::GotoMark(const ::sw::mark::IMark* const pMark)
{
    // Crsr-Moves ueberwachen, evt. Link callen
    BOOL bRet = TRUE;
    SwCallLink aLk( *this );
    SwBookmark* pBkmk = getIDocumentBookmarkAccess()->getBookmarks()[ nPos ];
    SwCursor* pCrsr = GetSwCrsr();
    SwCrsrSaveState aSaveState( *pCrsr );
    // watch Crsr-Moves
    CrsrStateHelper aCrsrSt(*this);
    aCrsrSt.SetCrsrToMark(pMark);

    // --> OD 2007-09-27 #i81002# - refactoring
    // simplify by using <SwBookmark::GetBookmarkStart()/GetBookmarkEnd()>
//    *pCrsr->GetPoint() = pBkmk->GetBookmarkPos();
    *pCrsr->GetPoint() = *pBkmk->BookmarkStart();
    if( pBkmk->GetOtherBookmarkPos() )
    {
        pCrsr->SetMark();
//        *pCrsr->GetMark() = *pBkmk->GetOtherBookmarkPos();
        *pCrsr->GetMark() = *pBkmk->BookmarkEnd();
//        if( *pCrsr->GetMark() > *pCrsr->GetPoint() )
//            pCrsr->Exchange();
    }
    // <--
    if(aCrsrSt.RollbackIfIllegal()) return false;

    if( pCrsr->IsSelOvr( nsSwCursorSelOverFlags::SELOVER_CHECKNODESSECTION |
                         nsSwCursorSelOverFlags::SELOVER_TOGGLE ) )
    {
        pCrsr->DeleteMark();
        pCrsr->RestoreSavePos();
        bRet = FALSE;
    }
    else
        UpdateCrsr(SwCrsrShell::SCROLLWIN|SwCrsrShell::CHKRANGE|SwCrsrShell::READONLY);
    return bRet;
    UpdateCrsr(SwCrsrShell::SCROLLWIN|SwCrsrShell::CHKRANGE|SwCrsrShell::READONLY);
    return true;
}
// TRUE, wenn's noch eine gab


BOOL SwCrsrShell::GoNextBookmark()
bool SwCrsrShell::GoNextBookmark()
{
    SwBookmark aBM(*GetCrsr()->GetPoint());
    USHORT nPos;
    const SwBookmarks& rBkmks = getIDocumentBookmarkAccess()->getBookmarks();
    rBkmks.Seek_Entry( &aBM, &nPos );
    if ( nPos == rBkmks.Count() )
        return FALSE;
    IDocumentMarkAccess* const pMarkAccess = getIDocumentMarkAccess();
    IDocumentMarkAccess::container_t vCandidates;
    remove_copy_if(
        upper_bound(
            pMarkAccess->getBookmarksBegin(),
            pMarkAccess->getBookmarksEnd(),
            *GetCrsr()->GetPoint(),
            bind(&::sw::mark::IMark::StartsAfter, _2, _1)), // finds the first that is starting after
        pMarkAccess->getBookmarksEnd(),
        back_inserter(vCandidates),
        &lcl_IsInvisibleBookmark);

    // alle die Inhaltlich auf der gleichen Position stehen, ueberspringen
    while( aBM.IsEqualPos( *rBkmks[ nPos ] ))
        if( ++nPos == rBkmks.Count() )
            return FALSE;
    // watch Crsr-Moves
    CrsrStateHelper aCrsrSt(*this);
    IDocumentMarkAccess::const_iterator_t ppMark = vCandidates.begin();
    for(; ppMark!=vCandidates.end(); ++ppMark)
    {
        aCrsrSt.SetCrsrToMark(ppMark->get());
        if(!aCrsrSt.RollbackIfIllegal())
            break; // found legal move
    }
    if(ppMark==vCandidates.end())
    {
        SttEndDoc(false);
        return false;
    }

    while( !GotoBookmark( nPos ))
        if( ++nPos == rBkmks.Count() )
            return FALSE;

    return TRUE;
    UpdateCrsr(SwCrsrShell::SCROLLWIN|SwCrsrShell::CHKRANGE|SwCrsrShell::READONLY);
    return true;
}

bool SwCrsrShell::GoPrevBookmark()
{
    IDocumentMarkAccess* const pMarkAccess = getIDocumentMarkAccess();
    // candidates from which to choose the mark before
    // no need to consider marks starting after rPos
    IDocumentMarkAccess::container_t vCandidates;
    remove_copy_if(
        pMarkAccess->getBookmarksBegin(),
        upper_bound(
            pMarkAccess->getBookmarksBegin(),
            pMarkAccess->getBookmarksEnd(),
            *GetCrsr()->GetPoint(),
            bind(&::sw::mark::IMark::StartsAfter, _2, _1)),
        back_inserter(vCandidates),
        &lcl_IsInvisibleBookmark);
    sort(
        vCandidates.begin(),
        vCandidates.end(),
        &lcl_ReverseMarkOrderingByEnd);

    // watch Crsr-Moves
    CrsrStateHelper aCrsrSt(*this);
    IDocumentMarkAccess::const_iterator_t ppMark = vCandidates.begin();
    for(; ppMark!=vCandidates.end(); ++ppMark)
    {
        // ignoring those not ending before the Crsr
        // (we were only able to eliminate those starting
        // behind the Crsr by the upper_bound(..)
        // above)
        if(!(**ppMark).EndsBefore(*GetCrsr()->GetPoint()))
            continue;
        aCrsrSt.SetCrsrToMark(ppMark->get());
        if(!aCrsrSt.RollbackIfIllegal())
            break; // found legal move
    }
    if(ppMark==vCandidates.end())
    {
        SttEndDoc(true);
        return false;
    }

    UpdateCrsr(SwCrsrShell::SCROLLWIN|SwCrsrShell::CHKRANGE|SwCrsrShell::READONLY);
    return true;
}

bool SwCrsrShell::IsFormProtected()
{
    return getIDocumentSettingAccess()->get(IDocumentSettingAccess::PROTECT_FORM);
}

SwBookmark* SwCrsrShell::IsInFieldBookmark()
::sw::mark::IFieldmark* SwCrsrShell::GetCurrentFieldmark()
{
    // TODO: Refactor
    SwPosition pos(*GetCrsr()->GetPoint());
    return getIDocumentBookmarkAccess()->getFieldBookmarkFor(pos);
    return getIDocumentMarkAccess()->getFieldmarkFor(pos);
}

SwFieldBookmark* SwCrsrShell::IsInFormFieldBookmark()
{
    // TODO: Refactor
    SwPosition pos(*GetCrsr()->GetPoint());
    return (SwFieldBookmark*)getIDocumentBookmarkAccess()->getFormFieldBookmarkFor(pos);
}

SwBookmark* SwCrsrShell::GetNextFieldBookmark()
::sw::mark::IFieldmark* SwCrsrShell::GetFieldmarkAfter()
{
    SwPosition pos(*GetCrsr()->GetPoint());
    return getIDocumentBookmarkAccess()->getNextFieldBookmarkFor(pos);
    return getIDocumentMarkAccess()->getFieldmarkAfter(pos);
}

SwBookmark* SwCrsrShell::GetPrevFieldBookmark()
::sw::mark::IFieldmark* SwCrsrShell::GetFieldmarkBefore()
{
    SwPosition pos(*GetCrsr()->GetPoint());
    return getIDocumentBookmarkAccess()->getPrevFieldBookmarkFor(pos);
    return getIDocumentMarkAccess()->getFieldmarkBefore(pos);
}

bool SwCrsrShell::GotoFieldBookmark(SwBookmark *pBkmk)
bool SwCrsrShell::GotoFieldmark(::sw::mark::IFieldmark const * const pMark)
{
    if(pBkmk==NULL) return false;
    // Crsr-Moves ueberwachen, evt. Link callen
    bool bRet = true;
    SwCallLink aLk( *this );
    SwCursor* pCrsr = GetSwCrsr();
    SwCrsrSaveState aSaveState( *pCrsr );
    if(pMark==NULL) return false;

    *pCrsr->GetPoint() = pBkmk->GetBookmarkPos();
    if( pBkmk->GetOtherBookmarkPos() )
    {
        pCrsr->SetMark();
        *pCrsr->GetMark() = *pBkmk->GetOtherBookmarkPos();
        if( *pCrsr->GetMark() > *pCrsr->GetPoint() )
            pCrsr->Exchange();
    }
    pCrsr->GetPoint()->nContent--;
    pCrsr->GetMark()->nContent++;
    // watch Crsr-Moves
    CrsrStateHelper aCrsrSt(*this);
    aCrsrSt.SetCrsrToMark(pMark);
    //aCrsrSt.m_pCrsr->GetPoint()->nContent--;
    //aCrsrSt.m_pCrsr->GetMark()->nContent++;
    if(aCrsrSt.RollbackIfIllegal()) return false;


    if( pCrsr->IsSelOvr( nsSwCursorSelOverFlags::SELOVER_CHECKNODESSECTION | nsSwCursorSelOverFlags::SELOVER_TOGGLE ) )
    {
        pCrsr->DeleteMark();
        pCrsr->RestoreSavePos();
        bRet = false;
    }
    else
        UpdateCrsr(SwCrsrShell::SCROLLWIN|SwCrsrShell::CHKRANGE|SwCrsrShell::READONLY);

    return bRet;
}

BOOL SwCrsrShell::GoPrevBookmark()
{
    const SwBookmarks& rBkmks = getIDocumentBookmarkAccess()->getBookmarks();
    if ( !rBkmks.Count() )
        return FALSE;

    USHORT nPos;
    SwCursor* pCrsr = GetSwCrsr();
    SwBookmark aBM( *pCrsr->GetPoint() );
    rBkmks.Seek_Entry( &aBM, &nPos );

    const SwBookmark* pBkmk;
    // alle die Inhaltlich auf der gleichen Position stehen, ueberspringen
    do
    {
        if ( nPos == 0 )
            return FALSE;
    } while( aBM < *(pBkmk = rBkmks[--nPos]) || aBM.IsEqualPos( *pBkmk ));

    SwCallLink aLk( *this );
    SwCrsrSaveState aSaveState( *pCrsr );

    BOOL bRet = FALSE;
    do
    {
        pBkmk = rBkmks[ nPos ];

        // --> OD 2007-09-27 #i81002# - refactoring
        // simplify by using <SwBookmark::BookmarkStart()/BookmarkEnd()>
        *pCrsr->GetPoint() = *pBkmk->BookmarkStart();
//        *pCrsr->GetPoint() = pBkmk->GetBookmarkPos();
        if( pBkmk->GetOtherBookmarkPos() )
        {
            pCrsr->SetMark();
//            *pCrsr->GetMark() = *pBkmk->GetOtherBookmarkPos();
            *pCrsr->GetMark() = *pBkmk->BookmarkEnd();
//            if( *pCrsr->GetMark() < *pCrsr->GetPoint() )
//                pCrsr->Exchange();
        }
        // <--
        if( !pCrsr->IsSelOvr( nsSwCursorSelOverFlags::SELOVER_CHECKNODESSECTION |
                              nsSwCursorSelOverFlags::SELOVER_TOGGLE ) )
        {
            UpdateCrsr(SwCrsrShell::SCROLLWIN|SwCrsrShell::CHKRANGE|SwCrsrShell::READONLY);
            bRet = TRUE;
        }

    } while( !bRet && nPos-- );

    if( !bRet )
    {
        pCrsr->DeleteMark();
        pCrsr->RestoreSavePos();
    }

    return bRet;
}



USHORT SwCrsrShell::GetBookmarkCnt(BOOL bBkmrk) const
{
    return getIDocumentBookmarkAccess()->getBookmarkCount(bBkmrk);
}


SwBookmark& SwCrsrShell::GetBookmark(USHORT nPos, BOOL bBkmrk)
{
    return getIDocumentBookmarkAccess()->getBookmark(nPos, bBkmrk);
}


void SwCrsrShell::DelBookmark(USHORT nPos)
{
    StartAction();
    getIDocumentBookmarkAccess()->deleteBookmark(nPos);
    EndAction();
}


void SwCrsrShell::DelBookmark( const String& rName )
{
    StartAction();
    getIDocumentBookmarkAccess()->deleteBookmark( rName );
    EndAction();
}


USHORT SwCrsrShell::FindBookmark( const String& rName )
{
    return getIDocumentBookmarkAccess()->findBookmark( rName );
}


// erzeugt einen eindeutigen Namen. Der Name selbst muss vorgegeben
// werden, es wird dann bei gleichen Namen nur durchnumeriert.
void SwCrsrShell::MakeUniqueBookmarkName( String& rName )
{
    getIDocumentBookmarkAccess()->makeUniqueBookmarkName( rName );
    UpdateCrsr(SwCrsrShell::SCROLLWIN|SwCrsrShell::CHKRANGE|SwCrsrShell::READONLY);
    return true;
}
diff --git a/sw/source/core/crsr/crossrefbookmark.cxx b/sw/source/core/crsr/crossrefbookmark.cxx
index 6841aba..38b502c 100644
--- a/sw/source/core/crsr/crossrefbookmark.cxx
+++ b/sw/source/core/crsr/crossrefbookmark.cxx
@@ -32,62 +32,79 @@
#include "precompiled_sw.hxx"

#include <crossrefbookmark.hxx>

#include <ndtxt.hxx>

TYPEINIT1( SwCrossRefBookmark, SwBookmark );  //rtti
using namespace rtl;

SwCrossRefBookmark::SwCrossRefBookmark( const SwPosition& aPos,
                                        const KeyCode& rCode,
                                        const String& rName,
                                        const String& rShortName )
    : SwBookmark( SwPosition( aPos ), rCode, rName, rShortName ),
      // --> OD 2007-11-16 #i83479#
      mnSubType( bookmarkfunc::isHeadingCrossRefBookmarkName( rName )
                 ? IDocumentBookmarkAccess::HEADING
                 : IDocumentBookmarkAccess::NUMITEM )
      // <--
namespace sw { namespace mark
{
    eMarkType = IDocumentBookmarkAccess::CROSSREF_BOOKMARK;
    CrossRefBookmark::CrossRefBookmark(const SwPaM& rPaM,
        const KeyCode& rCode,
        const OUString& rName,
        const OUString& rShortName,
        const OUString& rPrefix)
        : Bookmark(rPaM, rCode, rName, rShortName)
    {
        if(rPaM.HasMark())
            OSL_ENSURE((rPaM.GetMark()->nNode == rPaM.GetPoint()->nNode &&
                rPaM.Start()->nContent.GetIndex() == 0 &&
                rPaM.End()->nContent.GetIndex() == rPaM.GetPoint()->nNode.GetNode().GetTxtNode()->Len()),
                "<CrossRefBookmark::CrossRefBookmark(..)>"
                "- creation of cross-reference bookmark with an expanded PaM that does not expand over exactly one whole paragraph.");
        SetMarkPos(*rPaM.Start());
        if(!rName.getLength())
            m_aName = MarkBase::GenerateNewName(rPrefix);
    }

    ASSERT( GetBookmarkPos().nNode.GetNode().GetTxtNode(),
            "<SwCrossRefBookmark::SwCrossRefBookmark(..)> - cross-reference bookmark doesn't mark text node." )
    ASSERT( GetBookmarkPos().nContent.GetIndex() == 0,
            "<SwCrossRefBookmark::SwCrossRefBookmark(..)> - cross-reference bookmark doesn't mark start of text node." )
    ASSERT( mnSubType == IDocumentBookmarkAccess::HEADING ||
            bookmarkfunc::isNumItemCrossRefBookmarkName( rName ),
            "<SwCrossRefBookmark::SwCrossRefBookmark(..)> - name doesn't fit. Serious issue, please inform OD!" );
}
    void CrossRefBookmark::SetMarkPos(const SwPosition& rNewPos)
    {
        OSL_PRECOND(rNewPos.nNode.GetNode().GetTxtNode(),
            "<SwCrossRefBookmark::SetMarkPos(..)>"
            " - new bookmark position for cross-reference bookmark doesn't mark text node");
        OSL_PRECOND(rNewPos.nContent.GetIndex() == 0,
            "<SwCrossRefBookmark::SetMarkPos(..)>"
            " - new bookmark position for cross-reference bookmark doesn't mark start of text node");
        MarkBase::SetMarkPos(rNewPos);
    }

SwCrossRefBookmark::~SwCrossRefBookmark()
{
}
    const SwPosition& CrossRefBookmark::GetOtherMarkPos() const
    {
        OSL_PRECOND(false,
            "<SwCrossRefBookmark::GetOtherMarkPos(..)>"
            " - this should never be called!");
        return *static_cast<SwPosition*>(NULL);
    }

IDocumentBookmarkAccess::CrossReferenceBookmarkSubType SwCrossRefBookmark::GetSubType() const
{
    return mnSubType;
}
    bool CrossRefBookmark::IsLegalName(const ::rtl::OUString& rName)
    {
        return CrossRefNumItemBookmark::IsLegalName(rName) || CrossRefHeadingBookmark::IsLegalName(rName);
    }

const SwPosition* SwCrossRefBookmark::GetOtherBookmarkPos() const
{
    return 0;
}
    CrossRefHeadingBookmark::CrossRefHeadingBookmark(const SwPaM& rPaM,
        const KeyCode& rCode,
        const OUString& rName,
        const OUString& rShortName)
        : CrossRefBookmark(rPaM, rCode, rName, rShortName, our_sNamePrefix)
    { }

void SwCrossRefBookmark::SetBookmarkPos( const SwPosition* pNewPos1 )
{
    ASSERT( pNewPos1->nNode.GetNode().GetTxtNode(),
            "<SwCrossRefBookmark::SetBookmarkPos(..)> - new bookmark position for cross-reference bookmark doesn't mark text node" );
    ASSERT( pNewPos1->nContent.GetIndex() == 0,
            "<SwCrossRefBookmark::SetBookmarkPos(..)> - new bookmark position for cross-reference bookmark doesn't mark start of text node" );
    const ::rtl::OUString CrossRefHeadingBookmark::our_sNamePrefix = ::rtl::OUString::createFromAscii("__RefHeading__");

    SwBookmark::SetBookmarkPos( pNewPos1 );
}
    bool CrossRefHeadingBookmark::IsLegalName(const ::rtl::OUString& rName)
    {
        return rName.match(our_sNamePrefix);
    }

void SwCrossRefBookmark::SetOtherBookmarkPos( const SwPosition* /*pNewPos2*/ )
{
    // the other bookmark position for a cross-reference bookmark is allowed
    // to be set.
    ASSERT( false,
            "<SwCrossRefBookmark::SetOtherBookmarkPos(..)> - misusage of SwCrossRefBookmark: other bookmark position isn't allowed to be set." );
}
    CrossRefNumItemBookmark::CrossRefNumItemBookmark(const SwPaM& rPaM,
        const KeyCode& rCode,
        const OUString& rName,
        const OUString& rShortName)
        : CrossRefBookmark(rPaM, rCode, rName, rShortName, our_sNamePrefix)
    { }

    const ::rtl::OUString CrossRefNumItemBookmark::our_sNamePrefix = ::rtl::OUString::createFromAscii("__RefNumPara__");

    bool CrossRefNumItemBookmark::IsLegalName(const ::rtl::OUString& rName)
    {
        return rName.match(our_sNamePrefix);
    }
}}
diff --git a/sw/source/core/crsr/makefile.mk b/sw/source/core/crsr/makefile.mk
index 5e31d44..57cb499 100644
--- a/sw/source/core/crsr/makefile.mk
+++ b/sw/source/core/crsr/makefile.mk
@@ -49,6 +49,7 @@ CDEFS+=-Dmydebug
# --- Files --------------------------------------------------------

EXCEPTIONSFILES=    \
    $(SLO)$/crbm.obj \
    $(SLO)$/crsrsh.obj \
    $(SLO)$/viscrs.obj

diff --git a/sw/source/core/crsr/pam.cxx b/sw/source/core/crsr/pam.cxx
index b49c5ad..860117b 100644
--- a/sw/source/core/crsr/pam.cxx
+++ b/sw/source/core/crsr/pam.cxx
@@ -55,7 +55,7 @@
// <--
#include <ndtxt.hxx> // #111827#

#include <bookmrk.hxx>
#include <IMark.hxx>

// fuer den dummen ?MSC-? Compiler
inline xub_StrLen GetSttOrEnd( BOOL bCondition, const SwCntntNode& rNd )
@@ -767,12 +767,13 @@ BOOL SwPaM::HasReadonlySel( bool bFormView ) const
            }
        }
    }
// TODO: Form Protection when Enhanced Fields are enabled
    //FIXME FieldBk
    // TODO: Form Protection when Enhanced Fields are enabled
//  if( !bRet )
//    {
//      const SwDoc *pDoc=GetDoc();
//      SwBookmark *pA = ( pDoc && pPoint ? pDoc->getFieldBookmarkFor( *pPoint ) : NULL );
//      SwBookmark *pB = ( pDoc && pMark ? pDoc->getFieldBookmarkFor( *pMark ) : pA );
//      SwBookmark *pA = ( pDoc && pPoint ? pDoc->getFieldmarkFor( *pPoint ) : NULL );
//      SwBookmark *pB = ( pDoc && pMark ? pDoc->getFieldmarkFor( *pMark ) : pA );
//      bRet = ( pA != pB );
//      bool bProtectForm = pDoc->get( IDocumentSettingAccess::PROTECT_FORM );
//      if( bProtectForm )
diff --git a/sw/source/core/crsr/viscrs.cxx b/sw/source/core/crsr/viscrs.cxx
index dd6d1e2..78169de 100644
--- a/sw/source/core/crsr/viscrs.cxx
+++ b/sw/source/core/crsr/viscrs.cxx
@@ -86,94 +86,94 @@ MapMode* SwSelPaintRects::pMapMode = 0;


#ifdef SHOW_BOOKMARKS
#include <bookmrk.hxx>

class SwBookmarkRects : public SwSelPaintRects
{
    virtual void Paint( const Rectangle& rRect );
    virtual void FillRects();

public:
    SwBookmarkRects( const SwCrsrShell& rSh ) : SwSelPaintRects( rSh ) {}
};

void SwBookmarkRects::Paint( const Rectangle& rRect )
{
    Window* pWin = GetShell()->GetWin();

    RasterOp eOld( pWin->GetRasterOp() );
    BOOL bLCol = pWin->IsLineColor();
    Color aLCol( pWin->GetLineColor() );
    BOOL bFCol = pWin->IsFillColor();
    Color aFCol( pWin->GetFillColor() );

    pWin->SetRasterOp( ROP_XOR );
    Color aCol( RGB_COLORDATA( 0xF0, 0xC8, 0xF0 ) ^ COL_WHITE );
    pWin->SetFillColor( aCol );
    pWin->SetLineColor( aCol );

    pWin->DrawRect( rRect );

    if( bLCol ) pWin->SetLineColor( aLCol ); else pWin->SetLineColor();
    if( bFCol ) pWin->SetFillColor( aFCol ); else pWin->SetFillColor();
    pWin->SetRasterOp( eOld );
}

void SwBookmarkRects::FillRects()
{
    SwRegionRects aReg( GetShell()->VisArea() );

    const SwBookmarks& rBkmkTbl = GetShell()->getIDocumentBookmarkAccess()->getBookmarks();
    SwShellCrsr* pCrsr = 0;
    for( USHORT n = 0; n < rBkmkTbl.Count(); ++n )
    {
        const SwBookmark& rBkmk = *rBkmkTbl[ n ];
        if( rBkmk.IsBookMark() && rBkmk.GetOtherPos() )
        {
            if( !pCrsr )
            {
                pCrsr = new SwShellCrsr( *GetShell(), rBkmk.GetPos() );
                pCrsr->SetMark();
            }
            else
                *pCrsr->GetPoint() = rBkmk.GetPos();
            *pCrsr->GetMark() = *rBkmk.GetOtherPos();
            pCrsr->FillRects();
            for( USHORT i = 0; i < pCrsr->Count(); ++i )
                aReg -= (*pCrsr)[ i ];

            pCrsr->Remove( 0, i );
        }
    }
    if( pCrsr ) delete pCrsr;

    aReg.Invert();
    SwRects::Insert( &aReg, 0 );
}

SwBookmarkRects* pBookMarkRects = 0;

void ShowBookmarks( const SwCrsrShell* pSh, int nAction, const SwRect* pRect = 0 )
{
    if( !pBookMarkRects && pSh->getIDocumentBookmarkAccess()->getBookmarks().Count() )
        pBookMarkRects = new SwBookmarkRects( *pSh );

    if( pBookMarkRects )
    {
        switch( nAction )
        {
        case 1: pBookMarkRects->Show(); break;
        case 2: pBookMarkRects->Hide(); break;
        case 3: pBookMarkRects->Invalidate( *pRect ); break;
        }

        if( !pBookMarkRects->Count() )
            delete pBookMarkRects, pBookMarkRects = 0;
    }
}

#define SHOWBOOKMARKS1( nAct )          ShowBookmarks( GetShell(),nAct );
#define SHOWBOOKMARKS2( nAct, pRect )   ShowBookmarks( GetShell(),nAct, pRect );
// #include <IMark.hxx>
//
// class SwBookmarkRects : public SwSelPaintRects
// {
//  virtual void Paint( const Rectangle& rRect );
//  virtual void FillRects();
//
// public:
//  SwBookmarkRects( const SwCrsrShell& rSh ) : SwSelPaintRects( rSh ) {}
// };
//
// void SwBookmarkRects::Paint( const Rectangle& rRect )
// {
//  Window* pWin = GetShell()->GetWin();
//
//  RasterOp eOld( pWin->GetRasterOp() );
//  BOOL bLCol = pWin->IsLineColor();
//  Color aLCol( pWin->GetLineColor() );
//  BOOL bFCol = pWin->IsFillColor();
//  Color aFCol( pWin->GetFillColor() );
//
//  pWin->SetRasterOp( ROP_XOR );
//  Color aCol( RGB_COLORDATA( 0xF0, 0xC8, 0xF0 ) ^ COL_WHITE );
//  pWin->SetFillColor( aCol );
//  pWin->SetLineColor( aCol );
//
//  pWin->DrawRect( rRect );
//
//  if( bLCol ) pWin->SetLineColor( aLCol ); else pWin->SetLineColor();
//  if( bFCol ) pWin->SetFillColor( aFCol ); else pWin->SetFillColor();
//  pWin->SetRasterOp( eOld );
// }
//
// void SwBookmarkRects::FillRects()
// {
//  SwRegionRects aReg( GetShell()->VisArea() );
//
//     const SwBookmarks& rBkmkTbl = GetShell()->getIDocumentMarkAccess()->getBookmarks();
//  SwShellCrsr* pCrsr = 0;
//  for( USHORT n = 0; n < rBkmkTbl.Count(); ++n )
//  {
//      const SwBookmark& rBkmk = *rBkmkTbl[ n ];
//      if( rBkmk.IsBookMark() && rBkmk.GetOtherPos() )
//      {
//          if( !pCrsr )
//          {
//              pCrsr = new SwShellCrsr( *GetShell(), rBkmk.GetPos() );
//              pCrsr->SetMark();
//          }
//          else
//              *pCrsr->GetPoint() = rBkmk.GetPos();
//          *pCrsr->GetMark() = *rBkmk.GetOtherPos();
//          pCrsr->FillRects();
//          for( USHORT i = 0; i < pCrsr->Count(); ++i )
//              aReg -= (*pCrsr)[ i ];
//
//          pCrsr->Remove( 0, i );
//      }
//  }
//  if( pCrsr ) delete pCrsr;
//
//  aReg.Invert();
//  SwRects::Insert( &aReg, 0 );
// }
//
// SwBookmarkRects* pBookMarkRects = 0;
//
// void ShowBookmarks( const SwCrsrShell* pSh, int nAction, const SwRect* pRect = 0 )
// {
//     if( !pBookMarkRects && pSh->getIDocumentMarkAccess()->getBookmarks().Count() )
//      pBookMarkRects = new SwBookmarkRects( *pSh );
//
//  if( pBookMarkRects )
//  {
//      switch( nAction )
//      {
//      case 1: pBookMarkRects->Show(); break;
//      case 2: pBookMarkRects->Hide(); break;
//      case 3: pBookMarkRects->Invalidate( *pRect ); break;
//      }
//
//      if( !pBookMarkRects->Count() )
//          delete pBookMarkRects, pBookMarkRects = 0;
//  }
// }
//
// #define SHOWBOOKMARKS1( nAct )           ShowBookmarks( GetShell(),nAct );
// #define SHOWBOOKMARKS2( nAct, pRect )    ShowBookmarks( GetShell(),nAct, pRect );

#else

diff --git a/sw/source/core/doc/dbgoutsw.cxx b/sw/source/core/doc/dbgoutsw.cxx
index 0e995f8..aee5a3c 100644
--- a/sw/source/core/doc/dbgoutsw.cxx
+++ b/sw/source/core/doc/dbgoutsw.cxx
@@ -90,7 +90,7 @@ String lcl_dbg_out_SvPtrArr(const T & rArr)
    return aStr;
}

const char * dbg_out(const void * pVoid)
SW_DLLPUBLIC const char * dbg_out(const void * pVoid)
{
    char sBuffer[1024];

@@ -101,7 +101,7 @@ const char * dbg_out(const void * pVoid)
    return dbg_out(aTmpStr);
}

const char * dbg_out(const String & aStr)
SW_DLLPUBLIC const char * dbg_out(const String & aStr)
{
    aDbgOutResult = ByteString(aStr, RTL_TEXTENCODING_ASCII_US);

@@ -269,18 +269,18 @@ const String lcl_dbg_out(const SfxPoolItem & rItem)
    return aStr;
}

const char * dbg_out(const SfxPoolItem & rItem)
SW_DLLPUBLIC const char * dbg_out(const SfxPoolItem & rItem)
{
    return dbg_out(lcl_dbg_out(rItem));
}

const char * dbg_out(const SfxPoolItem * pItem)
SW_DLLPUBLIC const char * dbg_out(const SfxPoolItem * pItem)
{
    return dbg_out(pItem ? lcl_dbg_out(*pItem) :
                   String("(nil)", RTL_TEXTENCODING_ASCII_US));
}

const String lcl_dbg_out(const SfxItemSet & rSet)
SW_DLLPUBLIC const String lcl_dbg_out(const SfxItemSet & rSet)
{
    SfxItemIter aIter(rSet);
    const SfxPoolItem * pItem;
@@ -309,7 +309,7 @@ const String lcl_dbg_out(const SfxItemSet & rSet)
    return aStr;
}

const char * dbg_out(const SfxItemSet & rSet)
SW_DLLPUBLIC const char * dbg_out(const SfxItemSet & rSet)
{
    return dbg_out(lcl_dbg_out(rSet));
}
@@ -329,7 +329,7 @@ const String lcl_dbg_out(const SwTxtAttr & rAttr)
    return aStr;
}

const char * dbg_out(const SwTxtAttr & rAttr)
SW_DLLPUBLIC const char * dbg_out(const SwTxtAttr & rAttr)
{
    return dbg_out(lcl_dbg_out(rAttr));
}
@@ -350,7 +350,7 @@ const String lcl_dbg_out(const SwpHints & rHints)
    return aStr;
}

const char * dbg_out(const SwpHints &rHints)
SW_DLLPUBLIC const char * dbg_out(const SwpHints &rHints)
{
    return dbg_out(lcl_dbg_out(rHints));
}
@@ -371,7 +371,7 @@ String lcl_dbg_out(const SwPosition & rPos)
    return aStr;
}

const char * dbg_out(const SwPosition & rPos)
SW_DLLPUBLIC const char * dbg_out(const SwPosition & rPos)
{
    return dbg_out(lcl_dbg_out(rPos));
}
@@ -393,7 +393,7 @@ String lcl_dbg_out(const SwPaM & rPam)
   return aStr;
}

const char * dbg_out(const SwPaM & rPam)
SW_DLLPUBLIC const char * dbg_out(const SwPaM & rPam)
{
    return dbg_out(lcl_dbg_out(rPam));
}
@@ -403,7 +403,7 @@ String lcl_dbg_out(const SwNodeNum & )
    return String();/*rNum.ToString();*/
}

const char * dbg_out(const SwNodeNum & rNum)
SW_DLLPUBLIC const char * dbg_out(const SwNodeNum & rNum)
{
    return dbg_out(lcl_dbg_out(rNum));
}
@@ -425,7 +425,7 @@ String lcl_dbg_out(const SwRect & rRect)
    return aResult;
}

const char * dbg_out(const SwRect & rRect)
SW_DLLPUBLIC const char * dbg_out(const SwRect & rRect)
{
    return dbg_out(lcl_dbg_out(rRect));
}
@@ -452,7 +452,7 @@ String lcl_dbg_out(const SwFrmFmt & rFrmFmt)
    return aResult;
}

const char * dbg_out(const SwFrmFmt & rFrmFmt)
SW_DLLPUBLIC const char * dbg_out(const SwFrmFmt & rFrmFmt)
{
    return dbg_out(lcl_dbg_out(rFrmFmt));
}
@@ -677,12 +677,12 @@ String lcl_dbg_out(const SwNode & rNode)
    return aTmpStr;
}

const char * dbg_out(const SwNode & rNode)
SW_DLLPUBLIC const char * dbg_out(const SwNode & rNode)
{
    return dbg_out(lcl_dbg_out(rNode));
}

const char * dbg_out(const SwNode * pNode)
SW_DLLPUBLIC const char * dbg_out(const SwNode * pNode)
{
    if (NULL != pNode)
        return dbg_out(*pNode);
@@ -690,7 +690,7 @@ const char * dbg_out(const SwNode * pNode)
        return NULL;
}

const char * dbg_out(const SwCntntNode * pNode)
SW_DLLPUBLIC const char * dbg_out(const SwCntntNode * pNode)
{
    if (NULL != pNode)
        return dbg_out(*pNode);
@@ -698,7 +698,7 @@ const char * dbg_out(const SwCntntNode * pNode)
        return NULL;
}

const char * dbg_out(const SwTxtNode * pNode)
SW_DLLPUBLIC const char * dbg_out(const SwTxtNode * pNode)
{
    if (NULL != pNode)
        return dbg_out(*pNode);
@@ -741,7 +741,7 @@ String lcl_dbg_out(SwNodes & rNodes)
    return aStr;
}

const char * dbg_out(SwNodes & rNodes)
SW_DLLPUBLIC const char * dbg_out(SwNodes & rNodes)
{
    return dbg_out(lcl_dbg_out(rNodes));
}
@@ -793,7 +793,7 @@ String lcl_dbg_out(const SwUndo & rUndo)
    return aStr;
}

const char * dbg_out(const SwUndo & rUndo)
SW_DLLPUBLIC const char * dbg_out(const SwUndo & rUndo)
{
    return dbg_out(lcl_dbg_out(rUndo));
}
@@ -813,7 +813,7 @@ String lcl_dbg_out(SwOutlineNodes & rNodes)
    return aStr;
}

const char * dbg_out(SwOutlineNodes & rNodes)
SW_DLLPUBLIC const char * dbg_out(SwOutlineNodes & rNodes)
{
    return dbg_out(lcl_dbg_out(rNodes));
}
@@ -846,7 +846,7 @@ String lcl_dbg_out(const SwUndos & rUndos)
    return aStr;
}

const char * dbg_out(const SwUndos & rUndos)
SW_DLLPUBLIC const char * dbg_out(const SwUndos & rUndos)
{
    return dbg_out(lcl_dbg_out(rUndos));
}
@@ -861,7 +861,7 @@ String lcl_dbg_out(const SwRewriter & rRewriter)
    return aResult;
}

const char * dbg_out(const SwRewriter & rRewriter)
SW_DLLPUBLIC const char * dbg_out(const SwRewriter & rRewriter)
{
    return dbg_out(lcl_dbg_out(rRewriter));
}
@@ -897,7 +897,7 @@ String lcl_dbg_out(const SwNumRule & rRule)
    return aResult;
}

const char * dbg_out(const SwNumRule & rRule)
SW_DLLPUBLIC const char * dbg_out(const SwNumRule & rRule)
{
    return dbg_out(lcl_dbg_out(rRule));
}
@@ -913,7 +913,7 @@ String lcl_dbg_out(const SwTxtFmtColl & rFmt)
    return aResult;
}

const char * dbg_out(const SwTxtFmtColl & rFmt)
SW_DLLPUBLIC const char * dbg_out(const SwTxtFmtColl & rFmt)
{
    return dbg_out(lcl_dbg_out(rFmt));
}
@@ -923,7 +923,7 @@ String lcl_dbg_out(const SwFrmFmts & rFrmFmts)
    return lcl_dbg_out_SvPtrArr<SwFrmFmts>(rFrmFmts);
}

const char * dbg_out(const SwFrmFmts & rFrmFmts)
SW_DLLPUBLIC const char * dbg_out(const SwFrmFmts & rFrmFmts)
{
    return dbg_out(lcl_dbg_out(rFrmFmts));
}
@@ -949,7 +949,7 @@ String lcl_dbg_out(const SwNumRuleTbl & rTbl)
    return aResult;
}

const char * dbg_out(const SwNumRuleTbl & rTbl)
SW_DLLPUBLIC const char * dbg_out(const SwNumRuleTbl & rTbl)
{
    return dbg_out(lcl_dbg_out(rTbl));
}
@@ -994,7 +994,7 @@ String lcl_dbg_out(const SwFormToken & rToken)
    return rToken.GetString();
}

const char * dbg_out(const SwFormToken & rToken)
SW_DLLPUBLIC const char * dbg_out(const SwFormToken & rToken)
{
    return dbg_out(lcl_dbg_out(rToken));
}
@@ -1020,7 +1020,7 @@ String lcl_dbg_out(const SwFormTokens & rTokens)
    return aStr;
}

const char * dbg_out(const SwFormTokens & rTokens)
SW_DLLPUBLIC const char * dbg_out(const SwFormTokens & rTokens)
{
    return dbg_out(lcl_dbg_out(rTokens));
}
diff --git a/sw/source/core/doc/doc.cxx b/sw/source/core/doc/doc.cxx
index 1bb3204..ae48966 100644
--- a/sw/source/core/doc/doc.cxx
+++ b/sw/source/core/doc/doc.cxx
@@ -81,7 +81,6 @@
#include <ndole.hxx>
#include <ndgrf.hxx>
#include <rolbck.hxx>           // Undo-Attr
#include <bookmrk.hxx>          // fuer die Bookmarks
#include <doctxm.hxx>           // fuer die Verzeichnisse
#include <grfatr.hxx>
#include <poolfmt.hxx>          // PoolVorlagen-Id's
diff --git a/sw/source/core/doc/docbm.cxx b/sw/source/core/doc/docbm.cxx
index fb74d40..f4c3d30 100644
--- a/sw/source/core/doc/docbm.cxx
+++ b/sw/source/core/doc/docbm.cxx
@@ -33,39 +33,756 @@
#include "precompiled_sw.hxx"


#include <tools/pstm.hxx>
#include <svx/linkmgr.hxx>
#include <fmtanchr.hxx>
#include <frmfmt.hxx>
#include <node.hxx>
#include <doc.hxx>
#include <errhdl.hxx>
#include <cntfrm.hxx>
#include <dcontact.hxx>
#include <MarkManager.hxx>
#include <bookmrk.hxx>
// --> OD 2007-10-16 #i81002#
#include <boost/bind.hpp>
#include <cntfrm.hxx>
#include <crossrefbookmark.hxx>
// <--
#include <undobj.hxx>
#include <rolbck.hxx>
#include <pam.hxx>
#include <mvsave.hxx>
#include <swserv.hxx>
#include <redline.hxx>
#include <dcontact.hxx>
#include <doc.hxx>
#include <docary.hxx>
#include <editsh.hxx>
#include <errhdl.hxx>
#include <fmtanchr.hxx>
#include <frmfmt.hxx>
#include <functional>
#include <hintids.hxx>
#include <mvsave.hxx>
#include <ndtxt.hxx>
#include <node.hxx>
#include <pam.hxx>
#include <redline.hxx>
#include <rolbck.hxx>
#include <rtl/ustrbuf.hxx>
#include <rtl/ustring.hxx>
#include <sal/types.h>
#include <sortedobjs.hxx>
#include <svx/linkmgr.hxx>
#include <swserv.hxx>
#include <swundo.hxx>
#include <tools/pstm.hxx>
#include <undobj.hxx>
#include <unocrsr.hxx>
#include <viscrs.hxx>
// OD 2004-05-24 #i28701#
#include <sortedobjs.hxx>
#include "swundo.hxx"
#include "hintids.hxx"
// --> OD 2007-10-23 #i81002#
#include <ndtxt.hxx>
// <--
#include <stdio.h>

SV_IMPL_OP_PTRARR_SORT(SwBookmarks, SwBookmarkPtr)

using namespace ::std;
using namespace ::boost;
using namespace ::sw::mark;

namespace
{
    static bool lcl_GreaterThan( const SwPosition& rPos, const SwNodeIndex& rNdIdx, const SwIndex* pIdx )
    {
        return pIdx ? ( rPos.nNode > rNdIdx || ( rPos.nNode == rNdIdx && rPos.nContent >= pIdx->GetIndex() )) : rPos.nNode >= rNdIdx;
    }

    static bool lcl_Lower( const SwPosition& rPos, const SwNodeIndex& rNdIdx, const SwIndex* pIdx )
    {
        return rPos.nNode < rNdIdx || ( pIdx && rPos.nNode == rNdIdx && rPos.nContent < pIdx->GetIndex() );
    }

    static bool lcl_MarkOrderingByStart(const IDocumentMarkAccess::pMark_t& rpFirst,
        const IDocumentMarkAccess::pMark_t& rpSecond)
    {
        return rpFirst->GetMarkStart() < rpSecond->GetMarkStart();
    }

    static bool lcl_MarkOrderingByEnd(const IDocumentMarkAccess::pMark_t& rpFirst,
        const IDocumentMarkAccess::pMark_t& rpSecond)
    {
        return rpFirst->GetMarkEnd() < rpSecond->GetMarkEnd();
    }

    static void lcl_InsertMarkSorted(IDocumentMarkAccess::container_t& io_vMarks,
        const IDocumentMarkAccess::pMark_t& pMark)
    {
        io_vMarks.insert(
            lower_bound(
                io_vMarks.begin(),
                io_vMarks.end(),
                pMark,
                &lcl_MarkOrderingByStart),
            pMark);
    }

    static inline auto_ptr<SwPosition> lcl_PositionFromCntntNode(SwCntntNode * const pCntntNode, const bool bAtEnd=false)
    {
        auto_ptr<SwPosition> pResult(new SwPosition(*pCntntNode));
        pResult->nContent.Assign(pCntntNode, bAtEnd ? pCntntNode->Len() : 0);
        return pResult;
    }

    // return a position at the begin of rEnd, if it is a CntntNode
    // else set it to the begin of the Node after rEnd, if there is one
    // else set it to the end of the node before rStt
    // else set it to the CntntNode of the Pos outside the Range
    static inline auto_ptr<SwPosition> lcl_FindExpelPosition(const SwNodeIndex& rStt,
        const SwNodeIndex& rEnd,
        const SwPosition& rOtherPosition)
    {
        SwCntntNode * pNode = rEnd.GetNode().GetCntntNode();
        SwNodeIndex aStt = SwNodeIndex(rStt);
        SwNodeIndex aEnd = SwNodeIndex(rEnd);
        bool bAtEnd = false;
        if(!pNode)
            pNode = rEnd.GetNodes().GoNext(&aEnd), bAtEnd = false;
        if(!pNode)
            pNode = rStt.GetNodes().GoPrevious(&aStt), bAtEnd = true;
        if(pNode)
            return lcl_PositionFromCntntNode(pNode, bAtEnd);
        return auto_ptr<SwPosition>(new SwPosition(rOtherPosition));
    };

    static IMark* lcl_getMarkAfter(const IDocumentMarkAccess::container_t& rMarks, const SwPosition& rPos)
    {
        IDocumentMarkAccess::const_iterator_t pMarkAfter = upper_bound(
            rMarks.begin(),
            rMarks.end(),
            rPos,
            bind(&IMark::StartsAfter, _2, _1)); // finds the first that is starting after
        if(pMarkAfter == rMarks.end()) return NULL;
        return pMarkAfter->get();
    };

    static IMark* lcl_getMarkBefore(const IDocumentMarkAccess::container_t& rMarks, const SwPosition& rPos)
    {
        // candidates from which to choose the mark before
        IDocumentMarkAccess::container_t vCandidates;
        // no need to consider marks starting after rPos
        IDocumentMarkAccess::const_iterator_t pCandidatesEnd = upper_bound(
            rMarks.begin(),
            rMarks.end(),
            rPos,
            bind(&IMark::StartsAfter, _2, _1));
        vCandidates.reserve(pCandidatesEnd - rMarks.begin());
        // only marks ending before are candidates
        remove_copy_if(
            rMarks.begin(),
            pCandidatesEnd,
            back_inserter(vCandidates),
            bind(logical_not<bool>(), bind(&IMark::EndsBefore, _1, rPos)));
        // no candidate left => we are in front of the first mark or there are none
        if(!vCandidates.size()) return NULL;
        // return the highest (last) candidate using mark end ordering
        return max_element(vCandidates.begin(), vCandidates.end(), &lcl_MarkOrderingByEnd)->get();
    }

    static bool lcl_FixCorrectedMark(bool bChangedPos, bool bChangedOPos, MarkBase* io_pMark)
    {
        if( (bChangedPos || bChangedOPos) && io_pMark->IsExpanded() &&
            io_pMark->GetOtherMarkPos().nNode.GetNode().FindTableBoxStartNode() !=
            io_pMark->GetMarkPos().nNode.GetNode().FindTableBoxStartNode() )
        {
            if(!bChangedOPos)
                io_pMark->SetMarkPos(io_pMark->GetOtherMarkPos());
            io_pMark->ClearOtherMarkPos();
            DdeBookmark * const pDdeBkmk = dynamic_cast< DdeBookmark*>(io_pMark);
            if(pDdeBkmk && pDdeBkmk->IsServer())
                pDdeBkmk->SetRefObject(NULL);
            return true;
        }
        return false;
    }

    static IDocumentMarkAccess::iterator_t lcl_FindMark(
        IDocumentMarkAccess::container_t& rMarks,
        const IDocumentMarkAccess::pMark_t& rpMarkToFind)
    {
        IDocumentMarkAccess::iterator_t ppCurrentMark = lower_bound(
            rMarks.begin(), rMarks.end(),
            rpMarkToFind, &lcl_MarkOrderingByStart);
        // since there are usually not too many marks on the same start
        // position, we are not doing a bisect search for the upper bound
        // but instead start to iterate from pMarkLow directly
        while(ppCurrentMark != rMarks.end() && **ppCurrentMark == *rpMarkToFind)
        {
            if(ppCurrentMark->get() == rpMarkToFind.get())
            {
                //OSL_TRACE("found mark named '%s'",
                //    ::rtl::OUStringToOString(ppCurrentMark->get()->GetName(), RTL_TEXTENCODING_UTF8).getStr());
                return ppCurrentMark;
            }
            ++ppCurrentMark;
        }
        // reached a mark starting on a later start pos or the end of the
        // vector => not found
        return rMarks.end();
    };

    static IDocumentMarkAccess::iterator_t lcl_FindMarkAtPos(
        IDocumentMarkAccess::container_t& rMarks,
        const SwPosition& rPos,
        const IDocumentMarkAccess::MarkType eType)
    {
        for(IDocumentMarkAccess::iterator_t ppCurrentMark = lower_bound(
                rMarks.begin(), rMarks.end(),
                rPos,
                bind(&IMark::StartsBefore, _1, _2));
            ppCurrentMark != rMarks.end();
            ++ppCurrentMark)
        {
            // Once we reach a mark starting after the target pos
            // we do not need to continue
            if(ppCurrentMark->get()->StartsAfter(rPos))
                break;
            if(IDocumentMarkAccess::GetType(**ppCurrentMark) == eType)
            {
                //OSL_TRACE("found mark named '%s'",
                //    ::rtl::OUStringToOString(ppCurrentMark->get()->GetName(), RTL_TEXTENCODING_UTF8).getStr());
                return ppCurrentMark;
            }
        }
        // reached a mark starting on a later start pos or the end of the
        // vector => not found
        return rMarks.end();
    };

    static IDocumentMarkAccess::const_iterator_t lcl_FindMarkByName(
        const ::rtl::OUString& rName,
        IDocumentMarkAccess::const_iterator_t ppMarksBegin,
        IDocumentMarkAccess::const_iterator_t ppMarksEnd)
    {
        return find_if(
            ppMarksBegin,
            ppMarksEnd,
            bind(&::rtl::OUString::equals, bind(&IMark::GetName, _1), rName));
    }

#if FALSE
    static void lcl_DebugMarks(IDocumentMarkAccess::container_t vMarks)
    {
        OSL_TRACE("%d Marks", vMarks.size());
        for(IDocumentMarkAccess::iterator_t ppMark = vMarks.begin();
            ppMark != vMarks.end();
            ppMark++)
        {
            IMark* pMark = ppMark->get();
            ::rtl::OString sName = ::rtl::OUStringToOString(pMark->GetName(), RTL_TEXTENCODING_UTF8);
            const SwPosition* const pStPos = &pMark->GetMarkStart();
            const SwPosition* const pEndPos = &pMark->GetMarkEnd();
            OSL_TRACE("%s %s %d,%d %d,%d",
                typeid(*pMark).name(),
                sName.getStr(),
                pStPos->nNode.GetIndex(),
                pStPos->nContent.GetIndex(),
                pEndPos->nNode.GetIndex(),
                pEndPos->nContent.GetIndex());
        }
    };
#endif
}

IDocumentMarkAccess::MarkType IDocumentMarkAccess::GetType(const IMark& rBkmk)
{
    const std::type_info* const pMarkTypeInfo = &typeid(rBkmk);
    // not using dynamic_cast<> here for performance
    if(*pMarkTypeInfo == typeid(UnoMark))
        return UNO_BOOKMARK;
    else if(*pMarkTypeInfo == typeid(DdeBookmark))
        return DDE_BOOKMARK;
    else if(*pMarkTypeInfo == typeid(Bookmark))
        return BOOKMARK;
    else if(*pMarkTypeInfo == typeid(CrossRefHeadingBookmark))
        return CROSSREF_HEADING_BOOKMARK;
    else if(*pMarkTypeInfo == typeid(CrossRefNumItemBookmark))
        return CROSSREF_NUMITEM_BOOKMARK;
    else if(*pMarkTypeInfo == typeid(TextFieldmark))
        return TEXT_FIELDMARK;
    else if(*pMarkTypeInfo == typeid(CheckboxFieldmark))
        return CHECKBOX_FIELDMARK;
    else if(*pMarkTypeInfo == typeid(NavigatorReminder))
        return NAVIGATOR_REMINDER;
    else
    {
        OSL_ENSURE(false,
            "IDocumentMarkAccess::GetType(..)"
            " - unknown MarkType. This needs to be fixed!");
        return UNO_BOOKMARK;
    }
}

namespace sw { namespace mark
{
    MarkManager::MarkManager(SwDoc& rDoc)
        : m_pDoc(&rDoc)
    { }

    ::sw::mark::IMark* MarkManager::makeMark(const SwPaM& rPaM,
        const ::rtl::OUString& rName,
        const IDocumentMarkAccess::MarkType eType)
    {
#if FALSE
        {
            ::rtl::OString sName = ::rtl::OUStringToOString(rName, RTL_TEXTENCODING_UTF8);
            const SwPosition* const pPos1 = rPaM.GetPoint();
            const SwPosition* pPos2 = pPos1;
            if(rPaM.HasMark())
                pPos2 = rPaM.GetMark();
            OSL_TRACE("%s %d,%d %d,%d",
                sName.getStr(),
                pPos1->nNode.GetIndex(),
                pPos1->nContent.GetIndex(),
                pPos2->nNode.GetIndex(),
                pPos2->nContent.GetIndex());
        }
#endif
        // see for example _SaveCntntIdx, Shells
        OSL_PRECOND(m_vMarks.size() < USHRT_MAX,
            "MarkManager::makeMark(..)"
            " - more than USHRT_MAX marks are not supported correctly");
        // There should only be one CrossRefBookmark per Textnode per Type
        OSL_PRECOND(
            (eType != CROSSREF_NUMITEM_BOOKMARK && eType != CROSSREF_HEADING_BOOKMARK)
            || (lcl_FindMarkAtPos(m_vBookmarks, *rPaM.GetPoint(), eType) == m_vBookmarks.end()),
            "MarkManager::makeMark(..)"
            " - creating duplicate CrossRefBookmark");

        // create mark
        pMark_t pMark;
        switch(eType)
        {
            case IDocumentMarkAccess::TEXT_FIELDMARK:
                pMark = shared_ptr<IMark>(new TextFieldmark(rPaM));
                break;
            case IDocumentMarkAccess::CHECKBOX_FIELDMARK:
                pMark = shared_ptr<IMark>(new CheckboxFieldmark(rPaM));
                break;
            case IDocumentMarkAccess::NAVIGATOR_REMINDER:
                pMark = shared_ptr<IMark>(new NavigatorReminder(rPaM));
                break;
            case IDocumentMarkAccess::BOOKMARK:
                pMark = shared_ptr<IMark>(new Bookmark(rPaM, KeyCode(), rName, ::rtl::OUString()));
                break;
            case IDocumentMarkAccess::DDE_BOOKMARK:
                pMark = shared_ptr<IMark>(new DdeBookmark(rPaM));
                break;
            case IDocumentMarkAccess::CROSSREF_HEADING_BOOKMARK:
                pMark = shared_ptr<IMark>(new CrossRefHeadingBookmark(rPaM, KeyCode(), rName, ::rtl::OUString()));
                break;
            case IDocumentMarkAccess::CROSSREF_NUMITEM_BOOKMARK:
                pMark = shared_ptr<IMark>(new CrossRefNumItemBookmark(rPaM, KeyCode(), rName, ::rtl::OUString()));
                break;
            case IDocumentMarkAccess::UNO_BOOKMARK:
                pMark = shared_ptr<IMark>(new UnoMark(rPaM));
                break;
        }
        OSL_ENSURE(pMark.get(),
            "MarkManager::makeMark(..)"
            " - Mark was not created.");
        MarkBase* pMarkBase = dynamic_cast<MarkBase*>(pMark.get());

        if(pMark->GetMarkPos() != pMark->GetMarkStart())
            pMarkBase->Swap();

        // for performance reasons, we trust UnoMarks to have a (generated) unique name
        if(eType != IDocumentMarkAccess::UNO_BOOKMARK)
            pMarkBase->SetName(getUniqueMarkName(pMarkBase->GetName()));

        // register mark
        lcl_InsertMarkSorted(m_vMarks, pMark);
        switch(eType)
        {
            case IDocumentMarkAccess::BOOKMARK:
            case IDocumentMarkAccess::CROSSREF_NUMITEM_BOOKMARK:
            case IDocumentMarkAccess::CROSSREF_HEADING_BOOKMARK:
            // if(dynamic_cast<IBookmark*>)
                lcl_InsertMarkSorted(m_vBookmarks, pMark);
                break;
            case IDocumentMarkAccess::TEXT_FIELDMARK:
            case IDocumentMarkAccess::CHECKBOX_FIELDMARK:
            // if(dynamic_cast<IFieldmark*>
                lcl_InsertMarkSorted(m_vFieldmarks, pMark);
                break;
            case IDocumentMarkAccess::NAVIGATOR_REMINDER:
            case IDocumentMarkAccess::DDE_BOOKMARK:
            case IDocumentMarkAccess::UNO_BOOKMARK:
            // no special array for these
                break;
        }
        pMarkBase->InitDoc(m_pDoc);
#if FALSE
        OSL_TRACE("--- makeType ---");
        OSL_TRACE("Marks");
        lcl_DebugMarks(m_vMarks);
        OSL_TRACE("Bookmarks");
        lcl_DebugMarks(m_vBookmarks);
        OSL_TRACE("Fieldmarks");
        lcl_DebugMarks(m_vFieldmarks);
#endif
        return pMark.get();
    }

    ::sw::mark::IMark* MarkManager::getMarkForTxtNode(const SwTxtNode& rTxtNode,
        const IDocumentMarkAccess::MarkType eType)
    {
        SwPosition aPos(rTxtNode);
        aPos.nContent.Assign(&(const_cast<SwTxtNode&>(rTxtNode)), 0);
        const iterator_t ppExistingMark = lcl_FindMarkAtPos(m_vBookmarks, aPos, eType);
        if(ppExistingMark != m_vBookmarks.end())
            return ppExistingMark->get();
        const SwPaM aPaM(aPos);
        return makeMark(aPaM, ::rtl::OUString(), eType);
    }

    void MarkManager::repositionMark( ::sw::mark::IMark* const io_pMark,
        const SwPaM& rPaM)
    {
        OSL_PRECOND(io_pMark->GetMarkPos().GetDoc() == m_pDoc,
            "<MarkManager::repositionMark(..)>"
            " - Mark is not in my doc.");
        MarkBase* const pMarkBase = dynamic_cast< MarkBase* >(io_pMark);
        pMarkBase->SetMarkPos(*(rPaM.GetPoint()));
        if(rPaM.HasMark())
            pMarkBase->SetOtherMarkPos(*(rPaM.GetMark()));
        else
            pMarkBase->ClearOtherMarkPos();

        if(pMarkBase->GetMarkPos() != pMarkBase->GetMarkStart())
            pMarkBase->Swap();

        sortMarks();
    }

    bool MarkManager::renameMark(::sw::mark::IMark* io_pMark, const ::rtl::OUString& rNewName)
    {
        OSL_PRECOND(io_pMark->GetMarkPos().GetDoc() == m_pDoc,
            "<MarkManager::repositionMark(..)>"
            " - Mark is not in my doc.");
        if(io_pMark->GetName() == rNewName)
            return true;
        if(findMark(rNewName) != getMarksEnd())
            return false;
        dynamic_cast< ::sw::mark::MarkBase* >(io_pMark)->SetName(rNewName);
        return true;
    }

    void MarkManager::correctMarksAbsolute(const SwNodeIndex& rOldNode, const SwPosition& rNewPos, const xub_StrLen nOffset)
    {
        const SwNode* const pOldNode = &rOldNode.GetNode();
        SwPosition aNewPos(rNewPos);
        aNewPos.nContent += nOffset;
        bool isSortingNeeded = false;
        for(iterator_t ppMark = m_vMarks.begin();
            ppMark != m_vMarks.end();
            ppMark++)
        {
            // is on position ??
            bool bChangedPos = false, bChangedOPos = false;
            ::sw::mark::MarkBase* pMark = dynamic_cast< ::sw::mark::MarkBase* >(ppMark->get());
            if(&pMark->GetMarkPos().nNode.GetNode() == pOldNode)
            {
                pMark->SetMarkPos(aNewPos);
                bChangedPos = true;
            }
            if (pMark->IsExpanded() &&
                &pMark->GetOtherMarkPos().nNode.GetNode() == pOldNode)
            {
                pMark->SetMarkPos(aNewPos);
                bChangedOPos= true;
            }
            // illegal selection? collapse the mark and restore sorting later
            isSortingNeeded |= lcl_FixCorrectedMark(bChangedPos, bChangedOPos, pMark);
        }
        // restore sorting if needed
        if(isSortingNeeded)
            sortMarks();
#if FALSE
        OSL_TRACE("correctMarksAbsolute");
        lcl_DebugMarks(m_vMarks);
#endif
    }

    void MarkManager::correctMarksRelative(const SwNodeIndex& rOldNode, const SwPosition& rNewPos, const xub_StrLen nOffset)
    {
        const SwNode* const pOldNode = &rOldNode.GetNode();
        SwPosition aNewPos(rNewPos);
        aNewPos.nContent += nOffset;
        bool isSortingNeeded = false;
        for(iterator_t ppMark = m_vMarks.begin();
            ppMark != m_vMarks.end();
            ppMark++)
        {
            // is on position ??
            bool bChangedPos = false, bChangedOPos = false;
            ::sw::mark::MarkBase* const pMark = dynamic_cast< ::sw::mark::MarkBase* >(ppMark->get());
            if(&pMark->GetMarkPos().nNode.GetNode() == pOldNode)
            {
                SwPosition aNewPosRel(aNewPos);
                aNewPosRel.nContent += pMark->GetMarkPos().nContent.GetIndex();
                pMark->SetMarkPos(aNewPosRel);
                bChangedPos = true;
            }
            if(pMark->IsExpanded() &&
                &pMark->GetOtherMarkPos().nNode.GetNode() == pOldNode)
            {
                SwPosition aNewPosRel(aNewPos);
                aNewPosRel.nContent += pMark->GetOtherMarkPos().nContent.GetIndex();
                pMark->SetOtherMarkPos(aNewPosRel);
                bChangedOPos = true;
            }
            // illegal selection? collapse the mark and restore sorting later
            isSortingNeeded |= lcl_FixCorrectedMark(bChangedPos, bChangedOPos, pMark);
        }
        // restore sorting if needed
        if(isSortingNeeded)
            sortMarks();
#if FALSE
        OSL_TRACE("correctMarksRelative");
        lcl_DebugMarks(m_vMarks);
#endif
    }

    void MarkManager::deleteMarks(
        const SwNodeIndex& rStt,
        const SwNodeIndex& rEnd,
        ::std::vector<SaveBookmark>* pSaveBkmk,
        const SwIndex* pSttIdx,
        const SwIndex* pEndIdx)
    {
        vector<const_iterator_t> vMarksToDelete;
        bool isSortingNeeded = false;
        // copy all bookmarks in the move area to a vector storing all position data as offset
        // reassignment is performed after the move
        for(iterator_t ppMark = m_vMarks.begin();
            ppMark != m_vMarks.end();
            ppMark++)
        {
            // navigator marks should not be moved
            // TODO: Check if this might make them invalid
            if(IDocumentMarkAccess::GetType(**ppMark) == NAVIGATOR_REMINDER)
                continue;

            ::sw::mark::MarkBase* pMark = dynamic_cast< ::sw::mark::MarkBase* >(ppMark->get());
            // on position ??
            bool isPosInRange = (lcl_GreaterThan(pMark->GetMarkPos(), rStt, pSttIdx) &&
                lcl_Lower(pMark->GetMarkPos(), rEnd, pEndIdx));
            bool isOtherPosInRange = (pMark->IsExpanded() &&
                lcl_GreaterThan(pMark->GetOtherMarkPos(), rStt, pSttIdx) &&
                lcl_Lower(pMark->GetOtherMarkPos(), rEnd, pEndIdx));
            // special case: completely in range, touching the end?
            if(pEndIdx &&
                    ((isOtherPosInRange
                    && pMark->GetMarkPos().nNode == rEnd
                    && pMark->GetMarkPos().nContent == *pEndIdx)
                || (isPosInRange
                    && pMark->IsExpanded()
                    && pMark->GetOtherMarkPos().nNode == rEnd
                    && pMark->GetOtherMarkPos().nContent == *pEndIdx)))
            {
                isPosInRange = true, isOtherPosInRange = true;
            }

            if(isPosInRange && isOtherPosInRange)
            {
                // completely in range
                if(pSaveBkmk)
                    pSaveBkmk->push_back(SaveBookmark(true, true, *pMark, rStt, pSttIdx));
                vMarksToDelete.push_back(ppMark);
            }
            else if(isPosInRange ^ isOtherPosInRange)
            {
                // the bookmark is partitially in the range
                // move position of that is in the range out of it
                auto_ptr<SwPosition> pNewPos;
                if(pEndIdx)
                    pNewPos = auto_ptr<SwPosition>(new SwPosition(
                        rEnd,
                        *pEndIdx));
                else
                    pNewPos = lcl_FindExpelPosition(
                        rStt,
                        rEnd,
                        isPosInRange ? pMark->GetOtherMarkPos() : pMark->GetMarkPos());

                if(isPosInRange)
                    pMark->SetMarkPos(*pNewPos);
                else
                    pMark->SetOtherMarkPos(*pNewPos);

                // illegal selection? collapse the mark and restore sorting later
                isSortingNeeded |= lcl_FixCorrectedMark(isPosInRange, isOtherPosInRange, pMark);
            }
        }

        // we just remembered the iterators to delete, so we do not need to search
        // for the shared_ptr<> (the entry in m_vMarks) again
        // reverse iteration, since erasing an entry invalidates iterators
        // behind it (the iterators in vMarksToDelete are sorted)
        for(vector<const_iterator_t>::reverse_iterator pppMark = vMarksToDelete.rbegin();
            pppMark != vMarksToDelete.rend();
            pppMark++)
            deleteMark(*pppMark);
        if(isSortingNeeded)
            sortMarks();
#if FALSE
        OSL_TRACE("deleteMarks");
        lcl_DebugMarks(m_vMarks);
#endif
    }

    void MarkManager::deleteMark(const const_iterator_t ppMark)
    {
        if(ppMark == m_vMarks.end()) return;

        switch(IDocumentMarkAccess::GetType(**ppMark))
        {
            case IDocumentMarkAccess::BOOKMARK:
            case IDocumentMarkAccess::CROSSREF_HEADING_BOOKMARK:
            case IDocumentMarkAccess::CROSSREF_NUMITEM_BOOKMARK:
            // if(dynamic_cast<IBookmark*>)
            {
                IDocumentMarkAccess::iterator_t ppBookmark = lcl_FindMark(m_vBookmarks, *ppMark);
                OSL_ENSURE(ppBookmark != m_vBookmarks.end(),
                    "<MarkManager::deleteMark(..)>"
                    " - Bookmark not found.");
                m_vBookmarks.erase(ppBookmark);
                break;
            }
            case IDocumentMarkAccess::TEXT_FIELDMARK:
            case IDocumentMarkAccess::CHECKBOX_FIELDMARK:
            // if(dynamic_cast<IFieldmark*>
            {
                IDocumentMarkAccess::iterator_t ppFieldmark = lcl_FindMark(m_vFieldmarks, *ppMark);
                OSL_ENSURE(ppFieldmark != m_vFieldmarks.end(),
                    "<MarkManager::deleteMark(..)>"
                    " - Bookmark not found.");
                m_vFieldmarks.erase(ppFieldmark);
                break;
            }
            case IDocumentMarkAccess::NAVIGATOR_REMINDER:
            case IDocumentMarkAccess::DDE_BOOKMARK:
            case IDocumentMarkAccess::UNO_BOOKMARK:
            // no special array for these
                break;
        }
        DdeBookmark* const pDdeBookmark = dynamic_cast<DdeBookmark*>(ppMark->get());
        if(pDdeBookmark)
            pDdeBookmark->DeregisterFromDoc(m_pDoc);
        m_vMarks.erase(m_vMarks.begin() + (ppMark - m_vMarks.begin())); // clumsy const-cast
    }

    void MarkManager::deleteMark(const IMark* const pMark)
    {
        OSL_PRECOND(pMark->GetMarkPos().GetDoc() == m_pDoc,
            "<MarkManager::repositionMark(..)>"
            " - Mark is not in my doc.");
        // finds the last Mark that is starting before pMark
        // (pMarkLow < pMark)
        iterator_t pMarkLow = lower_bound(
            m_vMarks.begin(), m_vMarks.end(),
            pMark->GetMarkStart(),
            bind(&IMark::StartsBefore, _1, _2));
        // finds the first Mark that pMark is starting before
        // (pMark < pMarkHigh)
        //iterator_t pMarkHigh = upper_bound(
        //    pMarkLow, m_vMarks.end(),
        //    pMark->GetMarkStart(),
        //    bind(&IMark::StartsBefore, _2, _1));
        // since it should be rare that pMark isnt found at all
        // we skip the bisect search on the upper bound
        iterator_t pMarkHigh = m_vMarks.end();
        iterator_t pMarkFound = find_if(
            pMarkLow, pMarkHigh,
            bind(equal_to<const IMark*>(), bind(&shared_ptr<IMark>::get, _1), pMark));
        if(pMarkFound != pMarkHigh)
            deleteMark(pMarkFound);
    }

    void MarkManager::clearAllMarks()
    {
        m_vFieldmarks.clear();
        m_vBookmarks.clear();
#ifdef DEBUG
        for(iterator_t pBkmk = m_vMarks.begin();
            pBkmk != m_vMarks.end();
            ++pBkmk)
            OSL_ENSURE(pBkmk->unique(),
                "<MarkManager::clearAllMarks(..)>"
                " - a Bookmark is still in use.");
#endif
        m_vMarks.clear();
    }

    IDocumentMarkAccess::const_iterator_t MarkManager::findMark(const ::rtl::OUString& rName) const
    {
        return lcl_FindMarkByName(rName, m_vMarks.begin(), m_vMarks.end());
    }

    IDocumentMarkAccess::const_iterator_t MarkManager::findBookmark(const ::rtl::OUString& rName) const
    {
        return lcl_FindMarkByName(rName, m_vBookmarks.begin(), m_vBookmarks.end());
    }

    IDocumentMarkAccess::const_iterator_t MarkManager::getMarksBegin() const
        { return m_vMarks.begin(); }

    IDocumentMarkAccess::const_iterator_t MarkManager::getMarksEnd() const
        { return m_vMarks.end(); }

    sal_Int32 MarkManager::getMarksCount() const
        { return m_vMarks.size(); }

    IDocumentMarkAccess::const_iterator_t MarkManager::getBookmarksBegin() const
        { return m_vBookmarks.begin(); }

    IDocumentMarkAccess::const_iterator_t MarkManager::getBookmarksEnd() const
        { return m_vBookmarks.end(); }

    sal_Int32 MarkManager::getBookmarksCount() const
        { return m_vBookmarks.size(); }

    IFieldmark* MarkManager::getFieldmarkFor(const SwPosition& rPos) const
    {
        const_iterator_t pFieldmark = find_if(
            m_vFieldmarks.begin(),
            // we do not need to check marks starting behind the positon
            lower_bound(
                m_vFieldmarks.begin(),
                m_vFieldmarks.end(),
                rPos,
                bind(&IMark::StartsAfter, _1, _2)),
            bind(&IMark::IsCoveringPosition, _1, rPos));
        if(pFieldmark == m_vFieldmarks.end()) return NULL;
        return dynamic_cast<IFieldmark*>(pFieldmark->get());
    }

    IFieldmark* MarkManager::getFieldmarkAfter(const SwPosition& rPos) const
        { return dynamic_cast<IFieldmark*>(lcl_getMarkAfter(m_vFieldmarks, rPos)); }

    IFieldmark* MarkManager::getFieldmarkBefore(const SwPosition& rPos) const
        { return dynamic_cast<IFieldmark*>(lcl_getMarkBefore(m_vFieldmarks, rPos)); }

    ::rtl::OUString MarkManager::getUniqueMarkName(const ::rtl::OUString& rName) const
    {
        OSL_ENSURE(rName.getLength(),
            "<MarkManager::getUniqueMarkName(..)>"
            " - a name should be proposed");
        if(findMark(rName) == getMarksEnd()) return rName;
        ::rtl::OUStringBuffer sBuf;
        ::rtl::OUString sTmp;
        for(sal_Int32 nCnt = 1; nCnt < SAL_MAX_INT32; nCnt++)
        {
            sTmp = sBuf.append(rName).append(nCnt).makeStringAndClear();
            if(findMark(sTmp) == getMarksEnd()) break;
        }
        return sTmp;
    }

    void MarkManager::sortMarks()
    {
        sort(m_vMarks.begin(), m_vMarks.end(), &lcl_MarkOrderingByStart);
        sort(m_vBookmarks.begin(), m_vBookmarks.end(), &lcl_MarkOrderingByStart);
        sort(m_vFieldmarks.begin(), m_vFieldmarks.end(), &lcl_MarkOrderingByStart);
    }

}} // namespace ::sw::mark


// old implementation

//SV_IMPL_OP_PTRARR_SORT(SwBookmarks, SwBookmarkPtr)

#define PCURCRSR (_pCurrCrsr)
#define FOREACHPAM_START(pSttCrsr) \
@@ -89,659 +806,269 @@ SV_IMPL_OP_PTRARR_SORT(SwBookmarks, SwBookmarkPtr)
        } while((_pStartShell=(ViewShell*)_pStartShell->GetNext())!= pEShell ); \
    }


/** IDocumentBookmarkAccess ssc
*/
const SwBookmarks& SwDoc::getBookmarks() const
namespace
{
    return *pBookmarkTbl;
}
    // Aufbau vom Array: 2 longs,
    //  1. Long enthaelt Type und Position im DocArray,
    //  2. die ContentPosition
    //
    //  CntntType --
    //          0x8000 = Bookmark Pos1
    //          0x8001 = Bookmark Pos2
    //          0x2000 = Absatzgebundener Rahmen
    //          0x2001 = Auto-Absatzgebundener Rahmen, der umgehaengt werden soll
    //          0x1000 = Redline Mark
    //          0x1001 = Redline Point
    //          0x0800 = Crsr aus der CrsrShell Mark
    //          0x0801 = Crsr aus der CrsrShell Point
    //          0x0400 = UnoCrsr Mark
    //          0x0401 = UnoCrsr Point
    //

SwBookmark* SwDoc::makeBookmark( /*[in]*/const SwPaM& rPaM, /*[in]*/const KeyCode& rCode,
                                 /*[in]*/ const String& rName, /*[in]*/const String& rShortName,
                                 /*[in]*/IDocumentBookmarkAccess::BookmarkType eMark )
{
    SwBookmark *pBM( 0 );
    if (FORM_FIELDMARK_TEXT == eMark || FORM_FIELDMARK_NO_TEXT == eMark /* rName.CompareToAscii(FIELD_BOOKMARK_PREFIX, strlen(FIELD_BOOKMARK_PREFIX))==0 */)
    class _SwSaveTypeCountContent
    {
        pBM = new SwFieldBookmark(*rPaM.GetPoint(), rCode, rName, rShortName, eMark);
        if( rPaM.HasMark() )
            pBM->SetOtherBookmarkPos( rPaM.GetMark() );
        else
            pBM->SetOtherBookmarkPos( &pBM->GetBookmarkPos() );
        union {
            struct { USHORT nType, nCount; } TC;
            ULONG nTypeCount;
            } TYPECOUNT;
        xub_StrLen nContent;

        // TODO: lcl_FixPosition( *pBM->pPos1 );
        // TODO: lcl_FixPosition( *pBM->pPos2 );
        if( *pBM->GetOtherBookmarkPos() < pBM->GetBookmarkPos() )
        {
            SwPosition _pos( pBM->GetBookmarkPos() );
            pBM->SetBookmarkPos( pBM->GetOtherBookmarkPos() );
            pBM->SetOtherBookmarkPos( &_pos );
        }
        //ASSERT(*pBM->pPos1<=*pBM->pPos2, "");
    }
    else if( MARK == eMark )
    {
        pBM = new SwMark( *rPaM.GetPoint(), rCode, rName, rShortName );
    }
//    // --> OD 2007-10-16 #TESTING#
//    else if ( BOOKMARK == eMark )
//    {
//        if ( ( !rPaM.HasMark() &&
//               rPaM.GetPoint()->nNode.GetNode().GetTxtNode() &&
//               rPaM.GetPoint()->nContent.GetIndex() == 0 ) ||
//             ( rPaM.HasMark() &&
//               rPaM.GetMark()->nNode == rPaM.GetPoint()->nNode &&
//               rPaM.GetPoint()->nNode.GetNode().GetTxtNode() &&
//               rPaM.Start()->nContent.GetIndex() == 0 &&
//               rPaM.End()->nContent.GetIndex() ==
//                    rPaM.GetPoint()->nNode.GetNode().GetTxtNode()->Len() ) )
//        {
//            pBM = new SwCrossRefBookmark( *(rPaM.Start()), rCode, rName, rShortName);
//        }
//        else
//        {
//            ASSERT( false,
//                    "<SwDoc::makeBookmark(..)> - creation of cross-reference bookmark with invalid PaM" );
//        }
//    }
//    // <--
    else if( BOOKMARK == eMark || DDE_BOOKMARK == eMark)
    {
        // --> OD 2007-09-26 #i81002#
        pBM = new SwBookmark( rPaM, rCode, rName, rShortName);
        if ( eMark == DDE_BOOKMARK )
        {
            pBM->SetType( eMark );
        }
        // <--
    }
    // --> OD 2007-10-17 #i81002#
    else if ( eMark == CROSSREF_BOOKMARK )
    {
        if ( ( !rPaM.HasMark() &&
               rPaM.GetPoint()->nNode.GetNode().GetTxtNode() &&
               rPaM.GetPoint()->nContent.GetIndex() == 0 ) ||
             ( rPaM.HasMark() &&
               rPaM.GetMark()->nNode == rPaM.GetPoint()->nNode &&
               rPaM.GetPoint()->nNode.GetNode().GetTxtNode() &&
               rPaM.Start()->nContent.GetIndex() == 0 &&
               rPaM.End()->nContent.GetIndex() ==
                rPaM.GetPoint()->nNode.GetNode().GetTxtNode()->Len() ) )
        {
            pBM = new SwCrossRefBookmark( *(rPaM.Start()), rCode, rName, rShortName);
        }
        else
        {
            ASSERT( false,
                    "<SwDoc::makeBookmark(..)> - creation of cross-reference bookmark with invalid PaM" );
        }
    }
    else
    {
        // --> OD 2007-09-26 #i81002#
        pBM = new SwUNOMark( rPaM, rCode, rName, rShortName);
        // <--
    }

    // --> OD 2007-10-18 #i81002#
    if ( pBM )
    {
        if (FORM_FIELDMARK_TEXT == eMark || FORM_FIELDMARK_NO_TEXT == eMark /* pBM->GetName().CompareToAscii(FIELD_BOOKMARK_PREFIX, strlen(FIELD_BOOKMARK_PREFIX))==0 */)
        {
            StartUndo(UNDO_UI_REPLACE, NULL);
            //ASSERT(*PBM->pPos1<=*pBM->pPos2, "Bookmark positions not normalized!!!!");
            const SwTxtNode* pStartTxtNode=this->GetNodes()[pBM->GetBookmarkPos().nNode]->GetTxtNode();
            const SwTxtNode* pEndTxtNode=this->GetNodes()[pBM->GetOtherBookmarkPos()->nNode]->GetTxtNode();
            sal_Unicode ch_start=pStartTxtNode->GetTxt().GetChar(pBM->GetBookmarkPos().nContent.GetIndex());
            sal_Unicode ch_end=pEndTxtNode->GetTxt().GetChar(pBM->GetOtherBookmarkPos()->nContent.GetIndex()-1);
            bool form=(IDocumentBookmarkAccess::FORM_FIELDMARK_NO_TEXT==eMark);  /*(pBM->GetName().CompareToAscii(FIELD_FORM_BOOKMARK_PREFIX, strlen(FIELD_FORM_BOOKMARK_PREFIX))==0);*/
            if (form)
    public:
        _SwSaveTypeCountContent() { TYPECOUNT.nTypeCount = 0; nContent = 0; }
        _SwSaveTypeCountContent( USHORT nType )
            {
                if (ch_start!=CH_TXT_ATR_FORMELEMENT)
                {
                    const SwPaM rRg(pBM->GetBookmarkPos());
                    Insert(rRg, CH_TXT_ATR_FORMELEMENT);
                    SwPosition aTmp( pBM->GetBookmarkPos() );
                    aTmp.nContent--;
                    pBM->SetBookmarkPos( &aTmp );
                }
                SetTypeAndCount( nType, 0 );
                nContent = 0;
            }
        _SwSaveTypeCountContent( const SvULongs& rArr, USHORT& rPos )
            {
                TYPECOUNT.nTypeCount = rArr[ rPos++ ];
                nContent = static_cast<xub_StrLen>(rArr[ rPos++ ]);
            }
        void Add( SvULongs& rArr )
        {
            rArr.Insert( TYPECOUNT.nTypeCount, rArr.Count() );
            rArr.Insert( nContent, rArr.Count() );
        }

        void SetType( USHORT n )        { TYPECOUNT.TC.nType = n; }
        USHORT GetType() const          { return TYPECOUNT.TC.nType; }
        void IncType()                  { ++TYPECOUNT.TC.nType; }
        void DecType()                  { --TYPECOUNT.TC.nType; }

        void SetCount( USHORT n )       { TYPECOUNT.TC.nCount = n; }
        USHORT GetCount() const         { return TYPECOUNT.TC.nCount; }
        USHORT IncCount()               { return ++TYPECOUNT.TC.nCount; }
        USHORT DecCount()               { return --TYPECOUNT.TC.nCount; }

        void SetTypeAndCount( USHORT nT, USHORT nC )
            { TYPECOUNT.TC.nCount = nC; TYPECOUNT.TC.nType = nT; }

        void SetContent( xub_StrLen n )     { nContent = n; }
        xub_StrLen GetContent() const       { return nContent; }
    };

    // #i59534: If a paragraph will be splitted we have to restore some redline positions
    // This help function checks a position compared with a node and an content index

    static const int BEFORE_NODE = 0;          // Position before the given node index
    static const int BEFORE_SAME_NODE = 1;     // Same node index but content index before given content index
    static const int SAME_POSITION = 2;        // Same node index and samecontent index
    static const int BEHIND_SAME_NODE = 3;     // Same node index but content index behind given content index
    static const int BEHIND_NODE = 4;          // Position behind the given node index

    static int lcl_RelativePosition( const SwPosition& rPos, ULONG nNode, xub_StrLen nCntnt )
    {
        ULONG nIndex = rPos.nNode.GetIndex();
        int nReturn = BEFORE_NODE;
        if( nIndex == nNode )
        {
            xub_StrLen nCntIdx = rPos.nContent.GetIndex();
            if( nCntIdx < nCntnt )
                nReturn = BEFORE_SAME_NODE;
            else if( nCntIdx == nCntnt )
                nReturn = SAME_POSITION;
            else
            {
                if (ch_start!=CH_TXT_ATR_FIELDSTART)
                {
                    const SwPaM rRg(pBM->GetBookmarkPos());
                    Insert(rRg, CH_TXT_ATR_FIELDSTART);
                    SwPosition aTmp( pBM->GetBookmarkPos() );
                    aTmp.nContent--;
                    pBM->SetBookmarkPos( &aTmp );
                }
                if (ch_end!=CH_TXT_ATR_FIELDEND)
                {
                    const SwPaM rRg(*pBM->GetOtherBookmarkPos());
                    Insert(rRg, CH_TXT_ATR_FIELDEND);
                }
            }
                nReturn = BEHIND_SAME_NODE;
        }
        if ( !pBookmarkTbl->Insert( pBM ) )
            delete pBM, pBM = 0;
        else
        else if( nIndex > nNode )
            nReturn = BEHIND_NODE;
        return nReturn;
    }


    static inline int lcl_Greater( const SwPosition& rPos, const SwNodeIndex& rNdIdx, const SwIndex* pIdx )
    {
        return rPos.nNode > rNdIdx || ( pIdx && rPos.nNode == rNdIdx && rPos.nContent > pIdx->GetIndex() );
    }

    static void lcl_ChkPaM( SvULongs& rSaveArr, ULONG nNode, xub_StrLen nCntnt,
                    const SwPaM& rPam, _SwSaveTypeCountContent& rSave,
                    BOOL bChkSelDirection )
    {
        // SelektionsRichtung beachten
        bool bBound1IsStart = !bChkSelDirection ? TRUE :
                            ( *rPam.GetPoint() < *rPam.GetMark()
                                ? rPam.GetPoint() == &rPam.GetBound()
                                : rPam.GetMark() == &rPam.GetBound());

        const SwPosition* pPos = &rPam.GetBound( TRUE );
        if( pPos->nNode.GetIndex() == nNode &&
            ( bBound1IsStart ? pPos->nContent.GetIndex() < nCntnt
                                : pPos->nContent.GetIndex() <= nCntnt ))
        {
            if( BOOKMARK == eMark && DoesUndo() )
            {
                ClearRedo();
                AppendUndo( new SwUndoInsBookmark( *pBM ));
            }
            switch( eMark )
            {
                case UNO_BOOKMARK:
                case DDE_BOOKMARK:
                break;
                default:
                    SetModified();
            }
            rSave.SetContent( pPos->nContent.GetIndex() );
            rSave.Add( rSaveArr );
        }
        if (FORM_FIELDMARK_TEXT == eMark || FORM_FIELDMARK_NO_TEXT == eMark /*pBM->GetName().CompareToAscii(FIELD_BOOKMARK_PREFIX, strlen(FIELD_BOOKMARK_PREFIX))==0*/)
            EndUndo(UNDO_UI_REPLACE, NULL);
    }
    return pBM;
}

SwBookmark* SwDoc::getFieldBookmarkFor(const SwPosition &pos) const
{
    //@TODO make impl recursive
    int nCount=pBookmarkTbl->Count();
    while(--nCount>=0)
    {
        SwBookmark *pBM=(*pBookmarkTbl)[static_cast<USHORT>(nCount)];
        if (pBM->GetOtherBookmarkPos()!=NULL
            && FORM_FIELDMARK_TEXT==pBM->GetType() /* pBM->GetName().CompareToAscii(FIELD_BOOKMARK_PREFIX, strlen(FIELD_BOOKMARK_PREFIX))==0 */
            && pBM->GetBookmarkPos()<pos
            && pos < *(pBM->GetOtherBookmarkPos()))
            return pBM;
    }
    return NULL;
}

SwFieldBookmark* SwDoc::getFormFieldBookmarkFor(const SwPosition &pos) const
{
    //@TODO make impl recursive
    int nCount=pBookmarkTbl->Count();
    while(--nCount>=0)
    {
        SwBookmark *pBM=(*pBookmarkTbl)[static_cast<USHORT>(nCount)];
        if (pBM->GetOtherBookmarkPos()!=NULL
            && FORM_FIELDMARK_NO_TEXT==pBM->GetType() /* pBM->GetName().CompareToAscii(FIELD_FORM_BOOKMARK_PREFIX, strlen(FIELD_FORM_BOOKMARK_PREFIX))==0 */
            && pBM->GetBookmarkPos()<=pos
            && pos <= *(pBM->GetOtherBookmarkPos()))
            return (SwFieldBookmark*)pBM;
    }
    return NULL;
}

SwBookmark* SwDoc::getNextFieldBookmarkFor(const SwPosition &pos) const
{
    USHORT i=0;
    USHORT nCount=pBookmarkTbl->Count();
    SwBookmark *pBM=NULL;
    while(i<nCount
        && ((pBM=(*pBookmarkTbl)[i])==NULL
        || !pBM->IsFormFieldMark() /* pBM->GetName().CompareToAscii(FIELD_BOOKMARK_PREFIX, strlen(FIELD_BOOKMARK_PREFIX))!=0 */
        || pos >= pBM->GetBookmarkPos() ))
        i++;

    if (i<nCount)
        return pBM;
    else
    {
        i=0;
        while(i<nCount
            && ((pBM=(*pBookmarkTbl)[i])==NULL || !pBM->IsFormFieldMark() /*pBM->GetName().CompareToAscii(FIELD_BOOKMARK_PREFIX, strlen(FIELD_BOOKMARK_PREFIX))!=0*/ ))
            i++;
        return (i<nCount?pBM:NULL);
    }
}

SwBookmark* SwDoc::getPrevFieldBookmarkFor(const SwPosition &pos) const
{
    int nCount=pBookmarkTbl->Count();
    int i=nCount-1;
    SwBookmark *pBM=NULL;
    while(i>=0
        && ((pBM=(*pBookmarkTbl)[static_cast<USHORT>(i)])==NULL
        || !pBM->IsFormFieldMark() /*pBM->GetName().CompareToAscii(FIELD_BOOKMARK_PREFIX, strlen(FIELD_BOOKMARK_PREFIX))!=0*/
        || pBM->GetOtherBookmarkPos()==NULL
        || pos <= *pBM->GetOtherBookmarkPos()))
        i--;

    if (i>=0)
        return pBM;
    else
    {
        i=nCount-1;
        while(i>=0
            && ((pBM=(*pBookmarkTbl)[static_cast<USHORT>(i)])==NULL ||  !pBM->IsFormFieldMark() /*pBM->GetName().CompareToAscii(FIELD_BOOKMARK_PREFIX, strlen(FIELD_BOOKMARK_PREFIX))!=0*/ ))
            i--;
        return (i>=0?pBM:NULL);
    }
}

/*
bool SwDoc::isValidSelectionWrtFieldBookmarks(const SwPosition &posA, const SwPostion &posB) {
//@TODO optimize this
    SwBookmark *pA=getFieldBookmarkFor(posA);
    SwBookmark *pB=getFieldBookmarkFor(posB);
    return pA==pB;
}
*/

// TODO not finished yet, still neet to add this check
bool _checkFieldBookmarkSanity(const SwDoc *pDoc)
{
    int nCount=pDoc->getBookmarks().Count();
    while(--nCount>=0)
    {
        SwBookmark *pBM=pDoc->getBookmarks()[static_cast<USHORT>(nCount)];
        if (pBM->IsFormFieldMark() /* pBM->GetName().CompareToAscii(FIELD_BOOKMARK_PREFIX, strlen(FIELD_BOOKMARK_PREFIX))==0 */)
        pPos = &rPam.GetBound( FALSE );
        if( pPos->nNode.GetIndex() == nNode &&
            ( (bBound1IsStart && bChkSelDirection)
                        ? pPos->nContent.GetIndex() <= nCntnt
                        : pPos->nContent.GetIndex() < nCntnt ))
        {
            rtl::OUString s(pBM->GetName());
            rtl::OString aOString = ::rtl::OUStringToOString (s, RTL_TEXTENCODING_UTF8);
            const SwTxtNode* pStartTxtNode=pDoc->GetNodes()[pBM->GetBookmarkPos().nNode]->GetTxtNode();
            const SwTxtNode* pEndTxtNode=pDoc->GetNodes()[pBM->GetOtherBookmarkPos()->nNode]->GetTxtNode();
            sal_Unicode ch_start=pStartTxtNode->GetTxt().GetChar(pBM->GetBookmarkPos().nContent.GetIndex());
            sal_Unicode ch_end=pEndTxtNode->GetTxt().GetChar(pBM->GetOtherBookmarkPos()->nContent.GetIndex()-1);
            printf("CHECK(%s %p[%i/'%c'] %p[%i/'%c']);\n", aOString.getStr(), pStartTxtNode, ch_start, ch_start, pEndTxtNode, ch_end, ch_end);
            rSave.SetContent( pPos->nContent.GetIndex() );
            rSave.IncType();
            rSave.Add( rSaveArr );
            rSave.DecType();
        }
    }
    return true;

}

void SwDoc::deleteBookmark( /*[in]*/sal_uInt16 nPos )

// IDocumentMarkAccess for SwDoc

IDocumentMarkAccess* SwDoc::getIDocumentMarkAccess()
    { return static_cast< IDocumentMarkAccess* >(pMarkManager.get()); }

const IDocumentMarkAccess* SwDoc::getIDocumentMarkAccess() const
    { return static_cast< IDocumentMarkAccess* >(pMarkManager.get()); }

// SaveBookmark

SaveBookmark::SaveBookmark(
    bool bSavePos,
    bool bSaveOtherPos,
    const IMark& rBkmk,
    const SwNodeIndex & rMvPos,
    const SwIndex* pIdx)
    : m_aName(rBkmk.GetName())
    , m_aShortName()
    , m_aCode()
    , m_bSavePos(bSavePos)
    , m_bSaveOtherPos(bSaveOtherPos)
    , m_eOrigBkmType(IDocumentMarkAccess::GetType(rBkmk))
{
    SwBookmark *pBM = (*pBookmarkTbl)[nPos];
    if( DoesUndo() && !pBM->IsUNOMark())
    const IBookmark* const pBookmark = dynamic_cast< const IBookmark* >(&rBkmk);
    if(pBookmark)
    {
        ClearRedo();
        AppendUndo( new SwUndoDelBookmark( *pBM ));
        m_aShortName = pBookmark->GetShortName();
        m_aCode = pBookmark->GetKeyCode();
    }
    m_nNode1 = rBkmk.GetMarkPos().nNode.GetIndex();
    m_nCntnt1 = rBkmk.GetMarkPos().nContent.GetIndex();

    if(m_bSavePos)
    {
        m_nNode1 -= rMvPos.GetIndex();
        if(pIdx && !m_nNode1)
            m_nCntnt1 -= pIdx->GetIndex();
    }

    // #108964# UNO bookmark don't contribute to the document state,
    // and hence changing them shouldn't set the document modified
    if( !pBM->IsUNOMark() )
        SetModified();

    pBookmarkTbl->Remove(nPos);

    SwServerObject* pServObj = pBM->GetObject();
    if( pServObj )          // dann aus der Liste entfernen
        GetLinkManager().RemoveServer( pServObj );

    delete pBM;
}

void SwDoc::deleteBookmark( /*[in]*/const String& rName )
{
    USHORT nFnd = findBookmark( rName );
    if( USHRT_MAX != nFnd )
        deleteBookmark( nFnd );
}

// --> OD 2007-10-24 #i81002#
bool SwDoc::isCrossRefBookmarkName( /*[in]*/const String& rName )
{
    return bookmarkfunc::isHeadingCrossRefBookmarkName( rName ) ||
           bookmarkfunc::isNumItemCrossRefBookmarkName( rName );
}
// <--

sal_uInt16 SwDoc::findBookmark( /*[in]*/const String& rName )
{
    ASSERT( rName.Len(), "wo ist der Name?" );
    for( USHORT n = pBookmarkTbl->Count(); n ; )
        if( rName.Equals( (*pBookmarkTbl)[ --n ]->GetName() ) )
            return n;
    return USHRT_MAX;
}

// Zur Vereinfachung gibt es auch den direkten Zugriff
// auf die "echten" Bookmarks

sal_uInt16 SwDoc::getBookmarkCount( /*[in]*/bool bBkmrk) const
{
    USHORT nRet = pBookmarkTbl->Count();
    if(bBkmrk)
    if(rBkmk.IsExpanded())
    {
        for( USHORT i = nRet; i; --i )
        m_nNode2 = rBkmk.GetOtherMarkPos().nNode.GetIndex();
        m_nCntnt2 = rBkmk.GetOtherMarkPos().nContent.GetIndex();

        if(m_bSaveOtherPos)
        {
            if(!(*pBookmarkTbl)[i - 1]->IsBookMark())
                nRet--;
        }
    }
    return nRet;
}


SwBookmark& SwDoc::getBookmark( /*[in]*/sal_uInt16 nPos,  /*[in]*/bool bBkmrk)
{
    if( bBkmrk )
    {
        USHORT i = 0;
        do {
            if(!(*pBookmarkTbl)[i]->IsBookMark())
                nPos++;

            i++;
        }
        while( i < nPos || !(*pBookmarkTbl)[nPos]->IsBookMark() );
    }
    return *(*pBookmarkTbl)[nPos];
}

void SwDoc::makeUniqueBookmarkName( String& rNm )
{
    ASSERT( rNm.Len(), "es sollte ein Name vorgegeben werden!" );

    // wir erzeugen uns eine temp. Bookmark
    String sTmp;
    USHORT nCnt = 0, n;
    USHORT nBookCnt = pBookmarkTbl->Count();
    do {
        sTmp = rNm;
        // #i35726# try without number extension first
        if(nCnt)
            sTmp += String::CreateFromInt32( nCnt );
        nCnt++;
        for( n = 0; n < nBookCnt; ++n )
            if( (*pBookmarkTbl)[ n ]->GetName().Equals( sTmp ))
                break;
    } while( n < nBookCnt );

    // --> OD 2007-10-24 #i81002#
    // a cross-reference bookmark name still have to be a cross-reference
    // bookmark name after renaming due to duplicate names and vice versa.
    // Thus, consider this, when changing the renaming algorithm
    ASSERT( isCrossRefBookmarkName( rNm ) == isCrossRefBookmarkName( sTmp ),
            "<SwDoc::makeUniqueBookmarkName(..)> - change of the bookmark name causes change of bookmark name type" );
    // <--

    rNm = sTmp;
}

// --> OD 2007-11-16 #i83479#
String SwDoc::getCrossRefBookmarkName(
                /*[in]*/const SwTxtNode& rTxtNode,
                /*[in]*/const CrossReferenceBookmarkSubType nCrossRefType ) const
{
    for( USHORT n = pBookmarkTbl->Count(); n ; )
    {
        const SwCrossRefBookmark* pCrossRefBkmk(
                    dynamic_cast<SwCrossRefBookmark*>((*pBookmarkTbl)[ --n ]) );
        if ( pCrossRefBkmk &&
             pCrossRefBkmk->GetBookmarkPos().nNode.GetNode().GetTxtNode() ==
                &rTxtNode &&
             pCrossRefBkmk->GetSubType() == nCrossRefType )
        {
            return pCrossRefBkmk->GetName();
        }
    }

    return String();
}

String SwDoc::makeCrossRefBookmark(
                    /*[in]*/const SwTxtNode& rTxtNode,
                    /*[in]*/const CrossReferenceBookmarkSubType nCrossRefType )
{
    SwPosition aPos( rTxtNode );
    aPos.nContent.Assign( &(const_cast<SwTxtNode&>(rTxtNode)), 0 );
    SwPaM aPaM( aPos );
    KeyCode rKeyCodeDummy;
    String sBkmkName( bookmarkfunc::generateNewCrossRefBookmarkName( nCrossRefType ) );
    makeUniqueBookmarkName( sBkmkName );
    SwBookmark* pCrossRefBk =
            makeBookmark( aPaM, rKeyCodeDummy, sBkmkName, sBkmkName, CROSSREF_BOOKMARK );
    if ( pCrossRefBk )
    {
        return pCrossRefBk->GetName();
    }
    else
    {
        return String();
    }
}

/*  */

SaveBookmark::SaveBookmark( int eType, const SwBookmark& rBkmk,
                            const SwNodeIndex & rMvPos,
                            const SwIndex* pIdx )
    : aName( rBkmk.GetName() ),
      aShortName( rBkmk.GetShortName() ),
      aCode( rBkmk.GetKeyCode() ),
      eBkmkType( (SaveBookmarkType)eType ),
      eOrigBkmType(rBkmk.GetType())
{
    nNode1 = rBkmk.GetBookmarkPos().nNode.GetIndex();
    nCntnt1 = rBkmk.GetBookmarkPos().nContent.GetIndex();

    if( nsSaveBookmarkType::BKMK_POS & eBkmkType )
    {
        nNode1 -= rMvPos.GetIndex();
        if( pIdx && !nNode1 )
            nCntnt1 = nCntnt1 - pIdx->GetIndex();
    }

    if( rBkmk.GetOtherBookmarkPos() )
    {
        nNode2 = rBkmk.GetOtherBookmarkPos()->nNode.GetIndex();
        nCntnt2 = rBkmk.GetOtherBookmarkPos()->nContent.GetIndex();

        if( nsSaveBookmarkType::BKMK_POS_OTHER & eBkmkType )
        {
            nNode2 -= rMvPos.GetIndex();
            if( pIdx && !nNode2 )
                nCntnt2 = nCntnt2 - pIdx->GetIndex();
            m_nNode2 -= rMvPos.GetIndex();
            if(pIdx && !m_nNode2)
                m_nCntnt2 -= pIdx->GetIndex();
        }
    }
    else
        nNode2 = ULONG_MAX, nCntnt2 = STRING_NOTFOUND;
        m_nNode2 = ULONG_MAX, m_nCntnt2 = STRING_NOTFOUND;
}

void SaveBookmark::SetInDoc( SwDoc* pDoc, const SwNodeIndex& rNewPos,
                            const SwIndex* pIdx )
void SaveBookmark::SetInDoc(
    SwDoc* pDoc,
    const SwNodeIndex& rNewPos,
    const SwIndex* pIdx)
{
    SwPaM aPam( rNewPos.GetNode() );
    if( pIdx )
    SwPaM aPam(rNewPos.GetNode());
    if(pIdx)
        aPam.GetPoint()->nContent = *pIdx;

    if( ULONG_MAX != nNode2 )
    if(ULONG_MAX != m_nNode2)
    {
        aPam.SetMark();

        if( nsSaveBookmarkType::BKMK_POS_OTHER & eBkmkType )
        if(m_bSaveOtherPos)
        {
            aPam.GetMark()->nNode += nNode2;
            if( pIdx && !nNode2 )
                aPam.GetMark()->nContent += nCntnt2;
            aPam.GetMark()->nNode += m_nNode2;
            if(pIdx && !m_nNode2)
                aPam.GetMark()->nContent += m_nCntnt2;
            else
                aPam.GetMark()->nContent.Assign( aPam.GetCntntNode( FALSE ),
                                                        nCntnt2 );
                aPam.GetMark()->nContent.Assign(aPam.GetCntntNode(FALSE), m_nCntnt2);
        }
        else
        {
            aPam.GetMark()->nNode = nNode2;
            aPam.GetMark()->nContent.Assign( aPam.GetCntntNode( FALSE ),
                                                    nCntnt2 );
            aPam.GetMark()->nNode = m_nNode2;
            aPam.GetMark()->nContent.Assign(aPam.GetCntntNode(FALSE), m_nCntnt2);
        }
    }

    if( nsSaveBookmarkType::BKMK_POS & eBkmkType )
    if(m_bSavePos)
    {
        aPam.GetPoint()->nNode += nNode1;
        aPam.GetPoint()->nNode += m_nNode1;

        if( pIdx && !nNode1 )
            aPam.GetPoint()->nContent += nCntnt1;
        if(pIdx && !m_nNode1)
            aPam.GetPoint()->nContent += m_nCntnt1;
        else
            aPam.GetPoint()->nContent.Assign( aPam.GetCntntNode(), nCntnt1 );
            aPam.GetPoint()->nContent.Assign(aPam.GetCntntNode(), m_nCntnt1);
    }
    else
    {
        aPam.GetPoint()->nNode = nNode1;
        aPam.GetPoint()->nContent.Assign( aPam.GetCntntNode(), nCntnt1 );
        aPam.GetPoint()->nNode = m_nNode1;
        aPam.GetPoint()->nContent.Assign(aPam.GetCntntNode(), m_nCntnt1);
    }

    if( !aPam.HasMark() ||
        CheckNodesRange( aPam.GetPoint()->nNode, aPam.GetMark()->nNode, TRUE ))
        pDoc->makeBookmark( aPam, aCode, aName, aShortName, eOrigBkmType );
}


inline int GreaterThan( const SwPosition& rPos, const SwNodeIndex& rNdIdx,
                        const SwIndex* pIdx )
{
    return pIdx ? ( rPos.nNode > rNdIdx || ( rPos.nNode == rNdIdx &&
                                        rPos.nContent >= pIdx->GetIndex() ))
                : rPos.nNode >= rNdIdx;
}
inline int Lower( const SwPosition& rPos, const SwNodeIndex& rNdIdx,
                        const SwIndex* pIdx )
{
    return rPos.nNode < rNdIdx || ( pIdx && rPos.nNode == rNdIdx &&
                                        rPos.nContent < pIdx->GetIndex() );
}
inline int Greater( const SwPosition& rPos, const SwNodeIndex& rNdIdx,
                        const SwIndex* pIdx )
{
    return rPos.nNode > rNdIdx || ( pIdx && rPos.nNode == rNdIdx &&
                                        rPos.nContent > pIdx->GetIndex() );
}

void _DelBookmarks( const SwNodeIndex& rStt, const SwNodeIndex& rEnd,
                    SaveBookmarks* pSaveBkmk,
                    const SwIndex* pSttIdx, const SwIndex* pEndIdx )
{
    // kein gueltiger Bereich ??
    if( rStt.GetIndex() > rEnd.GetIndex() || ( rStt == rEnd &&
        (!pSttIdx || pSttIdx->GetIndex() >= pEndIdx->GetIndex())) )
        return;

    // kopiere alle Bookmarks, die im Move Bereich stehen in ein
    // Array, das alle Angaben auf die Position als Offset speichert.
    // Die neue Zuordung erfolgt nach dem Moven.
    SwDoc* pDoc = rStt.GetNode().GetDoc();
    const SwBookmarks& rBkmks = pDoc->getBookmarks();
    USHORT nCnt;

    for( nCnt = 0; nCnt < rBkmks.Count(); ++nCnt )
    if(!aPam.HasMark()
        || CheckNodesRange(aPam.GetPoint()->nNode, aPam.GetMark()->nNode, TRUE))
    {
        // liegt auf der Position ??
        int eType = nsSaveBookmarkType::BKMK_POS_NONE;
        SwBookmark* pBkmk = rBkmks[ nCnt ];
        //simple marks should not be moved
        if(pBkmk->IsMark())
            continue;
        if( GreaterThan( pBkmk->GetBookmarkPos(), rStt, pSttIdx ) &&
            Lower( pBkmk->GetBookmarkPos(), rEnd, pEndIdx ))
            eType = nsSaveBookmarkType::BKMK_POS;
        if( pBkmk->GetOtherBookmarkPos() &&
            GreaterThan( *pBkmk->GetOtherBookmarkPos(), rStt, pSttIdx ) &&
            Lower( *pBkmk->GetOtherBookmarkPos(), rEnd, pEndIdx ))
            eType |= nsSaveBookmarkType::BKMK_POS_OTHER;

        if( nsSaveBookmarkType::BKMK_POS_NONE == eType )        // auf zum naechsten
            continue;

        if( pSaveBkmk )
        ::sw::mark::IBookmark* const pBookmark = dynamic_cast< ::sw::mark::IBookmark* >(pDoc->getIDocumentMarkAccess()->makeMark(aPam, m_aName, m_eOrigBkmType));
        if(pBookmark)
        {
                // Besonderheit: komplett eingeschlossen? dann mitnehmen
            if( pEndIdx && (nsSaveBookmarkType::BKMK_POS_OTHER | nsSaveBookmarkType::BKMK_POS) != eType &&
                ( ( nsSaveBookmarkType::BKMK_POS_OTHER & eType &&
                    pBkmk->GetBookmarkPos().nNode == rEnd &&
                    pBkmk->GetBookmarkPos().nContent == *pEndIdx ) ||
                ( nsSaveBookmarkType::BKMK_POS & eType && pBkmk->GetOtherBookmarkPos() &&
                    pBkmk->GetOtherBookmarkPos()->nNode == rEnd &&
                    pBkmk->GetOtherBookmarkPos()->nContent == *pEndIdx ) ) )
                    eType = nsSaveBookmarkType::BKMK_POS_OTHER | nsSaveBookmarkType::BKMK_POS;

            SaveBookmark * pSBkmk = new SaveBookmark( eType, *pBkmk, rStt, pSttIdx );
            pSaveBkmk->C40_INSERT( SaveBookmark, pSBkmk, pSaveBkmk->Count() );
            pDoc->deleteBookmark( nCnt-- );
        }
        else if( (nsSaveBookmarkType::BKMK_POS_OTHER | nsSaveBookmarkType::BKMK_POS ) == eType ||
                ( nsSaveBookmarkType::BKMK_POS == eType && !pBkmk->GetOtherBookmarkPos() ) )
            pDoc->deleteBookmark( nCnt-- );
        else
        {
            // --> OD 2007-10-17 #i81002# - refactoring:
            // no direct manipulation of <SwBookmark> member.
//            SwPosition* pPos = (SwPosition*)(nsSaveBookmarkType::BKMK_POS & eType
//                               ? &pBkmk->GetBookmarkPos()
//                               : pBkmk->GetOtherBookmarkPos());
            SwPosition aNewPos( nsSaveBookmarkType::BKMK_POS & eType
                                ? pBkmk->GetBookmarkPos()
                                : *pBkmk->GetOtherBookmarkPos() );
            aNewPos.nNode = rEnd;
            if( pEndIdx )
                aNewPos.nContent = *pEndIdx;
            else
            {
                SwCntntNode* pCNd = aNewPos.nNode.GetNode().GetCntntNode();
                BOOL bStt = TRUE;
                if( !pCNd && 0 == ( pCNd = pDoc->GetNodes().GoNext( &(aNewPos.nNode) )) )
                {
                    bStt = FALSE;
                    aNewPos.nNode = rStt;
                    if( 0 == ( pCNd = pDoc->GetNodes().GoPrevious( &(aNewPos.nNode) )) )
                    {
                        aNewPos.nNode = nsSaveBookmarkType::BKMK_POS == eType
                                        ? pBkmk->GetOtherBookmarkPos()->nNode
                                        : pBkmk->GetBookmarkPos().nNode;
                        pCNd = aNewPos.nNode.GetNode().GetCntntNode();
                    }
                }
                xub_StrLen nTmp = bStt ? 0 : pCNd->Len();
                aNewPos.nContent.Assign( pCNd, nTmp );
            }
            if ( nsSaveBookmarkType::BKMK_POS & eType )
            {
                pBkmk->SetBookmarkPos( &aNewPos );
            }
            else
            {
                pBkmk->SetOtherBookmarkPos( &aNewPos );
            }

            // keine ungueltigen Selektionen zulassen!
            if( pBkmk->GetOtherBookmarkPos() &&
                pBkmk->GetOtherBookmarkPos()->nNode.GetNode().FindTableBoxStartNode() !=
                pBkmk->GetBookmarkPos().nNode.GetNode().FindTableBoxStartNode() )
            {
//                SwPaM aPam( pPos == pBkmk->GetOtherBookmarkPos()
//                            ? pBkmk->GetBookmarkPos()
//                            : *pBkmk->GetOtherBookmarkPos()  );
                const SwPaM aPam( nsSaveBookmarkType::BKMK_POS & eType
                                  ? *pBkmk->GetOtherBookmarkPos()
                                  : pBkmk->GetBookmarkPos() );
                const String sNm( pBkmk->GetName() );
                const String sShortNm( pBkmk->GetShortName() );
                const KeyCode aKCode( pBkmk->GetKeyCode() );
                const IDocumentBookmarkAccess::BookmarkType eBkmkType( pBkmk->GetType() );

                bool bMake = !pBkmk->IsUNOMark();
                pDoc->deleteBookmark( nCnt-- );
                if( bMake )
                    pDoc->makeBookmark( aPam, aKCode, sNm, sShortNm, eBkmkType );
            }
            // <--
            pBookmark->SetKeyCode(m_aCode);
            pBookmark->SetShortName(m_aShortName);
        }
    }
}

// _DelBookmarks, _{Save,Restore}CntntIdx

void _DelBookmarks(
    const SwNodeIndex& rStt,
    const SwNodeIndex& rEnd,
    ::std::vector<SaveBookmark> * pSaveBkmk,
    const SwIndex* pSttIdx,
    const SwIndex* pEndIdx)
{
    // illegal range ??
    if(rStt.GetIndex() > rEnd.GetIndex()
        || (rStt == rEnd && (!pSttIdx || pSttIdx->GetIndex() >= pEndIdx->GetIndex())))
        return;
    SwDoc* const pDoc = rStt.GetNode().GetDoc();

    pDoc->getIDocumentMarkAccess()->deleteMarks(rStt, rEnd, pSaveBkmk, pSttIdx, pEndIdx);

    // kopiere alle Redlines, die im Move Bereich stehen in ein
    // Array, das alle Angaben auf die Position als Offset speichert.
    // Die neue Zuordung erfolgt nach dem Moven.
    SwRedlineTbl& rTbl = (SwRedlineTbl&)pDoc->GetRedlineTbl();
    for( nCnt = 0; nCnt < rTbl.Count(); ++nCnt )
    for(USHORT nCnt = 0; nCnt < rTbl.Count(); ++nCnt )
    {
        // liegt auf der Position ??
        SwRedline* pRedl = rTbl[ nCnt ];
@@ -753,7 +1080,7 @@ void _DelBookmarks( const SwNodeIndex& rStt, const SwNodeIndex& rEnd,
            SwPosition *pTmp = pRStt; pRStt = pREnd, pREnd = pTmp;
        }

        if( Greater( *pRStt, rStt, pSttIdx ) && Lower( *pRStt, rEnd, pEndIdx ))
        if( lcl_Greater( *pRStt, rStt, pSttIdx ) && lcl_Lower( *pRStt, rEnd, pEndIdx ))
        {
            pRStt->nNode = rEnd;
            if( pEndIdx )
@@ -776,7 +1103,7 @@ void _DelBookmarks( const SwNodeIndex& rStt, const SwNodeIndex& rEnd,
                pRStt->nContent.Assign( pCNd, nTmp );
            }
        }
        if( Greater( *pREnd, rStt, pSttIdx ) && Lower( *pREnd, rEnd, pEndIdx ))
        if( lcl_Greater( *pREnd, rStt, pSttIdx ) && lcl_Lower( *pREnd, rEnd, pEndIdx ))
        {
            pREnd->nNode = rStt;
            if( pSttIdx )
@@ -802,172 +1129,50 @@ void _DelBookmarks( const SwNodeIndex& rStt, const SwNodeIndex& rEnd,
    }
}




/*  */


// Aufbau vom Array: 2 longs,
//  1. Long enthaelt Type und Position im DocArray,
//  2. die ContentPosition
//
//  CntntType --
//          0x8000 = Bookmark Pos1
//          0x8001 = Bookmark Pos2
//          0x2000 = Absatzgebundener Rahmen
//          0x2001 = Auto-Absatzgebundener Rahmen, der umgehaengt werden soll
//          0x1000 = Redline Mark
//          0x1001 = Redline Point
//          0x0800 = Crsr aus der CrsrShell Mark
//          0x0801 = Crsr aus der CrsrShell Point
//          0x0400 = UnoCrsr Mark
//          0x0401 = UnoCrsr Point
//

class _SwSaveTypeCountContent
{
    union {
        struct { USHORT nType, nCount; } TC;
        ULONG nTypeCount;
        } TYPECOUNT;
    xub_StrLen nContent;

public:
    _SwSaveTypeCountContent() { TYPECOUNT.nTypeCount = 0; nContent = 0; }
    _SwSaveTypeCountContent( USHORT nType )
        {
            SetTypeAndCount( nType, 0 );
            nContent = 0;
        }
    _SwSaveTypeCountContent( const SvULongs& rArr, USHORT& rPos )
        {
            TYPECOUNT.nTypeCount = rArr[ rPos++ ];
            nContent = static_cast<xub_StrLen>(rArr[ rPos++ ]);
        }
    void Add( SvULongs& rArr )
    {
        rArr.Insert( TYPECOUNT.nTypeCount, rArr.Count() );
        rArr.Insert( nContent, rArr.Count() );
    }

    void SetType( USHORT n )        { TYPECOUNT.TC.nType = n; }
    USHORT GetType() const          { return TYPECOUNT.TC.nType; }
    void IncType()                  { ++TYPECOUNT.TC.nType; }
    void DecType()                  { --TYPECOUNT.TC.nType; }

    void SetCount( USHORT n )       { TYPECOUNT.TC.nCount = n; }
    USHORT GetCount() const         { return TYPECOUNT.TC.nCount; }
    USHORT IncCount()               { return ++TYPECOUNT.TC.nCount; }
    USHORT DecCount()               { return --TYPECOUNT.TC.nCount; }

    void SetTypeAndCount( USHORT nT, USHORT nC )
        { TYPECOUNT.TC.nCount = nC; TYPECOUNT.TC.nType = nT; }

    void SetContent( xub_StrLen n )     { nContent = n; }
    xub_StrLen GetContent() const       { return nContent; }
};


void _ChkPaM( SvULongs& rSaveArr, ULONG nNode, xub_StrLen nCntnt,
                const SwPaM& rPam, _SwSaveTypeCountContent& rSave,
                BOOL bChkSelDirection )
{
    // SelektionsRichtung beachten
    bool bBound1IsStart = !bChkSelDirection ? TRUE :
                        ( *rPam.GetPoint() < *rPam.GetMark()
                            ? rPam.GetPoint() == &rPam.GetBound()
                            : rPam.GetMark() == &rPam.GetBound());

    const SwPosition* pPos = &rPam.GetBound( TRUE );
    if( pPos->nNode.GetIndex() == nNode &&
        ( bBound1IsStart ? pPos->nContent.GetIndex() < nCntnt
                            : pPos->nContent.GetIndex() <= nCntnt ))
    {
        rSave.SetContent( pPos->nContent.GetIndex() );
        rSave.Add( rSaveArr );
    }

    pPos = &rPam.GetBound( FALSE );
    if( pPos->nNode.GetIndex() == nNode &&
        ( (bBound1IsStart && bChkSelDirection)
                    ? pPos->nContent.GetIndex() <= nCntnt
                    : pPos->nContent.GetIndex() < nCntnt ))
    {
        rSave.SetContent( pPos->nContent.GetIndex() );
        rSave.IncType();
        rSave.Add( rSaveArr );
        rSave.DecType();
    }
}

// #i59534: If a paragraph will be splitted we have to restore some redline positions
// This help function checks a position compared with a node and an content index

const int BEFORE_NODE = 0;          // Position before the given node index
const int BEFORE_SAME_NODE = 1;     // Same node index but content index before given content index
const int SAME_POSITION = 2;        // Same node index and samecontent index
const int BEHIND_SAME_NODE = 3;     // Same node index but content index behind given content index
const int BEHIND_NODE = 4;          // Position behind the given node index

int lcl_RelativePosition( const SwPosition& rPos, ULONG nNode, xub_StrLen nCntnt )
{
    ULONG nIndex = rPos.nNode.GetIndex();
    int nReturn = BEFORE_NODE;
    if( nIndex == nNode )
    {
        xub_StrLen nCntIdx = rPos.nContent.GetIndex();
        if( nCntIdx < nCntnt )
            nReturn = BEFORE_SAME_NODE;
        else if( nCntIdx == nCntnt )
            nReturn = SAME_POSITION;
        else
            nReturn = BEHIND_SAME_NODE;
    }
    else if( nIndex > nNode )
        nReturn = BEHIND_NODE;
    return nReturn;
}

void _SaveCntntIdx( SwDoc* pDoc, ULONG nNode, xub_StrLen nCntnt,
                    SvULongs& rSaveArr, BYTE nSaveFly )
void _SaveCntntIdx(SwDoc* pDoc,
    ULONG nNode,
    xub_StrLen nCntnt,
    SvULongs& rSaveArr,
    BYTE nSaveFly)
{
    // 1. Bookmarks
    _SwSaveTypeCountContent aSave;
    aSave.SetTypeAndCount( 0x8000, 0 );

    const SwBookmarks& rBkmks = pDoc->getBookmarks();
    for( ; aSave.GetCount() < rBkmks.Count(); aSave.IncCount() )
    IDocumentMarkAccess* const pMarkAccess = pDoc->getIDocumentMarkAccess();
    const sal_Int32 nBkmks = pMarkAccess->getMarksCount();
    for(; aSave.GetCount() < nBkmks; aSave.IncCount())
    {
        bool bEqual = false;
        bool bLower = false;
        const SwBookmark* pBkmk = rBkmks[ aSave.GetCount() ];
        if( pBkmk->GetBookmarkPos().nNode.GetIndex() == nNode &&
            pBkmk->GetBookmarkPos().nContent.GetIndex() <= nCntnt )
        const ::sw::mark::IMark* pBkmk = (pMarkAccess->getMarksBegin() + aSave.GetCount())->get();
        if(pBkmk->GetMarkPos().nNode.GetIndex() == nNode
            && pBkmk->GetMarkPos().nContent.GetIndex() <= nCntnt)
        {
            if( pBkmk->GetBookmarkPos().nContent.GetIndex() < nCntnt )
            if(pBkmk->GetMarkPos().nContent.GetIndex() < nCntnt)
            {
                bLower = true; // a hint for the other position...
                aSave.SetContent( pBkmk->GetBookmarkPos().nContent.GetIndex() );
                aSave.Add( rSaveArr );
                aSave.SetContent(pBkmk->GetMarkPos().nContent.GetIndex());
                aSave.Add(rSaveArr);
            }
            else // if a bookmark position is equal nCntnt, the other position
                bEqual = true; // has to decide if it is added to the array
        }

        if( pBkmk->GetOtherBookmarkPos() && pBkmk->GetOtherBookmarkPos()->nNode.GetIndex() ==
            nNode && pBkmk->GetOtherBookmarkPos()->nContent.GetIndex() <= nCntnt )
        if(pBkmk->IsExpanded()
            && pBkmk->GetOtherMarkPos().nNode.GetIndex() == nNode
            && pBkmk->GetOtherMarkPos().nContent.GetIndex() <= nCntnt)
        {
            if( bLower || pBkmk->GetOtherBookmarkPos()->nContent.GetIndex() < nCntnt )
            if(bLower || pBkmk->GetOtherMarkPos().nContent.GetIndex() < nCntnt)
            {
                if( bEqual )
                if(bEqual)
                { // the other position is before, the (main) position is equal
                    aSave.SetContent( pBkmk->GetBookmarkPos().nContent.GetIndex() );
                    aSave.Add( rSaveArr );
                    aSave.SetContent(pBkmk->GetMarkPos().nContent.GetIndex());
                    aSave.Add(rSaveArr);
                }
                aSave.SetContent( pBkmk->GetOtherBookmarkPos()->nContent.GetIndex() );
                aSave.SetContent(pBkmk->GetOtherMarkPos().nContent.GetIndex());
                aSave.IncType();
                aSave.Add( rSaveArr );
                aSave.Add(rSaveArr);
                aSave.DecType();
            }
        }
@@ -1031,7 +1236,7 @@ void _SaveCntntIdx( SwDoc* pDoc, ULONG nNode, xub_StrLen nCntnt,
                            aSave.SetType( 0x2000 );
                            aSave.SetContent( pAPos->nContent.GetIndex() );

                            ASSERT( nNode == pAPos->nNode.GetIndex(),
                            OSL_ENSURE( nNode == pAPos->nNode.GetIndex(),
                                    "_SaveCntntIdx: Wrong Node-Index" );
                            if( FLY_AUTO_CNTNT == rAnchor.GetAnchorId() )
                            {
@@ -1045,10 +1250,10 @@ void _SaveCntntIdx( SwDoc* pDoc, ULONG nNode, xub_StrLen nCntnt,
                            }
                            aSave.SetCount( pDoc->GetSpzFrmFmts()->Count() );
                            while( aSave.GetCount() &&
                                   &rFmt != (*pDoc->GetSpzFrmFmts())[
                                                aSave.DecCount() ] )
                                    &rFmt != (*pDoc->GetSpzFrmFmts())[
                                    aSave.DecCount() ] )
                                ; // nothing
                            ASSERT( &rFmt == (*pDoc->GetSpzFrmFmts())[
                            OSL_ENSURE( &rFmt == (*pDoc->GetSpzFrmFmts())[
                                                    aSave.GetCount() ],
                                    "_SaveCntntIdx: Lost FrameFormat" );
                            aSave.Add( rSaveArr );
@@ -1101,14 +1306,14 @@ void _SaveCntntIdx( SwDoc* pDoc, ULONG nNode, xub_StrLen nCntnt,
                SwPaM *_pStkCrsr = PCURSH->GetStkCrsr();
                if( _pStkCrsr )
                do {
                    ::_ChkPaM( rSaveArr, nNode, nCntnt, *_pStkCrsr,
                    lcl_ChkPaM( rSaveArr, nNode, nCntnt, *_pStkCrsr,
                                aSave, FALSE );
                    aSave.IncCount();
                } while ( (_pStkCrsr != 0 ) &&
                    ((_pStkCrsr=(SwPaM *)_pStkCrsr->GetNext()) != PCURSH->GetStkCrsr()) );

                FOREACHPAM_START( PCURSH->_GetCrsr() )
                    ::_ChkPaM( rSaveArr, nNode, nCntnt, *PCURCRSR,
                    lcl_ChkPaM( rSaveArr, nNode, nCntnt, *PCURCRSR,
                                aSave, FALSE );
                    aSave.IncCount();
                FOREACHPAM_END()
@@ -1123,7 +1328,7 @@ void _SaveCntntIdx( SwDoc* pDoc, ULONG nNode, xub_StrLen nCntnt,
        for( USHORT n = 0; n < rTbl.Count(); ++n )
        {
            FOREACHPAM_START( rTbl[ n ] )
                ::_ChkPaM( rSaveArr, nNode, nCntnt, *PCURCRSR, aSave, FALSE );
                lcl_ChkPaM( rSaveArr, nNode, nCntnt, *PCURCRSR, aSave, FALSE );
                aSave.IncCount();
            FOREACHPAM_END()

@@ -1131,7 +1336,7 @@ void _SaveCntntIdx( SwDoc* pDoc, ULONG nNode, xub_StrLen nCntnt,
            if( pUnoTblCrsr )
            {
                FOREACHPAM_START( &pUnoTblCrsr->GetSelRing() )
                    ::_ChkPaM( rSaveArr, nNode, nCntnt, *PCURCRSR, aSave, FALSE );
                    lcl_ChkPaM( rSaveArr, nNode, nCntnt, *PCURCRSR, aSave, FALSE );
                    aSave.IncCount();
                FOREACHPAM_END()
            }
@@ -1140,13 +1345,16 @@ void _SaveCntntIdx( SwDoc* pDoc, ULONG nNode, xub_StrLen nCntnt,
}


void _RestoreCntntIdx( SwDoc* pDoc, SvULongs& rSaveArr,
                        ULONG nNode, xub_StrLen nOffset, BOOL bAuto )
void _RestoreCntntIdx(SwDoc* pDoc,
    SvULongs& rSaveArr,
    ULONG nNode,
    xub_StrLen nOffset,
    BOOL bAuto)
{
    SwCntntNode* pCNd = pDoc->GetNodes()[ nNode ]->GetCntntNode();
    const SwBookmarks& rBkmks = pDoc->getBookmarks();
    const SwRedlineTbl& rRedlTbl = pDoc->GetRedlineTbl();
    SwSpzFrmFmts* pSpz = pDoc->GetSpzFrmFmts();
    IDocumentMarkAccess* const pMarkAccess = pDoc->getIDocumentMarkAccess();
    USHORT n = 0;
    while( n < rSaveArr.Count() )
    {
@@ -1154,102 +1362,96 @@ void _RestoreCntntIdx( SwDoc* pDoc, SvULongs& rSaveArr,
        SwPosition* pPos = 0;
        switch( aSave.GetType() )
        {
        case 0x8000:
        {
            // --> OD 2007-09-27 #i81002# - refactoring
            // Do not directly manipulate members of <SwBookmark>
//            pPos = (SwPosition*)&rBkmks[ aSave.GetCount() ]->GetBookmarkPos();
            SwPosition aNewPos( rBkmks[ aSave.GetCount() ]->GetBookmarkPos() );
            aNewPos.nNode = *pCNd;
            aNewPos.nContent.Assign( pCNd, aSave.GetContent() + nOffset );
            rBkmks[ aSave.GetCount() ]->SetBookmarkPos( &aNewPos );
            // <--
        }
        break;
        case 0x8001:
        {
            // --> OD 2007-09-27 #i81002# - refactoring
            // Do not directly manipulate members of <SwBookmark>
//            pPos = (SwPosition*)rBkmks[ aSave.GetCount() ]->GetOtherBookmarkPos();
            SwPosition aNewPos( *(rBkmks[ aSave.GetCount() ]->GetOtherBookmarkPos()) );
            aNewPos.nNode = *pCNd;
            aNewPos.nContent.Assign( pCNd, aSave.GetContent() + nOffset );
            rBkmks[ aSave.GetCount() ]->SetOtherBookmarkPos( &aNewPos );
            // <--
        }
        break;
        case 0x1001:
            pPos = (SwPosition*)rRedlTbl[ aSave.GetCount() ]->GetPoint();
            break;
        case 0x1000:
            pPos = (SwPosition*)rRedlTbl[ aSave.GetCount() ]->GetMark();
            break;
        case 0x2000:
            case 0x8000:
            {
                SwFrmFmt *pFrmFmt = (*pSpz)[ aSave.GetCount() ];
                const SwFmtAnchor& rFlyAnchor = pFrmFmt->GetAnchor();
                if( rFlyAnchor.GetCntntAnchor() )
                {
                    SwFmtAnchor aNew( rFlyAnchor );
                    SwPosition aNewPos( *rFlyAnchor.GetCntntAnchor() );
                    aNewPos.nNode = *pCNd;
                    if( FLY_AUTO_CNTNT == rFlyAnchor.GetAnchorId() )
                        aNewPos.nContent.Assign( pCNd,
                                                 aSave.GetContent() + nOffset );
                    else
                        aNewPos.nContent.Assign( 0, 0 );
                    aNew.SetAnchor( &aNewPos );
                    pFrmFmt->SetFmtAttr( aNew );
                }
                MarkBase* pMark = dynamic_cast<MarkBase*>(pMarkAccess->getMarksBegin()[aSave.GetCount()].get());
                SwPosition aNewPos(pMark->GetMarkPos());
                aNewPos.nNode = *pCNd;
                aNewPos.nContent.Assign(pCNd, aSave.GetContent() + nOffset);
                pMark->SetMarkPos(aNewPos);
            }
            break;
        case 0x2001:
            if( bAuto )
            case 0x8001:
            {
                SwFrmFmt *pFrmFmt = (*pSpz)[ aSave.GetCount() ];
                SfxPoolItem *pAnchor = (SfxPoolItem*)&pFrmFmt->GetAnchor();
                pFrmFmt->SwModify::Modify( pAnchor, pAnchor );
                MarkBase* pMark = dynamic_cast<MarkBase*>(pMarkAccess->getMarksBegin()[aSave.GetCount()].get());
                SwPosition aNewPos(pMark->GetOtherMarkPos());
                aNewPos.nNode = *pCNd;
                aNewPos.nContent.Assign(pCNd, aSave.GetContent() + nOffset);
                pMark->SetOtherMarkPos(aNewPos);
            }
            break;

        case 0x0800:
        case 0x0801:
            {
                USHORT nCnt = 0;
                SwCrsrShell* pShell = pDoc->GetEditShell();
                if( pShell )
            case 0x1001:
                pPos = (SwPosition*)rRedlTbl[ aSave.GetCount() ]->GetPoint();
                break;
            case 0x1000:
                pPos = (SwPosition*)rRedlTbl[ aSave.GetCount() ]->GetMark();
                break;
            case 0x2000:
                {
                    FOREACHSHELL_START( pShell )
                        SwPaM *_pStkCrsr = PCURSH->GetStkCrsr();
                        if( _pStkCrsr )
                        do {
                            if( aSave.GetCount() == nCnt )
                            {
                                pPos = &_pStkCrsr->GetBound( 0x0800 ==
                                                    aSave.GetType() );
                                break;
                            }
                            ++nCnt;
                        } while ( (_pStkCrsr != 0 ) &&
                            ((_pStkCrsr=(SwPaM *)_pStkCrsr->GetNext()) != PCURSH->GetStkCrsr()) );

                        if( pPos )
                            break;

                        FOREACHPAM_START( PCURSH->_GetCrsr() )
                            if( aSave.GetCount() == nCnt )
                            {
                                pPos = &PCURCRSR->GetBound( 0x0800 ==
                                                    aSave.GetType() );
                                break;
                            }
                            ++nCnt;
                        FOREACHPAM_END()
                        if( pPos )
                            break;

                    FOREACHSHELL_END( pShell )
                    SwFrmFmt *pFrmFmt = (*pSpz)[ aSave.GetCount() ];
                    const SwFmtAnchor& rFlyAnchor = pFrmFmt->GetAnchor();
                    if( rFlyAnchor.GetCntntAnchor() )
                    {
                        SwFmtAnchor aNew( rFlyAnchor );
                        SwPosition aNewPos( *rFlyAnchor.GetCntntAnchor() );
                        aNewPos.nNode = *pCNd;
                        if( FLY_AUTO_CNTNT == rFlyAnchor.GetAnchorId() )
                            aNewPos.nContent.Assign( pCNd,
                                                     aSave.GetContent() + nOffset );
                        else
                            aNewPos.nContent.Assign( 0, 0 );
                        aNew.SetAnchor( &aNewPos );
                        pFrmFmt->SetFmtAttr( aNew );
                    }
                }
                break;
            case 0x2001:
                if( bAuto )
                {
                    SwFrmFmt *pFrmFmt = (*pSpz)[ aSave.GetCount() ];
                    SfxPoolItem *pAnchor = (SfxPoolItem*)&pFrmFmt->GetAnchor();
                    pFrmFmt->SwModify::Modify( pAnchor, pAnchor );
                }
                break;

            case 0x0800:
            case 0x0801:
                {
                    USHORT nCnt = 0;
                    SwCrsrShell* pShell = pDoc->GetEditShell();
                    if( pShell )
                    {
                        FOREACHSHELL_START( pShell )
                            SwPaM *_pStkCrsr = PCURSH->GetStkCrsr();
                            if( _pStkCrsr )
                            do {
                                if( aSave.GetCount() == nCnt )
                                {
                                    pPos = &_pStkCrsr->GetBound( 0x0800 ==
                                                        aSave.GetType() );
                                    break;
                                }
                                ++nCnt;
                            } while ( (_pStkCrsr != 0 ) &&
                                ((_pStkCrsr=(SwPaM *)_pStkCrsr->GetNext()) != PCURSH->GetStkCrsr()) );

                            if( pPos )
                                break;

                            FOREACHPAM_START( PCURSH->_GetCrsr() )
                                if( aSave.GetCount() == nCnt )
                                {
                                    pPos = &PCURCRSR->GetBound( 0x0800 ==
                                                        aSave.GetType() );
                                    break;
                                }
                                ++nCnt;
                            FOREACHPAM_END()
                            if( pPos )
                                break;

                        FOREACHSHELL_END( pShell )
                    }
            }
            break;

@@ -1300,52 +1502,15 @@ void _RestoreCntntIdx( SwDoc* pDoc, SvULongs& rSaveArr,
    }
}

SwFieldBookmark::SwFieldBookmark(const SwPosition& aPos,
        const KeyCode& rCode,
        const String& rName, const String& rShortName,
        IDocumentBookmarkAccess::BookmarkType eMark)
    : SwBookmark(aPos, rCode, rName, rShortName),
        fftype(0), // Type: 0 = Text, 1 = Check Box, 2 = List
        ffres(0),
        ffprot(0),
        ffsize(0), // 0 = Auto, 1=Exact (see ffhps)
        fftypetxt(0), // Type of text field: 0 = Regular text, 1 = Number, 2 = Date, 3 = Current date, 4 = Current time, 5 = Calculation
        ffrecalc(0),
        ffmaxlen(0), // Number of characters for text field. Zero means unlimited.
        ffhps(24) // Check box size (half-point sizes).
{
    eMarkType = eMark;
}

void SwFieldBookmark::SetChecked(bool checked)
{
    ASSERT(fftype==1, "This method is for checkboxes only...");
    ffres=(checked?1:0);
}

bool SwFieldBookmark::IsChecked()
{
    ASSERT(fftype==1, "This method is for checkboxes only...");
    return ffres!=0;
}

void SwFieldBookmark::SetFieldType(int newfftype)
{
    this->fftype=newfftype;
}

int SwFieldBookmark::GetFieldType()
{
    return fftype;
}

void _RestoreCntntIdx( SvULongs& rSaveArr, const SwNode& rNd,
                        xub_StrLen nLen, xub_StrLen nChkLen )
void _RestoreCntntIdx(SvULongs& rSaveArr,
    const SwNode& rNd,
    xub_StrLen nLen,
    xub_StrLen nChkLen)
{
    const SwDoc* pDoc = rNd.GetDoc();
    const SwBookmarks& rBkmks = pDoc->getBookmarks();
    const SwRedlineTbl& rRedlTbl = pDoc->GetRedlineTbl();
    const SwSpzFrmFmts* pSpz = pDoc->GetSpzFrmFmts();
    const IDocumentMarkAccess* const pMarkAccess = pDoc->getIDocumentMarkAccess();
    SwCntntNode* pCNd = (SwCntntNode*)rNd.GetCntntNode();

    USHORT n = 0;
@@ -1361,26 +1526,20 @@ void _RestoreCntntIdx( SvULongs& rSaveArr, const SwNode& rNd,
            {
            case 0x8000:
            {
                // --> OD 2007-09-27 #i81002# - refactoring
                // Do not directly manipulate members of <SwBookmark>
//                pPos = (SwPosition*)&rBkmks[ aSave.GetCount() ]->GetBookmarkPos();
                SwPosition aNewPos( rBkmks[ aSave.GetCount() ]->GetBookmarkPos() );
                MarkBase* pMark = dynamic_cast<MarkBase*>(pMarkAccess->getMarksBegin()[aSave.GetCount()].get());
                SwPosition aNewPos(pMark->GetMarkPos());
                aNewPos.nNode = rNd;
                aNewPos.nContent.Assign( pCNd, Min( aSave.GetContent(), nLen ) );
                rBkmks[ aSave.GetCount() ]->SetBookmarkPos( &aNewPos );
                // <--
                aNewPos.nContent.Assign(pCNd, Min(aSave.GetContent(), nLen));
                pMark->SetMarkPos(aNewPos);
            }
            break;
            case 0x8001:
            {
                // --> OD 2007-09-27 #i81002# - refactoring
                // Do not directly manipulate members of <SwBookmark>
//                pPos = (SwPosition*)rBkmks[ aSave.GetCount() ]->GetOtherBookmarkPos();
                SwPosition aNewPos( *(rBkmks[ aSave.GetCount() ]->GetOtherBookmarkPos()) );
                MarkBase* pMark = dynamic_cast<MarkBase*>(pMarkAccess->getMarksBegin()[aSave.GetCount()].get());
                SwPosition aNewPos(pMark->GetOtherMarkPos());
                aNewPos.nNode = rNd;
                aNewPos.nContent.Assign( pCNd, Min( aSave.GetContent(), nLen ) );
                rBkmks[ aSave.GetCount() ]->SetOtherBookmarkPos( &aNewPos );
                // <--
                aNewPos.nContent.Assign(pCNd, Min(aSave.GetContent(), nLen));
                pMark->SetOtherMarkPos(aNewPos);
            }
            break;
            case 0x1001:
@@ -1500,85 +1659,3 @@ void _RestoreCntntIdx( SvULongs& rSaveArr, const SwNode& rNd,
        }
    }
}

// --> OD 2007-11-09 #i81002#
namespace bookmarkfunc
{
    const String getHeadingCrossRefBookmarkNamePrefix()
    {
        static const String sPrefix( String::CreateFromAscii( "__RefHeading__" ) );

        return sPrefix;
    }

    const String getNumItemCrossRefBookmarkNamePrefix()
    {
        static String sPrefix( String::CreateFromAscii( "__RefNumPara__" ) );

        return sPrefix;
    }

    bool isHeadingCrossRefBookmarkName( /*[in]*/const String& rName )
    {
        bool bRet( false );

        const xub_StrLen cLenOfFixedFirstPart =
                                    getHeadingCrossRefBookmarkNamePrefix().Len();
        if ( rName.Len() > cLenOfFixedFirstPart )
        {
            const String aFirstPartOfName = rName.Copy( 0, cLenOfFixedFirstPart );
            const String aRestOfName = rName.Copy( cLenOfFixedFirstPart );
            if ( aRestOfName.ToInt64() > 0 &&
                 aFirstPartOfName.Equals( getHeadingCrossRefBookmarkNamePrefix() ) )
            {
                bRet = true;
            }
        }

        return bRet;

    }

    bool isNumItemCrossRefBookmarkName( /*[in]*/const String& rName )
    {
        bool bRet( false );

        const xub_StrLen cLenOfFixedFirstPart =
                                    getNumItemCrossRefBookmarkNamePrefix().Len();
        if ( rName.Len() > cLenOfFixedFirstPart )
        {
            const String aFirstPartOfName = rName.Copy( 0, cLenOfFixedFirstPart );
            const String aRestOfName = rName.Copy( cLenOfFixedFirstPart );
            if ( aRestOfName.ToInt64() > 0 &&
                 aFirstPartOfName.Equals( getNumItemCrossRefBookmarkNamePrefix() ) )
            {
                bRet = true;
            }
        }

        return bRet;

    }

    // --> OD 2007-11-16 #i83479#
    String generateNewCrossRefBookmarkName(
            /*[in]*/const IDocumentBookmarkAccess::CrossReferenceBookmarkSubType nSubType )
    {
        String sNewName;
        if ( nSubType == IDocumentBookmarkAccess::HEADING )
        {
            sNewName = getHeadingCrossRefBookmarkNamePrefix();
        }
        else if ( nSubType == IDocumentBookmarkAccess::NUMITEM )
        {
            sNewName = getNumItemCrossRefBookmarkNamePrefix();
        }

        long n = Time().GetTime();
        n += Date().GetDate();
        sNewName.Append( String::CreateFromInt32( n ) );

        return sNewName;
    }
}
// <--
diff --git a/sw/source/core/doc/doccorr.cxx b/sw/source/core/doc/doccorr.cxx
index e48bdac..c7c3e4e 100644
--- a/sw/source/core/doc/doccorr.cxx
+++ b/sw/source/core/doc/doccorr.cxx
@@ -37,6 +37,7 @@
#include <rootfrm.hxx>
#include <editsh.hxx>
#include <viscrs.hxx>
#include <IMark.hxx>
#include <bookmrk.hxx>
#include <redline.hxx>
#include <mvsave.hxx>
@@ -73,17 +74,77 @@
        } while( (_pCurrCrsr=(SwPaM *)_pCurrCrsr->GetNext()) != _pStartCrsr ); \
    }

/*  */
namespace
{
    // find the relevant section in which the SwUnoCrsr may wander. returns NULL if
    // no restrictions apply
    const SwStartNode* lcl_FindUnoCrsrSection( const SwNode& rNode )
    {
        const SwStartNode* pStartNode = rNode.StartOfSectionNode();
        while( ( pStartNode != NULL ) &&
               ( pStartNode->StartOfSectionNode() != pStartNode ) &&
               ( pStartNode->GetStartNodeType() == SwNormalStartNode ) )
            pStartNode = pStartNode->StartOfSectionNode();

#define _PaMCorrAbs1( pPam ) \
    for( int nb = 0; nb < 2; ++nb ) \
        if( &((pPam)->GetBound( BOOL(nb) ).nNode.GetNode()) == pOldNode )   \
        { \
            (pPam)->GetBound( BOOL(nb) ) = aNewPos; \
            (pPam)->GetBound( BOOL(nb) ).nContent += nOffset; \
        }
        return pStartNode;
    }

    static inline void lcl_PaMCorrAbs1(SwPaM * pPam,
        SwNode const * const pOldNode,
        const SwPosition& rNewPos,
        const xub_StrLen nOffset)
    {
        for(int nb = 0; nb < 2; ++nb)
            if(&((pPam)->GetBound(BOOL(nb)).nNode.GetNode()) == pOldNode)
            {
                (pPam)->GetBound(BOOL(nb)) = rNewPos;
                (pPam)->GetBound(BOOL(nb)).nContent += nOffset;
            }
    };

    static inline bool lcl_PaMCorrAbs2(SwPaM* pPam,
        const SwPosition& rNewPos,
        ULONG nSttNode,
        ULONG nEndNode)
    {
        bool bRet = false;

        for(int nb = 0; nb < 2; ++nb)
            if((pPam)->GetBound(BOOL(nb)).nNode >= nSttNode &&
                (pPam)->GetBound(BOOL(nb)).nNode <= nEndNode)
            {
                (pPam)->GetBound(BOOL(nb)) = rNewPos;
                bRet = true;
            }
        return bRet;
    };

    static inline void lcl_PaMCorrAbs3(SwPaM * pPam,
        const SwPosition& rStart,
        const SwPosition& rEnd,
        const SwPosition& rNewPos)
    {
        for(int nb = 0; nb < 2; ++nb)
            if(rStart <= (pPam)->GetBound(BOOL(nb)) &&
                (pPam)->GetBound(BOOL(nb)) <= rEnd )
                (pPam)->GetBound(BOOL(nb)) = rNewPos;
    };

    static inline void lcl_PaMCorrRel1(SwPaM * pPam,
        SwNode const * const pOldNode,
        const SwPosition& rNewPos,
        const xub_StrLen nCntIdx)
    {
        for(int nb = 0; nb < 2; ++nb)
            if(&((pPam)->GetBound(BOOL(nb)).nNode.GetNode()) == pOldNode)
            {
                (pPam)->GetBound(BOOL(nb)).nNode = rNewPos.nNode;
                (pPam)->GetBound(BOOL(nb)).nContent.Assign(
                    const_cast<SwIndexReg*>(rNewPos.nContent.GetIdxReg()),
                    nCntIdx + (pPam)->GetBound(BOOL(nb)).nContent.GetIndex());
            }
    }
}

void PaMCorrAbs( const SwNodeIndex &rOldNode,
                const SwPosition &rNewPos,
@@ -98,20 +159,18 @@ void PaMCorrAbs( const SwNodeIndex &rOldNode,
    {
        FOREACHSHELL_START( pShell )
            SwPaM *_pStkCrsr = PCURSH->GetStkCrsr();
    // Alle ueberfluessigen Crsr sind vom Stack, oder ??
    //      ASSERT( !_pStkCrsr, "Es stehen noch Crsr auf dem CrsrStack" );
            if( _pStkCrsr )
            do {
                _PaMCorrAbs1( _pStkCrsr )
                lcl_PaMCorrAbs1( _pStkCrsr, pOldNode, aNewPos, nOffset );
            } while ( (_pStkCrsr != 0 ) &&
                ((_pStkCrsr=(SwPaM *)_pStkCrsr->GetNext()) != PCURSH->GetStkCrsr()) );

            FOREACHPAM_START( PCURSH->_GetCrsr() )
                _PaMCorrAbs1( PCURCRSR )
                lcl_PaMCorrAbs1( PCURCRSR, pOldNode, aNewPos, nOffset );
            FOREACHPAM_END()

            if( PCURSH->IsTableMode() )
                _PaMCorrAbs1( PCURSH->GetTblCrs() )
                lcl_PaMCorrAbs1( PCURSH->GetTblCrs(), pOldNode, aNewPos, nOffset );

        FOREACHSHELL_END( pShell )
    }
@@ -121,14 +180,14 @@ void PaMCorrAbs( const SwNodeIndex &rOldNode,
        for( USHORT n = 0; n < rTbl.Count(); ++n )
        {
            FOREACHPAM_START( rTbl[ n ] )
                _PaMCorrAbs1( PCURCRSR )
                lcl_PaMCorrAbs1( PCURCRSR, pOldNode, aNewPos, nOffset );
            FOREACHPAM_END()

            SwUnoTableCrsr* pUnoTblCrsr = (SwUnoTableCrsr*)*rTbl[ n ];
            if( pUnoTblCrsr )
            {
                FOREACHPAM_START( &pUnoTblCrsr->GetSelRing() )
                    _PaMCorrAbs1( PCURCRSR )
                    lcl_PaMCorrAbs1( PCURCRSR, pOldNode, aNewPos, nOffset );
                FOREACHPAM_END()
            }
        }
@@ -136,113 +195,6 @@ void PaMCorrAbs( const SwNodeIndex &rOldNode,
}


void SwDoc::CorrAbs( const SwNodeIndex& rOldNode,
                     const SwPosition& rNewPos,
                     const xub_StrLen nOffset,
                     BOOL bMoveCrsr )
{
    const SwNode* pOldNode = &rOldNode.GetNode();
    SwPosition aNewPos( rNewPos );

    { // erstmal die Bookmark korrigieren
        SwBookmarks& rBkmks = *pBookmarkTbl;
        SwBookmark* pBkmk;
        for( USHORT n = 0; n < rBkmks.Count(); ++n )
        {
            // liegt auf der Position ??
            int bChgd = 0;
            if( &( pBkmk = (SwBookmark*)rBkmks[ n ])->GetBookmarkPos().nNode.GetNode() == pOldNode )
            {
                // --> OD 2007-09-26 #i81002# - refactoring
//                *pBkmk->pPos1 = aNewPos;
//                pBkmk->pPos1->nContent += nOffset;
                SwPosition aNewPos1( aNewPos );
                aNewPos1.nContent += nOffset;
                pBkmk->SetBookmarkPos( &aNewPos1 );
                // <--
                bChgd = 1;
            }
            if ( pBkmk->GetOtherBookmarkPos() &&
                 &pBkmk->GetOtherBookmarkPos()->nNode.GetNode() == pOldNode )
            {
                // --> OD 2007-09-26 #i81002# - refactoring
//                *pBkmk->pPos2 = aNewPos;
//                pBkmk->pPos2->nContent += nOffset;
                SwPosition aNewPos2( aNewPos );
                aNewPos2.nContent += nOffset;
                pBkmk->SetOtherBookmarkPos( &aNewPos );
                // <--
                bChgd = 2;
            }
            // ungueltige Selektion? Dann die Klammerung aufheben
            if( bChgd && pBkmk->GetOtherBookmarkPos() &&
                pBkmk->GetOtherBookmarkPos()->nNode.GetNode().FindTableBoxStartNode() !=
                pBkmk->GetBookmarkPos().nNode.GetNode().FindTableBoxStartNode() )
            {
                if( 1 == bChgd )
                {
                    // --> OD 2007-09-26 #i81002# - refactoring
//                    *pBkmk->pPos1 = *pBkmk->pPos2;
                    pBkmk->SetBookmarkPos( pBkmk->GetOtherBookmarkPos() );
                    // <--
                }
                // --> OD 2007-09-26 #i81002# - refactoring
//                delete pBkmk->pPos2, pBkmk->pPos2 = 0;
                pBkmk->SetOtherBookmarkPos( 0 );
                // <--
                if( pBkmk->IsServer() )
                    pBkmk->SetRefObject( 0 );
                // die Sortierung muss aufrecht erhalten bleiben!
                rBkmks.Remove( n-- );
                rBkmks.Insert( pBkmk );
            }
        }
    }
    { // dann die Redlines korrigieren
        SwRedlineTbl& rTbl = *pRedlineTbl;
        for( USHORT n = 0; n < rTbl.Count(); ++n )
        {
            // liegt auf der Position ??
            _PaMCorrAbs1( rTbl[ n ] )
        }
    }

    if( bMoveCrsr )
        ::PaMCorrAbs( rOldNode, rNewPos, nOffset );
}

/*  */

bool _PaMCorrAbs2( SwPaM* pPam,
                   const SwPosition& rNewPos,
                   ULONG nSttNode, ULONG nEndNode )
{
    bool bRet = false;

    for( int nb = 0; nb < 2; ++nb ) \
        if( (pPam)->GetBound( BOOL(nb) ).nNode >= nSttNode &&
            (pPam)->GetBound( BOOL(nb) ).nNode <= nEndNode )
        {
            (pPam)->GetBound( BOOL(nb) ) = rNewPos;
            bRet = true;
        }

    return bRet;
}

// find the relevant section in which the SwUnoCrsr may wander. returns NULL if
// no restrictions apply
const SwStartNode* lcl_FindUnoCrsrSection( const SwNode& rNode )
{
    const SwStartNode* pStartNode = rNode.StartOfSectionNode();
    while( ( pStartNode != NULL ) &&
           ( pStartNode->StartOfSectionNode() != pStartNode ) &&
           ( pStartNode->GetStartNodeType() == SwNormalStartNode ) )
        pStartNode = pStartNode->StartOfSectionNode();

    return pStartNode;
}

void PaMCorrAbs( const SwNodeIndex &rStartNode,
                 const SwNodeIndex &rEndNode,
                 const SwPosition &rNewPos )
@@ -257,20 +209,18 @@ void PaMCorrAbs( const SwNodeIndex &rStartNode,
    {
        FOREACHSHELL_START( pShell )
            SwPaM *_pStkCrsr = PCURSH->GetStkCrsr();
    // Alle ueberfluessigen Crsr sind vom Stack, oder ??
    //      ASSERT( !_pStkCrsr, "Es stehen noch Crsr auf dem CrsrStack" );
            if( _pStkCrsr )
            do {
                _PaMCorrAbs2( _pStkCrsr, aNewPos, nSttNode, nEndNode );
                lcl_PaMCorrAbs2( _pStkCrsr, aNewPos, nSttNode, nEndNode );
            } while ( (_pStkCrsr != 0 ) &&
                ((_pStkCrsr=(SwPaM *)_pStkCrsr->GetNext()) != PCURSH->GetStkCrsr()) );

            FOREACHPAM_START( PCURSH->_GetCrsr() )
                _PaMCorrAbs2( PCURCRSR, aNewPos, nSttNode, nEndNode );
                lcl_PaMCorrAbs2( PCURCRSR, aNewPos, nSttNode, nEndNode );
            FOREACHPAM_END()

            if( PCURSH->IsTableMode() )
                _PaMCorrAbs2( PCURSH->GetTblCrs(), aNewPos, nSttNode, nEndNode );
                lcl_PaMCorrAbs2( PCURSH->GetTblCrs(), aNewPos, nSttNode, nEndNode );

        FOREACHSHELL_END( pShell )
    }
@@ -292,7 +242,7 @@ void PaMCorrAbs( const SwNodeIndex &rStartNode,
                      pUnoCursor->GetPoint()->nNode.GetNode() ) );

            FOREACHPAM_START( pUnoCursor )
                bChange |= _PaMCorrAbs2(PCURCRSR, aNewPos, nSttNode, nEndNode);
                bChange |= lcl_PaMCorrAbs2(PCURCRSR, aNewPos, nSttNode, nEndNode);
            FOREACHPAM_END()

            SwUnoTableCrsr* pUnoTblCrsr = (SwUnoTableCrsr*)*pUnoCursor;
@@ -300,7 +250,7 @@ void PaMCorrAbs( const SwNodeIndex &rStartNode,
            {
                FOREACHPAM_START( &pUnoTblCrsr->GetSelRing() )
                    bChange |=
                        _PaMCorrAbs2( PCURCRSR, aNewPos, nSttNode, nEndNode );
                        lcl_PaMCorrAbs2( PCURCRSR, aNewPos, nSttNode, nEndNode );
                FOREACHPAM_END()
            }

@@ -317,30 +267,6 @@ void PaMCorrAbs( const SwNodeIndex &rStartNode,
}


void SwDoc::CorrAbs( const SwNodeIndex& rStartNode,
                     const SwNodeIndex& rEndNode,
                     const SwPosition& rNewPos,
                     BOOL bMoveCrsr )
{
    SwPosition aNewPos( rNewPos );

//  if( !DoesUndo() )
        // erstmal die Bookmarks/Redlines korrigieren
        _DelBookmarks( rStartNode, rEndNode );

    if( bMoveCrsr )
        ::PaMCorrAbs( rStartNode, rEndNode, rNewPos );
}


/*  */

#define _PaMCorrAbs3( pPam ) \
    for( int nb = 0; nb < 2; ++nb ) \
        if( aStart <= (pPam)->GetBound( BOOL(nb) ) && \
            (pPam)->GetBound( BOOL(nb) ) <= aEnd ) \
            (pPam)->GetBound( BOOL(nb) ) = aNewPos;

void PaMCorrAbs( const SwPaM& rRange,
                const SwPosition& rNewPos )
{
@@ -354,20 +280,18 @@ void PaMCorrAbs( const SwPaM& rRange,
    {
        FOREACHSHELL_START( pShell )
            SwPaM *_pStkCrsr = PCURSH->GetStkCrsr();
    // Alle ueberfluessigen Crsr sind vom Stack, oder ??
    //      ASSERT( !_pStkCrsr, "Es stehen noch Crsr auf dem CrsrStack" );
            if( _pStkCrsr )
            do {
                _PaMCorrAbs3( _pStkCrsr )
                lcl_PaMCorrAbs3( _pStkCrsr, aStart, aEnd, aNewPos );
            } while ( (_pStkCrsr != 0 ) &&
                ((_pStkCrsr=(SwPaM *)_pStkCrsr->GetNext()) != PCURSH->GetStkCrsr()) );

            FOREACHPAM_START( PCURSH->_GetCrsr() )
                _PaMCorrAbs3( PCURCRSR )
                lcl_PaMCorrAbs3( PCURCRSR, aStart, aEnd, aNewPos );
            FOREACHPAM_END()

            if( PCURSH->IsTableMode() )
                _PaMCorrAbs3( PCURSH->GetTblCrs() )
                lcl_PaMCorrAbs3( PCURSH->GetTblCrs(), aStart, aEnd, aNewPos );

        FOREACHSHELL_END( pShell )
    }
@@ -376,50 +300,67 @@ void PaMCorrAbs( const SwPaM& rRange,
        for( USHORT n = 0; n < rTbl.Count(); ++n )
        {
            FOREACHPAM_START( rTbl[ n ] )
                _PaMCorrAbs3( PCURCRSR )
                lcl_PaMCorrAbs3( PCURCRSR, aStart, aEnd, aNewPos );
            FOREACHPAM_END()

            SwUnoTableCrsr* pUnoTblCrsr = (SwUnoTableCrsr*)*rTbl[ n ];
            if( pUnoTblCrsr )
            {
                FOREACHPAM_START( &pUnoTblCrsr->GetSelRing() )
                    _PaMCorrAbs3( PCURCRSR )
                    lcl_PaMCorrAbs3( PCURCRSR, aStart, aEnd, aNewPos );
                FOREACHPAM_END()
            }
        }
    }
}


void SwDoc::CorrAbs( const SwPaM& rRange,
                    const SwPosition& rNewPos,
                    BOOL bMoveCrsr )
void SwDoc::CorrAbs(const SwNodeIndex& rOldNode,
    const SwPosition& rNewPos,
    const xub_StrLen nOffset,
    BOOL bMoveCrsr)
{
    SwPosition aStart( *rRange.Start() );
    SwPosition aEnd( *rRange.End() );
    SwPosition aNewPos( rNewPos );
    getIDocumentMarkAccess()->correctMarksAbsolute(rOldNode, rNewPos, nOffset);
    { // fix readlines
        SwRedlineTbl& rTbl = *pRedlineTbl;
        for( USHORT n = 0; n < rTbl.Count(); ++n )
        {
            // is on position ??
            lcl_PaMCorrAbs1( rTbl[ n ], &rOldNode.GetNode(), SwPosition(rNewPos), nOffset );
        }
    }

//  if( !DoesUndo() )
        // erstmal die Bookmarks/Redlines korrigieren
        _DelBookmarks( aStart.nNode, aEnd.nNode, 0,
                           &aStart.nContent, &aEnd.nContent );
    if( bMoveCrsr )
        ::PaMCorrAbs( rRange, rNewPos );
    if(bMoveCrsr)
        ::PaMCorrAbs(rOldNode, rNewPos, nOffset);
}

void SwDoc::CorrAbs(const SwPaM& rRange,
    const SwPosition& rNewPos,
    BOOL bMoveCrsr)
{
    SwPosition aStart(*rRange.Start());
    SwPosition aEnd(*rRange.End());
    SwPosition aNewPos(rNewPos);

    _DelBookmarks(aStart.nNode, aEnd.nNode, NULL,
        &aStart.nContent, &aEnd.nContent);
    if(bMoveCrsr)
        ::PaMCorrAbs(rRange, rNewPos);
}

void SwDoc::CorrAbs(const SwNodeIndex& rStartNode,
     const SwNodeIndex& rEndNode,
     const SwPosition& rNewPos,
     BOOL bMoveCrsr)
{
    SwPosition aNewPos(rNewPos);

    _DelBookmarks(rStartNode, rEndNode);

    if(bMoveCrsr)
        ::PaMCorrAbs(rStartNode, rEndNode, rNewPos);
}


/*  */

#define _PaMCorrRel1( pPam ) \
    for( int nb = 0; nb < 2; ++nb ) \
        if( &((pPam)->GetBound( BOOL(nb) ).nNode.GetNode()) == pOldNode ) \
        { \
            (pPam)->GetBound( BOOL(nb) ).nNode = aNewPos.nNode; \
            (pPam)->GetBound( BOOL(nb) ).nContent.Assign( (SwIndexReg*) \
                            aNewPos.nContent.GetIdxReg(), \
                            nCntIdx + (pPam)->GetBound( BOOL(nb) ).nContent. \
                                GetIndex() ); \
        }



@@ -438,20 +379,18 @@ void PaMCorrRel( const SwNodeIndex &rOldNode,
    {
        FOREACHSHELL_START( pShell )
            SwPaM *_pStkCrsr = PCURSH->GetStkCrsr();
    // Alle ueberfluessigen Crsr sind vom Stack, oder ??
    //      ASSERT( !_pStkCrsr, "Es stehen noch Crsr auf dem CrsrStack" );
            if( _pStkCrsr )
            do {
                _PaMCorrRel1( _pStkCrsr )
                lcl_PaMCorrRel1( _pStkCrsr, pOldNode, aNewPos, nCntIdx );
            } while ( (_pStkCrsr != 0 ) &&
                ((_pStkCrsr=(SwPaM *)_pStkCrsr->GetNext()) != PCURSH->GetStkCrsr()) );

            FOREACHPAM_START( PCURSH->_GetCrsr() )
                _PaMCorrRel1( PCURCRSR )
                lcl_PaMCorrRel1( PCURCRSR, pOldNode, aNewPos, nCntIdx);
            FOREACHPAM_END()

            if( PCURSH->IsTableMode() )
                _PaMCorrRel1( PCURSH->GetTblCrs() )
                lcl_PaMCorrRel1( PCURSH->GetTblCrs(), pOldNode, aNewPos, nCntIdx );

        FOREACHSHELL_END( pShell )
    }
@@ -460,109 +399,42 @@ void PaMCorrRel( const SwNodeIndex &rOldNode,
        for( USHORT n = 0; n < rTbl.Count(); ++n )
        {
            FOREACHPAM_START( rTbl[ n ] )
                _PaMCorrRel1( PCURCRSR )
                lcl_PaMCorrRel1( PCURCRSR, pOldNode, aNewPos, nCntIdx );
            FOREACHPAM_END()

            SwUnoTableCrsr* pUnoTblCrsr = (SwUnoTableCrsr*)*rTbl[ n ];
            if( pUnoTblCrsr )
            {
                FOREACHPAM_START( &pUnoTblCrsr->GetSelRing() )
                    _PaMCorrRel1( PCURCRSR )
                    lcl_PaMCorrRel1( PCURCRSR, pOldNode, aNewPos, nCntIdx );
                FOREACHPAM_END()
            }
        }
    }
}

void SwDoc::CorrRel( const SwNodeIndex& rOldNode,
                     const SwPosition& rNewPos,
                     const xub_StrLen nOffset,
                     BOOL bMoveCrsr )
void SwDoc::CorrRel(const SwNodeIndex& rOldNode,
    const SwPosition& rNewPos,
    const xub_StrLen nOffset,
    BOOL bMoveCrsr)
{
    const SwNode* pOldNode = &rOldNode.GetNode();
    SwPosition aNewPos( rNewPos );
    xub_StrLen nCntIdx = aNewPos.nContent.GetIndex() + nOffset;
    getIDocumentMarkAccess()->correctMarksRelative(rOldNode, rNewPos, nOffset);

    { // erstmal die Bookmark korrigieren
        SwBookmarks& rBkmks = *pBookmarkTbl;
        SwBookmark* pBkmk;
        for( USHORT n = 0; n < rBkmks.Count(); ++n )
        {
            // liegt auf der Position ??
            int bChgd = FALSE;
            if( &( pBkmk = (SwBookmark*)rBkmks[ n ])->GetBookmarkPos().nNode.GetNode()
                == pOldNode )
            {
                // --> OD 2007-09-26 #i81002# - refactoring
//                pBkmk->pPos1->nNode = aNewPos.nNode;
//                pBkmk->pPos1->nContent.Assign( (SwIndexReg*)
//                            aNewPos.nContent.GetIdxReg(),
//                            nCntIdx + pBkmk->pPos1->nContent.GetIndex() );
                SwPosition aNewPos1( pBkmk->GetBookmarkPos() );
                aNewPos1.nNode = aNewPos.nNode;
                aNewPos1.nContent.Assign( (SwIndexReg*)aNewPos.nContent.GetIdxReg(),
                                          nCntIdx + pBkmk->GetBookmarkPos().nContent.GetIndex() );
                pBkmk->SetBookmarkPos( &aNewPos1 );
                // <--
                bChgd = 1;
            }
            if ( pBkmk->GetOtherBookmarkPos() &&
                 &pBkmk->GetOtherBookmarkPos()->nNode.GetNode() == pOldNode )
            {
                // --> OD 2007-09-26 #i81002# - refactoring
//                pBkmk->pPos2->nNode = aNewPos.nNode;
//                pBkmk->pPos2->nContent.Assign( (SwIndexReg*)
//                            aNewPos.nContent.GetIdxReg(),
//                            nCntIdx + pBkmk->pPos2->nContent.GetIndex() );
                SwPosition aNewPos2( *(pBkmk->GetOtherBookmarkPos()) );
                aNewPos2.nNode = aNewPos.nNode;
                aNewPos2.nContent.Assign( (SwIndexReg*)aNewPos.nContent.GetIdxReg(),
                                          nCntIdx + pBkmk->GetOtherBookmarkPos()->nContent.GetIndex() );
                pBkmk->SetOtherBookmarkPos( &aNewPos2 );
                // <--
                bChgd = 2;
            }
            // ungueltige Selektion? Dann die Klammerung aufheben
            if( bChgd && pBkmk->GetOtherBookmarkPos() &&
                pBkmk->GetOtherBookmarkPos()->nNode.GetNode().FindTableBoxStartNode() !=
                pBkmk->GetBookmarkPos().nNode.GetNode().FindTableBoxStartNode() )
            {
                if( 1 == bChgd )
                {
                    // --> OD 2007-09-26 #i81002# - refactoring
//                    *pBkmk->pPos1 = *pBkmk->pPos2;
                    pBkmk->SetBookmarkPos( pBkmk->GetOtherBookmarkPos() );
                    // <--
                }
                // --> OD 2007-09-26 #i81002# - refactoring
//                delete pBkmk->pPos2, pBkmk->pPos2 = 0;
                pBkmk->SetOtherBookmarkPos( 0 );
                // <--
                if( pBkmk->IsServer() )
                    pBkmk->SetRefObject( 0 );

                // die Sortierung muss aufrecht erhalten bleiben!
                rBkmks.Remove( n-- );
                rBkmks.Insert( pBkmk );
            }
        }
    }
    { // dann die Redlines korrigieren
        SwRedlineTbl& rTbl = *pRedlineTbl;
        SwPosition aNewPos(rNewPos);
        for( USHORT n = 0; n < rTbl.Count(); ++n )
        {
            // liegt auf der Position ??
            _PaMCorrRel1( rTbl[ n ] )
            lcl_PaMCorrRel1( rTbl[ n ], &rOldNode.GetNode(), aNewPos, aNewPos.nContent.GetIndex() + nOffset );
        }
    }

    if( bMoveCrsr )
        ::PaMCorrRel( rOldNode, rNewPos, nOffset );
    if(bMoveCrsr)
        ::PaMCorrRel(rOldNode, rNewPos, nOffset);
}


/*  */

SwEditShell* SwDoc::GetEditShell( ViewShell** ppSh ) const
{
    // Layout und OLE-Shells sollten vorhanden sein!
diff --git a/sw/source/core/doc/docdde.cxx b/sw/source/core/doc/docdde.cxx
index 59cc7cd..a7c042f 100644
--- a/sw/source/core/doc/docdde.cxx
+++ b/sw/source/core/doc/docdde.cxx
@@ -47,54 +47,48 @@
#include <fmtcntnt.hxx>
#include <doc.hxx>
#include <swserv.hxx>           // fuer Server-Funktionalitaet
#include <bookmrk.hxx>          // fuer die Bookmarks
#include <IMark.hxx>
#include <bookmrk.hxx>
#include <section.hxx>          // fuer SwSectionFmt
#include <swtable.hxx>          // fuer SwTable
#include <node.hxx>
#include <ndtxt.hxx>
#include <pam.hxx>
#include <docary.hxx>
#include <MarkManager.hxx>

using namespace ::com::sun::star;

namespace
{

    static ::sw::mark::DdeBookmark* const lcl_FindDdeBookmark(const IDocumentMarkAccess& rMarkAccess, const String& rName)
    {
        //Iterating over all bookmarks, checking DdeBookmarks
        const String sNameLc = GetAppCharClass().lower(rName);
        for(IDocumentMarkAccess::const_iterator_t ppMark = rMarkAccess.getMarksBegin();
            ppMark != rMarkAccess.getMarksEnd();
            ppMark++)
        {
            ::sw::mark::DdeBookmark* const pBkmk = dynamic_cast< ::sw::mark::DdeBookmark*>(ppMark->get());
            if(pBkmk && GetAppCharClass().lower(pBkmk->GetName()) == sNameLc)
                return pBkmk;
        }
        return NULL;
    }
}

struct _FindItem
{
    const String& rItem;
    SwBookmark* pBkmk;
    SwTableNode* pTblNd;
    SwSectionNode* pSectNd;

    _FindItem( const String& rS )
        : rItem( rS ), pBkmk( 0 ), pTblNd( 0 ), pSectNd( 0 )
    _FindItem(const String& rS)
        : rItem(rS), pTblNd(0), pSectNd(0)
    {}

    void ClearObj()
    {
        if( pBkmk )
            pBkmk->SetRefObject( 0 );
        else if( pSectNd )
            pSectNd->GetSection().SetRefObject( 0 );
        else if( pTblNd )
            pTblNd->GetTable().SetRefObject( 0 );
    }
};


BOOL lcl_FindBookmark( const SwBookmarkPtr& rpBkmk, void* pArgs )
{
    BOOL bRet = TRUE;
    String sNm( GetAppCharClass().lower( rpBkmk->GetName() ));
    if( sNm.Equals( ((_FindItem*)pArgs)->rItem ) )
    {
        ((_FindItem*)pArgs)->pBkmk = rpBkmk;
        bRet = FALSE;
    }

    return bRet;
}



BOOL lcl_FindSection( const SwSectionFmtPtr& rpSectFmt, void* pArgs )
{
    SwSection* pSect = rpSectFmt->GetSection();
@@ -149,17 +143,12 @@ BOOL lcl_FindTable( const SwFrmFmtPtr& rpTableFmt, void* pArgs )
bool SwDoc::GetData( const String& rItem, const String& rMimeType,
                     uno::Any & rValue ) const
{
    // haben wir ueberhaupt das Item vorraetig?
    String sItem( GetAppCharClass().lower( rItem ));
    _FindItem aPara( sItem );
    ((SwBookmarks&)*pBookmarkTbl).ForEach( 0, pBookmarkTbl->Count(),
                                            lcl_FindBookmark, &aPara );
    if( aPara.pBkmk )
    {
        // gefunden, als erfrage die Daten
        return SwServerObject( *aPara.pBkmk ).GetData( rValue, rMimeType );
    }
    ::sw::mark::DdeBookmark* const pBkmk = lcl_FindDdeBookmark(*pMarkManager, rItem);
    if(pBkmk) return SwServerObject(*pBkmk).GetData(rValue, rMimeType);

    // haben wir ueberhaupt das Item vorraetig?
    String sItem(GetAppCharClass().lower(rItem));
    _FindItem aPara( sItem );
    ((SwSectionFmts&)*pSectionFmtTbl).ForEach( 0, pSectionFmtTbl->Count(),
                                                lcl_FindSection, &aPara );
    if( aPara.pSectNd )
@@ -183,16 +172,12 @@ bool SwDoc::GetData( const String& rItem, const String& rMimeType,
bool SwDoc::SetData( const String& rItem, const String& rMimeType,
                     const uno::Any & rValue )
{
    // haben wir ueberhaupt das Item vorraetig?
    String sItem( GetAppCharClass().lower( rItem ));
    _FindItem aPara( sItem );
    pBookmarkTbl->ForEach( 0, pBookmarkTbl->Count(), lcl_FindBookmark, &aPara );
    if( aPara.pBkmk )
    {
        // gefunden, als erfrage die Daten
        return SwServerObject( *aPara.pBkmk ).SetData( rMimeType, rValue );
    }
    ::sw::mark::DdeBookmark* const pBkmk = lcl_FindDdeBookmark(*pMarkManager, rItem);
    if(pBkmk) return SwServerObject(*pBkmk).SetData(rMimeType, rValue);

    // haben wir ueberhaupt das Item vorraetig?
    String sItem(GetAppCharClass().lower(rItem));
    _FindItem aPara( sItem );
    pSectionFmtTbl->ForEach( 0, pSectionFmtTbl->Count(), lcl_FindSection, &aPara );
    if( aPara.pSectNd )
    {
@@ -211,73 +196,48 @@ bool SwDoc::SetData( const String& rItem, const String& rMimeType,



::sfx2::SvLinkSource* SwDoc::CreateLinkSource( const String& rItem )
::sfx2::SvLinkSource* SwDoc::CreateLinkSource(const String& rItem)
{
    // haben wir ueberhaupt das Item vorraetig?
    String sItem( GetAppCharClass().lower( rItem ));
    _FindItem aPara( sItem );
    SwServerObject* pObj = NULL;

    SwServerObject* pObj;
    // bookmarks
    ::sw::mark::DdeBookmark* const pBkmk = lcl_FindDdeBookmark(*pMarkManager, rItem);
    if(pBkmk && pBkmk->IsExpanded()
        && (0 == (pObj = pBkmk->GetRefObject())))
    {
        // mark found, but no link yet -> create hotlink
        pObj = new SwServerObject(*pBkmk);
        pBkmk->SetRefObject(pObj);
        GetLinkManager().InsertServer(pObj);
    }
    if(pObj) return pObj;

    do {    // middle check Loop
        ((SwBookmarks&)*pBookmarkTbl).ForEach( 0, pBookmarkTbl->Count(),
                                                lcl_FindBookmark, &aPara );
        if( aPara.pBkmk && aPara.pBkmk->GetOtherBookmarkPos() )
        {
            // gefunden, also Hotlink einrichten
            // sollten wir schon einer sein?
            if( 0 == (pObj = aPara.pBkmk->GetObject()) )
            {
                pObj = new SwServerObject( *aPara.pBkmk );
                aPara.pBkmk->SetRefObject( pObj );
            }
            else if( pObj->HasDataLinks() )
                return pObj;
            break;
        }
    _FindItem aPara(GetAppCharClass().lower(rItem));
    // sections
    ((SwSectionFmts&)*pSectionFmtTbl).ForEach(0, pSectionFmtTbl->Count(), lcl_FindSection, &aPara);
    if(aPara.pSectNd
        && (0 == (pObj = aPara.pSectNd->GetSection().GetObject())))
    {
        // section found, but no link yet -> create hotlink
        pObj = new SwServerObject( *aPara.pSectNd );
        aPara.pSectNd->GetSection().SetRefObject( pObj );
        GetLinkManager().InsertServer(pObj);
    }
    if(pObj) return pObj;

        ((SwSectionFmts&)*pSectionFmtTbl).ForEach( 0, pSectionFmtTbl->Count(),
                                                    lcl_FindSection, &aPara );
        if( aPara.pSectNd )
        {
            // gefunden, also Hotlink einrichten
            // sollten wir schon einer sein?
            if( 0 == (pObj = aPara.pSectNd->GetSection().GetObject()) )
            {
                pObj = new SwServerObject( *aPara.pSectNd );
                aPara.pSectNd->GetSection().SetRefObject( pObj );
            }
            else if( pObj->HasDataLinks() )
                return pObj;
            break;
        }

        ((SwFrmFmts*)pTblFrmFmtTbl)->ForEach( 0, pTblFrmFmtTbl->Count(),
                                                lcl_FindTable, &aPara );
        if( aPara.pTblNd )
        {
            // gefunden, also Hotlink einrichten
            // sollten wir schon einer sein?
            if( 0 == (pObj = aPara.pTblNd->GetTable().GetObject()) )
            {
                pObj = new SwServerObject( *aPara.pTblNd );
                aPara.pTblNd->GetTable().SetRefObject( pObj );
            }
            else if( pObj->HasDataLinks() )
                return pObj;
            break;
        }
        // bis hierhin, also nicht vorhanden
        return 0;
    } while( FALSE );

    // neu angelegt also ab in die Verwaltung
    GetLinkManager().InsertServer( pObj );
    // tables
    ((SwFrmFmts*)pTblFrmFmtTbl)->ForEach(0, pTblFrmFmtTbl->Count(), lcl_FindTable, &aPara);
    if(aPara.pTblNd
        && (0 == (pObj = aPara.pTblNd->GetTable().GetObject())))
    {
        // table found, but no link yet -> create hotlink
        pObj = new SwServerObject(*aPara.pTblNd);
        aPara.pTblNd->GetTable().SetRefObject(pObj);
        GetLinkManager().InsertServer(pObj);
    }
    return pObj;
}



BOOL SwDoc::SelectServerObj( const String& rStr, SwPaM*& rpPam,
                            SwNodeRange*& rpRange ) const
{
@@ -369,23 +329,19 @@ BOOL SwDoc::SelectServerObj( const String& rStr, SwPaM*& rpPam,
            return FALSE;
    }

    ::sw::mark::DdeBookmark* const pBkmk = lcl_FindDdeBookmark(*pMarkManager, sItem);
    if(pBkmk)
    {
        if(pBkmk->IsExpanded())
            rpPam = new SwPaM(
                pBkmk->GetMarkPos(),
                pBkmk->GetOtherMarkPos());
        return static_cast<bool>(rpPam);
    }

    // alte "Mechanik"
    rCC.toLower( sItem );
    _FindItem aPara( sItem );
    if( pBookmarkTbl->Count() )
    {
        ((SwBookmarks&)*pBookmarkTbl).ForEach( 0, pBookmarkTbl->Count(),
                                            lcl_FindBookmark, &aPara );
        if( aPara.pBkmk )
        {
            // gefunden, also erzeuge einen Bereich
            if( aPara.pBkmk->GetOtherBookmarkPos() )
                // ein aufgespannter Bereich
                rpPam = new SwPaM( aPara.pBkmk->GetBookmarkPos(),
                                    *aPara.pBkmk->GetOtherBookmarkPos() );
            return 0 != rpPam;
        }
    }

    if( pSectionFmtTbl->Count() )
    {
diff --git a/sw/source/core/doc/docedt.cxx b/sw/source/core/doc/docedt.cxx
index 81afd2e..8b4ebe1 100644
--- a/sw/source/core/doc/docedt.cxx
+++ b/sw/source/core/doc/docedt.cxx
@@ -50,7 +50,7 @@
#include <fmtpdsc.hxx>
#include <txtftn.hxx>
#include <acorrect.hxx>     // Autokorrektur
#include <bookmrk.hxx>      // fuer SwBookmark
#include <IMark.hxx>        // fuer SwBookmark
#include <cntfrm.hxx>           // fuers Spell
#include <crsrsh.hxx>
#include <doc.hxx>
@@ -165,7 +165,6 @@ struct _SaveRedline
SV_DECL_PTRARR_DEL( _SaveRedlines, _SaveRedline*, 0, 4 )

SV_IMPL_VARARR( _SaveFlyArr, _SaveFly )
SV_IMPL_PTRARR( SaveBookmarks, SaveBookmark* )
SV_IMPL_PTRARR( _SaveRedlines, _SaveRedline* )

sal_Bool lcl_MayOverwrite( const SwTxtNode *pNode, const xub_StrLen nPos )
@@ -754,7 +753,7 @@ void SwDoc::DeleteSection( SwNode *pNode )
    // dann loesche mal alle Fly's, text::Bookmarks, ...
    DelFlyInRange( aSttIdx, aEndIdx );
    DeleteRedline( *pSttNd, true, USHRT_MAX );
    _DelBookmarks( aSttIdx, aEndIdx );
    _DelBookmarks(aSttIdx, aEndIdx);

    {
        // alle Crsr/StkCrsr/UnoCrsr aus dem Loeschbereich verschieben
@@ -1061,8 +1060,12 @@ bool SwDoc::Move( SwPaM& rPaM, SwPosition& rPos, SwMoveFlags eMvFlags )
        //          here without undo.
        BOOL bDoesUndo = DoesUndo();
        DoUndo( FALSE );
        _DelBookmarks( pStt->nNode, pEnd->nNode, NULL,
                       &pStt->nContent, &pEnd->nContent );
        _DelBookmarks(
            pStt->nNode,
            pEnd->nNode,
            NULL,
            &pStt->nContent,
            &pEnd->nContent);
        DoUndo( bDoesUndo );
    }

@@ -1137,9 +1140,13 @@ bool SwDoc::Move( SwPaM& rPaM, SwPosition& rPos, SwMoveFlags eMvFlags )
    // kopiere alle Bookmarks, die im Move Bereich stehen in ein
    // Array, das alle Angaben auf die Position als Offset speichert.
    // Die neue Zuordung erfolgt nach dem Moven.
    SaveBookmarks aSaveBkmk;
    _DelBookmarks( pStt->nNode, pEnd->nNode, &aSaveBkmk,
                   &pStt->nContent, &pEnd->nContent );
    ::std::vector< ::sw::mark::SaveBookmark> aSaveBkmks;
    _DelBookmarks(
        pStt->nNode,
        pEnd->nNode,
        &aSaveBkmks,
        &pStt->nContent,
        &pEnd->nContent);

    // falls durch die vorherigen Loeschungen (z.B. der Fussnoten) kein
    // Bereich mehr existiert, ist das immernoch ein gueltiger Move!
@@ -1241,9 +1248,14 @@ bool SwDoc::Move( SwPaM& rPaM, SwPosition& rPos, SwMoveFlags eMvFlags )

    // setze jetzt wieder die text::Bookmarks in das Dokument
    *rPaM.GetMark() = *pSavePam->Start();
    for( sal_uInt16 n = 0; n < aSaveBkmk.Count(); ++n )
        aSaveBkmk[n]->SetInDoc( this, rPaM.GetMark()->nNode,
                                    &rPaM.GetMark()->nContent );
    for(
        ::std::vector< ::sw::mark::SaveBookmark>::iterator pBkmk = aSaveBkmks.begin();
        pBkmk != aSaveBkmks.end();
        ++pBkmk)
        pBkmk->SetInDoc(
            this,
            rPaM.GetMark()->nNode,
            &rPaM.GetMark()->nContent);
    *rPaM.GetPoint() = *pSavePam->End();

    // verschiebe die Flys an die neue Position
@@ -1320,8 +1332,8 @@ bool SwDoc::Move( SwNodeRange& rRange, SwNodeIndex& rPos, SwMoveFlags eMvFlags )
    // kopiere alle Bookmarks, die im Move Bereich stehen in ein
    // Array, das alle Angaben auf die Position als Offset speichert.
    // Die neue Zuordung erfolgt nach dem Moven.
    SaveBookmarks aSaveBkmk;
    _DelBookmarks( rRange.aStart, rRange.aEnd, &aSaveBkmk );
    ::std::vector< ::sw::mark::SaveBookmark> aSaveBkmks;
    _DelBookmarks(rRange.aStart, rRange.aEnd, &aSaveBkmks);

    // sicher die absatzgebundenen Flys, damit verschoben werden koennen.
    _SaveFlyArr aSaveFlyArr;
@@ -1354,8 +1366,11 @@ bool SwDoc::Move( SwNodeRange& rRange, SwNodeIndex& rPos, SwMoveFlags eMvFlags )
        _RestFlyInRange( aSaveFlyArr, aIdx, NULL );

    // setze jetzt wieder die text::Bookmarks in das Dokument
    for( sal_uInt16 nCnt = 0; nCnt < aSaveBkmk.Count(); ++nCnt )
        aSaveBkmk[nCnt]->SetInDoc( this, aIdx );
    for(
        ::std::vector< ::sw::mark::SaveBookmark>::iterator pBkmk = aSaveBkmks.begin();
        pBkmk != aSaveBkmks.end();
        ++pBkmk)
        pBkmk->SetInDoc(this, aIdx);

    if( aSavRedlInsPosArr.Count() )
    {
@@ -1723,10 +1738,14 @@ bool SwDoc::Delete( SwPaM & rPam )
        DeleteRedline( rPam, true, USHRT_MAX );

    // loesche und verschiebe erstmal alle "Fly's am Absatz", die in der
    // SSelection liegen
    DelFlyInRange( rPam.GetMark()->nNode, rPam.GetPoint()->nNode );
    _DelBookmarks( pStt->nNode, pEnd->nNode, 0,
                       &pStt->nContent, &pEnd->nContent );
    // Selection liegen
    DelFlyInRange(rPam.GetMark()->nNode, rPam.GetPoint()->nNode);
    _DelBookmarks(
        pStt->nNode,
        pEnd->nNode,
        NULL,
        &pStt->nContent,
        &pEnd->nContent);

    SwNodeIndex aSttIdx( pStt->nNode );
    SwCntntNode * pCNd = aSttIdx.GetNode().GetCntntNode();
@@ -2224,16 +2243,16 @@ bool SwDoc::Replace( SwPaM& rPam, const String& rStr, bool bRegExpRplc )
                StartUndo(UNDO_EMPTY, NULL);

                // Bug 68584 - if any Redline will change (split!) the node
                String sNm; sNm = String::CreateFromInt32( (long)&aDelPam );
                SwBookmark* pBkmk = makeBookmark( aDelPam, KeyCode(), sNm, sNm, UNO_BOOKMARK );
                const ::sw::mark::IMark* pBkmk = getIDocumentMarkAccess()->makeMark( aDelPam, ::rtl::OUString(), IDocumentMarkAccess::UNO_BOOKMARK );

        //JP 06.01.98: MUSS noch optimiert werden!!!
        SetRedlineMode(
               (RedlineMode_t)(nsRedlineMode_t::REDLINE_ON | nsRedlineMode_t::REDLINE_SHOW_INSERT | nsRedlineMode_t::REDLINE_SHOW_DELETE ));
                //JP 06.01.98: MUSS noch optimiert werden!!!
                SetRedlineMode(
                    (RedlineMode_t)(nsRedlineMode_t::REDLINE_ON | nsRedlineMode_t::REDLINE_SHOW_INSERT | nsRedlineMode_t::REDLINE_SHOW_DELETE ));

                *aDelPam.GetPoint() = pBkmk->GetBookmarkPos();
                *aDelPam.GetMark() = *pBkmk->GetOtherBookmarkPos();
                deleteBookmark( getBookmarks().GetPos( pBkmk ));
                *aDelPam.GetPoint() = pBkmk->GetMarkPos();
                if(pBkmk->IsExpanded())
                    *aDelPam.GetMark() = pBkmk->GetOtherMarkPos();
                getIDocumentMarkAccess()->deleteMark(pBkmk);
                pStt = aDelPam.Start();
                pTxtNd = pStt->nNode.GetNode().GetTxtNode();
                nStt = pStt->nContent.GetIndex();
@@ -2306,8 +2325,7 @@ bool SwDoc::Replace( SwPaM& rPam, const String& rStr, bool bRegExpRplc )
                EndUndo(UNDO_EMPTY, NULL);

                // Bug 68584 - if any Redline will change (split!) the node
                String sNm; sNm = String::CreateFromInt32( (long)&aDelPam );
                SwBookmark* pBkmk = makeBookmark( aDelPam, KeyCode(), sNm, sNm, UNO_BOOKMARK );
                const ::sw::mark::IMark* pBkmk = getIDocumentMarkAccess()->makeMark( aDelPam, ::rtl::OUString(), IDocumentMarkAccess::UNO_BOOKMARK );

                SwIndex& rIdx = aDelPam.GetPoint()->nContent;
                rIdx.Assign( 0, 0 );
@@ -2318,9 +2336,10 @@ bool SwDoc::Replace( SwPaM& rPam, const String& rStr, bool bRegExpRplc )
//JP 06.01.98: MUSS noch optimiert werden!!!
SetRedlineMode( eOld );

                *rPam.GetPoint() = pBkmk->GetBookmarkPos();
                *rPam.GetMark() = *pBkmk->GetOtherBookmarkPos();
                deleteBookmark( getBookmarks().GetPos( pBkmk ));
                *rPam.GetPoint() = pBkmk->GetMarkPos();
                if(pBkmk->IsExpanded())
                    *rPam.GetMark() = pBkmk->GetOtherMarkPos();
                getIDocumentMarkAccess()->deleteMark(pBkmk);
            }
            bJoinTxt = sal_False;
        }
diff --git a/sw/source/core/doc/docnew.cxx b/sw/source/core/doc/docnew.cxx
index f469a03..18d6bed 100644
--- a/sw/source/core/doc/docnew.cxx
+++ b/sw/source/core/doc/docnew.cxx
@@ -105,6 +105,7 @@
#include <istyleaccess.hxx>
#include <swstylemanager.hxx>
#include <IGrammarContact.hxx>
#include <MarkManager.hxx>

#include <unochart.hxx>

@@ -218,6 +219,7 @@ SwDoc::SwDoc() :
    aNodes( this ),
    aUndoNodes( this ),
    mpAttrPool(new SwAttrPool(this)),
    pMarkManager(new ::sw::mark::MarkManager(*this)),
    pDfltFrmFmt( new SwFrmFmt( GetAttrPool(), sFrmFmtStr, 0 ) ),
    pEmptyPageFmt( new SwFrmFmt( GetAttrPool(), sEmptyPageStr, pDfltFrmFmt ) ),
    pColumnContFmt( new SwFrmFmt( GetAttrPool(), sColumnCntStr, pDfltFrmFmt ) ),
@@ -231,7 +233,6 @@ SwDoc::SwDoc() :
    pTblFrmFmtTbl( new SwFrmFmts() ),
    pTxtFmtCollTbl( new SwTxtFmtColls() ),
    pGrfFmtCollTbl( new SwGrfFmtColls() ),
    pBookmarkTbl( new SwBookmarks( 0, 16 ) ),
    pTOXTypes( new SwTOXTypes() ),
    pDefTOXBases( new SwDefTOXBase_Impl() ),
    pLayout( 0 ),                   // Rootframe des spezifischen Layouts.
@@ -570,7 +571,7 @@ SwDoc::~SwDoc()

    // in den BookMarks sind Indizies auf den Content. Diese muessen vorm
    // loesche der Nodes geloescht werden.
    pBookmarkTbl->DeleteAndDestroy( 0, pBookmarkTbl->Count() );
    pMarkManager->clearAllMarks();
    DELETEZ( pMacroTable );

    if( pExtInputRing )
@@ -695,7 +696,6 @@ SwDoc::~SwDoc()
    // <--

    delete pPrtData;
    delete pBookmarkTbl;
    delete pNumberFormatter;
    delete pFtnInfo;
    delete pEndNoteInfo;
@@ -830,7 +830,7 @@ void SwDoc::ClearDoc()

    // in den BookMarks sind Indizies auf den Content. Diese muessen vorm
    // loesche der Nodes geloescht werden.
    pBookmarkTbl->DeleteAndDestroy( 0, pBookmarkTbl->Count() );
    pMarkManager->clearAllMarks();
    pTOXTypes->DeleteAndDestroy( 0, pTOXTypes->Count() );

    // create a dummy pagedesc for the layout
diff --git a/sw/source/core/doc/makefile.mk b/sw/source/core/doc/makefile.mk
index 6450933..9e01f6f 100644
--- a/sw/source/core/doc/makefile.mk
+++ b/sw/source/core/doc/makefile.mk
@@ -46,6 +46,7 @@ EXCEPTIONSFILES = \
    $(SLO)$/acmplwrd.obj \
    $(SLO)$/dbgoutsw.obj \
    $(SLO)$/doc.obj \
    $(SLO)$/docbm.obj \
    $(SLO)$/doccomp.obj \
    $(SLO)$/docdraw.obj \
    $(SLO)$/docfmt.obj \
@@ -60,35 +61,34 @@ EXCEPTIONSFILES = \
    $(SLO)$/number.obj \
    $(SLO)$/swstylemanager.obj \
    $(SLO)$/tblcpy.obj \
        $(SLO)$/tblrwcl.obj \
        $(SLO)$/list.obj
    $(SLO)$/tblrwcl.obj \
    $(SLO)$/list.obj

SLOFILES =	$(EXCEPTIONSFILES) \
        $(SLO)$/docbasic.obj \
        $(SLO)$/docbm.obj \
        $(SLO)$/docchart.obj \
        $(SLO)$/doccorr.obj \
        $(SLO)$/docdde.obj \
        $(SLO)$/docdesc.obj \
        $(SLO)$/docedt.obj \
        $(SLO)$/docfld.obj \
        $(SLO)$/docfly.obj \
        $(SLO)$/docftn.obj \
        $(SLO)$/docredln.obj \
        $(SLO)$/docruby.obj \
        $(SLO)$/docstat.obj \
        $(SLO)$/extinput.obj \
        $(SLO)$/fmtcol.obj \
        $(SLO)$/ftnidx.obj \
        $(SLO)$/gctable.obj \
        $(SLO)$/lineinfo.obj \
        $(SLO)$/notxtfrm.obj \
        $(SLO)$/poolfmt.obj \
        $(SLO)$/sortopt.obj \
        $(SLO)$/swserv.obj \
        $(SLO)$/tblafmt.obj \
        $(SLO)$/visiturl.obj \
        $(SLO)$/htmltbl.obj
    $(SLO)$/docbasic.obj \
    $(SLO)$/docchart.obj \
    $(SLO)$/doccorr.obj \
    $(SLO)$/docdde.obj \
    $(SLO)$/docdesc.obj \
    $(SLO)$/docedt.obj \
    $(SLO)$/docfld.obj \
    $(SLO)$/docfly.obj \
    $(SLO)$/docftn.obj \
    $(SLO)$/docredln.obj \
    $(SLO)$/docruby.obj \
    $(SLO)$/docstat.obj \
    $(SLO)$/extinput.obj \
    $(SLO)$/fmtcol.obj \
    $(SLO)$/ftnidx.obj \
    $(SLO)$/gctable.obj \
    $(SLO)$/lineinfo.obj \
    $(SLO)$/notxtfrm.obj \
    $(SLO)$/poolfmt.obj \
    $(SLO)$/sortopt.obj \
    $(SLO)$/swserv.obj \
    $(SLO)$/tblafmt.obj \
    $(SLO)$/visiturl.obj \
    $(SLO)$/htmltbl.obj

# --- Tagets -------------------------------------------------------

diff --git a/sw/source/core/doc/swserv.cxx b/sw/source/core/doc/swserv.cxx
index 9cc0cfb..5df20bf 100644
--- a/sw/source/core/doc/swserv.cxx
+++ b/sw/source/core/doc/swserv.cxx
@@ -40,6 +40,7 @@
#include <swserv.hxx>
#include <swbaslnk.hxx>
#include <mvsave.hxx>
#include <IMark.hxx>
#include <bookmrk.hxx>
#include <pam.hxx>
#include <shellio.hxx>
@@ -57,7 +58,7 @@ SwServerObject::~SwServerObject()


BOOL SwServerObject::GetData( uno::Any & rData,
                                 const String & rMimeType, BOOL )
                                const String & rMimeType, BOOL )
{
    BOOL bRet = FALSE;
    WriterRef xWrt;
@@ -79,17 +80,17 @@ BOOL SwServerObject::GetData( uno::Any & rData,
        switch( eType )
        {
        case BOOKMARK_SERVER:
            if( CNTNT_TYPE.pBkmk->GetOtherBookmarkPos() )
            if( CNTNT_TYPE.pBkmk->IsExpanded() )
            {
                // Bereich aufspannen
                pPam = new SwPaM( CNTNT_TYPE.pBkmk->GetBookmarkPos(),
                                *CNTNT_TYPE.pBkmk->GetOtherBookmarkPos() );
                pPam = new SwPaM( CNTNT_TYPE.pBkmk->GetMarkPos(),
                                CNTNT_TYPE.pBkmk->GetOtherMarkPos() );
            }
            break;

        case TABLE_SERVER:
            pPam = new SwPaM( *CNTNT_TYPE.pTblNd,
                             *CNTNT_TYPE.pTblNd->EndOfSectionNode() );
                            *CNTNT_TYPE.pTblNd->EndOfSectionNode() );
            break;

        case SECTION_SERVER:
@@ -140,19 +141,17 @@ void SwServerObject::SendDataChanged( const SwPosition& rPos )
        const SwStartNode* pNd = 0;
        switch( eType )
        {
        case BOOKMARK_SERVER:
            if( CNTNT_TYPE.pBkmk->GetOtherBookmarkPos() )
            {
                SwBookmark& rBkmk = *CNTNT_TYPE.pBkmk;
                bCall = rBkmk.GetBookmarkPos() < *rBkmk.GetOtherBookmarkPos()
                    ? ( rBkmk.GetBookmarkPos() <= rPos && rPos < *rBkmk.GetOtherBookmarkPos() )
                    : ( *rBkmk.GetOtherBookmarkPos() <= rPos && rPos < rBkmk.GetBookmarkPos() );
            }
            break;
            case BOOKMARK_SERVER:
                if( CNTNT_TYPE.pBkmk->IsExpanded() )
                {
                    bCall = CNTNT_TYPE.pBkmk->GetMarkStart() <= rPos
                        && rPos < CNTNT_TYPE.pBkmk->GetMarkEnd();
                }
                break;

        case TABLE_SERVER:      pNd = CNTNT_TYPE.pTblNd;    break;
        case SECTION_SERVER:    pNd = CNTNT_TYPE.pSectNd;   break;
        case NONE_SERVER: break;
            case TABLE_SERVER:      pNd = CNTNT_TYPE.pTblNd;    break;
            case SECTION_SERVER:    pNd = CNTNT_TYPE.pSectNd;   break;
            case NONE_SERVER: break;
        }
        if( pNd )
        {
@@ -185,18 +184,10 @@ void SwServerObject::SendDataChanged( const SwPaM& rRange )
        switch( eType )
        {
        case BOOKMARK_SERVER:
            if( CNTNT_TYPE.pBkmk->GetOtherBookmarkPos() )
            if(CNTNT_TYPE.pBkmk->IsExpanded())
            {
                SwBookmark& rBkmk = *CNTNT_TYPE.pBkmk;
                const SwPosition* pBkStt = &rBkmk.GetBookmarkPos(),
                                * pBkEnd = rBkmk.GetOtherBookmarkPos();
                if( *pBkStt > *pBkEnd )
                {
                    const SwPosition* pTmp = pBkStt;
                    pBkStt = pBkEnd;
                    pBkEnd = pTmp;
                }
                bCall = *pStt <= *pBkEnd && *pEnd > *pBkStt;
                bCall = *pStt <= CNTNT_TYPE.pBkmk->GetMarkEnd()
                    && *pEnd > CNTNT_TYPE.pBkmk->GetMarkStart();
            }
            break;

@@ -236,17 +227,10 @@ BOOL SwServerObject::IsLinkInServer( const SwBaseLink* pChkLnk ) const
    switch( eType )
    {
    case BOOKMARK_SERVER:
        if( CNTNT_TYPE.pBkmk->GetOtherBookmarkPos() )
        if( CNTNT_TYPE.pBkmk->IsExpanded() )
        {
            SwBookmark& rBkmk = *CNTNT_TYPE.pBkmk;
            const SwPosition* pStt = &rBkmk.GetBookmarkPos(),
                            * pEnd = rBkmk.GetOtherBookmarkPos();
            if( *pStt > *pEnd )
            {
                const SwPosition* pTmp = pStt;
                pStt = pEnd;
                pEnd = pTmp;
            }
            const SwPosition* pStt = &CNTNT_TYPE.pBkmk->GetMarkStart(),
                            * pEnd = &CNTNT_TYPE.pBkmk->GetMarkEnd();

            nSttNd = pStt->nNode.GetIndex();
            nStt = pStt->nContent.GetIndex();
@@ -310,6 +294,31 @@ if( !pChkLnk )
    return FALSE;
}

void SwServerObject::SetNoServer()
{
    if(eType == BOOKMARK_SERVER && CNTNT_TYPE.pBkmk)
    {
        ::sw::mark::DdeBookmark* const pDdeBookmark = dynamic_cast< ::sw::mark::DdeBookmark* >(CNTNT_TYPE.pBkmk);
        if(pDdeBookmark) pDdeBookmark->SetRefObject(NULL);
    }
    CNTNT_TYPE.pBkmk = 0, eType = NONE_SERVER;
}

void SwServerObject::SetDdeBookmark( ::sw::mark::IMark& rBookmark)
{
    ::sw::mark::DdeBookmark* const pDdeBookmark = dynamic_cast< ::sw::mark::DdeBookmark* >(&rBookmark);
    if(pDdeBookmark)
    {
        eType = BOOKMARK_SERVER;
        CNTNT_TYPE.pBkmk = &rBookmark;
        pDdeBookmark->SetRefObject(this);
    }
    else
        OSL_ENSURE(false,
            "SwServerObject::SetNoServer(..)"
            " - setting an bookmark that is not DDE-capable");
}

/*  */


@@ -328,7 +337,6 @@ SwDataChanged::SwDataChanged( SwDoc* pDc, const SwPosition& rPos, USHORT nTyp )
    nCntnt = rPos.nContent.GetIndex();
}


SwDataChanged::~SwDataChanged()
{
    // JP 09.04.96: nur wenn das Layout vorhanden ist ( also waehrend der
@@ -361,7 +369,3 @@ SwDataChanged::~SwDataChanged()
        }
    }
}




diff --git a/sw/source/core/docnode/ndcopy.cxx b/sw/source/core/docnode/ndcopy.cxx
index b0f1839..3f82800 100644
--- a/sw/source/core/docnode/ndcopy.cxx
+++ b/sw/source/core/docnode/ndcopy.cxx
@@ -47,7 +47,7 @@
#include <swtable.hxx>
#include <ddefld.hxx>
#include <undobj.hxx>
#include <bookmrk.hxx>
#include <IMark.hxx>
#include <mvsave.hxx>
#include <cellatr.hxx>
#include <swtblfmt.hxx>
@@ -69,6 +69,144 @@
#endif
#endif

namespace
{
    /*
        The lcl_CopyBookmarks function has to copy bookmarks from the source to the destination nodes
        array. It is called after a call of the _CopyNodes(..) function. But this function does not copy
        every node (at least at the moment: 2/08/2006 ), section start and end nodes will not be copied if the corresponding end/start node is outside the copied pam.
        The lcl_NonCopyCount function counts the number of these nodes, given the copied pam and a node
        index inside the pam.
        rPam is the original source pam, rLastIdx is the last calculated position, rDelCount the number
        of "non-copy" nodes between rPam.Start() and rLastIdx.
        nNewIdx is the new position of interest.
    */

    static void lcl_NonCopyCount( const SwPaM& rPam, SwNodeIndex& rLastIdx, const ULONG nNewIdx, ULONG& rDelCount )
    {
        ULONG nStart = rPam.Start()->nNode.GetIndex();
        ULONG nEnd = rPam.End()->nNode.GetIndex();
        if( rLastIdx.GetIndex() < nNewIdx ) // Moving forward?
        {
            do // count "non-copy" nodes
            {
                SwNode& rNode = rLastIdx.GetNode();
                if( ( rNode.IsSectionNode() && rNode.EndOfSectionIndex() >= nEnd )
                    || ( rNode.IsEndNode() && rNode.StartOfSectionNode()->GetIndex() < nStart ) )
                    ++rDelCount;
                rLastIdx++;
            }
            while( rLastIdx.GetIndex() < nNewIdx );
        }
        else if( rDelCount ) // optimization: if there are no "non-copy" nodes until now,
                             // no move backward needed
        {
            while( rLastIdx.GetIndex() > nNewIdx )
            {
                SwNode& rNode = rLastIdx.GetNode();
                if( ( rNode.IsSectionNode() && rNode.EndOfSectionIndex() >= nEnd )
                    || ( rNode.IsEndNode() && rNode.StartOfSectionNode()->GetIndex() < nStart ) )
                    --rDelCount;
                rLastIdx--;
            }
        }
    }

    static void lcl_SetCpyPos( const SwPosition& rOrigPos,
                        const SwPosition& rOrigStt,
                        const SwPosition& rCpyStt,
                        SwPosition& rChgPos,
                        ULONG nDelCount )
    {
        ULONG nNdOff = rOrigPos.nNode.GetIndex();
        nNdOff -= rOrigStt.nNode.GetIndex();
        nNdOff -= nDelCount;
        xub_StrLen nCntntPos = rOrigPos.nContent.GetIndex();

        // --> OD, AMA 2008-07-07 #b6713815#
        // Always adjust <nNode> at to be changed <SwPosition> instance <rChgPos>
        rChgPos.nNode = nNdOff + rCpyStt.nNode.GetIndex();
        if( !nNdOff )
        // <--
        {
            // dann nur den Content anpassen
            if( nCntntPos > rOrigStt.nContent.GetIndex() )
                nCntntPos = nCntntPos - rOrigStt.nContent.GetIndex();
            else
                nCntntPos = 0;
            nCntntPos = nCntntPos + rCpyStt.nContent.GetIndex();
        }
        rChgPos.nContent.Assign( rChgPos.nNode.GetNode().GetCntntNode(), nCntntPos );
    }

    // TODO: use SaveBookmark (from _DelBookmarks)
    static void lcl_CopyBookmarks(const SwPaM& rPam, SwPaM& rCpyPam)
    {
        const SwDoc* pSrcDoc = rPam.GetDoc();
        SwDoc* pDestDoc =  rCpyPam.GetDoc();
        const IDocumentMarkAccess* const pSrcMarkAccess = pSrcDoc->getIDocumentMarkAccess();
        bool bDoesUndo = pDestDoc->DoesUndo();
        pDestDoc->DoUndo(false);

        const SwPosition &rStt = *rPam.Start(), &rEnd = *rPam.End();
        SwPosition* pCpyStt = rCpyPam.Start();

        typedef ::std::vector< const ::sw::mark::IMark* > mark_vector_t;
        mark_vector_t vMarksToCopy;
        for(IDocumentMarkAccess::const_iterator_t ppMark = pSrcMarkAccess->getMarksBegin();
            ppMark != pSrcMarkAccess->getMarksEnd();
            ppMark++)
        {
            const ::sw::mark::IMark* const pMark = ppMark->get();
            const SwPosition& rMarkStart = pMark->GetMarkStart();
            const SwPosition& rMarkEnd = pMark->GetMarkEnd();
            // only include marks that are in the range and not touching
            // both start and end
            bool bIsNotOnBoundary = pMark->IsExpanded()
                ? (rMarkStart != rStt || rMarkEnd != rEnd)  // rMarkStart != rMarkEnd
                : (rMarkStart != rStt && rMarkEnd != rEnd); // rMarkStart == rMarkEnd
            if(rMarkStart >= rStt && rMarkEnd <= rEnd && bIsNotOnBoundary)
            {
                vMarksToCopy.push_back(pMark);
            }
        }
        // We have to count the "non-copied" nodes..
        SwNodeIndex aCorrIdx(rStt.nNode);
        ULONG nDelCount = 0;
        for(mark_vector_t::const_iterator ppMark = vMarksToCopy.begin();
            ppMark != vMarksToCopy.end();
            ++ppMark)
        {
            const ::sw::mark::IMark* const pMark = *ppMark;
            SwPaM aTmpPam(*pCpyStt);
            lcl_NonCopyCount(rPam, aCorrIdx, pMark->GetMarkPos().nNode.GetIndex(), nDelCount);
            lcl_SetCpyPos( pMark->GetMarkPos(), rStt, *pCpyStt, *aTmpPam.GetPoint(), nDelCount);
            if(pMark->IsExpanded())
            {
                aTmpPam.SetMark();
                lcl_NonCopyCount(rPam, aCorrIdx, pMark->GetOtherMarkPos().nNode.GetIndex(), nDelCount);
                lcl_SetCpyPos(pMark->GetOtherMarkPos(), rStt, *pCpyStt, *aTmpPam.GetMark(), nDelCount);
            }

            ::sw::mark::IMark* const pNewMark = pDestDoc->getIDocumentMarkAccess()->makeMark(
                aTmpPam,
                pMark->GetName(),
                IDocumentMarkAccess::GetType(*pMark));
            // Explicitly try to get exactly the same name as in the source
            // because NavigatorReminders, DdeBookmarks etc. ignore the proposed name
            pDestDoc->getIDocumentMarkAccess()->renameMark(pNewMark, pMark->GetName());
            ::sw::mark::IBookmark* const pNewBookmark =
                dynamic_cast< ::sw::mark::IBookmark* const >(pNewMark);
            if(pNewBookmark) /* copying additional attributes for bookmarks */
            {
                const ::sw::mark::IBookmark* const pOldBookmark = dynamic_cast< const ::sw::mark::IBookmark* >(pMark);
                pNewBookmark->SetKeyCode(pOldBookmark->GetKeyCode());
                pNewBookmark->SetShortName(pOldBookmark->GetShortName());
            }
        }
        pDestDoc->DoUndo(bDoesUndo);
    }
}

// Struktur fuer das Mappen von alten und neuen Frame-Formaten an den
// Boxen und Lines einer Tabelle
@@ -438,133 +576,6 @@ BOOL lcl_ChkFlyFly( SwDoc* pDoc, ULONG nSttNd, ULONG nEndNd,
    return FALSE;
}

/*
    The lcl_CopyBookmarks function has to copy bookmarks from the source to the destination nodes
    array. It is called after a call of the _CopyNodes(..) function. But this function does not copy
    every node (at least at the moment: 2/08/2006 ), section start and end nodes will not be copied if the corresponding end/start node is outside the copied pam.
    The lcl_NonCopyCount function counts the number of these nodes, given the copied pam and a node
    index inside the pam.
    rPam is the original source pam, rLastIdx is the last calculated position, rDelCount the number
    of "non-copy" nodes between rPam.Start() and rLastIdx.
    nNewIdx is the new position of interest.
*/

void lcl_NonCopyCount( const SwPaM& rPam, SwNodeIndex& rLastIdx, const ULONG nNewIdx, ULONG& rDelCount )
{
    ULONG nStart = rPam.Start()->nNode.GetIndex();
    ULONG nEnd = rPam.End()->nNode.GetIndex();
    if( rLastIdx.GetIndex() < nNewIdx ) // Moving forward?
    {
        do // count "non-copy" nodes
        {
            SwNode& rNode = rLastIdx.GetNode();
            if( ( rNode.IsSectionNode() && rNode.EndOfSectionIndex() >= nEnd )
                || ( rNode.IsEndNode() && rNode.StartOfSectionNode()->GetIndex() < nStart ) )
                ++rDelCount;
            rLastIdx++;
        }
        while( rLastIdx.GetIndex() < nNewIdx );
    }
    else if( rDelCount ) // optimization: if there are no "non-copy" nodes until now,
                         // no move backward needed
    {
        while( rLastIdx.GetIndex() > nNewIdx )
        {
            SwNode& rNode = rLastIdx.GetNode();
            if( ( rNode.IsSectionNode() && rNode.EndOfSectionIndex() >= nEnd )
                || ( rNode.IsEndNode() && rNode.StartOfSectionNode()->GetIndex() < nStart ) )
                --rDelCount;
            rLastIdx--;
        }
    }
}

void lcl_SetCpyPos( const SwPosition& rOrigPos,
                    const SwPosition& rOrigStt,
                    const SwPosition& rCpyStt,
                    SwPosition& rChgPos,
                    ULONG nDelCount )
{
    ULONG nNdOff = rOrigPos.nNode.GetIndex();
    nNdOff -= rOrigStt.nNode.GetIndex();
    nNdOff -= nDelCount;
    xub_StrLen nCntntPos = rOrigPos.nContent.GetIndex();

    // --> OD, AMA 2008-07-07 #b6713815#
    // Always adjust <nNode> at to be changed <SwPosition> instance <rChgPos>
    rChgPos.nNode = nNdOff + rCpyStt.nNode.GetIndex();
    if( !nNdOff )
    // <--
    {
        // dann nur den Content anpassen
        if( nCntntPos > rOrigStt.nContent.GetIndex() )
            nCntntPos = nCntntPos - rOrigStt.nContent.GetIndex();
        else
            nCntntPos = 0;
        nCntntPos = nCntntPos + rCpyStt.nContent.GetIndex();
    }
    rChgPos.nContent.Assign( rChgPos.nNode.GetNode().GetCntntNode(), nCntntPos );
}

void lcl_CopyBookmarks( const SwPaM& rPam, SwPaM& rCpyPam )
{
    const SwDoc* pSrcDoc = rPam.GetDoc();
    SwDoc* pDestDoc =  rCpyPam.GetDoc();
    BOOL bDoesUndo = pDestDoc->DoesUndo();
    pDestDoc->DoUndo( FALSE );

    const SwPosition &rStt = *rPam.Start(), &rEnd = *rPam.End();
    SwPosition* pCpyStt = rCpyPam.Start();

    const SwBookmark* pBkmk;
    // We have to count the "non-copied" nodes..
    ULONG nDelCount = 0;
    SwNodeIndex aCorrIdx( rStt.nNode );
    std::vector< const SwBookmark* > aNewBookmarks;
    for( USHORT nCnt = pSrcDoc->getBookmarks().Count(); nCnt; )
    {
        // liegt auf der Position ??
        if( ( pBkmk = pSrcDoc->getBookmarks()[ --nCnt ])->GetBookmarkPos() < rStt
            || pBkmk->GetBookmarkPos() > rEnd )
            continue;

        if( pBkmk->GetOtherBookmarkPos() && ( *pBkmk->GetOtherBookmarkPos() < rStt ||
            *pBkmk->GetOtherBookmarkPos() > rEnd ) )
            continue;

        bool bMayBe = !pBkmk->GetOtherBookmarkPos() || *pBkmk->GetOtherBookmarkPos() == rEnd ||
                      *pBkmk->GetOtherBookmarkPos() == rStt;
        if( bMayBe && ( pBkmk->GetBookmarkPos() == rEnd || pBkmk->GetBookmarkPos() == rStt ) )
            continue;

        aNewBookmarks.push_back( pBkmk );
    }
    std::vector< const SwBookmark* >::iterator pBookmark = aNewBookmarks.begin();
    while( pBookmark != aNewBookmarks.end() )
    {
        SwPaM aTmpPam( *pCpyStt );
        pBkmk = *pBookmark;
        lcl_NonCopyCount( rPam, aCorrIdx, pBkmk->GetBookmarkPos().nNode.GetIndex(), nDelCount );
        lcl_SetCpyPos( pBkmk->GetBookmarkPos(), rStt, *pCpyStt, *aTmpPam.GetPoint(), nDelCount );
        if( pBkmk->GetOtherBookmarkPos() )
        {
            aTmpPam.SetMark();
            lcl_NonCopyCount( rPam, aCorrIdx, pBkmk->GetOtherBookmarkPos()->nNode.GetIndex(), nDelCount );
            lcl_SetCpyPos( *pBkmk->GetOtherBookmarkPos(), rStt, *pCpyStt,
                            *aTmpPam.GetMark(), nDelCount );
        }

        String sNewNm( pBkmk->GetName() );
        if( !pDestDoc->IsCopyIsMove() &&
            USHRT_MAX != pDestDoc->findBookmark( sNewNm ) )
            pDestDoc->makeUniqueBookmarkName( sNewNm );
        pDestDoc->makeBookmark( aTmpPam, pBkmk->GetKeyCode(), sNewNm,
                                pBkmk->GetShortName(), pBkmk->GetType() );
        ++pBookmark;
    }
    pDestDoc->DoUndo( bDoesUndo );
}

void lcl_DeleteRedlines( const SwPaM& rPam, SwPaM& rCpyPam )
{
    const SwDoc* pSrcDoc = rPam.GetDoc();
@@ -1138,7 +1149,7 @@ BOOL SwDoc::_Copy( SwPaM& rPam, SwPosition& rPos,
    aCpyPam.Exchange();

    // dann kopiere noch alle Bookmarks
    if( bCopyBookmarks && getBookmarks().Count() )
    if( bCopyBookmarks && getIDocumentMarkAccess()->getMarksCount() )
        lcl_CopyBookmarks( rPam, aCpyPam );

    if( nsRedlineMode_t::REDLINE_DELETE_REDLINES & eOld )
@@ -1212,7 +1223,7 @@ void SwDoc::CopyWithFlyInFly( const SwNodeRange& rRg,
    SwNodeRange aCpyRange( aSavePos, rInsPos );

    // dann kopiere noch alle Bookmarks
    if( getBookmarks().Count() )
    if( getIDocumentMarkAccess()->getMarksCount() )
    {
        SwPaM aRgTmp( rRg.aStart, rRg.aEnd );
        SwPaM aCpyTmp( aCpyRange.aStart, aCpyRange.aEnd );
diff --git a/sw/source/core/docnode/node.cxx b/sw/source/core/docnode/node.cxx
index 00b4a3e..acd1cea 100644
--- a/sw/source/core/docnode/node.cxx
+++ b/sw/source/core/docnode/node.cxx
@@ -2112,7 +2112,7 @@ const SwTxtNode   *SwNode::GetTxtNode() const
 */
const IDocumentSettingAccess* SwNode::getIDocumentSettingAccess() const { return GetDoc(); }
const IDocumentDeviceAccess* SwNode::getIDocumentDeviceAccess() const { return GetDoc(); }
const IDocumentBookmarkAccess* SwNode::getIDocumentBookmarkAccess() const { return GetDoc(); }
const IDocumentMarkAccess* SwNode::getIDocumentMarkAccess() const { return GetDoc()->getIDocumentMarkAccess(); }
const IDocumentRedlineAccess* SwNode::getIDocumentRedlineAccess() const { return GetDoc(); }
const IDocumentStylePoolAccess* SwNode::getIDocumentStylePoolAccess() const { return GetDoc(); }
const IDocumentLineNumberAccess* SwNode::getIDocumentLineNumberAccess() const { return GetDoc(); }
diff --git a/sw/source/core/docnode/section.cxx b/sw/source/core/docnode/section.cxx
index 57d87d6..3ce0459 100644
--- a/sw/source/core/docnode/section.cxx
+++ b/sw/source/core/docnode/section.cxx
@@ -62,7 +62,6 @@
#include <swserv.hxx>
#include <shellio.hxx>
#include <poolfmt.hxx>
#include <bookmrk.hxx>
#include <expfld.hxx>
#include <swbaslnk.hxx>
#include <mvsave.hxx>
@@ -1322,7 +1321,7 @@ void SwIntrnlSectRefLink::DataChanged( const String& rMimeType,
        //und alles dahinter liegende loeschen
        aIdx--;
        DelFlyInRange( aIdx, aEndIdx );
        _DelBookmarks( aIdx, aEndIdx );
        _DelBookmarks(aIdx, aEndIdx);
        aIdx++;

        pDoc->GetNodes().Delete( aIdx, aEndIdx.GetIndex() - aIdx.GetIndex() );
diff --git a/sw/source/core/edit/eddel.cxx b/sw/source/core/edit/eddel.cxx
index 6fbc5b0..7d8eecc 100644
--- a/sw/source/core/edit/eddel.cxx
+++ b/sw/source/core/edit/eddel.cxx
@@ -39,7 +39,7 @@
#include <pam.hxx>
#include <swundo.hxx>       // fuer die UndoIds
#include <edimp.hxx>
#include <bookmrk.hxx>
#include <IMark.hxx>
#include <docary.hxx>
#include <SwRewriter.hxx>
#ifndef _UNOBJ_HXX
diff --git a/sw/source/core/fields/reffld.cxx b/sw/source/core/fields/reffld.cxx
index 4ee023c..e9e8644 100644
--- a/sw/source/core/fields/reffld.cxx
+++ b/sw/source/core/fields/reffld.cxx
@@ -59,7 +59,7 @@
#include <txtfrm.hxx>
#include <flyfrm.hxx>
#include <pagedesc.hxx>
#include <bookmrk.hxx>
#include <IMark.hxx>
// --> OD 2007-10-18 #i81002#
#include <crossrefbookmark.hxx>
// <--
@@ -252,13 +252,13 @@ void SwGetRefField::SetSubType( USHORT n )
bool SwGetRefField::IsRefToHeadingCrossRefBookmark() const
{
    return GetSubType() == REF_BOOKMARK &&
           bookmarkfunc::isHeadingCrossRefBookmarkName( sSetRefName );
        ::sw::mark::CrossRefHeadingBookmark::IsLegalName(sSetRefName);
}

bool SwGetRefField::IsRefToNumItemCrossRefBookmark() const
{
    return GetSubType() == REF_BOOKMARK &&
           bookmarkfunc::isNumItemCrossRefBookmarkName( sSetRefName );
        ::sw::mark::CrossRefNumItemBookmark::IsLegalName(sSetRefName);
}

const SwTxtNode* SwGetRefField::GetReferencedTxtNode() const
@@ -869,27 +869,21 @@ SwTxtNode* SwGetRefFieldType::FindAnchor( SwDoc* pDoc, const String& rRefMark,

    case REF_BOOKMARK:
        {
            USHORT nPos = pDoc->findBookmark( rRefMark );
            if( USHRT_MAX != nPos )
            IDocumentMarkAccess::const_iterator_t ppMark = pDoc->getIDocumentMarkAccess()->findMark(rRefMark);
            if(ppMark != pDoc->getIDocumentMarkAccess()->getMarksEnd())
            {
                const SwBookmark& rBkmk = *pDoc->getBookmarks()[ nPos ];
                // --> OD 2007-09-27 #i81002# - refactoring
                // simplify by using <SwBookmark::GetBookmarkStart()>
//                const SwPosition* pPos = &rBkmk.GetBookmarkPos();
//                if( rBkmk.GetOtherBookmarkPos() && *pPos > *rBkmk.GetOtherBookmarkPos() )
//                    pPos = rBkmk.GetOtherBookmarkPos();
                const SwPosition* pPos = rBkmk.BookmarkStart();
                // <--
                const ::sw::mark::IMark* pBkmk = ppMark->get();
                const SwPosition* pPos = &pBkmk->GetMarkStart();

                pTxtNd = pDoc->GetNodes()[ pPos->nNode ]->GetTxtNode();
                *pStt = pPos->nContent.GetIndex();
                if( pEnd )
                if(pEnd)
                {
                    if( !rBkmk.GetOtherBookmarkPos() )
                    if(!pBkmk->IsExpanded())
                    {
                        *pEnd = *pStt;
                        // --> OD 2007-10-18 #i81002#
                        if ( dynamic_cast<const SwCrossRefBookmark*>(&rBkmk) != 0 )
                        if(dynamic_cast< ::sw::mark::CrossRefBookmark const *>(pBkmk))
                        {
                            ASSERT( pTxtNd,
                                    "<SwGetRefFieldType::FindAnchor(..)> - node marked by cross-reference bookmark isn't a text node --> crash" );
@@ -897,16 +891,8 @@ SwTxtNode* SwGetRefFieldType::FindAnchor( SwDoc* pDoc, const String& rRefMark,
                        }
                        // <--
                    }
                    else if( rBkmk.GetOtherBookmarkPos()->nNode == rBkmk.GetBookmarkPos().nNode )
                    {
                        // --> OD 2007-09-27 #i81002# - refactoring
                        // simplify by using <SwBookmark::GetBookmarkEnd()>
//                        *pEnd = rBkmk.GetOtherBookmarkPos() == pPos
//                                ? rBkmk.GetBookmarkPos().nContent.GetIndex()
//                                : rBkmk.GetOtherBookmarkPos()->nContent.GetIndex();
                        *pEnd = rBkmk.BookmarkEnd()->nContent.GetIndex();
                        // <--
                    }
                    else if(pBkmk->GetOtherMarkPos().nNode == pBkmk->GetMarkPos().nNode)
                        *pEnd = pBkmk->GetMarkEnd().nContent.GetIndex();
                    else
                        *pEnd = USHRT_MAX;
                }
diff --git a/sw/source/core/inc/MarkManager.hxx b/sw/source/core/inc/MarkManager.hxx
new file mode 100644
index 0000000..d6d8fd6
--- /dev/null
+++ b/sw/source/core/inc/MarkManager.hxx
@@ -0,0 +1,90 @@
/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: $
 * $Revision: $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

#ifndef _SW_BOOKMARK_MARKMANAGER_HXX
#define _SW_BOOKMARK_MARKMANAGER_HXX

#include <IMark.hxx>
#include <IDocumentMarkAccess.hxx>

namespace sw { namespace mark
{
    class MarkManager
        : private ::boost::noncopyable
        , virtual public IDocumentMarkAccess
    {
        public:
            MarkManager(/*[in/out]*/ SwDoc& rDoc);

            // IDocumentMarkAccess
            virtual ::sw::mark::IMark* makeMark(const SwPaM& rPaM, const ::rtl::OUString& rName, IDocumentMarkAccess::MarkType eMark);
            virtual ::sw::mark::IMark* getMarkForTxtNode(const SwTxtNode& rTxtNode, IDocumentMarkAccess::MarkType eMark);

            virtual void repositionMark(::sw::mark::IMark* io_pMark, const SwPaM& rPaM);
            virtual bool renameMark(::sw::mark::IMark* io_pMark, const ::rtl::OUString& rNewName);
            virtual void correctMarksAbsolute(const SwNodeIndex& rOldNode, const SwPosition& rNewPos, const xub_StrLen nOffset);
            virtual void correctMarksRelative(const SwNodeIndex& rOldNode, const SwPosition& rNewPos, const xub_StrLen nOffset);

            virtual void deleteMarks(const SwNodeIndex& rStt, const SwNodeIndex& rEnd, ::std::vector< ::sw::mark::SaveBookmark>* pSaveBkmk, const SwIndex* pSttIdx, const SwIndex* pEndIdx);

            // deleters
            virtual void deleteMark(const const_iterator_t ppMark);
            virtual void deleteMark(const ::sw::mark::IMark* const pMark);
            virtual void clearAllMarks();

            // marks
            virtual const_iterator_t getMarksBegin() const;
            virtual const_iterator_t getMarksEnd() const;
            virtual sal_Int32 getMarksCount() const;
            virtual const_iterator_t findMark(const ::rtl::OUString& rName) const;

            // bookmarks
            virtual const_iterator_t getBookmarksBegin() const;
            virtual const_iterator_t getBookmarksEnd() const;
            virtual sal_Int32 getBookmarksCount() const;
            virtual const_iterator_t findBookmark(const ::rtl::OUString& rName) const;

            // Fieldmarks
            virtual ::sw::mark::IFieldmark* getFieldmarkFor(const SwPosition& rPos) const;
            virtual ::sw::mark::IFieldmark* getFieldmarkBefore(const SwPosition& rPos) const;
            virtual ::sw::mark::IFieldmark* getFieldmarkAfter(const SwPosition& rPos) const;

        private:
            // make names
            ::rtl::OUString getUniqueMarkName(const ::rtl::OUString& rName) const;
            void sortMarks();

            container_t m_vMarks;
            container_t m_vBookmarks;
            container_t m_vFieldmarks;
            SwDoc * const m_pDoc;
    };
}}
#endif
diff --git a/sw/source/core/inc/bookmrk.hxx b/sw/source/core/inc/bookmrk.hxx
new file mode 100644
index 0000000..e134413
--- /dev/null
+++ b/sw/source/core/inc/bookmrk.hxx
@@ -0,0 +1,224 @@
/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: $
 * $Revision: $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

#ifndef _BOOKMRK_HXX
#define _BOOKMRK_HXX

#include <IMark.hxx>
#include <boost/scoped_ptr.hpp>
#include <boost/noncopyable.hpp>

struct SwPosition;  // fwd Decl. wg. UI
class SwDoc;

namespace sw { namespace mark
{
    class MarkBase
        : virtual public IMark
        , private ::boost::noncopyable
    {
        public:
            //getters
            virtual const SwPosition& GetMarkPos() const
                { return *m_pPos1; }
            virtual const ::rtl::OUString& GetName() const
                { return m_aName; }
            virtual bool IsCoveringPosition(const SwPosition& rPos) const
                { return GetMarkStart() <= rPos && rPos <= GetMarkEnd(); };
            virtual const SwPosition& GetOtherMarkPos() const
            {
                OSL_PRECOND(IsExpanded(), "<SwPosition::GetOtherMarkPos(..)> - I have no other Pos set." );
                return *m_pPos2;
            }
            virtual const SwPosition& GetMarkStart() const
            {
                if(!m_pPos2 /* !IsExpanded()*/) return *m_pPos1;
                return *m_pPos1 < *m_pPos2 ? *m_pPos1 : *m_pPos2;
            }
            virtual const SwPosition& GetMarkEnd() const
            {
                if(!m_pPos2 /* !IsExpanded()*/ ) return *m_pPos1;
                return *m_pPos1 > *m_pPos2 ? *m_pPos1 : *m_pPos2;
            }
            virtual bool IsExpanded() const
                { return m_pPos2; }

            //setters
            virtual void SetName(const ::rtl::OUString& rName)
                { m_aName = rName; }
            virtual void SetMarkPos(const SwPosition& rNewPos);
            virtual void SetOtherMarkPos(const SwPosition& rNewPos);
            virtual void ClearOtherMarkPos()
                { m_pPos2.reset(); }

            virtual void Swap()
            {
                if(m_pPos2)
                    m_pPos1.swap(m_pPos2);
            }

            virtual void InitDoc(SwDoc* const)
            {}

            virtual ~MarkBase();
        protected:
            MarkBase(const SwPaM& rPaM,
                const ::rtl::OUString& rName);
            ::boost::scoped_ptr<SwPosition> m_pPos1;
            ::boost::scoped_ptr<SwPosition> m_pPos2;
            ::rtl::OUString m_aName;
            static ::rtl::OUString GenerateNewName(const ::rtl::OUString& rPrefix);
    };

    class NavigatorReminder
        : public MarkBase
        , virtual public IMark
    {
        public:
            NavigatorReminder(const SwPaM& rPaM);
        private:
            static const ::rtl::OUString our_sNamePrefix;
    };

    class UnoMark
        : public MarkBase
    {
        public:
            UnoMark(const SwPaM& rPaM);
        private:
            static const ::rtl::OUString our_sNamePrefix;
    };

    class DdeBookmark
        : public MarkBase
    {
        public:
            DdeBookmark(const SwPaM& rPaM);

            //getters
            const SwServerObject* GetRefObject() const
                { return &m_aRefObj; }
            SwServerObject* GetRefObject()
                { return &m_aRefObj; }

            bool IsServer() const
                { return m_aRefObj.Is(); }

            //setters
            void SetRefObject( SwServerObject* pObj );

            void DeregisterFromDoc(SwDoc* const pDoc);
            virtual ~DdeBookmark();
        private:
            SwServerObjectRef m_aRefObj;
            static const ::rtl::OUString our_sNamePrefix;
    };

    class Bookmark
        : virtual public IBookmark
        , public DdeBookmark
    {
        public:
            Bookmark(const SwPaM& rPaM,
                const KeyCode& rCode,
                const ::rtl::OUString& rName,
                const ::rtl::OUString& rShortName);
            virtual void InitDoc(SwDoc* const io_Doc);

            virtual const ::rtl::OUString& GetShortName() const
                { return m_sShortName; }
            virtual const KeyCode& GetKeyCode() const
                { return m_aCode; }
            virtual void SetShortName(const ::rtl::OUString& rShortName)
                { m_sShortName = rShortName; }
            virtual void SetKeyCode(const KeyCode& rCode)
                { m_aCode = rCode; }
        private:
            KeyCode m_aCode;
            ::rtl::OUString m_sShortName;
    };

    class Fieldmark
        : virtual public IFieldmark
        , public MarkBase
    {
        public:
            Fieldmark(const SwPaM& rPaM);

            // getters
            ::rtl::OUString GetFieldname() const
                { return m_aFieldname; }
            ::rtl::OUString GetFieldHelptext() const
                { return m_aFieldHelptext; }

            // setters
            void SetFieldname(const ::rtl::OUString& aFieldname)
                { m_aFieldname = aFieldname; }
            void SetFieldHelptext(const ::rtl::OUString& aFieldHelptext)
                { m_aFieldHelptext = aFieldHelptext; }
        private:
            //int fftype; // Type: 0 = Text, 1 = Check Box, 2 = List
            //bool ffprot;

            ::rtl::OUString m_aFieldname;
            ::rtl::OUString m_aFieldHelptext;
            static const ::rtl::OUString our_sNamePrefix;

    };

    class TextFieldmark
        : public Fieldmark
    {
        public:
            TextFieldmark(const SwPaM& rPaM);
            virtual void InitDoc(SwDoc* const io_pDoc);
        private:
            //int fftypetxt; // Type of text field: 0 = Regular text, 1 = Number, 2 = Date, 3 = Current date, 4 = Current time, 5 = Calculation
            //int ffmaxlen; // Number of characters for text field. Zero means unlimited.
    };

    class CheckboxFieldmark
        : virtual public ICheckboxFieldmark
        , public Fieldmark
    {
        public:
            CheckboxFieldmark(const SwPaM& rPaM);
            virtual void InitDoc(SwDoc* const io_pDoc);
            bool IsChecked() const;
            void SetChecked(bool checked);
        private:
            bool m_isChecked;
            //bool ffsize; // 0 = Auto, 1=Exact (see ffhps)
            //bool ffrecalc;
            //int ffhps; // Check box size (half-point sizes).
    };

}}
#endif
diff --git a/sw/source/core/inc/crossrefbookmark.hxx b/sw/source/core/inc/crossrefbookmark.hxx
new file mode 100644
index 0000000..3712950
--- /dev/null
+++ b/sw/source/core/inc/crossrefbookmark.hxx
@@ -0,0 +1,104 @@
/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: crossrefbookmark.hxx,v $
 * $Revision: 1.3 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/
#ifndef _CROSSREFBOOKMRK_HXX
#define _CROSSREFBOOKMRK_HXX

#include <IMark.hxx>
#include <bookmrk.hxx>
#include <rtl/ustring.hxx>


namespace sw { namespace mark
{
    class CrossRefBookmark
        : public Bookmark
    {
        public:
            CrossRefBookmark(const SwPaM& rPaM,
                const KeyCode& rCode,
                const ::rtl::OUString& rName,
                const ::rtl::OUString& rShortName,
                const ::rtl::OUString& rPrefix);

            // getters
            virtual const SwPosition& GetOtherMarkPos() const;
            virtual const SwPosition& GetMarkStart() const
                { return *m_pPos1; }
            virtual const SwPosition& GetMarkEnd() const
                { return *m_pPos1; }
            virtual bool IsExpanded() const
                { return false; }

            // setters
            virtual void SetMarkPos(const SwPosition& rNewPos);
            virtual void SetOtherMarkPos(const SwPosition&)
            {
                OSL_PRECOND(false,
                    "<CrossRefBookmark::SetOtherMarkPos(..)>"
                    " - misusage of CrossRefBookmark: other bookmark position isn't allowed to be set." );
            }
            virtual void ClearOtherMarkPos()
            {
                OSL_PRECOND(false,
                    "<SwCrossRefBookmark::ClearOtherMarkPos(..)>"
                    " - misusage of CrossRefBookmark: other bookmark position isn't allowed to be set or cleared." );
            }

            static bool IsLegalName(const ::rtl::OUString& rName);
    };

    class CrossRefHeadingBookmark
        : public CrossRefBookmark
    {
        public:
            CrossRefHeadingBookmark(const SwPaM& rPaM,
                const KeyCode& rCode,
                const ::rtl::OUString& rName,
                const ::rtl::OUString& rShortName);
            static ::rtl::OUString GenerateNewName();
            static bool IsLegalName(const ::rtl::OUString& rName);
            static const ::rtl::OUString our_sNamePrefix;
    };

    class CrossRefNumItemBookmark
        : public CrossRefBookmark
    {
        public:
            CrossRefNumItemBookmark(const SwPaM& rPaM,
                const KeyCode& rCode,
                const ::rtl::OUString& rName,
                const ::rtl::OUString& rShortName);
            static ::rtl::OUString GenerateNewName();
            static bool IsLegalName(const ::rtl::OUString& rName);
            static const ::rtl::OUString our_sNamePrefix;
    };

}}
#endif
diff --git a/sw/source/core/inc/mvsave.hxx b/sw/source/core/inc/mvsave.hxx
index 8cfa17f..0ef3b67 100644
--- a/sw/source/core/inc/mvsave.hxx
+++ b/sw/source/core/inc/mvsave.hxx
@@ -36,11 +36,12 @@
#include <vcl/keycod.hxx>
#endif
#include <svtools/svarray.hxx>
#include <IDocumentBookmarkAccess.hxx>
#include <IDocumentMarkAccess.hxx>
#include <vector>

class SvNumberFormatter;
class SvULongs;
class SwBookmark;
class ::sw::mark::IMark;
class SwDoc;
class SwFmtAnchor;
class SwFrmFmt;
@@ -51,42 +52,44 @@ class SwPaM;
class SwNode;
struct SwPosition;

typedef USHORT SaveBookmarkType;
namespace nsSaveBookmarkType
namespace sw { namespace mark
{
    const SaveBookmarkType BKMK_POS_NONE = 0;
    const SaveBookmarkType BKMK_POS = 1;
    const SaveBookmarkType BKMK_POS_OTHER = 2;
}
    class SaveBookmark
    {
        public:
            SaveBookmark(bool bSavePos,
                bool bSaveOtherPos,
                const ::sw::mark::IMark& rBkmk,
                const SwNodeIndex& rMvPos,
                const SwIndex* pIdx =0);
            void SetInDoc(SwDoc* pDoc,
                const SwNodeIndex&,
                const SwIndex* pIdx =0);
            IDocumentMarkAccess::MarkType GetOriginalBkmType() const
                { return m_eOrigBkmType; }

class SaveBookmark
{
    String  aName, aShortName;
    ULONG nNode1, nNode2;
    xub_StrLen nCntnt1, nCntnt2;
    KeyCode aCode;
    SaveBookmarkType eBkmkType;
    IDocumentBookmarkAccess::BookmarkType eOrigBkmType;

public:
    SaveBookmark( int, const SwBookmark&, const SwNodeIndex&,
                                    const SwIndex* pIdx = 0 );
    void SetInDoc( SwDoc* pDoc, const SwNodeIndex&, const SwIndex* pIdx = 0);
    IDocumentBookmarkAccess::BookmarkType GetOriginalBkmType() const {return eOrigBkmType;}
};

SV_DECL_PTRARR_DEL( SaveBookmarks, SaveBookmark*, 0, 10 )

void _DelBookmarks( const SwNodeIndex& rStt,
                    const SwNodeIndex& rEnd,
                    SaveBookmarks* pSaveBkmk = 0,
                    const SwIndex* pSttIdx = 0,
                    const SwIndex* pEndIdx = 0 );

        private:
            ::rtl::OUString m_aName;
            ::rtl::OUString m_aShortName;
            KeyCode m_aCode;
            bool m_bSavePos;
            bool m_bSaveOtherPos;
            IDocumentMarkAccess::MarkType m_eOrigBkmType;
            ULONG m_nNode1;
            ULONG m_nNode2;
            xub_StrLen m_nCntnt1;
            xub_StrLen m_nCntnt2;
    };
}}

#define SAVEFLY 1
#define SAVEFLY_SPLIT 2

void _DelBookmarks(const SwNodeIndex& rStt,
    const SwNodeIndex& rEnd,
    ::std::vector< ::sw::mark::SaveBookmark> * SaveBkmk =0,
    const SwIndex* pSttIdx =0,
    const SwIndex* pEndIdx =0);
void _SaveCntntIdx( SwDoc* pDoc, ULONG nNode, xub_StrLen nCntnt,
                    SvULongs& rSaveArr, BYTE nSaveFly = 0 );
void _RestoreCntntIdx( SwDoc* pDoc, SvULongs& rSaveArr,
diff --git a/sw/source/core/text/EnhancedPDFExportHelper.cxx b/sw/source/core/text/EnhancedPDFExportHelper.cxx
index 4b9e9ec..614678d 100644
--- a/sw/source/core/text/EnhancedPDFExportHelper.cxx
+++ b/sw/source/core/text/EnhancedPDFExportHelper.cxx
@@ -86,7 +86,7 @@
#include <SwStyleNameMapper.hxx>
#include <itrpaint.hxx>
#include "i18npool/mslangid.hxx"
#include <bookmrk.hxx>
#include <IMark.hxx>
#include <SwNodeNum.hxx>

#include <stack>
@@ -2053,21 +2053,22 @@ void SwEnhancedPDFExportHelper::EnhancedPDFExport()

        if( pPDFExtOutDevData->GetIsExportNamedDestinations() )
        {
        //---> i56629 the iteration to convert the OOo bookmark (#bookmark)
        // into PDF named destination, see section 8.2.1 in PDF 1.4 spec
        // We need:
        // 1. a name for the destination, formed from the standard OOo bookmark name
        // 2. the destination, obtained from where the bookmark destination lies
            const SwBookmarks& rBkmks = mrSh.GetDoc()->getBookmarks();
            //iterate trhrough bookmarks
            sal_uInt16 nBkmks = rBkmks.Count(), nCnt;
            for(nCnt = 0; nCnt < nBkmks; nCnt++)
            //---> i56629 the iteration to convert the OOo bookmark (#bookmark)
            // into PDF named destination, see section 8.2.1 in PDF 1.4 spec
            // We need:
            // 1. a name for the destination, formed from the standard OOo bookmark name
            // 2. the destination, obtained from where the bookmark destination lies
            IDocumentMarkAccess* const pMarkAccess = mrSh.GetDoc()->getIDocumentMarkAccess();
            for(IDocumentMarkAccess::const_iterator_t ppMark = pMarkAccess->getBookmarksBegin();
                ppMark != pMarkAccess->getBookmarksEnd();
                ppMark++)
            {
//get the name
                SwBookmark* pBkmk = rBkmks[ nCnt ];
                //get the name
                const ::sw::mark::IMark* pBkmk = ppMark->get();
                mrSh.SwCrsrShell::ClearMark();
                rtl::OUString sBkName = pBkmk->GetName();
//jump to it

                //jump to it
                JumpToSwMark( &mrSh, sBkName );

                // Destination Rectangle
@@ -2081,8 +2082,8 @@ void SwEnhancedPDFExportHelper::EnhancedPDFExport()
                    pPDFExtOutDevData->CreateNamedDest( sBkName, rDestRect.SVRect(), nDestPageNum );
            }
            mrSh.SwCrsrShell::ClearMark();
            //<--- i56629
        }
//<--- i56629
    }
    else
    {
diff --git a/sw/source/core/text/inftxt.cxx b/sw/source/core/text/inftxt.cxx
index 33571e9..46e74ab 100644
--- a/sw/source/core/text/inftxt.cxx
+++ b/sw/source/core/text/inftxt.cxx
@@ -1204,22 +1204,24 @@ void SwTxtPaintInfo::_DrawBackBrush( const SwLinePortion &rPor ) const
    {
        SwRect aIntersect;
        CalcRect( rPor, &aIntersect, 0 );
        SwTxtNode *pNd = pFrm->GetTxtNode();
        SwBookmark *pBM=NULL;
        if ( aIntersect.HasArea() )
        if(aIntersect.HasArea())
        {
            if (pNd)
            SwTxtNode *pNd = pFrm->GetTxtNode();
            const ::sw::mark::IMark* pFieldmark = NULL;
            if(pNd)
            {
                const SwDoc *doc=pNd->GetDoc();
                if (doc!=NULL)
                if(doc)
                {
                    SwIndex aIndex( pNd, GetIdx() );
                    SwIndex aIndex(pNd, GetIdx());
                    SwPosition aPosition(*pNd, aIndex);
                    pBM=doc->getFieldBookmarkFor(aPosition);
                    pFieldmark=doc->getIDocumentMarkAccess()->getFieldmarkFor(aPosition);
                }
            }
            bool bIsStartMark=(1==GetLen() && CH_TXT_ATR_FIELDSTART==GetTxt().GetChar(GetIdx()));
            if (OnWin() && (pBM!=NULL || bIsStartMark))
            if(pFieldmark) OSL_TRACE("Found Fieldmark");
            if(bIsStartMark) OSL_TRACE("Found StartMark");
            if (OnWin() && (pFieldmark!=NULL || bIsStartMark))
            {
                OutputDevice* pOutDev = (OutputDevice*)GetOut();
                pOutDev->Push( PUSH_LINECOLOR | PUSH_FILLCOLOR );
diff --git a/sw/source/core/text/portxt.cxx b/sw/source/core/text/portxt.cxx
index 83eabfd..17b4e6a 100644
--- a/sw/source/core/text/portxt.cxx
+++ b/sw/source/core/text/portxt.cxx
@@ -52,7 +52,7 @@
#include <IDocumentSettingAccess.hxx>
#include <viewopt.hxx>  // SwViewOptions

#include <bookmrk.hxx>
#include <IMark.hxx>
#include <pam.hxx>
#include <doc.hxx>

@@ -769,9 +769,9 @@ void SwHolePortion::HandlePortion( SwPortionHandler& rPH ) const
    rPH.Text( GetLen(), GetWhichPor() );
}

void SwFieldMarkPortion::Paint( const SwTxtPaintInfo & ) const
void SwFieldMarkPortion::Paint( const SwTxtPaintInfo & rInf) const
{
//  SwTxtPortion::Paint(rInf);
    SwTxtPortion::Paint(rInf);
}

sal_Bool SwFieldMarkPortion::Format( SwTxtFormatInfo & )
@@ -782,19 +782,21 @@ sal_Bool SwFieldMarkPortion::Format( SwTxtFormatInfo & )
}


void SwFieldFormPortion::Paint( const SwTxtPaintInfo &rInf ) const
//FIXME Fieldbk
//void SwFieldFormPortion::Paint( const SwTxtPaintInfo& rInf ) const
void SwFieldFormPortion::Paint( const SwTxtPaintInfo& ) const
{
//  SwTxtPortion::Paint(rInf);
    SwTxtNode *pNd=const_cast<SwTxtNode*>(rInf.GetTxtFrm()->GetTxtNode());
    const SwDoc *doc=pNd->GetDoc();
    SwIndex aIndex( pNd, rInf.GetIdx() );
    SwPosition aPosition(*pNd, aIndex);
    SwFieldBookmark *pBM=doc->getFormFieldBookmarkFor(aPosition);
    ASSERT(pBM!=NULL, "Where is my form field bookmark???");
    bool checked=(pBM!=NULL?pBM->IsChecked():false);
    rInf.DrawCheckBox( *this , checked);
//    const XubString aTxt = XubString::CreateFromAscii("[ ]");
//    rInf.DrawText( aTxt, *this, 0, aTxt.Len(), false );
//    SwTxtNode *pNd=const_cast<SwTxtNode*>(rInf.GetTxtFrm()->GetTxtNode());
//    const SwDoc *doc=pNd->GetDoc();
//    SwIndex aIndex( pNd, rInf.GetIdx() );
//    SwPosition aPosition(*pNd, aIndex);
//    pMark = dynamic_cast< doc->getFieldmarkFor(aPosition);
//    OSL_ENSURE(pMark,
//        "SwFieldFormPortion::Paint(..)"
//        " - Where is my form field bookmark???");

//    bool checked=(pBM!=NULL?pBM->IsChecked():false);
//    rInf.DrawCheckBox(*this , checked);
}

sal_Bool SwFieldFormPortion::Format( SwTxtFormatInfo &rInf )
diff --git a/sw/source/core/txtnode/ndtxt.cxx b/sw/source/core/txtnode/ndtxt.cxx
index 8e8abe7..b9ff68e 100644
--- a/sw/source/core/txtnode/ndtxt.cxx
+++ b/sw/source/core/txtnode/ndtxt.cxx
@@ -88,7 +88,7 @@
#include <dcontact.hxx>
#include <redline.hxx>
#include <doctxm.hxx>
#include <bookmrk.hxx>
#include <IMark.hxx>
#include <scriptinfo.hxx>
#include <istyleaccess.hxx>
#include <SwStyleNameMapper.hxx>
@@ -1033,14 +1033,17 @@ void SwTxtNode::Update( const SwIndex & aPos, xub_StrLen nLen,
                }
            }

        const SwBookmarks& rBkmk = getIDocumentBookmarkAccess()->getBookmarks();
        for( USHORT i = 0; i < rBkmk.Count(); ++i )
        const IDocumentMarkAccess* const pMarkAccess = getIDocumentMarkAccess();
        for(IDocumentMarkAccess::const_iterator_t ppMark = pMarkAccess->getMarksBegin();
            ppMark != pMarkAccess->getMarksEnd();
            ppMark++)
        {
            // Bookmarks must never grow to either side, when
            // editing (directly) to the left or right (#i29942#)!
            // And a bookmark with same start and end must remain
            // to the left of the inserted text (used in XML import).
            const SwPosition* pEnd = rBkmk[i]->BookmarkEnd();
            const ::sw::mark::IMark* const pMark = ppMark->get();
            const SwPosition* pEnd = &pMark->GetMarkEnd();
            pIdx = (SwIndex*)&pEnd->nContent;
            if( this == &pEnd->nNode.GetNode() &&
                aPos.GetIndex() == pIdx->GetIndex() )
diff --git a/sw/source/core/undo/rolbck.cxx b/sw/source/core/undo/rolbck.cxx
index fcf13e0..776dee6 100644
--- a/sw/source/core/undo/rolbck.cxx
+++ b/sw/source/core/undo/rolbck.cxx
@@ -60,7 +60,7 @@
#include <rolbck.hxx>
#include <ndgrf.hxx>            // SwGrfNode
#include <undobj.hxx>           // fuer UndoDelete
#include <bookmrk.hxx>          // fuer SwBookmark
#include <IMark.hxx>            // fuer SwBookmark
#include <charfmt.hxx> // #i27615#
#ifndef _COMCORE_HRC
#include <comcore.hrc>
@@ -70,6 +70,7 @@
#include <undo.hrc>
#endif
#include <svx/brkitem.hxx>
#include <bookmrk.hxx>

SV_IMPL_PTRARR( SwpHstry, SwHstryHintPtr)

@@ -550,166 +551,114 @@ void SwHstryTxtFlyCnt::SetInDoc( SwDoc* pDoc, BOOL )



// JP 21.03.94: jetzt auch die Bookmarks in die History aufnehmen
SwHstryBookmark::SwHstryBookmark( const SwBookmark& rBkmk, BYTE nType )
    : SwHstryHint( HSTRY_BOOKMARK ),
      nNode1( 0 ),
      nNode2( rBkmk.GetOtherBookmarkPos() ? 0 : ULONG_MAX ),
      nCntnt1( 0 ),
      nCntnt2( 0 ),
      nTyp( nType ),
      // --> OD 2007-10-17 #i81002#
      eBkmkType( rBkmk.GetType() )
      // <--
SwHstryBookmark::SwHstryBookmark(
    const ::sw::mark::IMark& rBkmk,
    bool bSavePos,
    bool bSaveOtherPos)
    : SwHstryHint(HSTRY_BOOKMARK)
    , m_aName(rBkmk.GetName())
    , m_aShortName()
    , m_aKeycode()
    , m_nNode(bSavePos ?
        rBkmk.GetMarkPos().nNode.GetIndex() : 0)
    , m_nOtherNode(bSaveOtherPos ?
        rBkmk.GetOtherMarkPos().nNode.GetIndex() : 0)
    , m_nCntnt(bSavePos ?
        rBkmk.GetMarkPos().nContent.GetIndex() : 0)
    , m_nOtherCntnt(bSaveOtherPos ?
        rBkmk.GetOtherMarkPos().nContent.GetIndex() :0)
    , m_bSavePos(bSavePos)
    , m_bSaveOtherPos(bSaveOtherPos)
    , m_bHadOtherPos(rBkmk.IsExpanded())
    , m_eBkmkType(IDocumentMarkAccess::GetType(rBkmk))
{
    aName = rBkmk.GetName();
    aShortName = rBkmk.GetShortName();
    nKeyCode = rBkmk.GetKeyCode().GetCode() | rBkmk.GetKeyCode().GetModifier();

    if( BKMK_POS & nTyp )
    const ::sw::mark::IBookmark* const pBookmark = dynamic_cast< const ::sw::mark::IBookmark* >(&rBkmk);
    if(pBookmark)
    {
        nNode1 = rBkmk.GetBookmarkPos().nNode.GetIndex();
        nCntnt1 = rBkmk.GetBookmarkPos().nContent.GetIndex();
    }
    if( BKMK_OTHERPOS & nTyp )
    {
        nNode2 = rBkmk.GetOtherBookmarkPos()->nNode.GetIndex();
        nCntnt2 = rBkmk.GetOtherBookmarkPos()->nContent.GetIndex();
        m_aKeycode = pBookmark->GetKeyCode();
        m_aShortName = pBookmark->GetShortName();
    }
}


void SwHstryBookmark::SetInDoc( SwDoc* pDoc, BOOL )
void SwHstryBookmark::SetInDoc(SwDoc* pDoc, BOOL)
{
    BOOL bDoesUndo = pDoc->DoesUndo();
    pDoc->DoUndo( FALSE );
    bool bDoesUndo = pDoc->DoesUndo();
    pDoc->DoUndo(false);

    SwNodes& rNds = pDoc->GetNodes();
    IDocumentMarkAccess* pMarkAccess = pDoc->getIDocumentMarkAccess();
    ::std::auto_ptr<SwPaM> pPam;
    ::sw::mark::IMark* pMark = NULL;

    if( ( BKMK_POS == nTyp && ULONG_MAX == nNode2 ) ||
        ( BKMK_POS | BKMK_OTHERPOS ) == nTyp )
    if(m_bSavePos)
    {
        // voellig neu setzen
        SwCntntNode * pCntntNd = rNds[ nNode1 ]->GetCntntNode();
        ASSERT( pCntntNd, "Falscher Node fuer den Bookmark" );
        SwCntntNode* const pCntntNd = rNds[m_nNode]->GetCntntNode();
        OSL_ENSURE(pCntntNd,
            "<SwHstryBookmark::SetInDoc(..)>"
            " - wrong node for a mark");

        // #111660# don't crash when nNode1 doesn't point to content node.
        if( pCntntNd != NULL )
        {
            SwPaM aPam( *pCntntNd, nCntnt1 );
            if( ULONG_MAX != nNode2 )
            {
                aPam.SetMark();
                aPam.GetMark()->nNode = nNode2;
                pCntntNd = rNds[ aPam.GetMark()->nNode ]->GetCntntNode();
                ASSERT( pCntntNd, "Falscher Node fuer den Bookmark" );
                aPam.GetMark()->nContent.Assign( pCntntNd, nCntnt2 );
            }
            // --> OD 2007-10-17 #i81002#
            pDoc->makeBookmark( aPam, KeyCode( nKeyCode ), aName, aShortName, eBkmkType );
            // <--
        }
        if(pCntntNd)
            pPam = ::std::auto_ptr<SwPaM>(new SwPaM(*pCntntNd, m_nCntnt));
    }
    else
    {
        // dann muss das noch vorhandene manipuliert werden
        SwBookmark* const* ppBkmks = pDoc->getBookmarks().GetData();
        for( USHORT n = pDoc->getBookmarks().Count(); n; --n, ++ppBkmks )
            if( (*ppBkmks)->GetName() == aName )
            {
                ULONG nNd;
                USHORT nCnt;
                if( BKMK_POS == nTyp )
                {
                    if( !nNode2 && !(*ppBkmks)->GetOtherBookmarkPos() )
                    {
                        // dann muss der neu angelegt werden.
                        SwPaM aPam( (*ppBkmks)->GetBookmarkPos() );
                        aPam.SetMark();
                        aPam.GetPoint()->nNode = nNode1;
                        aPam.GetPoint()->nContent.Assign(
                                rNds[ nNode1 ]->GetCntntNode(), nCntnt1 );

                        pDoc->deleteBookmark( pDoc->getBookmarks().Count() - n );
                        // --> OD 2007-10-17 #i81002#
                        pDoc->makeBookmark( aPam, KeyCode( nKeyCode ),
                                            aName, aShortName,
                                            eBkmkType );
                        // <--
                        break;

                    }
                    nNd = nNode1;
                    nCnt = nCntnt1;
                    // --> OD 2007-09-27 #i81002# - refactoring
                    // Do not directly manipulate member of <SwBookmark>
//                    pPos = (SwPosition*)&(*ppBkmks)->GetBookmarkPos();
                    SwPosition aNewPos( (*ppBkmks)->GetBookmarkPos() );
                    aNewPos.nNode = nNd;
                    aNewPos.nContent.Assign( rNds[ aNewPos.nNode ]->GetCntntNode(),
                                             nCnt );
                    (*ppBkmks)->SetBookmarkPos( &aNewPos );
                    // <--
                }
                else
                {
                    if( !(*ppBkmks)->GetOtherBookmarkPos() )
                    {
                        // dann muss der neu angelegt werden.
                        SwPaM aPam( (*ppBkmks)->GetBookmarkPos() );
                        aPam.SetMark();
                        aPam.GetMark()->nNode = nNode2;
                        aPam.GetMark()->nContent.Assign(
                                rNds[ nNode2 ]->GetCntntNode(), nCntnt2 );

                        pDoc->deleteBookmark( pDoc->getBookmarks().Count() - n );
                        // --> OD 2007-10-17 #i81002#
                        pDoc->makeBookmark( aPam, KeyCode( nKeyCode ),
                                            aName, aShortName, eBkmkType );
                        // <--
                        break;
                    }
                    nNd = nNode2;
                    nCnt = nCntnt2;
                    // --> OD 2007-09-27 #i81002# - refactoring
                    // Do not directly manipulate member of <SwBookmark>
//                    pPos = (SwPosition*)(*ppBkmks)->GetOtherBookmarkPos();
                    SwPosition aNewPos( *((*ppBkmks)->GetOtherBookmarkPos()) );
                    aNewPos.nNode = nNd;
                    aNewPos.nContent.Assign( rNds[ aNewPos.nNode ]->GetCntntNode(),
                                             nCnt );
                    (*ppBkmks)->SetOtherBookmarkPos( &aNewPos );
                    // <--
                }

                // --> OD 2007-10-10 #i81002# - refactoring
                // Do not directly manipulate member of <SwBookmark>
//                pPos->nNode = nNd;
//                pPos->nContent.Assign( rNds[ pPos->nNode ]->GetCntntNode(),
//                                        nCnt );
                // <--
                break;
            }
        pMark = pMarkAccess->findMark(m_aName)->get();
        pPam = ::std::auto_ptr<SwPaM>(new SwPaM(pMark->GetMarkPos()));
    }

    pDoc->DoUndo( bDoesUndo );
    if(m_bSaveOtherPos)
    {
        SwCntntNode* const pCntntNd = rNds[m_nOtherNode]->GetCntntNode();
        OSL_ENSURE(pCntntNd,
            "<SwHstryBookmark::SetInDoc(..)>"
            " - wrong node for a mark");

        if(pPam.get() != NULL && pCntntNd)
        {
            pPam->SetMark();
            pPam->GetMark()->nNode = m_nOtherNode;
            pPam->GetMark()->nContent.Assign(pCntntNd, m_nOtherCntnt);
        }
    }
    else if(m_bHadOtherPos)
    {
        if(!pMark)
            pMark = pMarkAccess->findMark(m_aName)->get();
        OSL_ENSURE(pMark->IsExpanded(),
            "<SwHstryBookmark::SetInDoc(..)>"
            " - missing pos on old mark");
        pPam->SetMark();
        *pPam->GetMark() = pMark->GetOtherMarkPos();
    }

    if(pPam.get())
    {
        if(pMark)
            pMarkAccess->deleteMark(pMark);
        ::sw::mark::IBookmark* const pBookmark = dynamic_cast< ::sw::mark::IBookmark* >(
            pMarkAccess->makeMark(*pPam, m_aName, m_eBkmkType));
        if(pBookmark)
        {
            pBookmark->SetKeyCode(m_aKeycode);
            pBookmark->SetShortName(m_aShortName);
        }
    }
    pDoc->DoUndo(bDoesUndo);
}


BOOL SwHstryBookmark::IsEqualBookmark( const SwBookmark& rBkmk )
BOOL SwHstryBookmark::IsEqualBookmark(const ::sw::mark::IMark& rBkmk)
{
    return nNode1 == rBkmk.GetBookmarkPos().nNode.GetIndex() &&
           nCntnt1 == rBkmk.GetBookmarkPos().nContent.GetIndex() &&
            aName == rBkmk.GetName() &&
            aShortName == rBkmk.GetShortName() &&
            nKeyCode == (rBkmk.GetKeyCode().GetCode() |
                        rBkmk.GetKeyCode().GetModifier())
            ? TRUE : FALSE;
    return m_nNode == rBkmk.GetMarkPos().nNode.GetIndex()
        && m_nCntnt == rBkmk.GetMarkPos().nContent.GetIndex()
        && m_aName == rBkmk.GetName();
}

const String & SwHstryBookmark::GetName() const
const ::rtl::OUString& SwHstryBookmark::GetName() const
{
    return aName;
    return m_aName;
}

/*************************************************************************/
@@ -1064,12 +1013,11 @@ void SwHistory::Add( const SwFmtColl* pColl, ULONG nNodeIdx, BYTE nWhichNd )
}


// JP 21.03.94: Bookmarks jetzt auch in die History mitaufnehmen
void SwHistory::Add( const SwBookmark& rBkmk, BYTE nTyp )
void SwHistory::Add(const ::sw::mark::IMark& rBkmk, bool bSavePos, bool bSaveOtherPos)
{
    ASSERT( !nEndDiff, "nach REDO wurde die History noch nicht geloescht" );
    SwHstryHint * pHt = new SwHstryBookmark( rBkmk, nTyp );
    Insert( pHt, Count() );
    ASSERT(!nEndDiff, "nach REDO wurde die History noch nicht geloescht");
    SwHstryHint * pHt = new SwHstryBookmark(rBkmk, bSavePos, bSaveOtherPos);
    Insert(pHt, Count());
}


diff --git a/sw/source/core/undo/unbkmk.cxx b/sw/source/core/undo/unbkmk.cxx
index d8733da..86a7797 100644
--- a/sw/source/core/undo/unbkmk.cxx
+++ b/sw/source/core/undo/unbkmk.cxx
@@ -38,7 +38,7 @@
#include "pam.hxx"

#include "undobj.hxx"
#include "bookmrk.hxx"
#include "IMark.hxx"
#include "rolbck.hxx"

#include "SwRewriter.hxx"
@@ -46,13 +46,10 @@
inline SwDoc& SwUndoIter::GetDoc() const { return *pAktPam->GetDoc(); }


SwUndoBookmark::SwUndoBookmark( SwUndoId nUndoId, const SwBookmark& rBkmk )
SwUndoBookmark::SwUndoBookmark( SwUndoId nUndoId, const ::sw::mark::IMark& rBkmk )
    : SwUndo( nUndoId )
{
    BYTE nType = SwHstryBookmark::BKMK_POS;
    if( rBkmk.GetOtherBookmarkPos() )
        nType |= SwHstryBookmark::BKMK_OTHERPOS;
    pHBookmark = new SwHstryBookmark( rBkmk, nType );
    pHBookmark = new SwHstryBookmark(rBkmk, true, rBkmk.IsExpanded());
}


@@ -71,11 +68,13 @@ void SwUndoBookmark::SetInDoc( SwDoc* pDoc )

void SwUndoBookmark::ResetInDoc( SwDoc* pDoc )
{
    const SwBookmarks& rBkmkTbl = pDoc->getBookmarks();
    for( USHORT n = 0; n < rBkmkTbl.Count(); ++n )
        if( pHBookmark->IsEqualBookmark( *rBkmkTbl[ n ] ) )
    IDocumentMarkAccess* const pMarkAccess = pDoc->getIDocumentMarkAccess();
    for(IDocumentMarkAccess::const_iterator_t ppBkmk = pMarkAccess->getMarksBegin();
        ppBkmk != pMarkAccess->getMarksEnd();
        ppBkmk++)
        if( pHBookmark->IsEqualBookmark( **ppBkmk ))
        {
                pDoc->deleteBookmark( n );
                pMarkAccess->deleteMark( ppBkmk );
                break;
        }
}
@@ -89,7 +88,7 @@ SwRewriter SwUndoBookmark::GetRewriter() const
    return aResult;
}

SwUndoDelBookmark::SwUndoDelBookmark( const SwBookmark& rBkmk )
SwUndoDelBookmark::SwUndoDelBookmark( const ::sw::mark::IMark& rBkmk )
    : SwUndoBookmark( UNDO_DELBOOKMARK, rBkmk )
{
}
@@ -107,7 +106,7 @@ void SwUndoDelBookmark::Redo( SwUndoIter& rUndoIter )
}


SwUndoInsBookmark::SwUndoInsBookmark( const SwBookmark& rBkmk )
SwUndoInsBookmark::SwUndoInsBookmark( const ::sw::mark::IMark& rBkmk )
    : SwUndoBookmark( UNDO_INSBOOKMARK, rBkmk )
{
}
diff --git a/sw/source/core/undo/undel.cxx b/sw/source/core/undo/undel.cxx
index d33840b..e3ad5aa 100644
--- a/sw/source/core/undo/undel.cxx
+++ b/sw/source/core/undo/undel.cxx
@@ -152,7 +152,7 @@ SwUndoDelete::SwUndoDelete( SwPaM& rPam, BOOL bFullPara, BOOL bCalledByTblCpy )

        BOOL bDoesUndo = pDoc->DoesUndo();
        pDoc->DoUndo( FALSE );
        _DelBookmarks( pStt->nNode, pEnd->nNode );
        _DelBookmarks(pStt->nNode, pEnd->nNode);
        pDoc->DoUndo( bDoesUndo );
    }
    else
@@ -871,7 +871,7 @@ void SwUndoDelete::Redo( SwUndoIter& rUndoIter )
            DelCntntIndex( *rPam.GetMark(), *rPam.GetPoint(),
                            DelCntntType(nsDelCntntType::DELCNT_ALL | nsDelCntntType::DELCNT_CHKNOCNTNT) );

            _DelBookmarks( rPam.GetMark()->nNode, rPam.GetPoint()->nNode );
            _DelBookmarks(rPam.GetMark()->nNode, rPam.GetPoint()->nNode);
        }
        else
            DelCntntIndex( *rPam.GetMark(), *rPam.GetPoint() );
diff --git a/sw/source/core/undo/undobj.cxx b/sw/source/core/undo/undobj.cxx
index a49e37b..1b7f97b 100644
--- a/sw/source/core/undo/undobj.cxx
+++ b/sw/source/core/undo/undobj.cxx
@@ -44,9 +44,10 @@
#include <undobj.hxx>
#include <rolbck.hxx>
#include <ndnotxt.hxx>
#include <bookmrk.hxx>
#include <IMark.hxx>
#include <mvsave.hxx>
#include <redline.hxx>
#include <crossrefbookmark.hxx>
#ifndef _UNDO_HRC
#include <undo.hrc>
#endif
@@ -711,48 +712,46 @@ void SwUndoSaveCntnt::DelCntntIndex( const SwPosition& rMark,
    // 3. Bookmarks
    if( nsDelCntntType::DELCNT_BKM & nDelCntntType )
    {
        const SwBookmarks& rBkmkTbl = pDoc->getBookmarks();
        if( rBkmkTbl.Count() )
        IDocumentMarkAccess* const pMarkAccess = pDoc->getIDocumentMarkAccess();
        if( pMarkAccess->getMarksCount() )
        {
            const SwBookmark* pBkmk( 0 );

            for( USHORT n = 0; n < rBkmkTbl.Count(); ++n )
            for( USHORT n = 0; n < pMarkAccess->getMarksCount(); ++n )
            {
                BYTE nTyp = 0;
                // --> OD 2007-10-17 #i81002#
                pBkmk = rBkmkTbl[ n ];
                const SwPosition& rBkmkPos( pBkmk->GetBookmarkPos() );
                const SwPosition* pOtherBkmkPos( pBkmk->GetOtherBookmarkPos() );
                bool bSavePos = false;
                bool bSaveOtherPos = false;
                const ::sw::mark::IMark* pBkmk = (pMarkAccess->getMarksBegin() + n)->get();
                if( nsDelCntntType::DELCNT_CHKNOCNTNT & nDelCntntType )
                {
                    if( pStt->nNode <= pBkmk->GetBookmarkPos().nNode &&
                        pBkmk->GetBookmarkPos().nNode < pEnd->nNode )
                        nTyp = SwHstryBookmark::BKMK_POS;
                    if( pBkmk->GetOtherBookmarkPos() &&
                        pStt->nNode <= pBkmk->GetOtherBookmarkPos()->nNode &&
                        pBkmk->GetOtherBookmarkPos()->nNode < pEnd->nNode )
                    nTyp |= SwHstryBookmark::BKMK_OTHERPOS;
                    if( pStt->nNode <= pBkmk->GetMarkPos().nNode &&
                        pBkmk->GetMarkPos().nNode < pEnd->nNode )
                        bSavePos = true;
                    if( pBkmk->IsExpanded() &&
                        pStt->nNode <= pBkmk->GetOtherMarkPos().nNode &&
                        pBkmk->GetOtherMarkPos().nNode < pEnd->nNode )
                        bSaveOtherPos = true;
                }
                else
                {
                    bool bMayBe = false;
                    if( *pStt <= pBkmk->GetBookmarkPos() && pBkmk->GetBookmarkPos() <= *pEnd )
                    bool bMaybe = false;
                    if( *pStt <= pBkmk->GetMarkPos() && pBkmk->GetMarkPos() <= *pEnd )
                    {
                        if( pBkmk->GetBookmarkPos() == *pEnd ||
                            ( *pStt == pBkmk->GetBookmarkPos() && pBkmk->GetOtherBookmarkPos() ) )
                            bMayBe = true;
                        if( pBkmk->GetMarkPos() == *pEnd ||
                            ( *pStt == pBkmk->GetMarkPos() && pBkmk->IsExpanded() ) )
                            bMaybe = true;
                        else
                            nTyp = SwHstryBookmark::BKMK_POS;
                            bSavePos = true;
                    }
                    if( pBkmk->GetOtherBookmarkPos() &&
                        *pStt <= *pBkmk->GetOtherBookmarkPos() && *pBkmk->GetOtherBookmarkPos() <= *pEnd )
                    if( pBkmk->IsExpanded() &&
                        *pStt <= pBkmk->GetOtherMarkPos() && pBkmk->GetOtherMarkPos() <= *pEnd )
                    {
                        if( nTyp || ( *pBkmk->GetOtherBookmarkPos() < *pEnd &&
                            *pBkmk->GetOtherBookmarkPos() > *pStt ) )
                        if( bSavePos || bSaveOtherPos ||
                            ( pBkmk->GetOtherMarkPos() < *pEnd && pBkmk->GetOtherMarkPos() > *pStt ) )
                        {
                            if( bMayBe )
                                nTyp = SwHstryBookmark::BKMK_POS;
                            nTyp |= SwHstryBookmark::BKMK_OTHERPOS;
                            if( bMaybe )
                                bSavePos = true;
                            bSaveOtherPos = true;
                        }
                    }
                    // delete cross-reference bookmark at <pStt>, if only part of
@@ -763,35 +762,37 @@ void SwUndoSaveCntnt::DelCntntIndex( const SwPosition& rMark,
                                        rMark.nNode.GetNode().GetTxtNode() &&
                                        rPoint.nNode.GetNode().GetTxtNode() );
                    // <--
                    if( !nTyp && bDifferentTxtNodesAtMarkAndPoint && pBkmk->IsCrossRefMark() )
                    if( !bSavePos && !bSaveOtherPos && bDifferentTxtNodesAtMarkAndPoint &&
                        dynamic_cast< const ::sw::mark::CrossRefBookmark* >(pBkmk))
                    {
                        if( pStt->nNode == rBkmkPos.nNode &&
                        if( pStt->nNode == pBkmk->GetMarkPos().nNode &&
                            pEnd->nContent.GetIndex() !=
                                pEnd->nNode.GetNode().GetTxtNode()->Len() )
                        {
                            nTyp = SwHstryBookmark::BKMK_POS;
                            bSavePos = true;
                            bSaveOtherPos = false;
                        }
                        // delete cross-reference bookmark at <pEnd>, if only part of
                        // <pStt> text node content is deleted.
                        else if( pEnd->nNode == rBkmkPos.nNode &&
                        else if( pEnd->nNode == pBkmk->GetMarkPos().nNode &&
                            pStt->nContent.GetIndex() != 0 )
                        {
                            nTyp = SwHstryBookmark::BKMK_POS;
                            bSavePos = true;
                            bSaveOtherPos = false;
                        }
                    }
                }
                if( nTyp )
                if( bSavePos || bSaveOtherPos )
                {
                    if( !pHistory )
                        pHistory = new SwHistory;

                    pHistory->Add( *pBkmk, nTyp );
                    if ( ( SwHstryBookmark::BKMK_OTHERPOS |
                           SwHstryBookmark::BKMK_POS ) == nTyp ||
                         ( SwHstryBookmark::BKMK_POS == nTyp
                           && !pOtherBkmkPos ) )
                    pHistory->Add( *pBkmk, bSavePos, bSaveOtherPos );
                    if(bSavePos &&
                        (bSaveOtherPos || !pBkmk->IsExpanded()))
                    {
                        pDoc->deleteBookmark( n-- );
                        pMarkAccess->deleteMark(pMarkAccess->getMarksBegin()+n);
                        n--;
                    }
                }
            }
diff --git a/sw/source/core/unocore/unobkm.cxx b/sw/source/core/unocore/unobkm.cxx
index 62feb7f..e8312d3 100644
--- a/sw/source/core/unocore/unobkm.cxx
+++ b/sw/source/core/unocore/unobkm.cxx
@@ -37,7 +37,8 @@
#include <unoobj.hxx>
#include <unomap.hxx>
#include <unoprnms.hxx>
#include <bookmrk.hxx>
#include <IMark.hxx>
#include <crossrefbookmark.hxx>
#include <doc.hxx>
#include <docary.hxx>
#include <swundo.hxx>
@@ -53,58 +54,58 @@ using namespace ::com::sun::star::text;
using namespace ::com::sun::star::container;
using namespace ::com::sun::star::beans;
using ::rtl::OUString;
using ::rtl::OUStringBuffer;

namespace
{
    static OUString lcl_QuoteName(const OUString& rName)
    {
        static const OUString sStart = OUString(String(SW_RES(STR_START_QUOTE)));
        static const OUString sEnd = OUString(String(SW_RES(STR_END_QUOTE)));
        OUStringBuffer sBuf(64);
        return sBuf.append(sStart).append(rName).append(sEnd).makeStringAndClear();
    }
}

/******************************************************************
 * SwXBookmark
 ******************************************************************/
TYPEINIT1(SwXBookmark, SwClient)
/* -----------------------------13.03.00 12:15--------------------------------

 ---------------------------------------------------------------------------*/
const uno::Sequence< sal_Int8 > & SwXBookmark::getUnoTunnelId()
{
    static uno::Sequence< sal_Int8 > aSeq = ::CreateUnoTunnelId();
    return aSeq;
}
/* -----------------------------10.03.00 18:04--------------------------------

 ---------------------------------------------------------------------------*/
sal_Int64 SAL_CALL SwXBookmark::getSomething( const uno::Sequence< sal_Int8 >& rId )
    throw(uno::RuntimeException)
{
    if( rId.getLength() == 16
        && 0 == rtl_compareMemory( getUnoTunnelId().getConstArray(),
                                        rId.getConstArray(), 16 ) )
        && 0 == rtl_compareMemory( getUnoTunnelId().getConstArray(), rId.getConstArray(), 16 ) )
    {
        return sal::static_int_cast< sal_Int64 >( reinterpret_cast< sal_IntPtr >(this) );
    }
    return 0;
}
/* -----------------10.12.98 10:16-------------------
 *
 * --------------------------------------------------*/
SwXBookmark::SwXBookmark(SwBookmark* pBkm, SwDoc* pDc) :
        aLstnrCntnr( (text::XTextContent*)this ),
        pDoc(pDc),
        bIsDescriptor(0 == pBkm)
{
    if(pBkm)
        pBkm->Add(this);
}
/*-- 10.12.98 10:14:29---------------------------------------------------

  -----------------------------------------------------------------------*/
SwXBookmark::SwXBookmark(::sw::mark::IMark* pBkmk, SwDoc* pDoc)
    : m_aLstnrCntnr((text::XTextContent*)this)
    , m_pDoc(pDoc)
    , m_pRegisteredBookmark(NULL)
{
    registerInMark(pBkmk);
}

SwXBookmark::~SwXBookmark()
{
{ }

}
/*-- 10.12.98 10:14:39---------------------------------------------------

  -----------------------------------------------------------------------*/
void SwXBookmark::attachToRangeEx(const uno::Reference< text::XTextRange > & xTextRange, IDocumentBookmarkAccess::BookmarkType eMark)
                                        throw( lang::IllegalArgumentException, uno::RuntimeException )
void SwXBookmark::attachToRangeEx(
    const uno::Reference< text::XTextRange > & xTextRange,
    IDocumentMarkAccess::MarkType eType)
        throw(lang::IllegalArgumentException, uno::RuntimeException)
{
    if(!bIsDescriptor)
    if(m_pRegisteredBookmark)
        throw uno::RuntimeException();

    uno::Reference<lang::XUnoTunnel> xRangeTunnel( xTextRange, uno::UNO_QUERY);
@@ -114,50 +115,38 @@ void SwXBookmark::attachToRangeEx(const uno::Reference< text::XTextRange > & xTe
    {

        pRange = reinterpret_cast< SwXTextRange * >(
                sal::static_int_cast< sal_IntPtr >( xRangeTunnel->getSomething( SwXTextRange::getUnoTunnelId() )));
            sal::static_int_cast< sal_IntPtr >( xRangeTunnel->getSomething( SwXTextRange::getUnoTunnelId() )));
        pCursor = reinterpret_cast< OTextCursorHelper * >(
                sal::static_int_cast< sal_IntPtr >( xRangeTunnel->getSomething( OTextCursorHelper::getUnoTunnelId() )));
            sal::static_int_cast< sal_IntPtr >( xRangeTunnel->getSomething( OTextCursorHelper::getUnoTunnelId() )));
    }

    SwDoc* pDc = pRange ? (SwDoc*)pRange->GetDoc() : pCursor ?
        (SwDoc*)pCursor->GetDoc() : 0;
    if(pDc)
    {
        pDoc = pDc;
        SwUnoInternalPaM aPam(*pDoc);
        //das muss jetzt sal_True liefern
        m_pDoc = pDc;
        SwUnoInternalPaM aPam(*m_pDoc);
        SwXTextRange::XTextRangeToSwPaM(aPam, xTextRange);
        UnoActionContext aCont(pDoc);
        SwBookmark* pBkm = 0;
        UnoActionContext aCont(m_pDoc);
        if(!m_aName.Len())
             m_aName =  OUString::createFromAscii("Bookmark");
        if(eType == IDocumentMarkAccess::BOOKMARK && ::sw::mark::CrossRefNumItemBookmark::IsLegalName(m_aName))
            eType = IDocumentMarkAccess::CROSSREF_NUMITEM_BOOKMARK;
        else if(eType == IDocumentMarkAccess::BOOKMARK && ::sw::mark::CrossRefHeadingBookmark::IsLegalName(m_aName))
            eType = IDocumentMarkAccess::CROSSREF_HEADING_BOOKMARK;
        registerInMark(m_pDoc->getIDocumentMarkAccess()->makeMark(aPam, m_aName, eType));
        // --> OD 2007-10-23 #i81002#
        // Check, if bookmark has been created.
        // E.g., the creation of a cross-reference bookmark is suppress,
        // if the PaM isn't a valid one for cross-reference bookmarks.
        if(!m_pRegisteredBookmark)
        {
            if(!m_aName.Len())
                 m_aName =  C2S("Bookmark");
            // --> OD 2007-10-23 #i81002#
            // determine bookmark type due to its proposed name
            if( eMark == IDocumentBookmarkAccess::BOOKMARK &&
                pDoc->isCrossRefBookmarkName( m_aName ) )
                eMark = IDocumentBookmarkAccess::CROSSREF_BOOKMARK;
            // <--
            if( USHRT_MAX != pDoc->findBookmark(m_aName) )
                pDoc->makeUniqueBookmarkName( m_aName );
            KeyCode aCode;
            pBkm = pDoc->makeBookmark( aPam, aCode, m_aName, aEmptyStr, eMark);
            // --> OD 2007-10-23 #i81002#
            // Check, if bookmark has been created.
            // E.g., the creation of a cross-reference bookmark is suppress,
            // if the PaM isn't a valid one for cross-reference bookmarks.
            if ( pBkm )
            {
                pBkm->Add(this);
            }
            else
            {
                ASSERT( false,
                        "<SwXBookmark::attachToRange(..)> - could not create <SwBookmark> instance." );
            }
            // <--
            bIsDescriptor = sal_False;
            OSL_ENSURE(false,
                "<SwXBookmark::attachToRange(..)>"
                " - could not create Mark.");
            throw lang::IllegalArgumentException();
        }
        // <--
    }
    else
        throw lang::IllegalArgumentException();
@@ -166,293 +155,133 @@ void SwXBookmark::attachToRangeEx(const uno::Reference< text::XTextRange > & xTe
void SwXBookmark::attachToRange(const uno::Reference< text::XTextRange > & xTextRange)
    throw( lang::IllegalArgumentException, uno::RuntimeException )
{
    attachToRangeEx(xTextRange, IDocumentBookmarkAccess::BOOKMARK);
    attachToRangeEx(xTextRange, IDocumentMarkAccess::BOOKMARK);
}

SwXFieldmark::SwXFieldmark(bool _isReplacementObject, SwBookmark* pBkm, SwDoc* pDc)
    : SwXFieldmark_BASE(pBkm, pDc)
    , isReplacementObject(_isReplacementObject)
{ }


void SwXFieldmark::attachToRange(const uno::Reference< text::XTextRange > & xTextRange)
    throw( lang::IllegalArgumentException, uno::RuntimeException )
{
    attachToRangeEx(xTextRange, (isReplacementObject?IDocumentBookmarkAccess::FORM_FIELDMARK_NO_TEXT:IDocumentBookmarkAccess::FORM_FIELDMARK_TEXT));
}

::rtl::OUString SwXFieldmark::getDescription(void) throw( ::com::sun::star::uno::RuntimeException )
{
    vos::OGuard aGuard(Application::GetSolarMutex());
    SwFieldBookmark* pBkm = (SwFieldBookmark*)GetBookmark();
    OUString sRet;
    if(pBkm)
        sRet = pBkm->GetFFHelpText();
    /* //@TODO implement...
    else if(bIsDescriptor)
        sRet = m_aName;
        */
    else
        throw uno::RuntimeException();
    return sRet;
}

::sal_Int16 SAL_CALL SwXFieldmark::getType(  ) throw (::com::sun::star::uno::RuntimeException)
{
    vos::OGuard aGuard(Application::GetSolarMutex());
    SwFieldBookmark* pBkm = (SwFieldBookmark*)GetBookmark();
    ::sal_Int16 sRet;
    if(pBkm)
        sRet = static_cast<sal_Int16>(pBkm->GetFieldType());
    /* //@TODO implement...
    else if(bIsDescriptor)
        sRet = m_aName;
        */
    else
        throw uno::RuntimeException();
    return sRet;
}

::sal_Int16 SAL_CALL SwXFieldmark::getRes(  ) throw (::com::sun::star::uno::RuntimeException)
{
    vos::OGuard aGuard(Application::GetSolarMutex());
    SwFieldBookmark* pBkm = (SwFieldBookmark*)GetBookmark();
    ::sal_Int16 sRet;
    if(pBkm)
        sRet = static_cast<sal_Int16>(pBkm->GetFFRes());
    /* //@TODO implement...
    else if(bIsDescriptor)
        sRet = m_aName;
        */
    else
        throw uno::RuntimeException();
    return sRet;
}


void SAL_CALL SwXFieldmark::setType( ::sal_Int16 fieldType ) throw (::com::sun::star::uno::RuntimeException)
{
    vos::OGuard aGuard(Application::GetSolarMutex());
    SwFieldBookmark* pBkm = (SwFieldBookmark*)GetBookmark();
    if (pBkm)
        pBkm->SetFieldType(fieldType);
    else
        throw uno::RuntimeException();
}

void SAL_CALL SwXFieldmark::setRes( ::sal_Int16 res ) throw (::com::sun::star::uno::RuntimeException)
{
    vos::OGuard aGuard(Application::GetSolarMutex());
    SwFieldBookmark* pBkm = (SwFieldBookmark*)GetBookmark();
    if (pBkm)
        pBkm->SetFFRes(res);
    else
        throw uno::RuntimeException();
}

void SAL_CALL SwXFieldmark::setDescription( const ::rtl::OUString& description ) throw (::com::sun::star::uno::RuntimeException)
{
    vos::OGuard aGuard(Application::GetSolarMutex());
    SwFieldBookmark* pBkm = (SwFieldBookmark*)GetBookmark();
    if (pBkm)
        pBkm->SetFFHelpText(description);
    else
        throw uno::RuntimeException();
}



/*

::com::sun::star::uno::Any SAL_CALL SwXFieldmark::queryInterface( ::com::sun::star::uno::Type const & rType ) throw (::com::sun::star::uno::RuntimeException)
{
        return SwXBookmark::queryInterface(rType);
}
*/


/* -----------------18.02.99 13:31-------------------
 *
 * --------------------------------------------------*/
void SwXBookmark::attach(const uno::Reference< text::XTextRange > & xTextRange)
                            throw( lang::IllegalArgumentException, uno::RuntimeException )
    throw( lang::IllegalArgumentException, uno::RuntimeException )
{
    vos::OGuard aGuard(Application::GetSolarMutex());
    attachToRange( xTextRange );
}
/*-- 10.12.98 10:14:39---------------------------------------------------

  -----------------------------------------------------------------------*/
uno::Reference< text::XTextRange >  SwXBookmark::getAnchor(void) throw( uno::RuntimeException )
uno::Reference< text::XTextRange > SwXBookmark::getAnchor(void)
    throw( uno::RuntimeException )
{
    vos::OGuard aGuard(Application::GetSolarMutex());
    uno::Reference< text::XTextRange >  aRet;
    SwBookmark* pBkm = GetBookmark();

    if(pBkm)
    {
        const SwPosition& rPos = pBkm->GetBookmarkPos();
        const SwPosition* pMarkPos = pBkm->GetOtherBookmarkPos();

        aRet = SwXTextRange::CreateTextRangeFromPosition(pDoc, rPos, pMarkPos);
    }
    uno::Reference< text::XTextRange > aRet;
    if(m_pRegisteredBookmark)
        aRet = SwXTextRange::CreateTextRangeFromPosition(
            m_pDoc,
            m_pRegisteredBookmark->GetMarkPos(),
            m_pRegisteredBookmark->IsExpanded() ? &m_pRegisteredBookmark->GetOtherMarkPos() : NULL);
    else
        throw uno::RuntimeException();
    return aRet;


}
/*-- 10.12.98 10:14:40---------------------------------------------------

  -----------------------------------------------------------------------*/
void SwXBookmark::dispose(void) throw( uno::RuntimeException )
void SwXBookmark::dispose(void)
    throw( uno::RuntimeException )
{
    vos::OGuard aGuard(Application::GetSolarMutex());
    SwBookmark* pBkm = GetBookmark();
    if(pBkm)
        GetDoc()->deleteBookmark(getName());
    if(m_pRegisteredBookmark)
        GetDoc()->getIDocumentMarkAccess()->deleteMark(m_pRegisteredBookmark);
    else
        throw uno::RuntimeException();
}
/*-- 10.12.98 10:14:40---------------------------------------------------

  -----------------------------------------------------------------------*/
void SwXBookmark::addEventListener(const uno::Reference< lang::XEventListener > & aListener)
                                                throw( uno::RuntimeException )
    throw( uno::RuntimeException )
{
    if(!GetRegisteredIn())
    if(!m_pRegisteredBookmark)
        throw uno::RuntimeException();
    aLstnrCntnr.AddListener(aListener);
    m_aLstnrCntnr.AddListener(aListener);
}
/*-- 10.12.98 10:14:41---------------------------------------------------

  -----------------------------------------------------------------------*/
void SwXBookmark::removeEventListener(const uno::Reference< lang::XEventListener > & aListener)
    throw( uno::RuntimeException )
{
    if(!GetRegisteredIn() || !aLstnrCntnr.RemoveListener(aListener))
    if(!m_pRegisteredBookmark || !m_aLstnrCntnr.RemoveListener(aListener))
        throw uno::RuntimeException();
}
/*-- 10.12.98 10:14:41---------------------------------------------------

  -----------------------------------------------------------------------*/
OUString SwXBookmark::getName(void) throw( uno::RuntimeException )
OUString SwXBookmark::getName(void)
    throw(uno::RuntimeException)
{
    vos::OGuard aGuard(Application::GetSolarMutex());
    SwBookmark* pBkm = GetBookmark();
    OUString sRet;
    if(pBkm)
        sRet = pBkm->GetName();
    else if(bIsDescriptor)
        sRet = m_aName;
    if(m_pRegisteredBookmark)
        sRet = m_pRegisteredBookmark->GetName();
    else
        throw uno::RuntimeException();
        sRet = m_aName;
    return sRet;
}
/*-- 10.12.98 10:14:42---------------------------------------------------

  -----------------------------------------------------------------------*/
void SwXBookmark::setName(const OUString& rName) throw( uno::RuntimeException )
void SwXBookmark::setName(const OUString& rName)
    throw(uno::RuntimeException)
{
    vos::OGuard aGuard(Application::GetSolarMutex());
    SwBookmark* pBkm = GetBookmark();
    String sBkName(rName);
    String sOldName = getName();
    if(sOldName != sBkName && pBkm && USHRT_MAX == pDoc->findBookmark(sBkName))
    {
        KeyCode aCode;
        String sShortName;
        SwPaM aPam(pBkm->GetBookmarkPos());
        if(pBkm->GetOtherBookmarkPos())
        {
            aPam.SetMark();
            *aPam.GetMark() = *pBkm->GetOtherBookmarkPos();
        }

        SwRewriter aRewriter;

        {
            String aStr(SW_RES(STR_START_QUOTE));

            aStr += sOldName;
            aStr += String(SW_RES(STR_END_QUOTE));

            aRewriter.AddRule(UNDO_ARG1, aStr);
        }

        aRewriter.AddRule(UNDO_ARG2, SW_RES(STR_YIELDS));

        {
            String aStr(SW_RES(STR_START_QUOTE));

            aStr += String(rName);
            aStr += String(SW_RES(STR_END_QUOTE));
            aRewriter.AddRule(UNDO_ARG3, aStr);
        }

        pDoc->StartUndo(UNDO_BOOKMARK_RENAME, &aRewriter);

        // --> OD 2007-10-23 #i81002#
        SwBookmark* pMark = pDoc->makeBookmark( aPam, aCode,
                                                sBkName, sShortName,
                                                pBkm->GetType() );
        // <--
        pMark->Add(this);
        GetDoc()->deleteBookmark( sOldName );

        pDoc->EndUndo(UNDO_BOOKMARK_RENAME, NULL);
    }
    else if(bIsDescriptor)
        m_aName = sBkName;
    else
    if(!m_pRegisteredBookmark)
        m_aName = rName;
    if(!m_pRegisteredBookmark || getName() == rName)
        return;
    IDocumentMarkAccess* const pMarkAccess = m_pDoc->getIDocumentMarkAccess();
    if(pMarkAccess->findMark(rName) != pMarkAccess->getMarksEnd())
        throw uno::RuntimeException();

    SwPaM aPam(m_pRegisteredBookmark->GetMarkPos());
    if(m_pRegisteredBookmark->IsExpanded())
    {
        aPam.SetMark();
        *aPam.GetMark() = m_pRegisteredBookmark->GetOtherMarkPos();
    }

    SwRewriter aRewriter;
    aRewriter.AddRule(UNDO_ARG1, lcl_QuoteName(getName()));
    aRewriter.AddRule(UNDO_ARG2, SW_RES(STR_YIELDS));
    aRewriter.AddRule(UNDO_ARG3, lcl_QuoteName(rName));

    m_pDoc->StartUndo(UNDO_BOOKMARK_RENAME, &aRewriter);
    pMarkAccess->renameMark(m_pRegisteredBookmark, rName);
    m_pDoc->EndUndo(UNDO_BOOKMARK_RENAME, NULL);
}

/* -----------------02.11.99 11:30-------------------

 --------------------------------------------------*/
OUString SwXBookmark::getImplementationName(void) throw( uno::RuntimeException )
{
    return C2U("SwXBookmark");
    return OUString::createFromAscii("SwXBookmark");
}
/* -----------------02.11.99 11:30-------------------

 --------------------------------------------------*/
sal_Bool SwXBookmark::supportsService(const OUString& rServiceName) throw( uno::RuntimeException )
sal_Bool SwXBookmark::supportsService(const OUString& rServiceName)
    throw( uno::RuntimeException )
{
    return !rServiceName.compareToAscii("com.sun.star.text.Bookmark") ||
                !rServiceName.compareToAscii("com.sun.star.document.LinkTarget") ||
                    !rServiceName.compareToAscii("com.sun.star.text.TextContent");
;
}
/* -----------------02.11.99 11:30-------------------

 --------------------------------------------------*/
uno::Sequence< OUString > SwXBookmark::getSupportedServiceNames(void) throw( uno::RuntimeException )
uno::Sequence< OUString > SwXBookmark::getSupportedServiceNames(void)
    throw( uno::RuntimeException )
{
    uno::Sequence< OUString > aRet(3);
    OUString* pArr = aRet.getArray();
    pArr[0] = C2U("com.sun.star.text.Bookmark");
    pArr[1] = C2U("com.sun.star.document.LinkTarget");
    pArr[2] = C2U("com.sun.star.text.TextContent");
    aRet[0] = OUString::createFromAscii("com.sun.star.text.Bookmark");
    aRet[1] = OUString::createFromAscii("com.sun.star.document.LinkTarget");
    aRet[2] = OUString::createFromAscii("com.sun.star.text.TextContent");
    return aRet;
}
/*-- 10.12.98 10:14:42---------------------------------------------------

  -----------------------------------------------------------------------*/
void    SwXBookmark::Modify( SfxPoolItem *pOld, SfxPoolItem *pNew)
void SwXBookmark::Modify(SfxPoolItem *pOld, SfxPoolItem *pNew)
{
    ClientModify(this, pOld, pNew);
    if(!GetBookmark())
    if(!GetRegisteredIn())
    {
        pDoc = 0;
        aLstnrCntnr.Disposing();
        m_pRegisteredBookmark = NULL;
        m_pDoc = NULL;
        m_aLstnrCntnr.Disposing();
    }
}
/*-- 30.03.99 16:02:58---------------------------------------------------

  -----------------------------------------------------------------------*/
uno::Reference< beans::XPropertySetInfo >  SwXBookmark::getPropertySetInfo(void) throw( uno::RuntimeException )
uno::Reference< beans::XPropertySetInfo >  SwXBookmark::getPropertySetInfo(void)
    throw( uno::RuntimeException )
{
    static uno::Reference< beans::XPropertySetInfo >  aRef;
    if(!aRef.is())
@@ -467,20 +296,20 @@ uno::Reference< beans::XPropertySetInfo >  SwXBookmark::getPropertySetInfo(void)
    }
    return aRef;
}
/*-- 30.03.99 16:02:59---------------------------------------------------

  -----------------------------------------------------------------------*/
void SwXBookmark::setPropertyValue(const OUString& PropertyName, const uno::Any& /*aValue*/)
    throw( beans::UnknownPropertyException, beans::PropertyVetoException,
        lang::IllegalArgumentException, lang::WrappedTargetException, uno::RuntimeException )
    throw( beans::UnknownPropertyException,
        beans::PropertyVetoException,
        lang::IllegalArgumentException,
        lang::WrappedTargetException,
        uno::RuntimeException )
{
    // nothing to set here
    throw IllegalArgumentException ( OUString ( RTL_CONSTASCII_USTRINGPARAM ( "Property is read-only: " ) ) + PropertyName, static_cast < cppu::OWeakObject * > ( this ), 0 );
    //hier gibt es nichts zu setzen
}
/*-- 30.03.99 16:02:59---------------------------------------------------

  -----------------------------------------------------------------------*/
uno::Any SwXBookmark::getPropertyValue(const OUString& rPropertyName) throw( beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException )
uno::Any SwXBookmark::getPropertyValue(const OUString& rPropertyName)
    throw( beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException )
{
    uno::Any aRet;
    if(!SwXParagraph::getDefaultTextContentValue(aRet, rPropertyName))
@@ -490,33 +319,91 @@ uno::Any SwXBookmark::getPropertyValue(const OUString& rPropertyName) throw( bea
    }
    return aRet;
}
/*-- 30.03.99 16:02:59---------------------------------------------------

  -----------------------------------------------------------------------*/
void SwXBookmark::addPropertyChangeListener(const OUString& /*PropertyName*/,
    const uno::Reference< beans::XPropertyChangeListener > & /*aListener*/)
        throw( beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException )
{
}
/*-- 30.03.99 16:02:59---------------------------------------------------
{ }

  -----------------------------------------------------------------------*/
void SwXBookmark::removePropertyChangeListener(const OUString& /*PropertyName*/,
    const uno::Reference< beans::XPropertyChangeListener > & /*aListener*/)
            throw( beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException )
{
}
/*-- 30.03.99 16:03:00---------------------------------------------------
{ }

  -----------------------------------------------------------------------*/
void SwXBookmark::addVetoableChangeListener(const OUString& /*PropertyName*/,
    const uno::Reference< beans::XVetoableChangeListener > & /*aListener*/)
            throw( beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException )
{
}
/*-- 30.03.99 16:03:00---------------------------------------------------
        throw( beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException )
{ }

  -----------------------------------------------------------------------*/
void SwXBookmark::removeVetoableChangeListener(const OUString& /*PropertyName*/, const uno::Reference< beans::XVetoableChangeListener > & /*aListener*/) throw( beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException )
void SwXBookmark::removeVetoableChangeListener(const OUString& /*PropertyName*/, const uno::Reference< beans::XVetoableChangeListener > & /*aListener*/)
    throw( beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException )
{ }

SwXFieldmark::SwXFieldmark(bool _isReplacementObject, ::sw::mark::IMark* pBkm, SwDoc* pDc)
    : SwXFieldmark_BASE(pBkm, pDc)
    , isReplacementObject(_isReplacementObject)
{ }

void SwXFieldmark::attachToRange(const uno::Reference< text::XTextRange > & xTextRange)
    throw( lang::IllegalArgumentException, uno::RuntimeException )
{
    attachToRangeEx(xTextRange, (isReplacementObject?IDocumentMarkAccess::CHECKBOX_FIELDMARK:IDocumentMarkAccess::TEXT_FIELDMARK));
}

::rtl::OUString SwXFieldmark::getDescription(void) throw( ::com::sun::star::uno::RuntimeException )
{
    vos::OGuard aGuard(Application::GetSolarMutex());
//        TODO implement...
//        if(!GetBookmark())
    ::sw::mark::IFieldmark const * const pMark =
        dynamic_cast< ::sw::mark::IFieldmark const * const>(GetBookmark());
    if(!pMark)
        throw uno::RuntimeException();
    return pMark->GetFieldHelptext();
}

::sal_Int16 SAL_CALL SwXFieldmark::getType() throw (::com::sun::star::uno::RuntimeException)
{
    vos::OGuard aGuard(Application::GetSolarMutex());
    ::sw::mark::ICheckboxFieldmark const * const pAsCheckbox =
        dynamic_cast< ::sw::mark::ICheckboxFieldmark const * const>(GetBookmark());
    if(pAsCheckbox)
        return 1;
    return 0;
}

::sal_Int16 SAL_CALL SwXFieldmark::getRes() throw (::com::sun::star::uno::RuntimeException)
{
    vos::OGuard aGuard(Application::GetSolarMutex());
    ::sw::mark::ICheckboxFieldmark const * const pAsCheckbox =
        dynamic_cast< ::sw::mark::ICheckboxFieldmark const * const>(GetBookmark());
    if(pAsCheckbox && pAsCheckbox->IsChecked())
        return 1;
    return 0;
}

//FIXME Remove Method
void SAL_CALL SwXFieldmark::setType( ::sal_Int16 ) throw (::com::sun::star::uno::RuntimeException)
{
    vos::OGuard aGuard(Application::GetSolarMutex());
    throw uno::RuntimeException();
}

//FIXME Remove Method
void SAL_CALL SwXFieldmark::setRes( ::sal_Int16  ) throw (::com::sun::star::uno::RuntimeException)
{
    vos::OGuard aGuard(Application::GetSolarMutex());
    throw uno::RuntimeException();
}

void SAL_CALL SwXFieldmark::setDescription( const ::rtl::OUString& description )
    throw (::com::sun::star::uno::RuntimeException)
{
    vos::OGuard aGuard(Application::GetSolarMutex());
    const ::sw::mark::IFieldmark* pMark =
        dynamic_cast<const ::sw::mark::IFieldmark*>(GetBookmark());
    if(pMark)
        const_cast< ::sw::mark::IFieldmark*>(pMark)->SetFieldHelptext(description);
    else
        throw uno::RuntimeException();
}
diff --git a/sw/source/core/unocore/unocoll.cxx b/sw/source/core/unocore/unocoll.cxx
index c3d6747..d4c4364 100644
--- a/sw/source/core/unocore/unocoll.cxx
+++ b/sw/source/core/unocore/unocoll.cxx
@@ -48,7 +48,7 @@
#include <fmtanchr.hxx>
#include <ndtxt.hxx>
#include <section.hxx>
#include <bookmrk.hxx>
#include <IMark.hxx>
#include <ftnidx.hxx>
#include <fmtftn.hxx>
#include <txtftn.hxx>
@@ -71,6 +71,7 @@
#include <authfld.hxx>
#include <SwXTextDefaults.hxx>
#include <unochart.hxx>
#include <bookmrk.hxx>

#include "docsh.hxx"

@@ -200,9 +201,9 @@ const ProvNamesId_Type __FAR_DATA aProvNamesId[] =
    { "com.sun.star.image.ImageMapCircleObject",              SW_SERVICE_IMAP_CIRCLE },
    { "com.sun.star.image.ImageMapPolygonObject",             SW_SERVICE_IMAP_POLYGON },
    { "com.sun.star.text.TextGraphicObject",                  SW_SERVICE_TYPE_TEXT_GRAPHIC },
    { "com.sun.star.chart2.data.DataProvider",                SW_SERVICE_CHART2_DATA_PROVIDER },
    { "com.sun.star.text.Fieldmark",                          SW_SERVICE_TYPE_FIELDMARK },
    { "com.sun.star.text.FormFieldmark",                      SW_SERVICE_TYPE_FORMFIELDMARK },
    { "com.sun.star.chart2.data.DataProvider",                SW_SERVICE_CHART2_DATA_PROVIDER },

    // case-correct versions of the service names (see #i67811)
    { CSS_TEXT_TEXTFIELD_DATE_TIME,                   SW_SERVICE_FIELDTYPE_DATETIME },
@@ -1410,190 +1411,138 @@ uno::Reference< XTextSection >  SwXTextSections::GetObject( SwSectionFmt& rFmt )
        xRet = SwXTextSectionClient::CreateXTextSection(&rFmt);
    return xRet;
}
/******************************************************************
 *
 ******************************************************************/
/* -----------------------------06.04.00 12:44--------------------------------

 ---------------------------------------------------------------------------*/
OUString SwXBookmarks::getImplementationName(void) throw( RuntimeException )
{
    return C2U("SwXBookmarks");
    return OUString::createFromAscii("SwXBookmarks");
}
/* -----------------------------06.04.00 12:44--------------------------------

 ---------------------------------------------------------------------------*/
BOOL SwXBookmarks::supportsService(const OUString& rServiceName) throw( RuntimeException )
{
    return C2U("com.sun.star.text.Bookmarks") == rServiceName;
    return OUString::createFromAscii("com.sun.star.text.Bookmarks") == rServiceName;
}
/* -----------------------------06.04.00 12:44--------------------------------

 ---------------------------------------------------------------------------*/
Sequence< OUString > SwXBookmarks::getSupportedServiceNames(void) throw( RuntimeException )
{
    Sequence< OUString > aRet(1);
    OUString* pArray = aRet.getArray();
    pArray[0] = C2U("com.sun.star.text.Bookmarks");
    aRet[0] = OUString::createFromAscii("com.sun.star.text.Bookmarks");
    return aRet;
}
/*-- 14.01.99 09:05:48---------------------------------------------------

  -----------------------------------------------------------------------*/
SwXBookmarks::SwXBookmarks(SwDoc* _pDoc) :
    SwUnoCollection(_pDoc)
{
}
/*-- 14.01.99 09:05:48---------------------------------------------------
{ }

  -----------------------------------------------------------------------*/
SwXBookmarks::~SwXBookmarks()
{
}
/*-- 14.01.99 09:05:49---------------------------------------------------
{ }

  -----------------------------------------------------------------------*/
sal_Int32 SwXBookmarks::getCount(void) throw( uno::RuntimeException )
sal_Int32 SwXBookmarks::getCount(void)
    throw( uno::RuntimeException )
{
    vos::OGuard aGuard(Application::GetSolarMutex());
    if(!IsValid())
        throw uno::RuntimeException();
    return GetDoc()->getBookmarkCount(sal_True);
    return GetDoc()->getIDocumentMarkAccess()->getBookmarksCount();
}
/*-- 14.01.99 09:05:49---------------------------------------------------

  -----------------------------------------------------------------------*/
uno::Any SwXBookmarks::getByIndex(sal_Int32 nIndex)
    throw( IndexOutOfBoundsException, WrappedTargetException, uno::RuntimeException )
{
    vos::OGuard aGuard(Application::GetSolarMutex());
    uno::Any aRet;
    if(IsValid())
    {
        if(0 <= nIndex && GetDoc()->getBookmarkCount(true) > nIndex)
        {
            SwBookmark& rBkm = GetDoc()->getBookmark((sal_uInt16) nIndex, true);
            uno::Reference< XTextContent >  xRef = GetObject(rBkm, GetDoc());
            aRet.setValue(&xRef, ::getCppuType((uno::Reference<XTextContent>*)0));
        }
        else
            throw IndexOutOfBoundsException();
    }
    else
    if(!IsValid())
        throw uno::RuntimeException();
    IDocumentMarkAccess* const pMarkAccess = GetDoc()->getIDocumentMarkAccess();
    if(nIndex < 0 || nIndex >= pMarkAccess->getBookmarksCount())
        throw IndexOutOfBoundsException();

    uno::Any aRet;
    ::sw::mark::IMark* pBkmk = pMarkAccess->getBookmarksBegin()[nIndex].get();
    uno::Reference< XTextContent > xRef = GetObject(*pBkmk, GetDoc());
    aRet.setValue(&xRef, ::getCppuType((uno::Reference<XTextContent>*)0));
    return aRet;
}
/*-- 14.01.99 09:05:49---------------------------------------------------

  -----------------------------------------------------------------------*/
uno::Any SwXBookmarks::getByName(const rtl::OUString& rName)
    throw( NoSuchElementException, WrappedTargetException, uno::RuntimeException )
{
    vos::OGuard aGuard(Application::GetSolarMutex());
    uno::Any aRet;
    if(IsValid())
    {
        String aName(rName);
        sal_uInt16 nCount = GetDoc()->getBookmarkCount(true);
        uno::Reference< XTextContent >  xRef;
        for( sal_uInt16 i = 0; i < nCount; i++)
        {
            SwBookmark& rBkMk = GetDoc()->getBookmark( i, true );
            if(rBkMk.GetName() == aName)
            {
                xRef = SwXBookmarks::GetObject(rBkMk, GetDoc());
                aRet.setValue(&xRef, ::getCppuType((uno::Reference<XTextContent>*)0));
                break;
            }
        }
        if(!xRef.is())
            throw NoSuchElementException();
    }
    else
    if(!IsValid())
        throw uno::RuntimeException();

    IDocumentMarkAccess* const pMarkAccess = GetDoc()->getIDocumentMarkAccess();
    IDocumentMarkAccess::const_iterator_t ppBkmk = pMarkAccess->findBookmark(rName);
    if(ppBkmk == pMarkAccess->getBookmarksEnd())
        throw NoSuchElementException();

    uno::Any aRet;
    uno::Reference< XTextContent > xRef = SwXBookmarks::GetObject(*(ppBkmk->get()), GetDoc());
    aRet.setValue(&xRef, ::getCppuType((uno::Reference<XTextContent>*)0));
    return aRet;
}
/*-- 14.01.99 09:05:49---------------------------------------------------

  -----------------------------------------------------------------------*/
uno::Sequence< OUString > SwXBookmarks::getElementNames(void) throw( uno::RuntimeException )
uno::Sequence< OUString > SwXBookmarks::getElementNames(void)
    throw( uno::RuntimeException )
{
    vos::OGuard aGuard(Application::GetSolarMutex());
    if(!IsValid())
        throw uno::RuntimeException();
    sal_uInt16 nCount = GetDoc()->getBookmarkCount(true);
    uno::Sequence<OUString> aSeq(nCount);
    if(nCount)
    {
        OUString* pArray = aSeq.getArray();
        for( sal_uInt16 i = 0; i < nCount; i++)
        {
            SwBookmark& rBkMk = GetDoc()->getBookmark( i, true );
            pArray[i] = rBkMk.GetName();
        }
    }

    IDocumentMarkAccess* const pMarkAccess = GetDoc()->getIDocumentMarkAccess();
    uno::Sequence<OUString> aSeq(pMarkAccess->getBookmarksCount());
    sal_Int32 nCnt = 0;
    for(IDocumentMarkAccess::const_iterator_t ppMark = pMarkAccess->getBookmarksBegin();
        ppMark != pMarkAccess->getBookmarksEnd();)
        aSeq[nCnt++] = (*ppMark++)->GetName();
    return aSeq;
}
/*-- 14.01.99 09:05:49---------------------------------------------------

  -----------------------------------------------------------------------*/
sal_Bool SwXBookmarks::hasByName(const OUString& rName) throw( uno::RuntimeException )
sal_Bool SwXBookmarks::hasByName(const OUString& rName)
    throw( uno::RuntimeException )
{
    vos::OGuard aGuard(Application::GetSolarMutex());
    sal_Bool bRet = sal_False;
    if(IsValid())
    {
        String aName(rName);
        sal_uInt16 nCount = GetDoc()->getBookmarkCount(true);
        for( sal_uInt16 i = 0; i < nCount; i++)
        {
            SwBookmark& rBkMk = GetDoc()->getBookmark( i,true);
            if(rBkMk.GetName() == aName)
            {
                bRet = sal_True;
                break;
            }
        }
    }
    else
    if(!IsValid())
        throw uno::RuntimeException();
    return bRet;
}
/*-- 14.01.99 09:05:50---------------------------------------------------

  -----------------------------------------------------------------------*/
uno::Type SAL_CALL SwXBookmarks::getElementType() throw(uno::RuntimeException)
    IDocumentMarkAccess* const pMarkAccess = GetDoc()->getIDocumentMarkAccess();
    return pMarkAccess->findBookmark(rName) != pMarkAccess->getBookmarksEnd();
}

uno::Type SAL_CALL SwXBookmarks::getElementType()
    throw(uno::RuntimeException)
{
    return ::getCppuType((uno::Reference<XTextContent>*)0);
}
/*-- 14.01.99 09:05:50---------------------------------------------------

  -----------------------------------------------------------------------*/
sal_Bool SwXBookmarks::hasElements(void) throw( uno::RuntimeException )
sal_Bool SwXBookmarks::hasElements(void)
    throw( uno::RuntimeException )
{
    vos::OGuard aGuard(Application::GetSolarMutex());
    if(!IsValid())
        throw uno::RuntimeException();
    return GetDoc()->getBookmarkCount(true) != 0;
    return GetDoc()->getIDocumentMarkAccess()->getBookmarksCount() != 0;
}
/*-- 14.01.99 09:05:50---------------------------------------------------

  -----------------------------------------------------------------------*/
SwXBookmark*    SwXBookmarks::GetObject( SwBookmark& rBkm, SwDoc* pDoc )
SwXBookmark* SwXBookmarks::GetObject( ::sw::mark::IMark& rBkmk, SwDoc* pDoc)
{
    SwXBookmark* pBkm = (SwXBookmark*)SwClientIter( rBkm ).
                                    First( TYPE( SwXBookmark ));
    if( !pBkm )
    SwModify* const pModify = static_cast<SwModify*>(&rBkmk);
    SwXBookmark* pXBkmk = (SwXBookmark*)SwClientIter(*pModify).First(TYPE(SwXBookmark));
    if(!pXBkmk)
    {
        if (IDocumentBookmarkAccess::FORM_FIELDMARK_TEXT==rBkm.GetType())
            pBkm = new SwXFieldmark(false, &rBkm, pDoc);
        else if (IDocumentBookmarkAccess::FORM_FIELDMARK_NO_TEXT==rBkm.GetType())
            pBkm = new SwXFieldmark(true, &rBkm, pDoc);
        else
            pBkm = new SwXBookmark(&rBkm, pDoc);
        // FIXME: These belong in XTextFieldsSupplier
        //if (dynamic_cast< ::sw::mark::TextFieldmark* >(&rBkmk))
        //    pXBkmk = new SwXFieldmark(false, &rBkmk, pDoc);
        //else if (dynamic_cast< ::sw::mark::CheckboxFieldmark* >(&rBkmk))
        //    pXBkmk = new SwXFieldmark(true, &rBkmk, pDoc);
        //else
        OSL_ENSURE(
            dynamic_cast< ::sw::mark::IBookmark* >(&rBkmk),
            "<SwXBookmark::GetObject(..)>"
            "SwXBookmark requested for non-bookmark mark.");
        pXBkmk = new SwXBookmark(&rBkmk, pDoc);
    }
    return pBkm;
    return pXBkmk;
}

/******************************************************************
 *
 ******************************************************************/
diff --git a/sw/source/core/unocore/unoobj.cxx b/sw/source/core/unocore/unoobj.cxx
index 7a8a5ac..d0161949 100644
--- a/sw/source/core/unocore/unoobj.cxx
+++ b/sw/source/core/unocore/unoobj.cxx
@@ -38,7 +38,7 @@
#include <hintids.hxx>
#include <cmdid.h>
#include <hints.hxx>
#include <bookmrk.hxx>
#include <IMark.hxx>
#include <frmfmt.hxx>
#include <doc.hxx>
#include <istyleaccess.hxx>
@@ -1101,9 +1101,7 @@ void SwXTextCursor::gotoEnd(sal_Bool Expand) throw( uno::RuntimeException )
        throw uno::RuntimeException();
    }
}
/* -----------------05.03.99 07:27-------------------
 *
 * --------------------------------------------------*/

void SwXTextCursor::gotoRange(const uno::Reference< XTextRange > & xRange, sal_Bool bExpand )
                                throw( uno::RuntimeException )
{
@@ -1148,8 +1146,8 @@ void SwXTextCursor::gotoRange(const uno::Reference< XTextRange > & xRange, sal_B
    }
    else if(pRange && pRange->GetBookmark())
    {
        SwBookmark* pBkm = pRange->GetBookmark();
        pSrcNode = &pBkm->GetBookmarkPos().nNode.GetNode();
        ::sw::mark::IMark const * const pBkmk = pRange->GetBookmark();
        pSrcNode = &pBkmk->GetMarkPos().nNode.GetNode();
    }
    const SwStartNode* pTmp = pSrcNode ? pSrcNode->FindSttNodeByType(eSearchNodeType) : 0;

@@ -1190,9 +1188,9 @@ void SwXTextCursor::gotoRange(const uno::Reference< XTextRange > & xRange, sal_B
        }
        else
        {
            SwBookmark* pBkm = pRange->GetBookmark();
            pParamLeft = new SwPosition(pBkm->GetBookmarkPos());
            pParamRight = new SwPosition(pBkm->GetOtherBookmarkPos() ? *pBkm->GetOtherBookmarkPos() : *pParamLeft);
            ::sw::mark::IMark const * const pBkmk = pRange->GetBookmark();
            pParamLeft = new SwPosition(pBkmk->GetMarkPos());
            pParamRight = new SwPosition(pBkmk->IsExpanded() ? pBkmk->GetOtherMarkPos() : *pParamLeft);
        }
        if(*pParamRight < *pParamLeft)
        {
@@ -1230,12 +1228,12 @@ void SwXTextCursor::gotoRange(const uno::Reference< XTextRange > & xRange, sal_B
        }
        else
        {
            SwBookmark* pBkm = pRange->GetBookmark();
            *pOwnCursor->GetPoint() = pBkm->GetBookmarkPos();
            if(pBkm->GetOtherBookmarkPos())
            ::sw::mark::IMark const * const pBkmk = pRange->GetBookmark();
            *pOwnCursor->GetPoint() = pBkmk->GetMarkPos();
            if(pBkmk->IsExpanded())
            {
                pOwnCursor->SetMark();
                *pOwnCursor->GetMark() = *pBkm->GetOtherBookmarkPos();
                *pOwnCursor->GetMark() = pBkmk->GetOtherMarkPos();
            }
            else
                pOwnCursor->DeleteMark();
diff --git a/sw/source/core/unocore/unoobj2.cxx b/sw/source/core/unocore/unoobj2.cxx
index 9b536da..9c59817 100644
--- a/sw/source/core/unocore/unoobj2.cxx
+++ b/sw/source/core/unocore/unoobj2.cxx
@@ -37,6 +37,7 @@
#include <hintids.hxx>
#include <cmdid.h>
#include <hints.hxx>
#include <IMark.hxx>
#include <bookmrk.hxx>
#include <frmfmt.hxx>
#include <doc.hxx>
@@ -1119,18 +1120,13 @@ void SwXParagraphEnumeration::Modify( SfxPoolItem *pOld, SfxPoolItem *pNew)
 ******************************************************************/
TYPEINIT1(SwXTextRange, SwClient);

/* -----------------------------10.03.00 18:02--------------------------------

 ---------------------------------------------------------------------------*/
const uno::Sequence< sal_Int8 > & SwXTextRange::getUnoTunnelId()
{
    static uno::Sequence< sal_Int8 > aSeq = ::CreateUnoTunnelId();
    return aSeq;
}
/* -----------------------------10.03.00 18:02--------------------------------

 ---------------------------------------------------------------------------*/
    //XUnoTunnel
//XUnoTunnel
sal_Int64 SAL_CALL SwXTextRange::getSomething(
    const uno::Sequence< sal_Int8 >& rId )
        throw(uno::RuntimeException)
@@ -1143,47 +1139,37 @@ sal_Int64 SAL_CALL SwXTextRange::getSomething(
        }
    return 0;
}
/* -----------------------------06.04.00 16:34--------------------------------

 ---------------------------------------------------------------------------*/
OUString SwXTextRange::getImplementationName(void) throw( RuntimeException )
{
    return C2U("SwXTextRange");
    return OUString::createFromAscii("SwXTextRange");
}
/* -----------------------------06.04.00 16:34--------------------------------

 ---------------------------------------------------------------------------*/
BOOL SwXTextRange::supportsService(const OUString& rServiceName) throw( RuntimeException )
{
    String sServiceName(rServiceName);
    return sServiceName.EqualsAscii("com.sun.star.text.TextRange") ||
         sServiceName.EqualsAscii("com.sun.star.style.CharacterProperties")||
        sServiceName.EqualsAscii("com.sun.star.style.CharacterProperties")||
        sServiceName.EqualsAscii("com.sun.star.style.CharacterPropertiesAsian")||
        sServiceName.EqualsAscii("com.sun.star.style.CharacterPropertiesComplex")||
        sServiceName.EqualsAscii("com.sun.star.style.ParagraphProperties") ||
        sServiceName.EqualsAscii("com.sun.star.style.ParagraphPropertiesAsian") ||
        sServiceName.EqualsAscii("com.sun.star.style.ParagraphPropertiesComplex");
}
/* -----------------------------06.04.00 16:34--------------------------------

 ---------------------------------------------------------------------------*/
Sequence< OUString > SwXTextRange::getSupportedServiceNames(void) throw( RuntimeException )
{
    Sequence< OUString > aRet(7);
    OUString* pArray = aRet.getArray();
    pArray[0] = C2U("com.sun.star.text.TextRange");
     pArray[1] = C2U("com.sun.star.style.CharacterProperties");
    pArray[2] = C2U("com.sun.star.style.CharacterPropertiesAsian");
    pArray[3] = C2U("com.sun.star.style.CharacterPropertiesComplex");
    pArray[4] = C2U("com.sun.star.style.ParagraphProperties");
    pArray[5] = C2U("com.sun.star.style.ParagraphPropertiesAsian");
    pArray[6] = C2U("com.sun.star.style.ParagraphPropertiesComplex");
    aRet[0] = OUString::createFromAscii("com.sun.star.text.TextRange");
    aRet[1] = OUString::createFromAscii("com.sun.star.style.CharacterProperties");
    aRet[2] = OUString::createFromAscii("com.sun.star.style.CharacterPropertiesAsian");
    aRet[3] = OUString::createFromAscii("com.sun.star.style.CharacterPropertiesComplex");
    aRet[4] = OUString::createFromAscii("com.sun.star.style.ParagraphProperties");
    aRet[5] = OUString::createFromAscii("com.sun.star.style.ParagraphPropertiesAsian");
    aRet[6] = OUString::createFromAscii("com.sun.star.style.ParagraphPropertiesComplex");
    return aRet;
}

/*-- 10.12.98 12:54:43---------------------------------------------------

  -----------------------------------------------------------------------*/
SwXTextRange::SwXTextRange(SwPaM& rPam, const uno::Reference< XText > & rxParent) :
    eRangePosition(RANGE_IN_TEXT),
    pDoc(rPam.GetDoc()),
@@ -1191,145 +1177,103 @@ SwXTextRange::SwXTextRange(SwPaM& rPam, const uno::Reference< XText > & rxParent
    pBoxStartNode(0),
    aObjectDepend(this, 0),
    aPropSet(aSwMapProvider.GetPropertyMap(PROPERTY_MAP_TEXT_CURSOR)),
    xParentText(rxParent)
    xParentText(rxParent),
    pMark(NULL)
{
    //Bookmark an der anlegen
    _CreateNewBookmark(rPam);
}
/*-- 10.12.98 12:54:43---------------------------------------------------

  -----------------------------------------------------------------------*/
SwXTextRange::SwXTextRange(SwFrmFmt& rFmt, SwPaM& rPam) :
    eRangePosition(RANGE_IN_FRAME),
    pDoc(rPam.GetDoc()),
    pBox(0),
    pBoxStartNode(0),
    aObjectDepend(this, &rFmt),
    aPropSet(aSwMapProvider.GetPropertyMap(PROPERTY_MAP_TEXT_CURSOR))
    aPropSet(aSwMapProvider.GetPropertyMap(PROPERTY_MAP_TEXT_CURSOR)),
    pMark(NULL)
{
    //Bookmark an der anlegen
    _CreateNewBookmark(rPam);
}
/*-- 10.12.98 12:54:44---------------------------------------------------

  -----------------------------------------------------------------------*/
SwXTextRange::SwXTextRange(SwFrmFmt& rTblFmt, SwTableBox& rTblBox, SwPaM& rPam) :
    eRangePosition(RANGE_IN_CELL),
    pDoc(rPam.GetDoc()),
    pBox(&rTblBox),
    pBoxStartNode(0),
    aObjectDepend(this, &rTblFmt),
    aPropSet(aSwMapProvider.GetPropertyMap(PROPERTY_MAP_TEXT_CURSOR))
    aPropSet(aSwMapProvider.GetPropertyMap(PROPERTY_MAP_TEXT_CURSOR)),
    pMark(NULL)
{
    //Bookmark an der anlegen
    _CreateNewBookmark(rPam);
}
/* -----------------------------09.08.00 16:07--------------------------------

 ---------------------------------------------------------------------------*/
SwXTextRange::SwXTextRange(SwFrmFmt& rTblFmt, const SwStartNode& rStartNode, SwPaM& rPam) :
    eRangePosition(RANGE_IN_CELL),
    pDoc(rPam.GetDoc()),
    pBox(0),
    pBoxStartNode(&rStartNode),
    aObjectDepend(this, &rTblFmt),
    aPropSet(aSwMapProvider.GetPropertyMap(PROPERTY_MAP_TEXT_CURSOR))
    aPropSet(aSwMapProvider.GetPropertyMap(PROPERTY_MAP_TEXT_CURSOR)),
    pMark(NULL)
{
    //Bookmark an der anlegen
    _CreateNewBookmark(rPam);
}
/* -----------------19.02.99 11:39-------------------
 *
 * --------------------------------------------------*/

SwXTextRange::SwXTextRange(SwFrmFmt& rTblFmt) :
    eRangePosition(RANGE_IS_TABLE),
    pDoc(rTblFmt.GetDoc()),
    pBox(0),
    pBoxStartNode(0),
    aObjectDepend(this, &rTblFmt),
    aPropSet(aSwMapProvider.GetPropertyMap(PROPERTY_MAP_TEXT_CURSOR))
{
}
    aPropSet(aSwMapProvider.GetPropertyMap(PROPERTY_MAP_TEXT_CURSOR)),
    pMark(NULL)
{ }

/*-- 10.12.98 12:54:44---------------------------------------------------

  -----------------------------------------------------------------------*/
SwXTextRange::~SwXTextRange()
{
    vos::OGuard aGuard(Application::GetSolarMutex());
    if(GetBookmark())
        pDoc->deleteBookmark( GetBookmark()->GetName() );
    ::sw::mark::IMark const * const pBkmk = GetBookmark();
    if(pBkmk)
        pDoc->getIDocumentMarkAccess()->deleteMark(pBkmk);
}
/*-- 10.12.98 12:54:44---------------------------------------------------

  -----------------------------------------------------------------------*/
void    SwXTextRange::_CreateNewBookmark(SwPaM& rPam)
void SwXTextRange::_CreateNewBookmark(SwPaM& rPam)
{
    static sal_Int32 nBookmark = 0;
    String sBookmarkName;
    IDocumentMarkAccess* const pMarkAccess = pDoc->getIDocumentMarkAccess();

    SwBookmark* pBkm = GetBookmark();
    if(pBkm)
    {
        // If a bookmark exists already its name can be resused
        sBookmarkName = pBkm->GetName();
        pDoc->deleteBookmark( sBookmarkName );
    }
    else
    {
        // Otherwise we have to create a new name. This is not done
        // using SwDoc::MakeUniqueBookmarkName, because this method
        // starts counting bookmarks beginning with 1. That's required
        // for real bookmarks, but very slow in thsi case there lots
        // of bookmarks requiere any unique name only.
        String sPrefix(C2S("SwXTextPosition"));
        const SwBookmarks& rBookmarks = pDoc->getBookmarks();
        sal_uInt16 nBookmarks = rBookmarks.Count(), i;
        do
        {
            nBookmark++;
            if( nBookmark < 1 ) // on overwflow restart with 1
                nBookmark = 1;

            sBookmarkName = sPrefix;
            sBookmarkName += String::CreateFromInt32( nBookmark );
            for( i = 0; i < nBookmarks; i++ )
                if( rBookmarks[i]->GetName().Equals( sBookmarkName ) )
                    break;
        }
        while( i < nBookmarks );
    }

    KeyCode aCode;
    String sShortName;
    SwBookmark* pMark = pDoc->makeBookmark(rPam, aCode, sBookmarkName, sShortName, IDocumentBookmarkAccess::UNO_BOOKMARK);
    ::sw::mark::IMark const * const pBkmk = GetBookmark();
    if(pBkmk)
        pMarkAccess->deleteMark(pBkmk);
    pMark = pMarkAccess->makeMark(rPam, ::rtl::OUString(), IDocumentMarkAccess::UNO_BOOKMARK);
    pMark->Add(this);
}
/*-- 10.12.98 12:54:45---------------------------------------------------

  -----------------------------------------------------------------------*/
void    SwXTextRange::DeleteAndInsert(const String& rText) throw( uno::RuntimeException )
void SwXTextRange::DeleteAndInsert(const String& rText)
    throw(uno::RuntimeException)
{
    SwBookmark* pBkm = GetBookmark();
    if(pBkm )
    ::sw::mark::IMark const * const pBkmk = GetBookmark();
    if(pBkmk)
    {
        const SwPosition& rPoint = *pBkm->BookmarkStart();
        const SwPosition* pMark = pBkm->BookmarkEnd();
        SwCursor aNewCrsr( rPoint, 0, false );
        if(pMark)
        const SwPosition& rPoint = pBkmk->GetMarkStart();
        SwCursor aNewCrsr(rPoint, 0, false);
        if(pBkmk->IsExpanded())
        {
            aNewCrsr.SetMark();
            *aNewCrsr.GetMark() = *pMark;
            const SwPosition& rMark = pBkmk->GetMarkEnd();
            *aNewCrsr.GetMark() = rMark;
        }

        UnoActionContext aAction( pDoc );
        UnoActionContext aAction(pDoc);
        pDoc->StartUndo(UNDO_INSERT, NULL);
        if(aNewCrsr.HasMark())
            pDoc->DeleteAndJoin(aNewCrsr);

        if(rText.Len())
        {
            SwUnoCursorHelper::DocInsertStringSplitCR( *pDoc, aNewCrsr, rText );
            SwUnoCursorHelper::DocInsertStringSplitCR(*pDoc, aNewCrsr, rText);

            SwXTextCursor::SelectPam(aNewCrsr, sal_True);
            aNewCrsr.Left(rText.Len(), CRSR_SKIP_CHARS, FALSE, FALSE);
@@ -1337,12 +1281,8 @@ void    SwXTextRange::DeleteAndInsert(const String& rText) throw( uno::RuntimeEx
        _CreateNewBookmark(aNewCrsr);
        pDoc->EndUndo(UNDO_INSERT, NULL);
    }

}

/*-- 10.12.98 12:54:46---------------------------------------------------

  -----------------------------------------------------------------------*/
uno::Reference< XText >  SwXTextRange::getText(void) throw( uno::RuntimeException )
{
    vos::OGuard aGuard(Application::GetSolarMutex());
@@ -1394,91 +1334,69 @@ uno::Reference< XText >  SwXTextRange::getText(void) throw( uno::RuntimeExceptio
    }
    return xParentText;
}
/*-- 10.12.98 12:54:47---------------------------------------------------

  -----------------------------------------------------------------------*/
uno::Reference< XTextRange >  SwXTextRange::getStart(void) throw( uno::RuntimeException )
{
    vos::OGuard aGuard(Application::GetSolarMutex());
    uno::Reference< XTextRange >  xRet;
    SwBookmark* pBkm = GetBookmark();

    ::sw::mark::IMark const * const pBkmk = GetBookmark();
    if(!xParentText.is())
        getText();
    if(pBkm)
    if(pBkmk)
    {
        SwPaM aPam(*pBkm->BookmarkStart());
        SwPaM aPam(pBkmk->GetMarkStart());
        xRet = new SwXTextRange(aPam, xParentText);
    }
    else if(eRangePosition == RANGE_IS_TABLE)
    {
        //start und ende sind mit this identisch, wenn es eine Tabelle ist
        //start and end are this, if its a table
        xRet = this;
    }
    else
        throw uno::RuntimeException();
    return xRet;
}
/*-- 10.12.98 12:54:47---------------------------------------------------

  -----------------------------------------------------------------------*/
uno::Reference< XTextRange >  SwXTextRange::getEnd(void) throw( uno::RuntimeException )
{
    vos::OGuard aGuard(Application::GetSolarMutex());
    uno::Reference< XTextRange >  xRet;
    SwBookmark* pBkm = GetBookmark();
    ::sw::mark::IMark const * const pBkmk = GetBookmark();
    if(!xParentText.is())
        getText();
    if(pBkm)
    if(pBkmk)
    {
//      SwPaM aPam(pBkm->GetOtherPos()? *pBkm->GetOtherPos() : pBkm->GetPos());
        SwPaM aPam(*pBkm->BookmarkEnd());
        SwPaM aPam(pBkmk->GetMarkEnd());
        xRet = new SwXTextRange(aPam, xParentText);
    }
    else if(eRangePosition == RANGE_IS_TABLE)
    {
        //start und ende sind mit this identisch, wenn es eine Tabelle ist
        //start and end are this, if its a table
        xRet = this;
    }
    else
        throw uno::RuntimeException();
    return xRet;
}
/*-- 10.12.98 12:54:47---------------------------------------------------

  -----------------------------------------------------------------------*/
OUString SwXTextRange::getString(void) throw( uno::RuntimeException )
{
    vos::OGuard aGuard(Application::GetSolarMutex());
    SwBookmark* pBkm = GetBookmark();
    OUString sRet;
    //fuer Tabellen gibt es keine Bookmark, also auch keinen Text
    //evtl. koennte man hier die Tabelle als ASCII exportieren?
    if(pBkm && pBkm->GetOtherBookmarkPos())
    ::sw::mark::IMark const * const pBkmk = GetBookmark();
    // for tables there is no bookmark, thus also no text
    // one could export the table as ASCII here maybe?
    if(pBkmk && pBkmk->IsExpanded())
    {
        const SwPosition& rPoint = pBkm->GetBookmarkPos();
        const SwPosition* pMark = pBkm->GetOtherBookmarkPos();
        SwPaM aCrsr(*pMark, rPoint);
/*      if( rPoint.nNode.GetIndex() ==
            pMark->nNode.GetIndex() )
        {
            SwTxtNode* pTxtNd = aCrsr.GetNode()->GetTxtNode();
            if( pTxtNd )
            {
                sal_uInt16 nStt = aCrsr.Start()->nContent.GetIndex();
                sRet = pTxtNd->GetExpandTxt( nStt,
                        aCrsr.End()->nContent.GetIndex() - nStt );
            }
        }
        else
*/      {
            SwXTextCursor::getTextFromPam(aCrsr, sRet);
        }
        const SwPosition& rPoint = pBkmk->GetMarkPos();
        const SwPosition& rMark = pBkmk->GetOtherMarkPos();
        SwPaM aCrsr(rMark, rPoint);
        SwXTextCursor::getTextFromPam(aCrsr, sRet);
    }
    return sRet;
}
/*-- 10.12.98 12:54:48---------------------------------------------------

  -----------------------------------------------------------------------*/
void SwXTextRange::setString(const OUString& aString)
    throw( uno::RuntimeException )
{
@@ -1491,9 +1409,7 @@ void SwXTextRange::setString(const OUString& aString)
    else
        DeleteAndInsert(aString);
}
/*-- 10.12.98 12:54:48---------------------------------------------------

  -----------------------------------------------------------------------*/
void SwXTextRange::Modify( SfxPoolItem *pOld, SfxPoolItem *pNew)
{
    sal_Bool bAlreadyRegisterred = 0 != GetRegisteredIn();
@@ -1510,21 +1426,21 @@ void SwXTextRange::Modify( SfxPoolItem *pOld, SfxPoolItem *pNew)
                aObjectDepend.GetRegisteredIn())
            ((SwModify*)aObjectDepend.GetRegisteredIn())->Remove(&aObjectDepend);
    }
    if(!GetRegisteredIn())
        pMark = NULL;
}
/*-- 10.12.98 12:54:49---------------------------------------------------

  -----------------------------------------------------------------------*/
sal_Bool    SwXTextRange::GetPositions(SwPaM& rToFill) const
sal_Bool SwXTextRange::GetPositions(SwPaM& rToFill) const
{
    sal_Bool bRet = sal_False;
    SwBookmark* pBkm = GetBookmark();
    if(pBkm)
    ::sw::mark::IMark const * const pBkmk = GetBookmark();
    if(pBkmk)
    {
        *rToFill.GetPoint() = pBkm->GetBookmarkPos();
        if(pBkm->GetOtherBookmarkPos())
        *rToFill.GetPoint() = pBkmk->GetMarkPos();
        if(pBkmk->IsExpanded())
        {
            rToFill.SetMark();
            *rToFill.GetMark() = *pBkm->GetOtherBookmarkPos();
            *rToFill.GetMark() = pBkmk->GetOtherMarkPos();
        }
        else
            rToFill.DeleteMark();
@@ -1532,10 +1448,8 @@ sal_Bool    SwXTextRange::GetPositions(SwPaM& rToFill) const
    }
    return bRet;
}
/*-- 10.12.98 12:54:49---------------------------------------------------

  -----------------------------------------------------------------------*/
sal_Bool        SwXTextRange::XTextRangeToSwPaM( SwUnoInternalPaM& rToFill,
sal_Bool SwXTextRange::XTextRangeToSwPaM( SwUnoInternalPaM& rToFill,
                            const uno::Reference< XTextRange > & xTextRange)
{
    sal_Bool bRet = sal_False;
@@ -1614,9 +1528,7 @@ sal_Bool        SwXTextRange::XTextRangeToSwPaM( SwUnoInternalPaM& rToFill,
    }
    return bRet;
}
/* -----------------24.02.99 14:18-------------------
 * Der StartNode muss in einem existierenden Header/Footen liegen
 * --------------------------------------------------*/

sal_Bool lcl_IsStartNodeInFormat(sal_Bool bHeader, SwStartNode* pSttNode,
    const SwFrmFmt* pFrmFmt, SwFrmFmt*& rpFormat)
{
@@ -1641,10 +1553,8 @@ sal_Bool lcl_IsStartNodeInFormat(sal_Bool bHeader, SwStartNode* pSttNode,
    }
    return bRet;
}
/* -----------------03.11.98 15:58-------------------
 *
 * --------------------------------------------------*/
uno::Reference< XTextRange >  SwXTextRange::CreateTextRangeFromPosition(SwDoc* pDoc,

uno::Reference< XTextRange > SwXTextRange::CreateTextRangeFromPosition(SwDoc* pDoc,
                        const SwPosition& rPos, const SwPosition* pMark)
{
    uno::Reference< XTextRange >  aRet;
@@ -1755,44 +1665,37 @@ uno::Reference< XTextRange >  SwXTextRange::CreateTextRangeFromPosition(SwDoc* p
    delete pNewCrsr;
    return aRet;
}
/* -----------------------------03.04.00 09:11--------------------------------

 ---------------------------------------------------------------------------*/
uno::Reference< XEnumeration >  SAL_CALL SwXTextRange::createContentEnumeration(
        const OUString& rServiceName)
                throw( RuntimeException )
    const OUString& rServiceName)
        throw(RuntimeException)
{
    SwBookmark* pBkm = GetBookmark();
    if( !pBkm || COMPARE_EQUAL != rServiceName.compareToAscii("com.sun.star.text.TextContent") )
    ::sw::mark::IMark const * const pBkmk = GetBookmark();
    if( !pBkmk || COMPARE_EQUAL != rServiceName.compareToAscii("com.sun.star.text.TextContent") )
        throw RuntimeException();

    const SwPosition& rPoint = pBkm->GetBookmarkPos();
    const SwPosition* pMark = pBkm->GetOtherBookmarkPos();
    const SwPosition& rPoint = pBkmk->GetMarkPos();
    SwUnoCrsr* pNewCrsr = pDoc->CreateUnoCrsr(rPoint, FALSE);
    if(pMark && *pMark != rPoint)
    if(pBkmk->IsExpanded() && pBkmk->GetOtherMarkPos() != rPoint)
    {
        pNewCrsr->SetMark();
        *pNewCrsr->GetMark() = *pMark;
        *pNewCrsr->GetMark() = pBkmk->GetOtherMarkPos();
    }
    uno::Reference< XEnumeration > xRet = new SwXParaFrameEnumeration(*pNewCrsr, PARAFRAME_PORTION_TEXTRANGE);
    delete pNewCrsr;
    return xRet;
}
/* -----------------------------07.03.01 14:55--------------------------------

 ---------------------------------------------------------------------------*/
uno::Reference< XEnumeration >  SwXTextRange::createEnumeration(void) throw( RuntimeException )
uno::Reference< XEnumeration > SwXTextRange::createEnumeration(void) throw( RuntimeException )
{
    SwBookmark* pBkm = GetBookmark();
    if( !pBkm  )
        throw RuntimeException();
    const SwPosition& rPoint = pBkm->GetBookmarkPos();
    const SwPosition* pMark = pBkm->GetOtherBookmarkPos();
    ::sw::mark::IMark const * const pBkmk = GetBookmark();
    if(!pBkmk) throw RuntimeException();
    const SwPosition& rPoint = pBkmk->GetMarkPos();
    SwUnoCrsr* pNewCrsr = pDoc->CreateUnoCrsr(rPoint, FALSE);
    if(pMark && *pMark != rPoint)
    if(pBkmk->IsExpanded() && pBkmk->GetOtherMarkPos() != rPoint)
    {
        pNewCrsr->SetMark();
        *pNewCrsr->GetMark() = *pMark;
        *pNewCrsr->GetMark() = pBkmk->GetOtherMarkPos();
    }
    uno::Reference<XUnoTunnel> xTunnel(xParentText, UNO_QUERY);
    SwXText* pParentText = 0;
@@ -1806,23 +1709,17 @@ uno::Reference< XEnumeration >  SwXTextRange::createEnumeration(void) throw( Run
    uno::Reference< XEnumeration > xRet = new SwXParagraphEnumeration(pParentText, *pNewCrsr, eSetType);
    return xRet;
}
/* -----------------------------07.03.01 15:43--------------------------------

 ---------------------------------------------------------------------------*/
uno::Type  SwXTextRange::getElementType(void) throw( RuntimeException )
{
    return ::getCppuType((uno::Reference<XTextRange>*)0);
}
/* -----------------------------07.03.01 15:43--------------------------------

 ---------------------------------------------------------------------------*/
sal_Bool SwXTextRange::hasElements(void) throw( RuntimeException )
{
    return sal_True;
}
/* -----------------------------03.04.00 09:11--------------------------------

 ---------------------------------------------------------------------------*/
Sequence< OUString > SAL_CALL SwXTextRange::getAvailableServiceNames(void) throw( RuntimeException )
{
    Sequence< OUString > aRet(1);
@@ -1830,9 +1727,7 @@ Sequence< OUString > SAL_CALL SwXTextRange::getAvailableServiceNames(void) throw
    pArray[0] = OUString::createFromAscii("com.sun.star.text.TextContent");
    return aRet;
}
/*-- 03.05.00 12:41:46---------------------------------------------------

  -----------------------------------------------------------------------*/
uno::Reference< XPropertySetInfo > SAL_CALL SwXTextRange::getPropertySetInfo(  ) throw(RuntimeException)
{
    vos::OGuard aGuard(Application::GetSolarMutex());
@@ -1840,9 +1735,7 @@ uno::Reference< XPropertySetInfo > SAL_CALL SwXTextRange::getPropertySetInfo(  )
        aPropSet.getPropertySetInfo();
    return xRef;
}
/*-- 03.05.00 12:41:47---------------------------------------------------

  -----------------------------------------------------------------------*/
void SAL_CALL SwXTextRange::setPropertyValue(
    const OUString& rPropertyName, const Any& rValue )
    throw(UnknownPropertyException, PropertyVetoException,
@@ -1855,9 +1748,7 @@ void SAL_CALL SwXTextRange::setPropertyValue(
    SwXTextRange::GetPositions(aPaM);
    SwXTextCursor::SetPropertyValue(aPaM, aPropSet, rPropertyName, rValue);
}
/*-- 03.05.00 12:41:47---------------------------------------------------

  -----------------------------------------------------------------------*/
Any SAL_CALL SwXTextRange::getPropertyValue( const OUString& rPropertyName )
    throw(UnknownPropertyException, WrappedTargetException, RuntimeException)
{
@@ -1868,45 +1759,35 @@ Any SAL_CALL SwXTextRange::getPropertyValue( const OUString& rPropertyName )
    SwXTextRange::GetPositions(aPaM);
    return SwXTextCursor::GetPropertyValue(aPaM, aPropSet, rPropertyName);
}
/*-- 03.05.00 12:41:47---------------------------------------------------

  -----------------------------------------------------------------------*/
void SAL_CALL SwXTextRange::addPropertyChangeListener(
    const OUString& /*PropertyName*/, const uno::Reference< beans::XPropertyChangeListener >& /*aListener*/ )
    throw(beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException)
{
    DBG_WARNING("not implemented");
}
/*-- 03.05.00 12:41:48---------------------------------------------------

  -----------------------------------------------------------------------*/
void SAL_CALL SwXTextRange::removePropertyChangeListener(
    const OUString& /*PropertyName*/, const uno::Reference< beans::XPropertyChangeListener >& /*aListener*/ )
        throw(beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException)
{
    DBG_WARNING("not implemented");
}
/*-- 03.05.00 12:41:48---------------------------------------------------

  -----------------------------------------------------------------------*/
void SAL_CALL SwXTextRange::addVetoableChangeListener(
    const OUString& /*PropertyName*/, const uno::Reference< XVetoableChangeListener >& /*aListener*/ )
    throw(beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException)
{
    DBG_WARNING("not implemented");
}
/*-- 03.05.00 12:41:48---------------------------------------------------

  -----------------------------------------------------------------------*/
void SAL_CALL SwXTextRange::removeVetoableChangeListener(
    const OUString& /*PropertyName*/, const uno::Reference< beans::XVetoableChangeListener >& /*aListener*/ )
        throw(beans::UnknownPropertyException, lang::WrappedTargetException, uno::RuntimeException)
{
    DBG_WARNING("not implemented");
}
/*-- 03.05.00 12:41:48---------------------------------------------------

  -----------------------------------------------------------------------*/
PropertyState SAL_CALL SwXTextRange::getPropertyState( const OUString& rPropertyName )
    throw(UnknownPropertyException, RuntimeException)
{
@@ -1917,9 +1798,7 @@ PropertyState SAL_CALL SwXTextRange::getPropertyState( const OUString& rProperty
    SwXTextRange::GetPositions(aPaM);
    return SwXTextCursor::GetPropertyState(aPaM, aPropSet, rPropertyName);
}
/*-- 03.05.00 12:41:49---------------------------------------------------

  -----------------------------------------------------------------------*/
Sequence< PropertyState > SAL_CALL SwXTextRange::getPropertyStates(
    const Sequence< OUString >& rPropertyName ) throw(UnknownPropertyException, RuntimeException)
{
@@ -1930,9 +1809,7 @@ Sequence< PropertyState > SAL_CALL SwXTextRange::getPropertyStates(
    SwXTextRange::GetPositions(aPaM);
    return SwXTextCursor::GetPropertyStates(aPaM, aPropSet, rPropertyName);
}
/*-- 03.05.00 12:41:49---------------------------------------------------

  -----------------------------------------------------------------------*/
void SAL_CALL SwXTextRange::setPropertyToDefault( const OUString& rPropertyName )
    throw(UnknownPropertyException, RuntimeException)
{
@@ -1943,9 +1820,7 @@ void SAL_CALL SwXTextRange::setPropertyToDefault( const OUString& rPropertyName 
    SwXTextRange::GetPositions(aPaM);
    SwXTextCursor::SetPropertyToDefault(aPaM, aPropSet, rPropertyName);
}
/*-- 03.05.00 12:41:50---------------------------------------------------

  -----------------------------------------------------------------------*/
Any SAL_CALL SwXTextRange::getPropertyDefault( const OUString& rPropertyName )
    throw(UnknownPropertyException, WrappedTargetException, RuntimeException)
{
@@ -1956,9 +1831,7 @@ Any SAL_CALL SwXTextRange::getPropertyDefault( const OUString& rPropertyName )
    SwXTextRange::GetPositions(aPaM);
    return SwXTextCursor::GetPropertyDefault(aPaM, aPropSet, rPropertyName);
}
/*-- 10.03.2008 09:58:47---------------------------------------------------

  -----------------------------------------------------------------------*/
void SwXTextRange::makeRedline(
    const ::rtl::OUString& rRedlineType,
    const uno::Sequence< beans::PropertyValue >& rRedlineProperties )
diff --git a/sw/source/core/unocore/unoportenum.cxx b/sw/source/core/unocore/unoportenum.cxx
index 30e476b..eee2307 100644
--- a/sw/source/core/unocore/unoportenum.cxx
+++ b/sw/source/core/unocore/unoportenum.cxx
@@ -32,7 +32,7 @@
#include "precompiled_sw.hxx"


#include <bookmrk.hxx>
#include <IMark.hxx>
// --> OD 2007-10-23 #i81002#
#include <crossrefbookmark.hxx>
// <--
@@ -54,14 +54,117 @@
#include <vos/mutex.hxx>
#include <vcl/svapp.hxx>
#include <set>
#ifndef BOOST_SHARED_PTR_HPP_INCLUDED
#include <boost/shared_ptr.hpp>
#endif
#include <boost/bind.hpp>

using namespace ::com::sun::star;
using namespace ::com::sun::star::uno;
using namespace ::com::sun::star::text;
using ::rtl::OUString;
using namespace ::std;

namespace
{
    static const BYTE BKM_TYPE_START = 0;
    static const BYTE BKM_TYPE_END = 1;
    static const BYTE BKM_TYPE_START_END = 2;

    struct SwXBookmarkPortion_Impl
    {
        Reference<XTextContent>     xBookmark;
        BYTE                        nBkmType;
        const SwPosition            aPosition;

        SwXBookmarkPortion_Impl( SwXBookmark* pXMark, BYTE nType, const SwPosition &rPosition )
        : xBookmark ( pXMark )
        , nBkmType  ( nType )
        , aPosition ( rPosition )
        {
        }
        ULONG getIndex ()
        {
            return aPosition.nContent.GetIndex();
        }
    };
    typedef boost::shared_ptr < SwXBookmarkPortion_Impl > SwXBookmarkPortion_ImplSharedPtr;
    struct BookmarkCompareStruct
    {
        bool operator () ( const SwXBookmarkPortion_ImplSharedPtr &r1,
                           const SwXBookmarkPortion_ImplSharedPtr &r2 )
        {
            // #i16896# for bookmark portions at the same position, the start should
            // always precede the end. Hence compare positions, and use bookmark type
            // as tie-breaker for same position.
            // return ( r1->nIndex   == r2->nIndex )
            //   ? ( r1->nBkmType <  r2->nBkmType )
            //   : ( r1->nIndex   <  r2->nIndex );

            // MTG: 25/11/05: Note that the above code does not correctly handle
            // the case when one bookmark ends, and another begins in the same
            // position. When this occurs, the above code will return the
            // the start of the 2nd bookmark BEFORE the end of the first bookmark
            // See bug #i58438# for more details. The below code is correct and
            // fixes both #i58438 and #i16896#
            return r1->aPosition < r2->aPosition;
        }
    };
    typedef std::multiset < SwXBookmarkPortion_ImplSharedPtr, BookmarkCompareStruct > SwXBookmarkPortion_ImplList;


    static void lcl_FillBookmarkArray(SwDoc& rDoc, SwUnoCrsr& rUnoCrsr, SwXBookmarkPortion_ImplList& rBkmArr)
    {
        IDocumentMarkAccess* const pMarkAccess = rDoc.getIDocumentMarkAccess();
        if(!pMarkAccess->getBookmarksCount())
            return;

        // no need to consider marks starting after aEndOfPara
        SwPosition aEndOfPara(*rUnoCrsr.GetPoint());
        aEndOfPara.nContent = aEndOfPara.nNode.GetNode().GetTxtNode()->Len();
        const IDocumentMarkAccess::const_iterator_t pCandidatesEnd = upper_bound(
            pMarkAccess->getBookmarksBegin(),
            pMarkAccess->getBookmarksEnd(),
            aEndOfPara,
            bind(&::sw::mark::IMark::StartsAfter, _2, _1)); // finds the first that starts after

        // search for all bookmarks that start or end in this paragraph
        const SwNodeIndex nOwnNode = rUnoCrsr.GetPoint()->nNode;
        for(IDocumentMarkAccess::const_iterator_t ppMark = pMarkAccess->getBookmarksBegin();
            ppMark != pCandidatesEnd;
            ++ppMark)
        {
            ::sw::mark::IMark* const pBkmk = ppMark->get();
            bool hasOther = pBkmk->IsExpanded();

            const SwPosition& rStartPos = pBkmk->GetMarkStart();
            if(rStartPos.nNode == nOwnNode)
            {
                const BYTE nType = hasOther ? BKM_TYPE_START : BKM_TYPE_START_END;
                rBkmArr.insert(SwXBookmarkPortion_ImplSharedPtr(
                    new SwXBookmarkPortion_Impl ( SwXBookmarks::GetObject(*pBkmk, &rDoc ), nType, rStartPos)));
            }

            const SwPosition& rEndPos = pBkmk->GetMarkEnd();
            if(rEndPos.nNode == nOwnNode)
            {
                auto_ptr<SwPosition> pCrossRefEndPos;
                const SwPosition* pEndPos = NULL;
                if(hasOther)
                    pEndPos = &rEndPos;
                else if(dynamic_cast< ::sw::mark::CrossRefBookmark*>(pBkmk))
                {
                    // Crossrefbookmarks only remember the start position but have to span the whole paragraph
                    pCrossRefEndPos = auto_ptr<SwPosition>(new SwPosition(rEndPos));
                    pCrossRefEndPos->nContent = pCrossRefEndPos->nNode.GetNode().GetTxtNode()->Len();
                    pEndPos = pCrossRefEndPos.get();
                }
                if(pEndPos)
                    rBkmArr.insert(SwXBookmarkPortion_ImplSharedPtr(
                        new SwXBookmarkPortion_Impl ( SwXBookmarks::GetObject(*pBkmk, &rDoc ), BKM_TYPE_END, *pEndPos)));
            }
        }
    }
}

/******************************************************************
 *  SwXTextPortionEnumeration
 ******************************************************************/
@@ -246,51 +349,6 @@ void lcl_InsertTOXMarkPortion(
        pPortion->SetTOXMark(xContent);
    }
}
//-----------------------------------------------------------------------------
#define BKM_TYPE_START          0
#define BKM_TYPE_END            1
#define BKM_TYPE_START_END      2
struct SwXBookmarkPortion_Impl
{
    Reference<XTextContent>     xBookmark;
    BYTE                        nBkmType;
    const SwPosition            aPosition;

    SwXBookmarkPortion_Impl( SwXBookmark* pXMark, BYTE nType, const SwPosition &rPosition )
    : xBookmark ( pXMark )
    , nBkmType  ( nType )
    , aPosition ( rPosition )
    {
    }
    ULONG getIndex ()
    {
        return aPosition.nContent.GetIndex();
    }
};

typedef boost::shared_ptr < SwXBookmarkPortion_Impl > SwXBookmarkPortion_ImplSharedPtr;
struct BookmarkCompareStruct
{
    bool operator () ( const SwXBookmarkPortion_ImplSharedPtr &r1,
                       const SwXBookmarkPortion_ImplSharedPtr &r2 )
    {
        // #i16896# for bookmark portions at the same position, the start should
        // always precede the end. Hence compare positions, and use bookmark type
        // as tie-breaker for same position.
        // return ( r1->nIndex   == r2->nIndex )
        //   ? ( r1->nBkmType <  r2->nBkmType )
        //   : ( r1->nIndex   <  r2->nIndex );

        // MTG: 25/11/05: Note that the above code does not correctly handle
        // the case when one bookmark ends, and another begins in the same
        // position. When this occurs, the above code will return the
        // the start of the 2nd bookmark BEFORE the end of the first bookmark
        // See bug #i58438# for more details. The below code is correct and
        // fixes both #i58438 and #i16896#
        return r1->aPosition < r2->aPosition;
    }
};
typedef std::multiset < SwXBookmarkPortion_ImplSharedPtr, BookmarkCompareStruct > SwXBookmarkPortion_ImplList;

//-----------------------------------------------------------------------------
void lcl_ExportBookmark(
@@ -641,79 +699,7 @@ Reference<XTextRange> lcl_ExportHints(SwpHints* pHints,
    }
    return xRef;
}
//-----------------------------------------------------------------------------
void lcl_FillBookmarkArray(SwDoc& rDoc,SwUnoCrsr& rUnoCrsr, SwXBookmarkPortion_ImplList& rBkmArr )
{
    const SwBookmarks& rMarks = rDoc.getBookmarks();
    sal_uInt16 nArrLen = rMarks.Count();
    if ( nArrLen > 0 )
    {
        const SwNodeIndex nOwnNode = rUnoCrsr.GetPoint()->nNode;
        //search for all bookmarks that start or end in this paragraph
        for( sal_uInt16 n = 0; n < nArrLen; ++n )
        {
            SwBookmark* pMark = rMarks.GetObject( n );
            /*
            if (pMark!=NULL && pMark->GetName().CompareToAscii(FIELD_BOOKMARK_PREFIX, strlen(FIELD_BOOKMARK_PREFIX))==0) {
                continue;
            }

            if (pMark!=NULL && pMark->GetName().CompareToAscii(FIELD_FORM_BOOKMARK_PREFIX, strlen(FIELD_FORM_BOOKMARK_PREFIX))==0) {
                continue;
            }
            */
            if (pMark!=NULL && pMark->IsFormFieldMark())
            {
                continue;
            }

            // --> OD 2007-10-23 #i81002#
            if ( !pMark->IsBookMark() &&
                 !dynamic_cast<SwCrossRefBookmark*>(pMark) )
                continue;

            const SwPosition& rPos1 = pMark->GetBookmarkPos();
            // --> OD 2007-10-23 #i81002#
//            const SwPosition* pPos2 = pMark->GetOtherBookmarkPos();
            const SwPosition* pPos2( 0 );
            SwPosition* pCrossRefBkmkPos2( 0 );
            if ( dynamic_cast<SwCrossRefBookmark*>(pMark) )
            {
                pCrossRefBkmkPos2 = new SwPosition( pMark->GetBookmarkPos() );
                pCrossRefBkmkPos2->nContent =
                        pCrossRefBkmkPos2->nNode.GetNode().GetTxtNode()->Len();
                pPos2 = pCrossRefBkmkPos2;
            }
            else
            {
                pPos2 = pMark->GetOtherBookmarkPos();
            }
            // <--
            BOOL bBackward = pPos2 ? rPos1 > *pPos2: FALSE;
            if(rPos1.nNode == nOwnNode)
            {
                BYTE nType = bBackward ? BKM_TYPE_END : BKM_TYPE_START;
                if(!pPos2)
                {
                    nType = BKM_TYPE_START_END;
                }

                rBkmArr.insert ( SwXBookmarkPortion_ImplSharedPtr (
                    new SwXBookmarkPortion_Impl ( SwXBookmarks::GetObject( *pMark, &rDoc ), nType, rPos1 )));

            }
            if(pPos2 && pPos2->nNode == nOwnNode)
            {
                BYTE nType = bBackward ? BKM_TYPE_START : BKM_TYPE_END;
                rBkmArr.insert( SwXBookmarkPortion_ImplSharedPtr (
                    new SwXBookmarkPortion_Impl( SwXBookmarks::GetObject( *pMark, &rDoc ), nType, *pPos2 ) ) );
            }
            // --> OD 2007-10-23 #i81002#
            delete pCrossRefBkmkPos2;
            // <--
        }
    }
}
//-----------------------------------------------------------------------------
void lcl_FillRedlineArray(SwDoc& rDoc,SwUnoCrsr& rUnoCrsr, SwXRedlinePortion_ImplList& rRedArr )
{
@@ -960,7 +946,6 @@ void SwXTextPortionEnumeration::CreatePortions()
                                aRedArr,
                                aBreakArr,
                                nEndPos);

                        }
                        else if(USHRT_MAX != nFirstFrameIndex)
                        {
@@ -1029,40 +1014,40 @@ void SwXTextPortionEnumeration::CreatePortions()
                        }
                        if (start+1==end && pTxtNode->GetTxt().GetChar(start)==CH_TXT_ATR_FIELDSTART)
                        {
                            SwBookmark* pFieldmark=NULL;
                            ::sw::mark::IFieldmark* pFieldmark = NULL;
                            if (pDoc && pUnoCrsr->GetPoint())
                                pFieldmark=pDoc->getFieldBookmarkFor(*pUnoCrsr->GetPoint());
                            SwXTextPortion* pPortion=NULL;
                            xRef = (pPortion=new SwXTextPortion(pUnoCrsr, xParent, PORTION_FIELD_START));
                                pFieldmark = pDoc->getIDocumentMarkAccess()->getFieldmarkFor(*pUnoCrsr->GetPoint());
                            SwXTextPortion* pPortion = NULL;
                            xRef = (pPortion = new SwXTextPortion(pUnoCrsr, xParent, PORTION_FIELD_START));
                            if (pPortion && pFieldmark && pDoc)
                                pPortion->SetBookmark(new SwXFieldmark(false, pFieldmark, pDoc));
                                    pPortion->SetBookmark(new SwXFieldmark(false, pFieldmark, pDoc));
                        }
                        else if (start+1==end && pTxtNode->GetTxt().GetChar(start)==CH_TXT_ATR_FIELDEND)
                        {
                            SwBookmark* pFieldmark=NULL;
                            ::sw::mark::IFieldmark* pFieldmark = NULL;
                            if (pDoc && pUnoCrsr->GetPoint())
                            {
                                SwPosition aPos(*pUnoCrsr->GetPoint());
                                aPos.nContent=markerPos;
                                pFieldmark=pDoc->getFieldBookmarkFor(aPos);
                                aPos.nContent = markerPos;
                                pFieldmark = pDoc->getIDocumentMarkAccess()->getFieldmarkFor(aPos);
                            }
                            SwXTextPortion* pPortion=NULL;
                            SwXTextPortion* pPortion = NULL;
                            xRef = (pPortion = new SwXTextPortion(pUnoCrsr, xParent, PORTION_FIELD_END));
                            if (pPortion && pFieldmark && pDoc)
                                pPortion->SetBookmark(new SwXFieldmark(false, pFieldmark, pDoc));
                        }
                        else if (start+1==end && pTxtNode->GetTxt().GetChar(start)==CH_TXT_ATR_FORMELEMENT)
                        {
                            SwFieldBookmark* pFieldmark=NULL;
                            ::sw::mark::IFieldmark* pFieldmark = NULL;
                            if (pDoc && pUnoCrsr->GetPoint())
                            {
                                SwPosition aPos(*pUnoCrsr->GetPoint());
                                aPos.nContent=markerPos;
                                pFieldmark=pDoc->getFormFieldBookmarkFor(aPos);
                                pFieldmark = pDoc->getIDocumentMarkAccess()->getFieldmarkFor(aPos);
                            }
                            SwXTextPortion* pPortion=NULL;
                            xRef = (pPortion = new SwXTextPortion(pUnoCrsr, xParent, PORTION_FIELD_START_END));
                            if (pPortion && pFieldmark && pDoc)
                            if(pPortion && pFieldmark && pDoc)
                                pPortion->SetBookmark(new SwXFieldmark(true, pFieldmark, pDoc));
                        }
                        else
diff --git a/sw/source/core/unocore/unotext.cxx b/sw/source/core/unocore/unotext.cxx
index aa87d98..f1640d5 100644
--- a/sw/source/core/unocore/unotext.cxx
+++ b/sw/source/core/unocore/unotext.cxx
@@ -59,7 +59,7 @@
#include <redline.hxx>
#include <swundo.hxx>
#include <section.hxx>
#include <bookmrk.hxx>
#include <IMark.hxx>
#include <fmthbsh.hxx>
#include <fmtanchr.hxx>
#include <crsskip.hxx>
@@ -235,12 +235,11 @@ uno::Sequence< uno::Type > SAL_CALL SwXText::getTypes() throw(uno::RuntimeExcept
    return aRet;
}

/*-- 09.12.98 12:43:14---------------------------------------------------
    Gehoert der Range in den Text ? - dann einfuegen
  -----------------------------------------------------------------------*/
void SwXText::insertString(const uno::Reference< text::XTextRange > & xTextRange,
                                const OUString& aString, sal_Bool bAbsorb)
                                throw( uno::RuntimeException )
// belongs the range in the text ? insert it then.
void SwXText::insertString(const uno::Reference< text::XTextRange >& xTextRange,
    const OUString& aString,
    sal_Bool bAbsorb)
        throw( uno::RuntimeException )
{
    vos::OGuard aGuard(Application::GetSolarMutex());
    if(GetDoc() && xTextRange.is())
@@ -274,16 +273,12 @@ void SwXText::insertString(const uno::Reference< text::XTextRange > & xTextRange
            }
            else //dann pRange
            {
                SwBookmark* pBkm = pRange->GetBookmark();
                const SwStartNode* pTmp = pBkm->GetBookmarkPos().nNode.GetNode().StartOfSectionNode();
                while( pTmp && pTmp->IsSectionNode())
                {
                ::sw::mark::IMark const * const pBkmk = pRange->GetBookmark();
                const SwStartNode* pTmp = pBkmk->GetMarkPos().nNode.GetNode().StartOfSectionNode();
                while(pTmp && pTmp->IsSectionNode())
                    pTmp = pTmp->StartOfSectionNode();
                }
                if( !pOwnStartNode || pOwnStartNode != pTmp)
                {
                if(!pOwnStartNode || pOwnStartNode != pTmp)
                    throw uno::RuntimeException();
                }
            }
            if(bAbsorb)
            {
@@ -298,27 +293,23 @@ void SwXText::insertString(const uno::Reference< text::XTextRange > & xTextRange
                //Text davor eingefuegt wird
                UnoActionContext aContext(GetDoc());
                const SwPosition* pPos = pCursor
                                         ? pCursor->GetPaM()->Start()
                                         : pRange->GetBookmark()->BookmarkStart();
                    ? pCursor->GetPaM()->Start()
                    : &pRange->GetBookmark()->GetMarkStart();
                SwPaM aInsertPam(*pPos);
                sal_Bool bGroupUndo = GetDoc()->DoesGroupUndo();
                GetDoc()->DoGroupUndo(sal_False);

                SwUnoCursorHelper::DocInsertStringSplitCR( *GetDoc(), aInsertPam, aString );

                SwUnoCursorHelper::DocInsertStringSplitCR(*GetDoc(), aInsertPam, aString);
                GetDoc()->DoGroupUndo(bGroupUndo);
            }
        }
        else
        {
            throw uno::RuntimeException();
        }
    }
    else
    {
        throw uno::RuntimeException();
    }
}

/*-- 09.12.98 12:43:16---------------------------------------------------

  -----------------------------------------------------------------------*/
@@ -484,8 +475,8 @@ void SwXText::insertTextContent(const uno::Reference< text::XTextRange > & xRang
            }
            else if (pRange && pRange->GetBookmark())
            {
                SwBookmark* pBkm = pRange->GetBookmark();
                pSrcNode = &pBkm->GetBookmarkPos().nNode.GetNode();
                ::sw::mark::IMark const * const pBkmk = pRange->GetBookmark();
                pSrcNode = &pBkmk->GetMarkPos().nNode.GetNode();
            }
            else if (pPortion && pPortion->GetCrsr())
            {
@@ -1002,11 +993,10 @@ void SwXText::setString(const OUString& aString) throw( uno::RuntimeException )
    xRet->setString(aString);
    GetDoc()->EndUndo(UNDO_END, NULL);
}
/* -----------------------------28.03.00 11:12--------------------------------
    Description: Checks if pRange/pCursor are member of the same text interface.
                Only one of the pointers has to be set!
 ---------------------------------------------------------------------------*/
sal_Bool    SwXText::CheckForOwnMember(

//  Description: Checks if pRange/pCursor are member of the same text interface.
//              Only one of the pointers has to be set!
sal_Bool SwXText::CheckForOwnMember(
    const SwXTextRange* pRange,
    const OTextCursorHelper* pCursor)
        throw(lang::IllegalArgumentException, uno::RuntimeException)
@@ -1039,37 +1029,30 @@ sal_Bool    SwXText::CheckForOwnMember(

    const SwNode* pSrcNode;
    if(pCursor)
    {
        pSrcNode = pCursor->GetPaM()->GetNode();
    }
    else //dann pRange
    {
        SwBookmark* pBkm = pRange->GetBookmark();
        pSrcNode = &pBkm->GetBookmarkPos().nNode.GetNode();
        ::sw::mark::IMark const * const pBkmk = pRange->GetBookmark();
        pSrcNode = &pBkmk->GetMarkPos().nNode.GetNode();
    }
    const SwStartNode* pTmp = pSrcNode->FindSttNodeByType(eSearchNodeType);

    //SectionNodes ueberspringen
    while(pTmp && pTmp->IsSectionNode())
    {
        pTmp = pTmp->StartOfSectionNode();
    }

    //if the document starts with a section
    while(pOwnStartNode->IsSectionNode())
    {
        pOwnStartNode = pOwnStartNode->StartOfSectionNode();
    }

    //this checks if (this) and xRange are in the same text::XText interface
    return(pOwnStartNode == pTmp);
}

/* -----------------------------28.03.00 11:07--------------------------------

 ---------------------------------------------------------------------------*/
sal_Int16 SwXText::ComparePositions(
    const uno::Reference<text::XTextRange>& xPos1,
    const uno::Reference<text::XTextRange>& xPos2)
            throw(lang::IllegalArgumentException, uno::RuntimeException)
        throw(lang::IllegalArgumentException, uno::RuntimeException)
{
    sal_Int16 nCompare = 0;
    SwUnoInternalPaM aPam1(*GetDoc());
@@ -1109,12 +1092,12 @@ sal_Int16 SwXText::ComparePositions(
                const SwPosition *pStart2 = 0;

                if(pRange1)
                    pStart1 = pRange1->GetBookmark() ? pRange1->GetBookmark()->BookmarkStart() : 0;
                    pStart1 = pRange1->GetBookmark() ? &(pRange1->GetBookmark()->GetMarkStart()) : 0;
                else
                    pStart1 = pCursor1->GetPaM() ? pCursor1->GetPaM()->Start() : 0;

                if(pRange2)
                    pStart2 = pRange2->GetBookmark() ? pRange2->GetBookmark()->BookmarkStart() : 0;
                    pStart2 = pRange2->GetBookmark() ? &(pRange2->GetBookmark()->GetMarkStart()) : 0;
                else
                    pStart2 = pCursor2->GetPaM() ? pCursor2->GetPaM()->Start() : 0;

@@ -1598,10 +1581,9 @@ uno::Reference< text::XTextRange > SwXText::appendTextContent(
    }
    return xRet;
}
/*-- 11.05.2006 15:46:26---------------------------------------------------
    move previously appended paragraphs into a text frames
    to support import filters
  -----------------------------------------------------------------------*/

// move previously appended paragraphs into a text frames
// to support import filters
uno::Reference< text::XTextContent > SwXText::convertToTextFrame(
    const uno::Reference< text::XTextRange >& xStart,
    const uno::Reference< text::XTextRange >& xEnd,
@@ -1623,18 +1605,18 @@ uno::Reference< text::XTextContent > SwXText::convertToTextFrame(
        uno::Reference<lang::XUnoTunnel> xEndRangeTunnel( xEnd, uno::UNO_QUERY);
        SwXTextRange* pEndRange  = reinterpret_cast< SwXTextRange * >(
                   sal::static_int_cast< sal_IntPtr >( xEndRangeTunnel->getSomething( SwXTextRange::getUnoTunnelId()) ));
        //bokmarks have to be removed before the referenced text node is deleted in DelFullPara
        if( pStartRange )
        //bookmarks have to be removed before the referenced text node is deleted in DelFullPara
        if(pStartRange)
        {
            SwBookmark* pStartBookmark = pStartRange->GetBookmark();
            if( pStartBookmark )
                pDoc->deleteBookmark( pStartBookmark->GetName() );
            ::sw::mark::IMark const * const pStartBookmark = pStartRange->GetBookmark();
            if(pStartBookmark)
                pDoc->getIDocumentMarkAccess()->deleteMark(pStartBookmark);
        }
        if( pEndRange )
        if(pEndRange)
        {
            SwBookmark* pEndBookmark = pEndRange->GetBookmark();
            if( pEndBookmark )
                pDoc->deleteBookmark( pEndBookmark->GetName() );
            ::sw::mark::IMark const * const pEndBookmark = pEndRange->GetBookmark();
            if(pEndBookmark)
                pDoc->getIDocumentMarkAccess()->deleteMark(pEndBookmark);
        }

        pDoc->StartUndo( UNDO_START, NULL );
diff --git a/sw/source/core/view/viewsh.cxx b/sw/source/core/view/viewsh.cxx
index b63a32d..e5f901b 100644
--- a/sw/source/core/view/viewsh.cxx
+++ b/sw/source/core/view/viewsh.cxx
@@ -2698,8 +2698,8 @@ const IDocumentSettingAccess* ViewShell::getIDocumentSettingAccess() const { ret
IDocumentSettingAccess* ViewShell::getIDocumentSettingAccess() { return pDoc; }
const IDocumentDeviceAccess* ViewShell::getIDocumentDeviceAccess() const { return pDoc; }
IDocumentDeviceAccess* ViewShell::getIDocumentDeviceAccess() { return pDoc; }
const IDocumentBookmarkAccess* ViewShell::getIDocumentBookmarkAccess() const { return pDoc; }
IDocumentBookmarkAccess* ViewShell::getIDocumentBookmarkAccess() { return pDoc; }
const IDocumentMarkAccess* ViewShell::getIDocumentMarkAccess() const { return pDoc->getIDocumentMarkAccess(); }
IDocumentMarkAccess* ViewShell::getIDocumentMarkAccess() { return pDoc->getIDocumentMarkAccess(); }
const IDocumentDrawModelAccess* ViewShell::getIDocumentDrawModelAccess() const { return pDoc; }
IDocumentDrawModelAccess* ViewShell::getIDocumentDrawModelAccess() { return pDoc; }
const IDocumentRedlineAccess* ViewShell::getIDocumentRedlineAccess() const { return pDoc; }
diff --git a/sw/source/filter/html/htmlgrin.cxx b/sw/source/filter/html/htmlgrin.cxx
index a29fd32..3bb7686 100644
--- a/sw/source/filter/html/htmlgrin.cxx
+++ b/sw/source/filter/html/htmlgrin.cxx
@@ -75,12 +75,13 @@
#include <ndtxt.hxx>
#include <shellio.hxx>
#include <poolfmt.hxx>
#include <bookmrk.hxx>
#include <IMark.hxx>
#include <ndgrf.hxx>
#include <htmlnum.hxx>
#include <swcss1.hxx>
#include <swhtml.hxx>
#include <numrule.hxx>
#include <boost/shared_ptr.hpp>

using namespace ::com::sun::star;

@@ -1285,9 +1286,9 @@ BOOL SwHTMLParser::HasCurrentParaBookmarks( BOOL bIgnoreStack ) const
    BOOL bHasMarks = FALSE;
    ULONG nNodeIdx = pPam->GetPoint()->nNode.GetIndex();

    // 1. Schritt: befinden sich noch Bookmarks m Attribut-Stack?
    // Bookmarks werden hinten in den Stack geschrieben. Wir muessen
    // also nur die letzte Bookmark betrachten
    // first step: are there still bookmark in the attribute-stack?
    // bookmarks are added to the end of the stack - thus we only have
    // to check the last bookmark
    if( !bIgnoreStack )
    {
        _HTMLAttr* pAttr;
@@ -1305,13 +1306,15 @@ BOOL SwHTMLParser::HasCurrentParaBookmarks( BOOL bIgnoreStack ) const

    if( !bHasMarks )
    {
        // 2. Schritt: Wenn wir keine Bookmark gefunden haben, schauen wir,
        // ob schon eine gesetzt ist
        const SwBookmarks& rBookmarks = pDoc->getBookmarks();
        for( USHORT i=0; i<rBookmarks.Count(); i++ )
        // second step: when we didnt find a bookmark, check if there is one
        // set already
        IDocumentMarkAccess* const pMarkAccess = pDoc->getIDocumentMarkAccess();
        for(IDocumentMarkAccess::const_iterator_t ppMark = pMarkAccess->getMarksBegin();
            ppMark != pMarkAccess->getMarksEnd();
            ppMark++)
        {
            const SwBookmark* pBookmark = rBookmarks[i];
            ULONG nBookNdIdx = pBookmark->GetBookmarkPos().nNode.GetIndex();
            const ::sw::mark::IMark* pBookmark = ppMark->get();
            ULONG nBookNdIdx = pBookmark->GetMarkPos().nNode.GetIndex();
            if( nBookNdIdx==nNodeIdx )
            {
                bHasMarks = TRUE;
@@ -1377,33 +1380,30 @@ void SwHTMLParser::StripTrailingPara()

            // jetz muessen wir noch eventuell vorhandene Bookmarks
            // verschieben
            const SwBookmarks& rBookmarks = pDoc->getBookmarks();
            for( i=0; i<rBookmarks.Count(); i++ )
            IDocumentMarkAccess* const pMarkAccess = pDoc->getIDocumentMarkAccess();
            for(IDocumentMarkAccess::const_iterator_t ppMark = pMarkAccess->getMarksBegin();
                ppMark != pMarkAccess->getMarksEnd();
                ppMark++)
            {
                SwBookmark* pBookmark = rBookmarks[i];
                ULONG nBookNdIdx = pBookmark->GetBookmarkPos().nNode.GetIndex();
                if( nBookNdIdx==nNodeIdx )
                ::sw::mark::IMark* pMark = ppMark->get();
                ULONG nBookNdIdx = pMark->GetMarkPos().nNode.GetIndex();
                if(nBookNdIdx==nNodeIdx)
                {
                    // --> OD 2007-09-27 #i81002# - refactoring
                    // Do not directly manipulate member of <SwBookmark>
//                    SwPosition &rBookmkPos =
//                        (SwPosition&)pBookmark->GetBookmarkPos();
                    // <--

                    SwNodeIndex nNewNdIdx( pPam->GetPoint()->nNode );
                    SwCntntNode* pNd = pDoc->GetNodes().GoPrevious( &nNewNdIdx );
                    if( !pNd )
                    SwNodeIndex nNewNdIdx(pPam->GetPoint()->nNode);
                    SwCntntNode* pNd = pDoc->GetNodes().GoPrevious(&nNewNdIdx);
                    if(!pNd)
                    {
                        ASSERT( !this, "Hoppla, wo ist mein Vorgaenger-Node" );
                        ASSERT(!this, "Hoppla, wo ist mein Vorgaenger-Node");
                        return;
                    }

                    // --> OD 2007-09-27 #i81002# - refactoring
                    // Do not directly manipulate member of <SwBookmark>
                    SwPosition aNewPos ( pBookmark->GetBookmarkPos() );
                    aNewPos.nNode = nNewNdIdx;
                    aNewPos.nContent.Assign( pNd, pNd->Len() );
                    pBookmark->SetBookmarkPos( &aNewPos );
                    {
                        SwPosition aNewPos(*pNd);
                        aNewPos.nContent.Assign(pNd, pNd->Len());
                        const SwPaM aPaM(aNewPos);
                        pMarkAccess->repositionMark(ppMark->get(), aPaM);
                    }
                    // <--
                }
                else if( nBookNdIdx > nNodeIdx )
diff --git a/sw/source/filter/html/swhtml.cxx b/sw/source/filter/html/swhtml.cxx
index e39cd88a..17c6961 100644
--- a/sw/source/filter/html/swhtml.cxx
+++ b/sw/source/filter/html/swhtml.cxx
@@ -98,7 +98,7 @@
#include <expfld.hxx>
#include <poolfmt.hxx>
#include <pagedesc.hxx>
#include <bookmrk.hxx>      // fuer SwBookmark ...
#include <IMark.hxx>        // fuer SwBookmark ...
#ifndef _DOCSH_HXX
#include <docsh.hxx>
#endif
@@ -2760,26 +2760,22 @@ void SwHTMLParser::_SetAttr( BOOL bChkEnd, BOOL bBeforeTable,

                switch( nWhich )
                {
                case RES_FLTR_BOOKMARK:     // dann also ein Bookmark einfuegen
                case RES_FLTR_BOOKMARK: // insert bookmark
                    {
                        String aName( ((SfxStringItem*)pAttr->pItem)->GetValue() );
                        USHORT nBookPos = pDoc->findBookmark( aName );
                        if( nBookPos != USHRT_MAX )
                        {
                            const SwBookmark *pBkMk =
                                pDoc->getBookmarks()[nBookPos];
                            if( pBkMk->GetBookmarkPos() != *pAttrPam->GetPoint() )
                                pDoc->makeUniqueBookmarkName( aName );
                            else
                                break; // keine doppelte Bookmark an dieser Pos
                        }
                        const String sName( ((SfxStringItem*)pAttr->pItem)->GetValue() );
                        IDocumentMarkAccess* const pMarkAccess = pDoc->getIDocumentMarkAccess();
                        IDocumentMarkAccess::const_iterator_t ppBkmk = pMarkAccess->findMark( sName );
                        if( ppBkmk != pMarkAccess->getMarksEnd() &&
                            ppBkmk->get()->GetMarkStart() == *pAttrPam->GetPoint() )
                            break; // do not generate duplicates on this position
                        pAttrPam->DeleteMark();
                        pDoc->makeBookmark( *pAttrPam, KeyCode(),
                                            aName, aEmptyStr, IDocumentBookmarkAccess::BOOKMARK );
                        const ::sw::mark::IMark* const pNewMark = pMarkAccess->makeMark(
                            *pAttrPam,
                            sName,
                            IDocumentMarkAccess::BOOKMARK );

                        // ggfs. ein Bookmark anspringen
                        if( JUMPTO_MARK == eJumpTo &&
                            aName == sJmpMark )
                        // jump to bookmark
                        if( JUMPTO_MARK == eJumpTo && pNewMark->GetName() == ::rtl::OUString(sJmpMark) )
                        {
                            bChkJumpMark = TRUE;
                            eJumpTo = JUMPTO_NONE;
diff --git a/sw/source/filter/html/wrthtml.cxx b/sw/source/filter/html/wrthtml.cxx
index 4453539..2baaa46 100644
--- a/sw/source/filter/html/wrthtml.cxx
+++ b/sw/source/filter/html/wrthtml.cxx
@@ -76,7 +76,7 @@
#include <mdiexp.hxx>       // ...Percent()
#include <fltini.hxx>
#include <viewopt.hxx>
#include <bookmrk.hxx>      // fuer SwBookmark ...
#include <IMark.hxx>        // fuer SwBookmark ...
#include <poolfmt.hxx>
#include <pagedesc.hxx>
#include <section.hxx>
@@ -111,7 +111,7 @@ SwHTMLWriter::SwHTMLWriter( const String& rBaseURL )
{
    SetBaseURL( rBaseURL );
    bFirstLine = sal_True;
    nBkmkTabPos = USHRT_MAX;
    nBkmkTabPos = -1;
    pDfltColor = 0;
    nImgMapCnt = 1;
    pStartNdIdx = 0;
@@ -744,7 +744,7 @@ void SwHTMLWriter::Out_SwDoc( SwPaM* pPam )
    sal_Bool bSaveWriteAll = bWriteAll;     // sichern

    // suche die naechste text::Bookmark-Position aus der text::Bookmark-Tabelle
    nBkmkTabPos = bWriteAll ? FindPos_Bkmk( *pCurPam->GetPoint() ) : USHRT_MAX;
    nBkmkTabPos = bWriteAll ? FindPos_Bkmk( *pCurPam->GetPoint() ) : -1;

    // gebe alle Bereiche des Pams in das HTML-File aus.
    do {
@@ -774,12 +774,12 @@ void SwHTMLWriter::Out_SwDoc( SwPaM* pPam )
            else if( pNd->IsTableNode() )
            {
                OutHTML_SwTblNode( *this, *pNd->GetTableNode(), 0 );
                nBkmkTabPos = bWriteAll ? FindPos_Bkmk( *pCurPam->GetPoint() ) : USHRT_MAX;
                nBkmkTabPos = bWriteAll ? FindPos_Bkmk( *pCurPam->GetPoint() ) : -1;
            }
            else if( pNd->IsSectionNode() )
            {
                OutHTML_Section( *this, *pNd->GetSectionNode() );
                nBkmkTabPos = bWriteAll ? FindPos_Bkmk( *pCurPam->GetPoint() ) : USHRT_MAX;
                nBkmkTabPos = bWriteAll ? FindPos_Bkmk( *pCurPam->GetPoint() ) : -1;
            }
            else if( pNd == &pDoc->GetNodes().GetEndOfContent() )
                break;
@@ -1064,25 +1064,27 @@ void SwHTMLWriter::OutAnchor( const String& rName )
void SwHTMLWriter::OutBookmarks()
{
    // hole das aktuelle Bookmark
    const SwBookmark* pBookmark = USHRT_MAX != nBkmkTabPos ?
                            pDoc->getBookmarks()[ nBkmkTabPos ] : 0;
    const ::sw::mark::IMark* pBookmark = NULL;
    IDocumentMarkAccess* const pMarkAccess = pDoc->getIDocumentMarkAccess();
    if(nBkmkTabPos != -1)
        pBookmark = (pMarkAccess->getMarksBegin() + nBkmkTabPos)->get();
    // Ausgabe aller Bookmarks in diesem Absatz. Die Content-Position
    // wird vorerst nicht beruecksichtigt!
    sal_uInt32 nNode = pCurPam->GetPoint()->nNode.GetIndex();
    while( USHRT_MAX != nBkmkTabPos &&
        pBookmark->GetBookmarkPos().nNode.GetIndex() == nNode )
    while( nBkmkTabPos != -1 &&
        pBookmark->GetMarkPos().nNode.GetIndex() == nNode )
    {
        // Der Bereich derBookmark wird erstam ignoriert, da er von uns
        // auch nicht eingelesen wird.

        // erst die SWG spezifischen Daten:
        if( pBookmark->IsBookMark() && pBookmark->GetName().Len() )
        if(dynamic_cast< const ::sw::mark::IBookmark* >(pBookmark) && pBookmark->GetName().getLength() )
            OutAnchor( pBookmark->GetName() );

        if( ++nBkmkTabPos >= pDoc->getBookmarks().Count() )
            nBkmkTabPos = USHRT_MAX;
        if( ++nBkmkTabPos >= pMarkAccess->getMarksCount() )
            nBkmkTabPos = -1;
        else
            pBookmark = pDoc->getBookmarks()[ nBkmkTabPos ];
            pBookmark = (pMarkAccess->getMarksBegin() + nBkmkTabPos)->get();
    }

    sal_uInt16 nPos;
@@ -1407,7 +1409,7 @@ HTMLSaveData::~HTMLSaveData()
    rWrt.pCurPam = pOldPam;
    rWrt.SetEndPaM( pOldEnd );
    rWrt.bWriteAll = bOldWriteAll;
    rWrt.nBkmkTabPos = bOldWriteAll ? rWrt.FindPos_Bkmk( *pOldPam->GetPoint() ) : USHRT_MAX;
    rWrt.nBkmkTabPos = bOldWriteAll ? rWrt.FindPos_Bkmk( *pOldPam->GetPoint() ) : -1;
    rWrt.nLastParaToken = 0;
    rWrt.nDefListLvl = nOldDefListLvl;
    rWrt.nDirection = nOldDirection;
diff --git a/sw/source/filter/html/wrthtml.hxx b/sw/source/filter/html/wrthtml.hxx
index 03041f5..6118430 100644
--- a/sw/source/filter/html/wrthtml.hxx
+++ b/sw/source/filter/html/wrthtml.hxx
@@ -258,7 +258,7 @@ public:
    sal_uInt32 nLastLFPos;              // letzte Position eines LF

    sal_uInt16 nLastParaToken;          // fuers Absaetze zusammenhalten
    sal_uInt16 nBkmkTabPos;             // akt. Position in der Bookmark-Tabelle
    sal_Int32 nBkmkTabPos;              // akt. Position in der Bookmark-Tabelle
    sal_uInt16 nImgMapCnt;              // zum eindeutig
    sal_uInt16 nFormCntrlCnt;
    sal_uInt16 nEndNote;
diff --git a/sw/source/filter/rtf/swparrtf.cxx b/sw/source/filter/rtf/swparrtf.cxx
index fd9b851..20d2849 100644
--- a/sw/source/filter/rtf/swparrtf.cxx
+++ b/sw/source/filter/rtf/swparrtf.cxx
@@ -1785,7 +1785,7 @@ void SwRTFParser::NextToken( int nToken )
                                        aBookmarkEnd.maMkNode, aBookmarkEnd.mnMkCntnt);
                if (*mpBookmarkStart == aBookmarkEnd)
                    aBookmarkRegion.DeleteMark();
                pDoc->makeBookmark(aBookmarkRegion, aEmptyKeyCode, sBookmark, aEmptyStr, IDocumentBookmarkAccess::BOOKMARK);
                pDoc->getIDocumentMarkAccess()->makeMark(aBookmarkRegion, sBookmark, IDocumentMarkAccess::BOOKMARK);
            }
            delete mpBookmarkStart, mpBookmarkStart = 0;
        }
diff --git a/sw/source/filter/rtf/wrtrtf.cxx b/sw/source/filter/rtf/wrtrtf.cxx
index 84eb60c..08c9f87 100644
--- a/sw/source/filter/rtf/wrtrtf.cxx
+++ b/sw/source/filter/rtf/wrtrtf.cxx
@@ -67,7 +67,7 @@
#include <ndtxt.hxx>
#include <wrtrtf.hxx>
#include <flypos.hxx>
#include <bookmrk.hxx>      // fuer SwBookmark ...
#include <IMark.hxx>
#include <pagedesc.hxx>     // fuer SwPageDesc...
#include <ftninfo.hxx>
#include <charfmt.hxx>
@@ -133,7 +133,7 @@ ULONG SwRTFWriter::WriteStream()


    pCurEndPosLst = 0;
    nBkmkTabPos = USHRT_MAX;
    nBkmkTabPos = -1;
    pAktPageDesc = 0;
    pAttrSet = 0;
    pFlyFmt = 0;        // kein FlyFrmFormat gesetzt
@@ -262,7 +262,7 @@ void SwRTFWriter::Out_SwDoc( SwPaM* pPam )
{
    BOOL bSaveWriteAll = bWriteAll;     // sichern
    // suche die naechste Bookmark-Position aus der Bookmark-Tabelle
    nBkmkTabPos = bWriteAll ? FindPos_Bkmk( *pCurPam->GetPoint() ) : USHRT_MAX;
    nBkmkTabPos = bWriteAll ? FindPos_Bkmk( *pCurPam->GetPoint() ) : -1;

    // gebe alle Bereiche des Pams in das RTF-File aus.
    do {
@@ -1237,31 +1237,18 @@ void SwRTFWriter::OutRedline( xub_StrLen nCntntPos )
        }
}

void SwRTFWriter::OutBookmarks( xub_StrLen nCntntPos )
void SwRTFWriter::OutBookmarks( xub_StrLen nCntntPos)
{
    if (USHRT_MAX == nBkmkTabPos)
    IDocumentMarkAccess* const pMarkAccess = pDoc->getIDocumentMarkAccess();
    if (-1 == nBkmkTabPos)
        return;

    const SwBookmark* pBookmark = pDoc->getBookmarks()[nBkmkTabPos];
    if (!pBookmark)
    const ::sw::mark::IMark* pBookmark = (pMarkAccess->getMarksBegin() + nBkmkTabPos)->get();
    if(!pBookmark)
        return;

    // hole das aktuelle Bookmark
    const SwPosition* pStartPos = 0;
    const SwPosition* pEndPos = 0;

    if (pBookmark->GetOtherBookmarkPos())   // this bookmark spans text
    {
        // the start and endpoints are different
        SwPaM mPam(pBookmark->GetBookmarkPos(), *pBookmark->GetOtherBookmarkPos());
        pStartPos = mPam.Start();
        pEndPos = mPam.End();
    }
    else                            // this bookmark is a point
    {
        // so the start and endpoints are the same
        pStartPos = pEndPos = &pBookmark->GetBookmarkPos();
    }
    const SwPosition* pStartPos = &pBookmark->GetMarkStart();
    const SwPosition* pEndPos = &pBookmark->GetMarkEnd();

    ASSERT(pStartPos && pEndPos, "Impossible");
    if (!(pStartPos && pEndPos))
@@ -1274,20 +1261,18 @@ void SwRTFWriter::OutBookmarks( xub_StrLen nCntntPos )
        // es hier vollstaendig ausgegeben werden.

        // erst die SWG spezifischen Daten:
        if (
             pBookmark->GetShortName().Len() ||
             pBookmark->GetKeyCode().GetCode()
           )
        const ::sw::mark::IBookmark* const pAsBookmark = dynamic_cast< const ::sw::mark::IBookmark* >(pBookmark);
        if(pAsBookmark && (pAsBookmark->GetShortName().getLength() || pAsBookmark->GetKeyCode().GetCode()))
        {
            OutComment( *this, sRTF_BKMKKEY );
            OutULong( ( pBookmark->GetKeyCode().GetCode() |
                     pBookmark->GetKeyCode().GetModifier() ));
            if( !pBookmark->GetShortName().Len() )
            OutULong( ( pAsBookmark->GetKeyCode().GetCode() |
                     pAsBookmark->GetKeyCode().GetModifier() ));
            if( !pAsBookmark->GetShortName().getLength() )
                Strm() << "  " ;
            else
            {
                Strm() << ' ';
                OutRTF_AsByteString( *this, pBookmark->GetShortName(), eDefaultEncoding );
                OutRTF_AsByteString( *this, pAsBookmark->GetShortName(), eDefaultEncoding );
            }
            Strm() << '}';
        }
@@ -1303,31 +1288,29 @@ void SwRTFWriter::OutBookmarks( xub_StrLen nCntntPos )
        // es hier vollstaendig ausgegeben werden.

        // erst die SWG spezifischen Daten:
        if (
             pBookmark->GetShortName().Len() ||
             pBookmark->GetKeyCode().GetCode()
           )
        const ::sw::mark::IBookmark* const pAsBookmark = dynamic_cast< const ::sw::mark::IBookmark* >(pBookmark);
        if(pAsBookmark && (pAsBookmark->GetShortName().getLength() || pAsBookmark->GetKeyCode().GetCode()))
        {
            OutComment( *this, sRTF_BKMKKEY );
            OutULong( ( pBookmark->GetKeyCode().GetCode() |
                     pBookmark->GetKeyCode().GetModifier() ));
            if( !pBookmark->GetShortName().Len() )
            OutULong( ( pAsBookmark->GetKeyCode().GetCode() |
                     pAsBookmark->GetKeyCode().GetModifier() ));
            if( !pAsBookmark->GetShortName().getLength() )
                Strm() << "  " ;
            else
            {
                Strm() << ' ';
                OutRTF_AsByteString( *this, pBookmark->GetShortName(), eDefaultEncoding );
                OutRTF_AsByteString( *this, pAsBookmark->GetShortName(), eDefaultEncoding );
            }
            Strm() << '}';
        }
        OutComment( *this, sRTF_BKMKEND ) << ' ';
        RTFOutFuncs::Out_String( Strm(), pBookmark->GetName(),
        RTFOutFuncs::Out_String( Strm(), pAsBookmark->GetName(),
                                eDefaultEncoding, bWriteHelpFmt ) << '}';

        if( ++nBkmkTabPos >= pDoc->getBookmarks().Count() )
            nBkmkTabPos = USHRT_MAX;
        if(++nBkmkTabPos >= pMarkAccess->getMarksCount())
            nBkmkTabPos = -1;
        else
            pBookmark = pDoc->getBookmarks()[ nBkmkTabPos ];
            pBookmark = (pMarkAccess->getMarksBegin() + nBkmkTabPos)->get();
    }
}

diff --git a/sw/source/filter/rtf/wrtrtf.hxx b/sw/source/filter/rtf/wrtrtf.hxx
index 6ab30e4..16dcb18 100644
--- a/sw/source/filter/rtf/wrtrtf.hxx
+++ b/sw/source/filter/rtf/wrtrtf.hxx
@@ -112,7 +112,7 @@ public:
    const SwFlyFrmFmt* pFlyFmt; // liegt der Node in einem FlyFrame,
                                        // ist das Format gesetzt, sonst 0
    const SwPageDesc* pAktPageDesc;     // aktuell gesetzter PageDesc.
    USHORT nBkmkTabPos;             // akt. Position in der Bookmark-Tabelle
    sal_Int32 nBkmkTabPos;              // akt. Position in der Bookmark-Tabelle
    USHORT nCurScript;                  // actual scripttype
    rtl_TextEncoding eDefaultEncoding;
    rtl_TextEncoding eCurrentEncoding;
diff --git a/sw/source/filter/writer/writer.cxx b/sw/source/filter/writer/writer.cxx
index 12daf9e..b303147 100644
--- a/sw/source/filter/writer/writer.cxx
+++ b/sw/source/filter/writer/writer.cxx
@@ -46,10 +46,10 @@
#include <pam.hxx>
#include <doc.hxx>
#include <docary.hxx>
#include <bookmrk.hxx>          // fuer SwBookmark ...
#include <IMark.hxx>
#include <numrule.hxx>
#include <swerror.h>

#include <boost/bind.hpp>

using namespace ::com::sun::star;

@@ -70,7 +70,7 @@ struct Writer_Impl
    ~Writer_Impl();

    void RemoveFontList( SwDoc& rDoc );
    void InsertBkmk( const SwBookmark& rBkmk );
    void InsertBkmk( const ::sw::mark::IMark& rBkmk );
};

Writer_Impl::Writer_Impl( const SwDoc& /*rDoc*/ )
@@ -102,12 +102,12 @@ void Writer_Impl::RemoveFontList( SwDoc& rDoc )
    }
}

void Writer_Impl::InsertBkmk( const SwBookmark& rBkmk )
void Writer_Impl::InsertBkmk(const ::sw::mark::IMark& rBkmk)
{
    if( !pBkmkNodePos )
        pBkmkNodePos = new SwBookmarkNodeTable;

    ULONG nNd = rBkmk.GetBookmarkPos().nNode.GetIndex();
    ULONG nNd = rBkmk.GetMarkPos().nNode.GetIndex();
    SvPtrarr* pArr = pBkmkNodePos->Get( nNd );
    if( !pArr )
    {
@@ -118,9 +118,9 @@ void Writer_Impl::InsertBkmk( const SwBookmark& rBkmk )
    void* p = (void*)&rBkmk;
    pArr->Insert( p, pArr->Count() );

    if( rBkmk.GetOtherBookmarkPos() && rBkmk.GetOtherBookmarkPos()->nNode != nNd )
    if(rBkmk.IsExpanded() && rBkmk.GetOtherMarkPos().nNode != nNd)
    {
        nNd = rBkmk.GetOtherBookmarkPos()->nNode.GetIndex();
        nNd = rBkmk.GetOtherMarkPos().nNode.GetIndex();
        pArr = pBkmkNodePos->Get( nNd );
        if( !pArr )
        {
@@ -208,26 +208,17 @@ BOOL Writer::CopyNextPam( SwPaM ** ppPam )

// suche die naechste Bookmark-Position aus der Bookmark-Tabelle

USHORT Writer::FindPos_Bkmk( const SwPosition& rPos ) const
sal_Int32 Writer::FindPos_Bkmk(const SwPosition& rPos) const
{
    USHORT nRet = USHRT_MAX;
    const SwBookmarks& rBkmks = pDoc->getBookmarks();

    if( rBkmks.Count() )
    {
        SwBookmark aBkmk( rPos );
        USHORT nPos;
        if( rBkmks.Seek_Entry( &aBkmk, &nPos ))
        {
            // suche abwaerts nach weiteren Bookmarks auf der Cursor-Position
            while( 0 < nPos &&
                rBkmks[ nPos-1 ]->IsEqualPos( aBkmk ))
                --nPos;
        }
        else if( nPos < rBkmks.Count() )
            nRet = nPos;
    }
    return nRet;
    const IDocumentMarkAccess* const pMarkAccess = pDoc->getIDocumentMarkAccess();
    const IDocumentMarkAccess::const_iterator_t ppBkmk = ::std::lower_bound(
        pMarkAccess->getMarksBegin(),
        pMarkAccess->getMarksEnd(),
        rPos,
        ::boost::bind(&::sw::mark::IMark::StartsBefore, _1, _2)); // find the first Mark that does not start before
    if(ppBkmk != pMarkAccess->getMarksEnd())
        return ppBkmk - pMarkAccess->getMarksBegin();
    return -1;
}


@@ -542,19 +533,17 @@ void Writer::_AddFontItem( SfxItemPool& rPool, const SvxFontItem& rFont )
// OtherPos of the bookmarks also inserted.
void Writer::CreateBookmarkTbl()
{
    const SwBookmarks& rBkmks = pDoc->getBookmarks();
    for( USHORT n = rBkmks.Count(); n; )
    {
        const SwBookmark& rBkmk = *rBkmks[ --n ];
        if( rBkmk.IsBookMark() )
            pImpl->InsertBkmk( rBkmk );
    }
    const IDocumentMarkAccess* const pMarkAccess = pDoc->getIDocumentMarkAccess();
    for(IDocumentMarkAccess::const_iterator_t ppBkmk = pMarkAccess->getBookmarksBegin();
        ppBkmk != pMarkAccess->getBookmarksEnd();
        ++ppBkmk)
            pImpl->InsertBkmk(**ppBkmk);
}


// search alle Bookmarks in the range and return it in the Array
USHORT Writer::GetBookmarks( const SwCntntNode& rNd, xub_StrLen nStt,
                             xub_StrLen nEnd, SvPtrarr& rArr )
USHORT Writer::GetBookmarks(const SwCntntNode& rNd, xub_StrLen nStt,
    xub_StrLen nEnd, SvPtrarr& rArr)
{
    ASSERT( !rArr.Count(), "es sind noch Eintraege vorhanden" );

@@ -573,16 +562,16 @@ USHORT Writer::GetBookmarks( const SwCntntNode& rNd, xub_StrLen nStt,
            for( n = 0; n < pArr->Count(); ++n )
            {
                void* p = (*pArr)[ n ];
                const SwBookmark& rBkmk = *(SwBookmark*)p;
                if( rBkmk.GetBookmarkPos().nNode == nNd &&
                    (nCntnt = rBkmk.GetBookmarkPos().nContent.GetIndex() ) >= nStt &&
                const ::sw::mark::IMark& rBkmk = *(::sw::mark::IMark *)p;
                if( rBkmk.GetMarkPos().nNode == nNd &&
                    (nCntnt = rBkmk.GetMarkPos().nContent.GetIndex() ) >= nStt &&
                    nCntnt < nEnd )
                {
                    rArr.Insert( p, rArr.Count() );
                }
                else if( rBkmk.GetOtherBookmarkPos() && nNd ==
                        rBkmk.GetOtherBookmarkPos()->nNode.GetIndex() && (nCntnt =
                        rBkmk.GetOtherBookmarkPos()->nContent.GetIndex() ) >= nStt &&
                else if( rBkmk.IsExpanded() && nNd ==
                        rBkmk.GetOtherMarkPos().nNode.GetIndex() && (nCntnt =
                        rBkmk.GetOtherMarkPos().nContent.GetIndex() ) >= nStt &&
                        nCntnt < nEnd )
                {
                    rArr.Insert( p, rArr.Count() );
diff --git a/sw/source/filter/ww1/fltshell.cxx b/sw/source/filter/ww1/fltshell.cxx
index 754eb86..f1ca77e 100644
--- a/sw/source/filter/ww1/fltshell.cxx
+++ b/sw/source/filter/ww1/fltshell.cxx
@@ -510,7 +510,7 @@ void SwFltControlStack::SetAttrInDoc(const SwPosition& rTmpPos, SwFltStackEntry*
                ( !IsFlagSet(HYPO) || IsFlagSet(BOOK_AND_REF) ) && !pEntry->bConsumedByField)
            {
                MakeBookRegionOrPoint(pEntry, pDoc, aRegion, TRUE);
                pDoc->makeBookmark( aRegion, aEmptyKeyCode, rName, aEmptyStr, IDocumentBookmarkAccess::BOOKMARK);
                pDoc->getIDocumentMarkAccess()->makeMark( aRegion, rName, IDocumentMarkAccess::BOOKMARK);
            }
        }
        break;
diff --git a/sw/source/filter/ww8/wrtw8nds.cxx b/sw/source/filter/ww8/wrtw8nds.cxx
index cb19598..2d6f3b7 100644
--- a/sw/source/filter/ww8/wrtw8nds.cxx
+++ b/sw/source/filter/ww8/wrtw8nds.cxx
@@ -104,7 +104,7 @@
#include <numrule.hxx>
#include "wrtww8.hxx"
#include "ww8par.hxx"
#include <bookmrk.hxx>
#include <IMark.hxx>

using namespace ::com::sun::star;
using namespace ::com::sun::star::i18n;
@@ -1542,44 +1542,44 @@ Writer& OutWW8_SwTxtNode( Writer& rWrt, SwCntntNode& rNode )
        {
            sal_Unicode ch=aStr.GetChar(nAktPos);
            int ofs=(ch==CH_TXT_ATR_FIELDSTART || ch==CH_TXT_ATR_FIELDEND || ch==CH_TXT_ATR_FORMELEMENT?1:0);

            if (ch==CH_TXT_ATR_FIELDSTART) {
                SwPosition aPosition( *pNd, SwIndex( (SwTxtNode*)pNd, nAktPos+1 ) );
                SwFieldBookmark* pFieldmark=(SwFieldBookmark*)rWW8Wrt.pDoc->getFieldBookmarkFor( aPosition );
                ASSERT(pFieldmark!=NULL, "Looks like this doc is broken...; where is the Fieldmark for the FIELDSTART??");

                if (pFieldmark!=NULL) {
                    rWW8Wrt.AppendBookmark( pFieldmark->GetName(), 1);
                }
            IDocumentMarkAccess* const pMarkAccess = rWW8Wrt.pDoc->getIDocumentMarkAccess();
            if(ch==CH_TXT_ATR_FIELDSTART)
            {
                SwPosition aPosition(*pNd, SwIndex((SwTxtNode*)pNd, nAktPos+1));
                ::sw::mark::IFieldmark const * const pFieldmark=pMarkAccess->getFieldmarkFor(aPosition);
                OSL_ENSURE(pFieldmark,
                    "Looks like this doc is broken...; where is the Fieldmark for the FIELDSTART??");
                if(pFieldmark)
                    rWW8Wrt.AppendBookmark(pFieldmark->GetName(), 1);
                rWW8Wrt.OutField(NULL, ww::eFORMTEXT, String::CreateFromAscii(" FORMTEXT "), WRITEFIELD_START | WRITEFIELD_CMD_START);
                if (pFieldmark!=NULL) {
                    rWW8Wrt.WriteFormData( *pFieldmark );
                }
                if(pFieldmark)
                    rWW8Wrt.WriteFormData(*pFieldmark);
                rWW8Wrt.OutField(NULL, ww::eFORMTEXT, String(), WRITEFIELD_CMD_END);
            } else if (ch==CH_TXT_ATR_FIELDEND) {
                SwPosition aPosition( *pNd, SwIndex( (SwTxtNode*)pNd, nAktPos ) );
                SwFieldBookmark* pFieldmark=(SwFieldBookmark*)rWW8Wrt.pDoc->getFieldBookmarkFor( aPosition );
                ASSERT(pFieldmark!=NULL, "Looks like this doc is broken...; where is the Fieldmark for the FIELDSTART??");
            }
            else if (ch==CH_TXT_ATR_FIELDEND)
            {
                SwPosition aPosition(*pNd, SwIndex((SwTxtNode*)pNd, nAktPos));
                ::sw::mark::IFieldmark const * const pFieldmark=pMarkAccess->getFieldmarkFor(aPosition);
                OSL_ENSURE(pFieldmark,
                    "Looks like this doc is broken...; where is the Fieldmark for the FIELDSTART??");
                rWW8Wrt.OutField(NULL, ww::eFORMTEXT, String(), WRITEFIELD_CLOSE);
                if (pFieldmark!=NULL) {
                    rWW8Wrt.AppendBookmark( pFieldmark->GetName(), 0);
                }
            } else if (ch==CH_TXT_ATR_FORMELEMENT) {
                SwPosition aPosition( *pNd, SwIndex( (SwTxtNode*)pNd, nAktPos ) );
                SwFieldBookmark* pFieldmark=rWW8Wrt.pDoc->getFormFieldBookmarkFor( aPosition );
                ASSERT(pFieldmark!=NULL, "Looks like this doc is broken...; where is the Fieldmark for the FIELDSTART??");
                if (pFieldmark!=NULL) {
                    rWW8Wrt.AppendBookmark( pFieldmark->GetName(), 1);
                }
                if (pFieldmark)
                    rWW8Wrt.AppendBookmark(pFieldmark->GetName(), 0);
            }
            else if (ch==CH_TXT_ATR_FORMELEMENT)
            {
                SwPosition aPosition(*pNd, SwIndex((SwTxtNode*)pNd, nAktPos));
                ::sw::mark::IFieldmark const * const pFieldmark=pMarkAccess->getFieldmarkFor(aPosition);
                OSL_ENSURE(pFieldmark,
                    "Looks like this doc is broken...; where is the Fieldmark for the FIELDSTART??");
                if(pFieldmark)
                    rWW8Wrt.AppendBookmark(pFieldmark->GetName(), 1);
                rWW8Wrt.OutField(NULL, ww::eFORMCHECKBOX, String::CreateFromAscii(" FORMCHECKBOX "), WRITEFIELD_START | WRITEFIELD_CMD_START);
                if (pFieldmark!=NULL) {

                    rWW8Wrt.WriteFormData( *pFieldmark );
                }
                if(pFieldmark)
                    rWW8Wrt.WriteFormData(*pFieldmark);
                rWW8Wrt.OutField(NULL, ww::eFORMCHECKBOX, String(), WRITEFIELD_CMD_END | WRITEFIELD_CLOSE);
                if (pFieldmark!=NULL) {
                    rWW8Wrt.AppendBookmark( pFieldmark->GetName(), 0);
                }
                if(pFieldmark)
                    rWW8Wrt.AppendBookmark(pFieldmark->GetName(), 0);
            }
            nLen-=static_cast<USHORT>(ofs);
            String aSnippet(aAttrIter.GetSnippet(aStr, nAktPos+static_cast<USHORT>(ofs), nLen));
@@ -1592,7 +1592,7 @@ Writer& OutWW8_SwTxtNode( Writer& rWrt, SwCntntNode& rNode )
                    aSnippet.Insert(0x09,0);
                }
            }
            rWW8Wrt.OutSwString(aSnippet, 0, nLen, bUnicode, eChrSet );
            rWW8Wrt.OutSwString(aSnippet, 0, nLen, bUnicode, eChrSet);
        }

        if (aAttrIter.IsDropCap(nNextAttr))
diff --git a/sw/source/filter/ww8/wrtww8.cxx b/sw/source/filter/ww8/wrtww8.cxx
index 0f5372b..75586e7 100644
--- a/sw/source/filter/ww8/wrtww8.cxx
+++ b/sw/source/filter/ww8/wrtww8.cxx
@@ -77,7 +77,7 @@
#include <shellio.hxx>
#include <docstat.hxx>
#include <pagedesc.hxx>
#include <bookmrk.hxx>
#include <IMark.hxx>
#include <swtable.hxx>
#include <wrtww8.hxx>
#include <ww8par.hxx>
@@ -100,7 +100,7 @@
#include "writerhelper.hxx"
#include "writerwordglue.hxx"

#include <IDocumentBookmarkAccess.hxx>
#include <IDocumentMarkAccess.hxx>

#include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
#include <com/sun/star/document/XDocumentProperties.hpp>
@@ -176,7 +176,7 @@ class WW8_WrtBookmarks
{
private:
    SvULongs aSttCps, aEndCps;      // Array of Start- and End CPs
    SvBools aFieldBookmarks;       // If the bookmark is in a field result
    SvBools aFieldMarks;       // If the bookmark is in a field result
    std::vector<String> maSwBkmkNms;    // Array of Sw - Bookmarknames
    typedef std::vector<String>::iterator myIter;

@@ -189,9 +189,9 @@ public:
    WW8_WrtBookmarks();
    ~WW8_WrtBookmarks();

    void Append( WW8_CP nStartCp, const String& rNm, const SwBookmark* pBkmk=NULL );
    void Append( WW8_CP nStartCp, const String& rNm, const ::sw::mark::IMark* pBkmk=NULL );
    void Write( SwWW8Writer& rWrt );
    void MoveFieldBookmarks(ULONG nFrom,ULONG nTo);
    void MoveFieldMarks(ULONG nFrom,ULONG nTo);

//  String GetWWBkmkName( const String& rName ) const;
};
@@ -1228,7 +1228,7 @@ WW8_WrtBookmarks::~WW8_WrtBookmarks()
{
}

void WW8_WrtBookmarks::Append( WW8_CP nStartCp, const String& rNm,  const SwBookmark* )
void WW8_WrtBookmarks::Append( WW8_CP nStartCp, const String& rNm,  const ::sw::mark::IMark* )
{
    USHORT nPos = GetPos( rNm );
    if( USHRT_MAX == nPos )
@@ -1246,7 +1246,7 @@ void WW8_WrtBookmarks::Append( WW8_CP nStartCp, const String& rNm,  const SwBook

        aSttCps.Insert(nStartCp, nPos);
        aEndCps.Insert(nStartCp, nPos);
        aFieldBookmarks.Insert(BOOL(false), nPos);
        aFieldMarks.Insert(BOOL(false), nPos);
        maSwBkmkNms.insert(aIter, rNm);
    }
    else
@@ -1257,7 +1257,7 @@ void WW8_WrtBookmarks::Append( WW8_CP nStartCp, const String& rNm,  const SwBook
        //If this bookmark was around a field in writer, then we want to move
        //it to the field result in word. The end is therefore one cp
        //backwards from the 0x15 end mark that was inserted.
        if (aFieldBookmarks[nPos])
        if (aFieldMarks[nPos])
            --nStartCp;

        aEndCps.Replace( nStartCp, nPos );
@@ -1330,7 +1330,7 @@ USHORT WW8_WrtBookmarks::GetPos( const String& rNm )
    return nRet;
}

void WW8_WrtBookmarks::MoveFieldBookmarks(ULONG nFrom, ULONG nTo)
void WW8_WrtBookmarks::MoveFieldMarks(ULONG nFrom, ULONG nTo)
{
    for (USHORT nI=0;nI<aSttCps.Count();++nI)
    {
@@ -1339,7 +1339,7 @@ void WW8_WrtBookmarks::MoveFieldBookmarks(ULONG nFrom, ULONG nTo)
            aSttCps[nI] = nTo;
            if (aEndCps[nI] == nFrom)
            {
                aFieldBookmarks[nI] = true;
                aFieldMarks[nI] = true;
                aEndCps[nI] = nTo;
            }
        }
@@ -1347,7 +1347,7 @@ void WW8_WrtBookmarks::MoveFieldBookmarks(ULONG nFrom, ULONG nTo)
}

void SwWW8Writer::AppendBookmarks( const SwTxtNode& rNd,
                                    xub_StrLen nAktPos, xub_StrLen nLen )
    xub_StrLen nAktPos, xub_StrLen nLen )
{
    SvPtrarr aArr( 8, 8 );
    USHORT nCntnt;
@@ -1357,19 +1357,19 @@ void SwWW8Writer::AppendBookmarks( const SwTxtNode& rNd,
        ULONG nNd = rNd.GetIndex(), nSttCP = Fc2Cp( Strm().Tell() );
        for( USHORT n = 0; n < aArr.Count(); ++n )
        {
            const SwBookmark& rBkmk = *(SwBookmark*)aArr[ n ];

            if (rBkmk.IsFormFieldMark()) {
            ::sw::mark::IMark& rBkmk = *(::sw::mark::IMark*)aArr[ n ];
            if(dynamic_cast< ::sw::mark::IFieldmark *>(&rBkmk))
                continue;
            }

            const SwPosition* pPos = &rBkmk.GetBookmarkPos(),
                            * pOPos = rBkmk.GetOtherBookmarkPos();
            const SwPosition* pPos = &rBkmk.GetMarkPos();
            const SwPosition* pOPos = 0;
            if(rBkmk.IsExpanded())
                pOPos = &rBkmk.GetOtherMarkPos();
            if( pOPos && pOPos->nNode == pPos->nNode &&
                pOPos->nContent < pPos->nContent )
            {
                pOPos = pPos;
                pPos = rBkmk.GetOtherBookmarkPos();
                pPos = pOPos;
                pOPos = &rBkmk.GetMarkPos();
            }

            if( !pOPos || ( nNd == pPos->nNode.GetIndex() &&
@@ -1390,15 +1390,15 @@ void SwWW8Writer::AppendBookmarks( const SwTxtNode& rNd,
    }
}

void SwWW8Writer::MoveFieldBookmarks(ULONG nFrom, ULONG nTo)
void SwWW8Writer::MoveFieldMarks(ULONG nFrom, ULONG nTo)
{
    pBkmks->MoveFieldBookmarks(nFrom, nTo);
    pBkmks->MoveFieldMarks(nFrom, nTo);
}

void SwWW8Writer::AppendBookmark( const String& rName, USHORT nOffset )
void SwWW8Writer::AppendBookmark(const String& rName, USHORT nOffset)
{
    ULONG nSttCP = Fc2Cp( Strm().Tell() ) + nOffset;
    pBkmks->Append( nSttCP, rName );
    ULONG nSttCP = Fc2Cp(Strm().Tell()) + nOffset;
    pBkmks->Append(nSttCP, rName);
}


@@ -3177,19 +3177,25 @@ void WW8SHDLong::Write(SwWW8Writer & rWriter)
    rWriter.InsUInt16(m_ipat);
}

void SwWW8Writer::WriteFormData(SwFieldBookmark &rFieldmark)
void SwWW8Writer::WriteFormData(const ::sw::mark::IFieldmark& rFieldmark)
{
    ASSERT(bWrtWW8, "No 95 export yet");
    if (!bWrtWW8) return;

    int type=rFieldmark.GetFieldType();
    const String ffname=rFieldmark.GetFFName();
    const ::sw::mark::IFieldmark* pFieldmark = &rFieldmark;
    const ::sw::mark::ICheckboxFieldmark* pAsCheckbox = dynamic_cast< const ::sw::mark::ICheckboxFieldmark* >(pFieldmark);

    int type=0; // TextFieldmark
    if(pAsCheckbox) type=1;

    const ::rtl::OUString ffname = rFieldmark.GetFieldname();

    ULONG nDataStt = pDataStrm->Tell();
    pChpPlc->AppendFkpEntry( Strm().Tell() );
    pChpPlc->AppendFkpEntry(Strm().Tell());

    WriteChar( 0x01 );
    static BYTE aArr1[] = {
    WriteChar(0x01);
    static BYTE aArr1[] =
    {
        0x03, 0x6a, 0,0,0,0,    // sprmCPicLocation

        0x06, 0x08, 0x01,       // sprmCFData
@@ -3197,10 +3203,9 @@ void SwWW8Writer::WriteFormData(SwFieldBookmark &rFieldmark)
        0x02, 0x08, 0x01        // sprmCFFldVanish
    };
    BYTE* pDataAdr = aArr1 + 2;
    Set_UInt32( pDataAdr, nDataStt );
    Set_UInt32(pDataAdr, nDataStt);

    pChpPlc->AppendFkpEntry(Strm().Tell(),
                sizeof( aArr1 ), aArr1 );
    pChpPlc->AppendFkpEntry(Strm().Tell(), sizeof(aArr1), aArr1);

    sal_uInt8 aFldHeader[] =
    {
@@ -3209,15 +3214,17 @@ void SwWW8Writer::WriteFormData(SwFieldBookmark &rFieldmark)
    };

    aFldHeader[4] |= (type & 0x03);
    int ffres=rFieldmark.GetFFRes();
    int ffres=0; // rFieldmark.GetFFRes();
    if(pAsCheckbox && pAsCheckbox->IsChecked())
        ffres=1;
    aFldHeader[4] |= ((ffres<<2) & 0x7C);

    const String ffdeftext;
    const String ffformat;
    const String ffhelptext;
    const String ffstattext;
    const String ffentrymcr;
    const String ffexitmcr;
    const ::rtl::OUString ffdeftext;
    const ::rtl::OUString ffformat;
    const ::rtl::OUString ffhelptext;
    const ::rtl::OUString ffstattext;
    const ::rtl::OUString ffentrymcr;
    const ::rtl::OUString ffexitmcr;

    const sal_uInt8 aFldData[] =
    {
@@ -3231,43 +3238,45 @@ void SwWW8Writer::WriteFormData(SwFieldBookmark &rFieldmark)
    };
    int slen=sizeof(aFldData)
        +sizeof(aFldHeader)
        +2*ffname.Len()+4
        +2*ffdeftext.Len()+4
        +2*ffformat.Len()+4
        +2*ffhelptext.Len()+4
        +2*ffstattext.Len()+4
        +2*ffentrymcr.Len()+4
        +2*ffexitmcr.Len()+4;
        +2*ffname.getLength()+4
        +2*ffdeftext.getLength()+4
        +2*ffformat.getLength()+4
        +2*ffhelptext.getLength()+4
        +2*ffstattext.getLength()+4
        +2*ffentrymcr.getLength()+4
        +2*ffexitmcr.getLength()+4;
#ifdef OSL_BIGENDIAN
    slen=SWAPLONG(slen);
#endif // OSL_BIGENDIAN
    *((sal_uInt32 *)aFldData)=slen;
    int len=sizeof(aFldData) ;
    assert(len==0x44);
    pDataStrm->Write( aFldData, len);
    int len=sizeof(aFldData);
    OSL_ENSURE(len==0x44,
        "SwWW8Writer::WriteFormData(..)"
        " - wrong aFldData length");
    pDataStrm->Write(aFldData, len);

    len=sizeof(aFldHeader);
    assert(len==8);
    pDataStrm->Write( aFldHeader, len);
    OSL_ENSURE(len==8,
        "SwWW8Writer::WriteFormData(..)"
        " - wrong aFldHeader length");
    pDataStrm->Write(aFldHeader, len);

    WriteString_xstz( *pDataStrm, ffname, true); // Form field name
    WriteString_xstz(*pDataStrm, ffname, true); // Form field name

    if (type==0) {
        WriteString_xstz( *pDataStrm, ffdeftext, true);
    } else {
    if (type==0)
        WriteString_xstz(*pDataStrm, ffdeftext, true);
    else
        pDataStrm->WriteNumber((sal_uInt16)0);
    }
    WriteString_xstz( *pDataStrm, ffformat, true);
    WriteString_xstz( *pDataStrm, ffhelptext, true);
    WriteString_xstz( *pDataStrm, ffstattext, true);
    WriteString_xstz( *pDataStrm, ffentrymcr, true);
    WriteString_xstz( *pDataStrm, ffexitmcr, true);
    if (type==2) {
        // 0xFF, 0xFF
        // sal_uInt32 number of strings
        // (sal_uInt16 len; sal_uInt16 unicode char[len])*num of strings
    }

    WriteString_xstz(*pDataStrm, String(ffformat), true);
    WriteString_xstz(*pDataStrm, String(ffhelptext), true);
    WriteString_xstz(*pDataStrm, String(ffstattext), true);
    WriteString_xstz(*pDataStrm, String(ffentrymcr), true);
    WriteString_xstz(*pDataStrm, String(ffexitmcr), true);
//    if (type==2) {
//        // 0xFF, 0xFF
//        // sal_uInt32 number of strings
//        // (sal_uInt16 len; sal_uInt16 unicode char[len])*num of strings
//    }
}

void SwWW8Writer::OutWW8_TableNodeInfoInner(ww8::WW8TableNodeInfoInner::Pointer_t pNodeInfoInner)
diff --git a/sw/source/filter/ww8/wrtww8.hxx b/sw/source/filter/ww8/wrtww8.hxx
index b5c62dd..8741425 100644
--- a/sw/source/filter/ww8/wrtww8.hxx
+++ b/sw/source/filter/ww8/wrtww8.hxx
@@ -589,7 +589,7 @@ public:
        xub_StrLen nLen );
    void AppendBookmark( const String& rName, USHORT nOffset = 0 );
    String GetBookmarkName( USHORT nTyp, const String* pNm, USHORT nSeqNo );
    void MoveFieldBookmarks(ULONG nFrom, ULONG nTo);
    void MoveFieldMarks(ULONG nFrom, ULONG nTo);
    bool HasRefToObject(USHORT nTyp, const String* pNm, USHORT nSeqNo);

    void WriteAsStringTable(const ::std::vector<String>&, INT32& rfcSttbf,
@@ -730,7 +730,7 @@ public:
    void CollectOutlineBookmarks(const SwDoc &rDoc);
    void AddBookmark(String sBkmkName);

    void WriteFormData(SwFieldBookmark &rFieldmark);
    void WriteFormData(const ::sw::mark::IFieldmark& rFieldmark);
    WW8_WrPlcFld* CurrentFieldPlc() const;
private:
    //No copying
diff --git a/sw/source/filter/ww8/ww8atr.cxx b/sw/source/filter/ww8/ww8atr.cxx
index d3c2648..1d608c1 100644
--- a/sw/source/filter/ww8/ww8atr.cxx
+++ b/sw/source/filter/ww8/ww8atr.cxx
@@ -2520,12 +2520,12 @@ static Writer& OutWW8_SwField( Writer& rWrt, const SfxPoolItem& rHt )
            /*
            Is there a bookmark at the start position of this field, if so
            move it to the 0x14 of the result of the field.  This is what word
            does. MoveFieldBookmarks moves any bookmarks at this position to
            does. MoveFieldMarks moves any bookmarks at this position to
            the beginning of the field result, and marks the bookmark as a
            fieldbookmark which is to be ended before the field end mark
            instead of after it like a normal bookmark.
            */
            rWW8Wrt.MoveFieldBookmarks(nFrom,rWW8Wrt.Fc2Cp(rWrt.Strm().Tell()));
            rWW8Wrt.MoveFieldMarks(nFrom,rWW8Wrt.Fc2Cp(rWrt.Strm().Tell()));

            if (rVar.Len())
            {
diff --git a/sw/source/filter/ww8/ww8par.cxx b/sw/source/filter/ww8/ww8par.cxx
index e93c333..989cf49 100644
--- a/sw/source/filter/ww8/ww8par.cxx
+++ b/sw/source/filter/ww8/ww8par.cxx
@@ -74,7 +74,7 @@
#include <fmtfld.hxx>
#include <fmturl.hxx>
#include <fmtinfmt.hxx>
#include <bookmrk.hxx>
#include <IMark.hxx>
#include <reffld.hxx>
#include <fmthdft.hxx>
#include <fmtcntnt.hxx>
@@ -1056,13 +1056,21 @@ bool SwWW8FltRefStack::IsFtnEdnBkmField(const SwFmtFld& rFmtFld, USHORT& rBkmNo)
{
    const SwField* pFld = rFmtFld.GetFld();
    USHORT nSubType;
    return (pFld && (RES_GETREFFLD == pFld->Which())
            && ((REF_FOOTNOTE == (nSubType = pFld->GetSubType())) ||
                (REF_ENDNOTE  == nSubType))
            && ((SwGetRefField*)pFld)->GetSetRefName().Len()
                // find Sequence No of corresponding Foot-/Endnote
            && (USHRT_MAX != (rBkmNo = pDoc->findBookmark(
                ((SwGetRefField*)pFld)->GetSetRefName() ))));
    if(pFld && (RES_GETREFFLD == pFld->Which())
        && ((REF_FOOTNOTE == (nSubType = pFld->GetSubType())) || (REF_ENDNOTE  == nSubType))
        && ((SwGetRefField*)pFld)->GetSetRefName().Len())
    {
        const IDocumentMarkAccess* const pMarkAccess = pDoc->getIDocumentMarkAccess();
        IDocumentMarkAccess::const_iterator_t ppBkmk = pMarkAccess->findMark(
            ((SwGetRefField*)pFld)->GetSetRefName());
        if(ppBkmk != pMarkAccess->getMarksEnd())
        {
            // find Sequence No of corresponding Foot-/Endnote
            rBkmNo = ppBkmk - pMarkAccess->getMarksBegin();
            return true;
        }
    }
    return false;
}

void SwWW8FltRefStack::SetAttrInDoc(const SwPosition& rTmpPos,
@@ -1089,9 +1097,9 @@ void SwWW8FltRefStack::SetAttrInDoc(const SwPosition& rTmpPos,
                USHORT nBkmNo;
                if( IsFtnEdnBkmField(rFmtFld, nBkmNo) )
                {
                    SwBookmark& rBkMrk = pDoc->getBookmark( nBkmNo, false );
                    ::sw::mark::IMark const * const pMark = (pDoc->getIDocumentMarkAccess()->getMarksBegin() + nBkmNo)->get();

                    const SwPosition& rBkMrkPos = rBkMrk.GetBookmarkPos();
                    const SwPosition& rBkMrkPos = pMark->GetMarkPos();

                    SwTxtNode* pTxt = rBkMrkPos.nNode.GetNode().GetTxtNode();
                    if( pTxt && rBkMrkPos.nContent.GetIndex() )
@@ -2590,20 +2598,27 @@ bool SwWW8ImplReader::ReadChar(long nPosCp, long nCpOfs)
        case 0x15:
            if( !bSpec )        // Juristenparagraph
                cInsert = '\xa7';
            else { //0x15 is special --> so it's our field end mark...; hmmm what about field marks not handled by us??, maybe a problem with nested fields; probably an area of bugs... [well release quick and release often....]
                if (!maNewFieldCtxStack.empty() && pPaM!=NULL && pPaM->GetPoint()!=NULL) {
                    WW8NewFieldCtx *pFieldCtx=maNewFieldCtxStack.back();
            else
            {
                // 0x15 is special --> so it's our field end mark...;
                // hmmm what about field marks not handled by us??, maybe a problem with nested fields;
                // probably an area of bugs... [well release quick and release often....]
                if (!maNewFieldCtxStack.empty() && pPaM!=NULL && pPaM->GetPoint()!=NULL)
                {
                    ::boost::scoped_ptr<WW8NewFieldCtx> pFieldCtx(maNewFieldCtxStack.back());
                    maNewFieldCtxStack.pop_back();
                    SwPosition aEndPos = *pPaM->GetPoint();
                    SwPaM aFldPam( pFieldCtx->GetPtNode(), pFieldCtx->GetPtCntnt(), aEndPos.nNode, aEndPos.nContent.GetIndex());
                    SwFieldBookmark *pFieldmark=(SwFieldBookmark*)rDoc.makeBookmark(aFldPam, KeyCode(), pFieldCtx->GetBookmarkName(), String(), IDocumentBookmarkAccess::FORM_FIELDMARK_TEXT);
                    ASSERT(pFieldmark!=NULL, "hmmm; why was the bookmark not created?");
                    if (pFieldmark!=NULL) {
                        pFieldmark->SetFieldType(0); // 0==Text
                        // set field data here...
                        pFieldCtx->SetCurrentFieldParamsTo(*pFieldmark);
                    }
                    delete pFieldCtx;
                    SwPaM aFldPam(pFieldCtx->GetPtNode(), pFieldCtx->GetPtCntnt(), aEndPos.nNode, aEndPos.nContent.GetIndex());
                    IDocumentMarkAccess* const pMarkAccess = rDoc.getIDocumentMarkAccess();
                    ::sw::mark::IFieldmark* pFieldmark =
                        dynamic_cast< ::sw::mark::IFieldmark*>(pMarkAccess->makeMark(
                            aFldPam,
                            pFieldCtx->GetBookmarkName(),
                            IDocumentMarkAccess::TEXT_FIELDMARK));
                    OSL_ENSURE(pFieldmark!=NULL,
                        "hmmm; why was the bookmark not created?");
                    if (pFieldmark)
                        pFieldCtx->SetCurrentFieldParamsTo(pFieldmark);
                }
            }
            break;
diff --git a/sw/source/filter/ww8/ww8par.hxx b/sw/source/filter/ww8/ww8par.hxx
index 6911396..15118e9 100644
--- a/sw/source/filter/ww8/ww8par.hxx
+++ b/sw/source/filter/ww8/ww8par.hxx
@@ -117,6 +117,7 @@ class SfxItemSet;
class _ReadFieldParams;
class wwZOrderer;
class OutlinerParaObject;

namespace com{namespace sun {namespace star{
    namespace beans{ class XPropertySet;}
    namespace form { class XFormComponent;}
@@ -382,24 +383,23 @@ class WW8NewFieldCtx
private:
    SwNodeIndex maPtNode;
    xub_StrLen mnPtCntnt;
    ::rtl::OUString sBookmarkName;
    ::rtl::OUString sBookmarkType;
    ::rtl::OUString msBookmarkName;
    ::rtl::OUString msMarkType;
    typedef ::std::pair< ::rtl::OUString, ::rtl::OUString> Param_t;
    typedef ::std::vector< Param_t > Params_t;
    Params_t maParams;
  SwPaM * mpPaM;

public:
    WW8NewFieldCtx(SwPosition &aStartPos, ::rtl::OUString sBookmarkName, ::rtl::OUString sBookmarkType);
    WW8NewFieldCtx(SwPosition &aStartPos, ::rtl::OUString sBookmarkName, ::rtl::OUString sMarkType);
    ~WW8NewFieldCtx();

    SwNodeIndex GetPtNode() { return maPtNode; };
    xub_StrLen GetPtCntnt() { return mnPtCntnt; };
    ::rtl::OUString GetBookmarkName();
    ::rtl::OUString GetBookmarkType();
    ::rtl::OUString GetMarkType();
    void AddParam(::rtl::OUString name, ::rtl::OUString value);
    void SetCurrentFieldParamsTo(SwFieldBookmark &rFieldBookmark);

    void SetCurrentFieldParamsTo(::sw::mark::IFieldmark* pFieldmark);
};


diff --git a/sw/source/filter/ww8/ww8par3.cxx b/sw/source/filter/ww8/ww8par3.cxx
index cc524c6..de91277 100644
--- a/sw/source/filter/ww8/ww8par3.cxx
+++ b/sw/source/filter/ww8/ww8par3.cxx
@@ -94,7 +94,7 @@
#include "ww8par.hxx"
#include "ww8par2.hxx"  // wg. Listen-Attributen in Styles

#include <bookmrk.hxx>
#include <IMark.hxx>
#include <svtools/fltrcfg.hxx>

#include <stdio.h>
@@ -103,10 +103,12 @@ using namespace com::sun::star;
using namespace sw::util;
using namespace sw::types;

WW8NewFieldCtx::WW8NewFieldCtx(SwPosition &aStartPos, ::rtl::OUString _sBookmarkName, ::rtl::OUString _sBookmarkType)
: maPtNode(aStartPos.nNode), mnPtCntnt(aStartPos.nContent.GetIndex()),
  sBookmarkName(_sBookmarkName),
  sBookmarkType(_sBookmarkType), mpPaM(NULL)
WW8NewFieldCtx::WW8NewFieldCtx(SwPosition &aStartPos, ::rtl::OUString sBookmarkName, ::rtl::OUString sMarkType)
    : maPtNode(aStartPos.nNode)
    , mnPtCntnt(aStartPos.nContent.GetIndex())
    , msBookmarkName(sBookmarkName)
    , msMarkType(sMarkType)
    , mpPaM(NULL)
{
}

@@ -118,12 +120,12 @@ WW8NewFieldCtx::~WW8NewFieldCtx()

::rtl::OUString WW8NewFieldCtx::GetBookmarkName()
{
    return sBookmarkName;
    return msBookmarkName;
}

::rtl::OUString WW8NewFieldCtx::GetBookmarkType()
::rtl::OUString WW8NewFieldCtx::GetMarkType()
{
    return sBookmarkType;
    return msMarkType;
}

void WW8NewFieldCtx::AddParam(::rtl::OUString name, ::rtl::OUString value)
@@ -131,17 +133,26 @@ void WW8NewFieldCtx::AddParam(::rtl::OUString name, ::rtl::OUString value)
    maParams.push_back( Param_t(name, value) );
}

void WW8NewFieldCtx::SetCurrentFieldParamsTo(SwFieldBookmark &rFieldBookmark)
void WW8NewFieldCtx::SetCurrentFieldParamsTo(::sw::mark::IFieldmark* pFieldmark)
{
    for(Params_t::iterator i=maParams.begin();i!=maParams.end();i++) {
    for(Params_t::iterator i=maParams.begin();i!=maParams.end();i++)
    {
        ::rtl::OUString aName=i->first;
        ::rtl::OUString aValue=i->second;
        if (aName.compareToAscii("Description")==0) {
            rFieldBookmark.SetFFHelpText(aValue);
        } else if (aName.compareToAscii("Name")==0) {
            rFieldBookmark.SetFFName(aValue);
        } else if (aName.compareToAscii("Result")==0) {
            rFieldBookmark.SetFFRes( aValue.toInt32() );
        if(aName.compareToAscii("Description")==0)
        {
            pFieldmark->SetFieldHelptext(aValue);
        }
        else if(aName.compareToAscii("Name")==0)
        {
            pFieldmark->SetFieldname(aValue);
        }
        else if(aName.compareToAscii("Result")==0)
        {
            ::sw::mark::ICheckboxFieldmark* pAsCheckbox =
                dynamic_cast< ::sw::mark::ICheckboxFieldmark* >(pFieldmark);
            if(pAsCheckbox)
                pAsCheckbox->SetChecked(aValue.toInt32()==0);
        }
    }
}
@@ -269,12 +280,17 @@ eF_ResT SwWW8ImplReader::Read_F_FormCheckBox( WW8FieldDesc* pF, String& rStr )
    }

    if (aBookmarkName.Len()>0) {
        SwFieldBookmark *pFieldmark=(SwFieldBookmark*)rDoc.makeBookmark(*pPaM, KeyCode(), aBookmarkName, String(), IDocumentBookmarkAccess::FORM_FIELDMARK_NO_TEXT);
        ASSERT(pFieldmark!=NULL, "hmmm; why was the bookmark not created?");
        if (pFieldmark!=NULL) {
            pFieldmark->SetFieldType(1); // 0==Checkbox
            pFieldmark->SetFFName(aFormula.sTitle);
            pFieldmark->SetFFHelpText(aFormula.sToolTip);
        ::sw::mark::ICheckboxFieldmark* pFieldmark =
            dynamic_cast< ::sw::mark::ICheckboxFieldmark*>(rDoc.getIDocumentMarkAccess()->makeMark(
                *pPaM,
                aBookmarkName,
                IDocumentMarkAccess::CHECKBOX_FIELDMARK));
        OSL_ENSURE(pFieldmark,
            "hmmm; why was the bookmark not created?");
        if(pFieldmark)
        {
            pFieldmark->SetFieldname(aFormula.sTitle);
            pFieldmark->SetFieldHelptext(aFormula.sToolTip);
            pFieldmark->SetChecked(aFormula.nChecked!=0);
            // set field data here...
        }
diff --git a/sw/source/filter/ww8/ww8par5.cxx b/sw/source/filter/ww8/ww8par5.cxx
index 5450b90..9f1cfad 100644
--- a/sw/source/filter/ww8/ww8par5.cxx
+++ b/sw/source/filter/ww8/ww8par5.cxx
@@ -69,7 +69,7 @@
#include <flddat.hxx>           // class SwDateTimeField
#include <docufld.hxx>          // class SwPageNumberField
#include <reffld.hxx>           // class SwGetRefField
#include <bookmrk.hxx>
#include <IMark.hxx>
#include <expfld.hxx>           // class SwSetExpField
#include <dbfld.hxx>            // class SwDBField
#include <usrfld.hxx>
diff --git a/sw/source/ui/dbui/dbinsdlg.cxx b/sw/source/ui/dbui/dbinsdlg.cxx
index 3048eac..07e9b0a 100644
--- a/sw/source/ui/dbui/dbinsdlg.cxx
+++ b/sw/source/ui/dbui/dbinsdlg.cxx
@@ -131,6 +131,7 @@
#include "swabstdlg.hxx"
#include "table.hrc"
#include <unomid.h>
#include <IDocumentMarkAccess.hxx>


namespace swui
@@ -1334,6 +1335,7 @@ void SwInsertDBColAutoPilot::DataToDoc( const Sequence<Any>& rSelection,

            BOOL bSetCrsr = TRUE;
            USHORT n = 0, nCols = aColArr.Count();
            ::sw::mark::IMark* pMark = NULL;
            for( sal_Int32 i = 0 ; ; ++i )
            {
                BOOL bBreak = FALSE;
@@ -1452,7 +1454,10 @@ void SwInsertDBColAutoPilot::DataToDoc( const Sequence<Any>& rSelection,
                        // rSh.SwCrsrShell::MovePara( fnParaCurr, fnParaStart );
                        rSh.SwCrsrShell::MovePara(
                            GetfnParaCurr(), GetfnParaStart() );
                        rSh.SetBookmark( KeyCode(), C2S("DB_Mark"), aEmptyStr, IDocumentBookmarkAccess::MARK );
                        pMark = rSh.SetBookmark(
                            KeyCode(),
                            ::rtl::OUString(),
                            ::rtl::OUString(), IDocumentMarkAccess::UNO_BOOKMARK );
                        // rSh.SwCrsrShell::MovePara( fnParaCurr, fnParaEnd );
                        rSh.SwCrsrShell::MovePara(
                            GetfnParaCurr(), GetfnParaEnd() );
@@ -1479,11 +1484,12 @@ void SwInsertDBColAutoPilot::DataToDoc( const Sequence<Any>& rSelection,
                    pWait = ::std::auto_ptr<SwWait>(new SwWait( *pView->GetDocShell(), TRUE ));
            }

            if( !bSetCrsr && USHRT_MAX != (n = rSh.FindBookmark( C2S("DB_Mark" ))) )
            if( !bSetCrsr && pMark != NULL)
            {
                rSh.SetMark();
                rSh.GotoBookmark( n );
                rSh.DelBookmark( n );
                rSh.GotoMark( pMark );
                rSh.getIDocumentMarkAccess()->deleteMark( pMark );
                break;
            }
        }
    }
diff --git a/sw/source/ui/dialog/SwSpellDialogChildWindow.cxx b/sw/source/ui/dialog/SwSpellDialogChildWindow.cxx
index 92bba89..8dca8ef 100644
--- a/sw/source/ui/dialog/SwSpellDialogChildWindow.cxx
+++ b/sw/source/ui/dialog/SwSpellDialogChildWindow.cxx
@@ -63,7 +63,6 @@
#ifndef _DIALOG_HXX
#include <dialog.hrc>
#endif
#include <bookmrk.hxx>
#include <cmdid.h>

using namespace ::com::sun::star;
diff --git a/sw/source/ui/dialog/regionsw.cxx b/sw/source/ui/dialog/regionsw.cxx
index b0038a8..4793669 100644
--- a/sw/source/ui/dialog/regionsw.cxx
+++ b/sw/source/ui/dialog/regionsw.cxx
@@ -55,7 +55,6 @@
#endif

#include <svx/htmlcfg.hxx>
#include <bookmrk.hxx>
#include <section.hxx>
#include <docary.hxx>
#include <regionsw.hxx>
diff --git a/sw/source/ui/dialog/uiregionsw.cxx b/sw/source/ui/dialog/uiregionsw.cxx
index bae83e7d..2f90c9f 100644
--- a/sw/source/ui/dialog/uiregionsw.cxx
+++ b/sw/source/ui/dialog/uiregionsw.cxx
@@ -61,7 +61,7 @@

#include <comphelper/storagehelper.hxx>
#include <uitool.hxx>
#include <bookmrk.hxx>
#include <IMark.hxx>
#include <section.hxx>
#include <docary.hxx>
#include <doc.hxx>                      // fuers SwSectionFmt-Array
@@ -1588,9 +1588,7 @@ SwInsertSectionTabPage::~SwInsertSectionTabPage()
{
    delete m_pDocInserter;
}
/* -----------------21.05.99 12:58-------------------
 *
 * --------------------------------------------------*/

void    SwInsertSectionTabPage::SetWrtShell(SwWrtShell& rSh)
{
    m_pWrtSh = &rSh;
@@ -1606,12 +1604,14 @@ void    SwInsertSectionTabPage::SetWrtShell(SwWrtShell& rSh)
    }

    FillList();
    USHORT nCnt = m_pWrtSh->GetBookmarkCnt();
    for( USHORT i = 0; i < nCnt; ++i )
    IDocumentMarkAccess* const pMarkAccess = m_pWrtSh->getIDocumentMarkAccess();
    for( IDocumentMarkAccess::const_iterator_t ppMark = pMarkAccess->getMarksBegin();
        ppMark != pMarkAccess->getMarksEnd();
        ppMark++)
    {
        SwBookmark& rBm = m_pWrtSh->GetBookmark( i );
        if( rBm.GetOtherBookmarkPos() )
            aSubRegionED.InsertEntry( rBm.GetName() );
        const ::sw::mark::IMark* pBkmk = ppMark->get();
        if( pBkmk->IsExpanded() )
            aSubRegionED.InsertEntry( pBkmk->GetName() );
    }

    SwSection* pSect = ((SwInsertSectionTabDialog*)GetTabDialog())->GetSection();
diff --git a/sw/source/ui/dochdl/swdtflvr.cxx b/sw/source/ui/dochdl/swdtflvr.cxx
index 99f34e8..6539ad9 100644
--- a/sw/source/ui/dochdl/swdtflvr.cxx
+++ b/sw/source/ui/dochdl/swdtflvr.cxx
@@ -98,7 +98,7 @@
#include <ddefld.hxx>
#include <doc.hxx>
#include <pagedesc.hxx>
#include <bookmrk.hxx>
#include <IMark.hxx>
#include <docary.hxx>
#include <section.hxx>
#include <ndtxt.hxx>
@@ -159,6 +159,7 @@
#endif
#include <vos/mutex.hxx>
#include <vcl/svapp.hxx>
#include <swserv.hxx>

extern BOOL bFrmDrag;
extern BOOL bDDINetAttr;
@@ -883,11 +884,21 @@ int SwTransferable::PrepareForCopy( BOOL bIsCut )
        pWrtShell->Copy( pTmpDoc );

        {
            IDocumentMarkAccess* const pMarkAccess = pTmpDoc->getIDocumentMarkAccess();
            ::std::vector< ::sw::mark::IMark* > vDdeMarks;
            // find all DDE-Bookmarks
            for(IDocumentMarkAccess::const_iterator_t ppMark = pMarkAccess->getMarksBegin();
                ppMark != pMarkAccess->getMarksEnd();
                ppMark++)
            {
                if(IDocumentMarkAccess::DDE_BOOKMARK == IDocumentMarkAccess::GetType(**ppMark))
                    vDdeMarks.push_back(ppMark->get());
            }
            // remove all DDE-Bookmarks, they are invalid inside the clipdoc!
            const SwBookmarks& rBkmk = pTmpDoc->getBookmarks();
            for( USHORT n = rBkmk.Count(); n; )
                if( IDocumentBookmarkAccess::DDE_BOOKMARK == rBkmk[ --n ]->GetType() )
                    pTmpDoc->deleteBookmark( n );
            for(::std::vector< ::sw::mark::IMark* >::iterator ppMark = vDdeMarks.begin();
                ppMark != vDdeMarks.end();
                ppMark++)
                pMarkAccess->deleteMark(*ppMark);
        }

        // es wurde in der CORE eine neu angelegt (OLE-Objekte kopiert!)
@@ -3634,24 +3645,25 @@ SwTrnsfrDdeLink::SwTrnsfrDdeLink( SwTransferable& rTrans, SwWrtShell& rSh )
    }
    else
    {
        // wir erzeugen uns eine temp. Bookmark (ohne UNDO!)
        // creating a temp. bookmark without undo
        BOOL bUndo = rSh.DoesUndo();
        rSh.DoUndo( FALSE );
        BOOL bIsModified = rSh.IsModified();

        sName.AssignAscii( RTL_CONSTASCII_STRINGPARAM( "DDE_LINK" ));
        rSh.MakeUniqueBookmarkName( sName );

        //Ok, den eindeutigen Namen haben wir
        if( !rSh.SetBookmark( KeyCode(), sName, aEmptyStr, IDocumentBookmarkAccess::DDE_BOOKMARK ) )
            sName.Erase();
        else
        ::sw::mark::IMark* pMark = rSh.SetBookmark(
            KeyCode(),
            ::rtl::OUString(),
            ::rtl::OUString(),
            IDocumentMarkAccess::DDE_BOOKMARK);
        if(pMark)
        {
            sName = pMark->GetName();
            bDelBookmrk = TRUE;
            if( !bIsModified )
                rSh.ResetModified();
        }

        else
            sName.Erase();
        rSh.DoUndo( bUndo );
    }

@@ -3725,23 +3737,46 @@ BOOL SwTrnsfrDdeLink::WriteData( SvStream& rStrm )
    rStrm.Write( pMem, nLen );
    delete[] pMem;

    if( bDelBookmrk )
    //if( bDelBookmrk )
    //{
    //  // er wird das erstemal abgeholt, also ins Undo mitaufnehmen
    //  // aber wie??
    //}

    IDocumentMarkAccess* const pMarkAccess = pDocShell->GetDoc()->getIDocumentMarkAccess();
    IDocumentMarkAccess::const_iterator_t ppMark = pMarkAccess->findMark(sName);
    if(ppMark != pMarkAccess->getMarksEnd()
        && IDocumentMarkAccess::GetType(**ppMark) != IDocumentMarkAccess::BOOKMARK)
    {
        // er wird das erstemal abgeholt, also ins Undo mitaufnehmen
        // aber wie??
        // the mark is still a DdeBookmark
        // we replace it with a Bookmark, so it will get saved etc.
        ::sw::mark::IMark* const pMark = ppMark->get();
        SwServerObject* const pServerObject = dynamic_cast<SwServerObject *>(&refObj);

        // collecting state of old mark
        SwPaM aPaM(pMark->GetMarkStart());
        *aPaM.GetPoint() = pMark->GetMarkStart();
        if(pMark->IsExpanded())
        {
            aPaM.SetMark();
            *aPaM.GetMark() = pMark->GetMarkEnd();
        }
        ::rtl::OUString sMarkName = pMark->GetName();

        // remove mark
        pServerObject->SetNoServer(); // this removes the connection between SwServerObject and mark
        pMarkAccess->deleteMark(ppMark);

        // recreate as Bookmark
        ::sw::mark::IMark* const pNewMark = pMarkAccess->makeMark(
            aPaM,
            sMarkName,
            IDocumentMarkAccess::BOOKMARK);
        pServerObject->SetDdeBookmark(*pNewMark);
    }

    SwDoc* pDoc = pDocShell->GetDoc();
    USHORT nBookPos = pDoc->findBookmark( sName );
    if( USHRT_MAX != nBookPos )
    {
        SwBookmark* pBookMk = pDoc->getBookmarks()[ nBookPos ];
        pBookMk->SetType( IDocumentBookmarkAccess::BOOKMARK );
        pDoc->SetModified();
    }

    bDelBookmrk = FALSE;
    return TRUE;
    bDelBookmrk = false;
    return true;
}

// -----------------------------------------------------------------------
@@ -3768,7 +3803,8 @@ void SwTrnsfrDdeLink::Disconnect( BOOL bRemoveDataAdvise )
        // <--
        BOOL bIsModified = pDoc->IsModified();

        pDoc->deleteBookmark( sName );
        IDocumentMarkAccess* const pMarkAccess = pDoc->getIDocumentMarkAccess();
        pMarkAccess->deleteMark(pMarkAccess->findMark(sName));

        if( !bIsModified )
            pDoc->ResetModified();
diff --git a/sw/source/ui/docvw/edtwin.cxx b/sw/source/ui/docvw/edtwin.cxx
index 3d33d98..f5a39dd 100644
--- a/sw/source/ui/docvw/edtwin.cxx
+++ b/sw/source/ui/docvw/edtwin.cxx
@@ -149,7 +149,7 @@
#include <vos/mutex.hxx>
#include <vcl/svapp.hxx>

#include <bookmrk.hxx>
#include <IMark.hxx>
#include <doc.hxx>

#include "PostItMgr.hxx"
@@ -1475,8 +1475,8 @@ void SwEditWin::KeyInput(const KeyEvent &rKEvt)
                       KS_Fly_Change, KS_Draw_Change,
                       KS_SpecialInsert,
                       KS_EnterCharCell,
                       KS_GotoNextFieldBookmark,
                       KS_GotoPrevFieldBookmark,
                       KS_GotoNextFieldMark,
                       KS_GotoPrevFieldMark,
                       KS_Ende };


@@ -1897,10 +1897,12 @@ KEYINPUT_CHECKTABLE_INSDEL:
#ifdef SW_CRSR_TIMER
                    BOOL bOld = rSh.ChgCrsrTimerFlag( FALSE );
#endif
                    if (rSh.IsFormProtected() || rSh.IsInFieldBookmark()!=NULL || rSh.GetChar(FALSE)==CH_TXT_ATR_FORMELEMENT) {
                        eKeyState=KS_GotoNextFieldBookmark;
                    if (rSh.IsFormProtected() || rSh.GetCurrentFieldmark() || rSh.GetChar(FALSE)==CH_TXT_ATR_FORMELEMENT)
                    {
                        eKeyState=KS_GotoNextFieldMark;
                    }
                    else if( rSh.GetCurNumRule() && rSh.IsSttOfPara() &&
                    else
                    if( rSh.GetCurNumRule() && rSh.IsSttOfPara() &&
                        !rSh.HasReadonlySel() )
                    {
                        // --> OD 2007-10-02 #b660435#
@@ -1951,8 +1953,8 @@ KEYINPUT_CHECKTABLE_INSDEL:
#ifdef SW_CRSR_TIMER
                    BOOL bOld = rSh.ChgCrsrTimerFlag( FALSE );
#endif
                    if (rSh.IsFormProtected() || rSh.IsInFieldBookmark()!=NULL || rSh.GetChar(FALSE)==CH_TXT_ATR_FORMELEMENT) {
                        eKeyState=KS_GotoPrevFieldBookmark;
                    if (rSh.IsFormProtected() || rSh.GetCurrentFieldmark()|| rSh.GetChar(FALSE)==CH_TXT_ATR_FORMELEMENT) {
                        eKeyState=KS_GotoPrevFieldMark;
                    }
                    else if( rSh.GetCurNumRule() && rSh.IsSttOfPara() &&
                         !rSh.HasReadonlySel() )
@@ -2222,84 +2224,93 @@ KEYINPUT_CHECKTABLE_INSDEL:
            aCh = '\t';
            // kein break!
        case KS_InsChar:
        if (rSh.GetChar(FALSE)==CH_TXT_ATR_FORMELEMENT) {
            SwFieldBookmark *fieldBM=rSh.IsInFormFieldBookmark(); //$flr refactor!!!
               ASSERT(fieldBM!=NULL, "Where is my FieldBookmark??");
            if (fieldBM!=NULL) {
            fieldBM->SetChecked(!fieldBM->IsChecked());
            SwDocShell* pDocSh = rView.GetDocShell();
            SwDoc *pDoc=pDocSh->GetDoc();
            ASSERT(fieldBM->GetOtherBookmarkPos()!=NULL, "where is the otherpos?");
            if (fieldBM->GetOtherBookmarkPos()!=NULL) {
                SwPaM aPaM(fieldBM->GetBookmarkPos(), *fieldBM->GetOtherBookmarkPos());
                if (0) {
                rSh.StartAllAction();  //$flr TODO: understand why this not works
                pDoc->SetModified(aPaM);
                rSh.EndAllAction();
                } else {
                rSh.CalcLayout(); // workaround
            if (rSh.GetChar(FALSE)==CH_TXT_ATR_FORMELEMENT)
            {
                ::sw::mark::ICheckboxFieldmark* pFieldmark =
                    dynamic_cast< ::sw::mark::ICheckboxFieldmark* >
                        (rSh.GetCurrentFieldmark());
                OSL_ENSURE(pFieldmark,
                    "Where is my FieldMark??");
                if(pFieldmark)
                {
                    pFieldmark->SetChecked(!pFieldmark->IsChecked());
                    SwDocShell* pDocSh = rView.GetDocShell();
                    SwDoc *pDoc=pDocSh->GetDoc();
                    OSL_ENSURE(pFieldmark->IsExpanded(),
                        "where is the otherpos?");
                    if (pFieldmark->IsExpanded())
                    {
                        SwPaM aPaM(pFieldmark->GetMarkPos(), pFieldmark->GetOtherMarkPos());
                        if(0)
                        {
                            rSh.StartAllAction();  //$flr TODO: understand why this not works
                            pDoc->SetModified(aPaM);
                            rSh.EndAllAction();
                        }
                        else
                        {
                            rSh.CalcLayout(); // workaround
                        }
                    }
                }
                eKeyState = KS_Ende;
            }

            }
//          rSh.Overwrite(String('X'));
            eKeyState = KS_Ende;
        } else if( !rSh.HasReadonlySel() )
        {
            BOOL bIsNormalChar = GetAppCharClass().isLetterNumeric(
                                                        String( aCh ), 0 );
            if( bChkInsBlank && bIsNormalChar &&
                (aInBuffer.Len() || !rSh.IsSttPara() || !rSh.IsEndPara() ))
            else if(!rSh.HasReadonlySel())
            {
                // vor dem Zeichen noch ein Blank einfuegen. Dieses
                // kommt zwischen den Expandierten Text und dem neuen
                // "nicht Worttrenner".
                aInBuffer.Expand( aInBuffer.Len() + 1, ' ' );
            }
                BOOL bIsNormalChar = GetAppCharClass().isLetterNumeric(
                                                            String( aCh ), 0 );
                if( bChkInsBlank && bIsNormalChar &&
                    (aInBuffer.Len() || !rSh.IsSttPara() || !rSh.IsEndPara() ))
                {
                    // vor dem Zeichen noch ein Blank einfuegen. Dieses
                    // kommt zwischen den Expandierten Text und dem neuen
                    // "nicht Worttrenner".
                    aInBuffer.Expand( aInBuffer.Len() + 1, ' ' );
                }


            BOOL bIsAutoCorrectChar =  SvxAutoCorrect::IsAutoCorrectChar( aCh );
            if( !aKeyEvent.GetRepeat() && pACorr && bIsAutoCorrectChar &&
                    pACfg->IsAutoFmtByInput() &&
                (( pACorr->IsAutoCorrFlag( ChgWeightUnderl ) &&
                    ( '*' == aCh || '_' == aCh ) ) ||
                 ( pACorr->IsAutoCorrFlag( ChgQuotes ) && ('\"' == aCh ))||
                 ( pACorr->IsAutoCorrFlag( ChgSglQuotes ) && ( '\'' == aCh))))
            {
                FlushInBuffer();
                rSh.AutoCorrect( *pACorr, aCh );
                if( '\"' != aCh && '\'' != aCh )        // nur bei "*_" rufen!
                    rSh.UpdateAttr();
            }
            else if( !aKeyEvent.GetRepeat() && pACorr && bIsAutoCorrectChar &&
                    pACfg->IsAutoFmtByInput() &&
                pACorr->IsAutoCorrFlag( CptlSttSntnc | CptlSttWrd |
                                        ChgFractionSymbol | ChgOrdinalNumber |
                                        ChgToEnEmDash | SetINetAttr |
                                        Autocorrect ) &&
                '\"' != aCh && '\'' != aCh && '*' != aCh && '_' != aCh &&
                !bIsNormalChar
                )
            {
                FlushInBuffer();
                rSh.AutoCorrect( *pACorr, aCh );
                BOOL bIsAutoCorrectChar =  SvxAutoCorrect::IsAutoCorrectChar( aCh );
                if( !aKeyEvent.GetRepeat() && pACorr && bIsAutoCorrectChar &&
                        pACfg->IsAutoFmtByInput() &&
                    (( pACorr->IsAutoCorrFlag( ChgWeightUnderl ) &&
                        ( '*' == aCh || '_' == aCh ) ) ||
                     ( pACorr->IsAutoCorrFlag( ChgQuotes ) && ('\"' == aCh ))||
                     ( pACorr->IsAutoCorrFlag( ChgSglQuotes ) && ( '\'' == aCh))))
                {
                    FlushInBuffer();
                    rSh.AutoCorrect( *pACorr, aCh );
                    if( '\"' != aCh && '\'' != aCh )        // nur bei "*_" rufen!
                        rSh.UpdateAttr();
                }
                else if( !aKeyEvent.GetRepeat() && pACorr && bIsAutoCorrectChar &&
                        pACfg->IsAutoFmtByInput() &&
                    pACorr->IsAutoCorrFlag( CptlSttSntnc | CptlSttWrd |
                                            ChgFractionSymbol | ChgOrdinalNumber |
                                            ChgToEnEmDash | SetINetAttr |
                                            Autocorrect ) &&
                    '\"' != aCh && '\'' != aCh && '*' != aCh && '_' != aCh &&
                    !bIsNormalChar
                    )
                {
                    FlushInBuffer();
                    rSh.AutoCorrect( *pACorr, aCh );
                }
                else
                {
                    aInBuffer.Expand( aInBuffer.Len() + aKeyEvent.GetRepeat() + 1,aCh );
                    bFlushCharBuffer = Application::AnyInput( INPUT_KEYBOARD );
                    bFlushBuffer = !bFlushCharBuffer;
                    if( bFlushCharBuffer )
                        aKeyInputFlushTimer.Start();
                }
                eKeyState = KS_Ende;
            }
            else
            {
                aInBuffer.Expand( aInBuffer.Len() + aKeyEvent.GetRepeat() + 1,aCh );
                bFlushCharBuffer = Application::AnyInput( INPUT_KEYBOARD );
                bFlushBuffer = !bFlushCharBuffer;
                if( bFlushCharBuffer )
                    aKeyInputFlushTimer.Start();
                InfoBox( this, SW_RES( MSG_READONLY_CONTENT )).Execute();
    // ???          Window::KeyInput( aKeyEvent );
                eKeyState = KS_Ende;
            }
            eKeyState = KS_Ende;
        }
        else
        {
            InfoBox( this, SW_RES( MSG_READONLY_CONTENT )).Execute();
// ???          Window::KeyInput( aKeyEvent );
            eKeyState = KS_Ende;
        }
        break;

        case KS_CheckAutoCorrect:
@@ -2358,23 +2369,19 @@ KEYINPUT_CHECKTABLE_INSDEL:
                nKS_NUMINDENTINC_Count = 2;
                break;

        case KS_GotoNextFieldBookmark:
        {
        SwBookmark *pBM=rSh.GetNextFieldBookmark();
        if (pBM!=NULL) {
            rSh.GotoFieldBookmark(pBM);
        }
        }
            break;
            case KS_GotoNextFieldMark:
                {
                    ::sw::mark::IFieldmark const * const pFieldmark = rSh.GetFieldmarkAfter();
                    if(pFieldmark) rSh.GotoFieldmark(pFieldmark);
                }
                break;

        case KS_GotoPrevFieldBookmark:
        {
        SwBookmark *pBM=rSh.GetPrevFieldBookmark();
        if (pBM!=NULL) {
            rSh.GotoFieldBookmark(pBM);
        }
        }
            break;
            case KS_GotoPrevFieldMark:
                {
                    ::sw::mark::IFieldmark const * const pFieldmark = rSh.GetFieldmarkBefore();
                    if(pFieldmark) rSh.GotoFieldmark(pFieldmark);
                }
                break;

            case KS_NumIndentDec:
                // --> OD 2008-06-16 #i90078#
diff --git a/sw/source/ui/fldui/fldref.cxx b/sw/source/ui/fldui/fldref.cxx
index 5f3c1bc..24c025f 100644
--- a/sw/source/ui/fldui/fldref.cxx
+++ b/sw/source/ui/fldui/fldref.cxx
@@ -39,7 +39,7 @@

#include "swtypes.hxx"
#include <view.hxx>
#include <bookmrk.hxx>
#include <IMark.hxx>
#include <expfld.hxx>
#include <swmodule.hxx>
#ifndef _FLDREF_HXX
@@ -59,7 +59,8 @@
#endif
// --> OD 2007-11-14 #i83479#
#include <SwNodeNum.hxx>
#include <IDocumentBookmarkAccess.hxx>
#include <IDocumentMarkAccess.hxx>
#include <ndtxt.hxx>
// <--

// sw/inc/expfld.hxx
@@ -78,6 +79,8 @@ USHORT  nFldDlgFmtSel       = 0;

#define USER_DATA_VERSION_1 "1"
#define USER_DATA_VERSION USER_DATA_VERSION_1


/*--------------------------------------------------------------------
    Beschreibung:
 --------------------------------------------------------------------*/
@@ -544,11 +547,14 @@ void SwFldRefPage::UpdateSubType()
        {
            aSelectionLB.SetStyle(aSelectionLB.GetStyle()|WB_SORT);
            // alle Textmarken besorgen
            USHORT nCnt = pSh->GetBookmarkCnt(TRUE);
            for( USHORT n = 0; n < nCnt; ++n )
            IDocumentMarkAccess* const pMarkAccess = pSh->getIDocumentMarkAccess();
            for(IDocumentMarkAccess::const_iterator_t ppMark = pMarkAccess->getBookmarksBegin();
                ppMark != pMarkAccess->getBookmarksEnd();
                ppMark++)
            {
                const SwBookmark& rBkmk = pSh->GetBookmark( n, TRUE );
                aSelectionLB.InsertEntry( rBkmk.GetName() );
                const ::sw::mark::IMark* pBkmk = ppMark->get();
                if(IDocumentMarkAccess::BOOKMARK == IDocumentMarkAccess::GetType(*pBkmk))
                    aSelectionLB.InsertEntry( pBkmk->GetName() );
            }
            if (IsFldEdit())
                sOldSel = pRefFld->GetSetRefName();
@@ -952,16 +958,10 @@ BOOL SwFldRefPage::FillItemSet(SfxItemSet& )
                pSh->getIDocumentOutlineNodesAccess()->getOutlineNodes( maOutlineNodes );
                if ( nOutlIdx < maOutlineNodes.size() )
                {
                    IDocumentBookmarkAccess* pIDoc = pSh->getIDocumentBookmarkAccess();
                    aName = pIDoc->getCrossRefBookmarkName(
                                    *(maOutlineNodes[nOutlIdx]),
                                    IDocumentBookmarkAccess::HEADING );
                    if ( aName.Len() == 0 )
                    {
                        aName = pIDoc->makeCrossRefBookmark(
                                    *(maOutlineNodes[nOutlIdx]),
                                    IDocumentBookmarkAccess::HEADING );
                    }
                    ::sw::mark::IMark const * const pMark = pSh->getIDocumentMarkAccess()->getMarkForTxtNode(
                        *(maOutlineNodes[nOutlIdx]),
                        IDocumentMarkAccess::CROSSREF_HEADING_BOOKMARK);
                    aName = pMark->GetName();
                    nTypeId = TYP_GETREFFLD;
                    nSubType = REF_BOOKMARK;
                }
@@ -978,16 +978,10 @@ BOOL SwFldRefPage::FillItemSet(SfxItemSet& )
                pSh->getIDocumentListItemsAccess()->getNumItems( maNumItems );
                if ( nNumItemIdx < maNumItems.size() )
                {
                    IDocumentBookmarkAccess* pIDoc = pSh->getIDocumentBookmarkAccess();
                    aName = pIDoc->getCrossRefBookmarkName(
                    ::sw::mark::IMark const * const pMark = pSh->getIDocumentMarkAccess()->getMarkForTxtNode(
                        *(maNumItems[nNumItemIdx]->GetTxtNode()),
                        IDocumentBookmarkAccess::NUMITEM );
                    if ( aName.Len() == 0 )
                    {
                        aName = pIDoc->makeCrossRefBookmark(
                            *(maNumItems[nNumItemIdx]->GetTxtNode()),
                            IDocumentBookmarkAccess::NUMITEM );
                    }
                        IDocumentMarkAccess::CROSSREF_NUMITEM_BOOKMARK);
                    aName = pMark->GetName();
                    nTypeId = TYP_GETREFFLD;
                    nSubType = REF_BOOKMARK;
                }
diff --git a/sw/source/ui/inc/navipi.hxx b/sw/source/ui/inc/navipi.hxx
index 339fe8d..479ed13 100644
--- a/sw/source/ui/inc/navipi.hxx
+++ b/sw/source/ui/inc/navipi.hxx
@@ -101,7 +101,6 @@ class SwNavigationPI : public Window,

    long    nDocLBIniHeight;
    long    nWishWidth;
    USHORT  nActMark;
    USHORT  nAutoMarkIdx;
    USHORT  nRegionMode; // 0 - URL, 1 - Bereich mit Link 2 - B. ohne Link
    short   nZoomIn;
diff --git a/sw/source/ui/inc/view.hxx b/sw/source/ui/inc/view.hxx
index 9ff923a..958e83c 100644
--- a/sw/source/ui/inc/view.hxx
+++ b/sw/source/ui/inc/view.hxx
@@ -186,7 +186,7 @@ class SW_DLLPUBLIC SwView: public SfxViewShell
    static USHORT           nInsertObjectCtrlState;
    static USHORT           nInsertFieldCtrlState;
    static USHORT           nMoveType; // fuer Buttons unter dem Scrollbar (viewmdi)
    static USHORT           nActMark; // aktuelle Sprungmarke fuer unbenannte Merker
    static sal_Int32        nActMark; // aktuelle Sprungmarke fuer unbenannte Merker

    static BOOL             bExtra;
    static BOOL             bFound;
@@ -495,7 +495,7 @@ public:
    static USHORT   GetMoveType();
    static void     SetMoveType(USHORT nSet);
    DECL_STATIC_LINK( SwView, MoveNavigationHdl, bool* ); // #i75416#
    static void     SetActMark(BYTE nSet);
    static void     SetActMark(sal_Int32 nSet);

    BOOL            HandleWheelCommands( const CommandEvent& );

diff --git a/sw/source/ui/inc/wrtsh.hxx b/sw/source/ui/inc/wrtsh.hxx
index fcccff4..70e50997 100644
--- a/sw/source/ui/inc/wrtsh.hxx
+++ b/sw/source/ui/inc/wrtsh.hxx
@@ -102,7 +102,7 @@ private:
    using SwCrsrShell::GotoPage;
    using SwFEShell::InsertObject;
    using SwEditShell::AutoCorrect;
    using SwCrsrShell::GotoBookmark;
    using SwCrsrShell::GotoMark;

public:

@@ -409,13 +409,13 @@ typedef BOOL (SwWrtShell:: *FNSimpleMove)();
    virtual void DrawSelChanged( );

    // springe zum Bookmark und setze die "Selections-Flags" wieder richtig
    BOOL GotoBookmark( USHORT nPos );
    BOOL GotoBookmark( USHORT nPos, BOOL bSelect, BOOL bStart );
    BOOL GotoBookmark( const String& rName );
    BOOL GotoMark( const ::sw::mark::IMark* const pMark );
    BOOL GotoMark( const ::sw::mark::IMark* const pMark, BOOL bSelect, BOOL bStart );
    BOOL GotoMark( const ::rtl::OUString& rName );
    BOOL GoNextBookmark(); // TRUE, wenn's noch eine gab
    BOOL GoPrevBookmark();

        bool GotoFieldBookmark(SwBookmark *pBkmk);
    bool GotoFieldmark(::sw::mark::IFieldmark const * const pMark);

    BOOL GotoField( const SwFmtFld& rFld );

@@ -613,8 +613,7 @@ private:
        BOOKMARK_LAST_LAST_ENTRY
    };

    SW_DLLPRIVATE BOOL MoveBookMark(    BookMarkMove eFuncId,
                            USHORT nPos = 0 );
    SW_DLLPRIVATE BOOL MoveBookMark(BookMarkMove eFuncId, const ::sw::mark::IMark* const pMark=NULL);
};

inline void SwWrtShell::ResetCursorStack()
diff --git a/sw/source/ui/misc/bookmark.cxx b/sw/source/ui/misc/bookmark.cxx
index 78d8655..f7eace7 100644
--- a/sw/source/ui/misc/bookmark.cxx
+++ b/sw/source/ui/misc/bookmark.cxx
@@ -46,7 +46,7 @@
#include "wrtsh.hxx"        //
#include "cmdid.h"
#include "bookmark.hxx"     // SwInsertBookmarkDlg
#include "bookmrk.hxx"      //  SwBookmark
#include "IMark.hxx"
#include "bookmark.hrc"
#include "misc.hrc"

@@ -121,7 +121,8 @@ void SwInsertBookmarkDlg::Apply()
    for (USHORT nCount = aBookmarkBox.GetRemovedCount(); nCount > 0; nCount--)
    {
        String sRemoved = aBookmarkBox.GetRemovedEntry( nCount -1 ).GetName();
        rSh.DelBookmark( sRemoved );
        IDocumentMarkAccess* const pMarkAccess = rSh.getIDocumentMarkAccess();
        pMarkAccess->deleteMark( pMarkAccess->findMark(sRemoved) );
        SfxRequest aReq( rSh.GetView().GetViewFrame(), FN_DELETE_BOOKMARK );
        aReq.AppendItem( SfxStringItem( FN_DELETE_BOOKMARK, sRemoved ) );
        aReq.Done();
@@ -170,17 +171,17 @@ SwInsertBookmarkDlg::SwInsertBookmarkDlg( Window *pParent, SwWrtShell &rS, SfxRe
    aDeleteBtn.SetClickHdl(LINK(this, SwInsertBookmarkDlg, DeleteHdl));

    // Combobox mit vorhandenen Bookmarks fuellen
    USHORT nCount = rSh.GetBookmarkCnt(TRUE);

    for( USHORT nId = 0; nId < nCount; nId++ )
    IDocumentMarkAccess* const pMarkAccess = rSh.getIDocumentMarkAccess();
    USHORT nId = 0;
    for( IDocumentMarkAccess::const_iterator_t ppBookmark = pMarkAccess->getBookmarksBegin();
        ppBookmark != pMarkAccess->getBookmarksEnd();
        ppBookmark++)
    {
        SwBookmark& rBkmk = rSh.GetBookmark( nId, TRUE );
        aBookmarkBox.InsertEntry( SwBoxEntry( rBkmk.GetName(), nId ) );
        if(IDocumentMarkAccess::BOOKMARK == IDocumentMarkAccess::GetType(**ppBookmark))
            aBookmarkBox.InsertEntry( SwBoxEntry( ppBookmark->get()->GetName(), nId++ ) );
    }

    FreeResource();
    sRemoveWarning = String(SW_RES(STR_REMOVE_WARNING));

}

/*------------------------------------------------------------------------
diff --git a/sw/source/ui/shells/basesh.cxx b/sw/source/ui/shells/basesh.cxx
index e46fbe5..25b1efa 100644
--- a/sw/source/ui/shells/basesh.cxx
+++ b/sw/source/ui/shells/basesh.cxx
@@ -102,7 +102,6 @@
#endif
#include <viewopt.hxx>
#include <fontcfg.hxx>
#include <bookmrk.hxx>
#include <docstat.hxx>
#include <usrfld.hxx>
#include <expfld.hxx>
diff --git a/sw/source/ui/shells/textsh1.cxx b/sw/source/ui/shells/textsh1.cxx
index 92fee69..dcd91dd 100644
--- a/sw/source/ui/shells/textsh1.cxx
+++ b/sw/source/ui/shells/textsh1.cxx
@@ -78,7 +78,7 @@
#include <fmthdft.hxx>
#include <pagedesc.hxx>
#include <textsh.hxx>
#include <bookmrk.hxx>
#include <IMark.hxx>
#include <swdtflvr.hxx>
#include <docstat.hxx>
#include <outline.hxx>
@@ -567,8 +567,7 @@ void SwTextShell::Execute(SfxRequest &rReq)
        {
            if ( pItem )
            {
                String sName = ((SfxStringItem*)pItem)->GetValue();
                rWrtSh.MakeUniqueBookmarkName(sName);
                ::rtl::OUString sName = ((SfxStringItem*)pItem)->GetValue();
                rWrtSh.SetBookmark( KeyCode(), sName, aEmptyStr );
            }
            else
@@ -587,7 +586,10 @@ void SwTextShell::Execute(SfxRequest &rReq)
        case FN_DELETE_BOOKMARK:
        {
            if ( pItem )
                rWrtSh.DelBookmark( ((SfxStringItem*)pItem)->GetValue() );
            {
                IDocumentMarkAccess* const pMarkAccess = rWrtSh.getIDocumentMarkAccess();
                pMarkAccess->deleteMark( pMarkAccess->findMark(((SfxStringItem*)pItem)->GetValue()) );
            }
            break;
        }
        case FN_AUTOFORMAT_REDLINE_APPLY:
diff --git a/sw/source/ui/shells/txtcrsr.cxx b/sw/source/ui/shells/txtcrsr.cxx
index f7247baf..19b3636 100644
--- a/sw/source/ui/shells/txtcrsr.cxx
+++ b/sw/source/ui/shells/txtcrsr.cxx
@@ -48,7 +48,6 @@
#include <textsh.hxx>
#endif
#include <num.hxx>
#include <bookmrk.hxx>
#include <edtwin.hxx>
#include <crsskip.hxx>

diff --git a/sw/source/ui/uiview/makefile.mk b/sw/source/ui/uiview/makefile.mk
index cc0fa1c..2aa5e12 100644
--- a/sw/source/ui/uiview/makefile.mk
+++ b/sw/source/ui/uiview/makefile.mk
@@ -54,7 +54,8 @@ EXCEPTIONSFILES= \
        $(SLO)$/uivwimp.obj \
        $(SLO)$/view.obj \
        $(SLO)$/view2.obj \
        $(SLO)$/viewling.obj
        $(SLO)$/viewling.obj \
        $(SLO)$/viewmdi.obj \

SLOFILES =  \
        $(SLO)$/view0.obj \
diff --git a/sw/source/ui/uiview/view2.cxx b/sw/source/ui/uiview/view2.cxx
index c48ad07..243c994 100644
--- a/sw/source/ui/uiview/view2.cxx
+++ b/sw/source/ui/uiview/view2.cxx
@@ -119,7 +119,7 @@
#include <pagedesc.hxx>
#include <section.hxx>
#include <usrpref.hxx>
#include <bookmrk.hxx>
#include <IMark.hxx>
#include <navipi.hxx>
#include <tox.hxx>
#include <workctrl.hxx>
@@ -1566,10 +1566,18 @@ void SwView::ExecuteStatusLine(SfxRequest &rReq)
        {
            if (SFX_ITEM_SET == pArgs->GetItemState( nWhich, TRUE, &pItem))
            {
                USHORT nDest;
                nDest = ((const SfxUInt16Item *)pItem)->GetValue();
                rSh.EnterStdMode();
                rSh.GotoBookmark( nDest );
                const IDocumentMarkAccess* pMarkAccess = rSh.getIDocumentMarkAccess();
                const sal_Int32 nIdx = static_cast<const SfxUInt16Item*>(pItem)->GetValue();
                if(nIdx < pMarkAccess->getBookmarksCount())
                {
                    const IDocumentMarkAccess::const_iterator_t ppBookmark = rSh.getIDocumentMarkAccess()->getBookmarksBegin() + nIdx;
                    rSh.EnterStdMode();
                    rSh.GotoMark( ppBookmark->get() );
                }
                else
                    OSL_ENSURE(false,
                        "SwView::ExecuteStatusLine(..)"
                        " - Ignoring out of range bookmark index");
            }
        }
        break;
@@ -1871,6 +1879,8 @@ BOOL SwView::JumpToSwMark( const String& rMark )
                sMark.Search( cMarkSeperator, nPos + 1 )) )
                nPos = nLastPos;

        IDocumentMarkAccess::const_iterator_t ppMark;
        IDocumentMarkAccess* const pMarkAccess = pWrtShell->getIDocumentMarkAccess();
        if( STRING_NOTFOUND != nPos &&
            ( sCmp = sMark.Copy( nPos + 1 ) ).EraseAllChars().Len() )
        {
@@ -1919,8 +1929,8 @@ BOOL SwView::JumpToSwMark( const String& rMark )
                    bRet = TRUE;
                }
            }
            else if( USHRT_MAX != ( nPos = pWrtShell->FindBookmark( sMark ) ))
                pWrtShell->GotoBookmark( nPos, FALSE, TRUE ), bRet = TRUE;
            else if( pMarkAccess->getMarksEnd() != (ppMark = pMarkAccess->findMark(sMark)) )
                pWrtShell->GotoMark( ppMark->get(), FALSE, TRUE ), bRet = TRUE;
            else if( 0 != ( pINet = pWrtShell->FindINetAttr( sMark ) ))
                bRet = pWrtShell->GotoINetAttr( *pINet->GetTxtINetFmt() );

@@ -1941,8 +1951,8 @@ BOOL SwView::JumpToSwMark( const String& rMark )
                }
            }
        }
        else if( USHRT_MAX != ( nPos = pWrtShell->FindBookmark( sMark ) ))
            pWrtShell->GotoBookmark( nPos, FALSE, TRUE ), bRet = TRUE;
        else if( pMarkAccess->getMarksEnd() != (ppMark = pMarkAccess->findMark(sMark)))
            pWrtShell->GotoMark( ppMark->get(), FALSE, TRUE ), bRet = TRUE;
        else if( 0 != ( pINet = pWrtShell->FindINetAttr( sMark ) ))
            bRet = pWrtShell->GotoINetAttr( *pINet->GetTxtINetFmt() );

diff --git a/sw/source/ui/uiview/viewmdi.cxx b/sw/source/ui/uiview/viewmdi.cxx
index 08067ee..702c079 100644
--- a/sw/source/ui/uiview/viewmdi.cxx
+++ b/sw/source/ui/uiview/viewmdi.cxx
@@ -58,7 +58,7 @@
#include <uitool.hxx>
#include <edtwin.hxx>
#include <pagedesc.hxx>
#include <bookmrk.hxx>
#include <IMark.hxx>
#include <fldbas.hxx>
#include <workctrl.hxx>
#include <usrpref.hxx>
@@ -88,7 +88,8 @@
#include <postit.hxx>

USHORT  SwView::nMoveType = NID_PGE;
USHORT  SwView::nActMark = 0;
sal_Int32 SwView::nActMark = 0;


#define VIEW_IMAGECOLOR COL_LIGHTBLUE

@@ -455,37 +456,37 @@ IMPL_STATIC_LINK( SwView, MoveNavigationHdl, bool *, pbNext )
        break;
        case NID_MARK:
        {
            // Selektionen aufheben
            // unselect
            rSh.MoveCrsr();
            rSh.EnterStdMode();
            const USHORT nBookCnt = rSh.GetBookmarkCnt();
            USHORT nMarkCount = 0;
            USHORT nRealIdx[MAX_MARKS];
            for( USHORT nCount = 0; nCount < nBookCnt; ++nCount )

            // collect navigator reminders
            IDocumentMarkAccess* const pMarkAccess = rSh.getIDocumentMarkAccess();
            ::std::vector< const ::sw::mark::IMark* > vNavMarks;
            for( IDocumentMarkAccess::const_iterator_t ppMark = pMarkAccess->getMarksBegin();
                ppMark != pMarkAccess->getMarksEnd();
                ppMark++)
            {
                if( rSh.GetBookmark( nCount ).IsMark() )
                {
                    nRealIdx[nMarkCount] = nCount;
                    ++nMarkCount;
                }
                if( IDocumentMarkAccess::GetType(**ppMark) == IDocumentMarkAccess::NAVIGATOR_REMINDER )
                    vNavMarks.push_back(ppMark->get());
            }
            if (nMarkCount)

            // move
            if(vNavMarks.size())
            {
                if(!bNext)
                if(bNext)
                {
                    if (nActMark > 1)
                        --nActMark;
                    else
                        nActMark = nMarkCount;
                    nActMark++;
                    if (nActMark >= MAX_MARKS || nActMark >= static_cast<sal_Int32>(vNavMarks.size()))
                        nActMark = 0;
                }
                else
                {
                    ++nActMark;
                    if (nActMark > MAX_MARKS || nActMark > nMarkCount)
                        nActMark = 1;
                    nActMark--;
                    if (nActMark < 0 || nActMark >= static_cast<sal_Int32>(vNavMarks.size()))
                        nActMark = vNavMarks.size()-1;
                }

                rSh.GotoBookmark( nRealIdx[nActMark - 1] );
                rSh.GotoMark(vNavMarks[nActMark]);
            }
        }
        break;
@@ -701,7 +702,7 @@ void SwView::SetMoveType(USHORT nSet)
/*-----------------20.06.97 11:18-------------------

--------------------------------------------------*/
void SwView::SetActMark(BYTE nSet)
void SwView::SetActMark(sal_Int32 nSet)
{
    nActMark = nSet;
}
diff --git a/sw/source/ui/uno/unoatxt.cxx b/sw/source/ui/uno/unoatxt.cxx
index ffae96e..3d378cc 100644
--- a/sw/source/ui/uno/unoatxt.cxx
+++ b/sw/source/ui/uno/unoatxt.cxx
@@ -56,12 +56,13 @@
#include <swevent.hxx>
#include <doc.hxx>
#include <unocrsr.hxx>
#include <bookmrk.hxx>
#include <IMark.hxx>
#include <unoprnms.hxx>
#include <docsh.hxx>
#include <swunodef.hxx>
#include <swmodule.hxx>
#include <svtools/smplhint.hxx>
#include <svtools/macitem.hxx>

#include <svx/acorrcfg.hxx>

@@ -398,10 +399,8 @@ void SwXAutoTextGroup::renameByName(const OUString& aElementName,
    else
        throw uno::RuntimeException();
}
/* -----------------04.05.99 11:57-------------------
 *
 * --------------------------------------------------*/
sal_Bool lcl_CopySelToDoc( SwDoc* pInsDoc, OTextCursorHelper* pxCursor, SwXTextRange* pxRange )

sal_Bool lcl_CopySelToDoc( SwDoc* pInsDoc, OTextCursorHelper* pxCursor, SwXTextRange* pxRange)
{
    ASSERT( pInsDoc, "kein Ins.Dokument"  );

@@ -421,10 +420,10 @@ sal_Bool lcl_CopySelToDoc( SwDoc* pInsDoc, OTextCursorHelper* pxCursor, SwXTextR
        }
        else
        {
            SwBookmark* pBkm = pxRange->GetBookmark();
            if(pBkm && pBkm->GetOtherBookmarkPos())
            const ::sw::mark::IMark* const pBkmk = pxRange->GetBookmark();
            if(pBkmk && pBkmk->IsExpanded())
            {
                SwPaM aTmp(*pBkm->GetOtherBookmarkPos(), pBkm->GetBookmarkPos());
                SwPaM aTmp(pBkmk->GetOtherMarkPos(), pBkmk->GetMarkPos());
                bRet |= (true == pxRange->GetDoc()->Copy(aTmp, aPos));
            }
        }
@@ -1134,11 +1133,11 @@ void SwXAutoTextEntry::applyTo(const uno::Reference< text::XTextRange > & xTextR
    SwPaM* pInsertPaM = 0;
    if(pRange)
    {
        SwBookmark* pBkm = pRange->GetBookmark();
        if(pBkm->GetOtherBookmarkPos())
            pInsertPaM = new SwPaM(*pBkm->GetOtherBookmarkPos(), pBkm->GetBookmarkPos());
        const ::sw::mark::IMark* const pBkmk = pRange->GetBookmark();
        if(pBkmk->IsExpanded())
            pInsertPaM = new SwPaM(pBkmk->GetOtherMarkPos(), pBkmk->GetMarkPos());
        else
            pInsertPaM = new SwPaM(pBkm->GetBookmarkPos());
            pInsertPaM = new SwPaM(pBkmk->GetMarkPos());
    }
    else
    {
diff --git a/sw/source/ui/uno/unotxvw.cxx b/sw/source/ui/uno/unotxvw.cxx
index 42b0d69..0a7a991 100644
--- a/sw/source/ui/uno/unotxvw.cxx
+++ b/sw/source/ui/uno/unotxvw.cxx
@@ -66,7 +66,7 @@
#include <sfx2/request.hxx>
#include <frmatr.hxx>
#include <vos/mutex.hxx>
#include <bookmrk.hxx>
#include <IMark.hxx>
#include <unotxdoc.hxx>
#include <unodraw.hxx>
#include <svx/unoshcol.hxx>
@@ -435,13 +435,12 @@ sal_Bool SwXTextView::select(const uno::Any& aInterface) throw( lang::IllegalArg
                    xIfcTunnel->getSomething(SwXBookmark::getUnoTunnelId()));
            if(pBkm && pBkm->GetDoc() == pDoc)
            {

                sal_uInt16 nFndPos = rSh.FindBookmark(pBkm->getName());

                if( USHRT_MAX != nFndPos )
                IDocumentMarkAccess* const pMarkAccess = rSh.getIDocumentMarkAccess();
                IDocumentMarkAccess::const_iterator_t ppMark = pMarkAccess->findMark(pBkm->getName());
                if( ppMark != pMarkAccess->getMarksEnd() )
                {
                    rSh.EnterStdMode();
                    rSh.GotoBookmark( nFndPos );
                    rSh.GotoMark( ppMark->get() );
                }
                return sal_True;
            }
@@ -1441,8 +1440,8 @@ void SwXTextViewCursor::gotoRange(
        }
        else if(pRange && pRange->GetBookmark())
        {
            SwBookmark* pBkm = pRange->GetBookmark();
            pSrcNode = &pBkm->GetBookmarkPos().nNode.GetNode();
            const ::sw::mark::IMark* const pBkmk = pRange->GetBookmark();
            pSrcNode = &(pBkmk->GetMarkPos().nNode.GetNode());
        }
        else if (pPara && pPara->GetCrsr())
        {
diff --git a/sw/source/ui/utlui/bookctrl.cxx b/sw/source/ui/utlui/bookctrl.cxx
index 20c1ca6..1de7b99 100644
--- a/sw/source/ui/utlui/bookctrl.cxx
+++ b/sw/source/ui/utlui/bookctrl.cxx
@@ -53,8 +53,9 @@
#include "errhdl.hxx"
#include "swmodule.hxx"
#include "wrtsh.hxx"
#include "bookmrk.hxx"
#include "IMark.hxx"
#include "bookctrl.hxx"
#include <map>

SFX_IMPL_STATUSBAR_CONTROL( SwBookmarkControl, SfxStringItem );

@@ -134,25 +135,29 @@ void SwBookmarkControl::Command( const CommandEvent& rCEvt )
        CaptureMouse();
        BookmarkPopup_Impl aPop;
        SwWrtShell* pWrtShell = ::GetActiveWrtShell();
        USHORT nBookCnt;
        if( pWrtShell && 0 != ( nBookCnt = pWrtShell->GetBookmarkCnt() ) )
        if( pWrtShell && pWrtShell->getIDocumentMarkAccess()->getMarksCount() > 0 )
        {
            SvUShorts aBookArr;
            for( USHORT nCount = 0; nCount < nBookCnt; ++nCount )
            IDocumentMarkAccess* const pMarkAccess = pWrtShell->getIDocumentMarkAccess();
            IDocumentMarkAccess::const_iterator_t ppBookmarkStart = pMarkAccess->getBookmarksBegin();
            USHORT nPopupId = 1;
            ::std::map<sal_Int32, USHORT> aBookmarkIdx;
            for(IDocumentMarkAccess::const_iterator_t ppBookmark = ppBookmarkStart;
                ppBookmark != pMarkAccess->getBookmarksEnd();
                ppBookmark++)
            {
                SwBookmark& rBkmk = pWrtShell->GetBookmark( nCount );
                if( rBkmk.IsBookMark() )
                if(IDocumentMarkAccess::BOOKMARK == IDocumentMarkAccess::GetType(**ppBookmark))
                {
                    aBookArr.Insert( nCount, aBookArr.Count() );
                    aPop.InsertItem( aBookArr.Count(), rBkmk.GetName() );
                    aPop.InsertItem( nPopupId, ppBookmark->get()->GetName() );
                    aBookmarkIdx[nPopupId] = static_cast<USHORT>(ppBookmark - ppBookmarkStart);
                    nPopupId++;
                }
            }
            aPop.Execute( &GetStatusBar(), rCEvt.GetMousePosPixel());
            USHORT nCurrId = aPop.GetCurId();
            if( nCurrId != USHRT_MAX)
            {
                SfxUInt16Item aBookmark( FN_STAT_BOOKMARK, aBookArr[nCurrId-1] );
                SfxViewFrame::Current()->GetDispatcher()->Execute(  FN_STAT_BOOKMARK,
                SfxUInt16Item aBookmark( FN_STAT_BOOKMARK, aBookmarkIdx[nCurrId] );
                SfxViewFrame::Current()->GetDispatcher()->Execute( FN_STAT_BOOKMARK,
                    SFX_CALLMODE_ASYNCHRON|SFX_CALLMODE_RECORD,
                                        &aBookmark, 0L );
            }
@@ -160,5 +165,3 @@ void SwBookmarkControl::Command( const CommandEvent& rCEvt )
        ReleaseMouse();
    }
}


diff --git a/sw/source/ui/utlui/content.cxx b/sw/source/ui/utlui/content.cxx
index b925fdb..ce02579 100644
--- a/sw/source/ui/utlui/content.cxx
+++ b/sw/source/ui/utlui/content.cxx
@@ -61,7 +61,7 @@
#include <frmfmt.hxx>
#include <fldbas.hxx>
#include <txtatr.hxx>
#include <bookmrk.hxx>
#include <IMark.hxx>
#include <section.hxx>
#include <tox.hxx>
#define NAVIPI_CXX
@@ -122,6 +122,7 @@
#define CTYPE_CNT   0
#define CTYPE_CTT   1

using namespace ::std;
using namespace ::com::sun::star;
using namespace ::com::sun::star::text;
using namespace ::com::sun::star::uno;
@@ -141,37 +142,40 @@ SV_IMPL_OP_PTRARR_SORT(SwContentArr, SwContentPtr)
sal_Bool SwContentTree::bIsInDrag = sal_False;


/***************************************************************************
    Beschreibung: Hilfsmethoden
***************************************************************************/


sal_Bool lcl_IsContent(SvLBoxEntry* pEntry)
namespace
{
    return ((SwTypeNumber*)pEntry->GetUserData())->GetTypeId() == CTYPE_CNT;
}


sal_Bool lcl_IsContentType(SvLBoxEntry* pEntry)
{
    return ((SwTypeNumber*)pEntry->GetUserData())->GetTypeId() == CTYPE_CTT;
}


sal_Bool lcl_FindShell(SwWrtShell* pShell)
{
    sal_Bool bFound = sal_False;
    SwView *pView = SwModule::GetFirstView();
    while (pView)
    static sal_Bool lcl_IsContent(SvLBoxEntry* pEntry)
    {
        if(pShell == &pView->GetWrtShell())
        {
            bFound = sal_True;
            break;
        }
        pView = SwModule::GetNextView(pView);
        return ((SwTypeNumber*)pEntry->GetUserData())->GetTypeId() == CTYPE_CNT;
    }
    return bFound;


    static sal_Bool lcl_IsContentType(SvLBoxEntry* pEntry)
    {
        return ((SwTypeNumber*)pEntry->GetUserData())->GetTypeId() == CTYPE_CTT;
    }


    static sal_Bool lcl_FindShell(SwWrtShell* pShell)
    {
        sal_Bool bFound = sal_False;
        SwView *pView = SwModule::GetFirstView();
        while (pView)
        {
            if(pShell == &pView->GetWrtShell())
            {
                bFound = sal_True;
                break;
            }
            pView = SwModule::GetNextView(pView);
        }
        return bFound;
    }

    static bool lcl_IsUiVisibleBookmark(const IDocumentMarkAccess::pMark_t& rpMark)
    {
        return IDocumentMarkAccess::GetType(*rpMark) == IDocumentMarkAccess::BOOKMARK;
    }
}

/***************************************************************************
@@ -300,9 +304,13 @@ void SwContentType::Init(sal_Bool* pbInvalidateWindow)
            bEdit = sal_True;
        }
        break;
        case CONTENT_TYPE_BOOKMARK  :
        case CONTENT_TYPE_BOOKMARK:
        {
            nMemberCount = pWrtShell->GetBookmarkCnt(sal_True);
            IDocumentMarkAccess* const pMarkAccess = pWrtShell->getIDocumentMarkAccess();
            nMemberCount = static_cast<USHORT>(count_if(
                pMarkAccess->getBookmarksBegin(),
                pMarkAccess->getBookmarksEnd(),
                &lcl_IsUiVisibleBookmark));
            sTypeToken = aEmptyStr;
            bEdit = sal_True;
        }
@@ -663,16 +671,20 @@ void    SwContentType::FillMemberList(sal_Bool* pbLevelOrVisibiblityChanged)
            }
        }
        break;
        case CONTENT_TYPE_BOOKMARK  :
        case CONTENT_TYPE_BOOKMARK:
        {
            nMemberCount = pWrtShell->GetBookmarkCnt(sal_True);
            for(sal_uInt16 i = 0; i < nMemberCount; i++)
            IDocumentMarkAccess* const pMarkAccess = pWrtShell->getIDocumentMarkAccess();
            for(IDocumentMarkAccess::const_iterator_t ppBookmark = pMarkAccess->getBookmarksBegin();
                ppBookmark != pMarkAccess->getBookmarksEnd();
                ppBookmark++)
            {
                SwBookmark& rBkmk = pWrtShell->GetBookmark( i, sal_True );
                    const String& rBkmName = rBkmk.GetName();
                if(lcl_IsUiVisibleBookmark(*ppBookmark))
                {
                    const String& rBkmName = ppBookmark->get()->GetName();
                    //nYPos von 0 -> text::Bookmarks werden nach Alphabet sortiert
                    SwContent* pCnt = new SwContent(this, rBkmName, 0);
                    pMember->Insert(pCnt);//, pMember->Count());
                }
            }
        }
        break;
@@ -2885,7 +2897,8 @@ void SwContentTree::EditEntry(SvLBoxEntry* pEntry, sal_uInt8 nMode)
        case CONTENT_TYPE_BOOKMARK  :
            if(nMode == EDIT_MODE_DELETE)
            {
                pActiveShell->DelBookmark( pCnt->GetName() );
                IDocumentMarkAccess* const pMarkAccess = pActiveShell->getIDocumentMarkAccess();
                pMarkAccess->deleteMark( pMarkAccess->findMark(pCnt->GetName()) );
            }
            else if(nMode == EDIT_MODE_RENAME)
            {
@@ -3051,9 +3064,9 @@ void SwContentTree::GotoContent(SwContent* pCnt)
                bSel = sal_True;
        }
        break;
        case CONTENT_TYPE_BOOKMARK  :
        case CONTENT_TYPE_BOOKMARK:
        {
            pActiveShell->GotoBookmark(pCnt->GetName());
            pActiveShell->GotoMark(pCnt->GetName());
        }
        break;
        case CONTENT_TYPE_REGION    :
diff --git a/sw/source/ui/utlui/makefile.mk b/sw/source/ui/utlui/makefile.mk
index 5bf6995..9620f28 100644
--- a/sw/source/ui/utlui/makefile.mk
+++ b/sw/source/ui/utlui/makefile.mk
@@ -54,17 +54,17 @@ SRC1FILES =  \
                utlui.src

EXCEPTIONSFILES= \
        $(SLO)$/unotools.obj	\
        $(SLO)$/bookctrl.obj \
        $(SLO)$/navipi.obj \
        $(SLO)$/unotools.obj    \
        $(SLO)$/swrenamexnameddlg.obj

SLOFILES =  $(EXCEPTIONSFILES) \
        $(SLO)$/bookctrl.obj \
        $(SLO)$/condedit.obj \
        $(SLO)$/content.obj \
        $(SLO)$/gloslst.obj \
        $(SLO)$/glbltree.obj \
        $(SLO)$/initui.obj \
        $(SLO)$/navipi.obj \
        $(SLO)$/navicfg.obj \
        $(SLO)$/numfmtlb.obj \
        $(SLO)$/prcntfld.obj \
diff --git a/sw/source/ui/utlui/navipi.cxx b/sw/source/ui/utlui/navipi.cxx
index 7955550..eb3500e 100644
--- a/sw/source/ui/utlui/navipi.cxx
+++ b/sw/source/ui/utlui/navipi.cxx
@@ -60,7 +60,7 @@
#include <docsh.hxx>
#endif
#include <actctrl.hxx>
#include <bookmrk.hxx>
#include <IMark.hxx>
#include <navipi.hxx>
#include <content.hxx>
#include <workctrl.hxx>
@@ -86,8 +86,6 @@
#include <unomid.h>


static const sal_Unicode cPrefix = '_';

#define PAGE_CHANGE_TIMEOUT 1000 //Timeout fuer Seitenwechsel

#define JUMP_TYPE_TBL 0
@@ -157,16 +155,6 @@ void SwNavigationPI::MoveOutline(USHORT nSource, USHORT nTarget,
    }

}
/*------------------------------------------------------------------------
 Beschreibung:  Erzeugen des automatischen Namens des unbenannten Merkers
------------------------------------------------------------------------*/

inline String &MakeAutoName(String &rToChange, USHORT i)
{
    rToChange = cPrefix;
    rToChange += String::CreateFromInt32( i );
    return rToChange;
}


/*------------------------------------------------------------------------
@@ -606,40 +594,30 @@ BOOL SwNavigationPI::Close()
void SwNavigationPI::MakeMark()
{
    SwView *pView = GetCreateView();
    if (!pView)
        return;
    if (!pView) return;
    SwWrtShell &rSh = pView->GetWrtShell();
    IDocumentMarkAccess* const pMarkAccess = rSh.getIDocumentMarkAccess();

    const USHORT nBookCnt = rSh.GetBookmarkCnt();
    USHORT nMarkCount = 0;
    USHORT nFirstFound = MAX_MARKS;
    for (USHORT nCount = 0; nCount < nBookCnt; ++nCount)
    {
        SwBookmark& rBkmk = rSh.GetBookmark( nCount );
        if( rBkmk.IsMark() )
        {
            String aBookmark( rBkmk.GetName() );
            aBookmark.Erase(0, 1);
            nFirstFound = Min(nFirstFound, (USHORT)aBookmark.ToInt32());
            ++nMarkCount;
        }
    }
        // maximale Anzahl Bookmarks vergeben
    if (nAutoMarkIdx == MAX_MARKS)
        nAutoMarkIdx = 1;
        // erster freier neu vergeben
    else if (nFirstFound != MAX_MARKS)
        nAutoMarkIdx = Max(USHORT(1), USHORT(nFirstFound - 1));
    else
        ++nAutoMarkIdx;
    // collect and sort navigator reminder names
    ::std::vector< ::rtl::OUString > vNavMarkNames;
    for(IDocumentMarkAccess::const_iterator_t ppMark = pMarkAccess->getMarksBegin();
        ppMark != pMarkAccess->getMarksEnd();
        ppMark++)
        if( IDocumentMarkAccess::GetType(**ppMark) == IDocumentMarkAccess::NAVIGATOR_REMINDER )
            vNavMarkNames.push_back(ppMark->get()->GetName());
    ::std::sort(vNavMarkNames.begin(), vNavMarkNames.end());

    String aMark;
    MakeAutoName(aMark,nAutoMarkIdx);
    if (nMarkCount >= MAX_MARKS)
        rSh.DelBookmark( aMark );
    // we are maxed out and delete one
    // nAutoMarkIdx rotates through the available MarkNames
    // this assumes that IDocumentMarkAccess generates Names in ascending order
    if(vNavMarkNames.size() == MAX_MARKS)
        pMarkAccess->deleteMark(pMarkAccess->findMark(vNavMarkNames[nAutoMarkIdx]));

    rSh.SetBookmark(KeyCode(), aMark, aEmptyStr, IDocumentBookmarkAccess::MARK);
    SwView::SetActMark( static_cast<BYTE>(nAutoMarkIdx) );
    rSh.SetBookmark(KeyCode(), ::rtl::OUString(), ::rtl::OUString(), IDocumentMarkAccess::NAVIGATOR_REMINDER);
    SwView::SetActMark( nAutoMarkIdx );

    if(++nAutoMarkIdx == MAX_MARKS)
        nAutoMarkIdx = 0;
}

/*------------------------------------------------------------------------
@@ -806,8 +784,7 @@ SwNavigationPI::SwNavigationPI( SfxBindings* _pBindings,
    rBindings(*_pBindings),

    nWishWidth(0),
    nActMark(0),
    nAutoMarkIdx(0),
    nAutoMarkIdx(1),
    nRegionMode(REGION_MODE_NONE),

    bSmallMode(FALSE),
diff --git a/sw/source/ui/wrtsh/move.cxx b/sw/source/ui/wrtsh/move.cxx
index 65ea252..e250b35 100644
--- a/sw/source/ui/wrtsh/move.cxx
+++ b/sw/source/ui/wrtsh/move.cxx
@@ -670,10 +670,10 @@ BOOL SwWrtShell::GotoPage(USHORT nPage, BOOL bRecord)



BOOL SwWrtShell::GotoBookmark( USHORT nPos, BOOL bSelect, BOOL bStart )
BOOL SwWrtShell::GotoMark( const ::sw::mark::IMark* const pMark, BOOL bSelect, BOOL bStart )
{
    ShellMoveCrsr aTmp( this, bSelect );
    return SwCrsrShell::GotoBookmark( nPos, bStart );
    return SwCrsrShell::GotoMark( pMark, bStart );
}


diff --git a/sw/source/ui/wrtsh/wrtsh3.cxx b/sw/source/ui/wrtsh/wrtsh3.cxx
index ba85c0c..f7d2cdc 100644
--- a/sw/source/ui/wrtsh/wrtsh3.cxx
+++ b/sw/source/ui/wrtsh/wrtsh3.cxx
@@ -48,7 +48,7 @@
#include <tools/urlobj.hxx>
#include "wrtsh.hxx"
#include "view.hxx"
#include "bookmrk.hxx"
#include "IMark.hxx"
#include "doc.hxx"
#include "wrtsh.hrc"

@@ -60,8 +60,7 @@ using ::rtl::OUString;

extern sal_Bool bNoInterrupt;       // in mainwn.cxx

BOOL SwWrtShell::MoveBookMark(  BookMarkMove eFuncId,
                                    sal_uInt16 nPos )
BOOL SwWrtShell::MoveBookMark( BookMarkMove eFuncId, const ::sw::mark::IMark* const pMark)
{
//JP 08.03.96: die Wizards brauchen die Selektion !!
//  EndSelect();
@@ -70,7 +69,7 @@ BOOL SwWrtShell::MoveBookMark(  BookMarkMove eFuncId,
    BOOL bRet = sal_True;
    switch(eFuncId)
    {
        case BOOKMARK_INDEX:bRet = SwCrsrShell::GotoBookmark( nPos );break;
        case BOOKMARK_INDEX:bRet = SwCrsrShell::GotoMark( pMark );break;
        case BOOKMARK_NEXT: bRet = SwCrsrShell::GoNextBookmark();break;
        case BOOKMARK_PREV: bRet = SwCrsrShell::GoPrevBookmark();break;
        default:;//prevent warning
@@ -109,11 +108,10 @@ BOOL SwWrtShell::GotoField( const SwFmtFld& rFld )
    return bRet;
}

bool SwWrtShell::GotoFieldBookmark(SwBookmark *pBkmk)
bool SwWrtShell::GotoFieldmark(::sw::mark::IFieldmark const * const pMark)
{
   (this->*fnKillSel)( 0, sal_False );

    bool bRet = SwCrsrShell::GotoFieldBookmark(pBkmk);
    (this->*fnKillSel)( 0, sal_False );
    bool bRet = SwCrsrShell::GotoFieldmark(pMark);
    if( bRet && IsSelFrmMode() )
    {
        UnSelectFrm();
@@ -148,19 +146,17 @@ void SwWrtShell::DrawSelChanged( )
    bNoInterrupt = bOldVal;
}

BOOL SwWrtShell::GotoBookmark( const String& rName )
BOOL SwWrtShell::GotoMark( const ::rtl::OUString& rName )
{
    sal_uInt16 nPos = FindBookmark( rName );
    if( USHRT_MAX == nPos )
        return sal_False;

    return MoveBookMark( BOOKMARK_INDEX, nPos );
    IDocumentMarkAccess::const_iterator_t ppMark = getIDocumentMarkAccess()->findMark( rName );
    if(ppMark == getIDocumentMarkAccess()->getMarksEnd()) return false;
    return MoveBookMark( BOOKMARK_INDEX, ppMark->get() );
}


BOOL SwWrtShell::GotoBookmark( sal_uInt16 nPos )
BOOL SwWrtShell::GotoMark( const ::sw::mark::IMark* const pMark )
{
    return MoveBookMark( BOOKMARK_INDEX, nPos );
    return MoveBookMark( BOOKMARK_INDEX, pMark );
}