Index: editor/_source/classes/fckdomrange_gecko.js
===================================================================
--- editor/_source/classes/fckdomrange_gecko.js	(revision 1434)
+++ editor/_source/classes/fckdomrange_gecko.js	(working copy)
@@ -101,4 +101,4 @@
 	var selection = this.Window.getSelection() ;
 	selection.removeAllRanges() ;
 	selection.addRange( domRange ) ;
-}
\ No newline at end of file
+}
Index: editor/_source/classes/fckstyle.js
===================================================================
--- editor/_source/classes/fckstyle.js	(revision 1434)
+++ editor/_source/classes/fckstyle.js	(working copy)
@@ -759,21 +759,114 @@
 		var bookmark ;
 
 		if ( selectIt )
-			bookmark = range.CreateBookmark( true ) ;
+			bookmark = range.CreateBookmark() ;
 
 		var iterator = new FCKDomRangeIterator( range ) ;
 		iterator.EnforceRealBlocks = true ;
 
 		var block ;
+		var doc = range.Window.document ;
+		var tagPattern = FCKRegexLib.HTMLTag;
+
 		while( ( block = iterator.GetNextParagraph() ) )		// Only one =
 		{
 			// Create the new node right before the current one.
-			var newBlock = block.parentNode.insertBefore( this.BuildElement( range.Window.document ), block ) ;
+			// var newBlock = block.parentNode.insertBefore( this.BuildElement( range.Window.document ), block ) ;
+			var newBlock = this.BuildElement( doc ) ;
 
 			// Move everything from the current node to the new one.
-			FCKDomTools.MoveChildren( block, newBlock ) ;
+			if ( newBlock.nodeName.IEquals( 'pre' ) && !block.nodeName.IEquals( 'pre' ) )
+			{
+				// Handle converting from a regular block to a <pre> block.
+				var innerHTML = block.innerHTML.Trim() ;
+				var xhtmlIterator = new FCKXHTMLIterator( innerHTML ) ;
+				var results = [] ;
+				var lastNodeWasBr = false ;
 
-			// Delete the current node.
+				// 1. Delete ANSI whitespaces immediately before and after <BR> because they are not visible.
+				// 2. Compress other ANSI whitespaces since they're only visible as one single space previously.
+				// 3. Convert &nbsp; to spaces since &nbsp; is no longer needed in <PRE>.
+				var processor = function( type, value )
+				{
+					if ( type == 'tag' )
+					{
+						if ( /^<BR/i.test( value ) )
+						{
+							value = '\n' ;
+							if ( results.length > 0 )
+								results[results.length - 1] = results[results.length - 1].RTrim() ;
+							lastNodeWasBr = true ;
+						}
+						else
+							lastNodeWasBr = false ;
+					}
+					else
+					{
+						if ( lastNodeWasBr )
+							value = value.LTrim() ;
+						value = value.replace( /([ \t\n\r]+|&nbsp;)/g, ' ' ) ;
+						lastNodeWasBr = false ;
+					}
+					results.push( value ) ;
+				}
+				xhtmlIterator.Each( processor ) ;
+
+				// Assigning innerHTML to <PRE> in IE causes all linebreaks to be reduced to spaces.
+				// Assigning outerHTML to <PRE> in IE doesn't work if the <PRE> isn't contained in another node
+				// since the node reference is changed after outerHTML assignment.
+				// So, we need some hacks to workaround IE bugs here.
+				if ( FCKBrowserInfo.IsIE )
+				{
+					var temp = doc.createElement( 'div' ) ;
+					temp.appendChild( newBlock ) ;
+					newBlock.outerHTML = '<PRE>\n' + results.join( '' ) + '</PRE>' ;
+					newBlock = temp.removeChild( temp.firstChild ) ;
+				}
+				else
+					newBlock.innerHTML = results.join( '' ) ;
+			}
+			else if ( !newBlock.nodeName.IEquals( 'pre' ) && block.nodeName.IEquals( 'pre' ) )
+			{
+				var innerHTML = block.innerHTML ;
+
+				// Trim the first and last linebreaks immediately after and before <pre>, </pre>,
+				// if they exist.
+				// This is done because the linebreaks are not rendered.
+				innerHTML = innerHTML.replace( /(\r\n|\r)/g, '\n' ) ;
+				innerHTML = innerHTML.match( /^(?:[ \t]*\n)?((?:[a]|[^a])*)$/ )[1] ;
+				var lastWhiteSpaceMatch = /\n[ \t]*$/.exec( innerHTML ) ;
+				if ( lastWhiteSpaceMatch )
+					innerHTML = innerHTML.substr( 0, lastWhiteSpaceMatch.index ) ;
+
+				// 1. Convert spaces or tabs at the beginning or at the end to &nbsp;
+				var beginSpaces = /^[ \t]+/.exec( innerHTML ) ;
+				var endSpaces = /[ \t]+$/.exec( innerHTML ) ;
+				if ( endSpaces )
+					innerHTML = innerHTML.substr( 0, endSpaces.index ) + endSpaces[0].replace( /[ \t]/g, '&nbsp;' ) ;
+				if ( beginSpaces )
+					innerHTML = beginSpaces[0].replace( /[ \t]/g, '&nbsp;' ) + innerHTML.substr( beginSpaces[0].length ) ;
+
+				// 2. Convert \n to <BR>.
+				// 3. Convert contiguous (i.e. non-singular) spaces or tabs to &nbsp;
+				var xhtmlIterator = new FCKXHTMLIterator( innerHTML ) ;
+				var results = [] ;
+				var processor = function( type, value )
+				{
+					if ( type == 'text' )
+					{
+						value = value.replace( /\n/g, '<BR>' ) ;
+						value = value.replace( /[ \t]{2}/g, '&nbsp;&nbsp;' ) ;
+					}
+					results.push( value ) ;
+				}
+				xhtmlIterator.Each( processor ) ;
+				newBlock.innerHTML = results.join( '' ) ;
+			}
+			else	// Convering from a regular block to another regular block.
+				FCKDomTools.MoveChildren( block, newBlock ) ;
+
+			// Replace the current block.
+			block.parentNode.insertBefore( newBlock, block ) ;
 			FCKDomTools.RemoveNode( block ) ;
 		}
 
