Index: /CKEditor/branches/versions/3.5.x/CHANGES.html
===================================================================
--- /CKEditor/branches/versions/3.5.x/CHANGES.html	(revision 6177)
+++ /CKEditor/branches/versions/3.5.x/CHANGES.html	(revision 6178)
@@ -40,4 +40,5 @@
 			New features:</p>
 	<ul>
+		<li><a href="http://dev.ckeditor.com/ticket/4090">#4090</a> : Full Adobe AIR support.</li>
 		<li><a href="http://dev.ckeditor.com/ticket/5755">#5755</a> : Introduced the <a href="http://docs.cksource.com/ckeditor_api/symbols/CKEDITOR.config.html#.dialog_buttonsOrder">dialog_buttonsOrder</a> setting, making it possible to control the buttons order.</li>
 		<li><a href="http://dev.ckeditor.com/ticket/4648">#4648</a> : Added the new Iframe plugin.</li>
Index: /CKEditor/branches/versions/3.5.x/_samples/adobeair/application.xml
===================================================================
--- /CKEditor/branches/versions/3.5.x/_samples/adobeair/application.xml	(revision 6178)
+++ /CKEditor/branches/versions/3.5.x/_samples/adobeair/application.xml	(revision 6178)
@@ -0,0 +1,32 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<!--
+Copyright (c) 2003-2010, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.html or http://ckeditor.com/license
+-->
+<application xmlns="http://ns.adobe.com/air/application/1.0">
+	<id>com.ckeditor.air.sample</id>
+	<name>CKEditor - Adobe AIR Sample Application</name>
+	<version>1.0</version>
+	<filename>CKEditor AIR Samples</filename>
+	<description>This is a sample AIR application of CKEditor.</description>
+	<copyright>Copyright (c) 2003-2010, CKSource - Frederico Knabben. All rights reserved.</copyright>
+	<initialWindow>
+		<content>_samples/skins.html</content>
+		<title>CKEditor - Adobe AIR Sample</title>
+		<systemChrome>standard</systemChrome>
+		<transparent>false</transparent>
+		<visible>true</visible>
+		<minimizable>true</minimizable>
+		<maximizable>true</maximizable>
+		<resizable>true</resizable>
+		<x>100</x>
+		<y>80</y>
+		<width>950</width>
+		<height>700</height>
+		<minSize>900 600</minSize>
+	</initialWindow>
+	<installFolder>CKEditor/Sample AIR Application</installFolder>
+	<programMenuFolder>CKEditor/Sample AIR Application</programMenuFolder>
+	<customUpdateUI>false</customUpdateUI>
+	<allowBrowserInvocation>false</allowBrowserInvocation>
+</application>
Index: /CKEditor/branches/versions/3.5.x/_samples/adobeair/run.bat
===================================================================
--- /CKEditor/branches/versions/3.5.x/_samples/adobeair/run.bat	(revision 6178)
+++ /CKEditor/branches/versions/3.5.x/_samples/adobeair/run.bat	(revision 6178)
@@ -0,0 +1,12 @@
+@ECHO OFF
+::
+:: Copyright (c) 2003-2010, CKSource - Frederico Knabben. All rights reserved.
+:: For licensing, see LICENSE.html or http://ckeditor.com/license
+::
+:: Use this file to quickly run the sample in a Windows environment.
+::
+:: Be sure to change the following directory path so it matches your AIR SDK
+:: installation path.
+::
+
+D:/AdobeAIRSDK/bin/adl application.xml ../../
Index: /CKEditor/branches/versions/3.5.x/_samples/adobeair/sample.html
===================================================================
--- /CKEditor/branches/versions/3.5.x/_samples/adobeair/sample.html	(revision 6178)
+++ /CKEditor/branches/versions/3.5.x/_samples/adobeair/sample.html	(revision 6178)
@@ -0,0 +1,51 @@
+﻿<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<!--
+Copyright (c) 2003-2010, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.html or http://ckeditor.com/license
+-->
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+	<title>Replace Textarea by Code - CKEditor Sample</title>
+	<meta content="text/html; charset=utf-8" http-equiv="content-type" />
+	<script type="text/javascript" src="../../_dev/adobeair/AIRAliases.js"></script>
+	<script type="text/javascript" src="../../_dev/adobeair/AIRIntrospector.js"></script>
+	<!-- CKReleaser %REMOVE_LINE%
+	<script type="text/javascript" src="../../ckeditor.js"></script>
+	CKReleaser %REMOVE_START% -->
+	<script type="text/javascript" src="../../ckeditor_source.js"></script>
+	<!-- CKReleaser %REMOVE_END% -->
+	<link href="../sample.css" rel="stylesheet" type="text/css" />
+	<style type="text/css">
+		body { margin: 10px ; }
+	</style></head>
+<body>
+	<h1>
+		CKEditor - Adobe AIR Sample
+	</h1>
+	<p>
+		This is a sample HTML/JavaScript Adobe AIR application with CKEditor with default features.
+	</p>
+	<p>
+		<textarea cols="80" id="editor1" name="editor1" rows="10">&lt;p&gt;This is some &lt;strong&gt;sample text&lt;/strong&gt;. You are using &lt;a href="http://ckeditor.com/"&gt;CKEditor&lt;/a&gt;.&lt;/p&gt;</textarea>
+		<script type="text/javascript">
+		//<![CDATA[
+
+			// Replace the <textarea id="editor"> with an CKEditor
+			// instance, using default configurations.
+			CKEDITOR.replace( 'editor1' );
+
+		//]]>
+		</script>
+	</p>
+	<div id="footer" style="position:absolute;bottom:0;left:0;right:0;width:100%;padding-bottom:10px;">
+		<hr />
+		<p>
+			CKEditor - The text editor for Internet - <a href="#" onclick="window.runtime.flash.net.navigateToURL(new window.runtime.flash.net.URLRequest('http://ckeditor.com/'));return false;">http://ckeditor.com</a>
+		</p>
+		<p id="copy">
+			Copyright &copy; 2003-2010, <a href="#" onclick="window.runtime.flash.net.navigateToURL(new window.runtime.flash.net.URLRequest('http://cksource.com/'));return false;">CKSource</a> - Frederico
+			Knabben. All rights reserved.
+		</p>
+	</div>
+</body>
+</html>
Index: /CKEditor/branches/versions/3.5.x/_source/core/ckeditor_base.js
===================================================================
--- /CKEditor/branches/versions/3.5.x/_source/core/ckeditor_base.js	(revision 6177)
+++ /CKEditor/branches/versions/3.5.x/_source/core/ckeditor_base.js	(revision 6178)
@@ -13,5 +13,5 @@
 // ckeditor_source.js and ckeditor_basic_source.js files.
 
