Index: /FCKeditor/branches/features/new_samples/_dev/releaser/fckreleaser.php
===================================================================
--- /FCKeditor/branches/features/new_samples/_dev/releaser/fckreleaser.php	(revision 2266)
+++ /FCKeditor/branches/features/new_samples/_dev/releaser/fckreleaser.php	(revision 2267)
@@ -82,8 +82,8 @@
 {
 	$dirPath = str_replace( '\\', '/', $dirPath ) ;
-
+	
 	if ( substr( $dirPath, -1, 1 ) != '/' )
 		$dirPath .= '/' ;
-
+	
 	return $dirPath ;
 }
@@ -170,5 +170,5 @@
 		if ( isset( $releaseNode->Children[ 'IGNOREFILE' ] ) )
 		{
-			$ignoreNodes = $releaseNode->Children[ 'IGNOREFILE' ] ;
+			$ignoreNodes = $releaseNode->Children[ 'IGNOREFILE' ] ;	
 			foreach ( $ignoreNodes as $ignoreNode )
 			{
@@ -181,8 +181,8 @@
 		if ( isset( $releaseNode->Children[ 'ORIGINALFILE' ] ) )
 		{
-			$originalNodes = $releaseNode->Children[ 'ORIGINALFILE' ] ;
+			$originalNodes = $releaseNode->Children[ 'ORIGINALFILE' ] ;	
 			foreach ( $originalNodes as $originalNode )
 			{
-				$this->OriginalFiles[] = (object)array(
+				$this->OriginalFiles[] = (object)array( 
 					'Source' => $originalNode->Attributes[ 'SOURCEPATH' ],
 					'Target' => $originalNode->Attributes[ 'TARGETPATH' ] ) ;
@@ -239,5 +239,5 @@
 		while ( $file = readdir( $sourceDirHandler ) )
 		{
-			// Skip ".", ".." and hidden fields (Unix).
+			// Skip ".", ".." and hidden fields (Unix). 
 			if ( substr( $file, 0, 1 ) == '.' )
 				continue ;
@@ -327,7 +327,7 @@
 		// Project start time (registration at SourceForge, actually = 2003-03-01 18:20).
 		$startTime = gmmktime( 18, 20, 0, 3, 1, 2003 ) ;
-
+		
 		$currentTime = time() ;
-
+		
 		// Get the number of seconds since the project startup.
 		$seconds = $currentTime - $startTime ;
@@ -597,14 +597,14 @@
 		$script = $stringsProc->ProtectStrings( $script ) ;
 
+		// Remove "/* */" comments
+		$script = preg_replace(
+			'/(?<!\/)\/\*.*?\*\//s',
+			'', $script ) ;
+
 		// Remove "//" comments
 		$script = preg_replace(
-			'/\/\/.*$/m',
-			'', $script ) ;
-
-		// Remove "/* */" comments
-		$script = preg_replace(
-			'/(?m-s:^\s*\/\*).*?\*\//s',
-			'', $script ) ;
-
+				'/\/\/.*$/m',
+				'', $script ) ;
+		
 		// Remove spaces before the ";" at the end of the lines
 		$script = preg_replace(
@@ -966,4 +966,9 @@
 		}
 
+		// Fix invalid line breaks (must be all CRLF).
+		$data = preg_replace(
+			'/(?:(?<!\r)\n)|(?:\r(?!\n))/im',
+			"\r\n", $data ) ;
+
 		return $data ;
 	}
@@ -985,6 +990,7 @@
 	function ProtectStrings( $source )
 	{
+		// Catches string literals, regular expressions and conditional comments.
 		return preg_replace_callback(
-			'/(?:("|\').*?(?<!\\\\)\1|(?<![\/\\\\])\/[^\/\*].*?(?<!\\\\)\/)/',
+			'/(?:("|\').*?(?<!\\\\)\1)|(?:(?<![\*\/\\\\])\/[^\/\*].*?(?<!\\\\)\/(?=([\.\w])|(\s*[,;}\)])))|(?s:\/\*@(?:cc_on|if|elif|else|end).*?@\*\/)/',
 			array( &$this, '_ProtectStringsMatch' ), $source ) ;
 	}
Index: /FCKeditor/branches/features/new_samples/_whatsnew.html
===================================================================
--- /FCKeditor/branches/features/new_samples/_whatsnew.html	(revision 2266)
+++ /FCKeditor/branches/features/new_samples/_whatsnew.html	(revision 2267)
@@ -47,4 +47,6 @@
 		<li>[<a target="_blank" href="http://dev.fckeditor.net/ticket/2252">#2252</a>] It's now possible to enable the
 			browsers default menu using the configuration file (FCKConfig.BrowserContextMenu option).</li> 
+		<li>[<a target="_blank" href="http://dev.fckeditor.net/ticket/2247">#2247</a>] The SHIFT+SPACE
+			keystroke will now produce a &amp;nbsp; character.</li>
 	</ul>
 	<p>
@@ -92,4 +94,14 @@
 			multiple contiguous paragraphs to Formatted will now be merged into a single 
 			&lt;PRE&gt; block.</li>
+		<li>[<a target="_blank" href="http://dev.fckeditor.net/ticket/2363">#2363</a>] There
+			were some sporadic "Permission Denied" errors with IE on some situations.</li>
+		<li>[<a target="_blank" href="http://dev.fckeditor.net/ticket/2135">#2135</a>] Fixed a 
+			data loss bug in IE when there are @import statements in the editor's CSS files,
+			and IE's cache is set to "Check for newer versions on every visit".</li>
+		<li>[<a target="_blank" href="http://dev.fckeditor.net/ticket/2376">#2376</a>] FCK.InsertHtml()
+			will now insert to the last selected position after the user has selected things outside
+			of FCKeditor, in IE.</li>
+		<li>[<a target="_blank" href="http://dev.fckeditor.net/ticket/2368">#2368</a>] Fixed broken protect 
+			source logic for comments in IE.</li>
 	</ul>
 	<p>
Index: /FCKeditor/branches/features/new_samples/editor/_source/classes/fckeditingarea.js
===================================================================
--- /FCKeditor/branches/features/new_samples/editor/_source/classes/fckeditingarea.js	(revision 2266)
+++ /FCKeditor/branches/features/new_samples/editor/_source/classes/fckeditingarea.js	(revision 2267)
@@ -152,16 +152,21 @@
 		{
 			var editArea = this ;
-			( oIFrame.onreadystatechange = function()
-			{
-				if ( oIFrame.readyState == 'complete' )
-				{
-					oIFrame.onreadystatechange = null ;
-					editArea.Window._FCKEditingArea = editArea ;
-					FCKEditingArea_CompleteStart.call( editArea.Window ) ;
-				}
-			// It happened that IE changed the state to "complete" after the
-			// "if" and before the "onreadystatechange" assignement, making we
-			// lost the event call, so we do a manual call just to be sure.
-			} )() ;
+			
+			// Using a IE alternative for DOMContentLoaded, similar to the
+			// solution proposed at http://javascript.nwbox.com/IEContentLoaded/
+			setTimeout( function()
+					{
+						try 
+						{
+							editArea.Window.document.documentElement.doScroll("left") ;
+						}
+						catch(e)
+						{
+							setTimeout( arguments.callee, 0 ) ;
+							return ;
+						}
+						editArea.Window._FCKEditingArea = editArea ;
+						FCKEditingArea_CompleteStart.call( editArea.Window ) ;
+					}, 0 ) ;
 		}
 		else
Index: /FCKeditor/branches/features/new_samples/editor/_source/commandclasses/fck_othercommands.js
===================================================================
--- /FCKeditor/branches/features/new_samples/editor/_source/commandclasses/fck_othercommands.js	(revision 2266)
+++ /FCKeditor/branches/features/new_samples/editor/_source/commandclasses/fck_othercommands.js	(revision 2267)
@@ -614,2 +614,21 @@
 	}
 } ;
+
+// FCKRuleCommand
+var FCKNbsp = function()
+{
+	this.Name = 'Non Breaking Space' ;
+}
+
+FCKNbsp.prototype =
+{
+	Execute : function()
+	{
+		FCK.InsertHtml( '&nbsp;' ) ;
+	},
+
+	GetState : function()
+	{
+		return ( FCK.EditMode != FCK_EDITMODE_WYSIWYG ? FCK_TRISTATE_DISABLED : FCK_TRISTATE_OFF ) ;
+	}
+} ;
Index: /FCKeditor/branches/features/new_samples/editor/_source/internals/fck.js
===================================================================
--- /FCKeditor/branches/features/new_samples/editor/_source/internals/fck.js	(revision 2266)
+++ /FCKeditor/branches/features/new_samples/editor/_source/internals/fck.js	(revision 2267)
@@ -1102,5 +1102,8 @@
 	{
 		for ( var i = 0 ; i < this.Elements.length ; i++ )
-			this.Elements[i] = this.Elements[i].outerHTML ;
+		{
+			this.Elements[i] = '<div>&nbsp;' + this.Elements[i].outerHTML + '</div>' ;
+			this.Elements[i].isHtml = true ;
+		}
 	},
 
@@ -1110,8 +1113,8 @@
 		for ( var i = 0 ; i < this.Elements.length ; i++ )
 		{
-			if ( typeof( this.Elements[i] ) == 'string' )
+			if ( this.Elements[i].isHtml )
 			{
 				node.innerHTML = this.Elements[i] ;
-				this.Elements[i] = node.firstChild ;
+				this.Elements[i] = node.firstChild.removeChild( node.firstChild.lastChild ) ;
 			}
 		}
Index: /FCKeditor/branches/features/new_samples/editor/_source/internals/fck_gecko.js
===================================================================
--- /FCKeditor/branches/features/new_samples/editor/_source/internals/fck_gecko.js	(revision 2266)
+++ /FCKeditor/branches/features/new_samples/editor/_source/internals/fck_gecko.js	(revision 2267)
@@ -360,9 +360,43 @@
 	FCKUndo.SaveUndoStep() ;
 
-	if ( FCKBrowserInfo.IsGecko )
-	{
+	var fakeNodes = false ;
+	var prevCharNodeValue ;
+	if ( FCKBrowserInfo.IsGecko && /^(?:&nbsp;|&#160;)+$/.test( html ) )
+	{
+		// Get the previous character's text node value, if any.
+		var selection = FCK.EditorWindow.getSelection() ;
+		var range = selection && selection.rangeCount > 0 && selection.getRangeAt( 0 ) ;
+		var startNode, prevCharNode ;
+		if ( range ) 
+		{
+			if ( range.startContainer.nodeType == 1 )
+				startNode = range.startContainer.childNodes[ range.startOffset ] ;
+			else if ( range.startContainer.nodeType == 3 )
+				startNode = range.startContainer ;
+		}
+		if ( startNode )
+		{
+			if ( range.startContainer.nodeType == 1 )
+			{
+				var node = startNode.previousSibling ;
+				while ( node && node.nodeType == 3 && node.length < 1 )
+					node = node.previousSibling ;
+				if ( node && node.nodeType == 3 )
+					prevCharNode = node ;
+			}
+			else
+				prevCharNode = startNode ;
+		}
+		if ( prevCharNode )
+		{
+			prevCharNodeValue = prevCharNode.nodeValue ;
+			if ( range.startContainer.nodeType == 3 )
+				prevCharNodeValue = prevCharNodeValue.substr( 0, range.startOffset ) ;
+		}
+
 		// Using the following trick, &nbsp; present at the beginning and at
 		// the end of the HTML are preserved (#2248).
 		html = '<span id="__fakeFCKRemove1__" style="display:none;">fakeFCKRemove</span>' + html + '<span id="__fakeFCKRemove2__" style="display:none;">fakeFCKRemove</span>' ;
+		fakeNodes = true ;
 	}
 
@@ -370,9 +404,18 @@
 	doc.execCommand( 'inserthtml', false, html ) ;
 
-	if ( FCKBrowserInfo.IsGecko )
-	{
+	if ( fakeNodes )
+	{
+		// Retrieve the text node before the newly inserted text node.
+		// Note that this is a different node to the prevCharNode earlier.
+		var firstNode = doc.getElementById( '__fakeFCKRemove1__' ) ;
+		var textNode = firstNode.previousSibling ;
+
 		// Remove the fake nodes.
-		FCKDomTools.RemoveNode( doc.getElementById('__fakeFCKRemove1__') ) ;
+		FCKDomTools.RemoveNode( firstNode ) ;
 		FCKDomTools.RemoveNode( doc.getElementById('__fakeFCKRemove2__') ) ;
+
+		// Restore the previous character's text node value, if any.
+		if ( prevCharNodeValue && textNode && textNode.nodeType == 3 )
+			textNode.nodeValue = prevCharNodeValue ;
 	}
 
Index: /FCKeditor/branches/features/new_samples/editor/_source/internals/fck_ie.js
===================================================================
--- /FCKeditor/branches/features/new_samples/editor/_source/internals/fck_ie.js	(revision 2266)
+++ /FCKeditor/branches/features/new_samples/editor/_source/internals/fck_ie.js	(revision 2267)
@@ -136,4 +136,6 @@
 
 	this.EditorDocument.attachEvent("ondblclick", Doc_OnDblClick ) ;
+
+	this.EditorDocument.attachEvent("onbeforedeactivate", function(){ FCKSelection.Save( true ) ; } ) ;
 
 	// Catch cursor selection changes.
Index: /FCKeditor/branches/features/new_samples/editor/_source/internals/fckcommands.js
===================================================================
--- /FCKeditor/branches/features/new_samples/editor/_source/internals/fckcommands.js	(revision 2266)
+++ /FCKeditor/branches/features/new_samples/editor/_source/internals/fckcommands.js	(revision 2267)
@@ -81,4 +81,5 @@
 		case 'PageBreak'	: oCommand = new FCKPageBreakCommand() ; break ;
 		case 'Rule'			: oCommand = new FCKRuleCommand() ; break ;
+		case 'Nbsp'			: oCommand = new FCKNbsp() ; break ;
 
 		case 'TextColor'	: oCommand = new FCKTextColorCommand('ForeColor') ; break ;
Index: /FCKeditor/branches/features/new_samples/editor/_source/internals/fckdocumentprocessor.js
===================================================================
--- /FCKeditor/branches/features/new_samples/editor/_source/internals/fckdocumentprocessor.js	(revision 2266)
+++ /FCKeditor/branches/features/new_samples/editor/_source/internals/fckdocumentprocessor.js	(revision 2267)
@@ -143,4 +143,17 @@
 	}
 
+	var processElementsByName = function( elementName, doc )
+	{
+		var aObjects = doc.getElementsByTagName( elementName );
+		for ( var i = aObjects.length - 1 ; i >= 0 ; i-- )
+			processElement( aObjects[i] ) ;
+	}
+
+	var processObjectAndEmbed = function( doc )
+	{
+		processElementsByName( 'object', doc );
+		processElementsByName( 'embed', doc );
+	}
+
 	return FCKTools.Merge( FCKDocumentProcessor.AppendNew(),
 		       {
@@ -149,16 +162,8 @@
 					// Firefox 3 would sometimes throw an unknown exception while accessing EMBEDs and OBJECTs
 					// without the setTimeout().
-					FCKTools.RunFunction( function()
-						{
-							// Process OBJECTs first, since EMBEDs can sometimes go inside OBJECTS (e.g. Flash).
-							var aObjects = doc.getElementsByTagName( 'object' );
-							for ( var i = aObjects.length - 1 ; i >= 0 ; i-- )
-								processElement( aObjects[i] ) ;
-
-							// Now process any EMBEDs left.
-							var aEmbeds = doc.getElementsByTagName( 'embed' ) ;
-							for ( var i = aEmbeds.length - 1 ; i >= 0 ; i-- )
-								processElement( aEmbeds[i] ) ;
-						} ) ;
+					if ( FCKBrowserInfo.IsGecko )
+						FCKTools.RunFunction( processObjectAndEmbed, this, [ doc ] ) ;
+					else
+						processObjectAndEmbed( doc ) ;
 				},
 
Index: /FCKeditor/branches/features/new_samples/editor/_source/internals/fckselection_ie.js
===================================================================
--- /FCKeditor/branches/features/new_samples/editor/_source/internals/fckselection_ie.js	(revision 2266)
+++ /FCKeditor/branches/features/new_samples/editor/_source/internals/fckselection_ie.js	(revision 2267)
@@ -210,8 +210,9 @@
 }
 
-FCKSelection.Save = function()
+FCKSelection.Save = function( noFocus )
 {
 	// Ensures the editor has the selection focus. (#1801)
-	FCK.Focus() ;
+	if ( !noFocus )
+		FCK.Focus() ;
 
 	var editorDocument = FCK.EditorDocument ;
Index: /FCKeditor/branches/features/new_samples/fckconfig.js
===================================================================
--- /FCKeditor/branches/features/new_samples/fckconfig.js	(revision 2266)
+++ /FCKeditor/branches/features/new_samples/fckconfig.js	(revision 2267)
@@ -143,5 +143,6 @@
 	[ CTRL + 85 /*U*/, 'Underline' ],
 	[ CTRL + SHIFT + 83 /*S*/, 'Save' ],
-	[ CTRL + ALT + 13 /*ENTER*/, 'FitWindow' ]
+	[ CTRL + ALT + 13 /*ENTER*/, 'FitWindow' ],
+	[ SHIFT + 32 /*SPACE*/, 'Nbsp' ]
 ] ;
 
