Index: /FCKeditor/trunk/editor/_source/classes/fckdomrange.js
===================================================================
--- /FCKeditor/trunk/editor/_source/classes/fckdomrange.js	(revision 798)
+++ /FCKeditor/trunk/editor/_source/classes/fckdomrange.js	(revision 799)
@@ -52,5 +52,20 @@
 			if ( eStart != eEnd )
 				oElementPath = new FCKElementPath( eEnd ) ;
-			this.EndNode			= eEnd.nodeType == 3 ? eEnd : eEnd.childNodes[ innerRange.endOffset ] ;
+
+			// The innerRange.endContainer[ innerRange.endOffset ] is not
+			// usually part of the range, but the marker for the range end. So,
+			// let's get the previous available node as the real end.
+			var eEndNode = eEnd ;
+			if ( innerRange.endOffset == 0 )
+			{
+				while ( eEndNode && !eEndNode.previousSibling )
+					eEndNode = eEndNode.parentNode ;
+				
+				eEndNode = eEndNode.previousSibling ;
+			}
+			else if ( eEndNode.nodeType == 1 )
+				eEndNode = eEndNode.childNodes[ innerRange.endOffset - 1 ] ;
+
+			this.EndNode			= eEndNode ;
 			this.EndContainer		= eEnd ;
 			this.EndBlock			= oElementPath.Block ;
@@ -394,5 +409,5 @@
 	 *			4 = After End		<target>contents</target>^
 	 */
-	SetStart : function( targetElement, position )
+	SetStart : function( targetElement, position, noInfoUpdate )
 	{
 		var oRange = this._Range ;
@@ -417,5 +432,7 @@
 				oRange.setStartAfter( targetElement ) ;
 		}
-		this._UpdateElementInfo() ;
+		
+		if ( !noInfoUpdate )
+			this._UpdateElementInfo() ;
 	},
 
@@ -429,5 +446,5 @@
 	 *			4 = After End		<target>contents</target>^
 	 */
-	SetEnd : function( targetElement, position )
+	SetEnd : function( targetElement, position, noInfoUpdate )
 	{
 		var oRange = this._Range ;
@@ -452,5 +469,7 @@
 				oRange.setEndAfter( targetElement ) ;
 		}
-		this._UpdateElementInfo() ;
+
+		if ( !noInfoUpdate )
+			this._UpdateElementInfo() ;
 	},
 
@@ -509,5 +528,5 @@
 
 			case 'block_contents' :
-				if ( this.StartBlock )
+				if ( this.StartBlock && FCKConfig.EnterMode != 'br' )
 					this.SetStart( this.StartBlock, 1 ) ;
 				else
@@ -519,40 +538,23 @@
 					// If the offset node is not available, the the first one.
 					if ( oNode.nodeType == 1 )
-					{
-						if ( !( oNode = oNode.childNodes[ this._Range.startOffset ] ) )
-							oNode = oNode.firstChild ;
-					}
-
-					// Not able to defined the current position.
-					if ( !oNode )
-						return ;
+						oNode = oNode.childNodes[ this._Range.startOffset ] || oNode.firstChild ;
 
 					// We must look for the left boundary, relative to the range
 					// start, which is limited by a block element.
-					while ( true )
+					while ( oNode 
+							&& ( oNode.nodeType != 1 
+								|| ( oNode != this.StartBlockLimit
+									&& !FCKListsLib.BlockBoundaries[ oNode.nodeName.toLowerCase() ] ) ) )
 					{
-						oSibling = oNode.previousSibling ;
-
-						if ( !oSibling )
-						{
-							// Continue if we are not yet in the block limit (inside a <b>, for example).
-							if ( oNode.parentNode != this.StartBlockLimit )
-								oNode = oNode.parentNode ;
-							else
-								break ;
-						}
-						else if ( oSibling.nodeType != 1 || !(/^(?:P|DIV|H1|H2|H3|H4|H5|H6|ADDRESS|PRE|OL|UL|LI|DT|DE)$/).test( oSibling.nodeName.toUpperCase() ) )
-						{
-							// Continue if the sibling is not a block tag.
-							oNode = oSibling ;
-						}
-						else
+						this._Range.setStartBefore( oNode ) ;
+						
+						if ( oNode == oNode.parentNode.firstChild && FCKListsLib.BlockBoundaries[ oNode.parentNode.nodeName.toLowerCase() ] )
 							break ;
+
+						oNode = FCKDomTools.GetPreviousSourceNode( oNode, true ) ;
 					}
