Index: /FCKeditor/trunk/_test/automated/tests/fckdomrange.html
===================================================================
--- /FCKeditor/trunk/_test/automated/tests/fckdomrange.html	(revision 76)
+++ /FCKeditor/trunk/_test/automated/tests/fckdomrange.html	(revision 77)
@@ -329,4 +329,13 @@
 }
 
+function test_CheckIsEmpty_5()
+{
+	var range = new FCKDomRange( window ) ;
+	range.MoveToNodeContents( document.getElementById('_Strong').firstChild ) ;
+	range.SetEnd( document.getElementById('_Strong'), 2 ) ;
+
+	assertFalse( range.CheckIsEmpty() ) ;
+}
+
 function test_CheckStartOfBlock_1()
 {
@@ -364,5 +373,5 @@
 {
 	var range = new FCKDomRange( window ) ;
-	range.SetStart( document.getElementById('_P').lastChild, 2 ) ;
+	range.SetStart( document.getElementById('_P'), 2 ) ;
 
 	assertTrue( range.CheckEndOfBlock() ) ;
@@ -525,5 +534,5 @@
 //window.onload = function()
 //{
-//	test_MoveToBookmark() ;
+//	test_CheckIsEmpty_5() ;
 //}
 
Index: /FCKeditor/trunk/_test/manual/fckenterkey/test1.html
===================================================================
--- /FCKeditor/trunk/_test/manual/fckenterkey/test1.html	(revision 76)
+++ /FCKeditor/trunk/_test/manual/fckenterkey/test1.html	(revision 77)
@@ -14,5 +14,5 @@
 	<script type="text/javascript">
 
-FCKConfig.Debug = true ;
+FCKConfig.Debug = false ;
 FCKConfig.BasePath = '../../../editor/' ;
 
Index: /FCKeditor/trunk/editor/_packager.xml
===================================================================
--- /FCKeditor/trunk/editor/_packager.xml	(revision 76)
+++ /FCKeditor/trunk/editor/_packager.xml	(revision 77)
@@ -59,4 +59,5 @@
 		<File path="editor/_source/classes/fckdomrange_ie.js" />
 		<File path="editor/_source/classes/fckdocumentfragment_ie.js" />
+		<File path="editor/_source/classes/fckw3crange.js" />
 		<File path="editor/_source/classes/fckenterkey.js" />
 
@@ -142,4 +143,5 @@
 		<File path="editor/_source/classes/fckdomrange_gecko.js" />
 		<File path="editor/_source/classes/fckdocumentfragment_gecko.js" />
+		<File path="editor/_source/classes/fckw3crange.js" />
 		<File path="editor/_source/classes/fckenterkey.js" />
 
Index: /FCKeditor/trunk/editor/_source/classes/fckdocumentfragment_gecko.js
===================================================================
--- /FCKeditor/trunk/editor/_source/classes/fckdocumentfragment_gecko.js	(revision 76)
+++ /FCKeditor/trunk/editor/_source/classes/fckdocumentfragment_gecko.js	(revision 77)
@@ -23,4 +23,9 @@
 	{
 		targetNode.appendChild( this.RootNode ) ;
+	},
+	
+	InsertAfterNode : function( existingNode )
+	{
+		FCKDomTools.InsertAfterNode( existingNode, this.RootNode ) ;
 	}
 }
Index: /FCKeditor/trunk/editor/_source/classes/fckdocumentfragment_ie.js
===================================================================
--- /FCKeditor/trunk/editor/_source/classes/fckdocumentfragment_ie.js	(revision 76)
+++ /FCKeditor/trunk/editor/_source/classes/fckdocumentfragment_ie.js	(revision 77)
@@ -17,13 +17,27 @@
 
 // Append the contents of this Document Fragment to another node.
-FCKDocumentFragment.prototype.AppendTo = function( targetNode )
+FCKDocumentFragment.prototype = 
 {
-	FCKDomTools.MoveChildren( this.RootNode, targetNode ) ;
+	TypeName : 'FCKDocumentFragment',		// @Packager.RemoveLine
+
+	AppendTo : function( targetNode )
+	{
+		FCKDomTools.MoveChildren( this.RootNode, targetNode ) ;
+	},
+
+	AppendHtml : function( html )
+	{
+		var eTmpDiv = this._Document.createElement( 'div' ) ;
+		eTmpDiv.innerHTML = html ;
+		FCKDomTools.MoveChildren( eTmpDiv, this.RootNode ) ;
+	},
+
+	InsertAfterNode : function( existingNode )
+	{
+		var eRoot = this.RootNode ;
+		var eLast ;
+		
+		while( ( eLast = eRoot.lastChild ) )
+			FCKDomTools.InsertAfterNode( existingNode, eRoot.removeChild( eLast ) ) ;
+	}
 }
-
-FCKDocumentFragment.prototype.AppendHtml = function( html )
-{
-	var eTmpDiv = this._Document.createElement( 'div' ) ;
-	eTmpDiv.innerHTML = html ;
-	FCKDomTools.MoveChildren( eTmpDiv, this.RootNode ) ;
-}
Index: /FCKeditor/trunk/editor/_source/classes/fckdomrange.js
===================================================================
--- /FCKeditor/trunk/editor/_source/classes/fckdomrange.js	(revision 76)
+++ /FCKeditor/trunk/editor/_source/classes/fckdomrange.js	(revision 77)
@@ -108,5 +108,5 @@
 	},
 
