Index: _source/core/dom/element.js
===================================================================
--- _source/core/dom/element.js	(revision 3208)
+++ _source/core/dom/element.js	(working copy)
@@ -311,7 +311,13 @@
 		 */
 		focus : function()
 		{
-			this.$.focus();
+			// IE throws error if the element is not visible.
+			try
+			{
+				this.$.focus();
+			}
+			catch (e)
+			{}
 		},
 
 		/**
Index: _source/core/dom/nodelist.js
===================================================================
--- _source/core/dom/nodelist.js	(revision 3208)
+++ _source/core/dom/nodelist.js	(working copy)
@@ -17,6 +17,7 @@
 
 	getItem : function( index )
 	{
-		return new CKEDITOR.dom.node( this.$[ index ] );
+		var $node = this.$[ index ];
+		return $node ? new CKEDITOR.dom.node( $node ) : null;
 	}
 };
Index: _source/plugins/colorbutton/plugin.js
===================================================================
--- _source/plugins/colorbutton/plugin.js	(revision 3208)
+++ _source/plugins/colorbutton/plugin.js	(working copy)
@@ -37,6 +37,13 @@
 						block.autoSize = true;
 						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
 					},
 
 					onOpen : function()
@@ -93,7 +100,8 @@
 
 			// 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, '\')">' +
 					'<table cellspacing=0 cellpadding=0 width="100%">' +
@@ -118,7 +126,8 @@
 				var color = colors[ i ];
 				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, '\')">' +
 							'<span class="cke_colorbox" style="background-color:#', color, '"></span>' +
@@ -133,7 +142,8 @@
 					'</tr>' +
 					'<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, '\')">',
 								lang.more,
Index: _source/plugins/floatpanel/plugin.js
===================================================================
--- _source/plugins/floatpanel/plugin.js	(revision 3208)
+++ _source/plugins/floatpanel/plugin.js	(working copy)
@@ -150,6 +150,12 @@
 						iframe.$.contentWindow.focus();
 					}, 0);
 
+				panel.onEscape = CKEDITOR.tools.bind( function()
+					{
+						this.onEscape && this.onEscape();
+					},
+					this );
+
 				if ( this.onShow )
 					this.onShow.call( this );
 			},
Index: _source/plugins/listblock/plugin.js
===================================================================
--- _source/plugins/listblock/plugin.js	(revision 3208)
+++ _source/plugins/listblock/plugin.js	(working copy)
@@ -24,6 +24,13 @@
 					this.base( blockHolder );
 
 					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 = {};
@@ -65,10 +72,10 @@
 
 				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 )
 						{
@@ -78,18 +85,26 @@
 
 						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>' );
 					},
 
 					startGroup : function( title )
 					{
 						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>' );
 					},
 
 					commit : function()
@@ -112,7 +127,7 @@
 
 					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();
 
 						if ( group )
@@ -126,7 +141,7 @@
 
 					hideItem : function( value )
 					{
-						this.element.getDocument().getById( 'cke_' + this._.items[ value ] ).setStyle( 'display', 'none' );
+						this.element.getDocument().getById( this._.items[ value ] ).setStyle( 'display', 'none' );
 					},
 
 					showAll : function()
@@ -137,12 +152,12 @@
 
 						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();
 
 							group.setStyle( 'display', '' );
@@ -157,12 +172,12 @@
 						if ( !this.multiSelect )
 							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' );
 					},
 
 					unmarkAll : function()
@@ -172,13 +187,42 @@
 
 						for ( var value in items )
 						{
-							doc.getById( 'cke_' + items[ value ] ).removeClass( 'cke_selected' );
+							doc.getById( items[ value ] ).removeClass( 'cke_selected' );
 						}
 					},
 
 					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: _source/plugins/panel/plugin.js
===================================================================
--- _source/plugins/panel/plugin.js	(revision 3208)
+++ _source/plugins/panel/plugin.js	(working copy)
@@ -138,6 +138,22 @@
 					},
 					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();
 			}
 			else
@@ -175,37 +191,107 @@
 
 		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();
 
 		return block;
 	}
 };
 
-CKEDITOR.ui.panel.block = function( blockHolder )
+CKEDITOR.ui.panel.block = CKEDITOR.tools.createClass(
 {
-	this.element = blockHolder.append(
-		blockHolder.getDocument().createElement( 'div',
-			{
-				attributes :
+	$ : function( blockHolder )
+	{
+		this.element = blockHolder.append(
+			blockHolder.getDocument().createElement( 'div',
 				{
-					'class' : 'cke_panel_block'
-				},
-				styles :
-				{
-					display : 'none'
-				}
-			}) );
-};
+					attributes :
+					{
+						'class' : 'cke_panel_block'
+					},
+					styles :
+					{
+						display : 'none'
+					}
+				}) );
+		
+		this.keys = {};
+		
+		this._.focusIndex = -1;
+	},
+	
+	_ : {},
 
-CKEDITOR.ui.panel.block.prototype =
-{
-	show : function()
+	proto :
 	{
-		this.element.setStyle( 'display', '' );
-	},
+		show : function()
+		{
+			this.element.setStyle( 'display', '' );
+		},
 
-	hide : function()
-	{
-		this.element.setStyle( 'display', 'none' );
+		hide : function()
+		{
+			this.element.setStyle( 'display', 'none' );
+		},
+
+		onKeyDown : function( keystroke )
+		{
+			var keyAction = this.keys[ keystroke ];
+			switch ( keyAction )
+			{
+				// 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: _source/plugins/panelbutton/plugin.js
===================================================================
--- _source/plugins/panelbutton/plugin.js	(revision 3208)
+++ _source/plugins/panelbutton/plugin.js	(working copy)
@@ -93,11 +93,13 @@
 			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 13 :	// ENTER
+					case 32 :	// SPACE
+					case 40 :	// ARROW-DOWN
 						// Show panel  
 						CKEDITOR.tools.callFunction( clickFn, element );
 						break;
@@ -105,6 +107,7 @@
 						// Delegate the default behavior to toolbar button key handling.
 						instance.onkey( instance,  keystroke );
 				}
+
 				// Avoid subsequent focus grab on editor document.
 				ev.preventDefault();
 			});
@@ -190,6 +193,13 @@
 					if ( me.onClose )
 						me.onClose();
 				};
+
+			panel.onEscape = function()
+				{
+					panel.hide();
+					me.document.getById( _.id ).focus();
+				};
+
 			
 			if ( this.onBlock )
 				this.onBlock( panel, _.id );
Index: _source/plugins/richcombo/plugin.js
===================================================================
--- _source/plugins/richcombo/plugin.js	(revision 3208)
+++ _source/plugins/richcombo/plugin.js	(working copy)
@@ -120,27 +120,29 @@
 				},
 				execute : clickFn
 			};
-			
-			var keyDownFn = CKEDITOR.tools.addFunction( function( ev, element ){
-				
-				ev = new CKEDITOR.dom.event( ev ); 
-				var keystroke = ev.getKeystroke();
-				switch ( keystroke )
+
+			var keyDownFn = CKEDITOR.tools.addFunction( function( ev, element )
 				{
-					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();
-			});
-			
+					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">',
 				'<span id=', id );
@@ -202,6 +204,8 @@
 						this.element.getFirst().addClass( me.className + '_panel' );
 
 					me.document.getById( 'cke_' + me.id ).addClass( 'cke_on');
+					
+					list.focus( !me.multiSelect && me.getValue() );
 
 					me._.on = 1;
 
@@ -222,6 +226,12 @@
 						me.onClose();
 				};
 
+			panel.onEscape = function()
+				{
+					panel.hide();
+					me.document.getById( 'cke_' + me.id ).getFirst().getNext().focus();
+				};
+
 			list.onClick = function( value, marked )
 				{
 					// Move the focus to the main windows, otherwise it will stay
@@ -288,7 +298,7 @@
 		add : function( value, html, text )
 		{
 			this._.items[ value ] = text || value;
-			this._.list.add( value, html );
+			this._.list.add( value, html, text );
 		},
 
 		startGroup : function( title )
Index: _source/skins/default/panel.css
===================================================================
--- _source/skins/default/panel.css	(revision 3208)
+++ _source/skins/default/panel.css	(working copy)
@@ -154,7 +154,9 @@
     float: left;
 }
 
-a:hover.cke_colorbox
+a:hover.cke_colorbox,
+a:focus.cke_colorbox,
+a:active.cke_colorbox
 {
     border: #316ac5 1px solid;
     background-color: #dff1ff;
@@ -169,7 +171,11 @@
 }
 
 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;
     background-color: #dff1ff;