-
-					this._Range.setStartBefore( oNode ) ;
-				}
-
-				if ( this.EndBlock )
+				}
+
+				if ( this.EndBlock && FCKConfig.EnterMode != 'br'  )
 					this.SetEnd( this.EndBlock, 2 ) ;
 				else
@@ -562,35 +564,78 @@
 						oNode = oNode.childNodes[ this._Range.endOffset ] || oNode.lastChild ;
 
-					if ( !oNode )
-						return ;
-
 					// We must look for the right boundary, relative to the range
 					// end, which is limited by a block element.
-					while ( true )
+					while ( oNode 
+							&& ( oNode.nodeType != 1 
+								|| ( oNode != this.StartBlockLimit 
+									&& !FCKListsLib.BlockBoundaries[ oNode.nodeName.toLowerCase() ] ) ) )
 					{
-						oSibling = oNode.nextSibling ;
-
-						if ( !oSibling )
-						{
-							// Continue if we are not yet in the block limit (inside a <b>, for example).
-							if ( oNode.parentNode != this.EndBlockLimit )
-								oNode = oNode.parentNode ;
-							else
-								break ;
-						}
-						else if ( oSibling.nodeType != 1 || !(/^(?:P|DIV|H1|H2|H3|H4|H5|H6|ADDRESS|PRE|OL|UL|LI|DT|DE)$/).test( oSibling.nodeName.toUpperCase() ) )
-						{
-							// Continue if the sibling is not a block tag.
-							oNode = oSibling ;
-						}
-						else
+						this._Range.setEndAfter( oNode ) ;
+
+						if ( oNode == oNode.parentNode.lastChild && FCKListsLib.BlockBoundaries[ oNode.parentNode.nodeName.toLowerCase() ] )
 							break ;
+
+						oNode = FCKDomTools.GetNextSourceNode( oNode, true ) ;
 					}
-
+					
+					// In EnterMode='br', the end <br> boundary element must
+					// be included in the expanded range.
+					if ( oNode && oNode.nodeName.toLowerCase() == 'br' ) 
+						this._Range.setEndAfter( oNode ) ;
+				}
+
+				this._UpdateElementInfo() ;
+				break ;											// @Packager.Remove.Start
+
+			case 'list_contents' :
+				// Get the start node for the current range.
+				oNode = this._Range.startContainer ;
+
+				// If it is an element, get the current child node for the range (in the offset).
+				// If the offset node is not available, the the first one.
+				if ( oNode.nodeType == 1 )
+					oNode = oNode.childNodes[ this._Range.startOffset ] || oNode.firstChild ;
+
+				// We must look for the left boundary, relative to the range
+				// start, which is limited by a block element.
+				while ( oNode 
+						&& ( oNode.nodeType != 1 
+							|| ( oNode != this.StartBlockLimit
+								&& !FCKListsLib.ListBoundaries[ oNode.nodeName.toLowerCase() ] ) ) )
+				{
+					this._Range.setStartBefore( oNode ) ;
+
+					if ( oNode == oNode.parentNode.firstChild && FCKListsLib.ListBoundaries[ oNode.parentNode.nodeName.toLowerCase() ] )
+						break ;
+
+					oNode = FCKDomTools.GetPreviousSourceNode( oNode, true ) ;
+				}
+
+				oNode = this._Range.endContainer ;
+				if ( oNode.nodeType == 1 )
+					oNode = oNode.childNodes[ this._Range.endOffset ] || oNode.lastChild ;
+
+				// We must look for the right boundary, relative to the range
+				// end, which is limited by a block element.
+				while ( oNode 
+						&& ( oNode.nodeType != 1 
+							|| ( oNode != this.StartBlockLimit 
+								&& !FCKListsLib.ListBoundaries[ oNode.nodeName.toLowerCase() ] ) ) )
+				{
 					this._Range.setEndAfter( oNode ) ;
-				}
+
+					if ( oNode == oNode.parentNode.lastChild && FCKListsLib.ListBoundaries[ oNode.parentNode.nodeName.toLowerCase() ] )
+						break ;
+
+					oNode = FCKDomTools.GetNextSourceNode( oNode, true ) ;
+				}
+
+				// In EnterMode='br', the end <br> boundary element must
+				// be included in the expanded range.
+				if ( oNode && oNode.nodeName.toLowerCase() == 'br' ) 
+					this._Range.setEndAfter( oNode ) ;
 
 				this._UpdateElementInfo() ;