@@ -782,7 +875,7 @@
 			range.SelectBookmark( bookmark ) ;
 
 		if ( updateRange )
-			range.MoveToBookmark( range ) ;
+			range.MoveToBookmark( bookmark ) ;
 	},
 
 	/**
Index: editor/_source/classes/fckxhtmliterator.js
===================================================================
--- editor/_source/classes/fckxhtmliterator.js	(revision 0)
+++ editor/_source/classes/fckxhtmliterator.js	(revision 0)
@@ -0,0 +1,68 @@
+/*
+ * FCKeditor - The text editor for Internet - http://www.fckeditor.net
+ * Copyright (C) 2003-2007 Frederico Caldeira Knabben
+ *
+ * == BEGIN LICENSE ==
+ *
+ * Licensed under the terms of any of the following licenses at your
+ * choice:
+ *
+ *  - GNU General Public License Version 2 or later (the "GPL")
+ *    http://www.gnu.org/licenses/gpl.html
+ *
+ *  - GNU Lesser General Public License Version 2.1 or later (the "LGPL")
+ *    http://www.gnu.org/licenses/lgpl.html
+ *
+ *  - Mozilla Public License Version 1.1 or later (the "MPL")
+ *    http://www.mozilla.org/MPL/MPL-1.1.html
+ *
+ * == END LICENSE ==
+ *
+ * This class can be used to interate through nodes inside a range.
+ *
+ * During interation, the provided range can become invalid, due to document
+ * mutations, so CreateBookmark() used to restore it after processing, if
+ * needed.
+ */
+
+var FCKXHTMLIterator = function( source )
+{
+	this._sourceHTML = source ;
+}
+FCKXHTMLIterator.prototype = 
+{
+	Next : function()
+	{
+		if ( this._sourceHTML == null )
+			return null ;
+
+		var match = FCKRegexLib.HTMLTag.exec( this._sourceHTML ) ;
+		var retval ;
+		if ( match )
+		{
+			if ( match.index > 0 )
+			{
+				retval = { 'type' : 'text', 'value' : this._sourceHTML.substr( 0, match.index ) } ;
+				this._sourceHTML = this._sourceHTML.substr( match.index ) ;
+			}
+			else
+			{
+				retval = { 'type' : 'tag', 'value' : match[0] } ;
+				this._sourceHTML = this._sourceHTML.substr( match[0].length ) ;
+			}
+		}
+		else
+		{
+			retval = { 'type' : 'text', 'value' : this._sourceHTML } ;
+			this._sourceHTML = null ;
+		}
+		return retval ;
+	},
+
+	Each : function( func )
+	{
+		var chunk ;
+		while ( ( chunk = this.Next() ) )
+			func( chunk.type, chunk.value ) ;
+	}
+} ;
Index: editor/_source/internals/fckregexlib.js
===================================================================
--- editor/_source/internals/fckregexlib.js	(revision 1434)
+++ editor/_source/internals/fckregexlib.js	(working copy)
@@ -93,5 +93,7 @@
 // name is returned with $2.
 StyleVariableAttName : /#\(\s*("|')(.+?)\1[^\)]*\s*\)/g,
 
-RegExp : /^\/(.*)\/([gim]*)$/
+RegExp : /^\/(.*)\/([gim]*)$/,
+
+HTMLTag : /<[^\s<>](?:"[^"]*"|'[^']*'|[^<])*>/
 } ;
Index: editor/fckeditor.html
===================================================================
--- editor/fckeditor.html	(revision 1434)
+++ editor/fckeditor.html	(working copy)
@@ -186,6 +186,7 @@
 LoadScript( '_source/classes/fckmenublockpanel.js' ) ;
 LoadScript( '_source/classes/fckcontextmenu.js' ) ;
 LoadScript( '_source/internals/fck_contextmenu.js' ) ;
+LoadScript( '_source/classes/fckxhtmliterator.js' ) ;
 LoadScript( '_source/classes/fckplugin.js' ) ;
 LoadScript( '_source/internals/fckplugins.js' ) ;
 
Index: fckpackager.xml
===================================================================
--- fckpackager.xml	(revision 1434)
+++ fckpackager.xml	(working copy)
@@ -157,6 +157,7 @@
 		<File path="editor/_source/classes/fckmenublockpanel.js" />
 		<File path="editor/_source/classes/fckcontextmenu.js" />
 		<File path="editor/_source/internals/fck_contextmenu.js" />
+		<File path="editor/_source/class/fckxhtmliterator.js" />
 
 		<File path="editor/_source/classes/fckplugin.js" />
 		<File path="editor/_source/internals/fckplugins.js" />
@@ -252,6 +253,7 @@
 		<File path="editor/_source/classes/fckmenublockpanel.js" />
 		<File path="editor/_source/classes/fckcontextmenu.js" />
 		<File path="editor/_source/internals/fck_contextmenu.js" />
+		<File path="editor/_source/class/fckxhtmliterator.js" />
 
 		<File path="editor/_source/classes/fckplugin.js" />
 		<File path="editor/_source/internals/fckplugins.js" />
