Index: /CKEditor/tests/tt/4445/1.html
===================================================================
--- /CKEditor/tests/tt/4445/1.html	(revision 4353)
+++ /CKEditor/tests/tt/4445/1.html	(revision 4354)
@@ -4,5 +4,5 @@
 <head>
 	<title>Ticket: #4445</title>
-	<meta name="tags" content="editor,unit,all">
+	<meta name="tags" content="editor,unit,stable">
 	<script type="text/javascript" src="../../cktester/cell.js"></script>
 	<script>
@@ -38,5 +38,8 @@
 				} );
 				editor.focus();
-				tc.wait();
+				tc.wait( function()
+				{
+					tc.fail( 'callback is not invoked.' );
+				}, 2000 );
 			}
 		} ) );
Index: /CKEditor/tests/tt/4445/2.html
===================================================================
--- /CKEditor/tests/tt/4445/2.html	(revision 4353)
+++ /CKEditor/tests/tt/4445/2.html	(revision 4354)
@@ -4,5 +4,5 @@
 <head>
 	<title>Ticket: #4445</title>
-	<meta name="tags" content="editor,unit,all">
+	<meta name="tags" content="editor,unit,stable">
 	<script type="text/javascript" src="../../cktester/cell.js"></script>
 	<script>
@@ -27,13 +27,15 @@
 			test_setData_callback_source : function()
 			{
-				var editor = ts.editor;
+				var editor = ts.editor, callbackPassed = false;
 				editor.setData( contentToLoad, function()
 				{
-					tc.resume( function()
-					{
-						assert.isTrue( editor.checkDirty(), "editor shouldn be dirty." );
-						assert.areSame( contentToLoad, editor.getData(), "editor content doesn't match." );
-					} );
+					var thisEditor = this;
+					assert.areEqual( editor, thisEditor, 'editor instance doesn\'t match.' );
+					assert.isTrue( editor.checkDirty(), "editor shouldn be dirty." );
+					assert.areSame( contentToLoad, editor.getData(), "editor content doesn't match." );
+					callbackPassed = true;
 				} );
+				if( !callbackPassed )
+					assert.fail( 'callback is not invoked.' );
 			}
 		} ) );
Index: /CKEditor/trunk/CHANGES.html
===================================================================
--- /CKEditor/trunk/CHANGES.html	(revision 4353)
+++ /CKEditor/trunk/CHANGES.html	(revision 4354)
@@ -89,4 +89,5 @@
 	<li><a href="http://dev.fckeditor.net/ticket/3188">#3188</a> : Introduce
 		&lt;pre&gt; formatting feature when converting from other blocks.</li>
+	<li><a href="http://dev.fckeditor.net/ticket/4445">#4445</a> : editor::setData now support an optional callback parameter.</li>
 	</ul>
 	<p>
Index: /CKEditor/trunk/_source/core/editor.js
===================================================================
--- /CKEditor/trunk/_source/core/editor.js	(revision 4353)
+++ /CKEditor/trunk/_source/core/editor.js	(revision 4354)
@@ -575,9 +575,22 @@
 		 * Sets the editor data. The data must be provided in raw format.
 		 * @param {String} data HTML code to replace the curent content in the editor.
+		 * @param {Function} callback Function to be called after the setData is completed. 
 		 * @example
 		 * CKEDITOR.instances.editor1.<b>setData( '&lt;p&gt;This is the editor data.&lt;/p&gt;' )</b>;
-		 */
-		setData : function( data )
-		{
+		 * CKEDITOR.instances.editor1.setData( '&lt;p&gt;Some other editor data.&lt;/p&gt;', function()
+		 * {
+		 * 		CKEDITOR.instances.editor1.checkDirty(); 	// true
+		 * } );
+		 */
+		setData : function( data , callback )
+		{
+			if( callback )
+			{
+				this.on( 'dataReady', function( evt )
+				{
+					evt.removeListener();
+					callback.call( evt.editor );
+				} );
+			}
 			// Fire "setData" so data manipulation may happen.
 			var eventData = { dataValue : data };
Index: /CKEditor/trunk/_source/plugins/newpage/plugin.js
===================================================================
--- /CKEditor/trunk/_source/plugins/newpage/plugin.js	(revision 4353)
+++ /CKEditor/trunk/_source/plugins/newpage/plugin.js	(revision 4354)
@@ -20,29 +20,13 @@
 				{
 					var command = this;
-					function afterCommand()
+					editor.setData( editor.config.newpage_html, function()
 					{
-						// Defer to happen after 'selectionChange'.
-						setTimeout( function()
+						editor.fire( 'afterCommandExec',
 						{
-							editor.fire( 'afterCommandExec',
-							{
-								name: command.name,
-								command: command
-							} );
-						}, 500 );
-					}
-					if ( editor.mode == 'wysiwyg')
-						editor.on( 'contentDom', function( evt ){
-
-							evt.removeListener();
-	                        afterCommand();
+							name: command.name,
+							command: command
 						} );
-
-					editor.setData( editor.config.newpage_html );
+					} );
 					editor.focus();
-
-					if( editor.mode == 'source' )
-						afterCommand();
-
 				},
 				async : true
Index: /CKEditor/trunk/_source/plugins/sourcearea/plugin.js
===================================================================
--- /CKEditor/trunk/_source/plugins/sourcearea/plugin.js	(revision 4353)
+++ /CKEditor/trunk/_source/plugins/sourcearea/plugin.js	(revision 4354)
@@ -122,4 +122,5 @@
 						{
 							textarea.setValue( data );
+							editor.fire( 'dataReady' );
 						},
 
Index: /CKEditor/trunk/_source/plugins/wysiwygarea/plugin.js
===================================================================
--- /CKEditor/trunk/_source/plugins/wysiwygarea/plugin.js	(revision 4353)
+++ /CKEditor/trunk/_source/plugins/wysiwygarea/plugin.js	(revision 4354)
@@ -497,4 +497,8 @@
 									isPendingFocus = false;
 								}
+								setTimeout( function()
+								{
+									editor.fire( 'dataReady' );
+								}, 0 );
 
 								/*