-// if(!window.CKEDITOR)window.CKEDITOR=(function(){var a={timestamp:'',version:'%VERSION%',rev:'%REV%',_:{},status:'unloaded',basePath:(function(){var d=window.CKEDITOR_BASEPATH||'';if(!d){var e=document.getElementsByTagName('script');for(var f=0;f<e.length;f++){var g=e[f].src.match(/(^|.*[\\\/])ckeditor(?:_basic)?(?:_source)?.js(?:\?.*)?$/i);if(g){d=g[1];break;}}}if(d.indexOf('://')==-1)if(d.indexOf('/')===0)d=location.href.match(/^.*?:\/\/[^\/]*/)[0]+d;else d=location.href.match(/^[^\?]*\/(?:)/)[0]+d;return d;})(),getUrl:function(d){if(d.indexOf('://')==-1&&d.indexOf('/')!==0)d=this.basePath+d;if(this.timestamp&&d.charAt(d.length-1)!='/')d+=(d.indexOf('?')>=0?'&':'?')+('t=')+this.timestamp;return d;}},b=window.CKEDITOR_GETURL;if(b){var c=a.getUrl;a.getUrl=function(d){return b.call(a,d)||c.call(a,d);};}return a;})();
+// if(!window.CKEDITOR)window.CKEDITOR=(function(){var a={timestamp:'',version:'%VERSION%',rev:'%REV%',_:{},status:'unloaded',basePath:(function(){var d=window.CKEDITOR_BASEPATH||'';if(!d){var e=document.getElementsByTagName('script');for(var f=0;f<e.length;f++){var g=e[f].src.match(/(^|.*[\\\/])ckeditor(?:_basic)?(?:_source)?.js(?:\?.*)?$/i);if(g){d=g[1];break;}}}if(d.indexOf(':/')==-1)if(d.indexOf('/')===0)d=location.href.match(/^.*?:\/\/[^\/]*/)[0]+d;else d=location.href.match(/^[^\?]*\/(?:)/)[0]+d;return d;})(),getUrl:function(d){if(d.indexOf(':/')==-1&&d.indexOf('/')!==0)d=this.basePath+d;if(this.timestamp&&d.charAt(d.length-1)!='/')d+=(d.indexOf('?')>=0?'&':'?')+('t=')+this.timestamp;return d;}},b=window.CKEDITOR_GETURL;if(b){var c=a.getUrl;a.getUrl=function(d){return b.call(a,d)||c.call(a,d);};}return a;})();
 
 // #### Raw code
@@ -127,5 +127,5 @@
 				// In IE (only) the script.src string is the raw valued entered in the
 				// HTML. Other browsers return the full resolved URL instead.
-				if ( path.indexOf('://') == -1 )
+				if ( path.indexOf(':/') == -1 )
 				{
 					// Absolute path.
@@ -169,5 +169,5 @@
 			{
 				// If this is not a full or absolute path.
-				if ( resource.indexOf('://') == -1 && resource.indexOf( '/' ) !== 0 )
+				if ( resource.indexOf(':/') == -1 && resource.indexOf( '/' ) !== 0 )
 					resource = this.basePath + resource;
 
Index: /CKEditor/branches/versions/3.5.x/_source/core/dom/document.js
===================================================================
--- /CKEditor/branches/versions/3.5.x/_source/core/dom/document.js	(revision 6177)
+++ /CKEditor/branches/versions/3.5.x/_source/core/dom/document.js	(revision 6178)
@@ -166,4 +166,7 @@
 		{
 			var head = this.$.getElementsByTagName( 'head' )[0];
+			if ( !head )
+				head = this.getDocumentElement().append( new CKEDITOR.dom.element( 'head' ), true );
+			else
 			head = new CKEDITOR.dom.element( head );
 
@@ -221,4 +224,28 @@
 					return win;
 				})();
+		},
+
+		/**
+		 * Defines the document contents through document.write. Note that the
+		 * previous document contents will be lost (cleaned).
+		 * @since 3.5
+		 * @param {String} html The HTML defining the document contents.
+		 * @example
+		 * document.write(
+		 *     '&lt;html&gt;' +
+		 *         '&lt;head&gt;&lt;title&gt;Sample Doc&lt;/title&gt;&lt;/head&gt;' +
+		 *         '&lt;body&gt;Document contents created by code&lt;/body&gt;' +
+		 *      '&lt;/html&gt;' );
+		 */
+		write : function( html )
+		{
+			// Don't leave any history log in IE. (#5657)
+			this.$.open( 'text/html', 'replace' );
+
+			// Support for custom document.domain in IE.
+			CKEDITOR.env.isCustomDomain() &&  ( this.$.domain = document.domain );
+
+			this.$.write( html );
+			this.$.close();
 		}
 	});
Index: /CKEditor/branches/versions/3.5.x/_source/core/dom/element.js
===================================================================
--- /CKEditor/branches/versions/3.5.x/_source/core/dom/element.js	(revision 6177)
+++ /CKEditor/branches/versions/3.5.x/_source/core/dom/element.js	(revision 6178)
@@ -308,10 +308,14 @@
 		/**
 		 * Moves the selection focus to this element.
+		 * @param  {Boolean} defer Whether to asynchronously defer the
+		 * 		execution by 100 ms.
 		 * @example
 		 * var element = CKEDITOR.document.getById( 'myTextarea' );
 		 * <b>element.focus()</b>;
 		 */
