Index: /CKEditor/trunk/_source/core/htmlparser/fragment.js
===================================================================
--- /CKEditor/trunk/_source/core/htmlparser/fragment.js	(revision 3675)
+++ /CKEditor/trunk/_source/core/htmlparser/fragment.js	(revision 3676)
@@ -1,3 +1,3 @@
-﻿/*
+/*
 Copyright (c) 2003-2009, CKSource - Frederico Knabben. All rights reserved.
 For licensing, see LICENSE.html or http://ckeditor.com/license
@@ -65,4 +65,6 @@
 			pendingInline = [],
 			currentNode = fragment,
+		    // Indicate we're inside a <pre> element, spaces should be touched differently.
+			inPre = false,
 			returnPoint;
 
@@ -119,5 +121,6 @@
 
 			// Rtrim empty spaces on block end boundary. (#3585)
-			if ( element._.isBlockLike )
+			if ( element._.isBlockLike
+				 && inPre )
 			{
 
@@ -156,4 +159,11 @@
 			{
 				pendingInline.push( element );
+				return;
+			}
+			else if ( tagName == 'pre' )
+				inPre = true;
+			else if ( tagName == 'br' && inPre )
+			{
+				currentNode.add( new CKEDITOR.htmlParser.text( '\n' ) );
 				return;
 			}
@@ -264,4 +274,7 @@
 				currentNode = candidate;
 
+				if( currentNode.name == 'pre' )
+					inPre = false;
+
 				addElement( candidate, candidate.parent );
 
@@ -291,5 +304,6 @@
 		parser.onText = function( text )
 		{
-			if ( !currentNode._.hasInlineStarted )
+			// Trim empty spaces at beginning of element contents except <pre>.
+			if ( !currentNode._.hasInlineStarted && !inPre )
 			{
 				text = CKEDITOR.tools.ltrim( text );
@@ -303,4 +317,9 @@
 			if ( fixForBody && !currentNode.type )
 				this.onTagOpen( fixForBody, {} );
+
+			// Shrinking consequential spaces into one single for all elements 
+			// text contents.
+			if ( !inPre )
+				text = text.replace( /[\t\r\n ]{2,}|[\t\r\n]/g, ' ' );
 
 			currentNode.add( new CKEDITOR.htmlParser.text( text ) );
Index: /CKEditor/trunk/_source/core/htmlparser/text.js
===================================================================
--- /CKEditor/trunk/_source/core/htmlparser/text.js	(revision 3675)
+++ /CKEditor/trunk/_source/core/htmlparser/text.js	(revision 3676)
@@ -20,5 +20,5 @@
 		 * @example
 		 */
-		this.value = value.replace( spacesRegex, ' ' );
+		this.value = value;
 
 		/** @private */
@@ -47,5 +47,5 @@
 			var text = this.value;
 
-			if ( filter && !( text = filter.onText( text ) ) )
+			if ( filter && !( text = filter.onText( text, this ) ) )
 				return;
 
Index: /CKEditor/trunk/_source/plugins/htmldataprocessor/plugin.js
===================================================================
--- /CKEditor/trunk/_source/plugins/htmldataprocessor/plugin.js	(revision 3675)
+++ /CKEditor/trunk/_source/plugins/htmldataprocessor/plugin.js	(revision 3676)
@@ -66,5 +66,7 @@
 			delete blockLikeTags[i];
 	}
-
+	// We just avoid filler in <pre> right now.
+	// TODO: Support filler for <pre>, line break is also occupy line height.
+	delete blockLikeTags.pre;
 	var defaultDataFilterRules =
 	{
Index: /CKEditor/trunk/_source/plugins/htmlwriter/plugin.js
===================================================================
--- /CKEditor/trunk/_source/plugins/htmlwriter/plugin.js	(revision 3675)
+++ /CKEditor/trunk/_source/plugins/htmlwriter/plugin.js	(revision 3676)
@@ -79,9 +79,13 @@
 				});
 		}
-
 		this.setRules( 'br',
 			{
 				breakAfterOpen : true
 			});
+		// Disable indentation on <pre>.
+		this.setRules( 'pre',
+		{
+		  indent: false
+		} );
 	},
 
Index: /CKEditor/trunk/_source/tests/core/htmlparser/htmlparser.html
===================================================================
--- /CKEditor/trunk/_source/tests/core/htmlparser/htmlparser.html	(revision 3676)
+++ /CKEditor/trunk/_source/tests/core/htmlparser/htmlparser.html	(revision 3676)
@@ -0,0 +1,94 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html xmlns="http://www.w3.org/1999/xhtml">
+<head>
+	<title>CKEDITOR.htmlParser</title>
+	<link rel="stylesheet" type="text/css" href="../../test.css" />
+	<script type="text/javascript" src="../../../../ckeditor_source.js"></script> <!-- %REMOVE_LINE%
+	<script type="text/javascript" src="../../../ckeditor.js"></script>
+	%REMOVE_LINE% -->
+	<script type="text/javascript" src="../../test.js"></script>
+	<script type="text/javascript">
+	//<![CDATA[
+	
+CKEDITOR.plugins.load( 'htmlwriter' );
+var tc;
+CKEDITOR.test.addTestCase( tc = ( function()
+{
+	// Local reference to the "assert" object.
+	var assert = YAHOO.util.Assert;
+
+	/**
+	 * Wrapper of the combination of htmlParser with htmlWriter, for convenience of
+	 * testing, formatting of writer has been disabled.
+	 */
+	function htmlParse( htmlString , writerConfig)
+	{
+		var writer = new CKEDITOR.htmlParser.basicWriter();
+		writer.reset();
+		var fragment = CKEDITOR.htmlParser.fragment.fromHtml( htmlString );
+		fragment.writeHtml( writer );
+		return writer.getHtml();
+	}
+
+	/**
+	 * IE always returning CRLF for line-feed, so remove it when retrieving
+	 * pre-formated text from text area.
+	 */
+	function getTextAreaValue( id )
+	{
+		return CKEDITOR.document.getById( id ).getValue().replace( /\r/gi, '' );
+	}
+
+	return
+	{
+		/**
+		 * Test <pre> tag formatting.
+		 */
+		test_fromHtml_3715 : function()
+		{
+			assert.areSame( getTextAreaValue( 'htmlResult1' ),
+				htmlParse( getTextAreaValue( 'htmlOriginal1' ) ),
+				'<pre> parsing result doesn\'t match.' );
+		},
+
+		/**
+		 * Test compress empty spaces within text.
+		 */
+		test_fromHtml_3715_2 : function()
+		{
+			assert.areSame( getTextAreaValue( 'htmlResult2' ),
+				htmlParse( getTextAreaValue( 'htmlOriginal2' ) ),
+				'Spaces compressing result doesn\'t match.' );
+		},
+		name :document.title
+	};
+} )() );
+
+//window.onload = tc.test_fromHtml_3715;
+	//]]>
+	</script>
+</head>
+<body>
+	
+	<textarea id="htmlOriginal1"><pre>
+	text<b>
+inside<br /> <br /></b>
+
+pre
+</pre></textarea>
+	<textarea id="htmlResult1"><pre>
+	text<b>
+inside
+ 
+</b>
+
+pre
+</pre></textarea>
+
+<textarea id="htmlOriginal2"><p>
+	para		graph
+</p><b>compress   spaces</b></textarea>
+
+<textarea id="htmlResult2"><p>para graph </p><b>compress spaces</b></textarea>
+</body>
+</html>