-			break ;											// @Packager.Remove.Start
+				break ;											// @Packager.Remove.Start
 
 			default :
@@ -725,191 +770,121 @@
 	CheckHasRange : function()
 	{
-		return ( this._Range && true ) ;
-	},
-
-	_CheckIsParagraphBoundary : function( node )
-	{
-		if ( node.nodeType == 1 )
-		{
-			var tagName = node.tagName.toLowerCase() ;
-			return ! ( FCKListsLib.InlineNonEmptyElements[tagName] || tagName == 'img' ) ;
-		}
-		return false ;
-	},
-
-	_GenerateParagraphRange : function( paragraphList, targetWindow, startNode, endNode )
-	{
-		if ( ! startNode || ! endNode )
-			return ;
-		var range = new FCKDomRange( targetWindow ) ;
-		range._Range = new FCKW3CRange( targetWindow.document ) ;
-		if ( startNode.nodeName.toLowerCase() == 'br' )
-			range._Range.setStartBefore( startNode ) ;
+		return !!this._Range ;
+	},
+
+	GetParagraphs : function( forceBreakBr )
+	{
+		var retval = [] ;
+
+		// Get and "expanded" clone of this range.
+		var range = this.Clone() ;
+		if ( forceBreakBr )
+			range.Expand( 'list_contents' ) ;
 		else
-			range._Range.setStart( startNode, 0 ) ;
-		if ( endNode.nodeName.toLowerCase() == 'br' )
-			range._Range.setEndBefore( endNode ) ;
-		else
-			range._Range.setEnd( endNode, endNode.nodeType == 1 ? endNode.childNodes.length : endNode.nodeValue.length ) ;
-		range._UpdateElementInfo() ;
-		paragraphList.push( range ) ;
-	},
-
-	GetSelectedParagraphs : function()
-	{
-		this.MoveToSelection() ;
-
-		var startNode = this._Range.startContainer ;
-		var endNode = this._Range.endContainer ;
-		var startOffset = this._Range.startOffset ;
-		var endOffset = this._Range.endOffset ;
-		if ( startNode.childNodes && startNode.childNodes[startOffset] )
-			startNode = startNode.childNodes[startOffset] ;
-		if ( endNode.childNodes && endNode.childNodes[endOffset] )
-			endNode = endNode.childNodes[endOffset] ;
-
-		// Get the starting point of the selection's paragraph.
-		var paragraphStartNode = startNode ;
-		while ( paragraphStartNode && ! this._CheckIsParagraphBoundary( paragraphStartNode ) )
-		{
-			var candidate = null ;
-			if ( paragraphStartNode.previousSibling )
-			{
-				if ( ! this._CheckIsParagraphBoundary( paragraphStartNode.previousSibling ) )
-					candidate = paragraphStartNode.previousSibling ;
-				while ( candidate && candidate.lastChild && ! this._CheckIsParagraphBoundary( candidate.lastChild ) )
-					candidate = candidate.lastChild ;
-			}
-			else
-			{
-				if ( ! this._CheckIsParagraphBoundary( paragraphStartNode.parentNode ) )
-					candidate = paragraphStartNode.parentNode ;
-			}
-
-			if ( candidate )
-				paragraphStartNode = candidate ;
-			else
-				break ;
-		}
-
-		// Get the ending point of the selection's paragraph.
-		var paragraphEndNode = endNode ;
-		while ( paragraphEndNode && ! this._CheckIsParagraphBoundary( paragraphEndNode ) )
-		{
-			var candidate = null ;
-			if ( paragraphEndNode.firstChild )
-			{
-				if ( ! this._CheckIsParagraphBoundary( paragraphEndNode.firstChild ) )
-					candidate = paragraphEndNode.firstChild ;
-			}
-			else if ( paragraphEndNode.nextSibling )
-			{
-				if ( ! this._CheckIsParagraphBoundary( paragraphEndNode.nextSibling ) )
-					candidate = paragraphEndNode.nextSibling ;
-			}
-			else
-			{
-				var ancestor = paragraphEndNode.parentNode ;
-				while ( ancestor )
-				{
-					if ( this._CheckIsParagraphBoundary( ancestor ) )
-						break ;
-					if ( ancestor.nextSibling )
+			range.Expand( 'block_contents' ) ;
+	
+		var currentNode	= range.StartNode || range.StartContainer ;
+		var lastNode	= range.EndNode || range.EndContainer.lastChild || range.EndContainer ;
+
+		var boundarySet = FCKListsLib.BlockBoundaries ;
+		if ( forceBreakBr )
+			boundarySet = FCKListsLib.ListBoundaries ;
+		
+		// Let's reuse this range 
+		range = null ;
+
+		while ( currentNode )
+		{
+			// closeRange indicates that a paragraph boundary has been found,
+			// so the range must be appended to the list.
+			var closeRange = false ;
+			
+			var continueFromSibling = false ;
+			
+			// includeNode indicates that the current node is good to be part
+			// of the range.
+			var includeNode = ( currentNode.nodeType != 1 ) ;
+			
+			// If it is an element node, let's check if it can be part of the
+			// range.
+			if ( !includeNode )
+			{
+				var nodeName = currentNode.nodeName.toLowerCase() ;
+				
+				if ( boundarySet[ nodeName ] )
+				{
+					// <br> boundaries must be part of the range. It will
+					// happen only if EnterMode='br'.
+					if ( nodeName == 'br' )
+						includeNode = true ;
+				
+					closeRange = true ;
+				}
+				else
+				{
+					// If we have child nodes, let's check them.
+					if ( currentNode.firstChild )
 					{
-						if ( this._CheckIsParagraphBoundary( ancestor.nextSibling ) )
-							break ;
-						candidate = ancestor.nextSibling ;
+						currentNode = currentNode.firstChild ;
+						continue ;
+					}
+					includeNode = true ;
+				}
+			}
+			else if ( currentNode.nodeType == 3 )
+			{
+				// Ignore normal whitespaces (i.e. not including &nbsp; or
+				// other unicode whitespaces) before/after a block node.
+				if ( /^[\r\n\t ]+$/.test( currentNode.nodeValue ) )
+					includeNode = false ;
+			}
+			
+			// The current node is good to be part of the range and we are
+			// starting a new range, initialize it first.
+			if ( includeNode && !range )
+			{
+				range = new FCKDomRange( this.Window ) ;
+				range.SetStart( currentNode, 3, true ) ;
+			}
+				
+			// If we are in an element boundary, let's check if it is time
+			// to close the range, otherwise we include the parent within it.
+			if ( range && !closeRange )
+			{
+				var parentNode = currentNode.parentNode ;
+				while ( currentNode == parentNode.lastChild && currentNode != lastNode )
+				{
+					if ( boundarySet[ parentNode.nodeName.toLowerCase() ] )
+					{
+						closeRange = true ;		
 						break ;
 					}
-					else
-						ancestor = ancestor.parentNode ;
-				}
-			}
-
-			if ( candidate )
-				paragraphEndNode = candidate ;
-			else
+					
+					currentNode = parentNode ;
+					continueFromSibling = true ;
+				}
+			}
+			
+			// Now finally include the node.
+			if ( includeNode )
+				range.SetEnd( currentNode, 4, true ) ;
+			
+			// We have found a block boundary. Let's add the range to the list,
+			// and prepare it for the next one.
+			if ( ( closeRange || currentNode == lastNode ) && range )
+			{
+				range._UpdateElementInfo() ;
+				retval.push( range ) ;
+				range = null ;
+			}
+			
+			// Stop processing if this is the last one.
+			if ( currentNode == lastNode )
 				break ;
-		}
-
-		// Break up the range between paragraphStartNode and paragraphEndNode into paragraphs represented by ranges.
-		var retval = [] ;
-		var currentStart = paragraphStartNode ;
-		var currentEnd = currentStart ;
-
-		// Each iteration advances the position by one node in a DFS tree walk.
-		while ( currentEnd != paragraphEndNode )
-		{
-			// 1. if we come across a <br> node, save a new paragraph
-			// 2. if we come across a block element boundary, save a new paragraph
-			// 3. set currentStart to null after saving a new paragraph
-			// 4. set currentStart to currentEnd if currentStart is null and currentEnd is not boundary node
-			if ( currentStart == null && currentEnd.nodeType == 3 )
-			{
-				// Ignore normal whitespaces (i.e. not including &nbsp; or other unicode whitespaces) after a block node.
-				if ( currentEnd.nodeValue.search( /^[\r\n\t ]+$/ ) == 0 )
-				{
-					var prevNode = currentEnd.previousSibling ;
-					if ( prevNode )
-					{
-						var prevTag = String( prevNode.tagName ).toLowerCase() ;
-						if ( ! ( FCKListsLib.BlockElements[prevTag] || FCKListsLib.NonEmptyBlockElements[prevTag] ) )
-							currentStart = currentEnd ;
-					}
-				}
-				else if ( currentEnd.nodeValue.length > 0 )
-					currentStart = currentEnd ;
-			}
-
-			if ( currentEnd.firstChild )
-			{
-				if ( this._CheckIsParagraphBoundary( currentEnd.firstChild ) )
-				{
-					this._GenerateParagraphRange( retval, this.Window, currentStart, currentEnd ) ;
-					currentStart = null ;
-				}
-				currentEnd = currentEnd.firstChild ;
-			}
-			else if ( currentEnd.nextSibling )
-			{
-				if ( this._CheckIsParagraphBoundary( currentEnd.nextSibling ) )
-				{
-					this._GenerateParagraphRange( retval, this.Window, currentStart, currentEnd ) ;
-					currentStart = null ;
-				}
-				currentEnd = currentEnd.nextSibling ;
-			}
-			else
-			{
-				var ancestor = currentEnd.parentNode ;
-				while ( ancestor )
-				{
-					if ( this._CheckIsParagraphBoundary( ancestor ) )
-					{
-						this._GenerateParagraphRange( retval, this.Window, currentStart, currentEnd ) ;
-						currentStart = null ;
-					}
-					if ( ancestor.nextSibling )
-					{
-						if ( this._CheckIsParagraphBoundary( ancestor.nextSibling ) )
-						{
-							this._GenerateParagraphRange( retval, this.Window, currentStart, currentEnd ) ;
-							currentStart = null ;
-						}
-						currentEnd = ancestor.nextSibling ;
-						break ;
-					}
-					else
-						ancestor = ancestor.parentNode ;
-				}
-			}
-		}
-		// Record the final range as well.
-		if ( currentStart == null && currentEnd.nodeType == 3 )
-			currentStart = currentEnd ;
-		this._GenerateParagraphRange( retval, this.Window, currentStart, currentEnd ) ;
+			
+			currentNode = FCKDomTools.GetNextSourceNode( currentNode, continueFromSibling ) ;
+		}
 
 		return retval ;
 	}
