docs: function getTextificationFilter( editor ) {
  		var filter = new CKEDITOR.htmlParser.filter();
  
  		// Elements which creates vertical breaks (have vert margins) - took from HTML5 spec.
  		// http://dev.w3.org/html5/markup/Overview.html#toc
  		var replaceWithParaIf = { blockquote: 1, dl: 1, fieldset: 1, h1: 1, h2: 1, h3: 1, h4: 1, h5: 1, h6: 1, ol: 1, p: 1, table: 1, ul: 1 },
  
  			// All names except of <br>.
  			stripInlineIf = CKEDITOR.tools.extend( { br: 0 }, CKEDITOR.dtd.$inline ),
  
  			// What's finally allowed (cke:br will be removed later).
  			allowedIf = { p: 1, br: 1, 'cke:br': 1 },
  
  			knownIf = CKEDITOR.dtd,
  
  			// All names that will be removed (with content).
  			removeIf = CKEDITOR.tools.extend( { area: 1, basefont: 1, embed: 1, iframe: 1, map: 1, object: 1, param: 1 }, CKEDITOR.dtd.$nonBodyContent, CKEDITOR.dtd.$cdata );
  
  		var flattenTableCell = function( element ) {
  				delete element.name;
  				element.add( new CKEDITOR.htmlParser.text( ' ' ) );
  			},
  			// Squash adjacent headers into one. <h1>A</h1><h2>B</h2> -> <h1>A<br>B</h1><h2></h2>
  			// Empty ones will be removed later.
  			squashHeader = function( element ) {
  				var next = element,
  					br, el;
  
  				while ( ( next = next.next ) && next.name && next.name.match( /^h\d$/ ) ) {
  					// TODO shitty code - waitin' for htmlParse.element fix.
  					br = new CKEDITOR.htmlParser.element( 'cke:br' );
  					br.isEmpty = true;
  					element.add( br );
  					while ( ( el = next.children.shift() ) )
  						element.add( el );
  				}
  			};
  
  		filter.addRules( {
  			elements: {
  				h1: squashHeader,
  				h2: squashHeader,
  				h3: squashHeader,
  				h4: squashHeader,
  				h5: squashHeader,
  				h6: squashHeader,
  
  				img: function( element ) {
  					var alt = CKEDITOR.tools.trim( element.attributes.alt || '' ),
  						txt = ' ';
  
  					// Replace image with its alt if it doesn't look like an url or is empty.
  					if ( alt && !alt.match( /(^http|\.(jpe?g|gif|png))/i ) )
  						txt = ' [' + alt + '] ';
  
  					return new CKEDITOR.htmlParser.text( txt );
  				},
  
  				td: flattenTableCell,
  				th: flattenTableCell,
  
  				$: function( element ) {
  					var initialName = element.name,
  						br;
  
  					// Remove entirely.
  					if ( removeIf[ initialName ] )
  						return false;
  
  					// Remove all attributes.
  					element.attributes = {};
  
  					// Pass brs.
  					if ( initialName == 'br' )
  						return element;
  
  					// Elements that we want to replace with paragraphs.
  					if ( replaceWithParaIf[ initialName ] )
  						element.name = 'p';
  
  					// Elements that we want to strip (tags only, without the content).
  					else if ( stripInlineIf[ initialName ] )
  						delete element.name;
  
  					// Surround other known element with <brs> and strip tags.
  					else if ( knownIf[ initialName ] ) {
  						// TODO shitty code - waitin' for htmlParse.element fix.
  						br = new CKEDITOR.htmlParser.element( 'cke:br' );
  						br.isEmpty = true;
  
  						// Replace hrs (maybe sth else too?) with only one br.
  						if ( CKEDITOR.dtd.$empty[ initialName ] )
  							return br;
  
  						element.add( br, 0 );
  						br = br.clone();
  						br.isEmpty = true;
  						element.add( br );
  						delete element.name;
  					}
  
  					// Final cleanup - if we can still find some not allowed elements then strip their names.
  					if ( !allowedIf[ element.name ] )
  						delete element.name;
  
  					return element;
  				}
  			}
  		}, {
  			// Apply this filter to every element.
  			applyToAll: true
  		} );
  
  		return filter;
  	}