Index: /CKEditor/trunk/CHANGES.html
===================================================================
--- /CKEditor/trunk/CHANGES.html	(revision 5969)
+++ /CKEditor/trunk/CHANGES.html	(revision 5970)
@@ -79,5 +79,6 @@
 		<li><a href="http://dev.ckeditor.com/ticket/6416">#6416</a> : [IE9] Unable to make text selection with mouse in source area.</li>
 		<li><a href="http://dev.ckeditor.com/ticket/6099">#6099</a> : BIDI: when we apply explicit language direction to Numbered/Bulleted List the corresponding BIDI Tool bar icon is not highlighted in the Toolbar.</li>
-		<li><a href="http://dev.ckeditor.com/ticket/6100">#6100</a> : BIDI: when we change Table language direction indentation of text in Table cells is not applied correctly..</li>
+		<li><a href="http://dev.ckeditor.com/ticket/6100">#6100</a> : BIDI: when we change Table language direction indentation of text in Table cells is not applied correctly.</li>
+		<li><a href="http://dev.ckeditor.com/ticket/6376">#6376</a> : BIDI: BIDI buttons should not toggle the base language direction.</li>
 		<li>Updated the following language files:<ul>
 			<li><a href="http://dev.ckeditor.com/ticket/6427">#6427</a> : Ukrainian;</li>
Index: /CKEditor/trunk/_source/plugins/bidi/plugin.js
===================================================================
--- /CKEditor/trunk/_source/plugins/bidi/plugin.js	(revision 5969)
+++ /CKEditor/trunk/_source/plugins/bidi/plugin.js	(revision 5970)
@@ -75,12 +75,47 @@
 	}
 