-
 } ;
Index: /FCKeditor/trunk/editor/_source/classes/fckeditingarea.js
===================================================================
--- /FCKeditor/trunk/editor/_source/classes/fckeditingarea.js	(revision 798)
+++ /FCKeditor/trunk/editor/_source/classes/fckeditingarea.js	(revision 799)
@@ -303,4 +303,13 @@
 	// Kludge for #141... yet more code to workaround IE bugs
 	var range = this.Document.selection.createRange() ;
+
+	// Only apply the fix when in a block and the block is empty.
+	var parentNode = range.parentElement() ;
+
+	if ( ! ( parentNode.childNodes.length == 0 && ( 
+					FCKListsLib.BlockElements[parentNode.nodeName.toLowerCase()] || 
+					FCKListsLib.NonEmptyBlockElements[parentNode.nodeName.toLowerCase()] ) ) )
+		return ;
+
 	var oldLength = range.text.length ;
 	range.moveEnd( "character", 1 ) ;
Index: /FCKeditor/trunk/editor/_source/internals/fckdomtools.js
===================================================================
--- /FCKeditor/trunk/editor/_source/internals/fckdomtools.js	(revision 798)
+++ /FCKeditor/trunk/editor/_source/internals/fckdomtools.js	(revision 799)
@@ -270,15 +270,36 @@
 			return null ;
 