-		focus : function()
-		{
+		focus : (function()
+		{
+			function exec()
+			{
 			// IE throws error if the element is not visible.
 			try
@@ -321,5 +325,14 @@
 			catch (e)
 			{}
-		},
+			}
+
+			return function( defer )
+			{
+				if ( defer )
+					CKEDITOR.tools.setTimeout( exec, 100, this );
+				else
+					exec.call( this );
+			}
+		}()),
 
 		/**
Index: /CKEditor/branches/versions/3.5.x/_source/core/dom/node.js
===================================================================
--- /CKEditor/branches/versions/3.5.x/_source/core/dom/node.js	(revision 6177)
+++ /CKEditor/branches/versions/3.5.x/_source/core/dom/node.js	(revision 6178)
@@ -245,11 +245,5 @@
 		getDocument : function()
 		{
-			var document = new CKEDITOR.dom.document( this.$.ownerDocument || this.$.parentNode.ownerDocument );
-
-			return (
-			this.getDocument = function()
-				{
-					return document;
-				})();
+			return new CKEDITOR.dom.document( this.$.ownerDocument || this.$.parentNode.ownerDocument );
 		},
 
Index: /CKEditor/branches/versions/3.5.x/_source/core/editor.js
===================================================================
--- /CKEditor/branches/versions/3.5.x/_source/core/editor.js	(revision 6177)
+++ /CKEditor/branches/versions/3.5.x/_source/core/editor.js	(revision 6178)
@@ -228,4 +228,7 @@
 		}
 
+		// Load the Adobe AIR plugin conditionally.
+		CKEDITOR.env.air && ( plugins += ',adobeair' );
+
 		// Load all plugins defined in the "plugins" setting.
 		CKEDITOR.plugins.load( plugins.split( ',' ), function( plugins )
Index: /CKEditor/branches/versions/3.5.x/_source/core/tools.js
===================================================================
--- /CKEditor/branches/versions/3.5.x/_source/core/tools.js	(revision 6177)
+++ /CKEditor/branches/versions/3.5.x/_source/core/tools.js	(revision 6178)
@@ -639,5 +639,5 @@
 			return functions.push( function()
 				{
-					fn.apply( scope || this, arguments );
+					return fn.apply( scope || this, arguments );
 				}) - 1;
 		},
Index: /CKEditor/branches/versions/3.5.x/_source/core/ui.js
===================================================================
--- /CKEditor/branches/versions/3.5.x/_source/core/ui.js	(revision 6177)
+++ /CKEditor/branches/versions/3.5.x/_source/core/ui.js	(revision 6178)
@@ -92,4 +92,6 @@
 };
 
+CKEDITOR.event.implementOn( CKEDITOR.ui );
+
 /**
  * (Virtual Class) Do not call this constructor. This class is not really part
Index: /CKEditor/branches/versions/3.5.x/_source/plugins/adobeair/plugin.js
===================================================================
--- /CKEditor/branches/versions/3.5.x/_source/plugins/adobeair/plugin.js	(revision 6178)
+++ /CKEditor/branches/versions/3.5.x/_source/plugins/adobeair/plugin.js	(revision 6178)
@@ -0,0 +1,227 @@
+/*
+Copyright (c) 2003-2010, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.html or http://ckeditor.com/license
+*/
+
+(function()
+{
+	var eventNameList = [ 'click', 'keydown', 'mousedown', 'keypress' ];
+
+	// Inline event callbacks assigned via innerHTML/outerHTML, such as
+	// onclick/onmouseover, are ignored in AIR.
+	// Use DOM2 event listeners to substitue inline handlers instead.
+	function convertInlineHandlers( container )
+	{
+		// TODO: document.querySelectorAll is not supported in AIR.
+		var children = container.getElementsByTag( '*' ),
+			count = children.count(),
+			child;
+
+		for ( var i = 0; i < count; i++ )
+		{
+			child = children.getItem( i );
+
+			(function( node )
+			{
+				for ( var j = 0; j < eventNameList.length; j++ )
+				{
+					(function( eventName )
+					{
+						if ( node.hasAttribute( 'on' + eventName ) )
+						{
+							node.on( eventName, function( evt )
+							{
+								var inlineEventHandler = node.getAttribute( 'on' + eventName ),
+									callFunc = /(return\s*)?CKEDITOR\.tools\.callFunction\(([^)]+)\)/.exec( inlineEventHandler ),
+									hasReturn = callFunc && callFunc[ 1 ],
+									callFuncArgs = callFunc &&  callFunc[ 2 ].split( ',' ),
+									preventDefault = /return false;/.test( inlineEventHandler );
+
+								if ( callFuncArgs )
+								{
+									var nums = callFuncArgs.length,
+										argName;
+
+									for ( var i = 0; i < nums; i++ )
+									{
+										// Trim spaces around param.
+										callFuncArgs[ i ] = argName = CKEDITOR.tools.trim( callFuncArgs[ i ] );
+
+										// String form param.
+										var strPattern = argName.match( /^(["'])([^"']*?)\1$/ );
+										if ( strPattern )
+										{
+											callFuncArgs[ i ] = strPattern[ 2 ];
+											continue;
+										}
+
+										// Integer form param.
+										if ( argName.match( /\d+/ ) )
+										{
+											callFuncArgs[ i ] = parseInt( argName, 10 );
+											continue;
+										}
+
+										// Speical variables.
+										switch( argName )
+										{
+											case 'this' :
+												callFuncArgs[ i ] = node.$;
+												break;
+											case 'event' :
+												callFuncArgs[ i ] = evt.data.$;
+												break;
+											case 'null' :
+												callFuncArgs [ i ] = null;
+												break;
+										}
+									}
+
+									var retval = CKEDITOR.tools.callFunction.apply( window, callFuncArgs );
+									if ( hasReturn && retval === false )
+										 preventDefault = 1;
+								}
+
+								if ( preventDefault )
+									evt.data.preventDefault();
+							});
+						}
+					})( eventNameList[ j ] );
+				}
+			})( child );
+		}
+	}
+
+	CKEDITOR.plugins.add( 'adobeair',
+	{
+		init : function( editor )
+		{
+			if ( !CKEDITOR.env.air )
+				return;
+
+			// Body doesn't get default margin on AIR.
+			editor.addCss( 'body { padding: 8px }' );
+
+			editor.on( 'uiReady', function()
+				{
+					convertInlineHandlers( editor.container );
+
+					if ( editor.sharedSpaces )
+					{
+						for ( var space in editor.sharedSpaces )
+							convertInlineHandlers( editor.sharedSpaces[ space ] );
+					}
+
+					editor.on( 'elementsPathUpdate', function( evt ) { convertInlineHandlers( evt.data.space ); } );
+				});
+
+			editor.on( 'contentDom', function()
+				{
+					// Hyperlinks are enabled in editable documents in Adobe
+					// AIR. Prevent their click behavior.
+					editor.document.on( 'click', function( ev )
+						{
+							ev.data.preventDefault( true );
+						});
+				});
+		}
+	});
+
+	CKEDITOR.ui.on( 'ready', function( evt )
+		{
+			var ui = evt.data;
+			// richcombo, panelbutton and menu
+			if ( ui._.panel )
+			{
+				var panel = ui._.panel._.panel,
+						holder;
+
+				( function()
+				{
+					// Adding dom event listeners off-line are not supported in AIR,
+					// waiting for panel iframe loaded.
+					if ( !panel.isLoaded )
+					{
+						setTimeout( arguments.callee, 30 );
+						return;
+					}
+					holder = panel._.holder;
+					convertInlineHandlers( holder );
+				})();
+			}
+			else if ( ui instanceof CKEDITOR.dialog )
+				convertInlineHandlers( ui._.element );
+		});
+})();
+
+CKEDITOR.dom.document.prototype.write = CKEDITOR.tools.override( CKEDITOR.dom.document.prototype.write,
+	function( original_write )
+	{
+		function appendElement( parent, tagName, fullTag, text )
+		{
+			var node = parent.append( tagName ),
+				attrs = CKEDITOR.htmlParser.fragment.fromHtml( fullTag ).children[ 0 ].attributes;
+			attrs && node.setAttributes( attrs );
+			text && node.append( parent.getDocument().createText( text ) );
+		}
+
+		return function( html, mode )
+			{
+				// document.write() or document.writeln() fail silently after
+				// the page load event in Adobe AIR.
+				// DOM manipulation could be used instead.
+				if ( this.getBody() )
+				{
+					// We're taking the below extra work only because innerHTML
+					// on <html> element doesn't work as expected.
+					var doc = this,
+						head = this.getHead();
+
+					// Create style nodes for inline css. ( <style> content doesn't applied when setting via innerHTML )
+					html = html.replace( /(<style[^>]*>)([\s\S]*?)<\/style>/gi,
+						function ( match, startTag, styleText )
+						{
+							appendElement( head, 'style', startTag, styleText );
+							return '';
+						});
+
+					html = html.replace( /<base\b[^>]*\/>/i,
+						function( match )
+						{
+							appendElement( head, 'base', match );
+							return '';
+						});
+
+					html = html.replace( /<title>([\s\S]*)<\/title>/i,
+						function( match, title )
+						{
+							doc.$.title = title;
+							return '';
+						});
+
+					// Move the rest of head stuff.
+					html = html.replace( /<head>([\s\S]*)<\/head>/i,
+						function( headHtml )
+						{
+							// Inject the <head> HTML inside a <div>.
+							// Do that before getDocumentHead because WebKit moves
+							// <link css> elements to the <head> at this point.
+							var div = new CKEDITOR.dom.element( 'div', doc );
+							div.setHtml( headHtml );
+							// Move the <div> nodes to <head>.
+							div.moveChildren( head );
+							return '';
+						});
+
+					html.replace( /(<body[^>]*>)([\s\S]*)(?=$|<\/body>)/i,
+						function( match, startTag, innerHTML )
+						{
+							doc.getBody().setHtml( innerHTML );
+							var attrs = CKEDITOR.htmlParser.fragment.fromHtml( startTag ).children[ 0 ].attributes;
+							attrs && doc.getBody().setAttributes( attrs );
+						});
+				}
+				else
+					original_write.apply( this, arguments );
+			};
+	});
Index: /CKEditor/branches/versions/3.5.x/_source/plugins/button/plugin.js
===================================================================
--- /CKEditor/branches/versions/3.5.x/_source/plugins/button/plugin.js	(revision 6177)
+++ /CKEditor/branches/versions/3.5.x/_source/plugins/button/plugin.js	(revision 6178)
@@ -55,4 +55,43 @@
 	}
 };
