Index: CKEditor/branches/versions/3.1.x/CHANGES.html
===================================================================
--- CKEditor/branches/versions/3.1.x/CHANGES.html	(revision 4647)
+++ CKEditor/branches/versions/3.1.x/CHANGES.html	(revision 4653)
@@ -52,4 +52,5 @@
 		<li><a href="http://dev.fckeditor.net/ticket/4342">#4342</a> : Introduced the bodyId and bodyClass settings to specify the id and class. to be used in the editing area at runtime.</li>
 		<li><a href="http://dev.fckeditor.net/ticket/3401">#3401</a> : Introduced the baseHref setting so it's possible to set the URL to be used to resolve absolute and relative URLs in the contents.</li>
+		<li><a href="http://dev.fckeditor.net/ticket/4228">#4228</a> : Introduced the Shared Spaces feature.</li>
 	</ul>
 	<p>
Index: CKEditor/branches/versions/3.1.x/_samples/index.html
===================================================================
--- CKEditor/branches/versions/3.1.x/_samples/index.html	(revision 4647)
+++ CKEditor/branches/versions/3.1.x/_samples/index.html	(revision 4653)
@@ -38,4 +38,5 @@
 		<li><a href="api_dialog.html">Using the JavaScript API to customize dialogs</a></li>
 		<li><a href="enterkey.html">Using the "Enter" key in CKEditor</a></li>
+		<li><a href="sharedspaces.html">Shared toolbars</a></li>
 		<li><a href="jqueryadapter.html">jQuery adapter example</a></li>
 	</ul>
Index: CKEditor/branches/versions/3.1.x/_samples/sharedspaces.html
===================================================================
--- CKEditor/branches/versions/3.1.x/_samples/sharedspaces.html	(revision 4653)
+++ CKEditor/branches/versions/3.1.x/_samples/sharedspaces.html	(revision 4653)
@@ -0,0 +1,115 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<!--
+Copyright (c) 2003-2009, 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>
+	<script type="text/javascript" src="sample.js"></script>
+	<style id="styles" type="text/css">
+
+#editorsForm
+{
+	height: 400px;
+	overflow: auto;
+	border: solid 1px #555;
+	margin: 10px 0;
+	padding: 0 10px;
+}
+
+	</style>
+</head>
+<body>
+	<div id="html">
+		<div id="topSpace">
+		</div>
+		<form id="editorsForm" action="sample_posteddata.php" method="post">
+			<p>
+				<label for="editor1">
+					Editor 1 (uses the shared toolbar and element path):</label><br />
+				<textarea id="editor1" name="editor1" rows="10" cols="80">&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[
+					CKEDITOR.replace( 'editor1',
+						{
+							sharedSpaces :
+							{
+								top : 'topSpace',
+								bottom : 'bottomSpace'
+							},
+
+							// Removes the maximize plugin as it's not usable
+							// in a shared toolbar.
+							// Removes the resizer as it's not usable in a
+							// shared elements path.
+							removePlugins : 'maximize,resize'
+						} );
+				//]]>
+				</script>
+			</p>
+			<p>
+				<label for="editor2">
+					Editor 2 (uses the shared toolbar and element path):</label><br />
+				<textarea id="editor2" name="editor2" rows="10" cols="80">&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[
+					CKEDITOR.replace( 'editor2',
+						{
+							sharedSpaces :
+							{
+								top : 'topSpace',
+								bottom : 'bottomSpace'
+							},
+
+							// Removes the maximize plugin as it's not usable
+							// in a shared toolbar.
+							// Removes the resizer as it's not usable in a
+							// shared elements path.
+							removePlugins : 'maximize,resize'
+						} );
+				//]]>
+				</script>
+			</p>
+			<p>
+				<label for="editor3">
+					Editor 3 (uses the shared toolbar only):</label><br />
+				<textarea id="editor3" name="editor3" rows="10" cols="80">&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[
+					CKEDITOR.replace( 'editor3',
+						{
+							sharedSpaces :
+							{
+								top : 'topSpace'
+							},
+							
+							// Removes the maximize plugin as it's not usable
+							// in a shared toolbar.
+							removePlugins : 'maximize'
+						} );
+				//]]>
+				</script>
+			</p>
+			<p>
+				<label for="editor4">
+					Editor 4 (no shared spaces):</label><br />
+				<textarea id="editor4" name="editor4" rows="10" cols="80">&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[
+					CKEDITOR.replace( 'editor4' );
+				//]]>
+				</script>
+			</p>
+			<p>
+				<input type="submit" value="Submit" />
+			</p>
+		</form>
+		<div id="bottomSpace">
+		</div>
+	</div>
+	<div id="code">
+		<pre></pre>
+	</div>
+</body>
+</html>
Index: CKEditor/branches/versions/3.1.x/_source/skins/kama/elementspath.css
===================================================================
--- CKEditor/branches/versions/3.1.x/_source/skins/kama/elementspath.css	(revision 4647)
+++ CKEditor/branches/versions/3.1.x/_source/skins/kama/elementspath.css	(revision 4653)
@@ -14,7 +14,7 @@
 .cke_skin_kama .cke_path
 {
-	padding: 0 5px;
 	display: inline-block;
 	float: left;
+	margin-top: 5px;
 }
 
@@ -24,4 +24,9 @@
 }
 
+.cke_shared .cke_skin_kama .cke_path
+{
+	margin: 0 0 5px;
+}
+
 .cke_skin_kama .cke_path a,
 .cke_skin_kama .cke_path .cke_empty
@@ -29,9 +34,5 @@
 	display: inline-block;
 	float: left;
-	padding-top: 1px;
-	padding-bottom: 1px;
-	padding-left: 4px;
-	padding-right: 4px;
-	margin-bottom : 3px;
+	padding: 1px 4px 0;
 	color: #60676a;
 }
@@ -53,8 +54,5 @@
 {
 	background-color: #dff1ff;
-	padding-top: 1px;
-	padding-bottom: 1px;
-	padding-left: 4px;
-	padding-right: 4px;
+	padding: 1px 4px 0;
 	outline: none;
 	color : #000;
Index: CKEditor/branches/versions/3.1.x/_source/skins/kama/mainui.css
===================================================================
--- CKEditor/branches/versions/3.1.x/_source/skins/kama/mainui.css	(revision 4647)
+++ CKEditor/branches/versions/3.1.x/_source/skins/kama/mainui.css	(revision 4653)
@@ -30,6 +30,12 @@
 	background-position: 0 -1950px;
 	display: block;
+	padding: 5px;
 
 	/*background-color: Red;*/
+}
+
+.cke_shared .cke_skin_kama .cke_wrapper
+{
+	padding-bottom: 0;
 }
 
@@ -67,5 +73,4 @@
 {
 	margin: 5px;
-	padding: 0 5px 5px;
 }
 
@@ -138,2 +143,13 @@
 	top: 0;
 }
+
+.cke_skin_kama .cke_browser_ie7 .cke_editor
+{
+	display: inline-block;
+}
+
+.cke_shared .cke_skin_kama .cke_browser_ie7 .cke_wrapper
+{
+	padding-bottom: 5px;
+}
+
Index: CKEditor/branches/versions/3.1.x/_source/skins/kama/skin.js
===================================================================
--- CKEditor/branches/versions/3.1.x/_source/skins/kama/skin.js	(revision 4647)
+++ CKEditor/branches/versions/3.1.x/_source/skins/kama/skin.js	(revision 4653)
@@ -148,5 +148,5 @@
 					var cssContent,
 						uiStyle = getStylesheet( CKEDITOR.document ),
-						cssId = '#cke_' + CKEDITOR.tools.escapeCssSelector( editor.name );
+						cssId = '.cke_editor_' + CKEDITOR.tools.escapeCssSelector( editor.name );
 
 					var cssSelectors =
Index: CKEditor/branches/versions/3.1.x/_source/skins/kama/toolbar.css
===================================================================
--- CKEditor/branches/versions/3.1.x/_source/skins/kama/toolbar.css	(revision 4647)
+++ CKEditor/branches/versions/3.1.x/_source/skins/kama/toolbar.css	(revision 4653)
@@ -23,10 +23,4 @@
 {
 	clear: both;
-	padding: 5px 3px 5px 6px;
-}
-
-.cke_skin_kama .cke_rtl .cke_toolbox
-{
-	padding: 5px 6px 5px 3px;
 }
 
@@ -43,5 +37,5 @@
 	float: right;
 	border: 1px outset #D3D3D3;
-	margin: 11px 4px 2px;
+	margin: 11px 0 2px;
 	cursor: pointer;
 }
