Index: _source/core/config.js
===================================================================
--- _source/core/config.js	(revision 5774)
+++ _source/core/config.js	(working copy)
@@ -330,4 +330,19 @@
 	baseFloatZIndex : 10000
 };
 
+/**
+ * Indicates that some of the editor features, like alignement and text
+ * direction, should used the "computed value" of the feature to indicate it's
+ * on/off state, instead of using the "real value".
+ *
+ * If enabled, in a left to right written document, the "Left Justify"
+ * alignment button will show as active, even if the aligment style is not
+ * explicitly applied to the current paragraph in the editor.
+ * @name CKEDITOR.config.useComputedState
+ * @type Boolean
+ * @default true
+ * @example
+ * config.useComputedState = false;
+ */
+
 // PACKAGER_RENAME( CKEDITOR.config )
Index: _source/plugins/bidi/plugin.js
===================================================================
--- _source/plugins/bidi/plugin.js	(revision 5774)
+++ _source/plugins/bidi/plugin.js	(working copy)
@@ -17,31 +17,46 @@
 
 	function getState( editor, path, dir )
 	{
-		var selection = editor.getSelection(),
-			ranges = selection.getRanges();
+		var useComputedState = editor.config.useComputedState,
+			selectedElement;
 
-		var selectedElement = ranges && ranges[ 0 ].getEnclosedNode();
+		useComputedState = useComputedState === undefined || useComputedState;
 
-		// If this is not our element of interest, apply to fully selected elements from guardElements.
-		if ( !selectedElement || selectedElement
-				&& !( selectedElement.type == CKEDITOR.NODE_ELEMENT && selectedElement.getName() in directSelectionGuardElements )
-			)
-			selectedElement = getFullySelected( selection, guardElements );
+		if ( useComputedState )
+		{
+			var selection = editor.getSelection(),
+				ranges = selection.getRanges();
 
+			selectedElement = ranges && ranges[ 0 ].getEnclosedNode();
+
+			// If this is not our element of interest, apply to fully selected elements from guardElements.
+			if ( !selectedElement || selectedElement
+					&& !( selectedElement.type == CKEDITOR.NODE_ELEMENT && selectedElement.getName() in directSelectionGuardElements )
+				)
+				selectedElement = getFullySelected( selection, guardElements );
+		}
+
 		selectedElement = selectedElement || path.block || path.blockLimit;
 
 		if ( !selectedElement || selectedElement.getName() == 'body' )
 			return CKEDITOR.TRISTATE_OFF;
 
-		return ( selectedElement.getComputedStyle( 'direction' ) == dir ) ?
+		selectedElement = useComputedState ?
+			selectedElement.getComputedStyle( 'direction' ) :
+			selectedElement.getStyle( 'direction' ) || selectedElement.getAttribute( 'dir' );
+
+		return ( selectedElement == dir ) ?
 			CKEDITOR.TRISTATE_ON : CKEDITOR.TRISTATE_OFF;
 	}
 
 	function switchDir( element, dir, editor )
 	{
-		var dirBefore = element.getComputedStyle( 'direction' );
+		var dirBefore = element.getComputedStyle( 'direction' ),
+			currentDir = element.getStyle( 'direction' ) || element.getAttribute( 'dir' ) || '';
 
-		if ( element.hasAttribute( 'dir' ) && element.getAttribute( 'dir' ).toLowerCase() == dir )
+		element.removeStyle( 'direction' );
+
+		if ( currentDir.toLowerCase() == dir )
 			element.removeAttribute( 'dir' );
 		else
 			element.setAttribute( 'dir', dir );
Index: _source/plugins/justify/plugin.js
===================================================================
--- _source/plugins/justify/plugin.js	(revision 5774)
+++ _source/plugins/justify/plugin.js	(working copy)
@@ -18,12 +18,26 @@
 		if ( !firstBlock || firstBlock.getName() == 'body' )
 			return CKEDITOR.TRISTATE_OFF;
 
-		var currentAlign = firstBlock.getComputedStyle( 'text-align' ).replace( alignRemoveRegex, '' );
-		if ( ( !currentAlign && isDefaultAlign( this, firstBlock ) ) || currentAlign == this.value )
-			return CKEDITOR.TRISTATE_ON;
-		return CKEDITOR.TRISTATE_OFF;
+		return ( getAlignment( firstBlock, editor.config.useComputedState ) == this.value ) ? 
+			CKEDITOR.TRISTATE_ON : 
+			CKEDITOR.TRISTATE_OFF;
 	}
 
+	function getAlignment( element, useComputedState )
+	{
+		useComputedState = useComputedState === undefined || useComputedState;
+
+		var align = useComputedState ?
+			element.getComputedStyle( 'text-align' ) :
+			element.getStyle( 'text-align' ) || element.getAttribute( 'align' ) || '';
+
+		align && ( align = align.replace( /-moz-|-webkit-|start|auto/i, '' ) );
+
+		!align && useComputedState && ( align = element.getComputedStyle( 'direction' ) == 'rtl' ? 'right' : 'left' );
+
+		return align;
+	}
+
 	function onSelectionChange( evt )
 	{
 		var command = evt.editor.getCommand( this.name );
@@ -31,14 +45,6 @@
 		command.fire( 'state' );
 	}
 
-	function isDefaultAlign( command, element )
-	{
-		var direction = element.getComputedStyle( 'direction' ),
-			val = command.value;
-		return ( direction == 'rtl' && val == 'right' ) || ( direction == 'ltr' && val == 'left' );
-
-	}
-
 	function justifyCommand( editor, name, value )
 	{
 		this.name = name;
@@ -79,10 +85,13 @@
 			var bookmarks = selection.createBookmarks(),
 				ranges = selection.getRanges( true );
 
-
 			var cssClassName = this.cssClassName,
 				iterator,
 				block;
+
+			var useComputedState = editor.config.useComputedState;
+			useComputedState = useComputedState === undefined || useComputedState;
+
 			for ( var i = ranges.length - 1 ; i >= 0 ; i-- )
 			{
 				iterator = ranges[ i ].createIterator();
@@ -91,28 +100,26 @@
 				while ( ( block = iterator.getNextParagraph() ) )
 				{
 					block.removeAttribute( 'align' );
+					block.removeStyle( 'text-align' );
 
-					var isDefault = isDefaultAlign( this, block );
+					// Remove any of the alignment classes from the className.
+					var className = cssClassName && ( block.$.className =
+						CKEDITOR.tools.ltrim( block.$.className.replace( this.cssClassRegex, '' ) ) );
 
+					var apply =
+						( this.state == CKEDITOR.TRISTATE_OFF ) &&
+						( !useComputedState || ( getAlignment( block, true ) == this.value ) );
+
 					if ( cssClassName )
 					{
-						// Remove any of the alignment classes from the className.
-						var className = block.$.className =
-							CKEDITOR.tools.ltrim( block.$.className.replace( this.cssClassRegex, '' ) );
-
 						// Append the desired class name.
-						if ( this.state == CKEDITOR.TRISTATE_OFF && !isDefault )
+						if ( apply )
 							block.addClass( cssClassName );
 						else if ( !className )
 							block.removeAttribute( 'class' );
 					}
-					else
-					{
-						if ( this.state == CKEDITOR.TRISTATE_OFF && !isDefault )
-							block.setStyle( 'text-align', this.value );
-						else
-							block.removeStyle( 'text-align' );
-					}
+					else if ( apply )
+						block.setStyle( 'text-align', this.value );
 				}
 
 			}