+
+/**
+ * Handles a button click.
+ * @private
+ */
+CKEDITOR.ui.button._ =
+{
+	instances : [],
+
+	keydown : function( index, ev )
+	{
+		var instance = CKEDITOR.ui.button._.instances[ index ];
+
+		if ( instance.onkey )
+		{
+			ev = new CKEDITOR.dom.event( ev );
+			return ( instance.onkey( instance, ev.getKeystroke() ) !== false );
+		}
+	},
+
+	focus : function( index, ev )
+	{
+		var instance = CKEDITOR.ui.button._.instances[ index ],
+			retVal;
+
+		if ( instance.onfocus )
+			retVal = ( instance.onfocus( instance, new CKEDITOR.dom.event( ev ) ) !== false );
+
+		// FF2: prevent focus event been bubbled up to editor container, which caused unexpected editor focus.
+		if ( CKEDITOR.env.gecko && CKEDITOR.env.version < 10900 )
+			ev.preventBubble();
+		return retVal;
+	}
+};
+
+( function()
+{
+	var keydownFn = CKEDITOR.tools.addFunction( CKEDITOR.ui.button._.keydown, CKEDITOR.ui.button._ ),
+		focusFn = CKEDITOR.tools.addFunction( CKEDITOR.ui.button._.focus, CKEDITOR.ui.button._ );
 
 CKEDITOR.ui.button.prototype =
@@ -161,6 +200,6 @@
 
 		output.push(
-				' onkeydown="return CKEDITOR.ui.button._.keydown(', index, ', event);"' +
-				' onfocus="return CKEDITOR.ui.button._.focus(', index, ', event);"' +
+					' onkeydown="return CKEDITOR.tools.callFunction(', keydownFn, ', ', index, ', event);"' +
+					' onfocus="return CKEDITOR.tools.callFunction(', focusFn,', ', index, ', event);"' +
 				' onclick="CKEDITOR.tools.callFunction(', clickFn, ', this); return false;">' +
 					'<span class="cke_icon"' );
@@ -222,37 +261,5 @@
 };
 
-/**
- * Handles a button click.
- * @private
- */
-CKEDITOR.ui.button._ =
-{
-	instances : [],
-
-	keydown : function( index, ev )
-	{
-		var instance = CKEDITOR.ui.button._.instances[ index ];
-
-		if ( instance.onkey )
-		{
-			ev = new CKEDITOR.dom.event( ev );
-			return ( instance.onkey( instance, ev.getKeystroke() ) !== false );
-		}
-	},
-
-	focus : function( index, ev )
-	{
-		var instance = CKEDITOR.ui.button._.instances[ index ],
-			retVal;
-
-		if ( instance.onfocus )
-			retVal = ( instance.onfocus( instance, new CKEDITOR.dom.event( ev ) ) !== false );
-
-		// FF2: prevent focus event been bubbled up to editor container, which caused unexpected editor focus.
-		if ( CKEDITOR.env.gecko && CKEDITOR.env.version < 10900 )
-			ev.preventBubble();
-		return retVal;
-	}
-};
+})();
 
 /**
Index: /CKEditor/branches/versions/3.5.x/_source/plugins/clipboard/dialogs/paste.js
===================================================================
--- /CKEditor/branches/versions/3.5.x/_source/plugins/clipboard/dialogs/paste.js	(revision 6177)
+++ /CKEditor/branches/versions/3.5.x/_source/plugins/clipboard/dialogs/paste.js	(revision 6178)
@@ -1,3 +1,3 @@
-﻿/*
+/*
 Copyright (c) 2003-2010, CKSource - Frederico Knabben. All rights reserved.
 For licensing, see LICENSE.html or http://ckeditor.com/license
@@ -14,5 +14,6 @@
 			docElement = doc.$;
 
-		doc.getById( 'cke_actscrpt' ).remove();
+		var script = doc.getById( 'cke_actscrpt' );
+		script && script.remove();
 
 		CKEDITOR.env.ie ?
@@ -75,4 +76,16 @@
 				'</html>';
 
+			var src =
+				CKEDITOR.env.air ?
+					'javascript:void(0)' :
+				isCustomDomain ?
+					'javascript:void((function(){' +
+						'document.open();' +
+						'document.domain=\'' + document.domain + '\';' +
+						'document.close();' +
+						'})())"'
+				:
+					'';
+
 			var iframe = CKEDITOR.dom.element.createFromHtml(
 						'<iframe' +
@@ -80,11 +93,5 @@
 						' frameborder="0" ' +
 						' allowTransparency="true"' +
-						// Support for custom document.domain in IE.
-						( isCustomDomain ?
-							' src="javascript:void((function(){' +
-								'document.open();' +
-								'document.domain=\'' + document.domain + '\';' +
-								'document.close();' +
-							'})())"' : '' ) +
+						' src="' + src + '"' +
 						' role="region"' +
 						' aria-label="' + lang.pasteArea + '"' +
@@ -94,14 +101,14 @@
 
 			iframe.on( 'load', function( e )
-			{
-				e.removeListener();
-				var doc = iframe.getFrameDocument().$;
-				// Custom domain handling is needed after each document.open().
-				doc.open();
-				if ( isCustomDomain )
-					doc.domain = document.domain;
-				doc.write( htmlToLoad );
-				doc.close();
-			}, this );
+				{
+					e.removeListener();
+
+					var doc = iframe.getFrameDocument();
+					doc.write( htmlToLoad );
+
+					if ( CKEDITOR.env.air )
+						onPasteFrameLoad.call( this, doc.getWindow().$ );
+				},
+				this );
 
 			iframe.setCustomData( 'dialog', this );
Index: /CKEditor/branches/versions/3.5.x/_source/plugins/colorbutton/plugin.js
===================================================================
--- /CKEditor/branches/versions/3.5.x/_source/plugins/colorbutton/plugin.js	(revision 6177)
+++ /CKEditor/branches/versions/3.5.x/_source/plugins/colorbutton/plugin.js	(revision 6178)
@@ -44,4 +44,6 @@
 						// The block should not have scrollbars (#5933, #6056)
 						block.element.getDocument().getBody().setStyle( 'overflow', 'hidden' );
+
+						CKEDITOR.ui.fire( 'ready', this );
 
 						var keys = block.keys;
Index: /CKEditor/branches/versions/3.5.x/_source/plugins/dialog/plugin.js
===================================================================
--- /CKEditor/branches/versions/3.5.x/_source/plugins/dialog/plugin.js	(revision 6177)
+++ /CKEditor/branches/versions/3.5.x/_source/plugins/dialog/plugin.js	(revision 6178)
@@ -733,4 +733,5 @@
 				element.setStyle( 'display', 'block' );
 
+			CKEDITOR.ui.fire( 'ready', this );
 			// FIREFOX BUG: Fix vanishing caret for Firefox 2 or Gecko 1.8.
 			if ( CKEDITOR.env.gecko && CKEDITOR.env.version < 10900 )
Index: /CKEditor/branches/versions/3.5.x/_source/plugins/elementspath/plugin.js
===================================================================
--- /CKEditor/branches/versions/3.5.x/_source/plugins/elementspath/plugin.js	(revision 6177)
+++ /CKEditor/branches/versions/3.5.x/_source/plugins/elementspath/plugin.js	(revision 6178)
@@ -20,6 +20,7 @@
 				var element = CKEDITOR.document.getById( idBase + '0' );
 
-				if ( element )
-					element.focus();
+				// Make the first button focus accessible for IE. (#3417)
+				// Adobe AIR instead need while of delay.
+				element && element.focus( CKEDITOR.env.ie || CKEDITOR.env.air );
 			}
 		}
@@ -55,4 +56,51 @@
 							'<div id="' + spaceId + '" class="cke_path" role="group" aria-labelledby="' + spaceId + '_label">' + emptyHtml + '</div>';
 					}
+				});
+
+			function onClick( elementIndex )
+			{
+				editor.focus();
+				var element = editor._.elementsPath.list[ elementIndex ];
+				editor.getSelection().selectElement( element );
+			}
+
+			var onClickHanlder = CKEDITOR.tools.addFunction( onClick );
+
+			var onKeyDownHandler = CKEDITOR.tools.addFunction( function( elementIndex, ev )
+				{
+					var idBase = editor._.elementsPath.idBase,
+						element;
+
+					ev = new CKEDITOR.dom.event( ev );
+
+					var rtl = editor.lang.dir == 'rtl';
+					switch ( ev.getKeystroke() )
+					{
+						case rtl ? 39 : 37 :		// LEFT-ARROW
+						case 9 :					// TAB
+							element = CKEDITOR.document.getById( idBase + ( elementIndex + 1 ) );
+							if ( !element )
+								element = CKEDITOR.document.getById( idBase + '0' );
+							element.focus();
+							return false;
+
+						case rtl ? 37 : 39 :		// RIGHT-ARROW
+						case CKEDITOR.SHIFT + 9 :	// SHIFT + TAB
+							element = CKEDITOR.document.getById( idBase + ( elementIndex - 1 ) );
+							if ( !element )
+								element = CKEDITOR.document.getById( idBase + ( editor._.elementsPath.list.length - 1 ) );
+							element.focus();
+							return false;
+
+						case 27 :					// ESC
+							editor.focus();
+							return false;
+
+						case 13 :					// ENTER	// Opera
+						case 32 :					// SPACE
+							onClick( elementIndex );
+							return false;
+					}
+					return true;
 				});
 
@@ -113,7 +161,7 @@
 									' onfocus="event.preventBubble();"' : '' ) +
 									' hidefocus="true" ' +
-									' onkeydown="return CKEDITOR._.elementsPath.keydown(\'', editor.name, '\',', index, ', event);"' +
+									' onkeydown="return CKEDITOR.tools.callFunction(', onKeyDownHandler, ',', index, ', event );"' +
 									extra ,
-									' onclick="return CKEDITOR._.elementsPath.click(\'', editor.name, '\',', index, ');"',
+									' onclick="CKEDITOR.tools.callFunction('+ onClickHanlder, ',', index, '); return false;"',
 									' role="button" aria-labelledby="' + idBase + index + '_label">',
 										name,
@@ -129,5 +177,7 @@
 					}
 
-					getSpaceElement().setHtml( html.join('') + emptyHtml );
+					var space = getSpaceElement();
+					space.setHtml( html.join('') + emptyHtml );
+					editor.fire( 'elementsPathUpdate', { space : space } );
 				});
 
@@ -143,64 +193,2 @@
 	});
 })();
-
-/**
- * Handles the click on an element in the element path.
- * @private
- */
-CKEDITOR._.elementsPath =
-{
-	click : function( instanceName, elementIndex )
-	{
-		var editor = CKEDITOR.instances[ instanceName ];
-		editor.focus();
-
-		var element = editor._.elementsPath.list[ elementIndex ];
-		editor.getSelection().selectElement( element );
-
-		return false;
-	},
-
-	keydown : function( instanceName, elementIndex, ev )
-	{
-		var instance = CKEDITOR.ui.button._.instances[ elementIndex ];
-		var editor = CKEDITOR.instances[ instanceName ];
-		var idBase = editor._.elementsPath.idBase;
-
-		var element;
-
-		ev = new CKEDITOR.dom.event( ev );
-
-		var rtl = editor.lang.dir == 'rtl';
-		switch ( ev.getKeystroke() )
-		{
-			case rtl ? 39 : 37 :					// LEFT-ARROW
-			case 9 :					// TAB
-				element = CKEDITOR.document.getById( idBase + ( elementIndex + 1 ) );
-				if ( !element )
-					element = CKEDITOR.document.getById( idBase + '0' );
-				element.focus();
-				return false;
-
-			case rtl ? 37 : 39 :					// RIGHT-ARROW
-			case CKEDITOR.SHIFT + 9 :	// SHIFT + TAB
-				element = CKEDITOR.document.getById( idBase + ( elementIndex - 1 ) );
-				if ( !element )
-					element = CKEDITOR.document.getById( idBase + ( editor._.elementsPath.list.length - 1 ) );
-				element.focus();
-				return false;
-
-			case 27 :					// ESC
-				editor.focus();
-				return false;
-
-			case 13 :					// ENTER	// Opera
-			case 32 :					// SPACE
-				this.click( instanceName, elementIndex );
-				return false;
-
-			//default :
-			//	alert( ev.getKeystroke() );
-		}
-		return true;
-	}
-};
Index: /CKEditor/branches/versions/3.5.x/_source/plugins/floatpanel/plugin.js
===================================================================
--- /CKEditor/branches/versions/3.5.x/_source/plugins/floatpanel/plugin.js	(revision 6177)
+++ /CKEditor/branches/versions/3.5.x/_source/plugins/floatpanel/plugin.js	(revision 6178)
@@ -1,3 +1,3 @@
-﻿/*
+/*
 Copyright (c) 2003-2010, CKSource - Frederico Knabben. All rights reserved.
 For licensing, see LICENSE.html or http://ckeditor.com/license
@@ -306,5 +306,5 @@
 							this.allowBlur( true );
 						}, 0, this);
-					}, 0, this);
+					},  CKEDITOR.env.air ? 200 : 0, this);
 				this.visible = 1;
 
Index: /CKEditor/branches/versions/3.5.x/_source/plugins/menu/plugin.js
===================================================================
--- /CKEditor/branches/versions/3.5.x/_source/plugins/menu/plugin.js	(revision 6177)
+++ /CKEditor/branches/versions/3.5.x/_source/plugins/menu/plugin.js	(revision 6178)
@@ -1,3 +1,3 @@
-﻿/*
+/*
 Copyright (c) 2003-2010, CKSource - Frederico Knabben. All rights reserved.
 For licensing, see LICENSE.html or http://ckeditor.com/license
@@ -335,4 +335,6 @@
 				// Inject the HTML inside the panel.
 				element.setHtml( output.join( '' ) );
+
+				CKEDITOR.ui.fire( 'ready', this );
 
 				// Show the panel.
@@ -407,18 +409,18 @@
 					classes += ' ' + this.className;
 
-				var hasSubMenu = this.getItems;
-
-				output.push(
-					'<span class="cke_menuitem">' +
-					'<a id="', id, '"' +
-						' class="', classes, '" href="javascript:void(\'', ( this.label || '' ).replace( "'", '' ), '\')"' +
-						' title="', this.label, '"' +
-						' tabindex="-1"' +
-						'_cke_focus=1' +
-						' hidefocus="true"' +
-						' role="menuitem"' +
-						( hasSubMenu ? 'aria-haspopup="true"' : '' ) +
-						( state == CKEDITOR.TRISTATE_DISABLED ? 'aria-disabled="true"' : '' ) +
-						( state == CKEDITOR.TRISTATE_ON ? 'aria-pressed="true"' : '' ) );
+			var hasSubMenu = this.getItems;
+
+			output.push(
+				'<span class="cke_menuitem">' +
+				'<a id="', id, '"' +
+					' class="', classes, '" href="javascript:void(\'', ( this.label || '' ).replace( "'", '' ), '\')"' +
+					' title="', this.label, '"' +
+					' tabindex="-1"' +
+					'_cke_focus=1' +
+					' hidefocus="true"' +
+					' role="menuitem"' +
+					( hasSubMenu ? 'aria-haspopup="true"' : '' ) +
+					( state == CKEDITOR.TRISTATE_DISABLED ? 'aria-disabled="true"' : '' ) +
+					( state == CKEDITOR.TRISTATE_ON ? 'aria-pressed="true"' : '' ) );
 
 				// Some browsers don't cancel key events in the keydown but in the
@@ -442,25 +444,25 @@
 				output.push(
 //					' onkeydown="return CKEDITOR.ui.button._.keydown(', index, ', event);"' +
-						' onmouseover="CKEDITOR.tools.callFunction(', menu._.itemOverFn, ',', index, ');"' +
-						' onmouseout="CKEDITOR.tools.callFunction(', menu._.itemOutFn, ',', index, ');"' +
-						' onclick="CKEDITOR.tools.callFunction(', menu._.itemClickFn, ',', index, '); return false;"' +
-						'>' +
-							'<span class="cke_icon_wrapper"><span class="cke_icon"' +
-								( this.icon ? ' style="background-image:url(' + CKEDITOR.getUrl( this.icon ) + ');background-position:0 ' + offset + 'px;"'
-								: '' ) +
-								'></span></span>' +
-							'<span class="cke_label">' );
-
-				if ( hasSubMenu )
-				{
-					output.push(
-								'<span class="cke_menuarrow">',
-									'<span>&#',
-										( this.editor.lang.dir == 'rtl' ?
-											'9668' :	// BLACK LEFT-POINTING POINTER
-											'9658' ),	// BLACK RIGHT-POINTING POINTER
-									';</span>',
-								'</span>' );
-				}
+					' onmouseover="CKEDITOR.tools.callFunction(', menu._.itemOverFn, ',', index, ');"' +
+					' onmouseout="CKEDITOR.tools.callFunction(', menu._.itemOutFn, ',', index, ');"' +
+					' onclick="CKEDITOR.tools.callFunction(', menu._.itemClickFn, ',', index, '); return false;"' +
+					'>' +
+						'<span class="cke_icon_wrapper"><span class="cke_icon"' +
+							( this.icon ? ' style="background-image:url(' + CKEDITOR.getUrl( this.icon ) + ');background-position:0 ' + offset + 'px;"'
+							: '' ) +
+							'></span></span>' +
+						'<span class="cke_label">' );
+
+			if ( hasSubMenu )
+			{
+				output.push(
+							'<span class="cke_menuarrow">',
+								'<span>&#',
+									( this.editor.lang.dir == 'rtl' ?
+										'9668' :	// BLACK LEFT-POINTING POINTER
+										'9658' ),	// BLACK RIGHT-POINTING POINTER
+								';</span>',
+							'</span>' );
+			}
 
 				output.push(
@@ -469,5 +471,5 @@
 					'</a>' +
 					'</span>' );
-			}
+		}
 		}
 	});
Index: /CKEditor/branches/versions/3.5.x/_source/plugins/panel/plugin.js
===================================================================
--- /CKEditor/branches/versions/3.5.x/_source/plugins/panel/plugin.js	(revision 6177)
+++ /CKEditor/branches/versions/3.5.x/_source/plugins/panel/plugin.js	(revision 6178)
@@ -1,3 +1,3 @@
-﻿/*
+/*
 Copyright (c) 2003-2010, CKSource - Frederico Knabben. All rights reserved.
 For licensing, see LICENSE.html or http://ckeditor.com/license
@@ -137,10 +137,4 @@
 					langCode = parentDiv.getParent().getAttribute( 'lang' ),
 					doc = iframe.getFrameDocument();
-				// Initialize the IFRAME document body.
-				doc.$.open();
-
-				// Support for custom document.domain in IE.
-				if ( CKEDITOR.env.isCustomDomain() )
-					doc.$.domain = document.domain;
 
 				var onLoad = CKEDITOR.tools.addFunction( CKEDITOR.tools.bind( function( ev )
@@ -151,5 +145,5 @@
 					}, this ) );
 
-				doc.$.write(
+				var data =
 					'<!DOCTYPE html>' +
 					'<html dir="' + dir + '" class="' + className + '_container" lang="' + langCode + '">' +
@@ -163,6 +157,7 @@
 						// available. (#3031)
 						CKEDITOR.tools.buildStyleHtml( this.css ) +
-					'<\/html>' );
-				doc.$.close();
+					'<\/html>';
+
+				doc.write( data );
 
 				var win = doc.getWindow();
@@ -195,4 +190,5 @@
 				holder = doc.getBody();
 				holder.unselectable();
+				CKEDITOR.env.air && CKEDITOR.tools.callFunction( onLoad );
 			}
 			else
Index: /CKEditor/branches/versions/3.5.x/_source/plugins/richcombo/plugin.js
===================================================================
--- /CKEditor/branches/versions/3.5.x/_source/plugins/richcombo/plugin.js	(revision 6177)
+++ /CKEditor/branches/versions/3.5.x/_source/plugins/richcombo/plugin.js	(revision 6178)
@@ -107,10 +107,5 @@
 					}
 
-					if ( !_.committed )
-					{
-						_.list.commit();
-						_.committed = 1;
-					}
-
+					this.commit();
 					var value = this.getValue();
 					if ( value )
@@ -202,5 +197,5 @@
 							'<span id="' + id + '_text" class="cke_text cke_inline_label">' + this.label + '</span>' +
 						'</span>' +
-						'<span class=cke_openbutton>' + ( CKEDITOR.env.hc ? '<span>&#9660;</span>' : '' ) + '</span>' +	// BLACK DOWN-POINTING TRIANGLE
+						'<span class=cke_openbutton>' + ( CKEDITOR.env.hc ? '<span>&#9660;</span>' : CKEDITOR.env.air ?  '&nbsp;' : '' ) + '</span>' +	// BLACK DOWN-POINTING TRIANGLE
 					'</a>' +
 				'</span>' +
@@ -350,5 +345,10 @@
 		commit : function()
 		{
-			this._.list.commit();
+			if ( !this._.committed )
+			{
+				this._.list.commit();
+				this._.committed = 1;
+				CKEDITOR.ui.fire( 'ready', this );
+			}
 		},
 
Index: /CKEditor/branches/versions/3.5.x/_source/plugins/scayt/plugin.js
===================================================================
--- /CKEditor/branches/versions/3.5.x/_source/plugins/scayt/plugin.js	(revision 6177)
+++ /CKEditor/branches/versions/3.5.x/_source/plugins/scayt/plugin.js	(revision 6178)
@@ -1,3 +1,3 @@
-﻿/*
+/*
 Copyright (c) 2003-2010, CKSource - Frederico Knabben. All rights reserved.
 For licensing, see LICENSE.html or http://ckeditor.com/license
@@ -358,6 +358,6 @@
 		loadEngine : function( editor )
 		{
-			// SCAYT doesn't work with Firefox2, Opera.
-			if ( CKEDITOR.env.gecko && CKEDITOR.env.version < 10900 || CKEDITOR.env.opera )
+			// SCAYT doesn't work with Firefox2, Opera and AIR.
+			if ( CKEDITOR.env.gecko && CKEDITOR.env.version < 10900 || CKEDITOR.env.opera || CKEDITOR.env.air )
 				return editor.fire( 'showScaytState' );
 
@@ -757,5 +757,5 @@
 					editor.removeListener( 'showScaytState', showInitialState );
 
-					if ( !CKEDITOR.env.opera )
+					if ( !CKEDITOR.env.opera && !CKEDITOR.env.air )
 						command.setState( plugin.isScaytEnabled( editor ) ? CKEDITOR.TRISTATE_ON : CKEDITOR.TRISTATE_OFF );
 					else
@@ -765,5 +765,5 @@
 			editor.on( 'showScaytState', showInitialState );
 
-			if ( CKEDITOR.env.opera )
+			if ( CKEDITOR.env.opera || CKEDITOR.env.air )
 			{
 				editor.on( 'instanceReady', function()
Index: /CKEditor/branches/versions/3.5.x/_source/plugins/toolbar/plugin.js
===================================================================
--- /CKEditor/branches/versions/3.5.x/_source/plugins/toolbar/plugin.js	(revision 6177)
+++ /CKEditor/branches/versions/3.5.x/_source/plugins/toolbar/plugin.js	(revision 6178)
@@ -44,6 +44,7 @@
 					editor.toolbox.focusCommandExecuted = true;
 
-					// Make the first button focus accessible. (#3417)
-					if ( CKEDITOR.env.ie )
+					// Make the first button focus accessible for IE. (#3417)
+					// Adobe AIR instead need while of delay.
+					if ( CKEDITOR.env.ie || CKEDITOR.env.air )
 						setTimeout( function(){ editor.toolbox.focus(); }, 100 );
 					else
Index: /CKEditor/branches/versions/3.5.x/_source/plugins/wsc/plugin.js
===================================================================
--- /CKEditor/branches/versions/3.5.x/_source/plugins/wsc/plugin.js	(revision 6177)
+++ /CKEditor/branches/versions/3.5.x/_source/plugins/wsc/plugin.js	(revision 6178)
@@ -19,5 +19,5 @@
 
 		// SpellChecker doesn't work in Opera and with custom domain
-		command.modes = { wysiwyg : ( !CKEDITOR.env.opera && document.domain == window.location.hostname ) };
+		command.modes = { wysiwyg : ( !CKEDITOR.env.opera && !CKEDITOR.env.air && document.domain == window.location.hostname ) };
 
 		editor.ui.addButton( 'SpellChecker',
Index: /CKEditor/branches/versions/3.5.x/_source/plugins/wysiwygarea/plugin.js
===================================================================
--- /CKEditor/branches/versions/3.5.x/_source/plugins/wysiwygarea/plugin.js	(revision 6177)
+++ /CKEditor/branches/versions/3.5.x/_source/plugins/wysiwygarea/plugin.js	(revision 6178)
@@ -1,3 +1,3 @@
-﻿/*
+/*
 Copyright (c) 2003-2010, CKSource - Frederico Knabben. All rights reserved.
 For licensing, see LICENSE.html or http://ckeditor.com/license
@@ -108,5 +108,5 @@
 			if ( selIsLocked )
 				this.getSelection().lock();
-		}
+			}
 		else
 			this.document.$.execCommand( 'inserthtml', false, data );
@@ -475,6 +475,5 @@
 							iframe.remove();
 
-
-						var srcScript =
+						var src =
 							'document.open();' +
 
@@ -484,4 +483,15 @@
 
 							'document.close();';
+
+						// With IE, the custom domain has to be taken care at first,
+						// for other browers, the 'src' attribute should be left empty to
+						// trigger iframe's 'load' event.
+  						src =
+							CKEDITOR.env.air ?
+								'javascript:void(0)' :
+							CKEDITOR.env.ie ?
+								'javascript:void(function(){' + encodeURIComponent( src ) + '}())'
+							:
+								'';
 
 						iframe = CKEDITOR.dom.element.createFromHtml( '<iframe' +
@@ -489,8 +499,5 @@
   							' frameBorder="0"' +
   							' title="' + frameLabel + '"' +
-							// With IE, the custom domain has to be taken care at first,
-							// for other browers, the 'src' attribute should be left empty to
-							// trigger iframe's 'load' event.
-  							' src="' + ( CKEDITOR.env.ie ? 'javascript:void(function(){' + encodeURIComponent( srcScript ) + '}())' : '' ) + '"' +
+  							' src="' + src + '"' +
 							' tabIndex="' + ( CKEDITOR.env.webkit? -1 : editor.tabIndex ) + '"' +
   							' allowTransparency="true"' +
@@ -507,10 +514,8 @@
 								ev.removeListener();
 
-								var doc = iframe.getFrameDocument().$;
-
-								// Don't leave any history log in IE. (#5657)
-								doc.open( "text/html","replace" );
+								var doc = iframe.getFrameDocument();
 								doc.write( data );
-								doc.close();
+
+								CKEDITOR.env.air && contentDomReady( doc.getWindow().$ );
 							});
 
@@ -568,5 +573,5 @@
 						// Remove this script from the DOM.
 						var script = domDocument.getElementById( "cke_actscrpt" );
-						script.parentNode.removeChild( script );
+						script && script.parentNode.removeChild( script );
 
 						body.spellcheck = !editor.config.disableNativeSpellChecker;
@@ -1008,4 +1013,6 @@
 							focus : function()
 							{
+								var win = editor.window;
+
 								if ( isLoadingData )
 									isPendingFocus = true;
@@ -1021,8 +1028,8 @@
 									editor.selectionChange();
 								}
-								else if ( !CKEDITOR.env.opera && editor.window )
-								{
-									editor.window.focus();
-
+								else if ( !CKEDITOR.env.opera && win )
+								{
+									// AIR needs a while to focus when moving from a link.
+									CKEDITOR.env.air ? setTimeout( function () { win.focus(); }, 0 ) : win.focus();
 									editor.selectionChange();
 								}
Index: /CKEditor/branches/versions/3.5.x/_source/skins/kama/mainui.css
===================================================================
--- /CKEditor/branches/versions/3.5.x/_source/skins/kama/mainui.css	(revision 6177)
+++ /CKEditor/branches/versions/3.5.x/_source/skins/kama/mainui.css	(revision 6178)
@@ -126,4 +126,11 @@
 }
 
+/* Adobe AIR doesn't support *-resize cursor shape. */
+.cke_skin_kama .cke_browser_air .cke_resizer,
+.cke_skin_kama .cke_browser_air .cke_rtl .cke_resizer
+{
+	cursor: move;
+}
+
 .cke_skin_kama .cke_rtl .cke_resizer
 {
Index: /CKEditor/branches/versions/3.5.x/_source/skins/office2003/mainui.css
===================================================================
--- /CKEditor/branches/versions/3.5.x/_source/skins/office2003/mainui.css	(revision 6177)
+++ /CKEditor/branches/versions/3.5.x/_source/skins/office2003/mainui.css	(revision 6178)
@@ -94,4 +94,11 @@
 }
 
