Index: /CKEditor/trunk/_source/core/dom/element.js
===================================================================
--- /CKEditor/trunk/_source/core/dom/element.js	(revision 3310)
+++ /CKEditor/trunk/_source/core/dom/element.js	(revision 3311)
@@ -988,5 +988,8 @@
 		removeStyle : function( name )
 		{
-			this.setStyle( name, '' );
+			if ( this.$.style.removeAttribute )
+				this.$.style.removeAttribute( CKEDITOR.tools.cssStyleToDomStyle( name ) );
+			else
+				this.setStyle( name, '' );
 
 			if ( !this.$.style.cssText )
Index: /CKEditor/trunk/_source/core/test.js
===================================================================
--- /CKEditor/trunk/_source/core/test.js	(revision 3310)
+++ /CKEditor/trunk/_source/core/test.js	(revision 3311)
@@ -59,5 +59,13 @@
 	getInnerHtml : function( elementOrId )
 	{
-		var html = ( elementOrId.nodeType ? elementOrId : document.getElementById( elementOrId ) ).innerHTML;
+		var html;
+		
+		if ( typeof elementOrId == 'string' )
+			html = document.getElementById( elementOrId ).innerHTML;
+		else if ( elementOrId.getHtml )
+			html = elementOrId.getHtml();
+		else
+			html = elementOrId.innerHTML || '';
+
 		html = html.toLowerCase();
 		html = html.replace( /[\n\r]/g, '' );
Index: /CKEditor/trunk/_source/plugins/styles/plugin.js
===================================================================
--- /CKEditor/trunk/_source/plugins/styles/plugin.js	(revision 3310)
+++ /CKEditor/trunk/_source/plugins/styles/plugin.js	(revision 3311)
@@ -354,5 +354,5 @@
 						// Non element nodes, or empty elements can be added
 						// completely to the range.
-						if ( nodeType == CKEDITOR.NODE_TEXT || ( nodeType == CKEDITOR.NODE_ELEMENT && !currentNode.getChildCount() && currentNode.$.offsetWidth ) )
+						if ( nodeType == CKEDITOR.NODE_TEXT || ( nodeType == CKEDITOR.NODE_ELEMENT && !currentNode.getChildCount() ) )
 						{
 							var includedNode = currentNode;
Index: /CKEditor/trunk/_source/tests/plugins/styles/styles.html
===================================================================
--- /CKEditor/trunk/_source/tests/plugins/styles/styles.html	(revision 3310)
+++ /CKEditor/trunk/_source/tests/plugins/styles/styles.html	(revision 3311)
@@ -421,12 +421,73 @@
 		},
 
+		test_ticket_3091 : function()
+		{
+			var element = doc.getById( '_P1' );
+			element.setHtml( 'outter<table><tr><td>text</td></tr></table>outter' );
+
+			var range = new CKEDITOR.dom.range( doc );
+			range.selectNodeContents( element );
+			
+			var styleDef = 
+			{
+				element		: 'span',
+				styles		: { 'font-family' : '#(family)' },
+				overrides	: [ { element : 'font', attributes : { 'face' : null } } ]
+			};
+
+			var style = new CKEDITOR.style( styleDef, { 'family' : 'Arial,Helvetica,sans-serif' } );
+			style.applyToRange( range );
+
+			style = new CKEDITOR.style( styleDef, { 'family' : 'Comic Sans MS,cursive' } );
+			style.applyToRange( range );
+
+			style = new CKEDITOR.style( styleDef, { 'family' : 'Courier New,Courier,monospace' } );
+			style.applyToRange( range );
+
+			assert.areSame( '<span style="font-family:couriernew,courier,monospace;">outter</span><table><tbody><tr><td><span style="font-family:couriernew,courier,monospace;">text</span></td></tr></tbody></table><span style="font-family:couriernew,courier,monospace;">outter</span>', getInnerHtml( element ) );
+		},
+
+		test_ticket_3091_2 : function()
+		{
+			var element = doc.getById( '_P1' );
+			element.setHtml( 'outter<p>text</p>outter' );
+
+			var range = new CKEDITOR.dom.range( doc );
+			range.selectNodeContents( element );
+
+			var style = new CKEDITOR.style( { element : 'i', attributes : { title : 'x' } } );
+			style.applyToRange( range );
+
+			assert.areSame( '<i title="x">outter</i><p><i title="x">text</i></p><i title="x">outter</i>', getInnerHtml( element ), 'First step failed' );
+
+			style = new CKEDITOR.style( { element : 'i', attributes : { title : 'y' } } );
+			style.applyToRange( range );
+
+			assert.areSame( '<i title="y">outter</i><p><i title="y">text</i></p><i title="y">outter</i>', getInnerHtml( element ), 'Second step failed' );
+
+			style = new CKEDITOR.style( { element : 'i', attributes : { title : 'z' } } );
+			style.applyToRange( range );
+
+			assert.areSame( '<i title="z">outter</i><p><i title="z">text</i></p><i title="z">outter</i>', getInnerHtml( element ), 'Third step failed' );
+		},
+
+		// TC based on the state of the second step in the above test, before it got fixed.
+		test_ticket_3091_3 : function()
+		{
+			var element = doc.getById( '_P1' );
+			element.setHtml( '<p><i title="y">text</i><i title="x"></i></p><i title="y">outter</i><i title="x"></i>' );
+
+			var range = new CKEDITOR.dom.range( doc );
+			range.selectNodeContents( element );
+
+			var style = new CKEDITOR.style( { element : 'i', attributes : { title : 'z' } } );
+			style.applyToRange( range );
+
+			assert.areSame( '<p><i title="z">text</i></p><i title="z">outter</i>', getInnerHtml( element ) );
+		},
+
 		name : document.title
 	};
 })() );
-
-//window.onload = function()
-//{
-//	testCase.test_checkElementRemovable8();
-//}
 
 	//]]>
@@ -434,5 +495,5 @@
 </head>
 <body>
-	<p id="_P1"></p>
+	<div id="_P1"></div>
 </body>
 </html>
