Index: /CKEditor/branches/prototype/_source/core/dom/range.js
===================================================================
--- /CKEditor/branches/prototype/_source/core/dom/range.js	(revision 2807)
+++ /CKEditor/branches/prototype/_source/core/dom/range.js	(revision 2808)
@@ -984,4 +984,5 @@
 				case CKEDITOR.ENLARGE_BLOCK_CONTENTS:
 				case CKEDITOR.ENLARGE_LIST_ITEM_CONTENTS:
+					// DFS backward to get the block/list item boundary at or before the start.
 					var boundaryNodes = getBoundaryNodes.apply( this ),
 						startNode = boundaryNodes.startNode,
@@ -991,9 +992,10 @@
 							CKEDITOR.domWalker.listItemBoundary() ),
 						walker = new CKEDITOR.domWalker( startNode ),
-						data = walker.reverse( guardFunction),
+						data = walker.reverse( guardFunction ),
 						boundaryEvent = data.events.shift();
 
 					this.setStartBefore( boundaryEvent.from );
 
+					// DFS forward to get the block/list item boundary at or before the end.
 					walker.setNode( endNode );
 					data = walker.forward( guardFunction );
@@ -1188,20 +1190,74 @@
 				endPath = new CKEDITOR.dom.elementPath( this.endContainer ),
 				startBlockLimit = startPath.blockLimit,
-				endBlockLimit = endPath.blockLimit;
-
-			if ( startBlockLimit != endBlockLimit )
+				endBlockLimit = endPath.blockLimit,
+				startBlock = startPath.block,
+				endBlock = endPath.block,
+				elementPath = null;
+
+			if ( !startBlockLimit.equals( endBlockLimit ) )
 				return null;
 
+			// Get or fix current blocks.
 			if ( blockTag != 'br' )
 			{
-				if ( !startPath.block )
-				{
-					this.fixBlock( true, blockTag );
-					endPath = new CKEDITOR.dom.elementPath( this.endContainer );
-				}
-
-				if ( !endPath.block )
-					this.fixBlock( false, blockTag );
-			}
+				if ( !startBlock )
+				{
+					startBlock = this.fixBlock( true, blockTag );
+					endBlock = new CKEDITOR.dom.elementPath( this.endContainer );
+				}
+
+				if ( !endBlock )
+					endBlock = this.fixBlock( false, blockTag );
+			}
+
+			// Get the range position.
+			var isStartOfBlock = startBlock && this.checkStartOfBlock(),
+				isEndOfBlock = endBlock && this.checkEndOfBlock();
+
+			// Delete the current contents.
+			// TODO: Why is 2.x doing CheckIsEmpty()?
+			this.deleteContents();
+
+			if ( startBlock && startBlock.equals( endBlock ) )
+			{
+				if ( isEndOfBlock )
+				{
+					elementPath = new CKEDITOR.dom.elementPath( this.startContainer );
+					this.moveToPosition( endBlock, CKEDITOR.POSITION_AFTER_END );
+					endBlock = null;
+				}
+				else if ( isStartOfBlock )
+				{
+					elementPath = new CKEDITOR.dom.elementPath( this.startContainer );
+					this.moveToPosition( startBlock, CKEDITOR.POSITION_BEFORE_START );
+					startBlock = null;
+				}
+				else
+				{
+					// Extract the contents of the block from the selection point to the end
+					// of its contents.
+					this.setEndAt( startBlock, CKEDITOR.POSITION_BEFORE_END );
+					var documentFragment = this.extractContents();
+
+					// Duplicate the block element after it.
+					endBlock = startBlock.clone( false );
+					endBlock.removeAttribute( 'id' );
+
+					// Place the extracted contents into the duplicated block.
+					documentFragment.appendTo( endBlock );
+					endBlock.insertAfter( startBlock );
+					this.moveToPosition( startBlock, CKEDITOR.POSITION_AFTER_END );
+
+					// TODO: Append bogus br to startBlock for Gecko
+				}
+			}
+
+			return {
+				previousBlock : startBlock,
+				nextBlock : endBlock,
+				wasStartOfBlock : isStartOfBlock,
+				wasEndOfBlock : isEndOfBlock,
+				elementPath : elementPath 
+			};
 		},
 