-	CheckIsEmpty : function()
+	CheckIsEmpty : function( ignoreEndBRs )
 	{
 		if ( this.CheckIsCollapsed() )
@@ -116,7 +116,8 @@
 		var eToolDiv = this.Window.document.createElement( 'div' ) ;
 		this._Range.cloneContents().AppendTo( eToolDiv ) ;
-
-		// There must not be &nbsp; in the range, only "pure" spaces.
-		return (/^\s*$/).test( eToolDiv.innerHTML ) ;
+		
+		FCKDomTools.TrimNode( eToolDiv, ignoreEndBRs ) ;
+		
+		return ( eToolDiv.innerHTML.length == 0 ) ;
 	},
 
@@ -150,5 +151,5 @@
 		oTestRange.SetEnd( oTestRange.EndBlock || oTestRange.EndBlockLimit, 2 ) ;
 
-		var bIsEndOfBlock = oTestRange.CheckIsEmpty() ;
+		var bIsEndOfBlock = oTestRange.CheckIsEmpty( true ) ;
 
 		oTestRange.Release() ;
Index: /FCKeditor/trunk/editor/_source/classes/fckdomrange_ie.js
===================================================================
--- /FCKeditor/trunk/editor/_source/classes/fckdomrange_ie.js	(revision 76)
+++ /FCKeditor/trunk/editor/_source/classes/fckdomrange_ie.js	(revision 77)
@@ -36,7 +36,11 @@
 	if ( this._Range )
 	{
+		var bIsCollapsed = this.CheckIsCollapsed() ;
+		
 		// Create marker tags for the start and end boundaries.
 		var eStartMarker	= this._GetRangeMarkerTag( true ) ;
-		var eEndMarker		= this._GetRangeMarkerTag( false ) ;
+		
+		if ( !bIsCollapsed )
+			var eEndMarker	= this._GetRangeMarkerTag( false ) ;
 
 		// Create the main range which will be used for the selection.
@@ -45,22 +49,38 @@
 		// Position the range at the start boundary.
 		oIERange.moveToElementText( eStartMarker ) ;
+		oIERange.moveStart( 'character', 1 ) ;
 
-		// Create a tool range for the end.
-		var oIERangeEnd = this.Window.document.body.createTextRange() ;
+		if ( !bIsCollapsed )
+		{
+			// Create a tool range for the end.
+			var oIERangeEnd = this.Window.document.body.createTextRange() ;
 
-		// Position the tool range at the end.
-		oIERangeEnd.moveToElementText( eEndMarker ) ;
-		
-		// Move the end boundary of the main range to match the tool range.
-		oIERange.setEndPoint( 'EndToEnd', oIERangeEnd ) ;
-		
-		// Select the range.
-		oIERange.select() ;
+			// Position the tool range at the end.
+			oIERangeEnd.moveToElementText( eEndMarker ) ;
+			
+			// Move the end boundary of the main range to match the tool range.
+			oIERange.setEndPoint( 'EndToEnd', oIERangeEnd ) ;
+			oIERange.moveEnd( 'character', -1 ) ;
+		}
 		
 		// Remove the markers (reset the position, because of the changes in the DOM tree).
 		this._Range.setStartBefore( eStartMarker ) ;
 		eStartMarker.parentNode.removeChild( eStartMarker ) ;
-		this._Range.setEndBefore( eEndMarker ) ;
-		eEndMarker.parentNode.removeChild( eEndMarker ) ;
+		
+		if ( bIsCollapsed )
+		{
+			// The following trick is needed so IE makes collapsed selections
+			// inside empty blocks visible (expands the block).
+			oIERange.pasteHTML('&nbsp;') ;
+			oIERange.moveStart( 'character', -1 ) ;
+			oIERange.select() ;
+			oIERange.pasteHTML('') ;
+		}
+		else
+		{
+			this._Range.setEndBefore( eEndMarker ) ;
+			eEndMarker.parentNode.removeChild( eEndMarker ) ;
+			oIERange.select() ;
+		}
 	}
 }
