Index: /CKEditor/trunk/_source/core/dom/element.js
===================================================================
--- /CKEditor/trunk/_source/core/dom/element.js	(revision 3225)
+++ /CKEditor/trunk/_source/core/dom/element.js	(revision 3226)
@@ -312,5 +312,11 @@
 		focus : function()
 		{
-			this.$.focus();
+			// IE throws error if the element is not visible.
+			try
+			{
+				this.$.focus();
+			}
+			catch (e)
+			{}
 		},
 
Index: /CKEditor/trunk/_source/core/dom/nodelist.js
===================================================================
--- /CKEditor/trunk/_source/core/dom/nodelist.js	(revision 3225)
+++ /CKEditor/trunk/_source/core/dom/nodelist.js	(revision 3226)
@@ -18,5 +18,6 @@
 	getItem : function( index )
 	{
-		return new CKEDITOR.dom.node( this.$[ index ] );
+		var $node = this.$[ index ];
+		return $node ? new CKEDITOR.dom.node( $node ) : null;
 	}
 };
Index: /CKEditor/trunk/_source/plugins/colorbutton/plugin.js
===================================================================
--- /CKEditor/trunk/_source/plugins/colorbutton/plugin.js	(revision 3225)
+++ /CKEditor/trunk/_source/plugins/colorbutton/plugin.js	(revision 3226)
@@ -38,4 +38,11 @@
 						block.element.addClass( 'cke_colorblock' );
 						block.element.setHtml( renderColors( panel, type ) );
+
+						var keys = block.keys;
+						keys[ 39 ]	= 'next';					// ARROW-RIGHT
+						keys[ 9 ]	= 'next';					// TAB
+						keys[ 37 ]	= 'prev';					// ARROW-LEFT
+						keys[ CKEDITOR.SHIFT + 9 ]	= 'prev';	// SHIFT + TAB
+						keys[ 32 ]	= 'click';					// SPACE
 					},
 
@@ -94,5 +101,6 @@
 			// Render the "Automatic" button.
 			output.push(
-				'<a class="cke_colorauto"' +
+				'<a class="cke_colorauto" _cke_focus=1 hidefocus=true' +
+					' title="', lang.auto, '"' +
 					' onclick="CKEDITOR.tools.callFunction(', clickFn, ',null,\'', type, '\');"' +
 					' href="javascript:void(\'', lang.auto, '\')">' +
@@ -119,5 +127,6 @@
 				output.push(
 					'<td>' +
-						'<a class="cke_colorbox"' +
+						'<a class="cke_colorbox" _cke_focus=1 hidefocus=true' +
+							' title="', color, '"' +
 							' onclick="CKEDITOR.tools.callFunction(', clickFn, ',\'#', color, '\',\'', type, '\');"' +
 							' href="javascript:void(\'', color, '\')">' +
@@ -134,5 +143,6 @@
 					'<tr>' +
 						'<td colspan=8 align=center>' +
-							'<a class="cke_colormore"' +
+							'<a class="cke_colormore" _cke_focus=1 hidefocus=true' +
+								' title="', lang.more, '"' +
 								' onclick="CKEDITOR.tools.callFunction(', clickFn, ',\'?\',\'', type, '\');"' +
 								' href="javascript:void(\'', lang.more, '\')">',
Index: /CKEditor/trunk/_source/plugins/floatpanel/plugin.js
===================================================================
--- /CKEditor/trunk/_source/plugins/floatpanel/plugin.js	(revision 3225)
+++ /CKEditor/trunk/_source/plugins/floatpanel/plugin.js	(revision 3226)
@@ -150,4 +150,10 @@
 						iframe.$.contentWindow.focus();
 					}, 0);
+
+				panel.onEscape = CKEDITOR.tools.bind( function()
+					{
+						this.onEscape && this.onEscape();
+					},
+					this );
 
 				if ( this.onShow )
