Index: FCKeditor/trunk/_whatsnew.html
===================================================================
--- FCKeditor/trunk/_whatsnew.html	(revision 2276)
+++ FCKeditor/trunk/_whatsnew.html	(revision 2279)
@@ -49,4 +49,6 @@
 		<li>[<a target="_blank" href="http://dev.fckeditor.net/ticket/2032">#2032</a>] Added HTML samples
 			for legacy HTML and Flash-embedded HTML code.</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>
Index: FCKeditor/trunk/editor/_source/classes/fckdocumentfragment_gecko.js
===================================================================
--- FCKeditor/trunk/editor/_source/classes/fckdocumentfragment_gecko.js	(revision 2276)
+++ FCKeditor/trunk/editor/_source/classes/fckdocumentfragment_gecko.js	(revision 2279)
@@ -41,4 +41,11 @@
 	},
 
+	AppendHtml : function( html )
+	{
+		var eTmpDiv = this.RootNode.ownerDocument.createElement( 'div' ) ;
+		eTmpDiv.innerHTML = html ;
+		FCKDomTools.MoveChildren( eTmpDiv, this.RootNode ) ;
+	},
+
 	InsertAfterNode : function( existingNode )
 	{
Index: FCKeditor/trunk/editor/_source/commandclasses/fck_othercommands.js
===================================================================
--- FCKeditor/trunk/editor/_source/commandclasses/fck_othercommands.js	(revision 2276)
+++ FCKeditor/trunk/editor/_source/commandclasses/fck_othercommands.js	(revision 2279)
@@ -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/trunk/editor/_source/internals/fck_gecko.js
===================================================================
--- FCKeditor/trunk/editor/_source/internals/fck_gecko.js	(revision 2276)
+++ FCKeditor/trunk/editor/_source/internals/fck_gecko.js	(revision 2279)
@@ -350,5 +350,6 @@
 FCK.InsertHtml = function( html )
 {
-	var doc = FCK.EditorDocument ;
+	var doc = FCK.EditorDocument,
+		range;
 
 	html = FCKConfig.ProtectedSource.Protect( html ) ;
@@ -362,24 +363,28 @@
 	if ( FCKBrowserInfo.IsGecko )
 	{
-		// 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>' ;
-	}
-
-	// Insert the HTML code.
-	doc.execCommand( 'inserthtml', false, html ) ;
-
-	if ( FCKBrowserInfo.IsGecko )
-	{
-		// Remove the fake nodes.
-		FCKDomTools.RemoveNode( doc.getElementById('__fakeFCKRemove1__') ) ;
-		FCKDomTools.RemoveNode( doc.getElementById('__fakeFCKRemove2__') ) ;
-	}
+		html = html.replace( /&nbsp;$/, '$&<span _fcktemp="1"/>' ) ;
+
+		var docFrag = new FCKDocumentFragment( this.EditorDocument ) ;
+		docFrag.AppendHtml( html ) ;
+
+		var lastNode = docFrag.RootNode.lastChild ;
+
+		range = new FCKDomRange( this.EditorWindow ) ;
+		range.MoveToSelection() ;
+		range.InsertNode( docFrag.RootNode ) ;
+
+		range.MoveToPosition( lastNode, 4 ) ;
+	}
+	else
+		doc.execCommand( 'inserthtml', false, html ) ;
 
 	this.Focus() ;
 
 	// Save the caret position before calling document processor.
-	var range = new FCKDomRange( this.EditorWindow ) ;
-	range.MoveToSelection() ;
+	if ( !range )
+	{
+		range = new FCKDomRange( this.EditorWindow ) ;
+		range.MoveToSelection() ;
+	}
 	var bookmark = range.CreateBookmark() ;
 
Index: FCKeditor/trunk/editor/_source/internals/fckcommands.js
===================================================================
--- FCKeditor/trunk/editor/_source/internals/fckcommands.js	(revision 2276)
+++ FCKeditor/trunk/editor/_source/internals/fckcommands.js	(revision 2279)
@@ -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/trunk/fckconfig.js
===================================================================
--- FCKeditor/trunk/fckconfig.js	(revision 2276)
+++ FCKeditor/trunk/fckconfig.js	(revision 2279)
@@ -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' ]
 ] ;
 
