Index: /CKEditor/trunk/_source/core/dom/range.js
===================================================================
--- /CKEditor/trunk/_source/core/dom/range.js	(revision 3606)
+++ /CKEditor/trunk/_source/core/dom/range.js	(revision 3607)
@@ -266,7 +266,11 @@
 	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 )
 			{
@@ -274,5 +278,5 @@
 				if ( CKEDITOR.tools.trim( node.getText() ).length )
 					return false;
-			}
+				}
 			else
 			{
@@ -1120,37 +1124,73 @@
 
 					// 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;
 						};
-					walker.guard = guard;
+
+					walker.guard = boundaryGuard;
+
 
 					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.
 						this.setStartAt(
-							enlargeable, CKEDITOR.POSITION_BEFORE_START );
+								blockBoundary,
+								blockBoundary.contains( enlargeable ) ?
+									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 );
+
+					// tailBrGuard only used for on range end.
 					walker.guard = ( unit == CKEDITOR.ENLARGE_LIST_ITEM_CONTENTS ) ?
-						 listGuard : guard;
+						tailBrGuard : boundaryGuard;
+					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.
+						this.setEndAt(
+								blockBoundary,
+								blockBoundary.contains( enlargeable ) ?
+									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
Index: /CKEditor/trunk/_source/core/dom/walker.js
===================================================================
--- /CKEditor/trunk/_source/core/dom/walker.js	(revision 3606)
+++ /CKEditor/trunk/_source/core/dom/walker.js	(revision 3607)
@@ -354,4 +354,39 @@
 			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, parent;
+			// Is bookmark inner text node?
+			retval = ( node && !node.getName && ( parent = node.getParent() )
+						&& isBookmarkNode( parent ) );
+			// Is bookmark node?
+			retval = contentOnly ? retval : retval || isBookmarkNode( node );
+			return isReject ? !retval : !!retval;
+		};
+	};
 
 })();
Index: /CKEditor/trunk/_source/plugins/domiterator/plugin.js
===================================================================
--- /CKEditor/trunk/_source/plugins/domiterator/plugin.js	(revision 3606)
+++ /CKEditor/trunk/_source/plugins/domiterator/plugin.js	(revision 3607)
@@ -12,36 +12,4 @@
 (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 )
@@ -80,13 +48,14 @@
 				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 )
@@ -103,5 +72,4 @@
 
 			this._.nextNode = null;
-
 			while ( currentNode )
 			{
@@ -231,5 +199,5 @@
 					break;
 
-				currentNode = getNextSourceNode( currentNode, lastNode, continueFromSibling );
+				currentNode = currentNode.getNextSourceNode( continueFromSibling, null, lastNode );
 			}
 
@@ -302,5 +270,5 @@
 
 					this._.nextNode = ( block.equals( lastNode ) ? null :
-						getNextSourceNode( range.getBoundaryNodes().endNode, lastNode, true ) );
+						range.getBoundaryNodes().endNode.getNextSourceNode( true, null, lastNode ) );
 				}
 			}
@@ -335,5 +303,5 @@
 			{
 				this._.nextNode = ( isLast || block.equals( lastNode ) ) ? null :
-					getNextSourceNode( block, lastNode, true );
+					block.getNextSourceNode( true, null, lastNode );
 			}
 
Index: /CKEditor/trunk/_source/plugins/list/plugin.js
===================================================================
--- /CKEditor/trunk/_source/plugins/list/plugin.js	(revision 3606)
+++ /CKEditor/trunk/_source/plugins/list/plugin.js	(revision 3607)
@@ -378,5 +378,12 @@
 					paragraph.appendTo( body );
 					ranges = [ new CKEDITOR.dom.range( doc ) ];
-					ranges[0].selectNodeContents( paragraph );
+					// 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 );
 					selection.selectRanges( ranges );
 				}