@@ -396,2 +390,18 @@
 	cursor: default;
 }
+
+.cke_skin_kama .cke_browser_ie7 .cke_toolbox
+{
+	margin-bottom: 2px;
+}
+
+.cke_shared .cke_skin_kama .cke_browser_ie7 .cke_toolbox
+{
+	margin-bottom: 0;
+}
+
+.cke_skin_kama .cke_browser_gecko .cke_toolbox
+{
+	/* Define the padding-bottom otherwise the collapser button will not be clicable in FF */
+	padding-bottom: 1px;
+}
Index: CKEditor/branches/versions/3.1.x/_source/skins/office2003/mainui.css
===================================================================
--- CKEditor/branches/versions/3.1.x/_source/skins/office2003/mainui.css	(revision 4647)
+++ CKEditor/branches/versions/3.1.x/_source/skins/office2003/mainui.css	(revision 4653)
@@ -19,5 +19,7 @@
 }
 
-.cke_skin_office2003 .cke_top, .cke_skin_office2003 .cke_bottom
+.cke_skin_office2003 .cke_top,
+.cke_skin_office2003 .cke_bottom,
+ .cke_shared .cke_skin_office2003
 {
 	background-color: #f7f8fd;
Index: CKEditor/branches/versions/3.1.x/_source/skins/v2/mainui.css
===================================================================
--- CKEditor/branches/versions/3.1.x/_source/skins/v2/mainui.css	(revision 4647)
+++ CKEditor/branches/versions/3.1.x/_source/skins/v2/mainui.css	(revision 4653)
@@ -28,5 +28,7 @@
 }
 
