Index: /CKEditor/trunk/_source/tests/_assets/sample.css
===================================================================
--- /CKEditor/trunk/_source/tests/_assets/sample.css	(revision 2962)
+++ /CKEditor/trunk/_source/tests/_assets/sample.css	(revision 2962)
@@ -0,0 +1,4 @@
+﻿.sample
+{
+	position: absolute;
+}
Index: /CKEditor/trunk/_source/tests/_assets/sample.js
===================================================================
--- /CKEditor/trunk/_source/tests/_assets/sample.js	(revision 2962)
+++ /CKEditor/trunk/_source/tests/_assets/sample.js	(revision 2962)
@@ -0,0 +1,1 @@
+﻿var testVar = 'Test!';
Index: /CKEditor/trunk/_source/tests/_assets/sample.txt
===================================================================
--- /CKEditor/trunk/_source/tests/_assets/sample.txt	(revision 2962)
+++ /CKEditor/trunk/_source/tests/_assets/sample.txt	(revision 2962)
@@ -0,0 +1,1 @@
+Sample Text
Index: /CKEditor/trunk/_source/tests/_assets/sample.xml
===================================================================
--- /CKEditor/trunk/_source/tests/_assets/sample.xml	(revision 2962)
+++ /CKEditor/trunk/_source/tests/_assets/sample.xml	(revision 2962)
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<list>
+	<item id="test1" />
+	<item id="test2" />
+</list>
Index: /CKEditor/trunk/_source/tests/_assets/sample_xml.txt
===================================================================
--- /CKEditor/trunk/_source/tests/_assets/sample_xml.txt	(revision 2962)
+++ /CKEditor/trunk/_source/tests/_assets/sample_xml.txt	(revision 2962)
@@ -0,0 +1,5 @@
+<?xml version="1.0" encoding="utf-8" ?>
+<list>
+	<item id="test1" />
+	<item id="test2" />
+</list>
Index: /CKEditor/trunk/_source/tests/core/_editor/custom_config_1.js
===================================================================
--- /CKEditor/trunk/_source/tests/core/_editor/custom_config_1.js	(revision 2962)
+++ /CKEditor/trunk/_source/tests/core/_editor/custom_config_1.js	(revision 2962)
@@ -0,0 +1,10 @@
+/*
+Copyright (c) 2003-2009, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.html or http://ckeditor.com/license
+*/
+
+CKEDITOR.editorConfig = function( config )
+{
+	config.customConfig = '_editor/custom_config_2.js';
+	config.test_custom1 = 'Ok';
+};
Index: /CKEditor/trunk/_source/tests/core/_editor/custom_config_2.js
===================================================================
--- /CKEditor/trunk/_source/tests/core/_editor/custom_config_2.js	(revision 2962)
+++ /CKEditor/trunk/_source/tests/core/_editor/custom_config_2.js	(revision 2962)
@@ -0,0 +1,9 @@
+/*
+Copyright (c) 2003-2009, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.html or http://ckeditor.com/license
+*/
+
+CKEDITOR.editorConfig = function( config )
+{
+	config.test_custom2 = 'Ok';
+};
Index: /CKEditor/trunk/_source/tests/core/ajax.html
===================================================================
--- /CKEditor/trunk/_source/tests/core/ajax.html	(revision 2962)
+++ /CKEditor/trunk/_source/tests/core/ajax.html	(revision 2962)
@@ -0,0 +1,139 @@
+<!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.ajax</title>
+	<link rel="stylesheet" type="text/css" href="../test.css" />
+	<script type="text/javascript" src="../../../ckeditor_source.js"></script>
+	<script type="text/javascript" src="../test.js"></script>
+	<script type="text/javascript">
+	//<![CDATA[
+
+CKEDITOR.test.addTestCase( (function()
+{
+	// Local reference to the "assert" object.
+	var assert = CKEDITOR.test.assert;
+
+	return {
+		test_load_sync : function()
+		{
+			var data = CKEDITOR.ajax.load( '../_assets/sample.txt' );
+			assert.areSame( 'Sample Text\r\n', data, 'The loaded data doesn\'t match' );
+		},
+
+		test_load_sync_404 : function()
+		{
+			var data = CKEDITOR.ajax.load( '../_assets/404.txt' );
+			assert.isNull( data );
+		},
+
+		test_load_async : function()
+		{
+			var testCase = this;
+			var callback = function( data )
+			{
+				testCase.resume( function()
+					{
+						assert.areSame( 'Sample Text\r\n', data, 'The loaded data doesn\'t match' );
+					} );
+			};
+
+			CKEDITOR.ajax.load( '../_assets/sample.txt', callback );
+			this.wait();
+		},
+
+		test_load_async_404 : function()
+		{
+			var testCase = this;
+			var callback = function( data )
+			{
+				testCase.resume( function()
+					{
+						assert.isNull( data );
+					} );
+			};
+
+			CKEDITOR.ajax.load( '../_assets/404.txt', callback );
+			this.wait();
+		},
+
+		test_loadXml_sync : function()
+		{
+			var data = CKEDITOR.ajax.loadXml( '../_assets/sample.xml' );
+			assert.isInstanceOf( CKEDITOR.xml, data );
+			assert.isNotNull( data.selectSingleNode( '//list/item' ), 'The loaded data doesn\'t match (null)' );
+			assert.isNotUndefined( data.selectSingleNode( '//list/item' ), 'The loaded data doesn\'t match (undefined)' );
+		},
+
+		test_loadXml_sync_404 : function()
+		{
+			var data = CKEDITOR.ajax.loadXml( '../_assets/404.xml' );
+			assert.isNull( data );
+		},
+
+		test_loadXml_async : function()
+		{
+			var testCase = this;
+			var callback = function( data )
+			{
+				testCase.resume( function()
+					{
+						assert.isInstanceOf( CKEDITOR.xml, data );
+						assert.isNotNull( data.selectSingleNode( '//list/item' ), 'The loaded data doesn\'t match (null)' );
+						assert.isNotUndefined( data.selectSingleNode( '//list/item' ), 'The loaded data doesn\'t match (undefined)' );
+					} );
+			};
+
+			CKEDITOR.ajax.loadXml( '../_assets/sample.xml', callback );
+			this.wait();
+		},
+
+		test_loadXml_async_404 : function()
+		{
+			var testCase = this;
+			var callback = function( data )
+			{
+				testCase.resume( function()
+					{
+						assert.isNull( data );
+					} );
+			};
+
+			CKEDITOR.ajax.loadXml( '../_assets/404.xml', callback );
+			this.wait();
+		},
+
+		test_loadXml_sync_txt : function()
+		{
+			var data = CKEDITOR.ajax.loadXml( '../_assets/sample_xml.txt' );
+			assert.isInstanceOf( CKEDITOR.xml, data );
+			assert.isNotNull( data.selectSingleNode( '//list/item' ), 'The loaded data doesn\'t match (null)' );
+			assert.isNotUndefined( data.selectSingleNode( '//list/item' ), 'The loaded data doesn\'t match (undefined)' );
+		},
+
+		test_loadXml_async_txt : function()
+		{
+			var testCase = this;
+			var callback = function( data )
+			{
+				testCase.resume( function()
+					{
+						assert.isInstanceOf( CKEDITOR.xml, data );
+						assert.isNotNull( data.selectSingleNode( '//list/item' ), 'The loaded data doesn\'t match (null)' );
+						assert.isNotUndefined( data.selectSingleNode( '//list/item' ), 'The loaded data doesn\'t match (undefined)' );
+					} );
+			};
+
+			CKEDITOR.ajax.loadXml( '../_assets/sample_xml.txt', callback );
+			this.wait();
+		},
+
+		name : document.title
+	};
+})() );
+
+	//]]>
+	</script>
+</head>
+<body>
+</body>
+</html>
Index: /CKEditor/trunk/_source/tests/core/ckeditor.html
===================================================================
--- /CKEditor/trunk/_source/tests/core/ckeditor.html	(revision 2962)
+++ /CKEditor/trunk/_source/tests/core/ckeditor.html	(revision 2962)
@@ -0,0 +1,146 @@
+﻿<!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</title>
+	<link rel="stylesheet" type="text/css" href="../test.css" />
+	<script type="text/javascript" src="../../../ckeditor_source.js"></script>
+	<script type="text/javascript" src="../test.js"></script>
+	<script type="text/javascript">
+	//<![CDATA[
+
+CKEDITOR.test.addTestCase( (function()
+{
+	// Local reference to the "assert" object.
+	var assert = CKEDITOR.test.assert;
+
+	return {
+		test_replaceClass : function()
+		{
+			// Asserts the default value.
+			assert.areSame( 'ckeditor', CKEDITOR.replaceClass );
+		},
+
+		test_replaceByClassEnabled : function()
+		{
+			// Asserts the default value.
+			assert.isTrue( CKEDITOR.replaceByClassEnabled );
+		},
+
+		test_replaceId : function()
+		{
+			CKEDITOR.replace( 'editor1' );
+			assert.isObject( CKEDITOR.instances.editor1, 'editor instance not found' );
+			assert.areSame( 'editor1', CKEDITOR.instances.editor1.name, 'instance name doesn\'t match' );
+			assert.areSame( document.getElementById( 'editor1' ), CKEDITOR.instances.editor1.element.$, 'instance element doesn\'t match' );
+		},
+
+		test_replaceName : function()
+		{
+			CKEDITOR.replace( 'editor2' );
+			assert.isObject( CKEDITOR.instances.editor2, 'editor instance not found' );
+			assert.areSame( 'editor2', CKEDITOR.instances.editor2.name, 'instance name doesn\'t match' );
+			assert.areSame( document.getElementsByName( 'editor2' )[0], CKEDITOR.instances.editor2.element.$, 'instance element doesn\'t match' );
+		},
+
+		test_replaceElement : function()
+		{
+			CKEDITOR.replace( document.getElementById( 'editor5' ) );
+			assert.isObject( CKEDITOR.instances.editor5, 'editor instance not found' );
+			assert.areSame( 'editor5', CKEDITOR.instances.editor5.name, 'instance name doesn\'t match' );
+			assert.areSame( document.getElementById( 'editor5' ), CKEDITOR.instances.editor5.element.$, 'instance element doesn\'t match' );
+		},
+
+
+		test_replaceError : function()
+		{
+			try
+			{
+				CKEDITOR.replace( 'error' );
+			}
+			catch ( e )
+			{
+				assert.areSame( '[CKEDITOR.editor.replace] The element with id or name "error" was not found.', e );
+			}
+		},
+
+		test_replaceAll_Class : function()
+		{
+			CKEDITOR.replaceAll( 'myclass' );
+
+			assert.isObject( CKEDITOR.instances.editor3, 'editor3 instance not found' );
+			assert.areSame( 'editor3', CKEDITOR.instances.editor3.name, 'editor3 instance name doesn\'t match' );
+			assert.areSame( document.getElementById( 'editor3' ), CKEDITOR.instances.editor3.element.$, 'editor3 instance element doesn\'t match' );
+
+			assert.isObject( CKEDITOR.instances.editor4, 'editor4 instance not found' );
+			assert.areSame( 'editor4', CKEDITOR.instances.editor4.name, 'editor4 instance name doesn\'t match' );
+			assert.areSame( document.getElementsByName( 'editor4' )[0], CKEDITOR.instances.editor4.element.$, 'editor4 instance element doesn\'t match' );
+
+			assert.isUndefined( CKEDITOR.instances.editor6, 'editor6 should be undefined' );
+			assert.isUndefined( CKEDITOR.instances.editor7, 'editor7 should be undefined' );
+			assert.isUndefined( CKEDITOR.instances.editor8, 'editor8 should be undefined' );
+			assert.isUndefined( CKEDITOR.instances.editor8, 'editor9 should be undefined' );
+		},
+
+		test_replaceAll_Function : function()
+		{
+			CKEDITOR.replaceAll( function( textarea )
+				{
+					return ( textarea.id != 'editor6' && textarea.id != 'editor8' );
+				} );
+
+			assert.isObject( CKEDITOR.instances.editor7, 'editor7 instance not found' );
+			assert.areSame( 'editor7', CKEDITOR.instances.editor7.name, 'editor7 instance name doesn\'t match' );
+			assert.areSame( document.getElementById( 'editor7' ), CKEDITOR.instances.editor7.element.$, 'editor7 instance element doesn\'t match' );
+
+			assert.isObject( CKEDITOR.instances.editor9, 'editor9 instance not found' );
+			assert.areSame( 'editor9', CKEDITOR.instances.editor9.name, 'editor9 instance name doesn\'t match' );
+			assert.areSame( document.getElementById( 'editor9' ), CKEDITOR.instances.editor9.element.$, 'editor9 instance element doesn\'t match' );
+
+			assert.isUndefined( CKEDITOR.instances.editor6, 'editor6 should be undefined' );
+			assert.isUndefined( CKEDITOR.instances.editor8, 'editor8 should be undefined' );
+		},
+
+		test_replaceAll : function()
+		{
+			CKEDITOR.replaceAll();
+
+			assert.isObject( CKEDITOR.instances.editor6, 'editor6 instance not found' );
+			assert.areSame( 'editor6', CKEDITOR.instances.editor6.name, 'editor6 instance name doesn\'t match' );
+			assert.areSame( document.getElementById( 'editor6' ), CKEDITOR.instances.editor6.element.$, 'editor6 instance element doesn\'t match' );
+
+			assert.isObject( CKEDITOR.instances.editor8, 'editor8 editor instance not found' );
+			assert.areSame( 'editor8', CKEDITOR.instances.editor8.name, 'editor8 instance name doesn\'t match' );
+			assert.areSame( document.getElementById( 'editor8' ), CKEDITOR.instances.editor8.element.$, 'editor8 instance element doesn\'t match' );
+		},
+
+		test_add : function()
+		{
+			var textarea = CKEDITOR.dom.element.createFromHtml( '<textarea id="test_add">&lt;p&gt;test_add&lt;/p&gt;<\/textarea>' );
+			textarea.appendTo( new CKEDITOR.dom.element( document.body ) );
+
+			var editor = new CKEDITOR.editor( {}, textarea, CKEDITOR.ELEMENT_MODE_REPLACE );
+
+			CKEDITOR.add( editor );
+
+			assert.areSame( editor, CKEDITOR.instances.test_add );
+		},
+
+		name : document.title
+	};
+})() );
+
+	//]]>
+	</script>
+</head>
+<body>
+	<textarea id="editor1" cols="80" rows="10"></textarea>
+	<textarea name="editor2" cols="80" rows="10"></textarea>
+	<textarea id="editor3" name="editor3" class="myclass" cols="80" rows="10"></textarea>
+	<textarea name="editor4" class="myclass" cols="80" rows="10"></textarea>
+	<textarea id="editor5" cols="80" rows="10"></textarea>
+	<textarea id="editor6" cols="80" rows="10"></textarea>
+	<textarea id="editor7" cols="80" rows="10"></textarea>
+	<textarea id="editor8" cols="80" rows="10"></textarea>
+	<textarea id="editor9" cols="80" rows="10"></textarea>
+</body>
+</html>
Index: /CKEditor/trunk/_source/tests/core/ckeditor2.html
===================================================================
--- /CKEditor/trunk/_source/tests/core/ckeditor2.html	(revision 2962)
+++ /CKEditor/trunk/_source/tests/core/ckeditor2.html	(revision 2962)
@@ -0,0 +1,54 @@
+﻿<!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 2</title>
+	<link rel="stylesheet" type="text/css" href="../test.css" />
+	<script type="text/javascript" src="../../../ckeditor_basic_source.js"></script>
+	<script type="text/javascript" src="../test.js"></script>
+	<script type="text/javascript">
+	//<![CDATA[
+
+var before_loadFullCore = CKEDITOR.status;
+
+CKEDITOR.loadFullCore();
+
+	//]]>
+	</script>
+	<script type="text/javascript">
+	//<![CDATA[
+
+CKEDITOR.test.addTestCase( (function()
+{
+	// Local reference to the "assert" object.
+	var assert = CKEDITOR.test.assert;
+
+	return {
+		test_status1 : function()
+		{
+			assert.areSame( 'basic_loaded', before_loadFullCore );
+		},
+
+		test_status2 : function()
+		{
+			var testCase = this;
+			CKEDITOR.on( 'loaded', function()
+				{
+					testCase.resume( function()
+						{
+							assert.areSame( 'loaded', CKEDITOR.status );
+						});
+				});
+
+			this.wait();
+		},
+
+		name : document.title
+	};
+})() );
+
+	//]]>
+	</script>
+</head>
+<body>
+</body>
+</html>
Index: /CKEditor/trunk/_source/tests/core/dom/document.html
===================================================================
--- /CKEditor/trunk/_source/tests/core/dom/document.html	(revision 2962)
+++ /CKEditor/trunk/_source/tests/core/dom/document.html	(revision 2962)
@@ -0,0 +1,101 @@
+﻿<!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.dom.document</title>
+	<link rel="stylesheet" type="text/css" href="../../test.css" />
+	<script type="text/javascript" src="../../../../ckeditor_source.js"></script>
+	<script type="text/javascript" src="../../test.js"></script>
+	<script type="text/javascript">
+	//<![CDATA[
+
+CKEDITOR.test.addTestCase( (function()
+{
+	// Local reference to the "assert" object.
+	var assert = CKEDITOR.test.assert;
+
+	return {
+		test_$ : function()
+		{
+			var doc = new CKEDITOR.dom.document( document );
+			assert.areSame( document, doc.$ );
+		},
+
+		test_appendStyleSheet : function()
+		{
+			var cssUrl = CKEDITOR.basePath + '_source/tests/_assets/sample.css';
+
+			var doc = new CKEDITOR.dom.document( document );
+			doc.appendStyleSheet( cssUrl );
+
+			var links = document.getElementsByTagName( 'link' );
+
+			for ( var i = 0 ; i < links.length ; i++ )
+			{
+				if ( links[i].href == cssUrl )
+					return ;
+			}
+
+			assert.fail( 'The link element was not found' );
+		},
+
+		test_equals1 : function()
+		{
+			// Actually checks the real need for equals().
+			var doc1 = new CKEDITOR.dom.document( document );
+			assert.isFalse( doc1 == document );
+		},
+
+		test_equals2 : function()
+		{
+			// Actually checks the real need for equals().
+			var doc1 = new CKEDITOR.dom.document( document );
+			var doc2 = new CKEDITOR.dom.document( document );
+			assert.isFalse( doc1 == doc2, 'doc1 == doc2' );
+		},
+
+		test_equals3 : function()
+		{
+			var doc1 = new CKEDITOR.dom.document( document );
+			var doc2 = new CKEDITOR.dom.document( document );
+			assert.isTrue( doc1.equals( doc2 ), 'doc1.equals( doc2 )' );
+			assert.isTrue( doc2.equals( doc1 ), 'doc2.equals( doc1 )' );
+		},
+
+		test_getById1 : function()
+		{
+			var doc = new CKEDITOR.dom.document( document );
+			var element = doc.getById( 'test1' );
+			assert.areSame( document.getElementById( 'test1' ), element.$ );
+		},
+
+		test_getById2 : function()
+		{
+			var doc = new CKEDITOR.dom.document( document );
+			var element = doc.getById( 'test_invalid' );
+			assert.isNull( element );
+		},
+
+		test_getHead : function()
+		{
+			var doc = new CKEDITOR.dom.document( document );
+			assert.areSame( document.getElementsByTagName( 'head' )[0], doc.getHead().$ );
+		},
+
+		test_getBody : function()
+		{
+			var doc = new CKEDITOR.dom.document( document );
+			assert.areSame( document.body, doc.getBody().$, '1st call failed' );
+			assert.areSame( document.body, doc.getBody().$, '2nd call failed' );
+		},
+
+		name : document.title
+	};
+})() );
+
+	//]]>
+	</script>
+</head>
+<body>
+	<div id="test1"></div>
+</body>
+</html>
Index: /CKEditor/trunk/_source/tests/core/dom/element.html
===================================================================
--- /CKEditor/trunk/_source/tests/core/dom/element.html	(revision 2962)
+++ /CKEditor/trunk/_source/tests/core/dom/element.html	(revision 2962)
@@ -0,0 +1,517 @@
+﻿<!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.dom.element</title>
+	<link rel="stylesheet" type="text/css" href="../../test.css" />
+	<script type="text/javascript" src="../../../../ckeditor_source.js"></script>
+	<script type="text/javascript" src="../../test.js"></script>
+	<script type="text/javascript">
+	//<![CDATA[
+
+CKEDITOR.test.addTestCase( (function()
+{
+	// Local reference to the "assert" object.
+	var assert = CKEDITOR.test.assert;
+	var getInnerHtml = CKEDITOR.test.getInnerHtml;
+
+	return {
+		test_$ : function()
+		{
+			var element = new CKEDITOR.dom.element( document.getElementById( 'test1' ) );
+			assert.areSame( document.getElementById( 'test1' ), element.$ );
+		},
+
+		test_getId1 : function()
+		{
+			var element = new CKEDITOR.dom.element( document.getElementById( 'test1' ) );
+			assert.areEqual( 'test1', element.getId() );
+		},
+
+		test_getId2 : function()
+		{
+			var element = new CKEDITOR.dom.element( document.getElementsByTagName( 'div' )[0] );
+			assert.isNull( element.getId() );
+		},
+
+		test_getNameAtt1 : function()
+		{
+			var element = new CKEDITOR.dom.element( document.getElementsByName( 'named1' )[0] );
+			assert.areEqual( 'named1', element.getNameAtt() );
+		},
+
+		test_getNameAtt2 : function()
+		{
+			var element = new CKEDITOR.dom.element( document.getElementById( 'test1' ) );
+			assert.isNull( element.getNameAtt() );
+		},
+
+		test_getName : function()
+		{
+			var element = new CKEDITOR.dom.element( document.getElementById( 'test1' ) );
+			assert.areEqual( 'textarea', element.getName(), 'First call' );
+			assert.areEqual( 'textarea', element.getName(), 'Second call' );
+		},
+
+		test_hide : function()
+		{
+			var nativeElement = document.getElementById( 'test1' );
+			nativeElement.style.display = '';
+
+			var element = new CKEDITOR.dom.element( nativeElement );
+			element.hide();
+
+			assert.areEqual( 'none', nativeElement.style.display );
+		},
+
+		test_show : function()
+		{
+			var nativeElement = document.getElementById( 'test1' );
+			nativeElement.style.display = '';
+
+			var element = new CKEDITOR.dom.element( nativeElement );
+			element.show();
+
+			assert.areEqual( '', nativeElement.style.display );
+		},
+
+		test_createFromHtml : function()
+		{
+			var element = CKEDITOR.dom.element.createFromHtml( '<p>My test</p>' );
+			assert.areEqual( 'p', element.getName(), 'element name doesn\'t match' );
+			assert.areEqual( 'My test', element.$.innerHTML, 'the innerHTML doesn\'t match' );
+		},
+
+		test_append1 : function()
+		{
+			var element = new CKEDITOR.dom.element( document.getElementById( 'append' ) );
+			element.append( new CKEDITOR.dom.element( 'b' ) );
+			assert.areEqual( 'b', document.getElementById( 'append' ).firstChild.nodeName.toLowerCase() );
+		},
+
+		test_append2 : function()
+		{
+			var element = new CKEDITOR.dom.element( document.getElementById( 'append' ) );
+			element.append( 'i' );
+			assert.areEqual( 'i', document.getElementById( 'append' ).lastChild.nodeName.toLowerCase() );
+		},
+
+		test_appendText1 : function()
+		{
+			var element = new CKEDITOR.dom.element( document.getElementById( 'append' ) );
+			element.setHtml( '' );
+			element.appendText( 'Test appendText' );
+			assert.areEqual( 'Test appendText', document.getElementById( 'append' ).innerHTML );
+		},
+
+		test_appendText2 : function()
+		{
+			var element = new CKEDITOR.dom.element( 'script' );
+			element.appendText( 'Test appendText' );
+			assert.areEqual( 'Test appendText', element.$.text );
+		},
+
+		test_setHtml : function()
+		{
+			var element = new CKEDITOR.dom.element( document.getElementById( 'append' ) );
+			element.setHtml( '<b>Test</b>' );
+			assert.areEqual( '<b>test</b>', document.getElementById( 'append' ).innerHTML.toLowerCase(), 'First call doesn\'t match' );
+			element.setHtml( 'Another test' );
+			assert.areEqual( 'Another test', document.getElementById( 'append' ).innerHTML, 'Second call doesn\'t match' );
+		},
+
+		test_getDocument1 : function()
+		{
+			var element = new CKEDITOR.dom.element( 'div' );
+			assert.areSame( document, element.getDocument().$, 'First call' );
+			assert.areSame( document, element.getDocument().$, 'Second call' );
+		},
+
+		test_getDocument2 : function()
+		{
+			var element = new CKEDITOR.dom.element( document.body );
+			assert.areSame( document, element.getDocument().$, 'First call' );
+			assert.areSame( document, element.getDocument().$, 'Second call' );
+		},
+
+		test_getFirst1 : function()
+		{
+			var element = new CKEDITOR.dom.element( document.getElementById( 'append' ) );
+			element.setHtml( '<b>Test</b>' );
+			var first = element.getFirst();
+			assert.areSame( 'b', first.getName() );
+		},
+
+		test_getFirst2 : function()
+		{
+			var element = new CKEDITOR.dom.element( document.getElementById( 'append' ) );
+			element.setHtml( 'Test' );
+			var first = element.getFirst();
+			assert.areSame( 'Test', first.$.nodeValue );
+		},
+
+		test_getFirst3 : function()
+		{
+			var element = new CKEDITOR.dom.element( document.getElementById( 'append' ) );
+			element.setHtml( '' );
+			var first = element.getFirst();
+			assert.isNull( first );
+		},
+
+		test_setAttribute1 : function()
+		{
+			var element = new CKEDITOR.dom.element( document.getElementById( 'test1' ) );
+			element.setAttribute( 'class', 'Test' );
+
+			assert.areSame( 'Test', document.getElementById( 'test1' ).className );
+		},
+
+		test_setAttribute2 : function()
+		{
+			var element = new CKEDITOR.dom.element( document.getElementById( 'test1' ) );
+			element.setAttribute( 'style', 'position: absolute;' );
+
+			assert.areEqual( 'position:absolute', document.getElementById( 'test1' ).style.cssText.replace( /[\s;]/g, '' ).toLowerCase() );
+		},
+
+		test_setAttribute3 : function()
+		{
+			var element = new CKEDITOR.dom.element( document.getElementById( 'test1' ) );
+			element.setAttribute( 'name', 'TestName' );
+
+			assert.areEqual( 'TestName', document.getElementById( 'test1' ).name );
+		},
+
+		test_setAttribute4 : function()
+		{
+			var element = new CKEDITOR.dom.element( document.getElementById( 'test1' ) );
+			element.setAttribute( 'rows', 5 );
+
+			assert.areEqual( 5, document.getElementById( 'test1' ).rows );
+		},
+
+		test_setAttributes : function()
+		{
+			var element = new CKEDITOR.dom.element( document.getElementById( 'test2' ) );
+			element.setAttributes({
+				'class'	: 'Test',
+				'style'	: 'position: absolute;',
+				'name'	: 'TestName',
+				'rows'	: 5 });
+
+			assert.areSame( 'Test', document.getElementById( 'test1' ).className, 'class is wrong' );
+			assert.areEqual( 'position:absolute', document.getElementById( 'test1' ).style.cssText.replace( /[\s;]/g, '' ).toLowerCase(), 'style is wrong' );
+			assert.areEqual( 'TestName', document.getElementById( 'test1' ).name, 'name is wrong' );
+			assert.areEqual( 5, document.getElementById( 'test1' ).rows, 'rows is wrong' );
+		},
+
+		test_setStyle1 : function()
+		{
+			var element = new CKEDITOR.dom.element( document.getElementById( 'setStyle' ) );
+			element.setStyle( 'position', 'absolute' );
+
+			assert.areEqual( 'absolute', document.getElementById( 'setStyle' ).style.position );
+		},
+
+		test_setStyle2 : function()
+		{
+			var element = new CKEDITOR.dom.element( document.getElementById( 'setStyle' ) );
+			element.setStyle( 'float', 'right' );
+
+			assert.areEqual( 'right', document.getElementById( 'setStyle' ).style.cssFloat );
+		},
+
+		test_setStyles : function()
+		{
+			var element = new CKEDITOR.dom.element( document.getElementById( 'setStyle' ) );
+			element.setStyles({
+					 'position' : 'absolute',
+					 'float' : 'right'
+				});
+
+			assert.areEqual( 'absolute', document.getElementById( 'setStyle' ).style.position );
+			assert.areEqual( 'right', document.getElementById( 'setStyle' ).style.cssFloat );
+		},
+
+		test_setText1 : function()
+		{
+			var element = new CKEDITOR.dom.element( document.getElementById( 'setText' ) );
+			element.setText( 'A & B' );
+			assert.areSame( 'A &amp; B', document.getElementById( 'setText' ).innerHTML );
+		},
+
+		test_setText2 : function()
+		{
+			var element = new CKEDITOR.dom.element( document.getElementById( 'setText' ) );
+			element.setText( 'C & D' );
+			assert.areSame( 'C &amp; D', document.getElementById( 'setText' ).innerHTML );
+		},
+
+		test_addClass1 : function()
+		{
+			var element = new CKEDITOR.dom.element( 'div' );
+			element.addClass( 'classA' );
+			assert.areSame( 'classA', element.$.className );
+		},
+
+		test_addClass2 : function()
+		{
+			var element = new CKEDITOR.dom.element( 'div' );
+			element.addClass( 'classA' );
+			element.addClass( 'classA' );
+			assert.areSame( 'classA', element.$.className );
+		},
+
+		test_addClass3 : function()
+		{
+			var element = new CKEDITOR.dom.element( 'div' );
+			element.addClass( 'classA' );
+			element.addClass( 'classB' );
+			element.addClass( 'classC' );
+			assert.areSame( 'classA classB classC', element.$.className );
+		},
+
+		test_addClass4 : function()
+		{
+			var element = new CKEDITOR.dom.element( 'div' );
+			element.addClass( 'classA' );
+			element.addClass( 'classB' );
+			element.addClass( 'classC' );
+			element.addClass( 'classA' );
+			element.addClass( 'classB' );
+			element.addClass( 'classC' );
+			assert.areSame( 'classA classB classC', element.$.className );
+		},
+
+		test_removeClass1 : function()
+		{
+			document.getElementById( 'removeClass' ).innerHTML = '';
+
+			var element = CKEDITOR.dom.element.createFromHtml( '<div class="classA"></div>' );
+			element.appendTo( new CKEDITOR.dom.element( document.getElementById( 'removeClass' ) ) );
+
+			assert.areSame( '<div class="classa"></div>', getInnerHtml( 'removeClass' ) );
+			element.removeClass( 'classA' );
+			assert.areSame( '<div></div>', getInnerHtml( 'removeClass' ) );
+		},
+
+		test_removeClass2 : function()
+		{
+			document.getElementById( 'removeClass' ).innerHTML = '';
+
+			var element = CKEDITOR.dom.element.createFromHtml( '<div class="classA classB classC classD"></div>' );
+			element.appendTo( new CKEDITOR.dom.element( document.getElementById( 'removeClass' ) ) );
+
+			assert.areSame( '<div class="classa classb classc classd"></div>', getInnerHtml( 'removeClass' ) );
+			element.removeClass( 'classA' );
+			assert.areSame( '<div class="classb classc classd"></div>', getInnerHtml( 'removeClass' ) );
+			element.removeClass( 'classC' );
+			assert.areSame( '<div class="classb classd"></div>', getInnerHtml( 'removeClass' ) );
+			element.removeClass( 'classD' );
+			assert.areSame( '<div class="classb"></div>', getInnerHtml( 'removeClass' ) );
+			element.removeClass( 'classB' );
+			assert.areSame( '<div></div>', getInnerHtml( 'removeClass' ) );
+		},
+
+		test_removeClass3 : function()
+		{
+			document.getElementById( 'removeClass' ).innerHTML = '';
+
+			var element = CKEDITOR.dom.element.createFromHtml( '<div class="classA classB"></div>' );
+			element.appendTo( new CKEDITOR.dom.element( document.getElementById( 'removeClass' ) ) );
+
+			assert.areSame( '<div class="classa classb"></div>', getInnerHtml( 'removeClass' ) );
+			element.removeClass( 'classXXX' );
+			assert.areSame( '<div class="classa classb"></div>', getInnerHtml( 'removeClass' ) );
+			element.removeClass( 'classB' );
+			assert.areSame( '<div class="classa"></div>', getInnerHtml( 'removeClass' ) );
+			element.removeClass( 'classYYY' );
+			assert.areSame( '<div class="classa"></div>', getInnerHtml( 'removeClass' ) );
+		},
+
+		test_removeAttribute1 : function()
+		{
+			document.getElementById( 'removeClass' ).innerHTML = '';
+
+			var element = CKEDITOR.dom.element.createFromHtml( '<div class="classA"></div>' );
+			element.appendTo( new CKEDITOR.dom.element( document.getElementById( 'removeClass' ) ) );
+
+			element.removeAttribute( 'class' );
+			assert.areSame( '<div></div>', getInnerHtml( 'removeClass' ) );
+		},
+
+		test_removeAttribute2 : function()
+		{
+			document.getElementById( 'removeClass' ).innerHTML = '';
+
+			var element = CKEDITOR.dom.element.createFromHtml( '<div style="position:absolute"></div>' );
+			element.appendTo( new CKEDITOR.dom.element( document.getElementById( 'removeClass' ) ) );
+
+			element.removeAttribute( 'style' );
+			assert.areSame( '<div></div>', getInnerHtml( 'removeClass' ) );
+		},
+
+		test_removeAttribute3 : function()
+		{
+			document.getElementById( 'removeClass' ).innerHTML = '';
+
+			var element = CKEDITOR.dom.element.createFromHtml( '<div title="Test"></div>' );
+			element.appendTo( new CKEDITOR.dom.element( document.getElementById( 'removeClass' ) ) );
+
+			element.removeAttribute( 'title' );
+			assert.areSame( '<div></div>', getInnerHtml( 'removeClass' ) );
+		},
+
+		test_remove : function()
+		{
+			var element = new CKEDITOR.dom.element( document.getElementById( 'removeInner' ) );
+			element.remove();
+
+			assert.areSame( '', getInnerHtml( 'removeOuter' ) );
+		},
+
+		test_getAttribute_tabindex1 : function()
+		{
+			var element = new CKEDITOR.dom.element( document.getElementById( 'tabIndex10' ) );
+			assert.areEqual( 10, element.getAttribute( 'tabindex' ) );
+		},
+
+		test_getAttribute_tabindex2 : function()
+		{
+			var element = new CKEDITOR.dom.element( document.getElementById( 'tabIndexDef' ) );
+			assert.isNull( element.getAttribute( 'tabindex' ) );
+		},
+
+		test_getAttribute_tabindex3 : function()
+		{
+			var element = new CKEDITOR.dom.element( document.getElementById( 'tabIndexInputDef' ) );
+			assert.isNull( element.getAttribute( 'tabindex' ) );
+		},
+
+		test_getAttribute_tabindex4 : function()
+		{
+			var element = new CKEDITOR.dom.element( document.getElementById( 'tabIndexInput20' ) );
+			assert.areEqual( 20, element.getAttribute( 'tabindex' ) );
+		},
+
+		test_getAttribute_tabindex5 : function()
+		{
+			var element = new CKEDITOR.dom.element( document.getElementById( 'tabIndexScriptDef' ) );
+			assert.areEqual( null, element.getAttribute( 'tabindex' ) );
+		},
+
+		test_getTabIndex1 : function()
+		{
+			var element = new CKEDITOR.dom.element( document.getElementById( 'tabIndex10' ) );
+			assert.areSame( 10, element.getTabIndex() );
+		},
+
+		test_getTabIndex2 : function()
+		{
+			var element = new CKEDITOR.dom.element( document.getElementById( 'tabIndexDef' ) );
+			assert.areSame( -1, element.getTabIndex() );
+		},
+
+		test_getTabIndex3 : function()
+		{
+			var element = new CKEDITOR.dom.element( document.getElementById( 'tabIndexInputDef' ) );
+			assert.areSame( 0, element.getTabIndex() );
+		},
+
+		test_getTabIndex4 : function()
+		{
+			var element = new CKEDITOR.dom.element( document.getElementById( 'tabIndexInput20' ) );
+			assert.areSame( 20, element.getTabIndex() );
+		},
+
+		test_getTabIndex5 : function()
+		{
+			var element = new CKEDITOR.dom.element( document.getElementById( 'tabIndexScriptDef' ) );
+			assert.areSame( -1, element.getTabIndex() );
+		},
+
+		test_private1 : function()
+		{
+			var a = new CKEDITOR.dom.element( document.getElementById( 'test1' ) );
+			var b = new CKEDITOR.dom.element( document.getElementById( 'test1' ) );
+
+			assert.areSame( a._, b._ );
+		},
+
+		test_private2 : function()
+		{
+			var a = new CKEDITOR.dom.element( document.getElementById( 'test1' ) );
+			var b = new CKEDITOR.dom.element( document.getElementById( 'test2' ) );
+
+			assert.areNotSame( a._, b._ );
+		},
+
+		test_getText1 : function()
+		{
+			var element = new CKEDITOR.dom.element( document.getElementById( 'getText' ) );
+
+			// IE gives us a different result, which is ok for us (see code comments).
+			if ( CKEDITOR.env.ie )
+				assert.areSame( 'Some \nsample text for testing', element.getText().replace( /\r\n|\r/g, '\n' ) );
+			else
+				assert.areSame( 'Some  sample text    for    testing', element.getText() );
+		},
+
+		test_getText2 : function()
+		{
+			var element = new CKEDITOR.dom.element( document.getElementById( 'getText2' ).getElementsByTagName( 'b' )[0] );
+			assert.areSame( ' ', element.getText() );
+		},
+
+		test_getText3 : function()
+		{
+			var element = new CKEDITOR.dom.element( document.getElementById( 'getText3' ) );
+
+			// IE gives us a different result, which is ok for us (see code comments).
+			if ( CKEDITOR.env.ie )
+				assert.areSame( 'A B', element.getText() );
+			else
+				assert.areSame( 'A\nB', element.getText().replace( /\r\n|\r/g, '\n' ) );
+		},
+
+		test_hasAttributes1 : function()
+		{
+			var element = new CKEDITOR.dom.element( document.getElementsByTagName( 'big' )[0] );
+			assert.isFalse( element.hasAttributes() );
+		},
+
+		test_hasAttributes2 : function()
+		{
+			var element = new CKEDITOR.dom.element( document.getElementsByTagName( 'small' )[0] );
+			assert.isTrue( element.hasAttributes() );
+		},
+
+		name : document.title
+	};
+})() );
+
+	//]]>
+	</script>
+</head>
+<body>
+	<textarea id="test1" rows="10" cols="80"></textarea>
+	<textarea id="test2" rows="10" cols="80"></textarea>
+	<textarea name="named1" rows="10" cols="80"></textarea>
+	<div>Test</div>
+	<div id="append"></div>
+	<div id="setStyle"></div>
+	<div id="setText"></div>
+	<div id="removeClass"></div>
+	<div id="removeOuter"><b id="removeInner"></b></div>
+	<div id="tabIndex10" tabindex="10"></div>
+	<div id="tabIndexDef"></div>
+	<input id="tabIndexInputDef" />
+	<input id="tabIndexInput20" tabindex="20" />
+	<script id="tabIndexScriptDef" type="text/javascript"></script>
+	<div id="getText">Some <br /><b> sample text</b>    for <i>   testing</i></div>
+	<div id="getText2">A<b> </b>B</div>
+	<div id="getText3">A
+B</div>
+	<big>Test</big>
+	<small title="Testing">Test</small>
+</body>
+</html>
Index: /CKEditor/trunk/_source/tests/core/dom/node.html
===================================================================
--- /CKEditor/trunk/_source/tests/core/dom/node.html	(revision 2962)
+++ /CKEditor/trunk/_source/tests/core/dom/node.html	(revision 2962)
@@ -0,0 +1,126 @@
+<!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.dom.node</title>
+	<link rel="stylesheet" type="text/css" href="../../test.css" />
+	<script type="text/javascript" src="../../../../ckeditor_source.js"></script>
+	<script type="text/javascript" src="../../test.js"></script>
+	<script type="text/javascript">
+	//<![CDATA[
+
+CKEDITOR.test.addTestCase( (function()
+{
+	// Local reference to the "assert" object.
+	var assert = CKEDITOR.test.assert;
+
+	return {
+		test_getPosition1 : function()
+		{
+			var node1 = new CKEDITOR.dom.node( document.getElementsByTagName( 'h1' )[0] );
+			var node2 = new CKEDITOR.dom.node( document.getElementsByTagName( 'p' )[0] );
+
+			assert.areSame( CKEDITOR.POSITION_PRECEDING, node1.getPosition( node2 ) );
+		},
+
+		test_getPosition2 : function()
+		{
+			var node1 = new CKEDITOR.dom.node( document.getElementsByTagName( 'h1' )[0] );
+			var node2 = new CKEDITOR.dom.node( document.getElementsByTagName( 'p' )[0] );
+
+			assert.areSame( CKEDITOR.POSITION_FOLLOWING, node2.getPosition( node1 ) );
+		},
+
+		test_getPosition3 : function()
+		{
+			var node1 = new CKEDITOR.dom.node( document.getElementsByTagName( 'p' )[0] );
+			var node2 = new CKEDITOR.dom.node( document.getElementsByTagName( 'b' )[0] );
+
+			assert.areSame( CKEDITOR.POSITION_CONTAINS + CKEDITOR.POSITION_PRECEDING, node1.getPosition( node2 ) );
+		},
+
+		test_getPosition4 : function()
+		{
+			var node1 = new CKEDITOR.dom.node( document.getElementsByTagName( 'p' )[0] );
+			var node2 = new CKEDITOR.dom.node( document.getElementsByTagName( 'b' )[0] );
+
+			assert.areSame( CKEDITOR.POSITION_IS_CONTAINED + CKEDITOR.POSITION_FOLLOWING, node2.getPosition( node1 ) );
+		},
+
+		test_getPosition5 : function()
+		{
+			var node1 = new CKEDITOR.dom.node( document.getElementsByTagName( 'div' )[0] );
+			var node2 = new CKEDITOR.dom.node( document.getElementsByTagName( 'div' )[0] );
+
+			assert.areSame( CKEDITOR.POSITION_IDENTICAL, node1.getPosition( node2 ) );
+		},
+
+		test_getPosition6 : function()
+		{
+			var node1 = new CKEDITOR.dom.node( document.getElementsByTagName( 'h1' )[0] );
+			var node2 = new CKEDITOR.dom.node( document.getElementsByTagName( 'h1' )[0].firstChild );
+
+			assert.areSame( CKEDITOR.POSITION_CONTAINS + CKEDITOR.POSITION_PRECEDING, node1.getPosition( node2 ) );
+		},
+
+		test_getPosition7 : function()
+		{
+			var node1 = new CKEDITOR.dom.node( document.getElementsByTagName( 'h1' )[0] );
+			var node2 = new CKEDITOR.dom.node( document.getElementsByTagName( 'h1' )[0].firstChild );
+
+			assert.areSame( CKEDITOR.POSITION_IS_CONTAINED + CKEDITOR.POSITION_FOLLOWING, node2.getPosition( node1 ) );
+		},
+
+		test_getPosition8 : function()
+		{
+			var node1 = new CKEDITOR.dom.node( document.getElementsByTagName( 'h1' )[0].firstChild );
+			var node2 = new CKEDITOR.dom.node( document.getElementsByTagName( 'b' )[0].firstChild );
+
+			assert.areSame( CKEDITOR.POSITION_PRECEDING, node1.getPosition( node2 ) );
+		},
+
+		test_getPosition9 : function()
+		{
+			var node1 = new CKEDITOR.dom.node( document.getElementsByTagName( 'h1' )[0].firstChild );
+			var node2 = new CKEDITOR.dom.node( document.getElementsByTagName( 'b' )[0].firstChild );
+
+			assert.areSame( CKEDITOR.POSITION_FOLLOWING, node2.getPosition( node1 ) );
+		},
+
+		test_getPosition10 : function()
+		{
+			var node1 = new CKEDITOR.dom.node( document.getElementsByTagName( 'b' )[0] );
+			var node2 = new CKEDITOR.dom.node( document.getElementsByTagName( 'i' )[0] );
+
+			assert.areSame( CKEDITOR.POSITION_PRECEDING, node1.getPosition( node2 ) );
+		},
+
+		test_getPosition11 : function()
+		{
+			var node1 = new CKEDITOR.dom.node( document.getElementsByTagName( 'b' )[0] );
+			var node2 = new CKEDITOR.dom.node( document.getElementsByTagName( 'i' )[0] );
+
+			assert.areSame( CKEDITOR.POSITION_FOLLOWING, node2.getPosition( node1 ) );
+		},
+
+		name : document.title
+	};
+})() );
+
+//window.onload = function()
+//{
+//	var node1 = new CKEDITOR.dom.node( document.getElementsByTagName( 'h1' )[0] );
+//	var node2 = new CKEDITOR.dom.node( document.getElementsByTagName( 'p' )[0] );
+//
+//	alert( node1.getPosition( node2 ) );
+//};
+
+	//]]>
+	</script>
+</head>
+<body>
+	<div>
+		<h1>Title</h1>
+		<p><b>Sample</b> <i>Text</i></p>
+	</div>
+</body>
+</html>
Index: /CKEditor/trunk/_source/tests/core/dom/range.html
===================================================================
--- /CKEditor/trunk/_source/tests/core/dom/range.html	(revision 2962)
+++ /CKEditor/trunk/_source/tests/core/dom/range.html	(revision 2962)
@@ -0,0 +1,1680 @@
+<!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.dom.range</title>
+	<link rel="stylesheet" type="text/css" href="../../test.css" />
+	<script type="text/javascript" src="../../../../ckeditor_source.js"></script>
+	<script type="text/javascript" src="../../test.js"></script>
+	<script type="text/javascript">
+	//<![CDATA[
+
+var html1, html2;
+
+CKEDITOR.test.addTestCase( (function()
+{
+	// Local references.
+	var assert			= CKEDITOR.test.assert;
+	var getInnerHtml	= CKEDITOR.test.getInnerHtml;
+
+	var doc = new CKEDITOR.dom.document( document );
+
+	return {
+		test__constructor : function()
+		{
+			var range = new CKEDITOR.dom.range( doc );
+
+			assert.isNotNull( range, 'range must not be null' );
+
+			assert.isNull( range.startContainer, 'startContainer must be null' );
+			assert.isNull( range.startOffset, 'startOffset must be null' );
+			assert.isNull( range.endContainer, 'endContainer must be null' );
+			assert.isNull( range.endOffset, 'endOffset must be null' );
+
+			assert.isTrue( range.collapsed, 'range must be collapsed' );
+		},
+
+		test_setStart : function()
+		{
+			var range = new CKEDITOR.dom.range( doc );
+			range.setStart( doc.getById( 'playground' ), 1 );
+
+			assert.areSame( document.getElementById( 'playground' ), range.startContainer.$ );
+			assert.areSame( 1, range.startOffset );
+			assert.areSame( document.getElementById( 'playground' ), range.endContainer.$ );
+			assert.areSame( 1, range.endOffset, 'range.endOffset' );
+			assert.isTrue( range.collapsed );
+		},
+
+		test_setEnd : function()
+		{
+			var range = new CKEDITOR.dom.range( doc );
+			range.setEnd( doc.getById( 'playground' ), 1 );
+
+			assert.areSame( document.getElementById( 'playground' ), range.startContainer.$ );
+			assert.areSame( 1, range.startOffset );
+			assert.areSame( document.getElementById( 'playground' ), range.endContainer.$ );
+			assert.areSame( 1, range.endOffset, 'range.endOffset' );
+			assert.isTrue( range.collapsed );
+		},
+
+		test_setStartAfter : function()
+		{
+			var range = new CKEDITOR.dom.range( doc );
+			range.setStartAfter( doc.getById( '_B' ) );
+			range.setStartAfter( doc.getById( '_H1' ).getFirst() );
+
+			assert.areSame( document.getElementById( '_H1' ), range.startContainer.$, 'range.startContainer' );
+			assert.areSame( 1, range.startOffset, 'range.startOffset' );
+			assert.areSame( document.getElementById( '_Para' ), range.endContainer.$, 'range.endContainer' );
+			assert.areSame( 2, range.endOffset, 'range.endOffset' );
+			assert.isFalse( range.collapsed, 'range.collapsed' );
+		},
+
+		test_setStartBefore : function()
+		{
+			var range = new CKEDITOR.dom.range( doc );
+			range.setStartBefore( doc.getById( '_B' ) );
+			range.setStartBefore( doc.getById( '_H1' ).getFirst() );
+
+			assert.areSame( document.getElementById( '_H1' ), range.startContainer.$, 'range.startContainer' );
+			assert.areSame( 0, range.startOffset, 'range.startOffset' );
+			assert.areSame( document.getElementById( '_Para' ), range.endContainer.$, 'range.endContainer' );
+			assert.areSame( 1, range.endOffset, 'range.endOffset' );
+			assert.isFalse( range.collapsed, 'range.collapsed' );
+		},
+
+		test_setEndAfter : function()
+		{
+			var range = new CKEDITOR.dom.range( doc );
+			range.setEndAfter( doc.getById( '_H1' ).getFirst() );
+			range.setEndAfter( doc.getById( '_B' ) );
+
+			assert.areSame( document.getElementById( '_H1' ), range.startContainer.$, 'range.startContainer' );
+			assert.areSame( 1, range.startOffset, 'range.startOffset' );
+			assert.areSame( document.getElementById( '_Para' ), range.endContainer.$, 'range.endContainer' );
+			assert.areSame( 2, range.endOffset, 'range.endOffset' );
+			assert.isFalse( range.collapsed, 'range.collapsed' );
+		},
+
+		test_setEndBefore : function()
+		{
+			var range = new CKEDITOR.dom.range( doc );
+			range.setEndBefore( doc.getById( '_H1' ).getFirst() );
+			range.setEndBefore( doc.getById( '_B' ) );
+
+			assert.areSame( document.getElementById( '_H1' ), range.startContainer.$, 'range.startContainer' );
+			assert.areSame( 0, range.startOffset, 'range.startOffset' );
+			assert.areSame( document.getElementById( '_Para' ), range.endContainer.$, 'range.endContainer' );
+			assert.areSame( 1, range.endOffset, 'range.endOffset' );
+			assert.isFalse( range.collapsed, 'range.collapsed' );
+		},
+
+		test_setStartAt_1 : function()
+		{
+			var range = new CKEDITOR.dom.range( doc );
+			range.setStartAt( doc.getById('_Span'), CKEDITOR.POSITION_AFTER_START );
+
+			assert.areSame( document.getElementById('_Span'), range.startContainer.$, 'startContainer' );
+			assert.areSame( document.getElementById('_Span'), range.endContainer.$, 'endContainer' );
+			assert.isTrue( range.collapsed, 'collapsed' );
+		},
+
+		test_setStartAt_2 : function()
+		{
+			var range = new CKEDITOR.dom.range( doc );
+			range.setStartAt( doc.getById('_Span'), CKEDITOR.POSITION_BEFORE_END );
+
+			assert.areSame( document.getElementById('_Span'), range.startContainer.$, 'startContainer' );
+			assert.areSame( document.getElementById('_Span'), range.endContainer.$, 'endContainer' );
+			assert.isTrue( range.collapsed, 'collapsed' );
+		},
+
+		test_setStartAt_3 : function()
+		{
+			var range = new CKEDITOR.dom.range( doc );
+			range.setStartAt( doc.getById('_Span'), CKEDITOR.POSITION_BEFORE_START );
+
+			assert.areSame( document.getElementById('_P'), range.startContainer.$, 'startContainer' );
+			assert.areSame( document.getElementById('_P'), range.endContainer.$, 'endContainer' );
+			assert.isTrue( range.collapsed, 'collapsed' );
+		},
+
+		test_setStartAt_4 : function()
+		{
+			var range = new CKEDITOR.dom.range( doc );
+			range.setStartAt( doc.getById('_Span'), CKEDITOR.POSITION_AFTER_END );
+
+			assert.areSame( document.getElementById('_P'), range.startContainer.$, 'startContainer' );
+			assert.areSame( document.getElementById('_P'), range.endContainer.$, 'endContainer' );
+			assert.isTrue( range.collapsed, 'collapsed' );
+		},
+
+		test_setEndAt_1 : function()
+		{
+			var range = new CKEDITOR.dom.range( doc );
+			range.setEndAt( doc.getById('_Span'), CKEDITOR.POSITION_AFTER_START );
+
+			assert.areSame( document.getElementById('_Span'), range.startContainer.$, 'startContainer' );
+			assert.areSame( document.getElementById('_Span'), range.endContainer.$, 'endContainer' );
+			assert.isTrue( range.collapsed, 'collapsed' );
+		},
+
+		test_setEndAt_2 : function()
+		{
+			var range = new CKEDITOR.dom.range( doc );
+			range.setEndAt( doc.getById('_Span'), CKEDITOR.POSITION_BEFORE_END );
+
+			assert.areSame( document.getElementById('_Span'), range.startContainer.$, 'startContainer' );
+			assert.areSame( document.getElementById('_Span'), range.endContainer.$, 'endContainer' );
+			assert.isTrue( range.collapsed, 'collapsed' );
+		},
+
+		test_setEndAt_3 : function()
+		{
+			var range = new CKEDITOR.dom.range( doc );
+			range.setEndAt( doc.getById('_Span'), CKEDITOR.POSITION_BEFORE_START );
+
+			assert.areSame( document.getElementById('_P'), range.startContainer.$, 'startContainer' );
+			assert.areSame( document.getElementById('_P'), range.endContainer.$, 'endContainer' );
+			assert.isTrue( range.collapsed, 'collapsed' );
+		},
+
+		test_setEndAt_4 : function()
+		{
+			var range = new CKEDITOR.dom.range( doc );
+			range.setEndAt( doc.getById('_Span'), CKEDITOR.POSITION_AFTER_END );
+
+			assert.areSame( document.getElementById('_P'), range.startContainer.$, 'startContainer' );
+			assert.areSame( document.getElementById('_P'), range.endContainer.$, 'endContainer' );
+			assert.isTrue( range.collapsed, 'collapsed' );
+		},
+
+		test_collapsed : function()
+		{
+			var range = new CKEDITOR.dom.range( doc );
+			range.setStartAt( doc.getById( '_P' ), CKEDITOR.POSITION_AFTER_START );
+
+			assert.isTrue( range.collapsed );
+		},
+
+		test_collapse : function()
+		{
+			var range = new CKEDITOR.dom.range( doc );
+			range.setStartAt( doc.getById( '_Para' ), CKEDITOR.POSITION_AFTER_START );
+			range.setEndAt( doc.getById( '_Span' ), CKEDITOR.POSITION_BEFORE_END );
+
+			assert.areSame( document.getElementById('_Para'), range.startContainer.$, 'startContainer' );
+			assert.areSame( document.getElementById('_Span'), range.endContainer.$, 'endContainer' );
+			assert.isFalse( range.collapsed, 'collapsed' );
+
+			range.collapse( true );
+
+			assert.areSame( document.getElementById('_Para'), range.startContainer.$, 'startContainer' );
+			assert.areSame( document.getElementById('_Para'), range.endContainer.$, 'endContainer' );
+			assert.isTrue( range.collapsed, 'collapsed' );
+		},
+
+		test_selectNodeContents_Element : function()
+		{
+			var range = new CKEDITOR.dom.range( doc );
+
+			// Test with an Element node.
+			range.selectNodeContents( doc.getById( '_Para' ) );
+
+			assert.areSame( document.getElementById( '_Para' ), range.startContainer.$, 'range.startContainer' );
+			assert.areSame( 0, range.startOffset, 'range.startOffset' );
+			assert.areSame( document.getElementById( '_Para' ), range.endContainer.$, 'range.endContainer' );
+			assert.areSame( 3, range.endOffset, 'range.endOffset' );
+			assert.isFalse( range.collapsed, 'range.collapsed' );
+		},
+
+		test_selectNodeContents_Text : function()
+		{
+			var range = new CKEDITOR.dom.range( doc );
+
+			// Test with a Text node.
+			range.selectNodeContents( doc.getById( '_Para' ).getFirst() );
+
+			assert.areSame( document.getElementById( '_Para' ).firstChild, range.startContainer.$, 'range.startContainer' );
+			assert.areSame( 0, range.startOffset, 'range.startOffset' );
+			assert.areSame( document.getElementById( '_Para' ).firstChild, range.endContainer.$, 'range.endContainer' );
+			assert.areSame( 8, range.endOffset, 'range.endOffset' );
+			assert.isFalse( range.collapsed, 'range.collapsed' );
+		},
+
+		test_collapse_ToStart : function()
+		{
+			var range = new CKEDITOR.dom.range( doc );
+
+			range.selectNodeContents( doc.getById( '_P' ) );
+			range.collapse( true );
+
+			assert.areSame( document.getElementById( '_P' ), range.startContainer.$, 'range.startContainer' );
+			assert.areSame( 0, range.startOffset, 'range.startOffset' );
+			assert.areSame( document.getElementById( '_P' ), range.endContainer.$, 'range.endContainer' );
+			assert.areSame( 0, range.endOffset, 'range.endOffset' );
+			assert.isTrue( range.collapsed, 'range.collapsed' );
+		},
+
+		test_collapse_ToEnd : function()
+		{
+			var range = new CKEDITOR.dom.range( doc );
+
+			range.selectNodeContents( doc.getById( '_Para' ) );
+			range.collapse( false );
+
+			assert.areSame( document.getElementById( '_Para' ), range.startContainer.$, 'range.startContainer' );
+			assert.areSame( 3, range.startOffset, 'range.startOffset' );
+			assert.areSame( document.getElementById( '_Para' ), range.endContainer.$, 'range.endContainer' );
+			assert.areSame( 3, range.endOffset, 'range.endOffset' );
+			assert.isTrue( range.collapsed, 'range.collapsed' );
+		},
+
+		test_insertNode_ElementContents : function()
+		{
+			var newNode = new CKEDITOR.dom.element( 'span' );
+			newNode.setHtml( 'test_' );
+
+			var range = new CKEDITOR.dom.range( doc );
+
+			range.selectNodeContents( doc.getById( '_B' ) );
+			range.insertNode( newNode );
+
+			assert.areSame( document.getElementById( '_B' ), range.startContainer.$, 'range.startContainer' );
+			assert.areSame( 0, range.startOffset, 'range.startOffset' );
+			assert.areSame( document.getElementById( '_B' ), range.endContainer.$, 'range.endContainer' );
+			assert.areSame( 2, range.endOffset, 'range.endOffset' );
+			assert.isFalse( range.collapsed, 'range.collapsed' );
+		},
+
+		test_insertNode_ElementCollapsed : function()
+		{
+			var newNode = new CKEDITOR.dom.element( 'span' );
+			newNode.setHtml( 'test_' );
+
+			var range = new CKEDITOR.dom.range( doc );
+
+			range.setStartBefore( doc.getById( '_Para' ) );
+			range.insertNode( newNode );
+
+			assert.areSame( document.getElementById( 'playground' ), range.startContainer.$, 'range.startContainer' );
+			assert.areSame( 1, range.startOffset, 'range.startOffset' );
+			assert.areSame( document.getElementById( 'playground' ), range.endContainer.$, 'range.endContainer' );
+			assert.areSame( 2, range.endOffset, 'range.endOffset' );
+			assert.isFalse( range.collapsed, 'range.collapsed' );
+		},
+
+		test_insertNode_ElementNotCollapsed : function()
+		{
+			var newNode = new CKEDITOR.dom.element( 'span' );
+			newNode.setHtml( 'test_' );
+
+			var range = new CKEDITOR.dom.range( doc );
+
+			range.setStartBefore( doc.getById( '_Para' ) );
+			range.setStartBefore( doc.getById( '_H1' ) );
+			range.insertNode( newNode );
+
+			assert.areSame( document.getElementById( 'playground' ), range.startContainer.$, 'range.startContainer' );
+			assert.areSame( 0, range.startOffset, 'range.startOffset' );
+			assert.areSame( document.getElementById( 'playground' ), range.endContainer.$, 'range.endContainer' );
+			assert.areSame( 2, range.endOffset, 'range.endOffset' );
+			assert.isFalse( range.collapsed, 'range.collapsed' );
+		},
+
+		test_insertNode_DiffElements : function()
+		{
+			var newNode = new CKEDITOR.dom.element( 'span' );
+			newNode.setHtml( 'test_' );
+
+			var range = new CKEDITOR.dom.range( doc );
+
+			range.selectNodeContents( doc.getById( '_Para' ) );
+
+			range.setStart( doc.getById( '_H1' ), 0 );
+			range.insertNode( newNode );
+
+			assert.areSame( document.getElementById( '_H1' ), range.startContainer.$, 'range.startContainer' );
+			assert.areSame( 0, range.startOffset, 'range.startOffset' );
+			assert.areSame( document.getElementById( '_Para' ), range.endContainer.$, 'range.endContainer' );
+			assert.areSame( 3, range.endOffset, 'range.endOffset' );
+			assert.isFalse( range.collapsed, 'range.collapsed' );
+
+			assert.isTrue( range.startContainer.getChild( range.startOffset ).equals( newNode ), 'Start must be on new node' );
+		},
+
+		test_insertNode_TextCollapsed : function()
+		{
+			var newNode = new CKEDITOR.dom.element( 'span' );
+			newNode.setHtml( 'test_' );
+
+			var range = new CKEDITOR.dom.range( doc );
+
+			range.setStart( doc.getById( '_H1' ).getFirst(), 3 );
+			range.insertNode( newNode );
+
+			assert.areSame( document.getElementById( '_H1' ), range.startContainer.$, 'range.startContainer' );
+			assert.areSame( 1, range.startOffset, 'range.startOffset' );
+			assert.areSame( document.getElementById( '_H1' ), range.endContainer.$, 'range.endContainer' );
+			assert.areSame( 2, range.endOffset, 'range.endOffset' );
+			assert.isFalse( range.collapsed, 'range.collapsed' );
+		},
+
+		test_insertNode_TextNotCollapsed : function()
+		{
+			var newNode = new CKEDITOR.dom.element( 'span' );
+			newNode.setHtml( 'test_' );
+
+			var range = new CKEDITOR.dom.range( doc );
+
+			range.setStart( doc.getById( '_H1' ).getFirst(), 3 );
+			range.setEnd( doc.getById( '_H1' ).getFirst(), 5 );
+			range.insertNode( newNode );
+
+			assert.areSame( document.getElementById( '_H1' ), range.startContainer.$, 'range.startContainer' );
+			assert.areSame( 1, range.startOffset, 'range.startOffset' );
+			assert.areSame( document.getElementById( '_H1' ).childNodes[2], range.endContainer.$, 'range.endContainer' );
+			assert.areSame( 2, range.endOffset, 'range.endOffset' );
+			assert.isFalse( range.collapsed, 'range.collapsed' );
+		},
+
+		test_insertNode_Mixed : function()
+		{
+			var newNode = new CKEDITOR.dom.element( 'span' );
+			newNode.setHtml( 'test_' );
+
+			var range = new CKEDITOR.dom.range( doc );
+
+			range.setStart( doc.getById( '_H1' ).getFirst(), 0 );
+			range.setEnd( doc.getById( '_P' ), 1 );
+			range.insertNode( newNode );
+
+			assert.areSame( document.getElementById( '_H1' ), range.startContainer.$, 'range.startContainer' );
+			assert.areSame( 0, range.startOffset, 'range.startOffset' );
+			assert.areSame( document.getElementById( '_P' ), range.endContainer.$, 'range.endContainer' );
+			assert.areSame( 1, range.endOffset, 'range.endOffset' );
+			assert.isFalse( range.collapsed, 'range.collapsed' );
+		},
+
+		test_getCommonAncestor1 : function()
+		{
+			var range = new CKEDITOR.dom.range( doc );
+			range.setStart( doc.getById( '_H1' ).getFirst(), 3 );
+
+			assert.areSame( document.getElementById( '_H1' ).firstChild, range.getCommonAncestor().$ );
+		},
+
+		test_getCommonAncestor2 : function()
+		{
+			var range = new CKEDITOR.dom.range( doc );
+			range.setStart( doc.getById( '_H1' ), 0 );
+
+			assert.areSame( document.getElementById( '_H1' ), range.getCommonAncestor().$ );
+		},
+
+		test_getCommonAncestor3 : function()
+		{
+			var range = new CKEDITOR.dom.range( doc );
+			range.setStart( doc.getById( '_H1' ), 0 );
+			range.setEnd( doc.getById( '_Para' ), 0 );
+
+			assert.areSame( document.getElementById( 'playground' ), range.getCommonAncestor().$ );
+		},
+
+		test_getCommonAncestor4 : function()
+		{
+			var range = new CKEDITOR.dom.range( doc );
+			range.setStart( doc.getById( '_Para' ).getFirst(), 1 );
+			range.setEnd( doc.getById( '_B' ), 0 );
+
+			assert.areSame( document.getElementById( '_Para' ), range.getCommonAncestor().$ );
+		},
+
+		test_getCommonAncestor5 : function()
+		{
+			var range = new CKEDITOR.dom.range( doc );
+			range.setStart( doc.getBody(), 0 );
+			range.setEnd( doc.getById( '_B' ).getFirst(), 1 );
+
+			assert.areSame( document.body, range.getCommonAncestor().$ );
+		},
+
+		test_getCommonAncestor6 : function()
+		{
+			var range = new CKEDITOR.dom.range( doc );
+			range.setStart( doc.getById( '_EnlargeI' ).getFirst(), 2 );
+			range.setEnd( doc.getById( '_EnlargeB' ), 3 );
+
+			assert.areSame( document.getElementById( '_EnlargeB' ), range.getCommonAncestor().$ );
+		},
+
+		test_enlarge_element1 : function()
+		{
+			// For IE, see the next test.
+			if ( CKEDITOR.env.ie )
+				return;
+
+			// <p> Test <b> <i>  [Enlarge]</i> this</b>   </p>
+			// <p> Test <b> [<i>  Enlarge</i>] this</b>   </p>
+
+			var range = new CKEDITOR.dom.range( doc );
+			range.setStart( doc.getById( '_EnlargeI' ).getFirst(), 2 );
+			range.setEnd( doc.getById( '_EnlargeI' ), 1 );
+
+			range.enlarge( CKEDITOR.ENLARGE_ELEMENT );
+
+			assert.areSame( document.getElementById( '_EnlargeB' ), range.startContainer.$, 'range.startContainer' );
+			assert.areSame( 1, range.startOffset, 'range.startOffset' );
+			assert.areSame( document.getElementById( '_EnlargeB' ), range.endContainer.$, 'range.endContainer' );
+			assert.areSame( 2, range.endOffset, 'range.endOffset' );
+			assert.isFalse( range.collapsed, 'range.collapsed' );
+		},
+
+		test_enlarge_element1_ie : function()
+		{
+			// IE normalizes whitespaces when parsing the HTML, so we need a
+			// specific test for it.
+			if ( !CKEDITOR.env.ie )
+				return;
+
+			// <p>Test <b><i>[Enlarge]</i> this</b></p>
+			// <p>Test <b>[<i>Enlarge</i>] this</b></p>
+
+			var range = new CKEDITOR.dom.range( doc );
+			range.setStart( doc.getById( '_EnlargeI' ).getFirst(), 0 );
+			range.setEnd( doc.getById( '_EnlargeI' ), 1 );
+
+			range.enlarge( CKEDITOR.ENLARGE_ELEMENT );
+
+			assert.areSame( document.getElementById( '_EnlargeB' ), range.startContainer.$, 'range.startContainer' );
+			assert.areSame( 0, range.startOffset, 'range.startOffset' );
+			assert.areSame( document.getElementById( '_EnlargeB' ), range.endContainer.$, 'range.endContainer' );
+			assert.areSame( 1, range.endOffset, 'range.endOffset' );
+			assert.isFalse( range.collapsed, 'range.collapsed' );
+		},
+
+		test_enlarge_element2 : function()
+		{
+			// For IE, see the next test.
+			if ( CKEDITOR.env.ie )
+				return;
+
+			// <p> Test <b> <i>  [Enlarge</i> this]</b>   </p>
+			// <p> Test [<b> <i>  Enlarge</i> this</b>]   </p>
+
+			var range = new CKEDITOR.dom.range( doc );
+			range.setStart( doc.getById( '_EnlargeI' ).getFirst(), 2 );
+			range.setEnd( doc.getById( '_EnlargeB' ), 3 );
+
+			range.enlarge( CKEDITOR.ENLARGE_ELEMENT );
+
+			assert.areSame( document.getElementById( '_EnlargeP' ), range.startContainer.$, 'range.startContainer' );
+			assert.areSame( 1, range.startOffset, 'range.startOffset' );
+			assert.areSame( document.getElementById( '_EnlargeP' ), range.endContainer.$, 'range.endContainer' );
+			assert.areSame( 2, range.endOffset, 'range.endOffset' );
+			assert.isFalse( range.collapsed, 'range.collapsed' );
+		},
+
+		test_enlarge_element2_ie : function()
+		{
+			// IE normalizes whitespaces when parsing the HTML, so we need a
+			// specific test for it.
+			if ( !CKEDITOR.env.ie )
+				return;
+
+			// <p>Test <b><i>[Enlarge</i> this]</b></p>
+			// <p>Test [<b><i>Enlarge</i> this</b>]</p>
+
+			var range = new CKEDITOR.dom.range( doc );
+			range.setStart( doc.getById( '_EnlargeI' ).getFirst(), 0 );
+			range.setEnd( doc.getById( '_EnlargeB' ), 2 );
+
+			range.enlarge( CKEDITOR.ENLARGE_ELEMENT );
+
+			assert.areSame( document.getElementById( '_EnlargeP' ), range.startContainer.$, 'range.startContainer' );
+			assert.areSame( 1, range.startOffset, 'range.startOffset' );
+			assert.areSame( document.getElementById( '_EnlargeP' ), range.endContainer.$, 'range.endContainer' );
+			assert.areSame( 2, range.endOffset, 'range.endOffset' );
+			assert.isFalse( range.collapsed, 'range.collapsed' );
+		},
+
+		test_enlarge_element3 : function()
+		{
+			// For IE, see the next test.
+			if ( CKEDITOR.env.ie )
+				return;
+
+			// <p> [Test <b> <i>  Enlarge]</i> this</b>   </p>
+			// <p> [Test <b> <i>  Enlarge</i>] this</b>   </p>
+
+			var range = new CKEDITOR.dom.range( doc );
+			range.setStart( doc.getById( '_EnlargeP' ).getFirst(), 1 );
+			range.setEnd( doc.getById( '_EnlargeI' ), 1 );
+
+			range.enlarge( CKEDITOR.ENLARGE_ELEMENT );
+
+			assert.areSame( document.getElementById( '_EnlargeP' ).firstChild, range.startContainer.$, 'range.startContainer' );
+			assert.areSame( 1, range.startOffset, 'range.startOffset' );
+			assert.areSame( document.getElementById( '_EnlargeB' ), range.endContainer.$, 'range.endContainer' );
+			assert.areSame( 2, range.endOffset, 'range.endOffset' );
+			assert.isFalse( range.collapsed, 'range.collapsed' );
+		},
+
+		test_enlarge_element3_ie : function()
+		{
+			// IE normalizes whitespaces when parsing the HTML, so we need a
+			// specific test for it.
+			if ( !CKEDITOR.env.ie )
+				return;
+
+			// <p>[Test <b><i>Enlarge]</i> this</b></p>
+			// <p>[Test <b><i>Enlarge</i>] this</b></p>
+
+			var range = new CKEDITOR.dom.range( doc );
+			range.setStart( doc.getById( '_EnlargeP' ).getFirst(), 0 );
+			range.setEnd( doc.getById( '_EnlargeI' ), 1 );
+
+			range.enlarge( CKEDITOR.ENLARGE_ELEMENT );
+
+			assert.areSame( document.getElementById( '_EnlargeP' ).firstChild, range.startContainer.$, 'range.startContainer' );
+			assert.areSame( 0, range.startOffset, 'range.startOffset' );
+			assert.areSame( document.getElementById( '_EnlargeB' ), range.endContainer.$, 'range.endContainer' );
+			assert.areSame( 1, range.endOffset, 'range.endOffset' );
+			assert.isFalse( range.collapsed, 'range.collapsed' );
+		},
+
+		test_enlarge_element4 : function()
+		{
+			// For IE, see the next test.
+			if ( CKEDITOR.env.ie )
+				return;
+
+			// <p> [Test <b> <i>  Enlarge</i> this]</b>   </p>
+			// [<p> Test <b> <i>  Enlarge</i> this</b>   </p>]
+
+			var range = new CKEDITOR.dom.range( doc );
+			range.setStart( doc.getById( '_EnlargeP' ).getFirst(), 1 );
+			range.setEnd( doc.getById( '_EnlargeB' ).getChild( 2 ), 5 );
+
+			range.enlarge( CKEDITOR.ENLARGE_ELEMENT );
+
+			assert.areSame( document.getElementById( '_EnlargeP' ).parentNode, range.startContainer.$, 'range.startContainer' );
+			assert.areSame( doc.getById( '_EnlargeP' ).getIndex(), range.startOffset, 'range.startOffset' );
+			assert.areSame( document.getElementById( '_EnlargeP' ).parentNode, range.endContainer.$, 'range.endContainer' );
+			assert.areSame( doc.getById( '_EnlargeP' ).getIndex() + 1, range.endOffset, 'range.endOffset' );
+			assert.isFalse( range.collapsed, 'range.collapsed' );
+		},
+
+		test_enlarge_element4_ie : function()
+		{
+			// IE normalizes whitespaces when parsing the HTML, so we need a
+			// specific test for it.
+			if ( !CKEDITOR.env.ie )
+				return;
+
+			// <p>[Test <b><i>Enlarge</i> this]</b></p>
+			// [<p>Test <b><i>Enlarge</i> this</b></p>]
+
+			var range = new CKEDITOR.dom.range( doc );
+			range.setStart( doc.getById( '_EnlargeP' ).getFirst(), 0 );
+			range.setEnd( doc.getById( '_EnlargeB' ).getChild( 1 ), 5 );
+
+			range.enlarge( CKEDITOR.ENLARGE_ELEMENT );
+
+			assert.areSame( document.getElementById( '_EnlargeP' ).parentNode, range.startContainer.$, 'range.startContainer' );
+			assert.areSame( doc.getById( '_EnlargeP' ).getIndex(), range.startOffset, 'range.startOffset' );
+			assert.areSame( document.getElementById( '_EnlargeP' ).parentNode, range.endContainer.$, 'range.endContainer' );
+			assert.areSame( doc.getById( '_EnlargeP' ).getIndex() + 1, range.endOffset, 'range.endOffset' );
+			assert.isFalse( range.collapsed, 'range.collapsed' );
+		},
+
+		test_enlarge_element5 : function()
+		{
+			// For IE, see the next test.
+			if ( CKEDITOR.env.ie )
+				return;
+
+			// <p> Test<b> <i>  [Enlarge</i> this]</b>   </p>
+			// <p> Test<b> [<i>  Enlarge</i> this]</b>   </p>
+
+			var range = new CKEDITOR.dom.range( doc );
+			range.setStart( doc.getById( '_EnlargeI1' ).getFirst(), 2 );
+			range.setEnd( doc.getById( '_EnlargeB1' ).getChild( 2 ), 5 );
+
+			range.enlarge( CKEDITOR.ENLARGE_ELEMENT );
+
+			assert.areSame( document.getElementById( '_EnlargeB1' ), range.startContainer.$, 'range.startContainer' );
+			assert.areSame( 1, range.startOffset, 'range.startOffset' );
+			assert.areSame( document.getElementById( '_EnlargeB1' ).childNodes[ 2 ], range.endContainer.$, 'range.endContainer' );
+			assert.areSame( 5, range.endOffset, 'range.endOffset' );
+			assert.isFalse( range.collapsed, 'range.collapsed' );
+		},
+
+		test_enlarge_element5_ie : function()
+		{
+			// IE normalizes whitespaces when parsing the HTML, so we need a
+			// specific test for it.
+			if ( !CKEDITOR.env.ie )
+				return;
+
+			// <p>Test<b> <i>[Enlarge</i> this]</b></p>
+			// <p>Test<b> [<i>Enlarge</i> this]</b></p>
+
+			var range = new CKEDITOR.dom.range( doc );
+			range.setStart( doc.getById( '_EnlargeI1' ).getFirst(), 0 );
+			range.setEnd( doc.getById( '_EnlargeB1' ).getChild( 2 ), 5 );
+
+			range.enlarge( CKEDITOR.ENLARGE_ELEMENT );
+
+			assert.areSame( document.getElementById( '_EnlargeB1' ), range.startContainer.$, 'range.startContainer' );
+			assert.areSame( 1, range.startOffset, 'range.startOffset' );
+			assert.areSame( document.getElementById( '_EnlargeB1' ).childNodes[ 2 ], range.endContainer.$, 'range.endContainer' );
+			assert.areSame( 5, range.endOffset, 'range.endOffset' );
+			assert.isFalse( range.collapsed, 'range.collapsed' );
+		},
+
+		test_enlarge_element6 : function()
+		{
+			// For IE, see the next test.
+			if ( CKEDITOR.env.ie )
+				return;
+
+			// <p> <b> <i>  [Enlarge</i>] this</b>   </p>
+			// <p> <b> [<i>  Enlarge</i>] this</b>   </p>
+
+			var range = new CKEDITOR.dom.range( doc );
+			range.setStart( doc.getById( '_EnlargeI2' ).getFirst(), 2 );
+			range.setEnd( doc.getById( '_EnlargeB2' ), 2 );
+
+			range.enlarge( CKEDITOR.ENLARGE_ELEMENT );
+
+			assert.areSame( document.getElementById( '_EnlargeB2' ), range.startContainer.$, 'range.startContainer' );
+			assert.areSame( 1, range.startOffset, 'range.startOffset' );
+			assert.areSame( document.getElementById( '_EnlargeB2' ), range.endContainer.$, 'range.endContainer' );
+			assert.areSame( 2, range.endOffset, 'range.endOffset' );
+			assert.isFalse( range.collapsed, 'range.collapsed' );
+		},
+
+		test_enlarge_element6_ie : function()
+		{
+			// IE normalizes whitespaces when parsing the HTML, so we need a
+			// specific test for it.
+			if ( !CKEDITOR.env.ie )
+				return;
+
+			// <p><b><i>[Enlarge</i>] this</b></p>
+			// <p><b>[<i>Enlarge</i>] this</b></p>
+
+			var range = new CKEDITOR.dom.range( doc );
+			range.setStart( doc.getById( '_EnlargeI2' ).getFirst(), 0 );
+			range.setEnd( doc.getById( '_EnlargeB2' ), 1 );
+
+			range.enlarge( CKEDITOR.ENLARGE_ELEMENT );
+
+			assert.areSame( document.getElementById( '_EnlargeB2' ), range.startContainer.$, 'range.startContainer' );
+			assert.areSame( 0, range.startOffset, 'range.startOffset' );
+			assert.areSame( document.getElementById( '_EnlargeB2' ), range.endContainer.$, 'range.endContainer' );
+			assert.areSame( 1, range.endOffset, 'range.endOffset' );
+			assert.isFalse( range.collapsed, 'range.collapsed' );
+		},
+
+		test_enlarge_element7 : function()
+		{
+			// For IE, see the next test.
+			if ( CKEDITOR.env.ie )
+				return;
+
+			// <p> <b> <i>  [Enlarge</i> this]</b>   </p>
+			// [<p> <b> <i>  Enlarge</i> this</b>   </p>]
+
+			var range = new CKEDITOR.dom.range( doc );
+			range.setStart( doc.getById( '_EnlargeI2' ).getFirst(), 2 );
+			range.setEnd( doc.getById( '_EnlargeB2' ), 3 );
+
+			range.enlarge( CKEDITOR.ENLARGE_ELEMENT );
+
+			assert.areSame( document.getElementById( '_EnlargeP2' ).parentNode, range.startContainer.$, 'range.startContainer' );
+			assert.areSame( doc.getById( '_EnlargeP2' ).getIndex(), range.startOffset, 'range.startOffset' );
+			assert.areSame( document.getElementById( '_EnlargeP2' ).parentNode, range.endContainer.$, 'range.endContainer' );
+			assert.areSame( doc.getById( '_EnlargeP2' ).getIndex() + 1, range.endOffset, 'range.endOffset' );
+			assert.isFalse( range.collapsed, 'range.collapsed' );
+		},
+
+		test_enlarge_element7_ie : function()
+		{
+			// IE normalizes whitespaces when parsing the HTML, so we need a
+			// specific test for it.
+			if ( !CKEDITOR.env.ie )
+				return;
+
+			// <p><b><i>[Enlarge</i> this]</b></p>
+			// [<p><b><i>Enlarge</i> this</b></p>]
+
+			var range = new CKEDITOR.dom.range( doc );
+			range.setStart( doc.getById( '_EnlargeI2' ).getFirst(), 0 );
+			range.setEnd( doc.getById( '_EnlargeB2' ), 2 );
+
+			range.enlarge( CKEDITOR.ENLARGE_ELEMENT );
+
+			assert.areSame( document.getElementById( '_EnlargeP2' ).parentNode, range.startContainer.$, 'range.startContainer' );
+			assert.areSame( doc.getById( '_EnlargeP2' ).getIndex(), range.startOffset, 'range.startOffset' );
+			assert.areSame( document.getElementById( '_EnlargeP2' ).parentNode, range.endContainer.$, 'range.endContainer' );
+			assert.areSame( doc.getById( '_EnlargeP2' ).getIndex() + 1, range.endOffset, 'range.endOffset' );
+			assert.isFalse( range.collapsed, 'range.collapsed' );
+		},
+
+		test_enlarge_element8 : function()
+		{
+			// For IE, see the next test.
+			if ( CKEDITOR.env.ie )
+				return;
+
+			// <p> Test <b> <i>  [Enlarge</i> this</b>   </p><p> <b> <i>  Enlarge</i> this]</b>   </p>
+			// <p> Test [<b> <i>  Enlarge</i> this</b>   </p><p> <b> <i>  Enlarge</i> this</b>   </p>]
+
+			var range = new CKEDITOR.dom.range( doc );
+			range.setStart( doc.getById( '_EnlargeI' ).getFirst(), 2 );
+			range.setEnd( doc.getById( '_EnlargeB2' ), 3 );
+
+			range.enlarge( CKEDITOR.ENLARGE_ELEMENT );
+
+			assert.areSame( document.getElementById( '_EnlargeP' ), range.startContainer.$, 'range.startContainer' );
+			assert.areSame( 1, range.startOffset, 'range.startOffset' );
+			assert.areSame( document.getElementById( '_EnlargeP2' ).parentNode, range.endContainer.$, 'range.endContainer' );
+			assert.areSame( doc.getById( '_EnlargeP2' ).getIndex() + 1, range.endOffset, 'range.endOffset' );
+			assert.isFalse( range.collapsed, 'range.collapsed' );
+		},
+
+		test_enlarge_element8_ie : function()
+		{
+			// IE normalizes whitespaces when parsing the HTML, so we need a
+			// specific test for it.
+			if ( !CKEDITOR.env.ie )
+				return;
+
+			// <p>Test <b><i>[Enlarge</i> this</b></p><p><b><i>Enlarge</i> this]</b></p>
+			// <p>Test [<b><i>Enlarge</i> this</b></p><p><b><i>Enlarge</i> this</b></p>]
+
+			var range = new CKEDITOR.dom.range( doc );
+			range.setStart( doc.getById( '_EnlargeI' ).getFirst(), 0 );
+			range.setEnd( doc.getById( '_EnlargeB2' ), 2 );
+
+			range.enlarge( CKEDITOR.ENLARGE_ELEMENT );
+
+			assert.areSame( document.getElementById( '_EnlargeP' ), range.startContainer.$, 'range.startContainer' );
+			assert.areSame( 1, range.startOffset, 'range.startOffset' );
+			assert.areSame( document.getElementById( '_EnlargeP2' ).parentNode, range.endContainer.$, 'range.endContainer' );
+			assert.areSame( doc.getById( '_EnlargeP2' ).getIndex() + 1, range.endOffset, 'range.endOffset' );
+			assert.isFalse( range.collapsed, 'range.collapsed' );
+		},
+
+		test_enlarge_element9 : function()
+		{
+			// <p>Test<i> [Enlarge</i>]</p>
+			// <p>Test<i> [Enlarge</i>]</p>
+
+			var range = new CKEDITOR.dom.range( doc );
+			range.setStart( doc.getById( '_EnlargeI3' ).getFirst(), 1 );
+			range.setEnd( doc.getById( '_EnlargeP3' ), 2 );
+
+			range.enlarge( CKEDITOR.ENLARGE_ELEMENT );
+
+			assert.areSame( document.getElementById( '_EnlargeI3' ).firstChild, range.startContainer.$, 'range.startContainer' );
+			assert.areSame( 1, range.startOffset, 'range.startOffset' );
+			assert.areSame( document.getElementById( '_EnlargeP3' ), range.endContainer.$, 'range.endContainer' );
+			assert.areSame( 2, range.endOffset, 'range.endOffset' );
+			assert.isFalse( range.collapsed, 'range.collapsed' );
+		},
+
+		test_enlarge_element10 : function()
+		{
+			// For IE, see the next test.
+			if ( CKEDITOR.env.ie )
+				return;
+
+			// <p>Test <i> [Enlarge</i>]</p>
+			// <p>Test [<i> Enlarge</i>]</p>
+
+			var range = new CKEDITOR.dom.range( doc );
+			range.setStart( doc.getById( '_EnlargeI4' ).getFirst(), 1 );
+			range.setEnd( doc.getById( '_EnlargeP4' ), 2 );
+
+			range.enlarge( CKEDITOR.ENLARGE_ELEMENT );
+
+			assert.areSame( document.getElementById( '_EnlargeP4' ), range.startContainer.$, 'range.startContainer' );
+			assert.areSame( 1, range.startOffset, 'range.startOffset' );
+			assert.areSame( document.getElementById( '_EnlargeP4' ), range.endContainer.$, 'range.endContainer' );
+			assert.areSame( 2, range.endOffset, 'range.endOffset' );
+			assert.isFalse( range.collapsed, 'range.collapsed' );
+		},
+
+		test_enlarge_element10_ie : function()
+		{
+			// IE normalizes whitespaces when parsing the HTML, so we need a
+			// specific test for it.
+			if ( !CKEDITOR.env.ie )
+				return;
+
+			// <p>Test <i>[Enlarge</i>]</p>
+			// <p>Test [<i>Enlarge</i>]</p>
+
+			var range = new CKEDITOR.dom.range( doc );
+			range.setStart( doc.getById( '_EnlargeI4' ).getFirst(), 0 );
+			range.setEnd( doc.getById( '_EnlargeP4' ), 2 );
+
+			range.enlarge( CKEDITOR.ENLARGE_ELEMENT );
+
+			assert.areSame( document.getElementById( '_EnlargeP4' ), range.startContainer.$, 'range.startContainer' );
+			assert.areSame( 1, range.startOffset, 'range.startOffset' );
+			assert.areSame( document.getElementById( '_EnlargeP4' ), range.endContainer.$, 'range.endContainer' );
+			assert.areSame( 2, range.endOffset, 'range.endOffset' );
+			assert.isFalse( range.collapsed, 'range.collapsed' );
+		},
+
+		test_enlarge_element11 : function()
+		{
+			// <p>Test <i>[Enlarge]</i></p>
+			// <p>Test [<i>Enlarge</i>]</p>
+
+			var range = new CKEDITOR.dom.range( doc );
+			range.setStart( doc.getById( '_EnlargeI5' ), 0 );
+			range.setEnd( doc.getById( '_EnlargeI5' ), 1 );
+
+			range.enlarge( CKEDITOR.ENLARGE_ELEMENT );
+
+			assert.areSame( document.getElementById( '_EnlargeP5' ), range.startContainer.$, 'range.startContainer' );
+			assert.areSame( 1, range.startOffset, 'range.startOffset' );
+			assert.areSame( document.getElementById( '_EnlargeP5' ), range.endContainer.$, 'range.endContainer' );
+			assert.areSame( 2, range.endOffset, 'range.endOffset' );
+			assert.isFalse( range.collapsed, 'range.collapsed' );
+		},
+
+		test_enlarge_element12 : function()
+		{
+			// <p>Test <i><b></b>[Enlarge]</i></p>
+			// <p>Test [<i><b></b>Enlarge</i>]</p>
+
+			var range = new CKEDITOR.dom.range( doc );
+			range.setStart( doc.getById( '_EnlargeI6' ), 1 );
+			range.setEnd( doc.getById( '_EnlargeI6' ), 2 );
+
+			range.enlarge( CKEDITOR.ENLARGE_ELEMENT );
+
+			assert.areSame( document.getElementById( '_EnlargeP6' ), range.startContainer.$, 'range.startContainer' );
+			assert.areSame( 1, range.startOffset, 'range.startOffset' );
+			assert.areSame( document.getElementById( '_EnlargeP6' ), range.endContainer.$, 'range.endContainer' );
+			assert.areSame( 2, range.endOffset, 'range.endOffset' );
+			assert.isFalse( range.collapsed, 'range.collapsed' );
+		},
+
+		test_enlarge_element13 : function()
+		{
+			// <p>Test <i><b></b>[Enlarge]</i></p>
+			// <p>Test [<i><b></b>Enlarge</i>]</p>
+
+			doc.getById( '_EnlargeP' ).setHtml( 'this <i>is some </i>sample text' );
+
+			var range = new CKEDITOR.dom.range( doc );
+			range.setStart( doc.getById( '_EnlargeP' ), 0 );
+			range.setEnd( doc.getById( '_EnlargeP' ).getChild( 1 ), 0 );
+
+			range.enlarge( CKEDITOR.ENLARGE_ELEMENT );
+
+			assert.areSame( document.getElementById( '_EnlargeP' ), range.startContainer.$, 'range.startContainer' );
+			assert.areSame( 0, range.startOffset, 'range.startOffset' );
+			assert.areSame( document.getElementById( '_EnlargeP' ).childNodes[ 1 ], range.endContainer.$, 'range.endContainer' );
+			assert.areSame( 0, range.endOffset, 'range.endOffset' );
+			assert.isFalse( range.collapsed, 'range.collapsed' );
+		},
+
+		test_deleteContents_W3C_1 : function()
+		{
+			// W3C DOM Range Specs - Section 2.6 - Example 1
+
+			var range = new CKEDITOR.dom.range( doc );
+			range.setStart( doc.getById( '_Para' ).getFirst(), 1 );
+			range.setEnd( doc.getById( '_Para' ), 2 );
+
+			range.deleteContents();
+
+			assert.areSame( 't text.', getInnerHtml( '_Para' ), 'HTML after deletion' );
+
+			assert.areSame( document.getElementById( '_Para' ).firstChild, range.startContainer.$, 'range.startContainer' );
+			assert.areSame( 1, range.startOffset, 'range.startOffset' );
+			assert.areSame( document.getElementById( '_Para' ).firstChild, range.endContainer.$, 'range.endContainer' );
+			assert.areSame( 1, range.endOffset, 'range.endOffset' );
+			assert.isTrue( range.collapsed, 'range.collapsed' );
+		},
+
+		test_deleteContents_W3C_2 : function()
+		{
+			// W3C DOM Range Specs - Section 2.6 - Example 2
+
+			var range = new CKEDITOR.dom.range( doc );
+			range.setStart( doc.getById( '_B' ).getFirst(), 1 );
+			range.setEnd( doc.getById( '_B' ).getNext(), 1 );
+
+			range.deleteContents();
+
+			assert.areSame( 'this is <b id="_b">s</b>text.', getInnerHtml( '_Para' ) );
+
+			assert.areSame( document.getElementById( '_Para' ), range.startContainer.$, 'range.startContainer' );
+			assert.areSame( 2, range.startOffset, 'range.startOffset' );
+			assert.areSame( document.getElementById( '_Para' ), range.endContainer.$, 'range.endContainer' );
+			assert.areSame( 2, range.endOffset, 'range.endOffset' );
+			assert.isTrue( range.collapsed, 'range.collapsed' );
+		},
+
+		test_deleteContents_W3C_3 : function()
+		{
+			// W3C DOM Range Specs - Section 2.6 - Example 3
+
+			var range = new CKEDITOR.dom.range( doc );
+			range.setStart( doc.getById( '_B' ).getPrevious(), 1 );
+			range.setEnd( doc.getById( '_B' ).getFirst(), 1 );
+
+			range.deleteContents();
+
+			assert.areSame( 't<b id="_b">ome</b> text.', getInnerHtml( '_Para' ) );
+
+			assert.areSame( document.getElementById( '_Para' ), range.startContainer.$, 'range.startContainer' );
+			assert.areSame( 1, range.startOffset, 'range.startOffset' );
+			assert.areSame( document.getElementById( '_Para' ), range.endContainer.$, 'range.endContainer' );
+			assert.areSame( 1, range.endOffset, 'range.endOffset' );
+			assert.isTrue( range.collapsed, 'range.collapsed' );
+		},
+
+		test_deleteContents_W3C_4 : function()
+		{
+			// W3C DOM Range Specs - Section 2.6 - Example 4
+
+			var range = new CKEDITOR.dom.range( doc );
+			range.setStart( doc.getById( '_H1' ).getFirst(), 1 );
+			range.setEnd( doc.getById( 'playground' ).getLast().getFirst(), 1 );
+
+			range.deleteContents();
+
+			assert.areSame( '<h1 id="_h1">f</h1><p>nother paragraph.</p>', getInnerHtml( 'playground' ) );
+
+			assert.areSame( document.getElementById( 'playground' ), range.startContainer.$, 'range.startContainer' );
+			assert.areSame( 1, range.startOffset, 'range.startOffset' );
+			assert.areSame( document.getElementById( 'playground' ), range.endContainer.$, 'range.endContainer' );
+			assert.areSame( 1, range.endOffset, 'range.endOffset' );
+			assert.isTrue( range.collapsed, 'range.collapsed' );
+		},
+
+		test_deleteContents_Other : function()
+		{
+			var range = new CKEDITOR.dom.range( doc );
+			range.setStart( doc.getById( '_H1' ), 0 );
+			range.setEnd( doc.getById( 'playground' ).getLast(), 1 );
+
+			range.deleteContents();
+
+			assert.areSame( '<h1 id="_h1"></h1><p></p>', getInnerHtml( 'playground' ) );
+
+			assert.areSame( document.getElementById( 'playground' ), range.startContainer.$, 'range.startContainer' );
+			assert.areSame( 1, range.startOffset, 'range.startOffset' );
+			assert.areSame( document.getElementById( 'playground' ), range.endContainer.$, 'range.endContainer' );
+			assert.areSame( 1, range.endOffset, 'range.endOffset' );
+			assert.isTrue( range.collapsed, 'range.collapsed' );
+		},
+
+		test_deleteContents_Other_2 : function()
+		{
+			var range = new CKEDITOR.dom.range( doc );
+			range.setStart( doc.getById( 'playground' ), 0 );
+			range.setEnd( doc.getById( 'playground' ), 2 );
+
+			range.deleteContents();
+
+			assert.areSame( '<p>another paragraph.</p>', getInnerHtml( 'playground' ) );
+
+			assert.areSame( document.getElementById( 'playground' ), range.startContainer.$, 'range.startContainer' );
+			assert.areSame( 0, range.startOffset, 'range.startOffset' );
+			assert.areSame(document.getElementById( 'playground' ), range.endContainer.$, 'range.endContainer' );
+			assert.areSame( 0, range.endOffset, 'range.endOffset' );
+			assert.isTrue( range.collapsed, 'range.collapsed' );
+		},
+
+		test_deleteContents_Other_3 : function()
+		{
+			var range = new CKEDITOR.dom.range( doc );
+			range.selectNodeContents( doc.getById('_B') );
+
+			range.deleteContents();
+
+			assert.areSame( '', getInnerHtml('_B') );
+
+			assert.areSame( document.getElementById('_B'), range.startContainer.$, 'range.startContainer' );
+			assert.areSame( 0, range.startOffset, 'range.startOffset' );
+			assert.areSame( document.getElementById('_B'), range.endContainer.$, 'range.endContainer' );
+			assert.areSame( 0, range.endOffset, 'range.endOffset' );
+			assert.isTrue( range.collapsed, 'range.collapsed' );
+		},
+
+		test_deleteContents_Other_4 : function()
+		{
+			var range = new CKEDITOR.dom.range( doc );
+			range.selectNodeContents( doc.getById('_Para') );
+
+			range.deleteContents();
+
+			assert.areSame( '', getInnerHtml('_Para') );
+
+			assert.areSame( document.getElementById('_Para'), range.startContainer.$, 'range.startContainer' );
+			assert.areSame( 0, range.startOffset, 'range.startOffset' );
+			assert.areSame( document.getElementById('_Para'), range.endContainer.$, 'range.endContainer' );
+			assert.areSame( 0, range.endOffset, 'range.endOffset' );
+			assert.isTrue( range.collapsed, 'range.collapsed' );
+		},
+
+		test_extractContents_W3C_1 : function()
+		{
+			// W3C DOM Range Specs - Section 2.7 - Example 1
+
+			var range = new CKEDITOR.dom.range( doc );
+			range.setStart( doc.getById( '_Para' ).getFirst(), 1 );
+			range.setEnd( doc.getById( '_Para' ), 2 );
+
+			var docFrag = range.extractContents();
+
+			var tmpDiv = doc.createElement( 'div' );
+			docFrag.appendTo( tmpDiv );
+
+			assert.areSame( 'his is <b id="_b">some</b>', getInnerHtml( tmpDiv.$ ), 'Extracted HTML' );
+			assert.areSame( 't text.', getInnerHtml( '_Para' ), 'HTML after extraction' );
+
+			assert.areSame( document.getElementById( '_Para' ).firstChild, range.startContainer.$, 'range.startContainer' );
+			assert.areSame( 1, range.startOffset, 'range.startOffset' );
+			assert.areSame( document.getElementById( '_Para' ).firstChild, range.endContainer.$, 'range.endContainer' );
+			assert.areSame( 1, range.endOffset, 'range.endOffset' );
+			assert.isTrue( range.collapsed, 'range.collapsed' );
+		},
+
+		test_extractContents_W3C_2 : function()
+		{
+			// W3C DOM Range Specs - Section 2.7 - Example 2
+
+			var range = new CKEDITOR.dom.range( doc );
+			range.setStart( doc.getById( '_B' ).getFirst(), 1 );
+			range.setEnd( doc.getById( '_B' ).getNext(), 2 );
+
+			var docFrag = range.extractContents();
+
+			var tmpDiv = doc.createElement( 'div' );
+			docFrag.appendTo( tmpDiv );
+
+			assert.areSame( '<b id="_b">ome</b> t', getInnerHtml( tmpDiv.$ ), 'Extracted HTML' );
+			assert.areSame( 'this is <b id="_b">s</b>ext.', getInnerHtml( '_Para' ), 'HTML after extraction' );
+
+			assert.areSame( document.getElementById( '_Para' ), range.startContainer.$, 'range.startContainer' );
+			assert.areSame( 2, range.startOffset, 'range.startOffset' );
+			assert.areSame( document.getElementById( '_Para' ), range.endContainer.$, 'range.endContainer' );
+			assert.areSame( 2, range.endOffset, 'range.endOffset' );
+			assert.isTrue( range.collapsed, 'range.collapsed' );
+		},
+
+		test_extractContents_W3C_3 : function()
+		{
+			// W3C DOM Range Specs - Section 2.6 - Example 3
+
+			var range = new CKEDITOR.dom.range( doc );
+			range.setStart( doc.getById( '_B' ).getPrevious(), 1 );
+			range.setEnd( doc.getById( '_B' ).getFirst(), 1 );
+
+			var docFrag = range.extractContents();
+
+			var tmpDiv = doc.createElement( 'div' );
+			docFrag.appendTo( tmpDiv );
+
+			assert.areSame( 'his is <b id="_b">s</b>', getInnerHtml( tmpDiv.$ ), 'Extracted HTML' );
+			assert.areSame( 't<b id="_b">ome</b> text.', getInnerHtml( '_Para' ), 'HTML after extraction' );
+
+			assert.areSame( document.getElementById( '_Para' ), range.startContainer.$, 'range.startContainer' );
+			assert.areSame( 1, range.startOffset, 'range.startOffset' );
+			assert.areSame( document.getElementById( '_Para' ), range.endContainer.$, 'range.endContainer' );
+			assert.areSame( 1, range.endOffset, 'range.endOffset' );
+			assert.isTrue( range.collapsed, 'range.collapsed' );
+		},
+
+		test_extractContents_W3C_4 : function()
+		{
+			// W3C DOM Range Specs - Section 2.6 - Example 4
+
+			var range = new CKEDITOR.dom.range( doc );
+			range.setStart( doc.getById( '_H1' ).getFirst(), 1 );
+			range.setEnd( doc.getById( 'playground' ).getLast().getFirst(), 1 );
+
+			var docFrag = range.extractContents();
+
+			var tmpDiv = doc.createElement( 'div' );
+			docFrag.appendTo( tmpDiv );
+
+			assert.areSame( '<h1 id="_h1">ckw3crange test</h1><p id="_para">this is <b id="_b">some</b> text.</p><p>a</p>', getInnerHtml( tmpDiv.$ ), 'Extracted HTML' );
+			assert.areSame( '<h1 id="_h1">f</h1><p>nother paragraph.</p>', getInnerHtml( 'playground' ) );
+
+			assert.areSame( document.getElementById( 'playground' ), range.startContainer.$, 'range.startContainer' );
+			assert.areSame( 1, range.startOffset, 'range.startOffset' );
+			assert.areSame( document.getElementById( 'playground' ), range.endContainer.$, 'range.endContainer' );
+			assert.areSame( 1, range.endOffset, 'range.endOffset' );
+			assert.isTrue( range.collapsed, 'range.collapsed' );
+		},
+
+		test_extractContents_Other : function()
+		{
+			var range = new CKEDITOR.dom.range( doc );
+			range.setStart( doc.getById( '_H1' ), 0 );
+			range.setEnd( doc.getById( 'playground' ).getLast(), 1 );
+
+			var docFrag = range.extractContents();
+
+			var tmpDiv = doc.createElement( 'div' );
+			docFrag.appendTo( tmpDiv );
+
+			assert.areSame( '<h1 id="_h1">fckw3crange test</h1><p id="_para">this is <b id="_b">some</b> text.</p><p>another paragraph.</p>', getInnerHtml( tmpDiv.$ ), 'Extracted HTML' );
+			assert.areSame( '<h1 id="_h1"></h1><p></p>', getInnerHtml( 'playground' ) );
+
+			assert.areSame( document.getElementById( 'playground' ), range.startContainer.$, 'range.startContainer' );
+			assert.areSame( 1, range.startOffset, 'range.startOffset' );
+			assert.areSame( document.getElementById( 'playground' ), range.endContainer.$, 'range.endContainer' );
+			assert.areSame( 1, range.endOffset, 'range.endOffset' );
+			assert.isTrue( range.collapsed, 'range.collapsed' );
+		},
+
+		test_extractContents_Other_2 : function()
+		{
+			var range = new CKEDITOR.dom.range( doc );
+			range.setStart( doc.getById( 'playground' ), 0 );
+			range.setEnd( doc.getById( 'playground' ), 2 );
+
+			var docFrag = range.extractContents();
+
+			var tmpDiv = doc.createElement( 'div' );
+			docFrag.appendTo( tmpDiv );
+
+			assert.areSame( '<h1 id="_h1">fckw3crange test</h1><p id="_para">this is <b id="_b">some</b> text.</p>', getInnerHtml( tmpDiv.$ ), 'Extracted HTML' );
+			assert.areSame( '<p>another paragraph.</p>', getInnerHtml( 'playground' ) );
+
+			assert.areSame( document.getElementById( 'playground' ), range.startContainer.$, 'range.startContainer' );
+			assert.areSame( 0, range.startOffset, 'range.startOffset' );
+			assert.areSame( document.getElementById( 'playground' ), range.endContainer.$, 'range.endContainer' );
+			assert.areSame( 0, range.endOffset, 'range.endOffset' );
+			assert.isTrue( range.collapsed, 'range.collapsed' );
+		},
+
+		test_extractContents_Other_3 : function()
+		{
+			var range = new CKEDITOR.dom.range( doc );
+
+			range.selectNodeContents( doc.getById('_B') );
+
+			var docFrag = range.extractContents();
+
+			var tmpDiv = doc.createElement( 'div' );
+			docFrag.appendTo( tmpDiv );
+
+			assert.areSame( 'some', getInnerHtml( tmpDiv.$ ), 'Extracted HTML' );
+			assert.areSame( '', getInnerHtml('_B'), 'HTML after extraction' );
+
+			assert.areSame( document.getElementById('_B'), range.startContainer.$, 'range.startContainer' );
+			assert.areSame( 0, range.startOffset, 'range.startOffset' );
+			assert.areSame( document.getElementById('_B'), range.endContainer.$, 'range.endContainer' );
+			assert.areSame( 0, range.endOffset, 'range.endOffset' );
+			assert.isTrue( range.collapsed, 'range.collapsed' );
+		},
+
+		test_extractContents_Other_4 : function()
+		{
+			var range = new CKEDITOR.dom.range( doc );
+
+			range.selectNodeContents( doc.getById('_Para') );
+
+			var docFrag = range.extractContents();
+
+			var tmpDiv = doc.createElement( 'div' );
+			docFrag.appendTo( tmpDiv );
+
+			assert.areSame( 'this is <b id="_b">some</b> text.', getInnerHtml( tmpDiv.$ ), 'Extracted HTML' );
+			assert.areSame( '', getInnerHtml('_Para'), 'HTML after extraction' );
+
+			assert.areSame( document.getElementById('_Para'), range.startContainer.$, 'range.startContainer' );
+			assert.areSame( 0, range.startOffset, 'range.startOffset' );
+			assert.areSame( document.getElementById('_Para'), range.endContainer.$, 'range.endContainer' );
+			assert.areSame( 0, range.endOffset, 'range.endOffset' );
+			assert.isTrue( range.collapsed, 'range.collapsed' );
+		},
+
+		test_extractContents_Other_5 : function()
+		{
+			document.getElementById( 'playground' ).innerHTML = '<p><b><i>test</i></b></p>';
+
+			var range = new CKEDITOR.dom.range( doc );
+			range.setStartAfter( new CKEDITOR.dom.element( document.getElementById( 'playground' ).getElementsByTagName('i')[0] ) );
+			range.setEndAfter( new CKEDITOR.dom.element( document.getElementById( 'playground' ).getElementsByTagName('b')[0] ) );
+
+			var docFrag = range.extractContents();
+
+			var tmpDiv = doc.createElement( 'div' );
+			docFrag.appendTo( tmpDiv );
+
+			assert.areSame( '<b></b>', getInnerHtml( tmpDiv.$ ), 'Extracted HTML' );
+			assert.areSame( '<p><b><i>test</i></b></p>', getInnerHtml( 'playground' ), 'HTML after extraction' );
+
+			assert.areSame( document.getElementById( 'playground' ).firstChild, range.startContainer.$, 'range.startContainer' );
+			assert.areSame( 1, range.startOffset, 'range.startOffset' );
+			assert.areSame( document.getElementById( 'playground' ).firstChild, range.endContainer.$, 'range.endContainer' );
+			assert.areSame( 1, range.endOffset, 'range.endOffset' );
+			assert.isTrue( range.collapsed, 'range.collapsed' );
+		},
+
+		test_extractContents_Other_6 : function()
+		{
+			document.getElementById( 'playground' ).innerHTML = '<p><b><i>test</i></b></p>';
+
+			var range = new CKEDITOR.dom.range( doc );
+
+			range.setStartBefore( new CKEDITOR.dom.element( document.getElementById( 'playground' ).getElementsByTagName('b')[0] ) );
+			range.setEndBefore( new CKEDITOR.dom.element( document.getElementById( 'playground' ).getElementsByTagName('i')[0] ) );
+
+			var docFrag = range.extractContents();
+
+			var tmpDiv = doc.createElement( 'div' );
+			docFrag.appendTo( tmpDiv );
+
+			assert.areSame( '<b></b>', getInnerHtml( tmpDiv.$ ), 'Extracted HTML' );
+			assert.areSame( '<p><b><i>test</i></b></p>', getInnerHtml( 'playground' ), 'HTML after extraction' );
+
+			assert.areSame( document.getElementById( 'playground' ).firstChild, range.startContainer.$, 'range.startContainer' );
+			assert.areSame( 0, range.startOffset, 'range.startOffset' );
+			assert.areSame( document.getElementById( 'playground' ).firstChild, range.endContainer.$, 'range.endContainer' );
+			assert.areSame( 0, range.endOffset, 'range.endOffset' );
+			assert.isTrue( range.collapsed, 'range.collapsed' );
+		},
+
+		test_cloneContents_W3C_1 : function()
+		{
+			// W3C DOM Range Specs - Section 2.7 - Example 1
+
+			var range = new CKEDITOR.dom.range( doc );
+			range.setStart( doc.getById( '_Para' ).getFirst(), 1 );
+			range.setEnd( doc.getById( '_Para' ), 2 );
+
+			var bodyHtml = document.getElementById( 'playground' ).innerHTML;
+
+			var docFrag = range.cloneContents();
+
+			var tmpDiv = doc.createElement( 'div' );
+			docFrag.appendTo( tmpDiv );
+
+			assert.areSame( 'his is <b id="_b">some</b>', getInnerHtml( tmpDiv.$ ), 'Cloned HTML' );
+
+			// The body HTML must remain unchanged.
+			assert.areSame( bodyHtml.replace( /\s+_cke_expando=["\d]+/g, '' ), document.getElementById( 'playground' ).innerHTML.replace( /\s+_cke_expando=["\d]+/g, '' ), 'The HTML must remain untouched' );
+
+			// The range must also remain unchanged.
+			assert.areSame( document.getElementById( '_Para' ).firstChild, range.startContainer.$, 'range.startContainer' );
+			assert.areSame( 1, range.startOffset, 'range.startOffset' );
+			assert.areSame( document.getElementById( '_Para' ), range.endContainer.$, 'range.endContainer' );
+			assert.areSame( 2, range.endOffset, 'range.endOffset' );
+			assert.isFalse( range.collapsed, 'range.collapsed' );
+		},
+
+		test_cloneContents_W3C_2 : function()
+		{
+			// W3C DOM Range Specs - Section 2.7 - Example 2
+
+			var range = new CKEDITOR.dom.range( doc );
+			range.setStart( doc.getById( '_B' ).getFirst(), 1 );
+			range.setEnd( doc.getById( '_B' ).getNext(), 2 );
+
+			var bodyHtml = document.getElementById( 'playground' ).innerHTML;
+
+			var docFrag = range.cloneContents();
+
+			var tmpDiv = doc.createElement( 'div' );
+			docFrag.appendTo( tmpDiv );
+
+			assert.areSame( '<b id="_b">ome</b> t', getInnerHtml( tmpDiv.$ ), 'Cloned HTML' );
+
+			// The body HTML must remain unchanged.
+			assert.areSame( bodyHtml.replace( /\s+_cke_expando=["\d]+/g, '' ), document.getElementById( 'playground' ).innerHTML.replace( /\s+_cke_expando=["\d]+/g, '' ), 'The HTML must remain untouched' );
+
+			// The range must also remain unchanged.
+			assert.areSame( document.getElementById( '_B' ).firstChild, range.startContainer.$, 'range.startContainer' );
+			assert.areSame( 1, range.startOffset, 'range.startOffset' );
+			assert.areSame( document.getElementById( '_B' ).nextSibling, range.endContainer.$, 'range.endContainer' );
+			assert.areSame( 2, range.endOffset, 'range.endOffset' );
+			assert.isFalse( range.collapsed, 'range.collapsed' );
+		},
+
+		test_cloneContents_W3C_3 : function()
+		{
+			// W3C DOM Range Specs - Section 2.6 - Example 3
+
+			var range = new CKEDITOR.dom.range( doc );
+			range.setStart( doc.getById( '_B' ).getPrevious(), 1 );
+			range.setEnd( doc.getById( '_B' ).getFirst(), 1 );
+
+			var bodyHtml = document.getElementById( 'playground' ).innerHTML;
+
+			var docFrag = range.cloneContents();
+
+			var tmpDiv = doc.createElement( 'div' );
+			docFrag.appendTo( tmpDiv );
+
+			assert.areSame( 'his is <b id="_b">s</b>', getInnerHtml( tmpDiv.$ ), 'Cloned HTML' );
+
+			// The body HTML must remain unchanged.
+			assert.areSame( bodyHtml.replace( /\s+_cke_expando=["\d]+/g, '' ), document.getElementById( 'playground' ).innerHTML.replace( /\s+_cke_expando=["\d]+/g, '' ), 'The HTML must remain untouched' );
+
+			// The range must also remain unchanged.
+			assert.areSame( document.getElementById( '_B' ).previousSibling, range.startContainer.$, 'range.startContainer' );
+			assert.areSame( 1, range.startOffset, 'range.startOffset' );
+			assert.areSame( document.getElementById( '_B' ).firstChild, range.endContainer.$, 'range.endContainer' );
+			assert.areSame( 1, range.endOffset, 'range.endOffset' );
+			assert.isFalse( range.collapsed, 'range.collapsed' );
+		},
+
+		// W3C DOM Range Specs - Section 2.6 - Example 4
+		test_cloneContents_W3C_4 : function()
+		{
+			var range = new CKEDITOR.dom.range( doc );
+
+			range.setStart( doc.getById( '_H1' ).getFirst(), 1 );
+			range.setEnd( doc.getById( 'playground' ).getLast().getFirst(), 1 );
+
+			var bodyHtml = document.getElementById( 'playground' ).innerHTML;
+
+			var docFrag = range.cloneContents();
+
+			var tmpDiv = doc.createElement( 'div' );
+			docFrag.appendTo( tmpDiv );
+
+			assert.areSame( '<h1 id="_h1">ckw3crange test</h1><p id="_para">this is <b id="_b">some</b> text.</p><p>a</p>', getInnerHtml( tmpDiv.$ ), 'Cloned HTML' );
+
+			// The body HTML must remain unchanged.
+			assert.areSame( bodyHtml.replace( /\s+_cke_expando=["\d]+/g, '' ), document.getElementById( 'playground' ).innerHTML.replace( /\s+_cke_expando=["\d]+/g, '' ), 'The HTML must remain untouched' );
+
+			// The range must also remain unchanged.
+			assert.areSame( document.getElementById( '_H1' ).firstChild, range.startContainer.$, 'range.startContainer' );
+			assert.areSame( 1, range.startOffset, 'range.startOffset' );
+			assert.areSame( document.getElementById( 'playground' ).lastChild.firstChild, range.endContainer.$, 'range.endContainer' );
+			assert.areSame( 1, range.endOffset, 'range.endOffset' );
+			assert.isFalse( range.collapsed, 'range.collapsed' );
+		},
+
+		test_cloneContents_Other : function()
+		{
+			var range = new CKEDITOR.dom.range( doc );
+
+			range.setStart( doc.getById( '_H1' ), 0 );
+			range.setEnd( doc.getById( 'playground' ).getLast(), 1 );
+
+			var bodyHtml = document.getElementById( 'playground' ).innerHTML;
+
+			var docFrag = range.cloneContents();
+
+			var tmpDiv = doc.createElement( 'div' );
+			docFrag.appendTo( tmpDiv );
+
+			assert.areSame( '<h1 id="_h1">fckw3crange test</h1><p id="_para">this is <b id="_b">some</b> text.</p><p>another paragraph.</p>', getInnerHtml( tmpDiv.$ ), 'Cloned HTML' );
+
+			// The body HTML must remain unchanged.
+			assert.areSame( bodyHtml.replace( /\s+_cke_expando=["\d]+/g, '' ), document.getElementById( 'playground' ).innerHTML.replace( /\s+_cke_expando=["\d]+/g, '' ), 'The HTML must remain untouched' );
+
+			// The range must also remain unchanged.
+			assert.areSame( document.getElementById( '_H1' ), range.startContainer.$, 'range.startContainer' );
+			assert.areSame( 0, range.startOffset, 'range.startOffset' );
+			assert.areSame( document.getElementById( 'playground' ).lastChild, range.endContainer.$, 'range.endContainer' );
+			assert.areSame( 1, range.endOffset, 'range.endOffset' );
+			assert.isFalse( range.collapsed, 'range.collapsed' );
+		},
+
+		test_cloneContents_Other_2 : function()
+		{
+			var range = new CKEDITOR.dom.range( doc );
+
+			range.setStart( doc.getById( 'playground' ), 0 );
+			range.setEnd( doc.getById( 'playground' ), 2 );
+
+			var bodyHtml = document.getElementById( 'playground' ).innerHTML;
+
+			var docFrag = range.cloneContents();
+
+			var tmpDiv = doc.createElement( 'div' );
+			docFrag.appendTo( tmpDiv );
+
+			assert.areSame( '<h1 id="_h1">fckw3crange test</h1><p id="_para">this is <b id="_b">some</b> text.</p>', getInnerHtml( tmpDiv.$ ), 'Cloned HTML' );
+
+			// The body HTML must remain unchanged.
+			assert.areSame( bodyHtml.replace( /\s+_cke_expando=["\d]+/g, '' ), document.getElementById( 'playground' ).innerHTML.replace( /\s+_cke_expando=["\d]+/g, '' ), 'The HTML must remain untouched' );
+
+			// The range must also remain unchanged.
+			assert.areSame( document.getElementById( 'playground' ), range.startContainer.$, 'range.startContainer' );
+			assert.areSame( 0, range.startOffset, 'range.startOffset' );
+			assert.areSame( document.getElementById( 'playground' ), range.endContainer.$, 'range.endContainer' );
+			assert.areSame( 2, range.endOffset, 'range.endOffset' );
+			assert.isFalse( range.collapsed, 'range.collapsed' );
+		},
+
+		test_cloneContents_Other_3 : function()
+		{
+			var range = new CKEDITOR.dom.range( doc );
+
+			range.selectNodeContents( doc.getById('_B') );
+
+			var bodyHtml = document.getElementById( 'playground' ).innerHTML;
+
+			var docFrag = range.cloneContents();
+
+			var tmpDiv = doc.createElement( 'div' );
+			docFrag.appendTo( tmpDiv );
+
+			assert.areSame( 'some', getInnerHtml( tmpDiv.$ ), 'Cloned HTML' );
+
+			// The body HTML must remain unchanged.
+			assert.areSame( bodyHtml.replace( /\s+_cke_expando=["\d]+/g, '' ), document.getElementById( 'playground' ).innerHTML.replace( /\s+_cke_expando=["\d]+/g, '' ), 'The HTML must remain untouched' );
+
+			assert.areSame( document.getElementById('_B'), range.startContainer.$, 'range.startContainer' );
+			assert.areSame( 0, range.startOffset, 'range.startOffset' );
+			assert.areSame( document.getElementById('_B'), range.endContainer.$, 'range.endContainer' );
+			assert.areSame( 1, range.endOffset, 'range.endOffset' );
+			assert.isFalse( range.collapsed, 'range.collapsed' );
+		},
+
+		test_cloneContents_Other_4 : function()
+		{
+			var range = new CKEDITOR.dom.range( doc );
+
+			range.selectNodeContents( doc.getById('_Para') );
+
+			var bodyHtml = document.getElementById( 'playground' ).innerHTML;
+
+			var docFrag = range.cloneContents();
+
+			var tmpDiv = doc.createElement( 'div' );
+			docFrag.appendTo( tmpDiv );
+
+			assert.areSame( 'this is <b id="_b">some</b> text.', getInnerHtml( tmpDiv.$ ), 'Cloned HTML' );
+
+			// The body HTML must remain unchanged.
+			assert.areSame( bodyHtml.replace( /\s+_cke_expando=["\d]+/g, '' ), document.getElementById( 'playground' ).innerHTML.replace( /\s+_cke_expando=["\d]+/g, '' ), 'The HTML must remain untouched' );
+
+			assert.areSame( document.getElementById('_Para'), range.startContainer.$, 'range.startContainer' );
+			assert.areSame( 0, range.startOffset, 'range.startOffset' );
+			assert.areSame( document.getElementById('_Para'), range.endContainer.$, 'range.endContainer' );
+			assert.areSame( 3, range.endOffset, 'range.endOffset' );
+			assert.isFalse( range.collapsed, 'range.collapsed' );
+		},
+
+		/////////////
+
+		setUp : function()
+		{
+			 document.getElementById( 'playground' ).innerHTML = html1;
+			 document.getElementById( 'playground2' ).innerHTML = html2;
+		},
+
+		name : document.title
+	};
+})() );
+
+//window.onload = function()
+//{
+//	// Local references.
+//	var assert			= CKEDITOR.test.assert;
+//	var getInnerHtml	= CKEDITOR.test.getInnerHtml;
+
+//	var doc = new CKEDITOR.dom.document( document );
+
+//			doc.getById( '_EnlargeP' ).setHtml( 'this <i>is some </i>sample text' );
+
+//			var range = new CKEDITOR.dom.range( doc );
+//			range.setStart( doc.getById( '_EnlargeP' ), 0 );
+//			range.setEnd( doc.getById( '_EnlargeP' ).getChild( 1 ), 0 );
+
+//			range.enlarge( CKEDITOR.ENLARGE_ELEMENT );
+//}
+
+	//]]>
+	</script>
+</head>
+<body>
+	<div id="playground" style="visibility:hidden"><h1 id="_H1">FCKW3CRange Test</h1><p id="_Para">This is <b id="_B">some</b> text.</p><p>Another paragraph.</p></div>
+	<div id="playground2" style="visibility: hidden">
+		<h1>
+			Test page for FCKeditor
+		</h1>
+		<p id="_P">
+			This document contains various markup features commonly used by content editors
+			or "<span id="_Span" lang="fr">r&eacute;dacteurs de contenu</span>" as they are
+			called in <a id="_A" href="http://en.wikipedia.org/wiki/France" title="Wikipedia article about France">
+				France</a>.<br />
+			It is important that a <acronym id="_Acronym" title="what you see is what you get">WYSIWYG</acronym>
+			tool has features that are easily available for the editor. If not, there is a risk
+			that content won't receive <strong id="_Strong">proper</strong> markup. Examples
+			of commonly found content are:</p>
+		<p id="_Pnbsp">
+			&nbsp;
+		</p>
+		<p id="_Pspaces">
+		</p>
+		<ol>
+			<li>Headings</li>
+			<li style="color: Red">Links (with optional title) </li>
+			<li>Lists (like this one)
+				<ul>
+					<li>including nested lists </li>
+				</ul>
+			</li>
+			<li>Tables
+				<ul>
+					<li>caption</li>
+					<li>headers</li>
+					<li>summary</li>
+				</ul>
+			</li>
+			<li>Language information</li>
+			<li>Acronyms and abbreviations</li>
+			<li>Emphasis and strong emphasis </li>
+			<li>Quotes, inline and block </li>
+			<li>Images</li>
+		</ol>
+		<hr />
+		<h2 style="background-color: Silver">
+			Test procedure
+		</h2>
+		This text has no block tag. It should be corrected when working with the enter key
+		set to "p" or "div" tags. The "br" configuration should not make changes instead.
+		<p id="_P2">
+			In the test we will try to recreate this document using the editor tools. To make
+			sure tables can be inserted <em id="_Em">properly</em> we re-visit banana import
+			statistics from 1998.
+		</p>
+		<p id="_P3">
+			This paragraph has and image at the very end of its contents.<img id="_Img" src="img.gif"
+				alt="" />
+		</p>
+		This text has no block tag.<br />It should be corrected when working with the enter key
+		set to "p" or "div" tags. The <strong id="_StrongNoPara">"br" configuration</strong>
+		should not make changes instead.<br />It has three lines separated by BR tags.
+		<p>
+			In the test we will try to recreate this document using the editor tools. To make
+			sure tables can be inserted <em>properly</em> we re-visit banana import statistics
+			from 1998.
+		</p>
+		<table summary="Sweden was the top importing country by far in 1998.">
+			<caption>
+				Top banana importers 1998 (value of banana imports in millions of US dollars per
+				million people)<br />
+				<br />
+			</caption>
+			<tr>
+				<th scope="col">
+					Country</th>
+				<th scope="col">
+					Millions of US dollars per million people</th>
+			</tr>
+			<tr>
+				<td>
+					Sweden</td>
+				<td>
+					17.12</td>
+			</tr>
+			<tr>
+				<td>
+					United&nbsp;Kingdom</td>
+				<td>
+					8.88</td>
+			</tr>
+			<tr>
+				<td>
+					Germany</td>
+				<td>
+					8.36</td>
+			</tr>
+			<tr>
+				<td>
+					Italy</td>
+				<td>
+					5.96</td>
+			</tr>
+			<tr>
+				<td>
+					United States</td>
+				<td>
+					4.78</td>
+			</tr>
+		</table>
+		<p>
+			For block quotes we will have a look at <a href="http://fawny.org/rhcp.html">what Joe
+				Clark says about redheads</a>:</p>
+		<blockquote cite="http://fawny.org/rhcp.html#me">
+			<p>
+				"Since boyhood I&rsquo;ve always believed, at the deepest level, that redheads are
+				standard-bearers of the grandest and most wondrous human beauty."</p>
+		</blockquote>
+		<p>
+			<img src="img.gif" alt="" /></p>
+		<p>
+			The above is the FCKeditor logo loaded from the FCKeditor.net web site.</p>
+		<p><b id="_B1">Line 1<br />Line 2<br /><i id="_I1">Line 3</i></b></p>
+		<p id="_EnlargeP"> Test <b id="_EnlargeB"> <i id="_EnlargeI">  Enlarge</i> this</b>   </p>
+		<p id="_EnlargeP1"> Test<b id="_EnlargeB1"> <i id="_EnlargeI1">  Enlarge</i> this</b>   </p>
+		<p id="_EnlargeP2"> <b id="_EnlargeB2"> <i id="_EnlargeI2">  Enlarge</i> this</b>   </p>
+		<p id="_EnlargeP3">Test<i id="_EnlargeI3"> Enlarge</i></p>
+		<p id="_EnlargeP4">Test <i id="_EnlargeI4"> Enlarge</i></p>
+		<p id="_EnlargeP5">Test <i id="_EnlargeI5">Enlarge</i></p>
+		<p id="_EnlargeP6">Test <i id="_EnlargeI6"><b></b>Enlarge</i></p>
+	</div>
+	<script type="text/javascript">
+	//<![CDATA[
+
+html1 = document.getElementById( 'playground' ).innerHTML;
+html2 = document.getElementById( 'playground2' ).innerHTML;
+
+	//]]>
+	</script>
+</body>
+</html>
Index: /CKEditor/trunk/_source/tests/core/dom/text.html
===================================================================
--- /CKEditor/trunk/_source/tests/core/dom/text.html	(revision 2962)
+++ /CKEditor/trunk/_source/tests/core/dom/text.html	(revision 2962)
@@ -0,0 +1,69 @@
+<!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.dom.text</title>
+	<link rel="stylesheet" type="text/css" href="../../test.css" />
+	<script type="text/javascript" src="../../../../ckeditor_source.js"></script>
+	<script type="text/javascript" src="../../test.js"></script>
+	<script type="text/javascript">
+	//<![CDATA[
+
+CKEDITOR.test.addTestCase( (function()
+{
+	// Local reference to the "assert" object.
+	var assert = CKEDITOR.test.assert;
+
+	return {
+		test_substring1 : function()
+		{
+			var text = new CKEDITOR.dom.text( '0123456789' );
+
+			assert.areSame( '123', text.substring( 1, 4 ) );
+		},
+
+		test_substring2 : function()
+		{
+			var text = new CKEDITOR.dom.text( '0123456789' );
+
+			assert.areSame( '56789', text.substring( 5 ) );
+		},
+
+		test_substring3 : function()
+		{
+			var text = new CKEDITOR.dom.text( '0123456789' );
+
+			assert.areSame( '', text.substring( 1,1 ) );
+		},
+
+		test_substring4 : function()
+		{
+			var text = new CKEDITOR.dom.text( '0123456789' );
+
+			assert.areSame( '012', text.substring( -10,3 ) );
+		},
+
+		test_substring5 : function()
+		{
+			var text = new CKEDITOR.dom.text( '0123456789' );
+
+			assert.areSame( '89', text.substring( 8,100 ) );
+		},
+
+		test_substring6 : function()
+		{
+			var text = new CKEDITOR.dom.text( '0123456789' );
+
+			assert.areSame( '234', text.substring( 5,2 ) );
+		},
+
+		name : document.title
+	};
+})() );
+
+	//]]>
+	</script>
+</head>
+<body>
+	<p>0123456789</p>
+</body>
+</html>
Index: /CKEditor/trunk/_source/tests/core/dom/window.html
===================================================================
--- /CKEditor/trunk/_source/tests/core/dom/window.html	(revision 2962)
+++ /CKEditor/trunk/_source/tests/core/dom/window.html	(revision 2962)
@@ -0,0 +1,53 @@
+﻿<!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.dom.window</title>
+	<link rel="stylesheet" type="text/css" href="../../test.css" />
+	<script type="text/javascript" src="../../../../ckeditor_source.js"></script>
+	<script type="text/javascript" src="../../test.js"></script>
+	<script type="text/javascript">
+	//<![CDATA[
+
+var loadCalled;
+
+var testWindow = new CKEDITOR.dom.window( window );
+
+var t;
+
+testWindow.on( 'load', function()
+	{
+		t = document.createElement( 'textarea' );
+		t.id = 'fred';
+
+		document.body.appendChild( t );
+
+		loadCalled = true;
+	});
+
+testWindow.on( 'beforeunload', function()
+	{
+		t.value = new Date();
+	});
+
+CKEDITOR.test.addTestCase( (function()
+{
+	// Local reference to the "assert" object.
+	var assert = CKEDITOR.test.assert;
+
+	return {
+		test_loadEvent : function()
+		{
+			assert.isTrue( loadCalled );
+		},
+
+		name : document.title
+	};
+})() );
+
+	//]]>
+	</script>
+</head>
+<body>
+	<div id="test1"></div>
+</body>
+</html>
Index: /CKEditor/trunk/_source/tests/core/editor.html
===================================================================
--- /CKEditor/trunk/_source/tests/core/editor.html	(revision 2962)
+++ /CKEditor/trunk/_source/tests/core/editor.html	(revision 2962)
@@ -0,0 +1,103 @@
+<!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.editor</title>
+	<link rel="stylesheet" type="text/css" href="../test.css" />
+	<script type="text/javascript" src="../../../ckeditor_source.js"></script>
+	<script type="text/javascript" src="../test.js"></script>
+	<script type="text/javascript">
+	//<![CDATA[
+
+CKEDITOR.test.addTestCase( (function()
+{
+	// Local reference to the "assert" object.
+	var assert = CKEDITOR.test.assert;
+
+	return {
+		test_name : function()
+		{
+			assert.areSame( 'editor1', CKEDITOR.instances.editor1.name );
+		},
+
+		test_element : function()
+		{
+			assert.areSame( document.getElementById( 'editor1' ), CKEDITOR.instances.editor1.element.$ );
+		},
+
+		test_config : function()
+		{
+			// The instance default config must match the CKEDITOR.config.
+
+			var config = CKEDITOR.instances.editor1.config;
+
+			for ( var prop in CKEDITOR.config )
+				assert.areSame( CKEDITOR.config[ prop ], config[ prop ], '"' + prop + '" doesn\'t match' );
+		},
+
+		test_config_inpage : function()
+		{
+			// Pass in-page settings to the instance.
+			CKEDITOR.replace( 'editor2', { test1 : 'ball', baseHref : 'test' } );
+
+			var config = CKEDITOR.instances.editor2.config;
+
+			assert.areSame( 'ball', config.test1, '"test1" doesn\'t match' );
+			assert.areSame( 'test', config.baseHref, '"baseHref" doesn\'t match' );
+
+			// All other settings must match CKEDITOR.config.
+			for ( var prop in CKEDITOR.config )
+			{
+				if ( prop != 'test1' && prop != 'baseHref' )
+					assert.areSame( CKEDITOR.config[ prop ], config[ prop ], '"' + prop + '" doesn\'t match' );
+			}
+		},
+
+		test_config_customConfig : function()
+		{
+			var testCase = this;
+
+			CKEDITOR.on( 'instanceCreated', function( event )
+				{
+					if ( event.editor.name == 'editor3' )
+					{
+						event.editor.on( 'configLoaded', function()
+							{
+								testCase.resume( function()
+								{
+									var config = event.editor.config;
+
+									assert.areSame( 'Ok', config.test_custom1, '"test_custom1" doesn\'t match' );
+									assert.areSame( 'Ok', config.test_custom2, '"test_custom1" doesn\'t match' );
+									assert.areSame( 'ball', config.test1, '"test1" doesn\'t match' );
+									assert.areSame( 'test', config.baseHref, '"baseHref" doesn\'t match' );
+
+									// All other settings must match CKEDITOR.config.
+									for ( var prop in CKEDITOR.config )
+									{
+										if ( prop != 'customConfig' && prop != 'test_custom1' && prop != 'test_custom2' && prop != 'test1' && prop != 'baseHref' )
+											assert.areSame( CKEDITOR.config[ prop ], config[ prop ], '"' + prop + '" doesn\'t match' );
+									}
+								});
+							});
+					}
+				});
+
+			// Pass in-page settings to the instance.
+			CKEDITOR.replace( 'editor3', { customConfig : '_editor/custom_config_1.js', test1 : 'ball', baseHref : 'test' } );
+
+			this.wait();
+		},
+
+		name : document.title
+	};
+})() );
+
+	//]]>
+	</script>
+</head>
+<body>
+	<textarea id="editor1" class="ckeditor" cols="80" rows="10"></textarea>
+	<textarea id="editor2" cols="80" rows="10"></textarea>
+	<textarea id="editor3" cols="80" rows="10"></textarea>
+</body>
+</html>
Index: /CKEditor/trunk/_source/tests/core/env.html
===================================================================
--- /CKEditor/trunk/_source/tests/core/env.html	(revision 2962)
+++ /CKEditor/trunk/_source/tests/core/env.html	(revision 2962)
@@ -0,0 +1,46 @@
+<!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.env</title>
+	<link rel="stylesheet" type="text/css" href="../test.css" />
+	<script type="text/javascript" src="../../../ckeditor_source.js"></script>
+	<script type="text/javascript" src="../test.js"></script>
+	<script type="text/javascript">
+	//<![CDATA[
+
+CKEDITOR.test.addTestCase( (function()
+{
+	// Local reference to the "assert" object.
+	var assert = CKEDITOR.test.assert;
+
+	return {
+		test_ie : function()
+		{
+			if ( window.ActiveXObject )
+			{
+				assert.isTrue( CKEDITOR.env.ie		, 'ie should be true' );
+				assert.isFalse( CKEDITOR.env.opera	, 'opera should be false' );
+				assert.isFalse( CKEDITOR.env.webkit	, 'webkit should be false' );
+				assert.isFalse( CKEDITOR.env.air	, 'air should be false' );
+				assert.isFalse( CKEDITOR.env.gecko	, 'gecko should be false' );
+				assert.isFalse( CKEDITOR.env.mac	, 'ismac should be false' );
+			}
+			else
+				assert.isFalse( CKEDITOR.env.ie );
+		},
+
+		test_isCompatible : function()
+		{
+			assert.isTrue( CKEDITOR.env.isCompatible );
+		},
+
+		name : document.title
+	};
+})() );
+
+	//]]>
+	</script>
+</head>
+<body>
+</body>
+</html>
Index: /CKEditor/trunk/_source/tests/core/event.html
===================================================================
--- /CKEditor/trunk/_source/tests/core/event.html	(revision 2962)
+++ /CKEditor/trunk/_source/tests/core/event.html	(revision 2962)
@@ -0,0 +1,459 @@
+<!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.event</title>
+	<link rel="stylesheet" type="text/css" href="../test.css" />
+	<script type="text/javascript" src="../../../ckeditor_source.js"></script>
+	<script type="text/javascript" src="../test.js"></script>
+	<script type="text/javascript">
+	//<![CDATA[
+
+CKEDITOR.test.addTestCase( (function()
+{
+	// Local reference to the "assert" object.
+	var assert = CKEDITOR.test.assert;
+
+	return {
+		test_inherit : function()
+		{
+			// Create a testClass that inherits from CKEDITOR.event.
+			var testClass = function()
+			{
+				CKEDITOR.event.call( this );
+			};
+			testClass.prototype = CKEDITOR.event.prototype;
+
+			var calls = [];
+
+			var testInstance = new testClass();
+
+			testInstance.on( 'someEvent', function( ev )
+				{
+					assert.areSame( testInstance, this, 'Scope 1 is not valid' );
+
+					assert.areSame( 'someEvent', ev.name, 'ev.name (1) is wrong' );
+					assert.areSame( testInstance, ev.sender, 'ev.sender (1) is wrong' );
+					assert.isUndefined( ev.editor, 'ev.editor (1) is wrong' );
+					assert.isUndefined( ev.data, 'ev.data (1) is wrong' );
+					assert.isUndefined( ev.listenerData, 'ev.listenerData (1) is wrong' );
+
+					calls.push( 'a' );
+				} );
+
+			testInstance.on( 'someEvent', function( ev )
+				{
+					assert.areSame( testInstance, this, 'Scope 2 is not valid' );
+
+					assert.areSame( 'someEvent', ev.name, 'ev.name (2) is wrong' );
+					assert.areSame( testInstance, ev.sender, 'ev.sender (2) is wrong' );
+					assert.isUndefined( ev.editor, 'ev.editor (2) is wrong' );
+					assert.isUndefined( ev.data, 'ev.data (2) is wrong' );
+					assert.isUndefined( ev.listenerData, 'ev.listenerData (2) is wrong' );
+
+					calls.push( 'b' );
+				} );
+
+			assert.areSame( false, testInstance.fire( 'someEvent' ) );
+
+			assert.areSame( 2, calls.length, 'number of calls doesn\'t match' );
+			assert.areSame( 'a,b', calls.toString() );
+		},
+
+		test_implementOn : function()
+		{
+			// Create a testObject and implement CKEDITOR.event on it.
+			var testObject = { someprop : 'Test' };
+			CKEDITOR.event.implementOn( testObject );
+
+			assert.areSame( 'Test', testObject.someprop );
+
+			var calls = [];
+
+			testObject.on( 'someEvent', function( ev )
+				{
+					assert.areSame( testObject, this, 'Scope 1 is not valid' );
+
+					assert.areSame( 'someEvent', ev.name, 'ev.name (1) is wrong' );
+					assert.areSame( testObject, ev.sender, 'ev.sender (1) is wrong' );
+					assert.isUndefined( ev.editor, 'ev.editor (1) is wrong' );
+					assert.isUndefined( ev.data, 'ev.data (1) is wrong' );
+					assert.isUndefined( ev.listenerData, 'ev.listenerData (1) is wrong' );
+
+					calls.push( 'a' );
+				} );
+
+			testObject.on( 'someEvent', function( ev )
+				{
+					assert.areSame( testObject, this, 'Scope 2 is not valid' );
+
+					assert.areSame( 'someEvent', ev.name, 'ev.name (2) is wrong' );
+					assert.areSame( testObject, ev.sender, 'ev.sender (2) is wrong' );
+					assert.isUndefined( ev.editor, 'ev.editor (2) is wrong' );
+					assert.isUndefined( ev.data, 'ev.data (2) is wrong' );
+					assert.isUndefined( ev.listenerData, 'ev.listenerData (2) is wrong' );
+
+					calls.push( 'b' );
+				} );
+
+			assert.areSame( false, testObject.fire( 'someEvent' ) );
+
+			assert.areSame( 2, calls.length, 'number of calls doesn\'t match' );
+			assert.areSame( 'a,b', calls.toString() );
+		},
+
+		test_eventNameCase : function()
+		{
+			// Create a testObject and implement CKEDITOR.event on it.
+			var testObject = {};
+			CKEDITOR.event.implementOn( testObject );
+
+			var counter = 0;
+
+			// Event Names are case sensitive.
+
+			testObject.on( 'someEvent', function( ev )
+				{
+					assert.areSame( 'someEvent', ev.name, 'ev.name (someEvent) is wrong' );
+					counter++;
+				} );
+
+			testObject.on( 'SomeEvent', function( ev )
+				{
+					assert.areSame( 'SomeEvent', ev.name, 'ev.name (SomeEvent) is wrong' );
+					counter++;
+				} );
+
+			testObject.fire( 'someEvent' );
+			assert.areSame( 1, counter, '"someEvent" calls doesn\'t match' );
+
+			counter = 0;
+
+			testObject.fire( 'SomeEvent' );
+			assert.areSame( 1, counter, '"SomeEvent" calls doesn\'t match' );
+		},
+
+		test_scope : function()
+		{
+			// Create a testObject and implement CKEDITOR.event on it.
+			var testObject = {};
+			CKEDITOR.event.implementOn( testObject );
+
+			// Counter used just to check that the calls are effectively done.
+			var counter = 0;
+
+			var testScope = {};
+
+			testObject.on( 'someEvent', function( ev )
+				{
+					assert.areSame( testObject, this, 'scope (testObject) is wrong' );
+					assert.areSame( testObject, ev.sender, 'sender (testObject) is wrong' );
+					counter++;
+				} );
+
+			testObject.on( 'someEvent', function( ev )
+				{
+					assert.areSame( testScope, this, 'scope (testScope) is wrong' );
+					assert.areSame( testObject, ev.sender, 'sender (testScope) is wrong' );
+					counter++;
+				}, testScope );
+
+			testObject.fire( 'someEvent' );
+
+			assert.areSame( 2, counter, 'wrong number of calls' );
+		},
+
+		test_listenerData : function()
+		{
+			// Create a testObject and implement CKEDITOR.event on it.
+			var testObject = {};
+			CKEDITOR.event.implementOn( testObject );
+
+			// Counter used just to check that the calls are effectively done.
+			var counter = 0;
+
+			testObject.on( 'someEvent', function( ev )
+				{
+					assert.areSame( 'Test1', ev.listenerData, 'listenerData (1) is wrong' );
+					counter++;
+				}, null, 'Test1'  );
+
+			testObject.on( 'someEvent', function( ev )
+				{
+					assert.areSame( 'Test2', ev.listenerData, 'listenerData (2) is wrong' );
+					counter++;
+				}, null, 'Test2' );
+
+			testObject.fire( 'someEvent' );
+
+			assert.areSame( 2, counter, 'wrong number of calls' );
+		},
+
+		test_data : function()
+		{
+			// Create a testObject and implement CKEDITOR.event on it.
+			var testObject = {};
+			CKEDITOR.event.implementOn( testObject );
+
+			// Counter used just to check that the calls are effectively done.
+			var counter = 0;
+
+			testObject.on( 'someEvent', function( ev )
+				{
+					assert.areSame( 'Test data', ev.data, 'data (1) is wrong' );
+					counter++;
+				} );
+
+			testObject.on( 'someEvent', function( ev )
+				{
+					assert.areSame( 'Test data', ev.data, 'data (2) is wrong' );
+					counter++;
+				} );
+
+			testObject.fire( 'someEvent', 'Test data' );
+
+			assert.areSame( 2, counter, 'wrong number of calls' );
+		},
+
+		test_editor : function()
+		{
+			// Create a testObject and implement CKEDITOR.event on it.
+			var testObject = {};
+			CKEDITOR.event.implementOn( testObject );
+
+			// Counter used just to check that the calls are effectively done.
+			var counter = 0;
+
+			var editor = {};
+
+			testObject.on( 'someEvent', function( ev )
+				{
+					assert.areSame( editor, ev.editor, 'editor is wrong' );
+					counter++;
+				} );
+
+			testObject.fire( 'someEvent', null, editor );
+
+			assert.areSame( 1, counter, 'wrong number of calls' );
+		},
+
+		test_stop : function()
+		{
+			// Create a testObject and implement CKEDITOR.event on it.
+			var testObject = {};
+			CKEDITOR.event.implementOn( testObject );
+
+			var counter = 0;
+
+			testObject.on( 'someEvent', function( ev )
+				{
+					ev.stop();
+					counter++;
+				} );
+
+			testObject.on( 'someEvent', function( ev )
+				{
+					counter++;
+				} );
+
+			assert.areSame( false, testObject.fire( 'someEvent' ), 'fire must return "false"' );
+			assert.areSame( 1, counter, 'number of calls doesn\'t match' );
+		},
+
+		test_cancel : function()
+		{
+			// Create a testObject and implement CKEDITOR.event on it.
+			var testObject = {};
+			CKEDITOR.event.implementOn( testObject );
+
+			var counter = 0;
+
+			testObject.on( 'someEvent', function( ev )
+				{
+					ev.cancel();
+					counter++;
+				} );
+
+			testObject.on( 'someEvent', function( ev )
+				{
+					counter++;
+				} );
+
+			assert.areSame( true, testObject.fire( 'someEvent' ), 'fire must return "true"' );
+			assert.areSame( 1, counter, 'number of calls doesn\'t match' );
+		},
+
+		test_dataManipulation : function()
+		{
+			// Create a testObject and implement CKEDITOR.event on it.
+			var testObject = {};
+			CKEDITOR.event.implementOn( testObject );
+
+			var counter = 0;
+
+			testObject.on( 'someEvent', function( ev )
+				{
+					assert.areSame( 'Test1', ev.data );
+					ev.data = 'Test2';
+					counter++;
+				} );
+
+			testObject.on( 'someEvent', function( ev )
+				{
+					assert.areSame( 'Test2', ev.data );
+					ev.data = 'Test3';
+					counter++;
+				} );
+
+			testObject.on( 'someEvent', function( ev )
+				{
+					assert.areSame( 'Test3', ev.data );
+					ev.data = 'Test4';
+					counter++;
+				} );
+
+			assert.areSame( 'Test4', testObject.fire( 'someEvent', 'Test1' ), 'fire must return "Test4"' );
+			assert.areSame( 3, counter, 'number of calls doesn\'t match' );
+		},
+
+		test_priority : function()
+		{
+			// Create a testObject and implement CKEDITOR.event on it.
+			var testObject = {};
+			CKEDITOR.event.implementOn( testObject );
+
+			var calls = [];
+
+			testObject.on( 'someEvent', function( ev )
+				{
+					calls.push( 'e' );
+				}, null, null, 11 );
+
+			testObject.on( 'someEvent', function( ev )
+				{
+					calls.push( 'c' );
+				} );
+
+			testObject.on( 'someEvent', function( ev )
+				{
+					calls.push( 'a' );
+				}, null, null, 9 );
+
+			testObject.on( 'someEvent', function( ev )
+				{
+					calls.push( 'f' );
+				}, null, null, 11 );
+
+			testObject.on( 'someEvent', function( ev )
+				{
+					calls.push( 'd' );
+				} );
+
+			testObject.on( 'someEvent', function( ev )
+				{
+					calls.push( 'b' );
+				}, null, null, 9 );
+
+			testObject.fire( 'someEvent', 'Test data' );
+			assert.areSame( 'a,b,c,d,e,f', calls.toString() );
+		},
+
+		test_removeListener : function()
+		{
+			// Create a testObject and implement CKEDITOR.event on it.
+			var testObject = {};
+			CKEDITOR.event.implementOn( testObject );
+
+			var calls = [];
+
+			var listener = function( ev )
+				{
+					calls.push( 'a' );
+				};
+
+			testObject.on( 'someEvent', listener );
+
+			testObject.on( 'someEvent', function( ev )
+				{
+					calls.push( 'b' );
+				} );
+
+			testObject.fire( 'someEvent', 'Test data' );
+			assert.areSame( 'a,b', calls.toString() );
+
+			testObject.removeListener( 'someEvent', listener );
+
+			calls = [];
+
+			testObject.fire( 'someEvent', 'Test data' );
+			assert.areSame( 'b', calls.toString() );
+		},
+
+		test_fireOnce : function()
+		{
+			// Create a testObject and implement CKEDITOR.event on it.
+			var testObject = {};
+			CKEDITOR.event.implementOn( testObject );
+
+			var counter = 0;
+
+			testObject.on( 'someEvent', function( ev )
+				{
+					counter++;
+				} );
+
+			testObject.on( 'someEvent', function( ev )
+				{
+					counter++;
+				} );
+
+			assert.areSame( false, testObject.fireOnce( 'someEvent' ), 'fireOnce must return "false"' );
+			assert.areSame( 2, counter, 'number of calls doesn\'t match' );
+
+			counter = 0;
+
+			assert.areSame( false, testObject.fire( 'someEvent' ), 'fire must return "false"' );
+			assert.areSame( 0, counter, 'number of calls doesn\'t match' );
+		},
+
+		test_nestedCancel : function()
+		{
+			// Create a testObject and implement CKEDITOR.event on it.
+			var testObject = {};
+			CKEDITOR.event.implementOn( testObject );
+
+			var isCanceledA,
+				isCanceledB,
+				isCanceledC;
+
+			testObject.on( 'A', function( ev )
+				{
+					isCanceledB = testObject.fire( 'B' );
+					isCanceledC = testObject.fire( 'C' );
+				});
+
+			testObject.on( 'B', function( ev )
+				{
+					ev.cancel();
+				});
+
+			testObject.on( 'C', function( ev )
+				{
+				});
+
+			isCanceledA = testObject.fire( 'A' );
+
+			assert.areSame( false, isCanceledA, 'event A must not be canceled' );
+			assert.areSame( true, isCanceledB, 'event B must be canceled' );
+			assert.areSame( false, isCanceledC, 'event C must not be canceled' );
+		},
+
+		name : document.title
+	};
+})() );
+
+	//]]>
+	</script>
+</head>
+<body>
+</body>
+</html>
Index: /CKEditor/trunk/_source/tests/core/htmlparser/fragment.html
===================================================================
--- /CKEditor/trunk/_source/tests/core/htmlparser/fragment.html	(revision 2962)
+++ /CKEditor/trunk/_source/tests/core/htmlparser/fragment.html	(revision 2962)
@@ -0,0 +1,35 @@
+<!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.fragment</title>
+	<link rel="stylesheet" type="text/css" href="../../test.css" />
+	<script type="text/javascript" src="../../../../ckeditor_source.js"></script>
+	<script type="text/javascript" src="../../test.js"></script>
+	<script type="text/javascript">
+	//<![CDATA[
+
+CKEDITOR.test.addTestCase( (function()
+{
+	// Local reference to the "assert" object.
+	var assert = CKEDITOR.test.assert;
+
+	return {
+		test_fromHtml_1 : function()
+		{
+			var fragment = CKEDITOR.htmlParser.fragment.fromHtml( '<p>Test</p>' );
+
+			assert.areSame( 1, fragment.children.length, 'Wrong size' );
+			assert.areSame( CKEDITOR.NODE_ELEMENT, fragment.children[0].type, 'Wrong child type' );
+			assert.areSame( 'p', fragment.children[0].name, 'Wrong child name' );
+		},
+
+		name : document.title
+	};
+})() );
+
+	//]]>
+	</script>
+</head>
+<body>
+</body>
+</html>
Index: /CKEditor/trunk/_source/tests/core/scriptloader.html
===================================================================
--- /CKEditor/trunk/_source/tests/core/scriptloader.html	(revision 2962)
+++ /CKEditor/trunk/_source/tests/core/scriptloader.html	(revision 2962)
@@ -0,0 +1,52 @@
+﻿<!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.scriptLoader</title>
+	<link rel="stylesheet" type="text/css" href="../test.css" />
+	<script type="text/javascript" src="../../../ckeditor_source.js"></script>
+	<script type="text/javascript" src="../test.js"></script>
+	<script type="text/javascript">
+	//<![CDATA[
+
+CKEDITOR.test.addTestCase( (function()
+{
+	// Local reference to the "assert" object.
+	var assert = CKEDITOR.test.assert;
+
+	return {
+		test_loadCode : function()
+		{
+			CKEDITOR.scriptLoader.loadCode( 'var test="Testing!";' );
+
+			/*jsl:ignore*/
+			assert.areEqual( 'Testing!', test );
+			/*jsl:end*/
+		},
+
+		test_load : function()
+		{
+			var testCase = this;
+			var callback = function( data )
+			{
+				testCase.resume( function()
+					{
+						/*jsl:ignore*/
+						assert.areSame( 'Test!', testVar );
+						/*jsl:end*/
+					} );
+			};
+
+			CKEDITOR.scriptLoader.load( '../_assets/sample.js', callback );
+			this.wait();
+		},
+
+		name : document.title
+	};
+})() );
+
+	//]]>
+	</script>
+</head>
+<body>
+</body>
+</html>
Index: /CKEditor/trunk/_source/tests/core/tools.html
===================================================================
--- /CKEditor/trunk/_source/tests/core/tools.html	(revision 2962)
+++ /CKEditor/trunk/_source/tests/core/tools.html	(revision 2962)
@@ -0,0 +1,136 @@
+<!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.tools</title>
+	<link rel="stylesheet" type="text/css" href="../test.css" />
+	<script type="text/javascript" src="../../../ckeditor_source.js"></script>
+	<script type="text/javascript" src="../test.js"></script>
+	<script type="text/javascript">
+	//<![CDATA[
+
+CKEDITOR.test.addTestCase( (function()
+{
+	// Local reference to the "assert" object.
+	var assert = CKEDITOR.test.assert;
+
+	return {
+		test_extend : function()
+		{
+			var fakeFn = function() {};
+			var fakeObj = { fake1 : 1, fake2 : 2 };
+			var fakeArray = [ 'Test', 10, fakeFn, fakeObj ];
+
+			var target =
+			{
+				prop1 : 'Test',
+				prop2 : 10,
+				prop3 : fakeFn,
+				prop4 : fakeObj,
+				prop5 : fakeArray
+			};
+
+			CKEDITOR.tools.extend( target,
+				{
+					prop3 : 'Wrong',
+					prop6 : 'Good',
+					prop7 : fakeArray
+				} );
+
+			assert.areSame( 'Test'		, target.prop1, 'prop1 doesn\'t match' );
+			assert.areSame( 10			, target.prop2, 'prop2 doesn\'t match' );
+			assert.areSame( fakeFn		, target.prop3, 'prop3 doesn\'t match' );
+			assert.areSame( fakeObj		, target.prop4, 'prop4 doesn\'t match' );
+			assert.areSame( fakeArray	, target.prop5, 'prop5 doesn\'t match' );
+			assert.areSame( 'Good'		, target.prop6, 'prop6 doesn\'t match' );
+			assert.areSame( fakeArray	, target.prop7, 'prop7 doesn\'t match' );
+		},
+
+		test_isArray1 : function()
+		{
+			assert.isTrue( CKEDITOR.tools.isArray( [] ) );
+		},
+
+		test_isArray2 : function()
+		{
+			assert.isFalse( CKEDITOR.tools.isArray( { length:1 } ) );
+		},
+
+		test_isArray3 : function()
+		{
+			assert.isFalse( CKEDITOR.tools.isArray( null ) );
+		},
+
+		test_isArray4 : function()
+		{
+			assert.isFalse( CKEDITOR.tools.isArray( window.x ) );
+		},
+
+		test_htmlEncode1 : function()
+		{
+			assert.areSame( '&lt;b&gt;Test&lt;/b&gt;', CKEDITOR.tools.htmlEncode( '<b>Test</b>' ) );
+		},
+
+		test_htmlEncode2 : function()
+		{
+			assert.areSame( 'Test\'s &amp; "quote"', CKEDITOR.tools.htmlEncode( 'Test\'s & "quote"' ) );
+		},
+
+		test_cssStyleToDomStyle1 : function()
+		{
+			assert.areSame( 'backgroundColor', CKEDITOR.tools.cssStyleToDomStyle( 'background-color' ) );
+		},
+
+		test_cssStyleToDomStyle2 : function()
+		{
+			assert.areSame( 'cssFloat', CKEDITOR.tools.cssStyleToDomStyle( 'float' ) );
+		},
+
+		test_getNextNumber : function()
+		{
+			var number = CKEDITOR.tools.getNextNumber();
+			assert.areSame( number +  1, CKEDITOR.tools.getNextNumber() );
+			assert.areSame( number +  2, CKEDITOR.tools.getNextNumber() );
+			assert.areSame( number +  3, CKEDITOR.tools.getNextNumber() );
+		},
+
+		test_trim1 : function()
+		{
+			assert.areSame( 'test', CKEDITOR.tools.trim( '    test   ' ) );
+		},
+
+		test_trim2 : function()
+		{
+			assert.areSame( 'test', CKEDITOR.tools.trim( ' \n \t  test\n  \t ' ) );
+		},
+
+		test_ltrim1 : function()
+		{
+			assert.areSame( 'test   ', CKEDITOR.tools.ltrim( '    test   ' ) );
+		},
+
+		test_ltrim2 : function()
+		{
+			assert.areSame( 'test\n  \t ', CKEDITOR.tools.ltrim( ' \n \t  test\n  \t ' ) );
+		},
+
+		test_rtrim1 : function()
+		{
+			assert.areSame( '    test', CKEDITOR.tools.rtrim( '    test   ' ) );
+		},
+
+		test_rtrim2 : function()
+		{
+			assert.areSame( ' \n \t  test', CKEDITOR.tools.rtrim( ' \n \t  test\n  \t ' ) );
+		},
+
+		name : document.title
+	};
+})() );
+
+	//]]>
+	</script>
+</head>
+<body>
+	<iframe></iframe>
+</body>
+</html>
Index: /CKEditor/trunk/_source/tests/core/xml.html
===================================================================
--- /CKEditor/trunk/_source/tests/core/xml.html	(revision 2962)
+++ /CKEditor/trunk/_source/tests/core/xml.html	(revision 2962)
@@ -0,0 +1,142 @@
+<!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.xml</title>
+	<link rel="stylesheet" type="text/css" href="../test.css" />
+	<script type="text/javascript" src="../../../ckeditor_source.js"></script>
+	<script type="text/javascript" src="../test.js"></script>
+	<script type="text/javascript">
+	//<![CDATA[
+
+CKEDITOR.test.addTestCase( (function()
+{
+	// Local reference to the "assert" object.
+	var assert = CKEDITOR.test.assert;
+
+	return {
+		test_baseXml : function()
+		{
+			var xml = new CKEDITOR.xml( '<data />' );
+			assert.isObject( xml.baseXml );
+		},
+
+		test_selectSingleNode1a : function()
+		{
+			var xml = new CKEDITOR.xml( '<data><item /></data>' );
+			var node = xml.selectSingleNode( 'data/item' );
+			assert.areEqual( 'item', node.nodeName );
+		},
+
+		test_selectSingleNode1b : function()
+		{
+			var xml = new CKEDITOR.xml( '<data><item /></data>' );
+			var node = xml.selectSingleNode( 'item' );
+			assert.isNull( node );
+		},
+
+		test_selectSingleNode2a : function()
+		{
+			var xml = new CKEDITOR.xml( '<data><item><subitem/></item></data>' );
+			var contextNode = xml.selectSingleNode( 'data' );
+			var node = xml.selectSingleNode( 'item/subitem', contextNode );
+			assert.areEqual( 'subitem', node.nodeName );
+		},
+
+		test_selectSingleNode2b : function()
+		{
+			var xml = new CKEDITOR.xml( '<data><item><subitem/></item></data>' );
+			var contextNode = xml.selectSingleNode( 'data' );
+			var node = xml.selectSingleNode( 'subitem', contextNode );
+			assert.isNull( node );
+		},
+
+		test_selectSingleNode3 : function()
+		{
+			var xml = new CKEDITOR.xml( '<data><item id="x1"/><item id="x2"/></data>' );
+			var node = xml.selectSingleNode( '//item[@id="x2"]' );
+			assert.areEqual( 'item', node.nodeName );
+			assert.areEqual( 'x2', node.getAttribute( 'id' ) );
+		},
+
+		test_selectSingleNode4 : function()
+		{
+			// For may results, the first one must be returned.
+
+			var xml = new CKEDITOR.xml( '<data><item id="x1"/><item id="x2"/></data>' );
+			var node = xml.selectSingleNode( '//item' );
+			assert.areEqual( 'item', node.nodeName );
+			assert.areEqual( 'x1', node.getAttribute( 'id' ) );
+		},
+
+		test_selectNodes1 : function()
+		{
+			var xml = new CKEDITOR.xml( '<data><item /></data>' );
+			var nodes = xml.selectNodes( 'data/item' );
+			assert.areEqual( 1, nodes.length );
+			assert.areEqual( 'item', nodes[0].nodeName );
+		},
+
+		test_selectNodes2a : function()
+		{
+			var xml = new CKEDITOR.xml( '<data><item id="x1"/><item id="x2"/><item id="x3"/></data>' );
+			var nodes = xml.selectNodes( '//item' );
+			assert.areEqual( 3, nodes.length );
+			assert.areEqual( 'x1', nodes[0].getAttribute( 'id' ) );
+			assert.areEqual( 'x2', nodes[1].getAttribute( 'id' ) );
+			assert.areEqual( 'x3', nodes[2].getAttribute( 'id' ) );
+		},
+
+		test_selectNodes2b : function()
+		{
+			var xml = new CKEDITOR.xml( '<data><item id="x1"/><item id="x2"/><item id="x3"/></data>' );
+			var nodes = xml.selectNodes( '//itemX' );
+			assert.areEqual( 0, nodes.length );
+		},
+
+		test_selectNodes3a : function()
+		{
+			var xml = new CKEDITOR.xml( '<data><item id="x1"/><item id="x2"/><item id="x3"/></data>' );
+			var contextNode = xml.selectSingleNode( 'data' );
+			var nodes = xml.selectNodes( 'item', contextNode );
+			assert.areEqual( 3, nodes.length );
+			assert.areEqual( 'x1', nodes[0].getAttribute( 'id' ) );
+			assert.areEqual( 'x2', nodes[1].getAttribute( 'id' ) );
+			assert.areEqual( 'x3', nodes[2].getAttribute( 'id' ) );
+		},
+
+		test_selectNodes3b : function()
+		{
+			var xml = new CKEDITOR.xml( '<data><item id="x1"/><item id="x2"/><item id="x3"/></data>' );
+			var contextNode = xml.selectSingleNode( 'data' );
+			var nodes = xml.selectNodes( 'itemX', contextNode );
+			assert.areEqual( 0, nodes.length );
+		},
+
+		test_getInnerXml1 : function()
+		{
+			var xml = new CKEDITOR.xml( '<data><item/></data>' );
+			assert.areEqual( '<item/>', xml.getInnerXml( 'data' ) );
+		},
+
+		test_getInnerXml2 : function()
+		{
+			var xml = new CKEDITOR.xml( '<data><item id="x1"><subitem name="sub1"/></item></data>' );
+			assert.areEqual( '<subitem name="sub1"/>', xml.getInnerXml( '//item' ) );
+		},
+
+		test_getInnerXml3 : function()
+		{
+			var xml = new CKEDITOR.xml( '<data><item id="x1"/></data>' );
+			assert.isNull( xml.getInnerXml( '//itemX' ) );
+		},
+
+		name : document.title
+	};
+})() );
+
+	//]]>
+	</script>
+</head>
+<body>
+</body>
+</html>
Index: /CKEditor/trunk/_source/tests/plugins/htmldataprocessor/htmldataprocessor.html
===================================================================
--- /CKEditor/trunk/_source/tests/plugins/htmldataprocessor/htmldataprocessor.html	(revision 2962)
+++ /CKEditor/trunk/_source/tests/plugins/htmldataprocessor/htmldataprocessor.html	(revision 2962)
@@ -0,0 +1,102 @@
+<!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>Plugin: htmldataprocessor</title>
+	<link rel="stylesheet" type="text/css" href="../../test.css" />
+	<script type="text/javascript" src="../../../../ckeditor_source.js"></script>
+	<script type="text/javascript" src="../../test.js"></script>
+	<script type="text/javascript">
+
+CKEDITOR.plugins.load( 'htmldataprocessor' );
+
+	</script>
+	<script type="text/javascript">
+	//<![CDATA[
+
+var testCase;
+
+CKEDITOR.test.addTestCase( testCase = (function()
+{
+	// Local references.
+	var assert = CKEDITOR.test.assert;
+
+	// In these tests, we may "reset" the writer rules to avoid it formatting
+	// the output, making the assertion easier to the done. We don't need to
+	// test formatting features here, so this is ok.
+	var getDataProcessor = function()
+	{
+		var dataProcessor = new CKEDITOR.htmlDataProcessor();
+		dataProcessor.writer._.rules = [];
+		return dataProcessor;
+	};
+
+	// These tests go far beyond the strict htmlDataProcessor code testing. We
+	// are actually testing the entire parsing system here. The combination of
+	// htmlParser and htmlWriter inside htmlDataProcessor is useful in this
+	// sense.
+
+	return {
+		test_toDataFormat_1a : function()
+		{
+			var element = new CKEDITOR.dom.element.createFromHtml( '<div><p>Test</p></div>' );
+
+			assert.areSame( '<p>Test</p>', getDataProcessor().toDataFormat( element ) );
+		},
+
+		test_toDataFormat_1b : function()
+		{
+			var element = new CKEDITOR.dom.element.createFromHtml( '<div><x:x>Test</x:x></div>' );
+
+			// IE adds the XML namespace tag.
+			if ( CKEDITOR.env.ie )
+				assert.areSame( '<?xml:namespace prefix="x" /><x:x>Test</x:x>', getDataProcessor().toDataFormat( element ) );
+			else
+				assert.areSame( '<x:x>Test</x:x>', getDataProcessor().toDataFormat( element ) );
+		},
+
+		test_toDataFormat_2a : function()
+		{
+			var element = new CKEDITOR.dom.element.createFromHtml( '<div><br /><p>Test</p></div>' );
+
+			assert.areSame( '<br /><p>Test</p>', getDataProcessor().toDataFormat( element ) );
+		},
+
+		test_toDataFormat_2b : function()
+		{
+			var element = new CKEDITOR.dom.element.createFromHtml( '<div><x:x></x:x><p>Test</p></div>' );
+
+			// IE adds the XML namespace tag.
+			if ( CKEDITOR.env.ie )
+				assert.areSame( '<?xml:namespace prefix="x" /><x:x></x:x><p>Test</p>', getDataProcessor().toDataFormat( element ) );
+			else
+				assert.areSame( '<x:x></x:x><p>Test</p>', getDataProcessor().toDataFormat( element ) );
+		},
+
+		test_toDataFormat_3 : function()
+		{
+			var element = new CKEDITOR.dom.element.createFromHtml( '<div><x:x><p>Test</p></div>' );
+
+			assert.areSame( '<x:x><p>Test</p></x:x>', getDataProcessor().toDataFormat( element ) );
+		},
+
+		test_toDataFormat_ticket_2774 : function()
+		{
+			var element = new CKEDITOR.dom.element.createFromHtml( '<div><P class=MsoNormal><B><I><SPAN lang=EN-US><o:p>Test</o:p></SPAN></I></B></P></div>' );
+
+			// IE adds the XML namespace tag.
+			if ( CKEDITOR.env.ie )
+				assert.areSame( '<p class="MsoNormal"><b><i><span lang="EN-US"><?xml:namespace prefix="o" /><o:p>Test</o:p></span></i></b></p>', getDataProcessor().toDataFormat( element ) );
+			else
+				assert.areSame( '<p class="MsoNormal"><b><i><span lang="EN-US"><o:p>Test</o:p></span></i></b></p>', getDataProcessor().toDataFormat( element ) );
+		},
+
+		name : document.title
+	};
+})() );
+
+	//]]>
+	</script>
+</head>
+<body>
+</body>
+</html>
Index: /CKEditor/trunk/_source/tests/plugins/styles/styles.html
===================================================================
--- /CKEditor/trunk/_source/tests/plugins/styles/styles.html	(revision 2962)
+++ /CKEditor/trunk/_source/tests/plugins/styles/styles.html	(revision 2962)
@@ -0,0 +1,297 @@
+<!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>Plugin: styles</title>
+	<link rel="stylesheet" type="text/css" href="../../test.css" />
+	<script type="text/javascript" src="../../../../ckeditor_source.js"></script>
+	<script type="text/javascript" src="../../test.js"></script>
+	<script type="text/javascript">
+
+CKEDITOR.plugins.load( 'styles' );
+
+	</script>
+	<script type="text/javascript">
+	//<![CDATA[
+
+var testCase;
+
+CKEDITOR.test.addTestCase( testCase = (function()
+{
+	// Local references.
+	var assert			= CKEDITOR.test.assert;
+	var getInnerHtml	= CKEDITOR.test.getInnerHtml;
+
+	var doc = new CKEDITOR.dom.document( document );
+
+	return {
+		test_inline1 : function()
+		{
+			doc.getById( '_P1' ).setHtml( 'this is some sample text' );
+
+			var range = new CKEDITOR.dom.range( doc );
+			range.setStart( doc.getById( '_P1' ).getFirst(), 5 );
+			range.setEnd( doc.getById( '_P1' ).getFirst(), 7 );
+
+			var style = new CKEDITOR.style( { element : 'b' } );
+			style.applyToRange( range );
+
+			assert.areSame( 'this <b>is</b> some sample text', getInnerHtml( '_P1' ) );
+		},
+
+		test_inline2 : function()
+		{
+			doc.getById( '_P1' ).setHtml( 'this <b>is some </b>sample text' );
+
+			var range = new CKEDITOR.dom.range( doc );
+			range.setStart( doc.getById( '_P1' ).getChild( 1 ), 0 );
+			range.setEnd( doc.getById( '_P1' ), 2 );
+
+			var style = new CKEDITOR.style( { element : 'i' } );
+			style.applyToRange( range );
+
+			assert.areSame( 'this <i><b>is some </b></i>sample text', getInnerHtml( '_P1' ) );
+		},
+
+		test_inline3 : function()
+		{
+			doc.getById( '_P1' ).setHtml( 'this <b>is some </b>sample text' );
+
+			var range = new CKEDITOR.dom.range( doc );
+			range.setStart( doc.getById( '_P1' ).getChild( 1 ), 0 );
+			range.setEnd( doc.getById( '_P1' ).getChild( 1 ).getFirst(), 2 );
+
+			var style = new CKEDITOR.style( { element : 'i' } );
+			style.applyToRange( range );
+
+			assert.areSame( 'this <b><i>is</i> some </b>sample text', getInnerHtml( '_P1' ) );
+		},
+
+		// Inline - Remove inner duplicates.
+		test_inline4 : function()
+		{
+			doc.getById( '_P1' ).setHtml( 'this <b>is some </b>sample text' );
+
+			var range = new CKEDITOR.dom.range( doc );
+			range.setStart( doc.getById( '_P1' ), 0 );
+			range.setEnd( doc.getById( '_P1' ), 3 );
+
+			var style = new CKEDITOR.style( { element : 'b' } );
+			style.applyToRange( range );
+
+			assert.areSame( '<b>this is some sample text</b>', getInnerHtml( '_P1' ) );
+		},
+
+		// Inline - Merge with next.
+		test_inline5 : function()
+		{
+			doc.getById( '_P1' ).setHtml( 'this <b>is some </b>sample text' );
+
+			var range = new CKEDITOR.dom.range( doc );
+			range.setStart( doc.getById( '_P1' ), 0 );
+			range.setEnd( doc.getById( '_P1' ), 1 );
+
+			var style = new CKEDITOR.style( { element : 'b' } );
+			style.applyToRange( range );
+
+			assert.areSame( '<b>this is some </b>sample text', getInnerHtml( '_P1' ) );
+		},
+
+		// Inline - Merge with previous.
+		test_inline6 : function()
+		{
+			doc.getById( '_P1' ).setHtml( 'this <b>is some </b>sample text' );
+
+			var range = new CKEDITOR.dom.range( doc );
+			range.setStart( doc.getById( '_P1' ), 2 );
+			range.setEnd( doc.getById( '_P1' ).getChild( 2 ), 6 );
+
+			var style = new CKEDITOR.style( { element : 'b' } );
+			style.applyToRange( range );
+
+			assert.areSame( 'this <b>is some sample</b> text', getInnerHtml( '_P1' ) );
+		},
+
+		// Inline - Merge several with next.
+		test_inline7 : function()
+		{
+			doc.getById( '_P1' ).setHtml( '<i><u>this </u></i><b><i><u>is</u> some</i> sample</b> text' );
+
+			var range = new CKEDITOR.dom.range( doc );
+			range.setStart( doc.getById( '_P1' ), 0 );
+			range.setEnd( doc.getById( '_P1' ), 1 );
+
+			var style = new CKEDITOR.style( { element : 'b' } );
+			style.applyToRange( range );
+
+			assert.areSame( '<b><i><u>this is</u> some</i> sample</b> text', getInnerHtml( '_P1' ) );
+		},
+
+		// Inline - Merge several with previous.
+		test_inline8 : function()
+		{
+			doc.getById( '_P1' ).setHtml( 'this <b>is <i>some <u>sample</u></i></b><i><u> text</u></i>' );
+
+			var range = new CKEDITOR.dom.range( doc );
+			range.setStart( doc.getById( '_P1' ), 2 );
+			range.setEnd( doc.getById( '_P1' ), 3 );
+
+			var style = new CKEDITOR.style( { element : 'b' } );
+			style.applyToRange( range );
+
+			assert.areSame( 'this <b>is <i>some <u>sample text</u></i></b>', getInnerHtml( '_P1' ) );
+		},
+
+		test_inline9 : function()
+		{
+			doc.getById( '_P1' ).setHtml( 'this <i>is some </i>sample text' );
+
+			var range = new CKEDITOR.dom.range( doc );
+			range.setStart( doc.getById( '_P1' ), 0 );
+			range.setEnd( doc.getById( '_P1' ).getChild( 1 ), 0 );
+
+			var style = new CKEDITOR.style( { element : 'b' } );
+			style.applyToRange( range );
+
+			assert.areSame( '<b>this </b><i>is some </i>sample text', getInnerHtml( '_P1' ) );
+		},
+
+		test_inline10 : function()
+		{
+			doc.getById( '_P1' ).setHtml( 'this is some sample text' );
+
+			var range = new CKEDITOR.dom.range( doc );
+			range.setStart( doc.getById( '_P1' ), 0 );
+			range.setEnd( doc.getById( '_P1' ), 1 );
+
+			var style = new CKEDITOR.style(
+				{
+					element : 'b',
+					attributes :
+						{
+							lang : 'it',
+							title : 'test'
+						},
+					styles :
+						{
+							'font-size' : '10pt',
+							'text-decoration' : 'line-through'
+						}
+				} );
+			style.applyToRange( range );
+
+			assert.areSame( '<b lang="it" style="font-size: 10pt; text-decoration: line-through;" title="test">this is some sample text</b>', getInnerHtml( '_P1' ) );
+		},
+
+		test_inline11 : function()
+		{
+			doc.getById( '_P1' ).setHtml( 'this <b lang="it" class="sample">is</b> <b lang="it" style="font-size: 10pt; text-decoration: line-through;" title="test">some sample</b> <b>t</b>ext' );
+
+			var range = new CKEDITOR.dom.range( doc );
+			range.setStart( doc.getById( '_P1' ), 0 );
+			range.setEnd( doc.getById( '_P1' ), 7 );
+
+			var style = new CKEDITOR.style(
+				{
+					element : 'b',
+					attributes :
+						{
+							lang : 'it',
+							title : 'test'
+						},
+					styles :
+						{
+							'font-size' : '10pt',
+							'text-decoration' : 'line-through'
+						}
+				} );
+			style.applyToRange( range );
+
+			assert.areSame( '<b lang="it" style="font-size: 10pt; text-decoration: line-through;" title="test">this <b class="sample">is</b> some sample text</b>', getInnerHtml( '_P1' ) );
+		},
+
+		test_inline11 : function()
+		{
+			doc.getById( '_P1' ).setHtml( 'this <span class="a">is</span> some <span class="b">sample</span> text' );
+
+			var range = new CKEDITOR.dom.range( doc );
+			range.setStart( doc.getById( '_P1' ), 0 );
+			range.setEnd( doc.getById( '_P1' ), 5 );
+
+			var style = new CKEDITOR.style( { element : 'span', attributes : { 'class' : 'b' } } );
+			style.applyToRange( range );
+
+			assert.areSame( '<span class="b">this <span class="a">is</span> some sample text</span>', getInnerHtml( '_P1' ) );
+		},
+
+		test_inline12 : function()
+		{
+			doc.getById( '_P1' ).setHtml( 'this <span style="font-size:12pt; font-weight:600">is</span> some <span style="font-size:10px;">sample</span> text' );
+
+			var range = new CKEDITOR.dom.range( doc );
+			range.setStart( doc.getById( '_P1' ), 0 );
+			range.setEnd( doc.getById( '_P1' ), 5 );
+
+			var style = new CKEDITOR.style( { element : 'span', styles : { 'font-size' : '1.5em' } } );
+			style.applyToRange( range );
+
+			assert.areSame( '<span style="font-size: 1.5em;">this <span style="font-weight: 600;">is</span> some sample text</span>', getInnerHtml( '_P1' ) );
+		},
+
+		test_inline13 : function()
+		{
+			doc.getById( '_P1' ).setHtml( 'this <b>is some sample</b> text' );
+
+			var range = new CKEDITOR.dom.range( doc );
+			range.setStart( doc.getById( '_P1' ).getChild( 1 ).getFirst(), 3 );
+			range.setEnd( doc.getById( '_P1' ), 3 );
+
+			var style = new CKEDITOR.style( { element : 'i' } );
+			style.applyToRange( range );
+
+			assert.areSame( 'this <b>is <i>some sample</i></b><i> text</i>', getInnerHtml( '_P1' ) );
+		},
+
+		test_inline_nobreak1 : function()
+		{
+			doc.getById( '_P1' ).setHtml( 'this is <a href="http://example.com/">some sample</a> text' );
+
+			var range = new CKEDITOR.dom.range( doc );
+			range.setStart( doc.getById( '_P1' ), 0 );
+			range.setEnd( doc.getById( '_P1' ).getChild( 1 ).getFirst(), 4 );
+
+			var style = new CKEDITOR.style( { element : 'b' } );
+			style.applyToRange( range );
+
+			assert.areSame( '<b>this is </b><a href="http://example.com/"><b>some</b> sample</a> text', getInnerHtml( '_P1' ) );
+		},
+
+		test_ticket_2040 : function()
+		{
+			doc.getById( '_P1' ).setHtml( 'This is some <strong>sample text<\/strong>. You are using <a href="http://www.fckeditor.net/">FCKeditor<\/a>.' );
+
+			var range = new CKEDITOR.dom.range( doc );
+			range.setStart( doc.getById( '_P1' ), 1 );
+			range.setEnd( doc.getById( '_P1' ).getChild( 1 ).getFirst(), 6 );
+
+			var style = new CKEDITOR.style( { element : 'i' } );
+			style.applyToRange( range );
+
+			assert.areSame( 'this is some <strong><i>sample</i> text<\/strong>. you are using <a href="http://www.fckeditor.net/">fckeditor<\/a>.', getInnerHtml( '_P1' ) );
+		},
+
+		name : document.title
+	};
+})() );
+
+//window.onload = function()
+//{
+//	testCase.test_inline4();
+//}
+
+	//]]>
+	</script>
+</head>
+<body>
+	<p id="_P1"></p>
+</body>
+</html>
Index: /CKEditor/trunk/_source/tests/test.css
===================================================================
--- /CKEditor/trunk/_source/tests/test.css	(revision 2962)
+++ /CKEditor/trunk/_source/tests/test.css	(revision 2962)
@@ -0,0 +1,81 @@
+﻿/*
+Copyright (c) 2003-2009, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.html or http://ckeditor.com/license
+*/
+
+body
+{
+	margin:10px;
+}
+
+#testLogger
+{
+	position: absolute;
+	right: 10px;
+	left: 10px;
+	top: 10px;
+	font-family: Monospace;
+	border: solid 2px black;
+	background: #ffffff;
+	padding: 0px;
+}
+
+/* IE6 */
+* html #testLogger
+{
+	width: 100%;
+}
+
+#testLogger.testAll
+{
+	position: static;
+}
+
+#testLogger pre
+{
+	margin: 0 0 0 40px;
+	background-color: #f0f0f0;
+	padding: 1px 4px 1px 4px;
+}
+
+#testLogger div
+{
+	margin: 2px;
+}
+
+#testLogger div div
+{
+	margin-left: 20px;
+}
+
+.testEntry
+{
+	padding: 5px;
+	margin: 0 !important;
+}
+
+.testEntry:hover
+{
+	background-color: #ffff99;
+}
+
+.testFail, .testPass, .testIgnore
+{
+	padding-left: 3px;
+	padding-right: 3px;
+}
+
+.testFail
+{
+	background-color: #ff0000;
+}
+
+.testPass
+{
+	background-color: #00ff00;
+}
+
+.testIgnore
+{
+	background-color: #f1f100;
+}
Index: /CKEditor/trunk/_source/tests/test.js
===================================================================
--- /CKEditor/trunk/_source/tests/test.js	(revision 2962)
+++ /CKEditor/trunk/_source/tests/test.js	(revision 2962)
@@ -0,0 +1,93 @@
+﻿/*
+Copyright (c) 2003-2009, CKSource - Frederico Knabben. All rights reserved.
+For licensing, see LICENSE.html or http://ckeditor.com/license
+*/
+
+/*jsl:import yuitest.js*/
+
+// Inject the YUI Test files into the page.
+// URLs copied from http://developer.yahoo.com/yui/yuitest/
+document.write(
+	'<script type="text/javascript" src="' +
+	CKEDITOR.basePath +
+	'_source/' +		// %REMOVE_LINE%
+	'tests/yuitest.js"></script>' );
+
+document.write(
+	'<script type="text/javascript" src="' +
+	CKEDITOR.basePath +
+	'_source/' +
+	'core/test.js"></script>' );
+
+(function()
+{
+	var createLogger = function()
+	{
+		document.body.appendChild( document.createElement( 'div' ) ).id = 'testLogger';
+	};
+
+	var outputResult = function( text )
+	{
+		var div = document.getElementById('testLogger').appendChild( document.createElement( 'div' ) );
+		div.className = 'testEntry';
+		div.innerHTML = text;
+	};
+
+	var htmlEncode = function( data )
+	{
+		if ( typeof data != 'string' )
+			return data;
+
+		return data.replace(
+			/&/g, '&amp;' ).replace(
+			/</g, '&lt;' ).replace(
+			/>/g, '&gt;' );
+	};
+
+	window.onload = function()
+	{
+		createLogger();
+		var runner = YAHOO.tool.TestRunner;
+
+		var handleTestResult = function( data )
+		{
+			switch( data.type )
+			{
+				case runner.TEST_FAIL_EVENT:
+
+					var expected = data.error.expected;
+					if ( expected && expected.nodeType )
+						expected += ' (' + ( expected.nodeType == 1 ? expected.nodeName : expected.nodeValue ) + ')';
+
+					var actual = data.error.actual;
+					if ( actual && actual.nodeType )
+						actual += ' (' + ( actual.nodeType == 1 ? actual.nodeName : actual.nodeValue ) + ')';
+
+					outputResult(
+						'<span class="testFail">FAIL</span> Test named "' + data.testName +
+						'" failed with message: "' + htmlEncode( data.error.message ) +
+						'".<div>Expected:</div><pre>' + htmlEncode( expected ) +
+						'<br></pre><div>Actual:</div><pre>' + htmlEncode( actual ) + '<br></pre>' );
+					break;
+				case runner.TEST_PASS_EVENT:
+					outputResult( '<span class="testPass">PASS</span> Test named "' + data.testName + '" passed.' );
+					break;
+				case runner.TEST_IGNORE_EVENT:
+					outputResult( '<span class="testIgnore">IGNORE</span> Test named "' + data.testName + '" was ignored.' );
+					break;
+			}
+		};
+
+		runner.subscribe(runner.TEST_FAIL_EVENT, handleTestResult);
+		runner.subscribe(runner.TEST_IGNORE_EVENT, handleTestResult);
+		runner.subscribe(runner.TEST_PASS_EVENT, handleTestResult);
+
+		if ( window.parent && window.parent.onTestStart )
+		{
+			runner.subscribe(runner.TEST_CASE_BEGIN_EVENT, window.parent.onTestStart);
+			runner.subscribe(runner.TEST_CASE_COMPLETE_EVENT, window.parent.onTestComplete);
+		}
+
+		runner.run();
+	};
+})();
Index: /CKEditor/trunk/_source/tests/testall.html
===================================================================
--- /CKEditor/trunk/_source/tests/testall.html	(revision 2962)
+++ /CKEditor/trunk/_source/tests/testall.html	(revision 2962)
@@ -0,0 +1,95 @@
+<!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 Core Tests Runner</title>
+	<link rel="stylesheet" type="text/css" href="test.css" />
+	<script type="text/javascript">
+	//<![CDATA[
+
+var testList =
+[
+	'core/ajax',
+	'core/ckeditor',
+	'core/ckeditor2',
+	'core/editor',
+	'core/env',
+	'core/event',
+	'core/scriptloader',
+	'core/tools',
+	'core/xml',
+	'core/dom/document',
+	'core/dom/element',
+	'core/dom/node',
+	'core/dom/range',
+	'core/dom/window',
+	'core/htmlparser/fragment',
+	'plugins/htmldataprocessor/htmldataprocessor',
+	'plugins/styles/styles'
+];
+
+var currentTest;
+var totalFailed = 0;
+var totalPassed = 0;
+
+function runTest()
+{
+	currentTest = testList.shift();
+
+	if ( currentTest )
+		document.getElementById( 'testFrame' ).src = currentTest + '.html';
+}
+
+function onTestStart( data )
+{
+	var div = document.getElementById('testLogger').appendChild( document.createElement( 'div' ) );
+	div.className = 'testEntry';
+	div.innerHTML = 'Testing "' + data.testCase.name + '"...';
+}
+
+function onTestComplete( data )
+{
+	var failed = data.results.failed;
+	var passed = data.results.passed;
+
+	var html = '<span class="testIgnore">Unknown</span>';
+
+	if ( failed > 0 )
+		html = '<span class="testFail">FAIL</span>';
+	else
+		html = '<span class="testPass">PASS</span>';
+
+	html += ' <a href="' + currentTest + '.html" target="_blank">Test case "' + data.testCase.name + '"</a> (' + failed + ' failed / ' + passed + ' passed)';
+
+	var div = document.getElementById('testLogger').lastChild;
+	div.innerHTML = html;
+
+	totalFailed += failed;
+	totalPassed += passed;
+
+	document.getElementById('testFailed').innerHTML = totalFailed;
+	document.getElementById('testPassed').innerHTML = totalPassed;
+
+	document.title = totalFailed + ' failed / ' + totalPassed + ' passed - CKEditor Core Tests Runner';
+
+	runTest();
+}
+
+window.onload = function()
+{
+	// IE was "caching" the latest logged div on refresh. So, we must clean it
+	// on startup.
+	document.getElementById('testLogger').innerHTML = '';
+
+	runTest();
+};
+
+	//]]>
+	</script>
+</head>
+<body>
+	<h1>CKEditor Core Tests Runner (<span id="testFailed">0</span> failed / <span id="testPassed">0</span> passed)</h1>
+	<iframe id="testFrame" src="javascript:;" style="position: absolute; width: 50px; height: 50px; left: -1000px">
+	</iframe>
+	<div id="testLogger" class="testAll"></div>
+</body>
+</html>
Index: /CKEditor/trunk/_source/tests/yuitest.js
===================================================================
--- /CKEditor/trunk/_source/tests/yuitest.js	(revision 2962)
+++ /CKEditor/trunk/_source/tests/yuitest.js	(revision 2962)
@@ -0,0 +1,71 @@
+﻿/*jsl:ignoreall*/
+/*
+Copyright (c) 2008, Yahoo! Inc. All rights reserved.
+Code licensed under the BSD License:
+http://developer.yahoo.net/yui/license.txt
+version: 2.5.2
+
+== BEGIN LICENSE ==
+
+Software License Agreement (BSD License)
+
+Copyright (c) 2008, Yahoo! Inc.
+All rights reserved.
+
+Redistribution and use of this software in source and binary forms, with or without modification, are
+permitted provided that the following conditions are met:
+
+* Redistributions of source code must retain the above
+  copyright notice, this list of conditions and the
+  following disclaimer.
+
+* Redistributions in binary form must reproduce the above
+  copyright notice, this list of conditions and the
+  following disclaimer in the documentation and/or other
+  materials provided with the distribution.
+
+* Neither the name of Yahoo! Inc. nor the names of its
+  contributors may be used to endorse or promote products
+  derived from this software without specific prior
+  written permission of Yahoo! Inc.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED
+WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
+ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
+TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+== END LICENSE ==
+*/
+
+/*
+This file contains the YUI Tester code as well as its dependencies, in the
+order defined at:
+http://developer.yahoo.com/yui/yuitest/
+*/
+
+// yahoo-dom-event/yahoo-dom-event.js
+if(typeof YAHOO=="undefined"||!YAHOO){var YAHOO={};}YAHOO.namespace=function(){var A=arguments,E=null,C,B,D;for(C=0;C<A.length;C=C+1){D=A[C].split(".");E=YAHOO;for(B=(D[0]=="YAHOO")?1:0;B<D.length;B=B+1){E[D[B]]=E[D[B]]||{};E=E[D[B]];}}return E;};YAHOO.log=function(D,A,C){var B=YAHOO.widget.Logger;if(B&&B.log){return B.log(D,A,C);}else{return false;}};YAHOO.register=function(A,E,D){var I=YAHOO.env.modules;if(!I[A]){I[A]={versions:[],builds:[]};}var B=I[A],H=D.version,G=D.build,F=YAHOO.env.listeners;B.name=A;B.version=H;B.build=G;B.versions.push(H);B.builds.push(G);B.mainClass=E;for(var C=0;C<F.length;C=C+1){F[C](B);}if(E){E.VERSION=H;E.BUILD=G;}else{YAHOO.log("mainClass is undefined for module "+A,"warn");}};YAHOO.env=YAHOO.env||{modules:[],listeners:[]};YAHOO.env.getVersion=function(A){return YAHOO.env.modules[A]||null;};YAHOO.env.ua=function(){var C={ie:0,opera:0,gecko:0,webkit:0,mobile:null,air:0};var B=navigator.userAgent,A;if((/KHTML/).test(B)){C.webkit=1;}A=B.match(/AppleWebKit\/([^\s]*)/);if(A&&A[1]){C.webkit=parseFloat(A[1]);if(/ Mobile\//.test(B)){C.mobile="Apple";}else{A=B.match(/NokiaN[^\/]*/);if(A){C.mobile=A[0];}}A=B.match(/AdobeAIR\/([^\s]*)/);if(A){C.air=A[0];}}if(!C.webkit){A=B.match(/Opera[\s\/]([^\s]*)/);if(A&&A[1]){C.opera=parseFloat(A[1]);A=B.match(/Opera Mini[^;]*/);if(A){C.mobile=A[0];}}else{A=B.match(/MSIE\s([^;]*)/);if(A&&A[1]){C.ie=parseFloat(A[1]);}else{A=B.match(/Gecko\/([^\s]*)/);if(A){C.gecko=1;A=B.match(/rv:([^\s\)]*)/);if(A&&A[1]){C.gecko=parseFloat(A[1]);}}}}}return C;}();(function(){YAHOO.namespace("util","widget","example");if("undefined"!==typeof YAHOO_config){var B=YAHOO_config.listener,A=YAHOO.env.listeners,D=true,C;if(B){for(C=0;C<A.length;C=C+1){if(A[C]==B){D=false;break;}}if(D){A.push(B);}}}})();YAHOO.lang=YAHOO.lang||{};(function(){var A=YAHOO.lang,C=["toString","valueOf"],B={isArray:function(D){if(D){return A.isNumber(D.length)&&A.isFunction(D.splice);}return false;},isBoolean:function(D){return typeof D==="boolean";},isFunction:function(D){return typeof D==="function";},isNull:function(D){return D===null;},isNumber:function(D){return typeof D==="number"&&isFinite(D);},isObject:function(D){return(D&&(typeof D==="object"||A.isFunction(D)))||false;},isString:function(D){return typeof D==="string";},isUndefined:function(D){return typeof D==="undefined";},_IEEnumFix:(YAHOO.env.ua.ie)?function(F,E){for(var D=0;D<C.length;D=D+1){var H=C[D],G=E[H];if(A.isFunction(G)&&G!=Object.prototype[H]){F[H]=G;}}}:function(){},extend:function(H,I,G){if(!I||!H){throw new Error("extend failed, please check that "+"all dependencies are included.");}var E=function(){};E.prototype=I.prototype;H.prototype=new E();H.prototype.constructor=H;H.superclass=I.prototype;if(I.prototype.constructor==Object.prototype.constructor){I.prototype.constructor=I;}if(G){for(var D in G){if(A.hasOwnProperty(G,D)){H.prototype[D]=G[D];}}A._IEEnumFix(H.prototype,G);}},augmentObject:function(H,G){if(!G||!H){throw new Error("Absorb failed, verify dependencies.");}var D=arguments,F,I,E=D[2];if(E&&E!==true){for(F=2;F<D.length;F=F+1){H[D[F]]=G[D[F]];}}else{for(I in G){if(E||!(I in H)){H[I]=G[I];}}A._IEEnumFix(H,G);}},augmentProto:function(G,F){if(!F||!G){throw new Error("Augment failed, verify dependencies.");}var D=[G.prototype,F.prototype];for(var E=2;E<arguments.length;E=E+1){D.push(arguments[E]);}A.augmentObject.apply(this,D);},dump:function(D,I){var F,H,K=[],L="{...}",E="f(){...}",J=", ",G=" => ";if(!A.isObject(D)){return D+"";}else{if(D instanceof Date||("nodeType" in D&&"tagName" in D)){return D;}else{if(A.isFunction(D)){return E;}}}I=(A.isNumber(I))?I:3;if(A.isArray(D)){K.push("[");for(F=0,H=D.length;F<H;F=F+1){if(A.isObject(D[F])){K.push((I>0)?A.dump(D[F],I-1):L);}else{K.push(D[F]);}K.push(J);}if(K.length>1){K.pop();}K.push("]");}else{K.push("{");for(F in D){if(A.hasOwnProperty(D,F)){K.push(F+G);if(A.isObject(D[F])){K.push((I>0)?A.dump(D[F],I-1):L);}else{K.push(D[F]);}K.push(J);}}if(K.length>1){K.pop();}K.push("}");}return K.join("");},substitute:function(S,E,L){var I,H,G,O,P,R,N=[],F,J="dump",M=" ",D="{",Q="}";for(;;){I=S.lastIndexOf(D);if(I<0){break;}H=S.indexOf(Q,I);if(I+1>=H){break;}F=S.substring(I+1,H);O=F;R=null;G=O.indexOf(M);if(G>-1){R=O.substring(G+1);O=O.substring(0,G);}P=E[O];if(L){P=L(O,P,R);}if(A.isObject(P)){if(A.isArray(P)){P=A.dump(P,parseInt(R,10));}else{R=R||"";var K=R.indexOf(J);if(K>-1){R=R.substring(4);}if(P.toString===Object.prototype.toString||K>-1){P=A.dump(P,parseInt(R,10));}else{P=P.toString();}}}else{if(!A.isString(P)&&!A.isNumber(P)){P="~-"+N.length+"-~";N[N.length]=F;}}S=S.substring(0,I)+P+S.substring(H+1);}for(I=N.length-1;I>=0;I=I-1){S=S.replace(new RegExp("~-"+I+"-~"),"{"+N[I]+"}","g");}return S;},trim:function(D){try{return D.replace(/^\s+|\s+$/g,"");}catch(E){return D;}},merge:function(){var G={},E=arguments;for(var F=0,D=E.length;F<D;F=F+1){A.augmentObject(G,E[F],true);}return G;},later:function(K,E,L,G,H){K=K||0;E=E||{};var F=L,J=G,I,D;if(A.isString(L)){F=E[L];}if(!F){throw new TypeError("method undefined");}if(!A.isArray(J)){J=[G];}I=function(){F.apply(E,J);};D=(H)?setInterval(I,K):setTimeout(I,K);return{interval:H,cancel:function(){if(this.interval){clearInterval(D);}else{clearTimeout(D);}}};},isValue:function(D){return(A.isObject(D)||A.isString(D)||A.isNumber(D)||A.isBoolean(D));}};A.hasOwnProperty=(Object.prototype.hasOwnProperty)?function(D,E){return D&&D.hasOwnProperty(E);}:function(D,E){return !A.isUndefined(D[E])&&D.constructor.prototype[E]!==D[E];};B.augmentObject(A,B,true);YAHOO.util.Lang=A;A.augment=A.augmentProto;YAHOO.augment=A.augmentProto;YAHOO.extend=A.extend;})();YAHOO.register("yahoo",YAHOO,{version:"2.5.2",build:"1076"});YAHOO.util.Get=function(){var M={},L=0,Q=0,E=false,N=YAHOO.env.ua,R=YAHOO.lang;var J=function(V,S,W){var T=W||window,X=T.document,Y=X.createElement(V);for(var U in S){if(S[U]&&YAHOO.lang.hasOwnProperty(S,U)){Y.setAttribute(U,S[U]);}}return Y;};var H=function(S,T,V){var U=V||"utf-8";return J("link",{"id":"yui__dyn_"+(Q++),"type":"text/css","charset":U,"rel":"stylesheet","href":S},T);
+};var O=function(S,T,V){var U=V||"utf-8";return J("script",{"id":"yui__dyn_"+(Q++),"type":"text/javascript","charset":U,"src":S},T);};var A=function(S,T){return{tId:S.tId,win:S.win,data:S.data,nodes:S.nodes,msg:T,purge:function(){D(this.tId);}};};var B=function(S,V){var T=M[V],U=(R.isString(S))?T.win.document.getElementById(S):S;if(!U){P(V,"target node not found: "+S);}return U;};var P=function(V,U){var S=M[V];if(S.onFailure){var T=S.scope||S.win;S.onFailure.call(T,A(S,U));}};var C=function(V){var S=M[V];S.finished=true;if(S.aborted){var U="transaction "+V+" was aborted";P(V,U);return ;}if(S.onSuccess){var T=S.scope||S.win;S.onSuccess.call(T,A(S));}};var G=function(U,Y){var T=M[U];if(T.aborted){var W="transaction "+U+" was aborted";P(U,W);return ;}if(Y){T.url.shift();if(T.varName){T.varName.shift();}}else{T.url=(R.isString(T.url))?[T.url]:T.url;if(T.varName){T.varName=(R.isString(T.varName))?[T.varName]:T.varName;}}var b=T.win,a=b.document,Z=a.getElementsByTagName("head")[0],V;if(T.url.length===0){if(T.type==="script"&&N.webkit&&N.webkit<420&&!T.finalpass&&!T.varName){var X=O(null,T.win,T.charset);X.innerHTML='YAHOO.util.Get._finalize("'+U+'");';T.nodes.push(X);Z.appendChild(X);}else{C(U);}return ;}var S=T.url[0];if(T.type==="script"){V=O(S,b,T.charset);}else{V=H(S,b,T.charset);}F(T.type,V,U,S,b,T.url.length);T.nodes.push(V);if(T.insertBefore){var c=B(T.insertBefore,U);if(c){c.parentNode.insertBefore(V,c);}}else{Z.appendChild(V);}if((N.webkit||N.gecko)&&T.type==="css"){G(U,S);}};var K=function(){if(E){return ;}E=true;for(var S in M){var T=M[S];if(T.autopurge&&T.finished){D(T.tId);delete M[S];}}E=false;};var D=function(Z){var W=M[Z];if(W){var Y=W.nodes,S=Y.length,X=W.win.document,V=X.getElementsByTagName("head")[0];if(W.insertBefore){var U=B(W.insertBefore,Z);if(U){V=U.parentNode;}}for(var T=0;T<S;T=T+1){V.removeChild(Y[T]);}}W.nodes=[];};var I=function(T,S,U){var W="q"+(L++);U=U||{};if(L%YAHOO.util.Get.PURGE_THRESH===0){K();}M[W]=R.merge(U,{tId:W,type:T,url:S,finished:false,nodes:[]});var V=M[W];V.win=V.win||window;V.scope=V.scope||V.win;V.autopurge=("autopurge" in V)?V.autopurge:(T==="script")?true:false;R.later(0,V,G,W);return{tId:W};};var F=function(b,W,V,T,X,Y,a){var Z=a||G;if(N.ie){W.onreadystatechange=function(){var c=this.readyState;if("loaded"===c||"complete"===c){Z(V,T);}};}else{if(N.webkit){if(b==="script"){if(N.webkit>=420){W.addEventListener("load",function(){Z(V,T);});}else{var S=M[V];if(S.varName){var U=YAHOO.util.Get.POLL_FREQ;S.maxattempts=YAHOO.util.Get.TIMEOUT/U;S.attempts=0;S._cache=S.varName[0].split(".");S.timer=R.later(U,S,function(h){var e=this._cache,d=e.length,c=this.win,f;for(f=0;f<d;f=f+1){c=c[e[f]];if(!c){this.attempts++;if(this.attempts++>this.maxattempts){var g="Over retry limit, giving up";S.timer.cancel();P(V,g);}else{}return ;}}S.timer.cancel();Z(V,T);},null,true);}else{R.later(YAHOO.util.Get.POLL_FREQ,null,Z,[V,T]);}}}}else{W.onload=function(){Z(V,T);};}}};return{POLL_FREQ:10,PURGE_THRESH:20,TIMEOUT:2000,_finalize:function(S){R.later(0,null,C,S);},abort:function(T){var U=(R.isString(T))?T:T.tId;var S=M[U];if(S){S.aborted=true;}},script:function(S,T){return I("script",S,T);},css:function(S,T){return I("css",S,T);}};}();YAHOO.register("get",YAHOO.util.Get,{version:"2.5.2",build:"1076"});(function(){var Y=YAHOO,util=Y.util,lang=Y.lang,env=Y.env,PROV="_provides",SUPER="_supersedes",REQ="expanded",AFTER="_after";var YUI={dupsAllowed:{"yahoo":true,"get":true},info:{"base":"http://yui.yahooapis.com/2.5.2/build/","skin":{"defaultSkin":"sam","base":"assets/skins/","path":"skin.css","after":["reset","fonts","grids","base"],"rollup":3},dupsAllowed:["yahoo","get"],"moduleInfo":{"animation":{"type":"js","path":"animation/animation-min.js","requires":["dom","event"]},"autocomplete":{"type":"js","path":"autocomplete/autocomplete-min.js","requires":["dom","event"],"optional":["connection","animation"],"skinnable":true},"base":{"type":"css","path":"base/base-min.css","after":["reset","fonts","grids"]},"button":{"type":"js","path":"button/button-min.js","requires":["element"],"optional":["menu"],"skinnable":true},"calendar":{"type":"js","path":"calendar/calendar-min.js","requires":["event","dom"],"skinnable":true},"charts":{"type":"js","path":"charts/charts-experimental-min.js","requires":["element","json","datasource"]},"colorpicker":{"type":"js","path":"colorpicker/colorpicker-min.js","requires":["slider","element"],"optional":["animation"],"skinnable":true},"connection":{"type":"js","path":"connection/connection-min.js","requires":["event"]},"container":{"type":"js","path":"container/container-min.js","requires":["dom","event"],"optional":["dragdrop","animation","connection"],"supersedes":["containercore"],"skinnable":true},"containercore":{"type":"js","path":"container/container_core-min.js","requires":["dom","event"],"pkg":"container"},"cookie":{"type":"js","path":"cookie/cookie-beta-min.js","requires":["yahoo"]},"datasource":{"type":"js","path":"datasource/datasource-beta-min.js","requires":["event"],"optional":["connection"]},"datatable":{"type":"js","path":"datatable/datatable-beta-min.js","requires":["element","datasource"],"optional":["calendar","dragdrop"],"skinnable":true},"dom":{"type":"js","path":"dom/dom-min.js","requires":["yahoo"]},"dragdrop":{"type":"js","path":"dragdrop/dragdrop-min.js","requires":["dom","event"]},"editor":{"type":"js","path":"editor/editor-beta-min.js","requires":["menu","element","button"],"optional":["animation","dragdrop"],"supersedes":["simpleeditor"],"skinnable":true},"element":{"type":"js","path":"element/element-beta-min.js","requires":["dom","event"]},"event":{"type":"js","path":"event/event-min.js","requires":["yahoo"]},"fonts":{"type":"css","path":"fonts/fonts-min.css"},"get":{"type":"js","path":"get/get-min.js","requires":["yahoo"]},"grids":{"type":"css","path":"grids/grids-min.css","requires":["fonts"],"optional":["reset"]},"history":{"type":"js","path":"history/history-min.js","requires":["event"]},"imagecropper":{"type":"js","path":"imagecropper/imagecropper-beta-min.js","requires":["dom","event","dragdrop","element","resize"],"skinnable":true},"imageloader":{"type":"js","path":"imageloader/imageloader-min.js","requires":["event","dom"]},"json":{"type":"js","path":"json/json-min.js","requires":["yahoo"]},"layout":{"type":"js","path":"layout/layout-beta-min.js","requires":["dom","event","element"],"optional":["animation","dragdrop","resize","selector"],"skinnable":true},"logger":{"type":"js","path":"logger/logger-min.js","requires":["event","dom"],"optional":["dragdrop"],"skinnable":true},"menu":{"type":"js","path":"menu/menu-min.js","requires":["containercore"],"skinnable":true},"profiler":{"type":"js","path":"profiler/profiler-beta-min.js","requires":["yahoo"]},"profilerviewer":{"type":"js","path":"profilerviewer/profilerviewer-beta-min.js","requires":["profiler","yuiloader","element"],"skinnable":true},"reset":{"type":"css","path":"reset/reset-min.css"},"reset-fonts-grids":{"type":"css","path":"reset-fonts-grids/reset-fonts-grids.css","supersedes":["reset","fonts","grids","reset-fonts"],"rollup":4},"reset-fonts":{"type":"css","path":"reset-fonts/reset-fonts.css","supersedes":["reset","fonts"],"rollup":2},"resize":{"type":"js","path":"resize/resize-beta-min.js","requires":["dom","event","dragdrop","element"],"optional":["animation"],"skinnable":true},"selector":{"type":"js","path":"selector/selector-beta-min.js","requires":["yahoo","dom"]},"simpleeditor":{"type":"js","path":"editor/simpleeditor-beta-min.js","requires":["element"],"optional":["containercore","menu","button","animation","dragdrop"],"skinnable":true,"pkg":"editor"},"slider":{"type":"js","path":"slider/slider-min.js","requires":["dragdrop"],"optional":["animation"]},"tabview":{"type":"js","path":"tabview/tabview-min.js","requires":["element"],"optional":["connection"],"skinnable":true},"treeview":{"type":"js","path":"treeview/treeview-min.js","requires":["event"],"skinnable":true},"uploader":{"type":"js","path":"uploader/uploader-experimental.js","requires":["element"]},"utilities":{"type":"js","path":"utilities/utilities.js","supersedes":["yahoo","event","dragdrop","animation","dom","connection","element","yahoo-dom-event","get","yuiloader","yuiloader-dom-event"],"rollup":8},"yahoo":{"type":"js","path":"yahoo/yahoo-min.js"},"yahoo-dom-event":{"type":"js","path":"yahoo-dom-event/yahoo-dom-event.js","supersedes":["yahoo","event","dom"],"rollup":3},"yuiloader":{"type":"js","path":"yuiloader/yuiloader-beta-min.js","supersedes":["yahoo","get"]},"yuiloader-dom-event":{"type":"js","path":"yuiloader-dom-event/yuiloader-dom-event.js","supersedes":["yahoo","dom","event","get","yuiloader","yahoo-dom-event"],"rollup":5},"yuitest":{"type":"js","path":"yuitest/yuitest-min.js","requires":["logger"],"skinnable":true}}},ObjectUtil:{appendArray:function(o,a){if(a){for(var i=0;
+i<a.length;i=i+1){o[a[i]]=true;}}},keys:function(o,ordered){var a=[],i;for(i in o){if(lang.hasOwnProperty(o,i)){a.push(i);}}return a;}},ArrayUtil:{appendArray:function(a1,a2){Array.prototype.push.apply(a1,a2);},indexOf:function(a,val){for(var i=0;i<a.length;i=i+1){if(a[i]===val){return i;}}return -1;},toObject:function(a){var o={};for(var i=0;i<a.length;i=i+1){o[a[i]]=true;}return o;},uniq:function(a){return YUI.ObjectUtil.keys(YUI.ArrayUtil.toObject(a));}}};YAHOO.util.YUILoader=function(o){this._internalCallback=null;this._useYahooListener=false;this.onSuccess=null;this.onFailure=Y.log;this.onProgress=null;this.scope=this;this.data=null;this.insertBefore=null;this.charset=null;this.varName=null;this.base=YUI.info.base;this.ignore=null;this.force=null;this.allowRollup=true;this.filter=null;this.required={};this.moduleInfo=lang.merge(YUI.info.moduleInfo);this.rollups=null;this.loadOptional=false;this.sorted=[];this.loaded={};this.dirty=true;this.inserted={};var self=this;env.listeners.push(function(m){if(self._useYahooListener){self.loadNext(m.name);}});this.skin=lang.merge(YUI.info.skin);this._config(o);};Y.util.YUILoader.prototype={FILTERS:{RAW:{"searchExp":"-min\\.js","replaceStr":".js"},DEBUG:{"searchExp":"-min\\.js","replaceStr":"-debug.js"}},SKIN_PREFIX:"skin-",_config:function(o){if(o){for(var i in o){if(lang.hasOwnProperty(o,i)){if(i=="require"){this.require(o[i]);}else{this[i]=o[i];}}}}var f=this.filter;if(lang.isString(f)){f=f.toUpperCase();if(f==="DEBUG"){this.require("logger");}if(!Y.widget.LogWriter){Y.widget.LogWriter=function(){return Y;};}this.filter=this.FILTERS[f];}},addModule:function(o){if(!o||!o.name||!o.type||(!o.path&&!o.fullpath)){return false;}o.ext=("ext" in o)?o.ext:true;o.requires=o.requires||[];this.moduleInfo[o.name]=o;this.dirty=true;return true;},require:function(what){var a=(typeof what==="string")?arguments:what;this.dirty=true;YUI.ObjectUtil.appendArray(this.required,a);},_addSkin:function(skin,mod){var name=this.formatSkin(skin),info=this.moduleInfo,sinf=this.skin,ext=info[mod]&&info[mod].ext;if(!info[name]){this.addModule({"name":name,"type":"css","path":sinf.base+skin+"/"+sinf.path,"after":sinf.after,"rollup":sinf.rollup,"ext":ext});}if(mod){name=this.formatSkin(skin,mod);if(!info[name]){var mdef=info[mod],pkg=mdef.pkg||mod;this.addModule({"name":name,"type":"css","after":sinf.after,"path":pkg+"/"+sinf.base+skin+"/"+mod+".css","ext":ext});}}return name;},getRequires:function(mod){if(!mod){return[];}if(!this.dirty&&mod.expanded){return mod.expanded;}mod.requires=mod.requires||[];var i,d=[],r=mod.requires,o=mod.optional,info=this.moduleInfo,m;for(i=0;i<r.length;i=i+1){d.push(r[i]);m=info[r[i]];YUI.ArrayUtil.appendArray(d,this.getRequires(m));}if(o&&this.loadOptional){for(i=0;i<o.length;i=i+1){d.push(o[i]);YUI.ArrayUtil.appendArray(d,this.getRequires(info[o[i]]));}}mod.expanded=YUI.ArrayUtil.uniq(d);return mod.expanded;},getProvides:function(name,notMe){var addMe=!(notMe),ckey=(addMe)?PROV:SUPER,m=this.moduleInfo[name],o={};if(!m){return o;}if(m[ckey]){return m[ckey];}var s=m.supersedes,done={},me=this;var add=function(mm){if(!done[mm]){done[mm]=true;lang.augmentObject(o,me.getProvides(mm));}};if(s){for(var i=0;i<s.length;i=i+1){add(s[i]);}}m[SUPER]=o;m[PROV]=lang.merge(o);m[PROV][name]=true;return m[ckey];},calculate:function(o){if(this.dirty){this._config(o);this._setup();this._explode();if(this.allowRollup){this._rollup();}this._reduce();this._sort();this.dirty=false;}},_setup:function(){var info=this.moduleInfo,name,i,j;for(name in info){var m=info[name];if(m&&m.skinnable){var o=this.skin.overrides,smod;if(o&&o[name]){for(i=0;i<o[name].length;i=i+1){smod=this._addSkin(o[name][i],name);}}else{smod=this._addSkin(this.skin.defaultSkin,name);}m.requires.push(smod);}}var l=lang.merge(this.inserted);if(!this._sandbox){l=lang.merge(l,env.modules);}if(this.ignore){YUI.ObjectUtil.appendArray(l,this.ignore);}if(this.force){for(i=0;i<this.force.length;i=i+1){if(this.force[i] in l){delete l[this.force[i]];}}}for(j in l){if(lang.hasOwnProperty(l,j)){lang.augmentObject(l,this.getProvides(j));}}this.loaded=l;},_explode:function(){var r=this.required,i,mod;for(i in r){mod=this.moduleInfo[i];if(mod){var req=this.getRequires(mod);if(req){YUI.ObjectUtil.appendArray(r,req);}}}},_skin:function(){},formatSkin:function(skin,mod){var s=this.SKIN_PREFIX+skin;if(mod){s=s+"-"+mod;}return s;},parseSkin:function(mod){if(mod.indexOf(this.SKIN_PREFIX)===0){var a=mod.split("-");return{skin:a[1],module:a[2]};}return null;},_rollup:function(){var i,j,m,s,rollups={},r=this.required,roll;if(this.dirty||!this.rollups){for(i in this.moduleInfo){m=this.moduleInfo[i];if(m&&m.rollup){rollups[i]=m;}}this.rollups=rollups;}for(;;){var rolled=false;for(i in rollups){if(!r[i]&&!this.loaded[i]){m=this.moduleInfo[i];s=m.supersedes;roll=false;if(!m.rollup){continue;}var skin=(m.ext)?false:this.parseSkin(i),c=0;if(skin){for(j in r){if(i!==j&&this.parseSkin(j)){c++;roll=(c>=m.rollup);if(roll){break;}}}}else{for(j=0;j<s.length;j=j+1){if(this.loaded[s[j]]&&(!YUI.dupsAllowed[s[j]])){roll=false;break;}else{if(r[s[j]]){c++;roll=(c>=m.rollup);if(roll){break;}}}}}if(roll){r[i]=true;rolled=true;this.getRequires(m);}}}if(!rolled){break;}}},_reduce:function(){var i,j,s,m,r=this.required;for(i in r){if(i in this.loaded){delete r[i];}else{var skinDef=this.parseSkin(i);if(skinDef){if(!skinDef.module){var skin_pre=this.SKIN_PREFIX+skinDef.skin;for(j in r){m=this.moduleInfo[j];var ext=m&&m.ext;if(!ext&&j!==i&&j.indexOf(skin_pre)>-1){delete r[j];}}}}else{m=this.moduleInfo[i];s=m&&m.supersedes;if(s){for(j=0;j<s.length;j=j+1){if(s[j] in r){delete r[s[j]];}}}}}}},_sort:function(){var s=[],info=this.moduleInfo,loaded=this.loaded,checkOptional=!this.loadOptional,me=this;var requires=function(aa,bb){if(loaded[bb]){return false;}var ii,mm=info[aa],rr=mm&&mm.expanded,after=mm&&mm.after,other=info[bb],optional=mm&&mm.optional;if(rr&&YUI.ArrayUtil.indexOf(rr,bb)>-1){return true;}if(after&&YUI.ArrayUtil.indexOf(after,bb)>-1){return true;
+}if(checkOptional&&optional&&YUI.ArrayUtil.indexOf(optional,bb)>-1){return true;}var ss=info[bb]&&info[bb].supersedes;if(ss){for(ii=0;ii<ss.length;ii=ii+1){if(requires(aa,ss[ii])){return true;}}}if(mm.ext&&mm.type=="css"&&(!other.ext)){return true;}return false;};for(var i in this.required){s.push(i);}var p=0;for(;;){var l=s.length,a,b,j,k,moved=false;for(j=p;j<l;j=j+1){a=s[j];for(k=j+1;k<l;k=k+1){if(requires(a,s[k])){b=s.splice(k,1);s.splice(j,0,b[0]);moved=true;break;}}if(moved){break;}else{p=p+1;}}if(!moved){break;}}this.sorted=s;},toString:function(){var o={type:"YUILoader",base:this.base,filter:this.filter,required:this.required,loaded:this.loaded,inserted:this.inserted};lang.dump(o,1);},insert:function(o,type){this.calculate(o);if(!type){var self=this;this._internalCallback=function(){self._internalCallback=null;self.insert(null,"js");};this.insert(null,"css");return ;}this._loading=true;this.loadType=type;this.loadNext();},sandbox:function(o,type){if(o){}else{}this._config(o);if(!this.onSuccess){throw new Error("You must supply an onSuccess handler for your sandbox");}this._sandbox=true;var self=this;if(!type||type!=="js"){this._internalCallback=function(){self._internalCallback=null;self.sandbox(null,"js");};this.insert(null,"css");return ;}if(!util.Connect){var ld=new YAHOO.util.YUILoader();ld.insert({base:this.base,filter:this.filter,require:"connection",insertBefore:this.insertBefore,charset:this.charset,onSuccess:function(){this.sandbox(null,"js");},scope:this},"js");return ;}this._scriptText=[];this._loadCount=0;this._stopCount=this.sorted.length;this._xhr=[];this.calculate();var s=this.sorted,l=s.length,i,m,url;for(i=0;i<l;i=i+1){m=this.moduleInfo[s[i]];if(!m){this.onFailure.call(this.scope,{msg:"undefined module "+m,data:this.data});for(var j=0;j<this._xhr.length;j=j+1){this._xhr[j].abort();}return ;}if(m.type!=="js"){this._loadCount++;continue;}url=m.fullpath||this._url(m.path);var xhrData={success:function(o){var idx=o.argument[0],name=o.argument[2];this._scriptText[idx]=o.responseText;if(this.onProgress){this.onProgress.call(this.scope,{name:name,scriptText:o.responseText,xhrResponse:o,data:this.data});}this._loadCount++;if(this._loadCount>=this._stopCount){var v=this.varName||"YAHOO";var t="(function() {\n";var b="\nreturn "+v+";\n})();";var ref=eval(t+this._scriptText.join("\n")+b);this._pushEvents(ref);if(ref){this.onSuccess.call(this.scope,{reference:ref,data:this.data});}else{this.onFailure.call(this.scope,{msg:this.varName+" reference failure",data:this.data});}}},failure:function(o){this.onFailure.call(this.scope,{msg:"XHR failure",xhrResponse:o,data:this.data});},scope:this,argument:[i,url,s[i]]};this._xhr.push(util.Connect.asyncRequest("GET",url,xhrData));}},loadNext:function(mname){if(!this._loading){return ;}if(mname){if(mname!==this._loading){return ;}this.inserted[mname]=true;if(this.onProgress){this.onProgress.call(this.scope,{name:mname,data:this.data});}}var s=this.sorted,len=s.length,i,m;for(i=0;i<len;i=i+1){if(s[i] in this.inserted){continue;}if(s[i]===this._loading){return ;}m=this.moduleInfo[s[i]];if(!m){this.onFailure.call(this.scope,{msg:"undefined module "+m,data:this.data});return ;}if(!this.loadType||this.loadType===m.type){this._loading=s[i];var fn=(m.type==="css")?util.Get.css:util.Get.script,url=m.fullpath||this._url(m.path),self=this,c=function(o){self.loadNext(o.data);};if(env.ua.webkit&&env.ua.webkit<420&&m.type==="js"&&!m.varName){c=null;this._useYahooListener=true;}fn(url,{data:s[i],onSuccess:c,insertBefore:this.insertBefore,charset:this.charset,varName:m.varName,scope:self});return ;}}this._loading=null;if(this._internalCallback){var f=this._internalCallback;this._internalCallback=null;f.call(this);}else{if(this.onSuccess){this._pushEvents();this.onSuccess.call(this.scope,{data:this.data});}}},_pushEvents:function(ref){var r=ref||YAHOO;if(r.util&&r.util.Event){r.util.Event._load();}},_url:function(path){var u=this.base||"",f=this.filter;u=u+path;if(f){u=u.replace(new RegExp(f.searchExp),f.replaceStr);}return u;}};})();(function(){var B=YAHOO.util,K,I,J={},F={},M=window.document;YAHOO.env._id_counter=YAHOO.env._id_counter||0;var C=YAHOO.env.ua.opera,L=YAHOO.env.ua.webkit,A=YAHOO.env.ua.gecko,G=YAHOO.env.ua.ie;var E={HYPHEN:/(-[a-z])/i,ROOT_TAG:/^body|html$/i,OP_SCROLL:/^(?:inline|table-row)$/i};var N=function(P){if(!E.HYPHEN.test(P)){return P;}if(J[P]){return J[P];}var Q=P;while(E.HYPHEN.exec(Q)){Q=Q.replace(RegExp.$1,RegExp.$1.substr(1).toUpperCase());}J[P]=Q;return Q;};var O=function(Q){var P=F[Q];if(!P){P=new RegExp("(?:^|\\s+)"+Q+"(?:\\s+|$)");F[Q]=P;}return P;};if(M.defaultView&&M.defaultView.getComputedStyle){K=function(P,S){var R=null;if(S=="float"){S="cssFloat";}var Q=P.ownerDocument.defaultView.getComputedStyle(P,"");if(Q){R=Q[N(S)];}return P.style[S]||R;};}else{if(M.documentElement.currentStyle&&G){K=function(P,R){switch(N(R)){case"opacity":var T=100;try{T=P.filters["DXImageTransform.Microsoft.Alpha"].opacity;}catch(S){try{T=P.filters("alpha").opacity;}catch(S){}}return T/100;case"float":R="styleFloat";default:var Q=P.currentStyle?P.currentStyle[R]:null;return(P.style[R]||Q);}};}else{K=function(P,Q){return P.style[Q];};}}if(G){I=function(P,Q,R){switch(Q){case"opacity":if(YAHOO.lang.isString(P.style.filter)){P.style.filter="alpha(opacity="+R*100+")";if(!P.currentStyle||!P.currentStyle.hasLayout){P.style.zoom=1;}}break;case"float":Q="styleFloat";default:P.style[Q]=R;}};}else{I=function(P,Q,R){if(Q=="float"){Q="cssFloat";}P.style[Q]=R;};}var D=function(P,Q){return P&&P.nodeType==1&&(!Q||Q(P));};YAHOO.util.Dom={get:function(R){if(R&&(R.nodeType||R.item)){return R;}if(YAHOO.lang.isString(R)||!R){return M.getElementById(R);}if(R.length!==undefined){var S=[];for(var Q=0,P=R.length;Q<P;++Q){S[S.length]=B.Dom.get(R[Q]);}return S;}return R;},getStyle:function(P,R){R=N(R);var Q=function(S){return K(S,R);};return B.Dom.batch(P,Q,B.Dom,true);},setStyle:function(P,R,S){R=N(R);var Q=function(T){I(T,R,S);};B.Dom.batch(P,Q,B.Dom,true);},getXY:function(P){var Q=function(R){if((R.parentNode===null||R.offsetParent===null||this.getStyle(R,"display")=="none")&&R!=R.ownerDocument.body){return false;}return H(R);};return B.Dom.batch(P,Q,B.Dom,true);},getX:function(P){var Q=function(R){return B.Dom.getXY(R)[0];};return B.Dom.batch(P,Q,B.Dom,true);},getY:function(P){var Q=function(R){return B.Dom.getXY(R)[1];};return B.Dom.batch(P,Q,B.Dom,true);},setXY:function(P,S,R){var Q=function(V){var U=this.getStyle(V,"position");if(U=="static"){this.setStyle(V,"position","relative");U="relative";}var X=this.getXY(V);if(X===false){return false;}var W=[parseInt(this.getStyle(V,"left"),10),parseInt(this.getStyle(V,"top"),10)];if(isNaN(W[0])){W[0]=(U=="relative")?0:V.offsetLeft;}if(isNaN(W[1])){W[1]=(U=="relative")?0:V.offsetTop;}if(S[0]!==null){V.style.left=S[0]-X[0]+W[0]+"px";}if(S[1]!==null){V.style.top=S[1]-X[1]+W[1]+"px";}if(!R){var T=this.getXY(V);if((S[0]!==null&&T[0]!=S[0])||(S[1]!==null&&T[1]!=S[1])){this.setXY(V,S,true);}}};B.Dom.batch(P,Q,B.Dom,true);},setX:function(Q,P){B.Dom.setXY(Q,[P,null]);},setY:function(P,Q){B.Dom.setXY(P,[null,Q]);},getRegion:function(P){var Q=function(R){if((R.parentNode===null||R.offsetParent===null||this.getStyle(R,"display")=="none")&&R!=R.ownerDocument.body){return false;}var S=B.Region.getRegion(R);return S;};return B.Dom.batch(P,Q,B.Dom,true);},getClientWidth:function(){return B.Dom.getViewportWidth();},getClientHeight:function(){return B.Dom.getViewportHeight();},getElementsByClassName:function(T,X,U,V){X=X||"*";U=(U)?B.Dom.get(U):null||M;if(!U){return[];}var Q=[],P=U.getElementsByTagName(X),W=O(T);for(var R=0,S=P.length;R<S;++R){if(W.test(P[R].className)){Q[Q.length]=P[R];if(V){V.call(P[R],P[R]);}}}return Q;},hasClass:function(R,Q){var P=O(Q);var S=function(T){return P.test(T.className);};return B.Dom.batch(R,S,B.Dom,true);},addClass:function(Q,P){var R=function(S){if(this.hasClass(S,P)){return false;}S.className=YAHOO.lang.trim([S.className,P].join(" "));return true;};return B.Dom.batch(Q,R,B.Dom,true);},removeClass:function(R,Q){var P=O(Q);var S=function(T){if(!Q||!this.hasClass(T,Q)){return false;}var U=T.className;T.className=U.replace(P," ");if(this.hasClass(T,Q)){this.removeClass(T,Q);}T.className=YAHOO.lang.trim(T.className);return true;};return B.Dom.batch(R,S,B.Dom,true);},replaceClass:function(S,Q,P){if(!P||Q===P){return false;}var R=O(Q);var T=function(U){if(!this.hasClass(U,Q)){this.addClass(U,P);return true;}U.className=U.className.replace(R," "+P+" ");if(this.hasClass(U,Q)){this.replaceClass(U,Q,P);}U.className=YAHOO.lang.trim(U.className);return true;};return B.Dom.batch(S,T,B.Dom,true);},generateId:function(P,R){R=R||"yui-gen";var Q=function(S){if(S&&S.id){return S.id;}var T=R+YAHOO.env._id_counter++;if(S){S.id=T;}return T;};return B.Dom.batch(P,Q,B.Dom,true)||Q.apply(B.Dom,arguments);},isAncestor:function(P,Q){P=B.Dom.get(P);Q=B.Dom.get(Q);if(!P||!Q){return false;}if(P.contains&&Q.nodeType&&!L){return P.contains(Q);}else{if(P.compareDocumentPosition&&Q.nodeType){return !!(P.compareDocumentPosition(Q)&16);}else{if(Q.nodeType){return !!this.getAncestorBy(Q,function(R){return R==P;});}}}return false;},inDocument:function(P){return this.isAncestor(M.documentElement,P);},getElementsBy:function(W,Q,R,T){Q=Q||"*";R=(R)?B.Dom.get(R):null||M;if(!R){return[];}var S=[],V=R.getElementsByTagName(Q);for(var U=0,P=V.length;U<P;++U){if(W(V[U])){S[S.length]=V[U];if(T){T(V[U]);}}}return S;},batch:function(T,W,V,R){T=(T&&(T.tagName||T.item))?T:B.Dom.get(T);if(!T||!W){return false;}var S=(R)?V:window;if(T.tagName||T.length===undefined){return W.call(S,T,V);}var U=[];for(var Q=0,P=T.length;Q<P;++Q){U[U.length]=W.call(S,T[Q],V);}return U;},getDocumentHeight:function(){var Q=(M.compatMode!="CSS1Compat")?M.body.scrollHeight:M.documentElement.scrollHeight;var P=Math.max(Q,B.Dom.getViewportHeight());return P;},getDocumentWidth:function(){var Q=(M.compatMode!="CSS1Compat")?M.body.scrollWidth:M.documentElement.scrollWidth;var P=Math.max(Q,B.Dom.getViewportWidth());return P;},getViewportHeight:function(){var P=self.innerHeight;
+var Q=M.compatMode;if((Q||G)&&!C){P=(Q=="CSS1Compat")?M.documentElement.clientHeight:M.body.clientHeight;}return P;},getViewportWidth:function(){var P=self.innerWidth;var Q=M.compatMode;if(Q||G){P=(Q=="CSS1Compat")?M.documentElement.clientWidth:M.body.clientWidth;}return P;},getAncestorBy:function(P,Q){while(P=P.parentNode){if(D(P,Q)){return P;}}return null;},getAncestorByClassName:function(Q,P){Q=B.Dom.get(Q);if(!Q){return null;}var R=function(S){return B.Dom.hasClass(S,P);};return B.Dom.getAncestorBy(Q,R);},getAncestorByTagName:function(Q,P){Q=B.Dom.get(Q);if(!Q){return null;}var R=function(S){return S.tagName&&S.tagName.toUpperCase()==P.toUpperCase();};return B.Dom.getAncestorBy(Q,R);},getPreviousSiblingBy:function(P,Q){while(P){P=P.previousSibling;if(D(P,Q)){return P;}}return null;},getPreviousSibling:function(P){P=B.Dom.get(P);if(!P){return null;}return B.Dom.getPreviousSiblingBy(P);},getNextSiblingBy:function(P,Q){while(P){P=P.nextSibling;if(D(P,Q)){return P;}}return null;},getNextSibling:function(P){P=B.Dom.get(P);if(!P){return null;}return B.Dom.getNextSiblingBy(P);},getFirstChildBy:function(P,R){var Q=(D(P.firstChild,R))?P.firstChild:null;return Q||B.Dom.getNextSiblingBy(P.firstChild,R);},getFirstChild:function(P,Q){P=B.Dom.get(P);if(!P){return null;}return B.Dom.getFirstChildBy(P);},getLastChildBy:function(P,R){if(!P){return null;}var Q=(D(P.lastChild,R))?P.lastChild:null;return Q||B.Dom.getPreviousSiblingBy(P.lastChild,R);},getLastChild:function(P){P=B.Dom.get(P);return B.Dom.getLastChildBy(P);},getChildrenBy:function(Q,S){var R=B.Dom.getFirstChildBy(Q,S);var P=R?[R]:[];B.Dom.getNextSiblingBy(R,function(T){if(!S||S(T)){P[P.length]=T;}return false;});return P;},getChildren:function(P){P=B.Dom.get(P);if(!P){}return B.Dom.getChildrenBy(P);},getDocumentScrollLeft:function(P){P=P||M;return Math.max(P.documentElement.scrollLeft,P.body.scrollLeft);},getDocumentScrollTop:function(P){P=P||M;return Math.max(P.documentElement.scrollTop,P.body.scrollTop);},insertBefore:function(Q,P){Q=B.Dom.get(Q);P=B.Dom.get(P);if(!Q||!P||!P.parentNode){return null;}return P.parentNode.insertBefore(Q,P);},insertAfter:function(Q,P){Q=B.Dom.get(Q);P=B.Dom.get(P);if(!Q||!P||!P.parentNode){return null;}if(P.nextSibling){return P.parentNode.insertBefore(Q,P.nextSibling);}else{return P.parentNode.appendChild(Q);}},getClientRegion:function(){var R=B.Dom.getDocumentScrollTop(),Q=B.Dom.getDocumentScrollLeft(),S=B.Dom.getViewportWidth()+Q,P=B.Dom.getViewportHeight()+R;return new B.Region(R,S,P,Q);}};var H=function(){if(M.documentElement.getBoundingClientRect){return function(Q){var R=Q.getBoundingClientRect();var P=Q.ownerDocument;return[R.left+B.Dom.getDocumentScrollLeft(P),R.top+B.Dom.getDocumentScrollTop(P)];};}else{return function(R){var S=[R.offsetLeft,R.offsetTop];var Q=R.offsetParent;var P=(L&&B.Dom.getStyle(R,"position")=="absolute"&&R.offsetParent==R.ownerDocument.body);if(Q!=R){while(Q){S[0]+=Q.offsetLeft;S[1]+=Q.offsetTop;if(!P&&L&&B.Dom.getStyle(Q,"position")=="absolute"){P=true;}Q=Q.offsetParent;}}if(P){S[0]-=R.ownerDocument.body.offsetLeft;S[1]-=R.ownerDocument.body.offsetTop;}Q=R.parentNode;while(Q.tagName&&!E.ROOT_TAG.test(Q.tagName)){if(Q.scrollTop||Q.scrollLeft){if(!E.OP_SCROLL.test(B.Dom.getStyle(Q,"display"))){if(!C||B.Dom.getStyle(Q,"overflow")!=="visible"){S[0]-=Q.scrollLeft;S[1]-=Q.scrollTop;}}}Q=Q.parentNode;}return S;};}}();})();YAHOO.util.Region=function(C,D,A,B){this.top=C;this[1]=C;this.right=D;this.bottom=A;this.left=B;this[0]=B;};YAHOO.util.Region.prototype.contains=function(A){return(A.left>=this.left&&A.right<=this.right&&A.top>=this.top&&A.bottom<=this.bottom);};YAHOO.util.Region.prototype.getArea=function(){return((this.bottom-this.top)*(this.right-this.left));};YAHOO.util.Region.prototype.intersect=function(E){var C=Math.max(this.top,E.top);var D=Math.min(this.right,E.right);var A=Math.min(this.bottom,E.bottom);var B=Math.max(this.left,E.left);if(A>=C&&D>=B){return new YAHOO.util.Region(C,D,A,B);}else{return null;}};YAHOO.util.Region.prototype.union=function(E){var C=Math.min(this.top,E.top);var D=Math.max(this.right,E.right);var A=Math.max(this.bottom,E.bottom);var B=Math.min(this.left,E.left);return new YAHOO.util.Region(C,D,A,B);};YAHOO.util.Region.prototype.toString=function(){return("Region {"+"top: "+this.top+", right: "+this.right+", bottom: "+this.bottom+", left: "+this.left+"}");};YAHOO.util.Region.getRegion=function(D){var F=YAHOO.util.Dom.getXY(D);var C=F[1];var E=F[0]+D.offsetWidth;var A=F[1]+D.offsetHeight;var B=F[0];return new YAHOO.util.Region(C,E,A,B);};YAHOO.util.Point=function(A,B){if(YAHOO.lang.isArray(A)){B=A[1];A=A[0];}this.x=this.right=this.left=this[0]=A;this.y=this.top=this.bottom=this[1]=B;};YAHOO.util.Point.prototype=new YAHOO.util.Region();YAHOO.register("dom",YAHOO.util.Dom,{version:"2.5.2",build:"1076"});YAHOO.util.CustomEvent=function(D,B,C,A){this.type=D;this.scope=B||window;this.silent=C;this.signature=A||YAHOO.util.CustomEvent.LIST;this.subscribers=[];if(!this.silent){}var E="_YUICEOnSubscribe";if(D!==E){this.subscribeEvent=new YAHOO.util.CustomEvent(E,this,true);}this.lastError=null;};YAHOO.util.CustomEvent.LIST=0;YAHOO.util.CustomEvent.FLAT=1;YAHOO.util.CustomEvent.prototype={subscribe:function(B,C,A){if(!B){throw new Error("Invalid callback for subscriber to '"+this.type+"'");}if(this.subscribeEvent){this.subscribeEvent.fire(B,C,A);}this.subscribers.push(new YAHOO.util.Subscriber(B,C,A));},unsubscribe:function(D,F){if(!D){return this.unsubscribeAll();}var E=false;for(var B=0,A=this.subscribers.length;B<A;++B){var C=this.subscribers[B];if(C&&C.contains(D,F)){this._delete(B);E=true;}}return E;},fire:function(){this.lastError=null;var K=[],E=this.subscribers.length;if(!E&&this.silent){return true;}var I=[].slice.call(arguments,0),G=true,D,J=false;if(!this.silent){}var C=this.subscribers.slice(),A=YAHOO.util.Event.throwErrors;for(D=0;D<E;++D){var M=C[D];if(!M){J=true;}else{if(!this.silent){}var L=M.getScope(this.scope);if(this.signature==YAHOO.util.CustomEvent.FLAT){var B=null;if(I.length>0){B=I[0];}try{G=M.fn.call(L,B,M.obj);}catch(F){this.lastError=F;if(A){throw F;}}}else{try{G=M.fn.call(L,this.type,I,M.obj);}catch(H){this.lastError=H;if(A){throw H;}}}if(false===G){if(!this.silent){}break;}}}return(G!==false);},unsubscribeAll:function(){for(var A=this.subscribers.length-1;A>-1;A--){this._delete(A);}this.subscribers=[];return A;},_delete:function(A){var B=this.subscribers[A];if(B){delete B.fn;delete B.obj;}this.subscribers.splice(A,1);},toString:function(){return"CustomEvent: "+"'"+this.type+"', "+"scope: "+this.scope;}};YAHOO.util.Subscriber=function(B,C,A){this.fn=B;this.obj=YAHOO.lang.isUndefined(C)?null:C;this.override=A;};YAHOO.util.Subscriber.prototype.getScope=function(A){if(this.override){if(this.override===true){return this.obj;}else{return this.override;}}return A;};YAHOO.util.Subscriber.prototype.contains=function(A,B){if(B){return(this.fn==A&&this.obj==B);}else{return(this.fn==A);}};YAHOO.util.Subscriber.prototype.toString=function(){return"Subscriber { obj: "+this.obj+", override: "+(this.override||"no")+" }";};if(!YAHOO.util.Event){YAHOO.util.Event=function(){var H=false;var I=[];var J=[];var G=[];var E=[];var C=0;var F=[];var B=[];var A=0;var D={63232:38,63233:40,63234:37,63235:39,63276:33,63277:34,25:9};return{POLL_RETRYS:2000,POLL_INTERVAL:20,EL:0,TYPE:1,FN:2,WFN:3,UNLOAD_OBJ:3,ADJ_SCOPE:4,OBJ:5,OVERRIDE:6,lastError:null,isSafari:YAHOO.env.ua.webkit,webkit:YAHOO.env.ua.webkit,isIE:YAHOO.env.ua.ie,_interval:null,_dri:null,DOMReady:false,throwErrors:false,startInterval:function(){if(!this._interval){var K=this;var L=function(){K._tryPreloadAttach();};this._interval=setInterval(L,this.POLL_INTERVAL);}},onAvailable:function(P,M,Q,O,N){var K=(YAHOO.lang.isString(P))?[P]:P;for(var L=0;L<K.length;L=L+1){F.push({id:K[L],fn:M,obj:Q,override:O,checkReady:N});}C=this.POLL_RETRYS;this.startInterval();},onContentReady:function(M,K,N,L){this.onAvailable(M,K,N,L,true);},onDOMReady:function(K,M,L){if(this.DOMReady){setTimeout(function(){var N=window;if(L){if(L===true){N=M;}else{N=L;}}K.call(N,"DOMReady",[],M);},0);}else{this.DOMReadyEvent.subscribe(K,M,L);}},addListener:function(M,K,V,Q,L){if(!V||!V.call){return false;}if(this._isValidCollection(M)){var W=true;for(var R=0,T=M.length;R<T;++R){W=this.on(M[R],K,V,Q,L)&&W;}return W;}else{if(YAHOO.lang.isString(M)){var P=this.getEl(M);if(P){M=P;}else{this.onAvailable(M,function(){YAHOO.util.Event.on(M,K,V,Q,L);});return true;}}}if(!M){return false;}if("unload"==K&&Q!==this){J[J.length]=[M,K,V,Q,L];return true;}var Y=M;if(L){if(L===true){Y=Q;}else{Y=L;}}var N=function(Z){return V.call(Y,YAHOO.util.Event.getEvent(Z,M),Q);};var X=[M,K,V,N,Y,Q,L];var S=I.length;I[S]=X;if(this.useLegacyEvent(M,K)){var O=this.getLegacyIndex(M,K);if(O==-1||M!=G[O][0]){O=G.length;B[M.id+K]=O;G[O]=[M,K,M["on"+K]];E[O]=[];M["on"+K]=function(Z){YAHOO.util.Event.fireLegacyEvent(YAHOO.util.Event.getEvent(Z),O);};}E[O].push(X);}else{try{this._simpleAdd(M,K,N,false);}catch(U){this.lastError=U;this.removeListener(M,K,V);return false;}}return true;},fireLegacyEvent:function(O,M){var Q=true,K,S,R,T,P;S=E[M].slice();for(var L=0,N=S.length;L<N;++L){R=S[L];if(R&&R[this.WFN]){T=R[this.ADJ_SCOPE];P=R[this.WFN].call(T,O);Q=(Q&&P);}}K=G[M];if(K&&K[2]){K[2](O);}return Q;},getLegacyIndex:function(L,M){var K=this.generateId(L)+M;if(typeof B[K]=="undefined"){return -1;}else{return B[K];}},useLegacyEvent:function(L,M){if(this.webkit&&("click"==M||"dblclick"==M)){var K=parseInt(this.webkit,10);if(!isNaN(K)&&K<418){return true;}}return false;},removeListener:function(L,K,T){var O,R,V;if(typeof L=="string"){L=this.getEl(L);}else{if(this._isValidCollection(L)){var U=true;for(O=L.length-1;O>-1;O--){U=(this.removeListener(L[O],K,T)&&U);}return U;}}if(!T||!T.call){return this.purgeElement(L,false,K);}if("unload"==K){for(O=J.length-1;O>-1;O--){V=J[O];if(V&&V[0]==L&&V[1]==K&&V[2]==T){J.splice(O,1);return true;}}return false;}var P=null;var Q=arguments[3];if("undefined"===typeof Q){Q=this._getCacheIndex(L,K,T);}if(Q>=0){P=I[Q];}if(!L||!P){return false;}if(this.useLegacyEvent(L,K)){var N=this.getLegacyIndex(L,K);var M=E[N];if(M){for(O=0,R=M.length;O<R;++O){V=M[O];if(V&&V[this.EL]==L&&V[this.TYPE]==K&&V[this.FN]==T){M.splice(O,1);break;}}}}else{try{this._simpleRemove(L,K,P[this.WFN],false);}catch(S){this.lastError=S;return false;}}delete I[Q][this.WFN];delete I[Q][this.FN];I.splice(Q,1);return true;},getTarget:function(M,L){var K=M.target||M.srcElement;return this.resolveTextNode(K);},resolveTextNode:function(L){try{if(L&&3==L.nodeType){return L.parentNode;}}catch(K){}return L;},getPageX:function(L){var K=L.pageX;if(!K&&0!==K){K=L.clientX||0;if(this.isIE){K+=this._getScrollLeft();}}return K;},getPageY:function(K){var L=K.pageY;if(!L&&0!==L){L=K.clientY||0;if(this.isIE){L+=this._getScrollTop();}}return L;
+},getXY:function(K){return[this.getPageX(K),this.getPageY(K)];},getRelatedTarget:function(L){var K=L.relatedTarget;if(!K){if(L.type=="mouseout"){K=L.toElement;}else{if(L.type=="mouseover"){K=L.fromElement;}}}return this.resolveTextNode(K);},getTime:function(M){if(!M.time){var L=new Date().getTime();try{M.time=L;}catch(K){this.lastError=K;return L;}}return M.time;},stopEvent:function(K){this.stopPropagation(K);this.preventDefault(K);},stopPropagation:function(K){if(K.stopPropagation){K.stopPropagation();}else{K.cancelBubble=true;}},preventDefault:function(K){if(K.preventDefault){K.preventDefault();}else{K.returnValue=false;}},getEvent:function(M,K){var L=M||window.event;if(!L){var N=this.getEvent.caller;while(N){L=N.arguments[0];if(L&&Event==L.constructor){break;}N=N.caller;}}return L;},getCharCode:function(L){var K=L.keyCode||L.charCode||0;if(YAHOO.env.ua.webkit&&(K in D)){K=D[K];}return K;},_getCacheIndex:function(O,P,N){for(var M=0,L=I.length;M<L;M=M+1){var K=I[M];if(K&&K[this.FN]==N&&K[this.EL]==O&&K[this.TYPE]==P){return M;}}return -1;},generateId:function(K){var L=K.id;if(!L){L="yuievtautoid-"+A;++A;K.id=L;}return L;},_isValidCollection:function(L){try{return(L&&typeof L!=="string"&&L.length&&!L.tagName&&!L.alert&&typeof L[0]!=="undefined");}catch(K){return false;}},elCache:{},getEl:function(K){return(typeof K==="string")?document.getElementById(K):K;},clearCache:function(){},DOMReadyEvent:new YAHOO.util.CustomEvent("DOMReady",this),_load:function(L){if(!H){H=true;var K=YAHOO.util.Event;K._ready();K._tryPreloadAttach();}},_ready:function(L){var K=YAHOO.util.Event;if(!K.DOMReady){K.DOMReady=true;K.DOMReadyEvent.fire();K._simpleRemove(document,"DOMContentLoaded",K._ready);}},_tryPreloadAttach:function(){if(F.length===0){C=0;clearInterval(this._interval);this._interval=null;return ;}if(this.locked){return ;}if(this.isIE){if(!this.DOMReady){this.startInterval();return ;}}this.locked=true;var Q=!H;if(!Q){Q=(C>0&&F.length>0);}var P=[];var R=function(T,U){var S=T;if(U.override){if(U.override===true){S=U.obj;}else{S=U.override;}}U.fn.call(S,U.obj);};var L,K,O,N,M=[];for(L=0,K=F.length;L<K;L=L+1){O=F[L];if(O){N=this.getEl(O.id);if(N){if(O.checkReady){if(H||N.nextSibling||!Q){M.push(O);F[L]=null;}}else{R(N,O);F[L]=null;}}else{P.push(O);}}}for(L=0,K=M.length;L<K;L=L+1){O=M[L];R(this.getEl(O.id),O);}C--;if(Q){for(L=F.length-1;L>-1;L--){O=F[L];if(!O||!O.id){F.splice(L,1);}}this.startInterval();}else{clearInterval(this._interval);this._interval=null;}this.locked=false;},purgeElement:function(O,P,R){var M=(YAHOO.lang.isString(O))?this.getEl(O):O;var Q=this.getListeners(M,R),N,K;if(Q){for(N=Q.length-1;N>-1;N--){var L=Q[N];this.removeListener(M,L.type,L.fn);}}if(P&&M&&M.childNodes){for(N=0,K=M.childNodes.length;N<K;++N){this.purgeElement(M.childNodes[N],P,R);}}},getListeners:function(M,K){var P=[],L;if(!K){L=[I,J];}else{if(K==="unload"){L=[J];}else{L=[I];}}var R=(YAHOO.lang.isString(M))?this.getEl(M):M;for(var O=0;O<L.length;O=O+1){var T=L[O];if(T){for(var Q=0,S=T.length;Q<S;++Q){var N=T[Q];if(N&&N[this.EL]===R&&(!K||K===N[this.TYPE])){P.push({type:N[this.TYPE],fn:N[this.FN],obj:N[this.OBJ],adjust:N[this.OVERRIDE],scope:N[this.ADJ_SCOPE],index:Q});}}}}return(P.length)?P:null;},_unload:function(Q){var K=YAHOO.util.Event,N,M,L,P,O,R=J.slice();for(N=0,P=J.length;N<P;++N){L=R[N];if(L){var S=window;if(L[K.ADJ_SCOPE]){if(L[K.ADJ_SCOPE]===true){S=L[K.UNLOAD_OBJ];}else{S=L[K.ADJ_SCOPE];}}L[K.FN].call(S,K.getEvent(Q,L[K.EL]),L[K.UNLOAD_OBJ]);R[N]=null;L=null;S=null;}}J=null;if(I){for(M=I.length-1;M>-1;M--){L=I[M];if(L){K.removeListener(L[K.EL],L[K.TYPE],L[K.FN],M);}}L=null;}G=null;K._simpleRemove(window,"unload",K._unload);},_getScrollLeft:function(){return this._getScroll()[1];},_getScrollTop:function(){return this._getScroll()[0];},_getScroll:function(){var K=document.documentElement,L=document.body;if(K&&(K.scrollTop||K.scrollLeft)){return[K.scrollTop,K.scrollLeft];}else{if(L){return[L.scrollTop,L.scrollLeft];}else{return[0,0];}}},regCE:function(){},_simpleAdd:function(){if(window.addEventListener){return function(M,N,L,K){M.addEventListener(N,L,(K));};}else{if(window.attachEvent){return function(M,N,L,K){M.attachEvent("on"+N,L);};}else{return function(){};}}}(),_simpleRemove:function(){if(window.removeEventListener){return function(M,N,L,K){M.removeEventListener(N,L,(K));};}else{if(window.detachEvent){return function(L,M,K){L.detachEvent("on"+M,K);};}else{return function(){};}}}()};}();(function(){var EU=YAHOO.util.Event;EU.on=EU.addListener;
+/* DOMReady: based on work by: Dean Edwards/John Resig/Matthias Miller */
+if(EU.isIE){YAHOO.util.Event.onDOMReady(YAHOO.util.Event._tryPreloadAttach,YAHOO.util.Event,true);var n=document.createElement("p");EU._dri=setInterval(function(){try{n.doScroll("left");clearInterval(EU._dri);EU._dri=null;EU._ready();n=null;}catch(ex){}},EU.POLL_INTERVAL);}else{if(EU.webkit&&EU.webkit<525){EU._dri=setInterval(function(){var rs=document.readyState;if("loaded"==rs||"complete"==rs){clearInterval(EU._dri);EU._dri=null;EU._ready();}},EU.POLL_INTERVAL);}else{EU._simpleAdd(document,"DOMContentLoaded",EU._ready);}}EU._simpleAdd(window,"load",EU._load);EU._simpleAdd(window,"unload",EU._unload);EU._tryPreloadAttach();})();}YAHOO.util.EventProvider=function(){};YAHOO.util.EventProvider.prototype={__yui_events:null,__yui_subscribers:null,subscribe:function(A,C,F,E){this.__yui_events=this.__yui_events||{};var D=this.__yui_events[A];if(D){D.subscribe(C,F,E);}else{this.__yui_subscribers=this.__yui_subscribers||{};var B=this.__yui_subscribers;if(!B[A]){B[A]=[];}B[A].push({fn:C,obj:F,override:E});}},unsubscribe:function(C,E,G){this.__yui_events=this.__yui_events||{};var A=this.__yui_events;if(C){var F=A[C];if(F){return F.unsubscribe(E,G);}}else{var B=true;for(var D in A){if(YAHOO.lang.hasOwnProperty(A,D)){B=B&&A[D].unsubscribe(E,G);}}return B;}return false;},unsubscribeAll:function(A){return this.unsubscribe(A);},createEvent:function(G,D){this.__yui_events=this.__yui_events||{};var A=D||{};var I=this.__yui_events;
+if(I[G]){}else{var H=A.scope||this;var E=(A.silent);var B=new YAHOO.util.CustomEvent(G,H,E,YAHOO.util.CustomEvent.FLAT);I[G]=B;if(A.onSubscribeCallback){B.subscribeEvent.subscribe(A.onSubscribeCallback);}this.__yui_subscribers=this.__yui_subscribers||{};var F=this.__yui_subscribers[G];if(F){for(var C=0;C<F.length;++C){B.subscribe(F[C].fn,F[C].obj,F[C].override);}}}return I[G];},fireEvent:function(E,D,A,C){this.__yui_events=this.__yui_events||{};var G=this.__yui_events[E];if(!G){return null;}var B=[];for(var F=1;F<arguments.length;++F){B.push(arguments[F]);}return G.fire.apply(G,B);},hasEvent:function(A){if(this.__yui_events){if(this.__yui_events[A]){return true;}}return false;}};YAHOO.util.KeyListener=function(A,F,B,C){if(!A){}else{if(!F){}else{if(!B){}}}if(!C){C=YAHOO.util.KeyListener.KEYDOWN;}var D=new YAHOO.util.CustomEvent("keyPressed");this.enabledEvent=new YAHOO.util.CustomEvent("enabled");this.disabledEvent=new YAHOO.util.CustomEvent("disabled");if(typeof A=="string"){A=document.getElementById(A);}if(typeof B=="function"){D.subscribe(B);}else{D.subscribe(B.fn,B.scope,B.correctScope);}function E(J,I){if(!F.shift){F.shift=false;}if(!F.alt){F.alt=false;}if(!F.ctrl){F.ctrl=false;}if(J.shiftKey==F.shift&&J.altKey==F.alt&&J.ctrlKey==F.ctrl){var G;if(F.keys instanceof Array){for(var H=0;H<F.keys.length;H++){G=F.keys[H];if(G==J.charCode){D.fire(J.charCode,J);break;}else{if(G==J.keyCode){D.fire(J.keyCode,J);break;}}}}else{G=F.keys;if(G==J.charCode){D.fire(J.charCode,J);}else{if(G==J.keyCode){D.fire(J.keyCode,J);}}}}}this.enable=function(){if(!this.enabled){YAHOO.util.Event.addListener(A,C,E);this.enabledEvent.fire(F);}this.enabled=true;};this.disable=function(){if(this.enabled){YAHOO.util.Event.removeListener(A,C,E);this.disabledEvent.fire(F);}this.enabled=false;};this.toString=function(){return"KeyListener ["+F.keys+"] "+A.tagName+(A.id?"["+A.id+"]":"");};};YAHOO.util.KeyListener.KEYDOWN="keydown";YAHOO.util.KeyListener.KEYUP="keyup";YAHOO.util.KeyListener.KEY={ALT:18,BACK_SPACE:8,CAPS_LOCK:20,CONTROL:17,DELETE:46,DOWN:40,END:35,ENTER:13,ESCAPE:27,HOME:36,LEFT:37,META:224,NUM_LOCK:144,PAGE_DOWN:34,PAGE_UP:33,PAUSE:19,PRINTSCREEN:44,RIGHT:39,SCROLL_LOCK:145,SHIFT:16,SPACE:32,TAB:9,UP:38};YAHOO.register("event",YAHOO.util.Event,{version:"2.5.2",build:"1076"});YAHOO.register("yuiloader-dom-event", YAHOO, {version: "2.5.2", build: "1076"});
+
+// logger/logger-min.js
+YAHOO.widget.LogMsg=function(A){this.msg=this.time=this.category=this.source=this.sourceDetail=null;if(A&&(A.constructor==Object)){for(var B in A){this[B]=A[B];}}};YAHOO.widget.LogWriter=function(A){if(!A){YAHOO.log("Could not instantiate LogWriter due to invalid source.","error","LogWriter");return ;}this._source=A;};YAHOO.widget.LogWriter.prototype.toString=function(){return"LogWriter "+this._sSource;};YAHOO.widget.LogWriter.prototype.log=function(A,B){YAHOO.widget.Logger.log(A,B,this._source);};YAHOO.widget.LogWriter.prototype.getSource=function(){return this._sSource;};YAHOO.widget.LogWriter.prototype.setSource=function(A){if(!A){YAHOO.log("Could not set source due to invalid source.","error",this.toString());return ;}else{this._sSource=A;}};YAHOO.widget.LogWriter.prototype._source=null;YAHOO.widget.LogReader=function(B,A){this._sName=YAHOO.widget.LogReader._index;YAHOO.widget.LogReader._index++;this._buffer=[];this._filterCheckboxes={};this._lastTime=YAHOO.widget.Logger.getStartTime();if(A&&(A.constructor==Object)){for(var C in A){this[C]=A[C];}}this._initContainerEl(B);if(!this._elContainer){YAHOO.log("Could not instantiate LogReader due to an invalid container element "+B,"error",this.toString());return ;}this._initHeaderEl();this._initConsoleEl();this._initFooterEl();this._initDragDrop();this._initCategories();this._initSources();YAHOO.widget.Logger.newLogEvent.subscribe(this._onNewLog,this);YAHOO.widget.Logger.logResetEvent.subscribe(this._onReset,this);YAHOO.widget.Logger.categoryCreateEvent.subscribe(this._onCategoryCreate,this);YAHOO.widget.Logger.sourceCreateEvent.subscribe(this._onSourceCreate,this);this._filterLogs();YAHOO.log("LogReader initialized",null,this.toString());};YAHOO.lang.augmentObject(YAHOO.widget.LogReader,{_index:0,ENTRY_TEMPLATE:(function(){var A=document.createElement("pre");YAHOO.util.Dom.addClass(A,"yui-log-entry");return A;})(),VERBOSE_TEMPLATE:"<span class='{category}'>{label}</span>{totalTime}ms (+{elapsedTime}) {localTime}:</p><p>{sourceAndDetail}</p><p>{message}</p>",BASIC_TEMPLATE:"<p><span class='{category}'>{label}</span>{totalTime}ms (+{elapsedTime}) {localTime}: {sourceAndDetail}: {message}</p>"});YAHOO.widget.LogReader.prototype={logReaderEnabled:true,width:null,height:null,top:null,left:null,right:null,bottom:null,fontSize:null,footerEnabled:true,verboseOutput:true,entryFormat:null,newestOnTop:true,outputBuffer:100,thresholdMax:500,thresholdMin:100,isCollapsed:false,isPaused:false,draggable:true,toString:function(){return"LogReader instance"+this._sName;},pause:function(){this.isPaused=true;this._btnPause.value="Resume";this._timeout=null;this.logReaderEnabled=false;},resume:function(){this.isPaused=false;this._btnPause.value="Pause";this.logReaderEnabled=true;this._printBuffer();},hide:function(){this._elContainer.style.display="none";},show:function(){this._elContainer.style.display="block";},collapse:function(){this._elConsole.style.display="none";if(this._elFt){this._elFt.style.display="none";}this._btnCollapse.value="Expand";this.isCollapsed=true;},expand:function(){this._elConsole.style.display="block";if(this._elFt){this._elFt.style.display="block";}this._btnCollapse.value="Collapse";this.isCollapsed=false;},getCheckbox:function(A){return this._filterCheckboxes[A];},getCategories:function(){return this._categoryFilters;},showCategory:function(B){var D=this._categoryFilters;if(D.indexOf){if(D.indexOf(B)>-1){return ;}}else{for(var A=0;A<D.length;A++){if(D[A]===B){return ;}}}this._categoryFilters.push(B);this._filterLogs();var C=this.getCheckbox(B);if(C){C.checked=true;}},hideCategory:function(B){var D=this._categoryFilters;for(var A=0;A<D.length;A++){if(B==D[A]){D.splice(A,1);break;}}this._filterLogs();var C=this.getCheckbox(B);if(C){C.checked=false;}},getSources:function(){return this._sourceFilters;},showSource:function(A){var D=this._sourceFilters;if(D.indexOf){if(D.indexOf(A)>-1){return ;}}else{for(var B=0;B<D.length;B++){if(A==D[B]){return ;}}}D.push(A);this._filterLogs();var C=this.getCheckbox(A);if(C){C.checked=true;}},hideSource:function(A){var D=this._sourceFilters;for(var B=0;B<D.length;B++){if(A==D[B]){D.splice(B,1);break;}}this._filterLogs();var C=this.getCheckbox(A);if(C){C.checked=false;}},clearConsole:function(){this._timeout=null;this._buffer=[];this._consoleMsgCount=0;var A=this._elConsole;A.innerHTML="";},setTitle:function(A){this._title.innerHTML=this.html2Text(A);},getLastTime:function(){return this._lastTime;},formatMsg:function(C){var B=YAHOO.widget.LogReader,A=this.entryFormat||(this.verboseOutput?B.VERBOSE_TEMPLATE:B.BASIC_TEMPLATE),D={category:C.category,label:C.category.substring(0,4).toUpperCase(),sourceAndDetail:C.sourceDetail?C.source+" "+C.sourceDetail:C.source,message:this.html2Text(C.msg||C.message||"")};if(C.time&&C.time.getTime){D.localTime=C.time.toLocaleTimeString?C.time.toLocaleTimeString():C.time.toString();D.elapsedTime=C.time.getTime()-this.getLastTime();D.totalTime=C.time.getTime()-YAHOO.widget.Logger.getStartTime();}var E=B.ENTRY_TEMPLATE.cloneNode(true);if(this.verboseOutput){E.className+=" yui-log-verbose";}E.innerHTML=YAHOO.lang.substitute(A,D);return E;},html2Text:function(A){if(A){A+="";return A.replace(/&/g,"&#38;").replace(/</g,"&#60;").replace(/>/g,"&#62;");}return"";},_sName:null,_buffer:null,_consoleMsgCount:0,_lastTime:null,_timeout:null,_filterCheckboxes:null,_categoryFilters:null,_sourceFilters:null,_elContainer:null,_elHd:null,_elCollapse:null,_btnCollapse:null,_title:null,_elConsole:null,_elFt:null,_elBtns:null,_elCategoryFilters:null,_elSourceFilters:null,_btnPause:null,_btnClear:null,_initContainerEl:function(B){B=YAHOO.util.Dom.get(B);if(B&&B.tagName&&(B.tagName.toLowerCase()=="div")){this._elContainer=B;YAHOO.util.Dom.addClass(this._elContainer,"yui-log");}else{this._elContainer=document.body.appendChild(document.createElement("div"));YAHOO.util.Dom.addClass(this._elContainer,"yui-log");YAHOO.util.Dom.addClass(this._elContainer,"yui-log-container");var A=this._elContainer.style;
+if(this.width){A.width=this.width;}if(this.right){A.right=this.right;}if(this.top){A.top=this.top;}if(this.left){A.left=this.left;A.right="auto";}if(this.bottom){A.bottom=this.bottom;A.top="auto";}if(this.fontSize){A.fontSize=this.fontSize;}if(navigator.userAgent.toLowerCase().indexOf("opera")!=-1){document.body.style+="";}}},_initHeaderEl:function(){var A=this;if(this._elHd){YAHOO.util.Event.purgeElement(this._elHd,true);this._elHd.innerHTML="";}this._elHd=this._elContainer.appendChild(document.createElement("div"));this._elHd.id="yui-log-hd"+this._sName;this._elHd.className="yui-log-hd";this._elCollapse=this._elHd.appendChild(document.createElement("div"));this._elCollapse.className="yui-log-btns";this._btnCollapse=document.createElement("input");this._btnCollapse.type="button";this._btnCollapse.className="yui-log-button";this._btnCollapse.value="Collapse";this._btnCollapse=this._elCollapse.appendChild(this._btnCollapse);YAHOO.util.Event.addListener(A._btnCollapse,"click",A._onClickCollapseBtn,A);this._title=this._elHd.appendChild(document.createElement("h4"));this._title.innerHTML="Logger Console";},_initConsoleEl:function(){if(this._elConsole){YAHOO.util.Event.purgeElement(this._elConsole,true);this._elConsole.innerHTML="";}this._elConsole=this._elContainer.appendChild(document.createElement("div"));this._elConsole.className="yui-log-bd";if(this.height){this._elConsole.style.height=this.height;}},_initFooterEl:function(){var A=this;if(this.footerEnabled){if(this._elFt){YAHOO.util.Event.purgeElement(this._elFt,true);this._elFt.innerHTML="";}this._elFt=this._elContainer.appendChild(document.createElement("div"));this._elFt.className="yui-log-ft";this._elBtns=this._elFt.appendChild(document.createElement("div"));this._elBtns.className="yui-log-btns";this._btnPause=document.createElement("input");this._btnPause.type="button";this._btnPause.className="yui-log-button";this._btnPause.value="Pause";this._btnPause=this._elBtns.appendChild(this._btnPause);YAHOO.util.Event.addListener(A._btnPause,"click",A._onClickPauseBtn,A);this._btnClear=document.createElement("input");this._btnClear.type="button";this._btnClear.className="yui-log-button";this._btnClear.value="Clear";this._btnClear=this._elBtns.appendChild(this._btnClear);YAHOO.util.Event.addListener(A._btnClear,"click",A._onClickClearBtn,A);this._elCategoryFilters=this._elFt.appendChild(document.createElement("div"));this._elCategoryFilters.className="yui-log-categoryfilters";this._elSourceFilters=this._elFt.appendChild(document.createElement("div"));this._elSourceFilters.className="yui-log-sourcefilters";}},_initDragDrop:function(){if(YAHOO.util.DD&&this.draggable&&this._elHd){var A=new YAHOO.util.DD(this._elContainer);A.setHandleElId(this._elHd.id);this._elHd.style.cursor="move";}},_initCategories:function(){this._categoryFilters=[];var C=YAHOO.widget.Logger.categories;for(var A=0;A<C.length;A++){var B=C[A];this._categoryFilters.push(B);if(this._elCategoryFilters){this._createCategoryCheckbox(B);}}},_initSources:function(){this._sourceFilters=[];var C=YAHOO.widget.Logger.sources;for(var B=0;B<C.length;B++){var A=C[B];this._sourceFilters.push(A);if(this._elSourceFilters){this._createSourceCheckbox(A);}}},_createCategoryCheckbox:function(B){var A=this;if(this._elFt){var E=this._elCategoryFilters;var D=E.appendChild(document.createElement("span"));D.className="yui-log-filtergrp";var C=document.createElement("input");C.id="yui-log-filter-"+B+this._sName;C.className="yui-log-filter-"+B;C.type="checkbox";C.category=B;C=D.appendChild(C);C.checked=true;YAHOO.util.Event.addListener(C,"click",A._onCheckCategory,A);var F=D.appendChild(document.createElement("label"));F.htmlFor=C.id;F.className=B;F.innerHTML=B;this._filterCheckboxes[B]=C;}},_createSourceCheckbox:function(A){var D=this;if(this._elFt){var F=this._elSourceFilters;var E=F.appendChild(document.createElement("span"));E.className="yui-log-filtergrp";var C=document.createElement("input");C.id="yui-log-filter"+A+this._sName;C.className="yui-log-filter"+A;C.type="checkbox";C.source=A;C=E.appendChild(C);C.checked=true;YAHOO.util.Event.addListener(C,"click",D._onCheckSource,D);var B=E.appendChild(document.createElement("label"));B.htmlFor=C.id;B.className=A;B.innerHTML=A;this._filterCheckboxes[A]=C;}},_filterLogs:function(){if(this._elConsole!==null){this.clearConsole();this._printToConsole(YAHOO.widget.Logger.getStack());}},_printBuffer:function(){this._timeout=null;if(this._elConsole!==null){var B=this.thresholdMax;B=(B&&!isNaN(B))?B:500;if(this._consoleMsgCount<B){var A=[];for(var C=0;C<this._buffer.length;C++){A[C]=this._buffer[C];}this._buffer=[];this._printToConsole(A);}else{this._filterLogs();}if(!this.newestOnTop){this._elConsole.scrollTop=this._elConsole.scrollHeight;}}},_printToConsole:function(I){var B=I.length,M=document.createDocumentFragment(),P=[],Q=this.thresholdMin,C=this._sourceFilters.length,N=this._categoryFilters.length,K,H,G,F,L;if(isNaN(Q)||(Q>this.thresholdMax)){Q=0;}K=(B>Q)?(B-Q):0;for(H=K;H<B;H++){var E=false;var J=false;var O=I[H];var A=O.source;var D=O.category;for(G=0;G<C;G++){if(A==this._sourceFilters[G]){J=true;break;}}if(J){for(G=0;G<N;G++){if(D==this._categoryFilters[G]){E=true;break;}}}if(E){F=this.formatMsg(O);if(typeof F==="string"){P[P.length]=F;}else{M.insertBefore(F,this.newestOnTop?M.firstChild||null:null);}this._consoleMsgCount++;this._lastTime=O.time.getTime();}}if(P.length){P.splice(0,0,this._elConsole.innerHTML);this._elConsole.innerHTML=this.newestOnTop?P.reverse().join(""):P.join("");}else{if(M.firstChild){this._elConsole.insertBefore(M,this.newestOnTop?this._elConsole.firstChild||null:null);}}},_onCategoryCreate:function(D,C,A){var B=C[0];A._categoryFilters.push(B);if(A._elFt){A._createCategoryCheckbox(B);}},_onSourceCreate:function(D,C,A){var B=C[0];A._sourceFilters.push(B);if(A._elFt){A._createSourceCheckbox(B);}},_onCheckCategory:function(A,B){var C=this.category;if(!this.checked){B.hideCategory(C);}else{B.showCategory(C);}},_onCheckSource:function(A,B){var C=this.source;
+if(!this.checked){B.hideSource(C);}else{B.showSource(C);}},_onClickCollapseBtn:function(A,B){if(!B.isCollapsed){B.collapse();}else{B.expand();}},_onClickPauseBtn:function(A,B){if(!B.isPaused){B.pause();}else{B.resume();}},_onClickClearBtn:function(A,B){B.clearConsole();},_onNewLog:function(D,C,A){var B=C[0];A._buffer.push(B);if(A.logReaderEnabled===true&&A._timeout===null){A._timeout=setTimeout(function(){A._printBuffer();},A.outputBuffer);}},_onReset:function(C,B,A){A._filterLogs();}};if(!YAHOO.widget.Logger){YAHOO.widget.Logger={loggerEnabled:true,_browserConsoleEnabled:false,categories:["info","warn","error","time","window"],sources:["global"],_stack:[],maxStackEntries:2500,_startTime:new Date().getTime(),_lastTime:null,_windowErrorsHandled:false,_origOnWindowError:null};YAHOO.widget.Logger.log=function(B,F,G){if(this.loggerEnabled){if(!F){F="info";}else{F=F.toLocaleLowerCase();if(this._isNewCategory(F)){this._createNewCategory(F);}}var C="global";var A=null;if(G){var D=G.indexOf(" ");if(D>0){C=G.substring(0,D);A=G.substring(D,G.length);}else{C=G;}if(this._isNewSource(C)){this._createNewSource(C);}}var H=new Date();var J=new YAHOO.widget.LogMsg({msg:B,time:H,category:F,source:C,sourceDetail:A});var I=this._stack;var E=this.maxStackEntries;if(E&&!isNaN(E)&&(I.length>=E)){I.shift();}I.push(J);this.newLogEvent.fire(J);if(this._browserConsoleEnabled){this._printToBrowserConsole(J);}return true;}else{return false;}};YAHOO.widget.Logger.reset=function(){this._stack=[];this._startTime=new Date().getTime();this.loggerEnabled=true;this.log("Logger reset");this.logResetEvent.fire();};YAHOO.widget.Logger.getStack=function(){return this._stack;};YAHOO.widget.Logger.getStartTime=function(){return this._startTime;};YAHOO.widget.Logger.disableBrowserConsole=function(){YAHOO.log("Logger output to the function console.log() has been disabled.");this._browserConsoleEnabled=false;};YAHOO.widget.Logger.enableBrowserConsole=function(){this._browserConsoleEnabled=true;YAHOO.log("Logger output to the function console.log() has been enabled.");};YAHOO.widget.Logger.handleWindowErrors=function(){if(!YAHOO.widget.Logger._windowErrorsHandled){if(window.error){YAHOO.widget.Logger._origOnWindowError=window.onerror;}window.onerror=YAHOO.widget.Logger._onWindowError;YAHOO.widget.Logger._windowErrorsHandled=true;YAHOO.log("Logger handling of window.onerror has been enabled.");}else{YAHOO.log("Logger handling of window.onerror had already been enabled.");}};YAHOO.widget.Logger.unhandleWindowErrors=function(){if(YAHOO.widget.Logger._windowErrorsHandled){if(YAHOO.widget.Logger._origOnWindowError){window.onerror=YAHOO.widget.Logger._origOnWindowError;YAHOO.widget.Logger._origOnWindowError=null;}else{window.onerror=null;}YAHOO.widget.Logger._windowErrorsHandled=false;YAHOO.log("Logger handling of window.onerror has been disabled.");}else{YAHOO.log("Logger handling of window.onerror had already been disabled.");}};YAHOO.widget.Logger.categoryCreateEvent=new YAHOO.util.CustomEvent("categoryCreate",this,true);YAHOO.widget.Logger.sourceCreateEvent=new YAHOO.util.CustomEvent("sourceCreate",this,true);YAHOO.widget.Logger.newLogEvent=new YAHOO.util.CustomEvent("newLog",this,true);YAHOO.widget.Logger.logResetEvent=new YAHOO.util.CustomEvent("logReset",this,true);YAHOO.widget.Logger._createNewCategory=function(A){this.categories.push(A);this.categoryCreateEvent.fire(A);};YAHOO.widget.Logger._isNewCategory=function(B){for(var A=0;A<this.categories.length;A++){if(B==this.categories[A]){return false;}}return true;};YAHOO.widget.Logger._createNewSource=function(A){this.sources.push(A);this.sourceCreateEvent.fire(A);};YAHOO.widget.Logger._isNewSource=function(A){if(A){for(var B=0;B<this.sources.length;B++){if(A==this.sources[B]){return false;}}return true;}};YAHOO.widget.Logger._printToBrowserConsole=function(C){if(window.console&&console.log){var E=C.category;var D=C.category.substring(0,4).toUpperCase();var G=C.time;var F;if(G.toLocaleTimeString){F=G.toLocaleTimeString();}else{F=G.toString();}var H=G.getTime();var B=(YAHOO.widget.Logger._lastTime)?(H-YAHOO.widget.Logger._lastTime):0;YAHOO.widget.Logger._lastTime=H;var A=F+" ("+B+"ms): "+C.source+": ";console.log(A,C.msg);}};YAHOO.widget.Logger._onWindowError=function(A,C,B){try{YAHOO.widget.Logger.log(A+" ("+C+", line "+B+")","window");if(YAHOO.widget.Logger._origOnWindowError){YAHOO.widget.Logger._origOnWindowError();}}catch(D){return false;}};YAHOO.widget.Logger.log("Logger initialized");}YAHOO.register("logger",YAHOO.widget.Logger,{version:"2.5.2",build:"1076"});
+
+// yuitest/yuitest-min.js
+YAHOO.namespace("tool");YAHOO.tool.TestCase=function(A){this._should={};for(var B in A){this[B]=A[B];}if(!YAHOO.lang.isString(this.name)){this.name=YAHOO.util.Dom.generateId(null,"testCase");}};YAHOO.tool.TestCase.prototype={resume:function(A){YAHOO.tool.TestRunner.resume(A);},wait:function(B,A){throw new YAHOO.tool.TestCase.Wait(B,A);},setUp:function(){},tearDown:function(){}};YAHOO.tool.TestCase.Wait=function(B,A){this.segment=(YAHOO.lang.isFunction(B)?B:null);this.delay=(YAHOO.lang.isNumber(A)?A:0);};YAHOO.namespace("tool");YAHOO.tool.TestSuite=function(A){this.name="";this.items=[];if(YAHOO.lang.isString(A)){this.name=A;}else{if(YAHOO.lang.isObject(A)){YAHOO.lang.augmentObject(this,A,true);}}if(this.name===""){this.name=YAHOO.util.Dom.generateId(null,"testSuite");}};YAHOO.tool.TestSuite.prototype={add:function(A){if(A instanceof YAHOO.tool.TestSuite||A instanceof YAHOO.tool.TestCase){this.items.push(A);}},setUp:function(){},tearDown:function(){}};YAHOO.namespace("tool");YAHOO.tool.TestRunner=(function(){function B(C){this.testObject=C;this.firstChild=null;this.lastChild=null;this.parent=null;this.next=null;this.results={passed:0,failed:0,total:0,ignored:0};if(C instanceof YAHOO.tool.TestSuite){this.results.type="testsuite";this.results.name=C.name;}else{if(C instanceof YAHOO.tool.TestCase){this.results.type="testcase";this.results.name=C.name;}}}B.prototype={appendChild:function(C){var D=new B(C);if(this.firstChild===null){this.firstChild=this.lastChild=D;}else{this.lastChild.next=D;this.lastChild=D;}D.parent=this;return D;}};function A(){A.superclass.constructor.apply(this,arguments);this.masterSuite=new YAHOO.tool.TestSuite("YUI Test Results");this._cur=null;this._root=null;var D=[this.TEST_CASE_BEGIN_EVENT,this.TEST_CASE_COMPLETE_EVENT,this.TEST_SUITE_BEGIN_EVENT,this.TEST_SUITE_COMPLETE_EVENT,this.TEST_PASS_EVENT,this.TEST_FAIL_EVENT,this.TEST_IGNORE_EVENT,this.COMPLETE_EVENT,this.BEGIN_EVENT];for(var C=0;C<D.length;C++){this.createEvent(D[C],{scope:this});}}YAHOO.lang.extend(A,YAHOO.util.EventProvider,{TEST_CASE_BEGIN_EVENT:"testcasebegin",TEST_CASE_COMPLETE_EVENT:"testcasecomplete",TEST_SUITE_BEGIN_EVENT:"testsuitebegin",TEST_SUITE_COMPLETE_EVENT:"testsuitecomplete",TEST_PASS_EVENT:"pass",TEST_FAIL_EVENT:"fail",TEST_IGNORE_EVENT:"ignore",COMPLETE_EVENT:"complete",BEGIN_EVENT:"begin",_addTestCaseToTestTree:function(C,D){var E=C.appendChild(D);for(var F in D){if(F.indexOf("test")===0&&YAHOO.lang.isFunction(D[F])){E.appendChild(F);}}},_addTestSuiteToTestTree:function(C,F){var E=C.appendChild(F);for(var D=0;D<F.items.length;D++){if(F.items[D] instanceof YAHOO.tool.TestSuite){this._addTestSuiteToTestTree(E,F.items[D]);}else{if(F.items[D] instanceof YAHOO.tool.TestCase){this._addTestCaseToTestTree(E,F.items[D]);}}}},_buildTestTree:function(){this._root=new B(this.masterSuite);this._cur=this._root;for(var C=0;C<this.masterSuite.items.length;C++){if(this.masterSuite.items[C] instanceof YAHOO.tool.TestSuite){this._addTestSuiteToTestTree(this._root,this.masterSuite.items[C]);}else{if(this.masterSuite.items[C] instanceof YAHOO.tool.TestCase){this._addTestCaseToTestTree(this._root,this.masterSuite.items[C]);}}}},_handleTestObjectComplete:function(C){if(YAHOO.lang.isObject(C.testObject)){C.parent.results.passed+=C.results.passed;C.parent.results.failed+=C.results.failed;C.parent.results.total+=C.results.total;C.parent.results.ignored+=C.results.ignored;C.parent.results[C.testObject.name]=C.results;if(C.testObject instanceof YAHOO.tool.TestSuite){C.testObject.tearDown();this.fireEvent(this.TEST_SUITE_COMPLETE_EVENT,{testSuite:C.testObject,results:C.results});}else{if(C.testObject instanceof YAHOO.tool.TestCase){this.fireEvent(this.TEST_CASE_COMPLETE_EVENT,{testCase:C.testObject,results:C.results});}}}},_next:function(){if(this._cur.firstChild){this._cur=this._cur.firstChild;}else{if(this._cur.next){this._cur=this._cur.next;}else{while(this._cur&&!this._cur.next&&this._cur!==this._root){this._handleTestObjectComplete(this._cur);this._cur=this._cur.parent;}if(this._cur==this._root){this._cur.results.type="report";this._cur.results.timestamp=(new Date()).toLocaleString();this.fireEvent(this.COMPLETE_EVENT,{results:this._cur.results});this._cur=null;}else{this._handleTestObjectComplete(this._cur);this._cur=this._cur.next;}}}return this._cur;},_run:function(){var E=false;var D=this._next();if(D!==null){var C=D.testObject;if(YAHOO.lang.isObject(C)){if(C instanceof YAHOO.tool.TestSuite){this.fireEvent(this.TEST_SUITE_BEGIN_EVENT,{testSuite:C});C.setUp();}else{if(C instanceof YAHOO.tool.TestCase){this.fireEvent(this.TEST_CASE_BEGIN_EVENT,{testCase:C});}}if(typeof setTimeout!="undefined"){setTimeout(function(){YAHOO.tool.TestRunner._run();},0);}else{this._run();}}else{this._runTest(D);}}},_resumeTest:function(G){var C=this._cur;var H=C.testObject;var E=C.parent.testObject;var K=(E._should.fail||{})[H];var D=(E._should.error||{})[H];var F=false;var I=null;try{G.apply(E);if(K){I=new YAHOO.util.ShouldFail();F=true;}else{if(D){I=new YAHOO.util.ShouldError();F=true;}}}catch(J){if(J instanceof YAHOO.util.AssertionError){if(!K){I=J;F=true;}}else{if(J instanceof YAHOO.tool.TestCase.Wait){if(YAHOO.lang.isFunction(J.segment)){if(YAHOO.lang.isNumber(J.delay)){if(typeof setTimeout!="undefined"){setTimeout(function(){YAHOO.tool.TestRunner._resumeTest(J.segment);},J.delay);}else{throw new Error("Asynchronous tests not supported in this environment.");}}}return ;}else{if(!D){I=new YAHOO.util.UnexpectedError(J);F=true;}else{if(YAHOO.lang.isString(D)){if(J.message!=D){I=new YAHOO.util.UnexpectedError(J);F=true;}}else{if(YAHOO.lang.isFunction(D)){if(!(J instanceof D)){I=new YAHOO.util.UnexpectedError(J);F=true;}}else{if(YAHOO.lang.isObject(D)){if(!(J instanceof D.constructor)||J.message!=D.message){I=new YAHOO.util.UnexpectedError(J);F=true;}}}}}}}}if(F){this.fireEvent(this.TEST_FAIL_EVENT,{testCase:E,testName:H,error:I});}else{this.fireEvent(this.TEST_PASS_EVENT,{testCase:E,testName:H});}E.tearDown();C.parent.results[H]={result:F?"fail":"pass",message:I?I.getMessage():"Test passed",type:"test",name:H};
+if(F){C.parent.results.failed++;}else{C.parent.results.passed++;}C.parent.results.total++;if(typeof setTimeout!="undefined"){setTimeout(function(){YAHOO.tool.TestRunner._run();},0);}else{this._run();}},_runTest:function(F){var C=F.testObject;var D=F.parent.testObject;var G=D[C];var E=(D._should.ignore||{})[C];if(E){F.parent.results[C]={result:"ignore",message:"Test ignored",type:"test",name:C};F.parent.results.ignored++;F.parent.results.total++;this.fireEvent(this.TEST_IGNORE_EVENT,{testCase:D,testName:C});if(typeof setTimeout!="undefined"){setTimeout(function(){YAHOO.tool.TestRunner._run();},0);}else{this._run();}}else{D.setUp();this._resumeTest(G);}},fireEvent:function(C,D){D=D||{};D.type=C;A.superclass.fireEvent.call(this,C,D);},add:function(C){this.masterSuite.add(C);},clear:function(){this.masterSuite.items=[];},resume:function(C){this._resumeTest(C||function(){});},run:function(C){var D=YAHOO.tool.TestRunner;D._buildTestTree();D.fireEvent(D.BEGIN_EVENT);D._run();}});return new A();})();YAHOO.namespace("util");YAHOO.util.Assert={_formatMessage:function(B,A){var C=B;if(YAHOO.lang.isString(B)&&B.length>0){return YAHOO.lang.substitute(B,{message:A});}else{return A;}},fail:function(A){throw new YAHOO.util.AssertionError(this._formatMessage(A,"Test force-failed."));},areEqual:function(B,C,A){if(B!=C){throw new YAHOO.util.ComparisonFailure(this._formatMessage(A,"Values should be equal."),B,C);}},areNotEqual:function(A,C,B){if(A==C){throw new YAHOO.util.UnexpectedValue(this._formatMessage(B,"Values should not be equal."),A);}},areNotSame:function(A,C,B){if(A===C){throw new YAHOO.util.UnexpectedValue(this._formatMessage(B,"Values should not be the same."),A);}},areSame:function(B,C,A){if(B!==C){throw new YAHOO.util.ComparisonFailure(this._formatMessage(A,"Values should be the same."),B,C);}},isFalse:function(B,A){if(false!==B){throw new YAHOO.util.ComparisonFailure(this._formatMessage(A,"Value should be false."),false,B);}},isTrue:function(B,A){if(true!==B){throw new YAHOO.util.ComparisonFailure(this._formatMessage(A,"Value should be true."),true,B);}},isNaN:function(B,A){if(!isNaN(B)){throw new YAHOO.util.ComparisonFailure(this._formatMessage(A,"Value should be NaN."),NaN,B);}},isNotNaN:function(B,A){if(isNaN(B)){throw new YAHOO.util.UnexpectedValue(this._formatMessage(A,"Values should not be NaN."),NaN);}},isNotNull:function(B,A){if(YAHOO.lang.isNull(B)){throw new YAHOO.util.UnexpectedValue(this._formatMessage(A,"Values should not be null."),null);}},isNotUndefined:function(B,A){if(YAHOO.lang.isUndefined(B)){throw new YAHOO.util.UnexpectedValue(this._formatMessage(A,"Value should not be undefined."),undefined);}},isNull:function(B,A){if(!YAHOO.lang.isNull(B)){throw new YAHOO.util.ComparisonFailure(this._formatMessage(A,"Value should be null."),null,B);}},isUndefined:function(B,A){if(!YAHOO.lang.isUndefined(B)){throw new YAHOO.util.ComparisonFailure(this._formatMessage(A,"Value should be undefined."),undefined,B);}},isArray:function(B,A){if(!YAHOO.lang.isArray(B)){throw new YAHOO.util.UnexpectedValue(this._formatMessage(A,"Value should be an array."),B);}},isBoolean:function(B,A){if(!YAHOO.lang.isBoolean(B)){throw new YAHOO.util.UnexpectedValue(this._formatMessage(A,"Value should be a Boolean."),B);}},isFunction:function(B,A){if(!YAHOO.lang.isFunction(B)){throw new YAHOO.util.UnexpectedValue(this._formatMessage(A,"Value should be a function."),B);}},isInstanceOf:function(B,C,A){if(!(C instanceof B)){throw new YAHOO.util.ComparisonFailure(this._formatMessage(A,"Value isn't an instance of expected type."),B,C);}},isNumber:function(B,A){if(!YAHOO.lang.isNumber(B)){throw new YAHOO.util.UnexpectedValue(this._formatMessage(A,"Value should be a number."),B);}},isObject:function(B,A){if(!YAHOO.lang.isObject(B)){throw new YAHOO.util.UnexpectedValue(this._formatMessage(A,"Value should be an object."),B);}},isString:function(B,A){if(!YAHOO.lang.isString(B)){throw new YAHOO.util.UnexpectedValue(this._formatMessage(A,"Value should be a string."),B);}},isTypeOf:function(A,C,B){if(typeof C!=A){throw new YAHOO.util.ComparisonFailure(this._formatMessage(B,"Value should be of type "+expected+"."),expected,typeof actual);}}};YAHOO.util.AssertionError=function(A){arguments.callee.superclass.constructor.call(this,A);this.message=A;this.name="AssertionError";};YAHOO.lang.extend(YAHOO.util.AssertionError,Error,{getMessage:function(){return this.message;},toString:function(){return this.name+": "+this.getMessage();},valueOf:function(){return this.toString();}});YAHOO.util.ComparisonFailure=function(B,A,C){arguments.callee.superclass.constructor.call(this,B);this.expected=A;this.actual=C;this.name="ComparisonFailure";};YAHOO.lang.extend(YAHOO.util.ComparisonFailure,YAHOO.util.AssertionError,{getMessage:function(){return this.message+"\nExpected: "+this.expected+" ("+(typeof this.expected)+")\nActual:"+this.actual+" ("+(typeof this.actual)+")";}});YAHOO.util.UnexpectedValue=function(B,A){arguments.callee.superclass.constructor.call(this,B);this.unexpected=A;this.name="UnexpectedValue";};YAHOO.lang.extend(YAHOO.util.UnexpectedValue,YAHOO.util.AssertionError,{getMessage:function(){return this.message+"\nUnexpected: "+this.unexpected+" ("+(typeof this.unexpected)+") ";}});YAHOO.util.ShouldFail=function(A){arguments.callee.superclass.constructor.call(this,A||"This test should fail but didn't.");this.name="ShouldFail";};YAHOO.lang.extend(YAHOO.util.ShouldFail,YAHOO.util.AssertionError);YAHOO.util.ShouldError=function(A){arguments.callee.superclass.constructor.call(this,A||"This test should have thrown an error but didn't.");this.name="ShouldError";};YAHOO.lang.extend(YAHOO.util.ShouldError,YAHOO.util.AssertionError);YAHOO.util.UnexpectedError=function(A){arguments.callee.superclass.constructor.call(this,"Unexpected error: "+A.message);this.cause=A;this.name="UnexpectedError";this.stack=A.stack;};YAHOO.lang.extend(YAHOO.util.UnexpectedError,YAHOO.util.AssertionError);YAHOO.util.ArrayAssert={contains:function(E,D,B){var C=false;
+var F=YAHOO.util.Assert;for(var A=0;A<D.length&&!C;A++){if(D[A]===E){C=true;}}if(!C){F.fail(F._formatMessage(B,"Value "+E+" ("+(typeof E)+") not found in array ["+D+"]."));}},containsItems:function(C,D,B){for(var A=0;A<C.length;A++){this.contains(C[A],D,B);}},containsMatch:function(E,D,B){if(typeof E!="function"){throw new TypeError("ArrayAssert.containsMatch(): First argument must be a function.");}var C=false;var F=YAHOO.util.Assert;for(var A=0;A<D.length&&!C;A++){if(E(D[A])){C=true;}}if(!C){F.fail(F._formatMessage(B,"No match found in array ["+D+"]."));}},doesNotContain:function(E,D,B){var C=false;var F=YAHOO.util.Assert;for(var A=0;A<D.length&&!C;A++){if(D[A]===E){C=true;}}if(C){F.fail(F._formatMessage(B,"Value found in array ["+D+"]."));}},doesNotContainItems:function(C,D,B){for(var A=0;A<C.length;A++){this.doesNotContain(C[A],D,B);}},doesNotContainMatch:function(E,D,B){if(typeof E!="function"){throw new TypeError("ArrayAssert.doesNotContainMatch(): First argument must be a function.");}var C=false;var F=YAHOO.util.Assert;for(var A=0;A<D.length&&!C;A++){if(E(D[A])){C=true;}}if(C){F.fail(F._formatMessage(B,"Value found in array ["+D+"]."));}},indexOf:function(E,D,A,C){for(var B=0;B<D.length;B++){if(D[B]===E){YAHOO.util.Assert.areEqual(A,B,C||"Value exists at index "+B+" but should be at index "+A+".");return ;}}var F=YAHOO.util.Assert;F.fail(F._formatMessage(C,"Value doesn't exist in array ["+D+"]."));},itemsAreEqual:function(D,F,C){var A=Math.max(D.length,F.length);var E=YAHOO.util.Assert;for(var B=0;B<A;B++){E.areEqual(D[B],F[B],E._formatMessage(C,"Values in position "+B+" are not equal."));}},itemsAreEquivalent:function(E,F,B,D){if(typeof B!="function"){throw new TypeError("ArrayAssert.itemsAreEquivalent(): Third argument must be a function.");}var A=Math.max(E.length,F.length);for(var C=0;C<A;C++){if(!B(E[C],F[C])){throw new YAHOO.util.ComparisonFailure(YAHOO.util.Assert._formatMessage(D,"Values in position "+C+" are not equivalent."),E[C],F[C]);}}},isEmpty:function(C,A){if(C.length>0){var B=YAHOO.util.Assert;B.fail(B._formatMessage(A,"Array should be empty."));}},isNotEmpty:function(C,A){if(C.length===0){var B=YAHOO.util.Assert;B.fail(B._formatMessage(A,"Array should not be empty."));}},itemsAreSame:function(D,F,C){var A=Math.max(D.length,F.length);var E=YAHOO.util.Assert;for(var B=0;B<A;B++){E.areSame(D[B],F[B],E._formatMessage(C,"Values in position "+B+" are not the same."));}},lastIndexOf:function(E,D,A,C){var F=YAHOO.util.Assert;for(var B=D.length;B>=0;B--){if(D[B]===E){F.areEqual(A,B,F._formatMessage(C,"Value exists at index "+B+" but should be at index "+A+"."));return ;}}F.fail(F._formatMessage(C,"Value doesn't exist in array."));}};YAHOO.namespace("util");YAHOO.util.ObjectAssert={propertiesAreEqual:function(D,G,C){var F=YAHOO.util.Assert;var B=[];for(var E in D){B.push(E);}for(var A=0;A<B.length;A++){F.isNotUndefined(G[B[A]],F._formatMessage(C,"Property '"+B[A]+"' expected."));}},hasProperty:function(A,B,C){if(!(A in B)){var D=YAHOO.util.Assert;D.fail(D._formatMessage(C,"Property '"+A+"' not found on object."));}},hasOwnProperty:function(A,B,C){if(!YAHOO.lang.hasOwnProperty(B,A)){var D=YAHOO.util.Assert;D.fail(D._formatMessage(C,"Property '"+A+"' not found on object instance."));}}};YAHOO.util.DateAssert={datesAreEqual:function(B,D,A){if(B instanceof Date&&D instanceof Date){var C=YAHOO.util.Assert;C.areEqual(B.getFullYear(),D.getFullYear(),C._formatMessage(A,"Years should be equal."));C.areEqual(B.getMonth(),D.getMonth(),C._formatMessage(A,"Months should be equal."));C.areEqual(B.getDate(),D.getDate(),C._formatMessage(A,"Day of month should be equal."));}else{throw new TypeError("DateAssert.datesAreEqual(): Expected and actual values must be Date objects.");}},timesAreEqual:function(B,D,A){if(B instanceof Date&&D instanceof Date){var C=YAHOO.util.Assert;C.areEqual(B.getHours(),D.getHours(),C._formatMessage(A,"Hours should be equal."));C.areEqual(B.getMinutes(),D.getMinutes(),C._formatMessage(A,"Minutes should be equal."));C.areEqual(B.getSeconds(),D.getSeconds(),C._formatMessage(A,"Seconds should be equal."));}else{throw new TypeError("DateAssert.timesAreEqual(): Expected and actual values must be Date objects.");}}};YAHOO.namespace("util");YAHOO.util.UserAction={simulateKeyEvent:function(F,J,E,C,L,B,A,K,H,N,M){F=YAHOO.util.Dom.get(F);if(!F){throw new Error("simulateKeyEvent(): Invalid target.");}if(YAHOO.lang.isString(J)){J=J.toLowerCase();switch(J){case"keyup":case"keydown":case"keypress":break;case"textevent":J="keypress";break;default:throw new Error("simulateKeyEvent(): Event type '"+J+"' not supported.");}}else{throw new Error("simulateKeyEvent(): Event type must be a string.");}if(!YAHOO.lang.isBoolean(E)){E=true;}if(!YAHOO.lang.isBoolean(C)){C=true;}if(!YAHOO.lang.isObject(L)){L=window;}if(!YAHOO.lang.isBoolean(B)){B=false;}if(!YAHOO.lang.isBoolean(A)){A=false;}if(!YAHOO.lang.isBoolean(K)){K=false;}if(!YAHOO.lang.isBoolean(H)){H=false;}if(!YAHOO.lang.isNumber(N)){N=0;}if(!YAHOO.lang.isNumber(M)){M=0;}var I=null;if(YAHOO.lang.isFunction(document.createEvent)){try{I=document.createEvent("KeyEvents");I.initKeyEvent(J,E,C,L,B,A,K,H,N,M);}catch(G){try{I=document.createEvent("Events");}catch(D){I=document.createEvent("UIEvents");}finally{I.initEvent(J,E,C);I.view=L;I.altKey=A;I.ctrlKey=B;I.shiftKey=K;I.metaKey=H;I.keyCode=N;I.charCode=M;}}F.dispatchEvent(I);}else{if(YAHOO.lang.isObject(document.createEventObject)){I=document.createEventObject();I.bubbles=E;I.cancelable=C;I.view=L;I.ctrlKey=B;I.altKey=A;I.shiftKey=K;I.metaKey=H;I.keyCode=(M>0)?M:N;F.fireEvent("on"+J,I);}else{throw new Error("simulateKeyEvent(): No event simulation framework present.");}}},simulateMouseEvent:function(K,P,H,E,Q,J,G,F,D,B,C,A,O,M,I,L){K=YAHOO.util.Dom.get(K);if(!K){throw new Error("simulateMouseEvent(): Invalid target.");}if(YAHOO.lang.isString(P)){P=P.toLowerCase();switch(P){case"mouseover":case"mouseout":case"mousedown":case"mouseup":case"click":case"dblclick":case"mousemove":break;default:throw new Error("simulateMouseEvent(): Event type '"+P+"' not supported.");
+}}else{throw new Error("simulateMouseEvent(): Event type must be a string.");}if(!YAHOO.lang.isBoolean(H)){H=true;}if(!YAHOO.lang.isBoolean(E)){E=(P!="mousemove");}if(!YAHOO.lang.isObject(Q)){Q=window;}if(!YAHOO.lang.isNumber(J)){J=1;}if(!YAHOO.lang.isNumber(G)){G=0;}if(!YAHOO.lang.isNumber(F)){F=0;}if(!YAHOO.lang.isNumber(D)){D=0;}if(!YAHOO.lang.isNumber(B)){B=0;}if(!YAHOO.lang.isBoolean(C)){C=false;}if(!YAHOO.lang.isBoolean(A)){A=false;}if(!YAHOO.lang.isBoolean(O)){O=false;}if(!YAHOO.lang.isBoolean(M)){M=false;}if(!YAHOO.lang.isNumber(I)){I=0;}var N=null;if(YAHOO.lang.isFunction(document.createEvent)){N=document.createEvent("MouseEvents");if(N.initMouseEvent){N.initMouseEvent(P,H,E,Q,J,G,F,D,B,C,A,O,M,I,L);}else{N=document.createEvent("UIEvents");N.initEvent(P,H,E);N.view=Q;N.detail=J;N.screenX=G;N.screenY=F;N.clientX=D;N.clientY=B;N.ctrlKey=C;N.altKey=A;N.metaKey=M;N.shiftKey=O;N.button=I;N.relatedTarget=L;}if(L&&!N.relatedTarget){if(P=="mouseout"){N.toElement=L;}else{if(P=="mouseover"){N.fromElement=L;}}}K.dispatchEvent(N);}else{if(YAHOO.lang.isObject(document.createEventObject)){N=document.createEventObject();N.bubbles=H;N.cancelable=E;N.view=Q;N.detail=J;N.screenX=G;N.screenY=F;N.clientX=D;N.clientY=B;N.ctrlKey=C;N.altKey=A;N.metaKey=M;N.shiftKey=O;switch(I){case 0:N.button=1;break;case 1:N.button=4;break;case 2:break;default:N.button=0;}N.relatedTarget=L;K.fireEvent("on"+P,N);}else{throw new Error("simulateMouseEvent(): No event simulation framework present.");}}},fireMouseEvent:function(C,B,A){A=A||{};this.simulateMouseEvent(C,B,A.bubbles,A.cancelable,A.view,A.detail,A.screenX,A.screenY,A.clientX,A.clientY,A.ctrlKey,A.altKey,A.shiftKey,A.metaKey,A.button,A.relatedTarget);},click:function(B,A){this.fireMouseEvent(B,"click",A);},dblclick:function(B,A){this.fireMouseEvent(B,"dblclick",A);},mousedown:function(B,A){this.fireMouseEvent(B,"mousedown",A);},mousemove:function(B,A){this.fireMouseEvent(B,"mousemove",A);},mouseout:function(B,A){this.fireMouseEvent(B,"mouseout",A);},mouseover:function(B,A){this.fireMouseEvent(B,"mouseover",A);},mouseup:function(B,A){this.fireMouseEvent(B,"mouseup",A);},fireKeyEvent:function(B,C,A){A=A||{};this.simulateKeyEvent(C,B,A.bubbles,A.cancelable,A.view,A.ctrlKey,A.altKey,A.shiftKey,A.metaKey,A.keyCode,A.charCode);},keydown:function(B,A){this.fireKeyEvent("keydown",B,A);},keypress:function(B,A){this.fireKeyEvent("keypress",B,A);},keyup:function(B,A){this.fireKeyEvent("keyup",B,A);}};YAHOO.namespace("tool");YAHOO.tool.TestManager={TEST_PAGE_BEGIN_EVENT:"testpagebegin",TEST_PAGE_COMPLETE_EVENT:"testpagecomplete",TEST_MANAGER_BEGIN_EVENT:"testmanagerbegin",TEST_MANAGER_COMPLETE_EVENT:"testmanagercomplete",_curPage:null,_frame:null,_logger:null,_timeoutId:0,_pages:[],_results:null,_handleTestRunnerComplete:function(A){this.fireEvent(this.TEST_PAGE_COMPLETE_EVENT,{page:this._curPage,results:A.results});this._processResults(this._curPage,A.results);this._logger.clearTestRunner();if(this._pages.length){this._timeoutId=setTimeout(function(){YAHOO.tool.TestManager._run();},1000);}else{this.fireEvent(this.TEST_MANAGER_COMPLETE_EVENT,this._results);}},_processResults:function(C,A){var B=this._results;B.passed+=A.passed;B.failed+=A.failed;B.ignored+=A.ignored;B.total+=A.total;if(A.failed){B.failedPages.push(C);}else{B.passedPages.push(C);}A.name=C;A.type="page";B[C]=A;},_run:function(){this._curPage=this._pages.shift();this.fireEvent(this.TEST_PAGE_BEGIN_EVENT,this._curPage);this._frame.location.replace(this._curPage);},load:function(){if(parent.YAHOO.tool.TestManager!==this){parent.YAHOO.tool.TestManager.load();}else{if(this._frame){var A=this._frame.YAHOO.tool.TestRunner;this._logger.setTestRunner(A);A.subscribe(A.COMPLETE_EVENT,this._handleTestRunnerComplete,this,true);A.run();}}},setPages:function(A){this._pages=A;},start:function(){if(!this._initialized){this.createEvent(this.TEST_PAGE_BEGIN_EVENT);this.createEvent(this.TEST_PAGE_COMPLETE_EVENT);this.createEvent(this.TEST_MANAGER_BEGIN_EVENT);this.createEvent(this.TEST_MANAGER_COMPLETE_EVENT);if(!this._frame){var A=document.createElement("iframe");A.style.visibility="hidden";A.style.position="absolute";document.body.appendChild(A);this._frame=A.contentWindow||A.contentDocument.ownerWindow;}if(!this._logger){this._logger=new YAHOO.tool.TestLogger();}this._initialized=true;}this._results={passed:0,failed:0,ignored:0,total:0,type:"report",name:"YUI Test Results",failedPages:[],passedPages:[]};this.fireEvent(this.TEST_MANAGER_BEGIN_EVENT,null);this._run();},stop:function(){clearTimeout(this._timeoutId);}};YAHOO.lang.augmentObject(YAHOO.tool.TestManager,YAHOO.util.EventProvider.prototype);YAHOO.namespace("tool");YAHOO.tool.TestLogger=function(B,A){YAHOO.tool.TestLogger.superclass.constructor.call(this,B,A);this.init();};YAHOO.lang.extend(YAHOO.tool.TestLogger,YAHOO.widget.LogReader,{footerEnabled:true,newestOnTop:false,formatMsg:function(B){var A=B.category;var C=this.html2Text(B.msg);return"<pre><p><span class=\""+A+"\">"+A.toUpperCase()+"</span> "+C+"</p></pre>";},init:function(){if(YAHOO.tool.TestRunner){this.setTestRunner(YAHOO.tool.TestRunner);}this.hideSource("global");this.hideSource("LogReader");this.hideCategory("warn");this.hideCategory("window");this.hideCategory("time");this.clearConsole();},clearTestRunner:function(){if(this._runner){this._runner.unsubscribeAll();this._runner=null;}},setTestRunner:function(A){if(this._runner){this.clearTestRunner();}this._runner=A;A.subscribe(A.TEST_PASS_EVENT,this._handleTestRunnerEvent,this,true);A.subscribe(A.TEST_FAIL_EVENT,this._handleTestRunnerEvent,this,true);A.subscribe(A.TEST_IGNORE_EVENT,this._handleTestRunnerEvent,this,true);A.subscribe(A.BEGIN_EVENT,this._handleTestRunnerEvent,this,true);A.subscribe(A.COMPLETE_EVENT,this._handleTestRunnerEvent,this,true);A.subscribe(A.TEST_SUITE_BEGIN_EVENT,this._handleTestRunnerEvent,this,true);A.subscribe(A.TEST_SUITE_COMPLETE_EVENT,this._handleTestRunnerEvent,this,true);A.subscribe(A.TEST_CASE_BEGIN_EVENT,this._handleTestRunnerEvent,this,true);
+A.subscribe(A.TEST_CASE_COMPLETE_EVENT,this._handleTestRunnerEvent,this,true);},_handleTestRunnerEvent:function(D){var A=YAHOO.tool.TestRunner;var C="";var B="";switch(D.type){case A.BEGIN_EVENT:C="Testing began at "+(new Date()).toString()+".";B="info";break;case A.COMPLETE_EVENT:C="Testing completed at "+(new Date()).toString()+".\nPassed:"+D.results.passed+" Failed:"+D.results.failed+" Total:"+D.results.total;B="info";break;case A.TEST_FAIL_EVENT:C=D.testName+": "+D.error.getMessage();B="fail";break;case A.TEST_IGNORE_EVENT:C=D.testName+": ignored.";B="ignore";break;case A.TEST_PASS_EVENT:C=D.testName+": passed.";B="pass";break;case A.TEST_SUITE_BEGIN_EVENT:C="Test suite \""+D.testSuite.name+"\" started.";B="info";break;case A.TEST_SUITE_COMPLETE_EVENT:C="Test suite \""+D.testSuite.name+"\" completed.\nPassed:"+D.results.passed+" Failed:"+D.results.failed+" Total:"+D.results.total;B="info";break;case A.TEST_CASE_BEGIN_EVENT:C="Test case \""+D.testCase.name+"\" started.";B="info";break;case A.TEST_CASE_COMPLETE_EVENT:C="Test case \""+D.testCase.name+"\" completed.\nPassed:"+D.results.passed+" Failed:"+D.results.failed+" Total:"+D.results.total;B="info";break;default:C="Unexpected event "+D.type;C="info";}YAHOO.log(C,B,"TestRunner");}});YAHOO.namespace("tool.TestFormat");YAHOO.tool.TestFormat.JSON=function(A){return YAHOO.lang.JSON.stringify(A);};YAHOO.tool.TestFormat.XML=function(C){var A=YAHOO.lang;var B="<"+C.type+" name=\""+C.name.replace(/"/g,"&quot;").replace(/'/g,"&apos;")+"\"";if(C.type=="test"){B+=" result=\""+C.result+"\" message=\""+C.message+"\">";}else{B+=" passed=\""+C.passed+"\" failed=\""+C.failed+"\" ignored=\""+C.ignored+"\" total=\""+C.total+"\">";for(var D in C){if(A.hasOwnProperty(C,D)&&A.isObject(C[D])&&!A.isArray(C[D])){B+=arguments.callee(C[D]);}}}B+="</"+C.type+">";return B;};YAHOO.namespace("tool");YAHOO.tool.TestReporter=function(A,B){this.url=A;this.format=B||YAHOO.tool.TestFormat.XML;this._fields=new Object();this._form=null;this._iframe=null;};YAHOO.tool.TestReporter.prototype={constructor:YAHOO.tool.TestReporter,addField:function(A,B){this._fields[A]=B;},clearFields:function(){this._fields=new Object();},destroy:function(){if(this._form){this._form.parentNode.removeChild(this._form);this._form=null;}if(this._iframe){this._iframe.parentNode.removeChild(this._iframe);this._iframe=null;}this._fields=null;},report:function(A){if(!this._form){this._form=document.createElement("form");this._form.method="post";this._form.style.visibility="hidden";this._form.style.position="absolute";this._form.style.top=0;document.body.appendChild(this._form);if(YAHOO.env.ua.ie){this._iframe=document.createElement("<iframe name=\"yuiTestTarget\" />");}else{this._iframe=document.createElement("iframe");this._iframe.name="yuiTestTarget";}this._iframe.src="javascript:false";this._iframe.style.visibility="hidden";this._iframe.style.position="absolute";this._iframe.style.top=0;document.body.appendChild(this._iframe);this._form.target="yuiTestTarget";}this._form.action=this.url;while(this._form.hasChildNodes()){this._form.removeChild(this._form.lastChild);}this._fields.results=this.format(A);this._fields.useragent=navigator.userAgent;this._fields.timestamp=(new Date()).toLocaleString();for(var B in this._fields){if(YAHOO.lang.hasOwnProperty(this._fields,B)&&typeof this._fields[B]!="function"){if(YAHOO.env.ua.ie){input=document.createElement("<input name=\""+B+"\" >");}else{input=document.createElement("input");input.name=B;}input.type="hidden";input.value=this._fields[B];this._form.appendChild(input);}}delete this._fields.results;delete this._fields.useragent;delete this._fields.timestamp;if(arguments[1]!==false){this._form.submit();}}};YAHOO.register("yuitest",YAHOO.tool.TestRunner,{version:"2.5.2",build:"1076"});