@@ -92,4 +112,5 @@
 	
 	var eSpan = this.Window.document.createElement( 'span' ) ;
+	eSpan.innerHTML = '&nbsp;' ;
 	oRange.insertNode( eSpan ) ;
 	
Index: /FCKeditor/trunk/editor/_source/classes/fckenterkey.js
===================================================================
--- /FCKeditor/trunk/editor/_source/classes/fckenterkey.js	(revision 76)
+++ /FCKeditor/trunk/editor/_source/classes/fckenterkey.js	(revision 77)
@@ -107,12 +107,29 @@
 	var oRange = new FCKDomRange( this.Window ) ;
 	oRange.MoveToSelection() ;
+	
+	var oStartBlock = oRange.StartBlock ;
+	var oEndBlock = oRange.EndBlock ;
 
 	// The selection boundaries must be in the same "block limit" element
-	if ( oRange.StartBlockLimit == oRange.EndBlockLimit && oRange.StartBlock && oRange.EndBlock )
-	{
-		if ( oRange.StartBlock != oRange.EndBlock )
-		{
-			this.DoEnter() ;
-			oRange.MoveToSelection() ;
+	if ( oRange.StartBlockLimit == oRange.EndBlockLimit && oStartBlock && oEndBlock )
+	{
+		if ( !oRange.CheckIsCollapsed() )
+		{
+			var bEndOfBlock = oRange.CheckEndOfBlock() ;
+			
+			oRange.DeleteContents() ;
+			
+			if ( oStartBlock != oEndBlock )
+			{
+				oRange.SetStart(oEndBlock,1) ;
+				oRange.SetEnd(oEndBlock,1) ;
+				
+//				if ( bEndOfBlock )
+//					oEndBlock.parentNode.removeChild( oEndBlock ) ;
+			}
+		
+			oRange.Select() ;
+			
+			bCustom = ( oStartBlock == oEndBlock ) ;
 		}
 		
@@ -121,8 +138,13 @@
 			var oCurrentBlock = oRange.StartBlock ;
 			
-			var ePrevious = FCKDomTools.GetPreviousSourceElement( oCurrentBlock, true, [ oRange.StartBlockLimit.nodeName ], ['UL','OL'] ) ;
+			var ePrevious = FCKDomTools.GetPreviousSourceElement( oCurrentBlock, true, [ 'BODY', oRange.StartBlockLimit.nodeName ], ['UL','OL'] ) ;
 
 			bCustom = this._ExecuteBackspace( oRange, ePrevious, oCurrentBlock ) ;
-		}	
+		}
+		else if ( FCKBrowserInfo.IsGecko )
+		{
+			// Firefox looses the selection when executing CheckStartOfBlock, so we must reselect.
+			oRange.Select() ;
+		}
 	}
 