-.cke_skin_v2 .cke_top, .cke_skin_v2 .cke_bottom
+.cke_skin_v2 .cke_top,
+.cke_skin_v2 .cke_bottom,
+ .cke_shared .cke_skin_v2
 {
 	background-color: #efefde;
Index: CKEditor/branches/versions/3.1.x/_source/themes/default/theme.js
===================================================================
--- CKEditor/branches/versions/3.1.x/_source/themes/default/theme.js	(revision 4647)
+++ CKEditor/branches/versions/3.1.x/_source/themes/default/theme.js	(revision 4653)
@@ -6,4 +6,64 @@
 CKEDITOR.themes.add( 'default', (function()
 {
+	function checkSharedSpace( editor, spaceName )
+	{
+		var container,
+			element;
+
+		// Try to retrieve the target element from the sharedSpaces settings. 
+		element = editor.config.sharedSpaces;
+		element = element && element[ spaceName ];
+		element = element && CKEDITOR.document.getById( element );
+
+		// If the element is available, we'll then create the container for
+		// the space.			
+		if ( element )
+		{
+			// Creates an HTML structure that reproduces the editor class hierarchy.
+			var html = 
+				'<span class="cke_shared">' +
+				'<span class="' + editor.skinClass + ' cke_editor_' + editor.name + '">' +
+				'<span class="' + CKEDITOR.env.cssClass + '">' +
+				'<span class="cke_wrapper cke_' + editor.lang.dir + '">' +
+				'<span class="cke_editor">' +
+				'<div class="cke_' + spaceName + '">' +
+				'</div></span></span></span></span></span>';
+
+			var mainContainer = element.append( CKEDITOR.dom.element.createFromHtml( html, element.getDocument() ) );
+
+			// Only the first container starts visible. Others get hidden.
+			if ( element.getCustomData( 'cke_hasshared' ) )
+				mainContainer.hide();
+			else
+				element.setCustomData( 'cke_hasshared', 1 );
+			
+			// Get the deeper inner <div>.
+			container = mainContainer.getChild( [0,0,0,0] );
+
+			// When the editor gets focus, we show the space container, hiding others.
+			editor.on( 'focus', function()
+				{
+					for ( var i = 0, sibling, children = element.getChildren() ; ( sibling = children.getItem( i ) ) ; i++ )
+					{
+						if ( sibling.type == CKEDITOR.NODE_ELEMENT 
+							&& !sibling.equals( mainContainer ) 
+							&& sibling.hasClass( 'cke_shared' ) )
+						{
+							sibling.hide();
+						}
+					}
+
+					mainContainer.show();
+				});
+
+			editor.on( 'destroy', function()
+				{
+					mainContainer.remove();
+				});
+		}
+
+		return container;
+	}
+
 	return {
 		build : function( editor, themePath )
@@ -45,9 +105,15 @@
 			}
 
+			var sharedTop		= topHtml && checkSharedSpace( editor, 'top' ),
+				sharedBottoms	= checkSharedSpace( editor, 'bottom' );
+				
+			sharedTop		&& ( sharedTop.setHtml( topHtml )		, topHtml = '' );
+			sharedBottoms	&& ( sharedBottoms.setHtml( bottomHtml ), bottomHtml = '' );
+
 			var container = CKEDITOR.dom.element.createFromHtml( [
 				'<span' +
 					' id="cke_', name, '"' +
 					' onmousedown="return false;"' +
-					' class="', editor.skinClass, '"' +
+					' class="', editor.skinClass, ' cke_editor_', name, '"' +
 					' dir="', editor.lang.dir, '"' +
 					' title="', ( CKEDITOR.env.gecko ? ' ' : '' ), '"' +
@@ -99,5 +165,5 @@
 
 			var element = CKEDITOR.dom.element.createFromHtml( [
-					'<div id="cke_' + editor.name.replace('.', '\\.') + '_dialog" class="cke_skin_', editor.skinName,
+					'<div class="cke_editor_' + editor.name.replace('.', '\\.') + '_dialog cke_skin_', editor.skinName,
 						'" dir="', editor.lang.dir, '"' +
 						' lang="', editor.langCode, '"' +
@@ -234,2 +300,28 @@
 	return this.container.getChild( [ 0, 0 ] );
 };
+
+/**
+ * Makes it possible to place some of the editor UI blocks, like the toolbar
+ * and the elements path, into any element in the page.
+ * The elements used to hold the UI blocks can be shared among several editor
+ * instances. In that case, only the blocks of the active editor instance will
+ * display.
+ * @name CKEDITOR.config.sharedSpaces
+ * @type Object
+ * @default undefined
+ * @example
+ * // Place the toolbar inside the element with ID "someElementId" and the
+ * // elements path into the element with ID "anotherId".
+ * config.sharedSpaces =
+ * {
+ *     top : 'someElementId',
+ *     bottom : 'anotherId'
+ * };
+ * @example
+ * // Place the toolbar inside the element with ID "someElementId". The
+ * // elements path will remain attached to the editor UI.
+ * config.sharedSpaces =
+ * {
+ *     top : 'someElementId'
+ * };
+ */