-		var nextNode ;
+		var node ;
 		
 		if ( !startFromSibling && currentNode.firstChild )
-			nextNode = currentNode.firstChild ;
-		else
-			nextNode = ( currentNode.nextSibling || this.GetNextSourceNode( currentNode.parentNode, true, nodeType ) ) ;
-		
-		if ( nodeType && nextNode && nextNode.nodeType != nodeType )
-			return this.GetNextSourceNode( nextNode, false, nodeType ) ;
-		
-		return nextNode ;
+			node = currentNode.firstChild ;
+		else
+			node = ( currentNode.nextSibling || this.GetNextSourceNode( currentNode.parentNode, true, nodeType ) ) ;
+		
+		if ( nodeType && node && node.nodeType != nodeType )
+			return this.GetNextSourceNode( node, false, nodeType ) ;
+		
+		return node ;
+	},
+
+	/*
+	 * Get the next DOM node available in source order.
+	 */
+	GetPreviousSourceNode : function( currentNode, startFromSibling, nodeType )
+	{
+		if ( !currentNode )
+			return null ;
+
+		var node ;
+		
+		if ( !startFromSibling && currentNode.lastChild )
+			node = currentNode.lastChild ;
+		else
+			node = ( currentNode.previousSibling || this.GetPreviousSourceNode( currentNode.parentNode, true, nodeType ) ) ;
+		
+		if ( nodeType && node && node.nodeType != nodeType )
+			return this.GetPreviousSourceNode( node, false, nodeType ) ;
+		
+		return node ;
 	},
 