@@ -142,5 +164,5 @@
 	}
 
-	if ( previous.nodeName.IEquals( 'LI' ) )
+	if ( previous && previous.nodeName.IEquals( 'LI' ) )
 	{
 		var oNestedList = FCKDomTools.GetLastChild( previous, ['UL','OL'] ) ;
@@ -162,5 +184,5 @@
 		var oCurrentParent = currentBlock.parentNode ;
 
-		if ( previous.nodeName.toUpperCase() == 'TABLE' ) 
+		if ( previous.nodeName.IEquals( 'TABLE', 'HR' ) ) 
 		{
 			FCKDomTools.RemoveNode( previous ) ;
@@ -261,27 +283,19 @@
 			this._FixBlock( oRange, false, blockTag ) ;
 
+		// Get the current blocks.
+		var eStartBlock	= oRange.StartBlock ;
+		var eEndBlock	= oRange.EndBlock ;
+			
+		// Delete the current selection.
+		if ( !oRange.CheckIsEmpty() )
+			oRange.DeleteContents() ;
+
 		// If the selection boundaries are in the same block element
-		if ( oRange.StartBlock == oRange.EndBlock )
-		{
-			// Delete the current selection.
-			if ( !oRange.CheckIsEmpty() )
-			{
-				oRange.DeleteContents() ;
-			
-				// Get the new selection (it is collapsed at this point).
-			//	oRange.MoveToSelection() ;
-			}
-			
+		if ( eStartBlock == eEndBlock )
+		{
 			var eNewBlock ;
-			var bCleanupBlock = false ;
-
-			// Get the current block.
-			var eStartBlock = oRange.StartBlock ;
-			
+
 			var bIsStartOfBlock	= oRange.CheckStartOfBlock() ;
 			var bIsEndOfBlock	= oRange.CheckEndOfBlock() ;
-
-			FCKDebug.Output( 'bIsStartOfBlock: ' + bIsStartOfBlock ) ;
-			FCKDebug.Output( 'bIsEndOfBlock: ' + bIsEndOfBlock ) ;
 
 			if ( bIsStartOfBlock && !bIsEndOfBlock )
@@ -289,11 +303,5 @@
 				eNewBlock = eStartBlock.cloneNode(false) ;
 
-				if ( FCKBrowserInfo.IsIE )
-				{
-					// To make the block visible, we must fill it with a &nbsp; select it, and delete it.
-					eNewBlock.innerHTML = '&nbsp;' ;
-					bCleanupBlock = true ;
-				}
-				else if ( FCKBrowserInfo.IsGeckoLike )
+				if ( FCKBrowserInfo.IsGeckoLike )
 					eNewBlock.innerHTML = GECKO_BOGUS ;
 				
@@ -301,20 +309,16 @@
 				eStartBlock.parentNode.insertBefore( eNewBlock, eStartBlock ) ;
 
-				// This is tricky, but to make the new block visible correctly,
-				// we must place a &nbsp; inside it and then delete it using a selection.
+				// This is tricky, but to make the new block visible correctly
+				// we must select it.
 				if ( FCKBrowserInfo.IsIE )
 				{
 					// Move the selection to the new block.
-					oRange.MoveToElementStart( eNewBlock ) ;
-					
-					oRange.Expand( 'block_contents' ) ;
-
-					oRange.Select() ;				
-					oRange.DeleteContents() ;
-
-					// Move the selection to the new block.
-					oRange.MoveToElementStart( eStartBlock ) ;
-					oRange.Select() ;				
+					oRange.MoveToNodeContents( eNewBlock ) ;
+
+					oRange.Select() ;
 				}
+
+				// Move the selection to the new block.
+				oRange.MoveToElementStart( eStartBlock ) ;
 			}
 			else
@@ -340,11 +344,5 @@
 							eNewBlock = eStartBlock.cloneNode(false) ;
 						
-						if ( FCKBrowserInfo.IsIE )
-						{
-							// To make the block visible, we must fill it with a &nbsp; select it, and delete it.
-							eNewBlock.innerHTML = '&nbsp;' ;
-							bCleanupBlock = true ;
-						}
-						else if ( FCKBrowserInfo.IsGeckoLike )
+						if ( FCKBrowserInfo.IsGeckoLike )
 						{
 							eNewBlock.innerHTML = GECKO_BOGUS ;
@@ -372,20 +370,9 @@
 					// Place the extracted contents in the duplicated block.
 					eDocFrag.AppendTo( eNewBlock ) ;
-					
-					FCKDebug.Output( eNewBlock.innerHTML ) ;
 				}
 
 				if ( eNewBlock )
 				{
-//					// Place the new block after the current block element.
-//					if ( FCKBrowserInfo.IsIE )
-//					{
-//						// You gona think I'm crazy, but in IE we have to do
-//						// this way to make it work properly with LI in some cases.
-//						eStartBlock.parentNode.insertBefore( eNewBlock, eStartBlock ) ;		
-//						eNewBlock.swapNode( eStartBlock	) ;	
-//					}
-//					else
-						FCKDomTools.InsertAfterNode( eStartBlock, eNewBlock ) ;
+					FCKDomTools.InsertAfterNode( eStartBlock, eNewBlock ) ;
 
 					// Move the selection to the new block.
@@ -394,51 +381,14 @@
 					if ( FCKBrowserInfo.IsGecko )
 						eNewBlock.scrollIntoView( false ) ;
-					
-					if ( bCleanupBlock )
-						oRange.Expand( 'block_contents' ) ;
 				}
-
-				oRange.Select() ;
-				
-				if ( bCleanupBlock ) 
-					oRange.DeleteContents() ;
 			}
 		}
 		else
 		{
-			// We must divide the current range in three ranges. One for the start block part, other for the end block part, and another for the in between selection.
-		
-			// Create a clone of the current range for the start block and move the clone end boundary to the end of the start block.
-			var oStartRange = oRange.Clone() ;
-			oStartRange.SetEnd( oRange.StartBlock, 2 ) ;
-			
-			// Create a clone of the current range for the end block and move the clone start boundary to the start of the second block.
-			var oEndRange = oRange.Clone() ;
-			oEndRange.SetStart( oRange.EndBlock, 1 ) ;
-
-			// Move the start of the current range right after the start block.
-			oRange.SetStart( oRange.StartBlock, 4 ) ;
-			
-			// Move the end of the current range right before the end block.
-			oRange.SetEnd( oRange.EndBlock, 3 ) ;
-			
-			// Delete the contents of the three ranges.
-			if ( oStartRange.CheckStartOfBlock() )
-				FCKDomTools.RemoveNode( oStartRange.StartBlock ) ;
-			else
-				oStartRange.DeleteContents() ;
-			oRange.DeleteContents() ;
-			oEndRange.DeleteContents() ;
-			
-			if ( FCKBrowserInfo.IsGeckoLike && oEndRange.StartBlock.tagName.IEquals( 'LI' ) && !FCKListHandler.CheckListHasContents( oEndRange.StartBlock ) )
-				oEndRange.StartBlock.insertBefore( FCKTools.CreateBogusBR( this.Window.document ), oEndRange.StartBlock.firstChild ) ;
-			
 			// Move the selection to the end block.
-			oEndRange.Select() ;
-			
-			// Release the resources for the Start and End ranges.
-			oStartRange.Release() ;
-			oEndRange.Release() ;
-		}
+			oRange.MoveToElementStart( eEndBlock ) ;
+		}
+
+		oRange.Select() ;				
 	}
 	
