Index: _source/plugins/list/plugin.js
===================================================================
--- _source/plugins/list/plugin.js	(revision 3477)
+++ _source/plugins/list/plugin.js	Mon Jun 01 11:40:36 CST 2009
@@ -377,7 +377,14 @@
 							( editor.config.enterMode == CKEDITOR.ENTER_DIV ? 'div' : 'br' ) );
 					paragraph.appendTo( body );
 					ranges = [ new CKEDITOR.dom.range( doc ) ];
+					// IE exception on inserting anything when anchor inside <br>.
+					if ( paragraph.is( 'br' ) )
+					{
+						ranges[ 0 ].setStartBefore( paragraph );
+						ranges[ 0 ].setEndAfter( paragraph );
+					}
+					else
-					ranges[0].selectNodeContents( paragraph );
+						ranges[ 0 ].selectNodeContents( paragraph );
 					selection.selectRanges( ranges );
 				}
 			}
Index: _source/core/dom/range.js
===================================================================
--- _source/core/dom/range.js	(revision 3549)
+++ _source/core/dom/range.js	Mon Jun 01 12:00:54 CST 2009
@@ -265,15 +265,19 @@
 	// check(Start|End)OfBlock.
 	function getCheckStartEndBlockEvalFunction( isStart )
 	{
-		var hadBr = false;
+		var hadBr = false, bookmarkEvaluator = CKEDITOR.dom.walker.bookmark( true );
 		return function( node )
 		{
+			// First ignore bookmark nodes.
+			if ( bookmarkEvaluator( node ) )
+				return true;
+
 			if ( node.type == CKEDITOR.NODE_TEXT )
 			{
 				// If there's any visible text, then we're not at the start.
 				if ( CKEDITOR.tools.trim( node.getText() ).length )
 					return false;
-			}
+				}
 			else
 			{
 				// If there are non-empty inline elements (e.g. <img />), then we're not
@@ -1119,39 +1123,79 @@
 				case CKEDITOR.ENLARGE_LIST_ITEM_CONTENTS:
 
 					// Enlarging the start boundary.
-					var walkerRange = new CKEDITOR.dom.range( this.document );
-					walkerRange.setStartAt(
-						this.document.getBody(), CKEDITOR.POSITION_AFTER_START );
+					var walkerRange = new CKEDITOR.dom.range( this.document ),
+							body = this.document.getBody();
+					walkerRange.setStartAt( body, CKEDITOR.POSITION_AFTER_START );
 					walkerRange.setEnd( this.startContainer, this.startOffset );
 
 					var walker = new CKEDITOR.dom.walker( walkerRange ),
-
-						guard = CKEDITOR.dom.walker.blockBoundary(
+					    blockBoundary,  // The node on which the enlarging should stop.
+						tailBr, //
+					    defaultGuard = CKEDITOR.dom.walker.blockBoundary(
 								( unit == CKEDITOR.ENLARGE_LIST_ITEM_CONTENTS ) ? { br : 1 } : null ),
-						tailBr,
-						listGuard = function( node )
+						// Record the encountered 'blockBoundary' for later use.
+						boundaryGuard = function( node )
 						{
-							var result = guard( node );
-							if ( !result && node.is && node.is( 'br' ) )
+							var retval = defaultGuard( node );
+							if ( !retval )
+								blockBoundary = node;
+							return retval;
+						},
+						// Record the encounted 'tailBr' for later use.
+						tailBrGuard = function( node )
+						{
+							var retval = boundaryGuard( node );
+							if ( !retval && node.is && node.is( 'br' ) )
 								tailBr = node;
-							return result;
-						};
+							return retval;
+						},
+						guard = ( unit == CKEDITOR.ENLARGE_LIST_ITEM_CONTENTS ) ?
+						tailBrGuard : boundaryGuard;
+						
 					walker.guard = guard;
 
+
 					if ( ( enlargeable = walker.lastBackward() ) )
+					{
+						// It's the body which stop the enlaring if no block boundary found.
+						blockBoundary = blockBoundary || body;
+
+						// Start the range at different position by comparing
+						// the document position of it with 'enlargeable' node.
+						var position = blockBoundary.getPosition( enlargeable );
 						this.setStartAt(
-							enlargeable, CKEDITOR.POSITION_BEFORE_START );
+								blockBoundary,
+								( position | CKEDITOR.POSITION_CONTAINS | CKEDITOR.POSITION_PRECEDING )
+										== CKEDITOR.POSITION_CONTAINS + CKEDITOR.POSITION_PRECEDING ?
+								CKEDITOR.POSITION_AFTER_START :
+								CKEDITOR.POSITION_AFTER_END );
+					}
 
 					// Enlarging the end boundary.
 					walkerRange = this.clone();
 					walkerRange.collapse();
-					walkerRange.setEndAt(
-						this.document.getBody(), CKEDITOR.POSITION_BEFORE_END );
+					walkerRange.setEndAt( body, CKEDITOR.POSITION_BEFORE_END );
 					walker = new CKEDITOR.dom.walker( walkerRange );
-					walker.guard = ( unit == CKEDITOR.ENLARGE_LIST_ITEM_CONTENTS ) ?
-						 listGuard : guard;
+					walker.guard = guard;
+					blockBoundary = null;
+					// End the range right before the block boundary node.
+					;
 					if ( ( enlargeable = walker.lastForward() ) )
-							this.setEndAfter( enlargeable );
+					{
+						// It's the body which stop the enlaring if no block boundary found.
+						blockBoundary = blockBoundary || body;
+
+						// Start the range at different position by comparing
+						// the document position of it with 'enlargeable' node.
+						var position = blockBoundary.getPosition( enlargeable );
+						debugger;
+						this.setEndAt(
+								blockBoundary,
+								( position | CKEDITOR.POSITION_CONTAINS | CKEDITOR.POSITION_PRECEDING )
+										== CKEDITOR.POSITION_CONTAINS + CKEDITOR.POSITION_PRECEDING ?
+								CKEDITOR.POSITION_BEFORE_END :
+								CKEDITOR.POSITION_BEFORE_START );
+					}
 					// We must include the <br> at the end of range if there's
 					// one and we're expanding list item contents
 					if ( tailBr )
Index: _source/plugins/domiterator/plugin.js
===================================================================
--- _source/plugins/domiterator/plugin.js	(revision 3538)
+++ _source/plugins/domiterator/plugin.js	Mon Jun 01 11:52:22 CST 2009
@@ -12,38 +12,6 @@
 (function()
 {
 
-	function isBookmarkNode( node )
-	{
-		return ( node && node.getName
-					&& node.getName() == 'span'
-					&& node.hasAttribute( '_fck_bookmark' ) )
-				||
-				( node && !node.getName && isBookmarkNode( node.getParent()) );
-	}
-
-	function ignoreBookmarkEvaluator( node )
-	{
-		return !isBookmarkNode( node );
-	}
-
-
-	/**
-	 * Find next source order node, ignore bookmark nodes and stop at the specified end node.
-	 * @param {Object} currentNode
-	 * @param {Object} endNode
-	 */
-	function getNextSourceNode( currentNode, endNode, startFromSibling )
-	{
-		var next = currentNode;
-		do
-		{
-			next = next.getNextSourceNode(
-				startFromSibling, null, endNode );
-		}
-		while( isBookmarkNode( next ) )
-		return next;
-	}
-
 	var iterator = function( range )
 	{
 		if ( arguments.length < 1 )
@@ -79,15 +47,16 @@
 				range = this.range.clone();
 				range.enlarge( this.forceBrBreak ? CKEDITOR.ENLARGE_LIST_ITEM_CONTENTS : CKEDITOR.ENLARGE_BLOCK_CONTENTS );
 
-				var walker = new CKEDITOR.dom.walker( range );
-				walker.evaluator = ignoreBookmarkEvaluator;
+				var walker = new CKEDITOR.dom.walker( range ),
+					ignoreBookmarkTextEvaluator = CKEDITOR.dom.walker.bookmark( true, true );
+				// Avoid anchor inside bookmark inner text.
+				walker.evaluator = ignoreBookmarkTextEvaluator;
 				this._.nextNode = walker.next();
-
 				// TODO: It's better to have walker.reset() used here.
 				walker = new CKEDITOR.dom.walker( range );
-				walker.evaluator = ignoreBookmarkEvaluator;
+				walker.evaluator = ignoreBookmarkTextEvaluator;
 				var lastNode = walker.previous();
-				this._.lastNode = getNextSourceNode( lastNode, null, true );
+				this._.lastNode = lastNode.getNextSourceNode( true );
 				// Probably the document end is reached, we need a marker node.
 				if ( !this._.lastNode )
 				{
@@ -102,7 +71,6 @@
 				lastNode = this._.lastNode;
 
 			this._.nextNode = null;
-
 			while ( currentNode )
 			{
 				// closeRange indicates that a paragraph boundary has been found,
@@ -230,7 +198,7 @@
 				if ( isLast )
 					break;
 
-				currentNode = getNextSourceNode( currentNode, lastNode, continueFromSibling );
+				currentNode = currentNode.getNextSourceNode( continueFromSibling, null, lastNode );
 			}
 
 			// Now, based on the processed range, look for (or create) the block to be returned.
@@ -301,7 +269,7 @@
 					// lists) or the next sibling <li>.
 
 					this._.nextNode = ( block.equals( lastNode ) ? null :
-						getNextSourceNode( range.getBoundaryNodes().endNode, lastNode, true ) );
+						range.getBoundaryNodes().endNode.getNextSourceNode( true, null, lastNode ) );
 				}
 			}
 
@@ -334,7 +302,7 @@
 			if ( !this._.nextNode )
 			{
 				this._.nextNode = ( isLast || block.equals( lastNode ) ) ? null :
-					getNextSourceNode( block, lastNode, true );
+					block.getNextSourceNode( true, null, lastNode );
 			}
 
 			return block;
Index: _source/core/dom/walker.js
===================================================================
--- _source/core/dom/walker.js	(revision 3477)
+++ _source/core/dom/walker.js	Mon Jun 01 11:40:36 CST 2009
@@ -354,4 +354,43 @@
 			return this.blockBoundary( { br : 1 } );
 	};
 
+	/**
+	 * Whether the node is a bookmark node's inner text node.
+	 */
+	CKEDITOR.dom.walker.bookmarkContents = function( node )
+	{
+	},
+
+	/**
+	 * Whether the to-be-evaluated node is a bookmark node OR bookmark node
+	 * inner contents.
+	 * @param {Boolean} contentOnly Whether only test againt the text content of
+	 * bookmark node instead of the element itself(default).
+	 * @param {Boolean} isReject Whether should return 'false' for the bookmark
+	 * node instead of 'true'(default).
+	 */
+	CKEDITOR.dom.walker.bookmark = function( contentOnly, isReject )
+	{
+		function isBookmarkNode( node )
+		{
+			return ( node && node.getName
+					&& node.getName() == 'span'
+					&& node.hasAttribute('_fck_bookmark') );
+		}
+
+		return function( node )
+		{
+			var retval;
+			if ( contentOnly )
+			{
+				var parent;
+				retval = ( node && !node.getName && ( parent = node.getParent() )
+							&& isBookmarkNode( parent ) );
+			}
+			else
+				retval = isBookmarkNode( node );
+			return isReject ? !retval : retval;
+		};
+	}
+
 })();