Index: /FCKeditor/trunk/editor/_source/internals/fcklistslib.js
===================================================================
--- /FCKeditor/trunk/editor/_source/internals/fcklistslib.js	(revision 798)
+++ /FCKeditor/trunk/editor/_source/internals/fcklistslib.js	(revision 799)
@@ -54,4 +54,8 @@
 	// Object elements for the Styles System.
 	StyleObjectElements : { img:1,hr:1,li:1,table:1,tr:1,td:1,embed:1,object:1,ol:1,ul:1 },
+	
+	// Elements used to separate block contents.
+	BlockBoundaries : { p:1,div:1,h1:1,h2:1,h3:1,h4:1,h5:1,h6:1,hr:1,address:1,pre:1,ol:1,ul:1,li:1,dt:1,de:1,table:1,thead:1,tbody:1,tfoot:1,tr:1,th:1,td:1,caption:1,col:1,colgroup:1,blockquote:1 },
+	ListBoundaries : { p:1,div:1,h1:1,h2:1,h3:1,h4:1,h5:1,h6:1,hr:1,address:1,pre:1,ol:1,ul:1,li:1,dt:1,de:1,table:1,thead:1,tbody:1,tfoot:1,tr:1,th:1,td:1,caption:1,col:1,colgroup:1,blockquote:1,br:1 },
 
 	// Final setup of FCKListsLib once the editor is loaded (at FCK.StartEditor).
@@ -69,4 +73,7 @@
 		else
 			this.PathBlockLimitElements.div = 1 ;
+		
+		if ( FCKConfig.EnterMode == 'br' )
+			this.BlockBoundaries.br = 1 ;
 	}
 } ;