+/* Adobe AIR doesn't support *-resize cursor shape. */
+.cke_skin_office2003 .cke_browser_air .cke_resizer,
+.cke_skin_office2003 .cke_browser_air .cke_rtl .cke_resizer
+{
+	cursor: move;
+}
+
 .cke_skin_office2003 .cke_rtl .cke_resizer
 {
Index: /CKEditor/branches/versions/3.5.x/_source/skins/v2/mainui.css
===================================================================
--- /CKEditor/branches/versions/3.5.x/_source/skins/v2/mainui.css	(revision 6177)
+++ /CKEditor/branches/versions/3.5.x/_source/skins/v2/mainui.css	(revision 6178)
@@ -103,4 +103,11 @@
 }
 
+/* Adobe AIR doesn't support *-resize cursor shape. */
+.cke_skin_v2 .cke_browser_air .cke_resizer,
+.cke_skin_v2 .cke_browser_air .cke_rtl .cke_resizer
+{
+	cursor: move;
+}
+
 .cke_skin_v2 .cke_rtl .cke_resizer
 {
Index: /CKEditor/branches/versions/3.5.x/_source/themes/default/theme.js
===================================================================
--- /CKEditor/branches/versions/3.5.x/_source/themes/default/theme.js	(revision 6177)
+++ /CKEditor/branches/versions/3.5.x/_source/themes/default/theme.js	(revision 6178)
@@ -1,3 +1,3 @@
-﻿/*
+/*
 Copyright (c) 2003-2010, CKSource - Frederico Knabben. All rights reserved.
 For licensing, see LICENSE.html or http://ckeditor.com/license
@@ -46,4 +46,8 @@
 			container = mainContainer.getChild( [0,0,0,0] );
 
+			// Save a reference to the shared space container.
+			!editor.sharedSpaces && ( editor.sharedSpaces = {} );
+			editor.sharedSpaces[ spaceName ] = container;
+
 			// When the editor gets focus, we show the space container, hiding others.
 			editor.on( 'focus', function()
@@ -123,5 +127,5 @@
 					' title="', ( CKEDITOR.env.gecko ? ' ' : '' ), '"' +
 					' lang="', editor.langCode, '"' +
-					( CKEDITOR.env.webkit? ' tabindex="' + tabIndex + '"' : '' ) +
+						( CKEDITOR.env.webkit? ' tabindex="' + tabIndex + '"' : '' ) +
 					' role="application"' +
 					' aria-labelledby="cke_', name, '_arialbl"' +
Index: /CKEditor/branches/versions/3.5.x/ckeditor_basic_source.js
===================================================================
--- /CKEditor/branches/versions/3.5.x/ckeditor_basic_source.js	(revision 6177)
+++ /CKEditor/branches/versions/3.5.x/ckeditor_basic_source.js	(revision 6178)
@@ -6,5 +6,5 @@
 // Compressed version of core/ckeditor_base.js. See original for instructions.
 /*jsl:ignore*/
-if(!window.CKEDITOR)window.CKEDITOR=(function(){var a={timestamp:'',version:'%VERSION%',revision:'%REV%',_:{},status:'unloaded',basePath:(function(){var d=window.CKEDITOR_BASEPATH||'';if(!d){var e=document.getElementsByTagName('script');for(var f=0;f<e.length;f++){var g=e[f].src.match(/(^|.*[\\\/])ckeditor(?:_basic)?(?:_source)?.js(?:\?.*)?$/i);if(g){d=g[1];break;}}}if(d.indexOf('://')==-1)if(d.indexOf('/')===0)d=location.href.match(/^.*?:\/\/[^\/]*/)[0]+d;else d=location.href.match(/^[^\?]*\/(?:)/)[0]+d;return d;})(),getUrl:function(d){if(d.indexOf('://')==-1&&d.indexOf('/')!==0)d=this.basePath+d;if(this.timestamp&&d.charAt(d.length-1)!='/')d+=(d.indexOf('?')>=0?'&':'?')+('t=')+this.timestamp;return d;}},b=window.CKEDITOR_GETURL;if(b){var c=a.getUrl;a.getUrl=function(d){return b.call(a,d)||c.call(a,d);};}return a;})();
+if(!window.CKEDITOR)window.CKEDITOR=(function(){var a={timestamp:'',version:'%VERSION%',revision:'%REV%',_:{},status:'unloaded',basePath:(function(){var d=window.CKEDITOR_BASEPATH||'';if(!d){var e=document.getElementsByTagName('script');for(var f=0;f<e.length;f++){var g=e[f].src.match(/(^|.*[\\\/])ckeditor(?:_basic)?(?:_source)?.js(?:\?.*)?$/i);if(g){d=g[1];break;}}}if(d.indexOf(':/')==-1)if(d.indexOf('/')===0)d=location.href.match(/^.*?:\/\/[^\/]*/)[0]+d;else d=location.href.match(/^[^\?]*\/(?:)/)[0]+d;return d;})(),getUrl:function(d){if(d.indexOf(':/')==-1&&d.indexOf('/')!==0)d=this.basePath+d;if(this.timestamp&&d.charAt(d.length-1)!='/')d+=(d.indexOf('?')>=0?'&':'?')+('t=')+this.timestamp;return d;}},b=window.CKEDITOR_GETURL;if(b){var c=a.getUrl;a.getUrl=function(d){return b.call(a,d)||c.call(a,d);};}return a;})();
 /*jsl:end*/
 
Index: /CKEditor/branches/versions/3.5.x/ckeditor_source.js
===================================================================
--- /CKEditor/branches/versions/3.5.x/ckeditor_source.js	(revision 6177)
+++ /CKEditor/branches/versions/3.5.x/ckeditor_source.js	(revision 6178)
@@ -6,5 +6,5 @@
 // Compressed version of core/ckeditor_base.js. See original for instructions.
 /*jsl:ignore*/
-if(!window.CKEDITOR)window.CKEDITOR=(function(){var a={timestamp:'',version:'%VERSION%',revision:'%REV%',_:{},status:'unloaded',basePath:(function(){var d=window.CKEDITOR_BASEPATH||'';if(!d){var e=document.getElementsByTagName('script');for(var f=0;f<e.length;f++){var g=e[f].src.match(/(^|.*[\\\/])ckeditor(?:_basic)?(?:_source)?.js(?:\?.*)?$/i);if(g){d=g[1];break;}}}if(d.indexOf('://')==-1)if(d.indexOf('/')===0)d=location.href.match(/^.*?:\/\/[^\/]*/)[0]+d;else d=location.href.match(/^[^\?]*\/(?:)/)[0]+d;return d;})(),getUrl:function(d){if(d.indexOf('://')==-1&&d.indexOf('/')!==0)d=this.basePath+d;if(this.timestamp&&d.charAt(d.length-1)!='/')d+=(d.indexOf('?')>=0?'&':'?')+('t=')+this.timestamp;return d;}},b=window.CKEDITOR_GETURL;if(b){var c=a.getUrl;a.getUrl=function(d){return b.call(a,d)||c.call(a,d);};}return a;})();
+if(!window.CKEDITOR)window.CKEDITOR=(function(){var a={timestamp:'',version:'%VERSION%',revision:'%REV%',_:{},status:'unloaded',basePath:(function(){var d=window.CKEDITOR_BASEPATH||'';if(!d){var e=document.getElementsByTagName('script');for(var f=0;f<e.length;f++){var g=e[f].src.match(/(^|.*[\\\/])ckeditor(?:_basic)?(?:_source)?.js(?:\?.*)?$/i);if(g){d=g[1];break;}}}if(d.indexOf(':/')==-1)if(d.indexOf('/')===0)d=location.href.match(/^.*?:\/\/[^\/]*/)[0]+d;else d=location.href.match(/^[^\?]*\/(?:)/)[0]+d;return d;})(),getUrl:function(d){if(d.indexOf(':/')==-1&&d.indexOf('/')!==0)d=this.basePath+d;if(this.timestamp&&d.charAt(d.length-1)!='/')d+=(d.indexOf('?')>=0?'&':'?')+('t=')+this.timestamp;return d;}},b=window.CKEDITOR_GETURL;if(b){var c=a.getUrl;a.getUrl=function(d){return b.call(a,d)||c.call(a,d);};}return a;})();
 /*jsl:end*/
 