-	function switchDir( element, dir, editor, state )
-	{
-		var dirBefore = element.getComputedStyle( 'direction' );
-
+	function switchDir( element, dir, editor, database )
+	{
+		// Mark this element as processed by switchDir.
+		CKEDITOR.dom.element.setMarker( database, element, 'bidi_processed', 1 );
+
+		// Check whether one of the ancestors has already been styled.
+		var parent = element;
+		while ( ( parent = parent.getParent() ) && !parent.is( 'body' ) )
+		{
+			if ( parent.getCustomData( 'bidi_processed' ) )
+			{
+				// Ancestor style must dominate.
+				element.removeStyle( 'direction' );
+				element.removeAttribute( 'dir' );
+				return null;
+			}
+		}
+
+		var useComputedState = ( 'useComputedState' in editor.config ) ? editor.config.useComputedState : 1;
+		
+		var elementDir = useComputedState ? element.getComputedStyle( 'direction' )
+			: element.getStyle( 'direction' ) || element.hasAttribute( 'dir' );
+
+		// Stop if direction is same as present.
+		if ( elementDir == dir )
+			return null;
+
+		// Reuse computedState if we already have it.
+		var dirBefore = useComputedState ? elementDir : element.getComputedStyle( 'direction' );
+
+		// Clear direction on this element.
 		element.removeStyle( 'direction' );
-		element.removeAttribute( 'dir' );
-
-		if ( state == CKEDITOR.TRISTATE_OFF && element.getComputedStyle( 'direction' ).toLowerCase() != dir )
+
+		// Do the second check when computed state is ON, to check 
+		// if we need to apply explicit direction on this element.
+		if ( useComputedState )
+		{
+			element.removeAttribute( 'dir' );
+			if ( dir != element.getComputedStyle( 'direction' ) )
+				element.setAttribute( 'dir', dir );
+		}
+		else
+			// Set new direction for this element.
 			element.setAttribute( 'dir', dir );
 
@@ -88,9 +123,10 @@
 		// the element and all its children, so it will get really reflected
 		// like a mirror. (#5910)
-		var dirAfter = element.getComputedStyle( 'direction' );
-		if ( dirAfter != dirBefore )
+		if ( dir != dirBefore )
 			editor.fire( 'dirChanged', element );
 
 		editor.forceNextSelectionCheck();
+
+		return null;
 	}
 
@@ -119,4 +155,5 @@
 			if ( ranges && ranges.length )
 			{
+				var database = {};
 				// Apply do directly selected elements from guardElements.
 				var selectedElement = ranges[ 0 ].getEnclosedNode();
@@ -128,74 +165,39 @@
 					selectedElement = getFullySelected( selection, guardElements );
 
-				if ( selectedElement )
+				if ( selectedElement && !selectedElement.isReadOnly() )
+					switchDir( selectedElement, dir, editor, database );
+				
+				// Creates bookmarks for selection, as we may split some blocks.
+				var bookmarks = selection.createBookmarks();
+
+				var iterator,
+					block;
+
+				for ( var i = ranges.length - 1 ; i >= 0 ; i-- )
 				{
-					if ( !selectedElement.isReadOnly() )
-						switchDir( selectedElement, dir, editor, this.state );
-				}
-				else
-				{
-					// Creates bookmarks for selection, as we may split some blocks.
-					var bookmarks = selection.createBookmarks();
-
-					var iterator,
-						block;
-
-					for ( var i = ranges.length - 1 ; i >= 0 ; i-- )
+					// Array of elements processed as guardElements.
+					var processedElements = [];
+					// Walker searching for guardElements.
+					var walker = new CKEDITOR.dom.walker( ranges[ i ] );
+					walker.evaluator = function( node )
 					{
-						// Array of elements processed as guardElements.
-						var processedElements = [];
-						// Walker searching for guardElements.
-						var walker = new CKEDITOR.dom.walker( ranges[ i ] );
-						walker.evaluator = function( node ){
-							return node.type == CKEDITOR.NODE_ELEMENT
-								&& node.getName() in guardElements
-								&& !( node.getName() == ( enterMode == CKEDITOR.ENTER_P ) ? 'p' : 'div'
-									&& node.getParent().type == CKEDITOR.NODE_ELEMENT
-									&& node.getParent().getName() == 'blockquote'
-								);
-						};
-
-						while ( ( block = walker.next() ) )
-						{
-							switchDir( block, dir, editor, this.state );
-							processedElements.push( block );
-						}
-
-						iterator = ranges[ i ].createIterator();
-						iterator.enlargeBr = enterMode != CKEDITOR.ENTER_BR;
-
-						while ( ( block = iterator.getNextParagraph( enterMode == CKEDITOR.ENTER_P ? 'p' : 'div' ) ) )
-						{
-							if ( block.isReadOnly() )
-								continue;
-
-							var _break = 0;
-
-							// Check if block have been already processed by the walker above.
-							for ( var ii = 0; ii < processedElements.length; ii++ )
-							{
-								var parent = block.getParent();
-
-								while( parent && parent.getName() != 'body' )
-								{
-									if ( ( parent.$.isSameNode && parent.$.isSameNode( processedElements[ ii ].$ ) )
-											|| parent.$ == processedElements[ ii ].$ )
-									{
-										_break = 1;
-										break;
-									}
-									parent = parent.getParent();
-								}
-
-								if ( _break )
-									break;
-							}
-
-							if ( !_break )
-							{
-								switchDir( block, dir, editor, this.state );
-							}
-						}
-					}
+						return node.type == CKEDITOR.NODE_ELEMENT
+							&& node.getName() in guardElements
+							&& !( node.getName() == ( enterMode == CKEDITOR.ENTER_P ) ? 'p' : 'div'
+								&& node.getParent().type == CKEDITOR.NODE_ELEMENT
+								&& node.getParent().getName() == 'blockquote'
+							);
+					};
+
+					while ( ( block = walker.next() ) )
+						switchDir( block, dir, editor, database );
+
+					iterator = ranges[ i ].createIterator();
+					iterator.enlargeBr = enterMode != CKEDITOR.ENTER_BR;
+
+					while ( ( block = iterator.getNextParagraph( enterMode == CKEDITOR.ENTER_P ? 'p' : 'div' ) ) )
+						!block.isReadOnly() && switchDir( block, dir, editor, database );
+
+					CKEDITOR.dom.element.clearAllMarkers( database );
 
 					editor.forceNextSelectionCheck();