@@ -474,9 +424,12 @@
 		if ( bIsEndOfBlock && (/^H[1-6]$/).test( sStartBlockTag ) )
 		{
+			FCKDebug.Output( 'BR - Header' ) ;
+
 			// Insert a bogus BR after the current paragraph.
 			FCKDomTools.InsertAfterNode( oRange.StartBlock, FCKTools.CreateBogusBR( this.Window.document ) ) ;
 
 			// The space is required by Gecko only to make the cursor blink.
-			FCKDomTools.InsertAfterNode( oRange.StartBlock, this.Window.document.createTextNode( '' ) ) ;
+			if ( FCKBrowserInfo.IsGecko )
+				FCKDomTools.InsertAfterNode( oRange.StartBlock, this.Window.document.createTextNode( '' ) ) ;
 
 			// IE and Gecko have different behaviors regarding the position.
@@ -485,29 +438,33 @@
 		else
 		{
-			// Note that DomRange.InsertNode() will always add at the start boundary.
-			
-			// This is the textnode where the cursor will be positioned at.
-			oRange.InsertNode( this.Window.document.createTextNode( '' ) ) ;
+			FCKDebug.Output( 'BR - No Header' ) ;
 
 			var eBr = this.Window.document.createElement( 'br' ) ;
+
 			oRange.InsertNode( eBr ) ;
-
-			if ( bIsEndOfBlock && !FCKBrowserInfo.IsIE )
+			
+			// The space is required by Gecko only to make the cursor blink.
+			if ( FCKBrowserInfo.IsGecko )
+				FCKDomTools.InsertAfterNode( eBr, this.Window.document.createTextNode( '' ) ) ;
+				
+			// If we are at the end of a block, we must be sure the bogus node is available in that block.
+			if ( bIsEndOfBlock && FCKBrowserInfo.IsGecko )
 			{
 				var eLastBr = FCKDomTools.GetLastChild( eBr.parentNode, 'BR' ) ;
 
-				if ( eLastBr && eLastBr == eBr )
-					FCKDomTools.InsertAfterNode( eBr.nextSibling, FCKTools.CreateBogusBR( this.Window.document ) ) ;
+				if ( eLastBr && eLastBr.getAttribute( 'type', 2 ) != '_moz' )
+					eBr.parentNode.appendChild( FCKTools.CreateBogusBR( this.Window.document ) ) ;
 			}
 
 			if ( FCKBrowserInfo.IsIE )
-			{
 				oRange.SetStart( eBr, 4 ) ;
-				oRange.Collapse( true ) ;
-			}
 			else
 				oRange.SetStart( eBr.nextSibling, 1 ) ;
-		}
-		
+
+		}
+		
+		// This collapse guarantees the cursor will be blinking.
+		oRange.Collapse( true ) ;
+
 		oRange.Select() ;
 	}