Index: /CKEditor/trunk/_source/plugins/listblock/plugin.js
===================================================================
--- /CKEditor/trunk/_source/plugins/listblock/plugin.js	(revision 3225)
+++ /CKEditor/trunk/_source/plugins/listblock/plugin.js	(revision 3226)
@@ -1,3 +1,3 @@
-/*
+﻿/*
 Copyright (c) 2003-2009, CKSource - Frederico Knabben. All rights reserved.
 For licensing, see LICENSE.html or http://ckeditor.com/license
@@ -26,4 +26,11 @@
 					this.multiSelect = !!multiSelect;
 
+					var keys = this.keys;
+					keys[ 40 ]	= 'next';					// ARROW-DOWN
+					keys[ 9 ]	= 'next';					// TAB
+					keys[ 38 ]	= 'prev';					// ARROW-UP
+					keys[ CKEDITOR.SHIFT + 9 ]	= 'prev';	// SHIFT + TAB
+					keys[ 32 ]	= 'click';					// SPACE
+
 					this._.pendingHtml = [];
 					this._.items = {};
@@ -66,8 +73,8 @@
 				proto :
 				{
-					add : function( value, html )
+					add : function( value, html, title )
 					{
 						var pendingHtml = this._.pendingHtml,
-							id = CKEDITOR.tools.getNextNumber();
+							id = 'cke_' + CKEDITOR.tools.getNextNumber();
 
 						if ( !this._.started )
@@ -79,5 +86,13 @@
 						this._.items[ value ] = id;
 
-						pendingHtml.push( '<li id=cke_', id, ' class=cke_panel_listItem><a hidefocus=true href="javascript:void(\'', value, '\')" onclick="CKEDITOR.tools.callFunction(', this._.getClick(), ',\'', value, '\');">', html || value, '</a></li>' );
+						pendingHtml.push( 
+							'<li id=', id, ' class=cke_panel_listItem>' +
+								'<a _cke_focus=1 hidefocus=true' +
+									' title="', title || value, '"' +
+									' href="javascript:void(\'', value, '\')"' +
+									' onclick="CKEDITOR.tools.callFunction(', this._.getClick(), ',\'', value, '\');">',
+									html || value,
+								'</a>' +
+							'</li>' );
 					},
 
@@ -86,9 +101,9 @@
 						this._.close();
 
-						var id = CKEDITOR.tools.getNextNumber();
+						var id = 'cke_' + CKEDITOR.tools.getNextNumber();
 
 						this._.groups[ title ] = id;
 
-						this._.pendingHtml.push( '<h1 id=cke_', id, ' class=cke_panel_grouptitle>', title, '</h1>' );
+						this._.pendingHtml.push( '<h1 id=', id, ' class=cke_panel_grouptitle>', title, '</h1>' );
 					},
 
@@ -113,5 +128,5 @@
 					hideGroup : function( groupTitle )
 					{
-						var group = this.element.getDocument().getById( 'cke_' + this._.groups[ groupTitle ] ),
+						var group = this.element.getDocument().getById( this._.groups[ groupTitle ] ),
 							list = group && group.getNext();
 
@@ -127,5 +142,5 @@
 					hideItem : function( value )
 					{
-						this.element.getDocument().getById( 'cke_' + this._.items[ value ] ).setStyle( 'display', 'none' );
+						this.element.getDocument().getById( this._.items[ value ] ).setStyle( 'display', 'none' );
 					},
 
@@ -138,10 +153,10 @@
 						for ( var value in items )
 						{
-							doc.getById( 'cke_' + items[ value ] ).setStyle( 'display', '' );
+							doc.getById( items[ value ] ).setStyle( 'display', '' );
 						}
 
 						for ( title in groups )
 						{
-							var group = doc.getById( 'cke_' + groups[ title ] ),
+							var group = doc.getById( groups[ title ] ),
 								list = group.getNext();
 
@@ -158,10 +173,10 @@
 							this.unmarkAll();
 
-						this.element.getDocument().getById( 'cke_' + this._.items[ value ] ).addClass( 'cke_selected' );
+						this.element.getDocument().getById( this._.items[ value ] ).addClass( 'cke_selected' );
 					},
 
 					unmark : function( value )
 					{
-						this.element.getDocument().getById( 'cke_' + this._.items[ value ] ).removeClass( 'cke_selected' );
+						this.element.getDocument().getById( this._.items[ value ] ).removeClass( 'cke_selected' );
 					},
 
@@ -173,5 +188,5 @@
 						for ( var value in items )
 						{
-							doc.getById( 'cke_' + items[ value ] ).removeClass( 'cke_selected' );
+							doc.getById( items[ value ] ).removeClass( 'cke_selected' );
 						}
 					},
@@ -179,5 +194,34 @@
 					isMarked : function( value )
 					{
-						return this.element.getDocument().getById( 'cke_' + this._.items[ value ] ).hasClass( 'cke_selected' );
+						return this.element.getDocument().getById( this._.items[ value ] ).hasClass( 'cke_selected' );
+					},
+
+					focus : function( value )
+					{
+						this._.focusIndex = -1;
+
+						if ( value )
+						{
+							var selected = this.element.getDocument().getById( this._.items[ value ] ).getFirst();
+
+							var links = this.element.getElementsByTag( 'a' ),
+								link,
+								i = -1;
+
+							while( ( link = links.getItem( ++i ) ) )
+							{
+								if ( link.equals( selected ) )
+								{
+									this._.focusIndex = i;
+									break;
+								}
+							}
+
+							setTimeout( function()
+								{
+									selected.focus();
+								},
+								0 );
+						}
 					}
 				}
Index: /CKEditor/trunk/_source/plugins/panel/plugin.js
===================================================================
--- /CKEditor/trunk/_source/plugins/panel/plugin.js	(revision 3225)
+++ /CKEditor/trunk/_source/plugins/panel/plugin.js	(revision 3226)
@@ -142,4 +142,20 @@
 					this);
 
+				doc.on( 'keydown', function( evt )
+					{
+						var keystroke = evt.data.getKeystroke();
+
+						// Delegate key processing to block.
+						if ( this._.onKeyDown && this._.onKeyDown( keystroke ) === false )
+						{
+							evt.data.preventDefault();
+							return;
+						}
+
+						if ( keystroke == 27 )		// ESC
+							this.onEscape && this.onEscape();
+					},
+					this );
+
 				holder = doc.getBody();
 			}
@@ -179,4 +195,9 @@
 		this._.currentBlock = block;
 
+		// Reset the focus index, so it will always go into the first one.
+		block._.focusIndex = -1;
+
+		this._.onKeyDown = block.onKeyDown && CKEDITOR.tools.bind( block.onKeyDown, block );
+
 		block.show();
 
@@ -185,30 +206,95 @@
 };
 
-CKEDITOR.ui.panel.block = function( blockHolder )
-{
-	this.element = blockHolder.append(
-		blockHolder.getDocument().createElement( 'div',
+CKEDITOR.ui.panel.block = CKEDITOR.tools.createClass(
+{
+	$ : function( blockHolder )
+	{
+		this.element = blockHolder.append(
+			blockHolder.getDocument().createElement( 'div',
+				{
+					attributes :
+					{
+						'class' : 'cke_panel_block'
+					},
+					styles :
+					{
+						display : 'none'
+					}
+				}) );
+		
+		this.keys = {};
+		
+		this._.focusIndex = -1;
+	},
+	
+	_ : {},
+
+	proto :
+	{
+		show : function()
+		{
+			this.element.setStyle( 'display', '' );
+		},
+
+		hide : function()
+		{
+			this.element.setStyle( 'display', 'none' );
+		},
+
+		onKeyDown : function( keystroke )
+		{
+			var keyAction = this.keys[ keystroke ];
+			switch ( keyAction )
 			{
-				attributes :
-				{
-					'class' : 'cke_panel_block'
-				},
-				styles :
-				{
-					display : 'none'
-				}
-			}) );
-};
-
-CKEDITOR.ui.panel.block.prototype =
-{
-	show : function()
-	{
-		this.element.setStyle( 'display', '' );
-	},
-
-	hide : function()
-	{
-		this.element.setStyle( 'display', 'none' );
+				// Move forward.
+				case 'next' :
+					var index = this._.focusIndex,
+						links = this.element.getElementsByTag( 'a' ),
+						link;
+					
+					while ( ( link = links.getItem( ++index ) ) )
+					{
+						// Move the focus only if the element is marked with
+						// the _cke_focus and it it's visible (check if it has
+						// width).
+						if ( link.getAttribute( '_cke_focus' ) && link.$.offsetWidth )
+						{
+							this._.focusIndex = index;
+							link.focus();
+							break;
+						}
+					}
+					return false;
+
+				// Move backward.
+				case 'prev' :
+					var index = this._.focusIndex,
+						links = this.element.getElementsByTag( 'a' ),
+						link;
+
+					while ( index > 0 && ( link = links.getItem( --index ) ) )
+					{
+						// Move the focus only if the element is marked with
+						// the _cke_focus and it it's visible (check if it has
+						// width).
+						if ( link.getAttribute( '_cke_focus' ) && link.$.offsetWidth )
+						{
+							this._.focusIndex = index;
+							link.focus();
+							break;
+						}
+					}
+					return false;
+
+				case 'click' :
+					var index = this._.focusIndex,
+						link = index >= 0 && this.element.getElementsByTag( 'a' ).getItem( index );
+
+					if ( link )
+						link.$.click();
+
+					return false;
+			}
+		}
 	}
-};
+});
Index: /CKEditor/trunk/_source/plugins/panelbutton/plugin.js
===================================================================
--- /CKEditor/trunk/_source/plugins/panelbutton/plugin.js	(revision 3225)
+++ /CKEditor/trunk/_source/plugins/panelbutton/plugin.js	(revision 3226)
@@ -94,9 +94,11 @@
 				
 				ev = new CKEDITOR.dom.event( ev ); 
+
 				var keystroke = ev.getKeystroke();
 				switch ( keystroke )
 				{
-					case 13 :					// ENTER
-					case 32 :					// SPACE
+					case 13 :	// ENTER
+					case 32 :	// SPACE
+					case 40 :	// ARROW-DOWN
 						// Show panel  
 						CKEDITOR.tools.callFunction( clickFn, element );
@@ -106,4 +108,5 @@
 						instance.onkey( instance,  keystroke );
 				}
+
 				// Avoid subsequent focus grab on editor document.
 				ev.preventDefault();
@@ -191,4 +194,11 @@
 						me.onClose();
 				};
+
+			panel.onEscape = function()
+				{
+					panel.hide();
+					me.document.getById( _.id ).focus();
+				};
+
 			
 			if ( this.onBlock )
Index: /CKEditor/trunk/_source/plugins/richcombo/plugin.js
===================================================================
--- /CKEditor/trunk/_source/plugins/richcombo/plugin.js	(revision 3225)
+++ /CKEditor/trunk/_source/plugins/richcombo/plugin.js	(revision 3226)
@@ -121,25 +121,27 @@
 				execute : clickFn
 			};
-			
-			var keyDownFn = CKEDITOR.tools.addFunction( function( ev, element ){
-				
-				ev = new CKEDITOR.dom.event( ev ); 
-				var keystroke = ev.getKeystroke();
-				switch ( keystroke )
-				{
-					case 13 :					// ENTER
-					case 32 :					// SPACE
-						// Show panel  
-						CKEDITOR.tools.callFunction( clickFn, element );
-						break;
-					default :
-						// Delegate the default behavior to toolbar button key handling.
-						instance.onkey( instance,  keystroke );
-				}
-				
-				// Avoid subsequent focus grab on editor document.
-				ev.preventDefault();
-			});
-			
+
+			var keyDownFn = CKEDITOR.tools.addFunction( function( ev, element )
+				{
+					ev = new CKEDITOR.dom.event( ev );
+
+					var keystroke = ev.getKeystroke();
+					switch ( keystroke )
+					{
+						case 13 :	// ENTER
+						case 32 :	// SPACE
+						case 40 :	// ARROW-DOWN
+							// Show panel
+							CKEDITOR.tools.callFunction( clickFn, element );
+							break;
+						default :
+							// Delegate the default behavior to toolbar button key handling.
+							instance.onkey( instance,  keystroke );
+					}
+
+					// Avoid subsequent focus grab on editor document.
+					ev.preventDefault();
+				});
+
 			output.push(
 				'<span class="cke_rcombo">',
@@ -203,4 +205,6 @@
 
 					me.document.getById( 'cke_' + me.id ).addClass( 'cke_on');
+					
+					list.focus( !me.multiSelect && me.getValue() );
 
 					me._.on = 1;
@@ -221,4 +225,10 @@
 					if ( me.onClose )
 						me.onClose();
+				};
+
+			panel.onEscape = function()
+				{
+					panel.hide();
+					me.document.getById( 'cke_' + me.id ).getFirst().getNext().focus();
 				};
 
@@ -289,5 +299,5 @@
 		{
 			this._.items[ value ] = text || value;
-			this._.list.add( value, html );
+			this._.list.add( value, html, text );
 		},
 
Index: /CKEditor/trunk/_source/skins/default/panel.css
===================================================================
--- /CKEditor/trunk/_source/skins/default/panel.css	(revision 3225)
+++ /CKEditor/trunk/_source/skins/default/panel.css	(revision 3226)
@@ -155,5 +155,7 @@
 }
 
-a:hover.cke_colorbox
+a:hover.cke_colorbox,
+a:focus.cke_colorbox,
+a:active.cke_colorbox
 {
     border: #316ac5 1px solid;
@@ -170,5 +172,9 @@
 
 a:hover.cke_colorauto,
-a:hover.cke_colormore
+a:hover.cke_colormore,
+a:focus.cke_colorauto,
+a:focus.cke_colormore,
+a:active.cke_colorauto,
+a:active.cke_colormore
 {
     border: #316ac5 1px solid;