@@ -520,40 +477,26 @@
 
 // Transform a block without a block tag in a valid block (orphan text in the body or td, usually).
-FCKEnterKey.prototype._FixBlock = function( range, isStartBlock, blockTag )
-{
+FCKEnterKey.prototype._FixBlock = function( range, isStart, blockTag )
+{
+	// Bookmark the range so we can restore it later.
 	var oBookmark = range.CreateBookmark() ;
 
-	// Create a range clone to the ending boundary.
-	var oTempRange = range.Clone() ;
-	oTempRange.Collapse( isStartBlock ) ;
+	// Collapse the range to the requested ending boundary.
+	range.Collapse( isStart ) ;
 
 	// Expands it to the block contents.
-	oTempRange.Expand( 'block_contents' ) ;
-
+	range.Expand( 'block_contents' ) ;
+
+	// Create the fixed block.
 	var oFixedBlock = this.Window.document.createElement( blockTag ) ;
-	
-	// In IE, the range boundary cannot be positioned between tags, so we must use markers.
-	if ( FCKBrowserInfo.IsIE )
-	{
-		var eStartMarker	= oTempRange.InsertMarkerTag( true ) ;
-		var eEndMarker		= oTempRange.InsertMarkerTag( false ) ;
-		
-		eStartMarker.parentNode.insertBefore( oFixedBlock, eStartMarker ) ;
-
-		oTempRange.ExtractContents().AppendTo( oFixedBlock ) ;
-		FCKDomTools.TrimNode( oFixedBlock ) ;
-	}
-
-	oTempRange.ExtractContents().AppendTo( oFixedBlock ) ;
+
+	// Move the contents of the temporary range to the fixed block.
+	range.ExtractContents().AppendTo( oFixedBlock ) ;
 	FCKDomTools.TrimNode( oFixedBlock ) ;
 
-	if ( !FCKBrowserInfo.IsIE )
-		oTempRange.InsertNode( oFixedBlock ) ;
-	
+	// Insert the fixed block into the DOM.
+	range.InsertNode( oFixedBlock ) ;
+	
+	// Move the range back to the bookmarked place.
 	range.MoveToBookmark( oBookmark ) ;
-
-	// A bookmark may leave the range boundary between nodes, which causes
-	// problems. The following trick will fix it.
-	range.Select() ;
-	range.MoveToSelection() ;
-}
+}
Index: /FCKeditor/trunk/editor/_source/classes/fckw3crange.js
===================================================================
--- /FCKeditor/trunk/editor/_source/classes/fckw3crange.js	(revision 76)
+++ /FCKeditor/trunk/editor/_source/classes/fckw3crange.js	(revision 77)
@@ -234,5 +234,13 @@
 		// be handled by the rest of the code .
 		if ( startNode.nodeType == 3 )
+		{
 			startNode.splitText( startOffset ) ;
+			
+			// In cases the end node is the same as the start node, the above
+			// splitting will also split the end, so me must move the end to
+			// the second part of the split.
+			if ( startNode == endNode )
+				endNode = startNode.nextSibling ;
+		}
 		else
 		{
@@ -399,5 +407,5 @@
 
 			endNode = this.endContainer ;
-			if ( endNode.nodeType == 3 )
+			if ( endNode.nodeType == 3 && endNode.nextSibling )
 			{
 				endNode.data += endNode.nextSibling.data ;
Index: /FCKeditor/trunk/editor/_source/fckjscoreextensions.js
===================================================================
--- /FCKeditor/trunk/editor/_source/fckjscoreextensions.js	(revision 76)
+++ /FCKeditor/trunk/editor/_source/fckjscoreextensions.js	(revision 77)
@@ -115,15 +115,18 @@
 String.prototype.Trim = function()
 {
-	return this.replace( /(^\s*)|(\s*$)/g, '' ) ;
+	// We are not using \s because we don't want "non-breaking spaces to be caught".
+	return this.replace( /(^[ \t\n\r]*)|([ \t\n\r]*$)/g, '' ) ;
 }
 
 String.prototype.LTrim = function()
 {
-	return this.replace( /^\s*/g, '' ) ;
+	// We are not using \s because we don't want "non-breaking spaces to be caught".
+	return this.replace( /^[ \t\n\r]*/g, '' ) ;
 }
 
 String.prototype.RTrim = function()
 {
-	return this.replace( /\s*$/g, '' ) ;
+	// We are not using \s because we don't want "non-breaking spaces to be caught".
+	return this.replace( /[ \t\n\r]*$/g, '' ) ;
 }
 
Index: /FCKeditor/trunk/editor/_source/internals/fckdomtools.js
===================================================================
--- /FCKeditor/trunk/editor/_source/internals/fckdomtools.js	(revision 76)
+++ /FCKeditor/trunk/editor/_source/internals/fckdomtools.js	(revision 77)
@@ -19,8 +19,8 @@
 
 	// Remove blank spaces from the beginning and the end of the contents of a node.
-	TrimNode : function( node )
+	TrimNode : function( node, ignoreEndBRs )
 	{
 		this.LTrimNode( node ) ;
-		this.RTrimNode( node ) ;
+		this.RTrimNode( node, ignoreEndBRs ) ;
 	},
 
@@ -51,5 +51,5 @@
 	},
 
-	RTrimNode : function( node )
+	RTrimNode : function( node, ignoreEndBRs )
 	{
 		var eChildNode ;
@@ -60,5 +60,5 @@
 			{
 				case 1 :
-					if ( eChildNode.nodeName.toUpperCase() == 'BR' && eChildNode.hasAttribute('_moz_editor_bogus_node') )
+					if ( eChildNode.nodeName.toUpperCase() == 'BR' && ( ignoreEndBRs || eChildNode.getAttribute( 'type', 2 ) == '_moz' ) )
 					{
 						node.removeChild( eChildNode ) ;
@@ -141,4 +141,7 @@
 			return null ;
 
+		if ( stopSearchElements && currentNode.nodeType == 1 && currentNode.nodeName.IEquals( stopSearchElements ) )
+			return null ;
+
 		if ( currentNode.previousSibling )
 			currentNode = currentNode.previousSibling ;
@@ -222,5 +225,5 @@
 	GetIndexOf : function( node )
 	{
-		var currentNode = node.parentNode.firstChild ;
+		var currentNode = node.parentNode ? node.parentNode.firstChild : null ;
 		var currentIndex = -1 ;
 		
Index: /FCKeditor/trunk/editor/_source/internals/fcklisthandler.js
===================================================================
--- /FCKeditor/trunk/editor/_source/internals/fcklisthandler.js	(revision 76)
+++ /FCKeditor/trunk/editor/_source/internals/fcklisthandler.js	(revision 77)
@@ -16,7 +16,8 @@
 		{
 			var oDocument = FCKTools.GetElementDocument( listItem ) ;
+			var oDogFrag = new FCKDocumentFragment( oDocument ) ;
 			
 			// All children and successive siblings will be moved to a a DocFrag.
-			var eNextSiblings = oDocument.createDocumentFragment() ;
+			var eNextSiblings = oDogFrag.RootNode ;
 			var eHasLiSibling = false ;
 
@@ -59,11 +60,11 @@
 				{
 					var eChildList = eParent.cloneNode( false ) ;
-					eChildList.appendChild( eNextSiblings ) ;
+					oDogFrag.AppendTo( eChildList ) ;
 					listItem.appendChild( eChildList ) ;
 				}
 				else if ( bWellNested )
-					FCKDomTools.InsertAfterNode( eParent.parentNode, eNextSiblings ) ;
+					oDogFrag.InsertAfterNode( eParent.parentNode ) ;
 				else
-					FCKDomTools.InsertAfterNode( eParent, eNextSiblings ) ;
+					oDogFrag.InsertAfterNode( eParent ) ;
 				
 				// Move the LI after its parent.parentNode (the upper LI in the hierarchy).
@@ -78,12 +79,10 @@
 				{
 					var eNextList = eParent.cloneNode( false ) ;
-					eNextList.appendChild( eNextSiblings ) ;
+					oDogFrag.AppendTo( eNextList ) ;
 					FCKDomTools.InsertAfterNode( eParent, eNextList ) ;
 				}
-				
+
 				var eBlock = oDocument.createElement( 'p' ) ;	// TODO: Get from configuration.
-				eBlock.appendChild( eParent.removeChild( listItem ) ) ;
-				FCKDomTools.RemoveNode( listItem, true ) ;
-
+				FCKDomTools.MoveChildren( eParent.removeChild( listItem ), eBlock ) ;
 				FCKDomTools.InsertAfterNode( eParent, eBlock ) ;
 				
Index: /FCKeditor/trunk/editor/fckeditor.html
===================================================================
--- /FCKeditor/trunk/editor/fckeditor.html	(revision 76)
+++ /FCKeditor/trunk/editor/fckeditor.html	(revision 77)
@@ -72,4 +72,5 @@
 LoadScript( '_source/classes/fckdomrange.js' ) ;
 LoadScript( '_source/classes/fckdocumentfragment_' + sSuffix + '.js' ) ;
+LoadScript( '_source/classes/fckw3crange.js' ) ;
 LoadScript( '_source/classes/fckdomrange_' + sSuffix + '.js' ) ;
 LoadScript( '_source/classes/fckenterkey.js' ) ;
