Index: t3lib/config_default.php
===================================================================
--- t3lib/config_default.php	(Revision 10092)
+++ t3lib/config_default.php	(Arbeitskopie)
@@ -170,7 +170,7 @@
 		'em_wsdlURL' => 'http://typo3.org/wsdl/tx_ter_wsdl.php',				// The SOAP URL for uploading extensions to the TER2. Usually doesn't need to be changed.
 		'em_mirrorListURL' => 'http://repositories.typo3.org/mirrors.xml.gz',				// Allows to preset the URL for fetching the extension repository mirror list from. Used in the Extension Manager.
 
-		'requiredExt' => 'cms,lang,sv,em,list,pagetree',		// String (exclude). List of extensions which are REQUIRED and cannot be unloaded by the Extension Manager!
+		'requiredExt' => 'cms,lang,sv,em,list',		// String (exclude). List of extensions which are REQUIRED and cannot be unloaded by the Extension Manager!
 		'excludeForPackaging' => '(CVS|\..*|.*~|.*\.bak)',		// String: List of directories and files which will not be packaged into extensions nor taken into account otherwise by the Extension Manager. Perl regular expression syntax!
 		'extCache' => 1,						// <p>Integer (0, 1, 2, 3)</p><dl><dt>0</dt><dd>ext-scripts (ext_localconf.php and ext_tables.php) are NOT cached, but included every time</dd><dt>1</dt><dd>scripts cached to typo3conf/temp_CACHED_[sitePathHash]* (saves some milliseconds even with PHP accelerators)</dd><dt>2</dt><dd>scripts cached and prefix includes a hash based on the 'extList' string</dd><dt>3</dt><dd>scripts cached to typo3conf/temp_CACHED_* (no hash included at all...)</dd></dl>
 		'extList' => 'filelist,version,tsconfig_help,context_help,extra_page_cm_options,impexp,belog,about,cshmanual,aboutmodules,setup,opendocs,install,t3editor,felogin,feedit,recycler',						// String (exclude) List of extensions which are enabled for this install. Use the Extension Manager (EM) to manage this!
@@ -217,7 +217,227 @@
 			options.enableShowPalettes=1
 			options.file_list.enableDisplayBigControlPanel=selectable
 			options.file_list.enableDisplayThumbnails=selectable
-			options.file_list.enableClipBoard=selectable',	// String (exclude). Enter lines of default backend user/group TSconfig.
+			options.file_list.enableClipBoard=selectable
+			options.pageTree {
+				doktypesToShowInNewPageDragArea = 1,6,4,7,3,254,255,199
+			}
+
+			options.contextMenu {
+				table {
+					pages_root {
+						disableItems =
+
+						items {
+							100 = ITEM
+							100 {
+								name = view
+								label = LLL:EXT:lang/locallang_core.xml:cm.view
+								spriteIcon = actions-document-view
+								displayCondition = canBeViewed != 0
+								callbackAction = viewPage
+							}
+
+							200 = ITEM
+							200 {
+								name = new
+								label = LLL:EXT:lang/locallang_core.xml:cm.new
+								spriteIcon = actions-page-new
+								displayCondition = canCreateNewPages != 0
+								callbackAction = newPageWizard
+							}
+
+							300 = DIVIDER
+
+							400 = ITEM
+							400 {
+								name = history
+								label = LLL:EXT:lang/locallang_misc.xml:CM_history
+								spriteIcon = actions-document-history-open
+								displayCondition = canShowHistory != 0
+								callbackAction = openHistoryPopUp
+							}
+						}
+					}
+
+					pages {
+						disableItems =
+
+						items {
+							100 = ITEM
+							100 {
+								name = view
+								label = LLL:EXT:lang/locallang_core.xml:cm.view
+								spriteIcon = actions-document-view
+								displayCondition = canBeViewed != 0
+								callbackAction = viewPage
+							}
+
+							200 = DIVIDER
+
+							300 = ITEM
+							300 {
+								name = disable
+								label = LLL:EXT:lang/locallang_core.xml:cm.hide
+								spriteIcon = actions-edit-hide
+								displayCondition = getRecord|hidden = 0 && canBeDisabledAndEnabled != 0
+								callbackAction = disablePage
+							}
+
+							400 = ITEM
+							400 {
+								name = enable
+								label = LLL:EXT:lang/locallang_core.xml:cm.unhide
+								spriteIcon = actions-edit-unhide
+								displayCondition = getRecord|hidden = 1 && canBeDisabledAndEnabled != 0
+								callbackAction = enablePage
+							}
+
+							500 = ITEM
+							500 {
+								name = edit
+								label = LLL:EXT:lang/locallang_core.xml:cm.edit
+								spriteIcon = actions-document-open
+								displayCondition = canBeEdited != 0
+								callbackAction = editPageProperties
+							}
+
+							600 = ITEM
+							600 {
+								name = info
+								label = LLL:EXT:lang/locallang_core.xml:cm.info
+								spriteIcon = actions-document-info
+								displayCondition = canShowInfo != 0
+								callbackAction = openInfoPopUp
+							}
+
+							700 = ITEM
+							700 {
+								name = history
+								label = LLL:EXT:lang/locallang_misc.xml:CM_history
+								spriteIcon = actions-document-history-open
+								displayCondition = canShowHistory != 0
+								callbackAction = openHistoryPopUp
+							}
+
+							800 = DIVIDER
+
+							900 = SUBMENU
+							900 {
+								label = LLL:EXT:lang/locallang_core.xml:cm.copyPasteActions
+
+								100 = ITEM
+								100 {
+									name = new
+									label = LLL:EXT:lang/locallang_core.xml:cm.new
+									spriteIcon = actions-page-new
+									displayCondition = canCreateNewPages != 0
+									callbackAction = newPageWizard
+								}
+
+								200 = DIVIDER
+
+								300 = ITEM
+								300 {
+									name = cut
+									label = LLL:EXT:lang/locallang_core.xml:cm.cut
+									spriteIcon = actions-edit-cut
+									displayCondition = isInCutMode = 0 && canBeCut != 0 && isMountPoint != 1
+									callbackAction = enableCutMode
+								}
+
+								400 = ITEM
+								400 {
+									name = cut
+									label = LLL:EXT:lang/locallang_core.xml:cm.cut
+									spriteIcon = actions-edit-cut-release
+									displayCondition = isInCutMode = 1 && canBeCut != 0
+									callbackAction = disableCutMode
+								}
+
+								500 = ITEM
+								500 {
+									name = copy
+									label = LLL:EXT:lang/locallang_core.xml:cm.copy
+									spriteIcon = actions-edit-copy
+									displayCondition = isInCopyMode = 0 && canBeCopied != 0
+									callbackAction = enableCopyMode
+								}
+
+								600 = ITEM
+								600 {
+									name = copy
+									label = LLL:EXT:lang/locallang_core.xml:cm.copy
+									spriteIcon = actions-edit-copy-release
+									displayCondition = isInCopyMode = 1 && canBeCopied != 0
+									callbackAction = disableCopyMode
+								}
+
+								700 = ITEM
+								700 {
+									name = pasteInto
+									label = LLL:EXT:lang/locallang_core.xml:cm.pasteinto
+									spriteIcon = actions-document-paste-into
+									displayCondition = getContextInfo|inCopyMode = 1 || getContextInfo|inCutMode = 1 && canBePastedInto != 0
+									callbackAction = pasteIntoNode
+								}
+
+								800 = ITEM
+								800 {
+									name = pasteAfter
+									label = LLL:EXT:lang/locallang_core.xml:cm.pasteafter
+									spriteIcon = actions-document-paste-after
+									displayCondition = getContextInfo|inCopyMode = 1 || getContextInfo|inCutMode = 1 && canBePastedAfter != 0
+									callbackAction = pasteAfterNode
+								}
+
+								900 = DIVIDER
+
+								1000 = ITEM
+								1000 {
+									name = delete
+									label = LLL:EXT:lang/locallang_core.xml:cm.delete
+									spriteIcon = actions-edit-delete
+									displayCondition = canBeRemoved != 0 && isMountPoint != 1
+									callbackAction = removeNode
+								}
+							}
+
+							1000 = SUBMENU
+							1000 {
+								label = LLL:EXT:lang/locallang_core.xml:cm.branchActions
+
+								100 = ITEM
+								100 {
+									name = mountAsTreeroot
+									label = LLL:EXT:lang/locallang_core.xml:cm.tempMountPoint
+									spriteIcon = actions-system-extension-documentation
+									displayCondition = canBeTemporaryMountPoint != 0 && isMountPoint = 0
+									callbackAction = mountAsTreeRoot
+								}
+
+								200 = DIVIDER
+
+								300 = ITEM
+								300 {
+									name = expandBranch
+									label = LLL:EXT:lang/locallang_core.xml:cm.expandBranch
+									displayCondition =
+									callbackAction = expandBranch
+								}
+
+								400 = ITEM
+								400 {
+									name = collapseBranch
+									label = LLL:EXT:lang/locallang_core.xml:cm.collapseBranch
+									displayCondition =
+									callbackAction = collapseBranch
+								}
+							}
+						}
+					}
+				}
+			}
+		',	// String (exclude). Enter lines of default backend user/group TSconfig.
 		'defaultPageTSconfig' => 'mod.web_list.enableDisplayBigControlPanel=selectable
 			mod.web_list.enableClipBoard=selectable
 			mod.web_list.enableLocalizationView=selectable',			// String (exclude).Enter lines of default Page TSconfig.
@@ -385,6 +605,9 @@
 			'TYPO3.LiveSearchActions.ExtDirect' => 't3lib/extjs/dataprovider/class.extdirect_dataprovider_backendlivesearch.php:extDirect_DataProvider_BackendLiveSearch',
 			'TYPO3.BackendUserSettings.ExtDirect' => 't3lib/extjs/dataprovider/class.extdirect_dataprovider_beusersettings.php:extDirect_DataProvider_BackendUserSettings',
 			'TYPO3.ExtDirectStateProvider.ExtDirect' => 't3lib/extjs/dataprovider/class.extdirect_dataprovider_state.php:extDirect_DataProvider_State',
+			'TYPO3.Components.PageTree.DataProvider' => 't3lib/tree/pagetree/extdirect/class.t3lib_tree_pagetree_extdirect_tree.php:t3lib_tree_pagetree_extdirect_Tree',
+			'TYPO3.Components.PageTree.Commands' => 't3lib/tree/pagetree/extdirect/class.t3lib_tree_pagetree_extdirect_tree.php:t3lib_tree_pagetree_extdirect_Commands',
+			'TYPO3.Components.PageTree.ContextMenuDataProvider' => 't3lib/contextmenu/pagetree/extdirect/class.t3lib_contextmenu_pagetree_extdirect_contextmenu.php:t3lib_contextmenu_pagetree_extdirect_ContextMenu',
 		),
 	),
 	'EXTCONF' => array(		// Here you may add manually set configuration options for your extensions. Eg. $TYPO3_CONF_VARS['EXTCONF']['my_extension_key']['my_option'] = 'my_value';
@@ -702,4 +925,4 @@
 $ACCESS_TIME = $EXEC_TIME - ($EXEC_TIME % 60);		// $ACCESS_TIME is a common time in minutes for access control
 $SIM_ACCESS_TIME = $ACCESS_TIME;		// if $SIM_EXEC_TIME is changed this value must be set accordingly
 
-?>
+?>
\ No newline at end of file
Index: t3lib/stddb/tables.php
===================================================================
--- t3lib/stddb/tables.php	(Revision 10092)
+++ t3lib/stddb/tables.php	(Arbeitskopie)
@@ -375,6 +375,10 @@
 	'help' => '',
 );
 
+	// register the pagetree core navigation component
+t3lib_extMgm::addCoreNavigationComponent('web', 'typo3-pagetree', array(
+	'TYPO3.Components.PageTree'
+));
 
 /**
  * $TBE_STYLES configures backend styles and colors; Basically this contains all the values that can be used to create new skins for TYPO3.
Index: t3lib/js/extjs/components/pagetree/javascript/deletiondropzone.js
===================================================================
--- t3lib/js/extjs/components/pagetree/javascript/deletiondropzone.js	(Revision 0)
+++ t3lib/js/extjs/components/pagetree/javascript/deletiondropzone.js	(Revision 0)
@@ -0,0 +1,294 @@
+/***************************************************************
+ *  Copyright notice
+ *
+ *  (c) 2010 TYPO3 Tree Team <http://forge.typo3.org/projects/typo3v4-extjstrees>
+ *  All rights reserved
+ *
+ *  This script is part of the TYPO3 project. The TYPO3 project is
+ *  free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  The GNU General Public License can be found at
+ *  http://www.gnu.org/copyleft/gpl.html.
+ *  A copy is found in the textfile GPL.txt and important notices to the license
+ *  from the author is found in LICENSE.txt distributed with these scripts.
+ *
+ *
+ *  This script is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  This copyright notice MUST APPEAR in all copies of the script!
+ ***************************************************************/
+Ext.namespace('TYPO3.Components.PageTree');
+
+/**
+ * @class TYPO3.Components.PageTree.DeletionDropZone
+ *
+ * Deletion Drop Zone
+ *
+ * @namespace TYPO3.Components.PageTree
+ * @extends Ext.Panel
+ * @author Stefan Galinski <stefan.galinski@gmail.com>
+ */
+TYPO3.Components.PageTree.DeletionDropZone = Ext.extend(Ext.Panel, {
+	/**
+	 * Border
+	 *
+	 * @type {Boolean}
+	 */
+	border: true,
+
+	/**
+	 * Hide the drop zone initially
+	 *
+	 * @type {Boolean}
+	 */
+	hidden: true,
+
+	/**
+	 * Command Provider
+	 *
+	 * @cfg {Object}
+	 */
+	commandProvider: null,
+
+	/**
+	 * Drag and Drop Group
+	 *
+	 * @cfg {String}
+	 */
+	ddGroup: '',
+
+	/**
+	 * Main Application
+	 *
+	 * @cfg {TYPO3.Components.PageTree.App}
+	 */
+	app: null,
+
+	/**
+	 * Removed node had a previous sibling
+	 *
+	 * @type {Boolean}
+	 */
+	isPreviousSibling: false,
+
+	/**
+	 * Removed node
+	 *
+	 * @type {Ext.tree.TreeNode}
+	 */
+	previousNode: null,
+
+	/**
+	 * Click Handler for the recovery text
+	 *
+	 * @type {Function}
+	 */
+	textClickHandler: null,
+
+	/**
+	 * Amount of drops (used to prevent early hiding of the box)
+	 *
+	 * @type {int}
+	 */
+	amountOfDrops: 0,
+
+	/**
+	 * Listeners
+	 *
+	 * The "afterrender" event creates the drop zone
+	 */
+	listeners: {
+		afterrender: {
+			fn: function() {
+				this.createDropZone();
+				
+				this.getEl().on('mouseout', function(e) {
+					if (!e.within(this.getEl(), true)) {
+						this.removeClass(this.id + '-activateProxyOver');
+						if (!this.app.activeTree.shouldCopyNode) {
+							this.app.activeTree.copyHint.show();
+						}
+					}
+				}, this);
+			}
+		},
+
+		beforehide: {
+			fn: function() {
+				if (this.textClickHandler) {
+					return false;
+				}
+			}
+		}
+	},
+
+	/**
+	 * Initializes the component
+	 *
+	 * @return {void}
+	 */
+	initComponent: function() {
+		this.html = '<p><span id="' + this.id + '-icon" class="' +
+			TYPO3.Components.PageTree.Sprites.TrashCan +
+			'">&nbsp;</span><span id="' + this.id + '-text">' +
+			TYPO3.Components.PageTree.LLL.dropToRemove + '</span></p>';
+
+		TYPO3.Components.PageTree.DeletionDropZone.superclass.initComponent.apply(this, arguments);
+	},
+
+
+	/**
+	 * Creates the drop zone and it's functionality
+	 *
+	 * @return {void}
+	 */
+	createDropZone: function() {
+		(new Ext.dd.DropZone(this.getEl(), {
+			ddGroup: this.ddGroup,
+
+			notifyOver: function(ddProxy, e) {
+				ddProxy.setDragElPos(e.xy[0], e.xy[1] - 60);
+				return this.id + '-proxyOver';
+			}.createDelegate(this),
+
+			notifyEnter: function() {
+				this.addClass(this.id + '-activateProxyOver');
+				if (!this.app.activeTree.shouldCopyNode) {
+					this.app.activeTree.copyHint.hide();
+				}
+
+				return this.id + '-proxyOver';
+			}.createDelegate(this),
+
+			notifyDrop: function(ddProxy, e, n) {
+				var node = n.node;
+				if (!node) {
+					return;
+				}
+
+				var tree = node.ownerTree;
+				if (!top.TYPO3.configuration.inWorkspace) {
+					this.setHeight(50);
+					this.updateIcon(TYPO3.Components.PageTree.Sprites.TrashCanRestore);
+					this.updateText(
+						node.text + '<br />' +
+						'<span class="' + this.id + '-restore">' +
+							'<span class="' + this.id + '-restoreText">' +
+							TYPO3.Components.PageTree.LLL.dropZoneElementRemoved +
+							'</span>' +
+						'</span>',
+						false
+					);
+
+					++this.amountOfDrops;
+					(function() {
+						if (!--this.amountOfDrops) {
+							this.toOriginState();
+						}
+					}).defer(10000, this);
+
+					this.textClickHandler = this.restoreNode.createDelegate(this, [node, tree]);
+					Ext.get(this.id + '-text').on('click', this.textClickHandler);
+
+					this.isPreviousSibling = false;
+					this.previousNode = node.parentNode;
+					if (node.previousSibling) {
+						this.previousNode = node.previousSibling;
+						this.isPreviousSibling = true;
+					}
+				}
+
+				node.ownerTree.commandProvider.deleteNode(node, tree);
+			}.createDelegate(this)
+		}));
+	},
+
+	/**
+	 * Updates the drop zone text label
+	 *
+	 * @param {String} text
+	 * @param {Boolean} animate
+	 * @return {void}
+	 */
+	updateText: function(text, animate) {
+		animate = animate || false;
+
+		var elementText = Ext.get(this.id + '-text');
+		if (animate) {
+			elementText.animate({opacity: {to: 0}}, 1, function(elementText) {
+				elementText.update(text);
+				elementText.setStyle('opacity', 1);
+			});
+		} else {
+			elementText.update(text);
+		}
+	},
+
+	/**
+	 * Updates the drop zone icon with another sprite icon
+	 *
+	 * @param {String} classes
+	 * @return {void}
+	 */
+	updateIcon: function(classes) {
+		Ext.get(this.id + '-icon').set({
+			'class': classes
+		});
+	},
+
+	/**
+	 * Resets the drop zone to the initial state
+	 *
+	 * @param {Boolean} hide
+	 * @return {void}
+	 */
+	toOriginState: function(hide) {
+		if (hide !== false) {
+			hide = true;
+		}
+
+		Ext.get(this.id + '-text').un('click', this.textClickHandler);
+		this.previousNode = this.textClickHandler = null;
+		this.isPreviousSibling = false;
+
+		if (hide && !this.app.activeTree.dragZone.dragging) {
+			this.hide();
+		}
+
+		this.setHeight(35);
+		this.updateText(TYPO3.Components.PageTree.LLL.dropToRemove, false);
+		this.updateIcon(TYPO3.Components.PageTree.Sprites.TrashCan);
+	},
+
+	/**
+	 * Restores the last removed node
+	 *
+	 * @param {Ext.tree.TreeNode} node
+	 * @param {TYPO3.Components.PageTree.Tree} tree
+	 * @return {void}
+	 */
+	restoreNode: function(node, tree) {
+		if (this.isPreviousSibling) {
+			this.commandProvider.restoreNodeAfterDestination(node, tree, this.previousNode);
+		} else {
+			this.commandProvider.restoreNodeToFirstChildOfDestination(node, tree, this.previousNode);
+		}
+		this.setHeight(35);
+		this.updateText(TYPO3.Components.PageTree.LLL.dropZoneElementRestored);
+
+		(function() {
+			if (this.textClickHandler) {
+				this.toOriginState();
+			}
+		}).defer(3000, this);
+	}
+});
+
+// XTYPE Registration
+Ext.reg('TYPO3.Components.PageTree.DeletionDropZone', TYPO3.Components.PageTree.DeletionDropZone);
\ No newline at end of file
Index: t3lib/js/extjs/components/pagetree/javascript/treeeditor.js
===================================================================
--- t3lib/js/extjs/components/pagetree/javascript/treeeditor.js	(Revision 0)
+++ t3lib/js/extjs/components/pagetree/javascript/treeeditor.js	(Revision 0)
@@ -0,0 +1,123 @@
+/***************************************************************
+*  Copyright notice
+*
+*  (c) 2010 TYPO3 Tree Team <http://forge.typo3.org/projects/typo3v4-extjstrees>
+*  All rights reserved
+*
+*  This script is part of the TYPO3 project. The TYPO3 project is
+*  free software; you can redistribute it and/or modify
+*  it under the terms of the GNU General Public License as published by
+*  the Free Software Foundation; either version 2 of the License, or
+*  (at your option) any later version.
+*
+*  The GNU General Public License can be found at
+*  http://www.gnu.org/copyleft/gpl.html.
+*  A copy is found in the textfile GPL.txt and important notices to the license
+*  from the author is found in LICENSE.txt distributed with these scripts.
+*
+*
+*  This script is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*  GNU General Public License for more details.
+*
+*  This copyright notice MUST APPEAR in all copies of the script!
+***************************************************************/
+Ext.namespace('TYPO3.Components.PageTree');
+
+/**
+ * @class TYPO3.Components.PageTree.TreeEditor
+ *
+ * Custom Tree Editor implementation to enable different source fields for the
+ * editable label.
+ *
+ * @namespace TYPO3.Components.PageTree
+ * @extends Ext.tree.TreeEditor
+ * @author Stefan Galinski <stefan.galinski@gmail.com>
+ */
+TYPO3.Components.PageTree.TreeEditor = Ext.extend(Ext.tree.TreeEditor, {
+	/**
+	 * Don't send any save events if the value wasn't changed
+	 *
+	 * @type {Boolean}
+	 */
+	ignoreNoChange: true,
+
+	/**
+	 * Edit delay
+	 *
+	 * @type {int}
+	 */
+	editDelay: 250,
+
+	/**
+	 * Indicates if an underlying shadow should be shown
+	 *
+	 * @type {Boolean}
+	 */
+	shadow: false,
+
+	/**
+	 * Listeners
+	 *
+	 * Handles the synchronization between the edited label and the shown label.
+	 */
+	listeners: {
+		beforecomplete: function(node) {
+			this.updatedValue = this.getValue();
+			if (this.updatedValue === '') {
+				return false;
+			}
+			this.setValue(this.editNode.attributes.prefix + Ext.util.Format.htmlEncode(this.updatedValue) + this.editNode.attributes.suffix);
+		},
+
+		complete: {
+			fn: function(node, newValue, oldValue) {
+				this.editNode.ownerTree.commandProvider.saveTitle(node, this.updatedValue, oldValue, this);
+			}
+		}
+	},
+
+	/**
+	 * Updates the edit node
+	 *
+	 * @param {Ext.tree.TreeNode} node
+	 * @param {String} editableText
+	 * @param {String} updatedNode
+	 * @return {void}
+	 */
+	updateNodeText: function(node, editableText, updatedNode) {
+		this.editNode.setText(this.editNode.attributes.prefix + updatedNode + this.editNode.attributes.suffix);
+		this.editNode.attributes.editableText = editableText;
+	},
+
+	/**
+	 * Overridden method to set another editable text than the node text attribute
+	 *
+	 * @param {Ext.tree.TreeNode} node
+	 * @return {Boolean}
+	 */
+	triggerEdit: function(node) {
+		this.completeEdit();
+		if (node.attributes.editable !== false) {
+			this.editNode = node;
+			if (this.tree.autoScroll) {
+				Ext.fly(node.ui.getEl()).scrollIntoView(this.tree.body);
+			}
+
+			var value = node.text || '';
+			if (!Ext.isGecko && Ext.isEmpty(node.text)) {
+				node.setText(' ');
+			}
+
+				// TYPO3 MODIFICATION to use another attribute
+			value = node.attributes.editableText;
+
+			this.autoEditTimer = this.startEdit.defer(this.editDelay, this, [node.ui.textNode, value]);
+			return false;
+		}
+	}
+});
+
+// XTYPE Registration
+Ext.reg('TYPO3.Components.PageTree.TreeEditor', TYPO3.Components.PageTree.TreeEditor);
\ No newline at end of file
Index: t3lib/js/extjs/components/pagetree/javascript/Ext.ux.state.TreePanel.js
===================================================================
--- t3lib/js/extjs/components/pagetree/javascript/Ext.ux.state.TreePanel.js	(Revision 0)
+++ t3lib/js/extjs/components/pagetree/javascript/Ext.ux.state.TreePanel.js	(Revision 0)
@@ -0,0 +1,145 @@
+/***************************************************************
+*  Copyright notice
+*
+*  (c) 2010 TYPO3 Tree Team <http://forge.typo3.org/projects/typo3v4-extjstrees>
+*  All rights reserved
+*
+*  This script is part of the TYPO3 project. The TYPO3 project is
+*  free software; you can redistribute it and/or modify
+*  it under the terms of the GNU General Public License as published by
+*  the Free Software Foundation; either version 2 of the License, or
+*  (at your option) any later version.
+*
+*  The GNU General Public License can be found at
+*  http://www.gnu.org/copyleft/gpl.html.
+*  A copy is found in the textfile GPL.txt and important notices to the license
+*  from the author is found in LICENSE.txt distributed with these scripts.
+*
+*
+*  This script is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*  GNU General Public License for more details.
+*
+*  This copyright notice MUST APPEAR in all copies of the script!
+***************************************************************/
+Ext.ns('Ext.ux.state');
+
+// dummy constructor
+Ext.ux.state.TreePanel = function() {};
+
+/**
+ * State Provider for a tree panel
+ */
+Ext.override(Ext.ux.state.TreePanel, {
+	/**
+	 * Initializes the plugin
+	 * @param {Ext.tree.TreePanel} tree
+	 * @private
+	 */
+	init:function(tree) {
+		tree.lastSelectedNode = null;
+		tree.isRestoringState = false;
+		tree.stateHash = {};
+
+		// install event handlers on TreePanel
+		tree.on({
+			// add path of expanded node to stateHash
+			 beforeexpandnode:function(n) {
+				if (this.isRestoringState) {
+					return;
+				}
+
+				this.stateHash[n.id] = n.getPath();
+			},
+
+			// delete path and all subpaths of collapsed node from stateHash
+			beforecollapsenode:function(n) {
+				if (this.isRestoringState) {
+					return;
+				}
+
+				delete this.stateHash[n.id];
+				var cPath = n.getPath();
+				for(var p in this.stateHash) {
+					if(this.stateHash.hasOwnProperty(p)) {
+						if(this.stateHash[p].indexOf(cPath) !== -1) {
+							delete this.stateHash[p];
+						}
+					}
+				}
+			},
+
+			beforeclick: function(node) {
+				if (this.isRestoringState) {
+					return;
+				}
+				this.stateHash['lastSelectedNode'] = node.id;
+			}
+		});
+
+			// update state on node expand or collapse
+		tree.stateEvents = tree.stateEvents || [];
+		tree.stateEvents.push('expandnode', 'collapsenode', 'click');
+
+		// add state related props to the tree
+		Ext.apply(tree, {
+			// keeps expanded nodes paths keyed by node.ids
+			 stateHash:{},
+
+			restoreState: function() {
+				this.isRestoringState = true;
+				for(var p in this.stateHash) {
+					if(this.stateHash.hasOwnProperty(p)) {
+						this.expandPath(this.stateHash[p]);
+					}
+				}
+					// get last selected node
+				if (this.stateHash['lastSelectedNode']) {
+					var node = this.getNodeById(this.stateHash['lastSelectedNode']);
+					if (node) {
+						this.selectPath(node.getPath());
+
+						var contentId = TYPO3.Backend.ContentContainer.getIdFromUrl() ||
+							String(fsMod.recentIds['web']) || '-1';
+
+						var isCurrentSelectedNode = (
+							String(node.attributes.nodeData.id) === contentId ||
+							contentId.indexOf('pages' + String(node.attributes.nodeData.id)) !== -1
+						);
+
+						if (contentId !== '-1' && !isCurrentSelectedNode &&
+							this.commandProvider && this.commandProvider.singleClick
+						) {
+							this.commandProvider.singleClick(node, this);
+						}
+					}
+				}
+
+				this.isRestoringState = false;
+			},
+
+			// apply state on tree initialization
+			applyState:function(state) {
+				if(state) {
+					Ext.apply(this, state);
+
+					// it is too early to expand paths here
+					// so do it once on root load
+					this.root.on({
+						load: {
+							single:true,
+							scope:this,
+							fn: this.restoreState
+						}
+					});
+				}
+			},
+
+			// returns stateHash for save by state manager
+			getState:function() {
+				return {stateHash:this.stateHash};
+			}
+		});
+	}
+});
\ No newline at end of file
Index: t3lib/js/extjs/components/pagetree/javascript/contextmenu.js
===================================================================
--- t3lib/js/extjs/components/pagetree/javascript/contextmenu.js	(Revision 0)
+++ t3lib/js/extjs/components/pagetree/javascript/contextmenu.js	(Revision 0)
@@ -0,0 +1,188 @@
+/***************************************************************
+*  Copyright notice
+*
+*  (c) 2010 TYPO3 Tree Team <http://forge.typo3.org/projects/typo3v4-extjstrees>
+*  All rights reserved
+*
+*  This script is part of the TYPO3 project. The TYPO3 project is
+*  free software; you can redistribute it and/or modify
+*  it under the terms of the GNU General Public License as published by
+*  the Free Software Foundation; either version 2 of the License, or
+*  (at your option) any later version.
+*
+*  The GNU General Public License can be found at
+*  http://www.gnu.org/copyleft/gpl.html.
+*  A copy is found in the textfile GPL.txt and important notices to the license
+*  from the author is found in LICENSE.txt distributed with these scripts.
+*
+*
+*  This script is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*  GNU General Public License for more details.
+*
+*  This copyright notice MUST APPEAR in all copies of the script!
+***************************************************************/
+Ext.namespace('TYPO3.Components.PageTree');
+
+/**
+ * @class TYPO3.Components.PageTree.ContextMenu
+ *
+ * Context menu implementation
+ *
+ * @namespace TYPO3.Components.PageTree
+ * @extends Ext.menu.Menu
+ * @author Stefan Galinski <stefan.galinski@gmail.com>
+ */
+TYPO3.Components.PageTree.ContextMenu = Ext.extend(Ext.menu.Menu, {
+	/**
+	 * Context menu node
+	 *
+	 * @cfg {Ext.tree.TreeNode}
+	 */
+	node: null,
+
+	/**
+	 * Page Tree
+	 *
+	 * @cfg {TYPO3.Components.PageTree.Tree}
+	 */
+	pageTree: null,
+
+	/**
+	 * Component Id
+	 *
+	 * @type {String}
+	 */
+	id: 'typo3-pagetree-contextmenu',
+
+	/**
+	 * Listeners
+	 *
+	 * The itemclick event triggers the configured single click action
+	 */
+	listeners: {
+		itemclick: {
+			fn: function (item) {
+				if (this.pageTree.commandProvider[item.callbackAction]) {
+					if (item.parentMenu.pageTree.stateHash) {
+						fsMod.recentIds['web'] = item.parentMenu.node.attributes.nodeData.id;
+						item.parentMenu.pageTree.stateHash['lastSelectedNode'] = item.parentMenu.node.id;
+					}
+
+					this.pageTree.commandProvider[item.callbackAction](
+						item.parentMenu.node,
+						item.parentMenu.pageTree
+					);
+				}
+			}
+		}
+	},
+
+	/**
+	 * Fills the menu with the actions
+	 *
+	 * @param {Ext.tree.TreeNode} node
+	 * @param {TYPO3.Components.PageTree.Tree} pageTree
+	 * @param {Object} contextMenuConfiguration
+	 * @return {void}
+	 */
+	fill: function(node, pageTree, contextMenuConfiguration) {
+		this.node = node;
+		this.pageTree = pageTree;
+
+		var components = this.preProcessContextMenuConfiguration(contextMenuConfiguration);
+		if (components.length) {
+			for (var component in components) {
+				if (components[component] === '-') {
+					this.addSeparator();
+				} else if (typeof components[component] === 'object') {
+					this.addItem(components[component]);
+				}
+			}
+		}
+	},
+
+	/**
+	 * Parses the context menu actions array recursively and generates the
+	 * components for the context menu including separators/dividers and sub menus
+	 *
+	 * @param {Object} contextMenuConfiguration
+	 * @param {int} level
+	 * @return {Object}
+	 */
+	preProcessContextMenuConfiguration: function(contextMenuConfiguration, level) {
+		level = level || 0;
+		if (level > 5) {
+			return [];
+		}
+
+		var components = [];
+		var index = 0;
+
+		var modulesInsideGroup = false;
+		var subMenus = 0;
+		for (var singleAction in contextMenuConfiguration) {
+			if (contextMenuConfiguration[singleAction]['type'] === 'submenu') {
+				var subMenuComponents = this.preProcessContextMenuConfiguration(
+					contextMenuConfiguration[singleAction]['childActions'],
+					level + 1
+				);
+
+				if (subMenuComponents.length) {
+					var subMenu = new TYPO3.Components.PageTree.ContextMenu({
+						id: this.id + '-sub' + ++subMenus,
+						items: subMenuComponents,
+						node: this.node,
+						pageTree: this.pageTree
+					});
+
+					components[index++] = {
+						text: contextMenuConfiguration[singleAction]['label'],
+						cls: 'contextMenu-subMenu',
+						menu: subMenu,
+						icon: contextMenuConfiguration[singleAction]['icon'],
+						iconCls: contextMenuConfiguration[singleAction]['class']
+					};
+				}
+			} else if (contextMenuConfiguration[singleAction]['type'] === 'divider') {
+				if (modulesInsideGroup) {
+					components[index++] = '-';
+					modulesInsideGroup = false;
+				}
+			} else {
+				modulesInsideGroup = true;
+
+				if (typeof contextMenuConfiguration[singleAction] === 'object') {
+					var component = {
+						'text': contextMenuConfiguration[singleAction]['label'],
+						'icon': contextMenuConfiguration[singleAction]['icon'],
+						'iconCls': contextMenuConfiguration[singleAction]['class'],
+						'callbackAction': contextMenuConfiguration[singleAction]['callbackAction']
+					};
+
+					component.itemTpl = Ext.menu.Item.prototype.itemTpl = new Ext.XTemplate(
+						'<a id="{id}" class="{cls}" hidefocus="true" unselectable="on" href="{href}">',
+							'<span class="{hrefTarget}">',
+								'<img src="{icon}" class="x-menu-item-icon {iconCls}" unselectable="on" />',
+							'</span>',
+							'<span class="x-menu-item-text">{text}</span>',
+						'</a>'
+					);
+
+					components[index++] = component;
+				}
+			}
+		}
+
+			// remove divider if it's the last item of the context menu
+		if (components.last() === '-') {
+			components[components.length - 1] = '';
+		}
+
+		return components;
+	}
+});
+
+// XTYPE Registration
+Ext.reg('TYPO3.Components.PageTree.ContextMenu', TYPO3.Components.PageTree.ContextMenu);
\ No newline at end of file
Index: t3lib/js/extjs/components/pagetree/javascript/loadorder.txt
===================================================================
--- t3lib/js/extjs/components/pagetree/javascript/loadorder.txt	(Revision 0)
+++ t3lib/js/extjs/components/pagetree/javascript/loadorder.txt	(Revision 0)
@@ -0,0 +1,10 @@
+treeeditor.js
+tree.js
+filteringtree.js
+nodeui.js
+deletiondropzone.js
+toppanel.js
+contextmenu.js
+actions.js
+Ext.ux.state.TreePanel.js
+app.js
\ No newline at end of file
Index: t3lib/js/extjs/components/pagetree/javascript/tree.js
===================================================================
--- t3lib/js/extjs/components/pagetree/javascript/tree.js	(Revision 0)
+++ t3lib/js/extjs/components/pagetree/javascript/tree.js	(Revision 0)
@@ -0,0 +1,566 @@
+/***************************************************************
+*  Copyright notice
+*
+*  (c) 2010 TYPO3 Tree Team <http://forge.typo3.org/projects/typo3v4-extjstrees>
+*  All rights reserved
+*
+*  This script is part of the TYPO3 project. The TYPO3 project is
+*  free software; you can redistribute it and/or modify
+*  it under the terms of the GNU General Public License as published by
+*  the Free Software Foundation; either version 2 of the License, or
+*  (at your option) any later version.
+*
+*  The GNU General Public License can be found at
+*  http://www.gnu.org/copyleft/gpl.html.
+*  A copy is found in the textfile GPL.txt and important notices to the license
+*  from the author is found in LICENSE.txt distributed with these scripts.
+*
+*
+*  This script is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*  GNU General Public License for more details.
+*
+*  This copyright notice MUST APPEAR in all copies of the script!
+***************************************************************/
+Ext.namespace('TYPO3.Components.PageTree');
+
+/**
+ * @class TYPO3.Components.PageTree.Tree
+ *
+ * Generic Tree Panel
+ *
+ * @namespace TYPO3.Components.PageTree
+ * @extends Ext.tree.TreePanel
+ * @author Stefan Galinski <stefan.galinski@gmail.com>
+ */
+TYPO3.Components.PageTree.Tree = Ext.extend(Ext.tree.TreePanel, {
+	/**
+	 * Border
+	 *
+	 * @type {Boolean}
+	 */
+	border: false,
+
+	/**
+	 * Indicates if the root node is visible
+	 *
+	 * @type {Boolean}
+	 */
+	rootVisible: false,
+
+	/**
+	 * Enable the drag and drop feature
+	 *
+	 * @cfg {Boolean}
+	 */
+	enableDD: true,
+
+	/**
+	 * Drag and Drop Group
+	 *
+	 * @cfg {String}
+	 */
+	ddGroup: '',
+
+	/**
+	 * Indicates if the label should be editable
+	 *
+	 * @cfg {Boolean}
+	 */
+	labelEdit: true,
+
+	/**
+	 * User Interface Provider
+	 *
+	 * @cfg {Ext.tree.TreeNodeUI}
+	 */
+	uiProvider: null,
+
+	/**
+	 * Data Provider
+	 *
+	 * @cfg {Object}
+	 */
+	treeDataProvider: null,
+
+	/**
+	 * Command Provider
+	 *
+	 * @cfg {Object}
+	 */
+	commandProvider : null,
+
+	/**
+	 * Context menu provider
+	 *
+	 * @cfg {Object}
+	 */
+	contextMenuProvider: null,
+
+	/**
+	 * Id of the deletion drop zone if any
+	 *
+	 * @cfg {String}
+	 */
+	deletionDropZoneId: '',
+
+	/**
+	 * Root Node Configuration
+	 *
+	 * @type {Object}
+	 */
+	rootNodeConfig: {
+		id: 'root',
+		expanded: true,
+		nodeData: {
+			id: 'root'
+		}
+	},
+
+	/**
+	 * Indicator if the control key is pressed
+	 *
+	 * @type {Boolean}
+	 */
+	isControlPressed: false,
+
+	/**
+	 * Context Node
+	 *
+	 * @type {Ext.tree.TreeNode}
+	 */
+	t3ContextNode: null,
+
+	/**
+	 * Context Information
+	 *
+	 * @type {Object}
+	 */
+	t3ContextInfo: {
+		inCopyMode: false,
+		inCutMode: false
+	},
+
+	/**
+	 * Registered clicks for the double click feature
+	 *
+	 * @type {int}
+	 */
+	clicksRegistered: 0,
+
+	/**
+	 * Indicator if the control key was pressed
+	 *
+	 * @type {Boolean}
+	 */
+	controlKeyPressed: false,
+
+	/**
+	 * Listeners
+	 *
+	 * Event handlers that handle click events and synchronizes the label edit,
+	 * double click and single click events in a useful way.
+	 */
+	listeners: {
+			// single click handler that only triggers after a delay to let the double click event
+			// a possibility to be executed (needed for label edit)
+		click: {
+			fn: function(node, event) {
+				if (this.clicksRegistered === 2) {
+					this.clicksRegistered = 0;
+					event.stopEvent();
+					return false;
+				}
+
+				this.clicksRegistered = 0;
+				if (this.commandProvider.singleClick) {
+					this.commandProvider.singleClick(node, this);
+				}
+			},
+			delay: 400
+		},
+
+			// prevent the expanding / collapsing on double click
+		beforedblclick: {
+			fn: function() {
+				return false;
+			}
+		},
+
+			// prevents label edit on a selected node
+		beforeclick: {
+			fn: function(node, event) {
+				if (!this.clicksRegistered && this.getSelectionModel().isSelected(node)) {
+					node.fireEvent('click', node, event);
+					++this.clicksRegistered;
+					return false;
+				}
+				++this.clicksRegistered;
+			}
+		}
+	},
+
+	/**
+	 * Initializes the component
+	 *
+	 * @return {void}
+	 */
+	initComponent: function() {
+		if (!this.uiProvider) {
+			this.uiProvider = TYPO3.Components.PageTree.PageTreeNodeUI;
+		}
+		Ext.dd.DragDropMgr.useCache = false;
+		this.root = new Ext.tree.AsyncTreeNode(this.rootNodeConfig);
+		this.addTreeLoader();
+
+		if (this.labelEdit) {
+			this.enableInlineEditor();
+		}
+
+		if (this.enableDD) {
+			this.dragConfig = {ddGroup: this.ddGroup};
+			this.enableDragAndDrop();
+		}
+
+		if (this.contextMenuProvider) {
+			this.enableContextMenu();
+		}
+
+		TYPO3.Components.PageTree.Tree.superclass.initComponent.apply(this, arguments);
+	},
+
+	/**
+	 * Refreshes the tree
+	 *
+	 * @param {Function} callback
+	 * @param {Object} scope
+	 * return {void}
+	 */
+	refreshTree: function(callback, scope) {
+			// remove readable rootline elements while refreshing
+		if (!this.inRefreshingMode) {
+			var rootlineElements = Ext.select('.x-tree-node-readableRootline');
+			if (rootlineElements) {
+				rootlineElements.each(function(element) {
+					element.remove();
+				});
+			}
+		}
+
+		this.refreshNode(this.root, callback, scope);
+	},
+
+	/**
+	 * Refreshes a given node
+	 *
+	 * @param {Ext.tree.TreeNode} node
+	 * @param {Function} callback
+	 * @param {Object} scope
+	 * return {void}
+	 */
+	refreshNode: function(node, callback, scope) {
+		if (this.inRefreshingMode) {
+			return;
+		}
+
+		scope = scope || node;
+		this.inRefreshingMode = true;
+		var loadCallback = function(node) {
+			node.ownerTree.inRefreshingMode = false;
+			if (node.ownerTree.restoreState) {
+				node.ownerTree.restoreState(node.getPath());
+			}
+		};
+
+		if (callback) {
+			loadCallback = callback.createSequence(loadCallback);
+		}
+
+		this.getLoader().load(node, loadCallback, scope);
+	},
+
+	/**
+	 * Adds a tree loader implementation that uses the directFn feature
+	 *
+	 * return {void}
+	 */
+	addTreeLoader: function() {
+		this.loader = new Ext.tree.TreeLoader({
+			directFn: this.treeDataProvider.getNextTreeLevel,
+			paramOrder: 'nodeId,attributes',
+			nodeParameter: 'nodeId',
+			baseAttrs: {
+				uiProvider: this.uiProvider
+			},
+
+				// an id can never be zero in ExtJS, but this is needed
+				// for the root line feature or it will never be working!
+			createNode: function(attr) {
+				if (attr.id == 0) {
+					attr.id = 'siteRootNode';
+				}
+
+				return Ext.tree.TreeLoader.prototype.createNode.call(this, attr);
+			},
+
+			listeners: {
+				beforeload: function(treeLoader, node) {
+					treeLoader.baseParams.nodeId = node.id;
+					treeLoader.baseParams.attributes = node.attributes.nodeData;
+				}
+			}
+		});
+	},
+
+	/**
+	 * Enables the context menu feature
+	 *
+	 * return {void}
+	 */
+	enableContextMenu: function() {
+		this.contextMenu = new TYPO3.Components.PageTree.ContextMenu();
+
+		this.on('contextmenu', function(node, event) {
+			this.openContextMenu(node, event);
+		});
+	},
+
+	/**
+	 * Open a context menu for the given node
+	 *
+	 * @param {Ext.tree.TreeNode} node
+	 * @param {Ext.EventObject} event
+	 * return {void}
+	 */
+	openContextMenu: function(node, event) {
+		var attributes = Ext.apply(node.attributes.nodeData, {
+			t3ContextInfo: node.ownerTree.t3ContextInfo
+		});
+
+		this.contextMenuProvider.getActionsForNodeArray(
+			attributes,
+			function(configuration) {
+				this.contextMenu.removeAll();
+				this.contextMenu.fill(node, this, configuration);
+				if (this.contextMenu.items.length) {
+					this.contextMenu.showAt(event.getXY());
+
+				}
+			},
+			this
+		);
+	},
+
+	/**
+	 * Initialize the inline editor for the given tree.
+	 *
+	 * @return {void}
+	 */
+	enableInlineEditor: function() {
+		(new TYPO3.Components.PageTree.TreeEditor(this));
+	},
+
+	/**
+	 * Enables the drag and drop feature
+	 *
+	 * return {void}
+	 */
+	enableDragAndDrop: function() {
+			// init proxy element
+		this.on('startdrag', this.initDd, this);
+		this.on('enddrag', this.stopDd, this);
+
+			// node is moved
+		this.on('movenode', this.moveNode, this);
+
+			// new node is created/copied
+		this.on('beforenodedrop', this.beforeDropNode, this);
+		this.on('nodedrop', this.dropNode, this);
+
+			// listens on the ctrl key to toggle the copy mode
+		(new Ext.KeyMap(document, {
+			key: Ext.EventObject.CONTROL,
+			scope: this,
+			buffer: 250,
+			fn: function() {
+				if (!this.controlKeyPressed && this.dragZone.dragging && this.copyHint) {
+					if (this.shouldCopyNode) {
+						this.copyHint.show();
+					} else {
+						this.copyHint.hide();
+					}
+
+					this.shouldCopyNode = !this.shouldCopyNode;
+					this.dragZone.proxy.el.toggleClass('typo3-pagetree-copy');
+				}
+				this.controlKeyPressed = true;
+			}
+		}, 'keydown'));
+
+		(new Ext.KeyMap(document, {
+			key: Ext.EventObject.CONTROL,
+			scope: this,
+			fn: function() {
+				this.controlKeyPressed = false;
+			}
+		}, 'keyup'));
+
+			// listens on the escape key to stop the dragging
+		(new Ext.KeyMap(document, {
+			key: Ext.EventObject.ESC,
+			scope: this,
+			buffer: 250,
+			fn: function(event) {
+				if (this.dragZone.dragging) {
+					Ext.dd.DragDropMgr.stopDrag(event);
+					this.dragZone.onInvalidDrop(event);
+				}
+			}
+		}, 'keydown'));
+	},
+
+	/**
+	 * Disables the deletion drop zone if configured
+	 *
+	 * @return {void}
+	 */
+	stopDd: function() {
+		if (this.deletionDropZoneId) {
+			Ext.getCmp(this.deletionDropZoneId).hide();
+		}
+	},
+
+	/**
+	 * Enables the deletion drop zone if configured. Also it creates the
+	 * shown dd proxy element.
+	 *
+	 * @return {void}
+	 */
+	initDd: function() {
+		if (this.deletionDropZoneId) {
+			Ext.getCmp(this.deletionDropZoneId).show();
+		}
+		this.initDDProxyElement();
+	},
+
+	/**
+	 * Adds the copy hint to the proxy element
+	 *
+	 * @return {void}
+	 */
+	initDDProxyElement: function() {
+		this.shouldCopyNode = false;
+		this.copyHint = new Ext.Element(document.createElement('div')).addClass(this.id + '-copy');
+		this.copyHint.dom.appendChild(document.createTextNode(TYPO3.Components.PageTree.LLL.copyHint));
+		this.copyHint.setVisibilityMode(Ext.Element.DISPLAY);
+		this.dragZone.proxy.el.shadow = false;
+		this.dragZone.proxy.ghost.dom.appendChild(this.copyHint.dom);
+	},
+
+	/**
+	 * Creates a Fake Node
+	 *
+	 * This must be done to prevent the calling of the moveNode event.
+	 *
+	 * @param {object} dragElement
+	 */
+	beforeDropNode: function(dragElement) {
+		if (dragElement.data && dragElement.data.item && dragElement.data.item.shouldCreateNewNode) {
+			this.t3ContextInfo.serverNodeType = dragElement.data.item.nodeType;
+			dragElement.dropNode = new Ext.tree.TreeNode({
+				text: TYPO3.Components.PageTree.LLL.fakeNodeHint,
+				leaf: true,
+				isInsertedNode: true
+			});
+
+				// fix incorrect cancel value
+			dragElement.cancel = false;
+
+		} else if (this.shouldCopyNode) {
+			dragElement.dropNode.ui.onOut();
+			var attributes = dragElement.dropNode.attributes;
+			attributes.isCopiedNode = true;
+			attributes.id = 'fakeNode';
+			dragElement.dropNode = new Ext.tree.TreeNode(attributes);
+		}
+
+		return true;
+	},
+
+	/**
+	 * Differentiate between the copy and insert event
+	 *
+	 * @param {Ext.tree.TreeDropZone} dragElement
+	 * return {void}
+	 */
+	dropNode: function(dragElement) {
+		this.controlKeyPressed = false;
+		if (dragElement.dropNode.attributes.isInsertedNode) {
+			dragElement.dropNode.attributes.isInsertedNode = false;
+			this.insertNode(dragElement.dropNode);
+		} else if (dragElement.dropNode.attributes.isCopiedNode) {
+			dragElement.dropNode.attributes.isCopiedNode = false;
+			this.copyNode(dragElement.dropNode)
+		}
+	},
+
+	/**
+	 * Moves a node
+	 *
+	 * @param {TYPO3.Components.PageTree.Tree} tree
+	 * @param {Ext.tree.TreeNode} movedNode
+	 * @param {Ext.tree.TreeNode} oldParent
+	 * @param {Ext.tree.TreeNode} newParent
+	 * @param {int} position
+	 * return {void}
+	 */
+	moveNode: function(tree, movedNode, oldParent, newParent, position) {
+		this.controlKeyPressed = false;
+		tree.t3ContextNode = movedNode;
+
+		if (position === 0) {
+			this.commandProvider.moveNodeToFirstChildOfDestination(newParent, tree);
+		} else {
+			var previousSiblingNode = newParent.childNodes[position - 1];
+			this.commandProvider.moveNodeAfterDestination(previousSiblingNode, tree);
+		}
+	},
+
+	/**
+	 * Inserts a node
+	 *
+	 * @param {Ext.tree.TreeNode} movedNode
+	 * return {void}
+	 */
+	insertNode: function(movedNode) {
+		this.t3ContextNode = movedNode.parentNode;
+
+		movedNode.disable();
+		if (movedNode.previousSibling) {
+			this.commandProvider.insertNodeAfterDestination(movedNode, this);
+		} else {
+			this.commandProvider.insertNodeToFirstChildOfDestination(movedNode, this);
+		}
+	},
+
+	/**
+	 * Copies a node
+	 *
+	 * @param {Ext.tree.TreeNode} movedNode
+	 * return {void}
+	 */
+	copyNode: function(movedNode) {
+		this.t3ContextNode = movedNode;
+
+		movedNode.disable();
+		if (movedNode.previousSibling) {
+			this.commandProvider.copyNodeAfterDestination(movedNode, this);
+		} else {
+			this.commandProvider.copyNodeToFirstChildOfDestination(movedNode, this);
+		}
+	}
+});
+
+// XTYPE Registration
+Ext.reg('TYPO3.Components.PageTree.Tree', TYPO3.Components.PageTree.Tree);
\ No newline at end of file
Index: t3lib/js/extjs/components/pagetree/javascript/app.js
===================================================================
--- t3lib/js/extjs/components/pagetree/javascript/app.js	(Revision 0)
+++ t3lib/js/extjs/components/pagetree/javascript/app.js	(Revision 0)
@@ -0,0 +1,407 @@
+/***************************************************************
+*  Copyright notice
+*
+*  (c) 2010 TYPO3 Tree Team <http://forge.typo3.org/projects/typo3v4-extjstrees>
+*  All rights reserved
+*
+*  This script is part of the TYPO3 project. The TYPO3 project is
+*  free software; you can redistribute it and/or modify
+*  it under the terms of the GNU General Public License as published by
+*  the Free Software Foundation; either version 2 of the License, or
+*  (at your option) any later version.
+*
+*  The GNU General Public License can be found at
+*  http://www.gnu.org/copyleft/gpl.html.
+*  A copy is found in the textfile GPL.txt and important notices to the license
+*  from the author is found in LICENSE.txt distributed with these scripts.
+*
+*
+*  This script is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*  GNU General Public License for more details.
+*
+*  This copyright notice MUST APPEAR in all copies of the script!
+***************************************************************/
+Ext.namespace('TYPO3.Components.PageTree');
+
+/**
+ * @class TYPO3.Components.PageTree.App
+ *
+ * Page tree main application that controls setups the components
+ *
+ * @namespace TYPO3.Components.PageTree
+ * @extends Ext.Panel
+ * @author Stefan Galinski <stefan.galinski@gmail.com>
+ */
+TYPO3.Components.PageTree.App = Ext.extend(Ext.Panel, {
+	/**
+	 * Panel id
+	 *
+	 * @type {String}
+	 */
+	id: 'typo3-pagetree',
+
+	/**
+	 * Border
+	 *
+	 * @type {Boolean}
+	 */
+	border: false,
+
+	/**
+	 * Layout Type
+	 *
+	 * @type {String}
+	 */
+	layout:'fit',
+
+	/**
+	 * Active tree
+	 *
+	 * @type {TYPO3.Components.PageTree.Tree}
+	 */
+	activeTree: null,
+
+	/**
+	 * Listeners
+	 *
+	 * The afterlayout wizard relayoutes the navigation container to fix some nasty
+	 * scrollbar issues.
+	 *
+	 * @type {Object}
+	 */
+	listeners: {
+		afterlayout: {
+			fn: function() {
+				this.ownerCt.doLayout();
+			},
+			buffer: 250
+		}
+	},
+
+	/**
+	 * Initializes the application
+	 *
+	 * Set's the necessary language labels, configuration options and sprite icons by an
+	 * external call and initializes the needed components.
+	 *
+	 * @return {void}
+	 */
+	initComponent: function() {
+		TYPO3.Components.PageTree.DataProvider.loadResources(function(response) {
+			TYPO3.Components.PageTree.LLL = response['LLL'];
+			TYPO3.Components.PageTree.Configuration = response['Configuration'];
+			TYPO3.Components.PageTree.Sprites = response['Sprites'];
+
+			var tree = this.activeTree = new TYPO3.Components.PageTree.Tree({
+				id: this.id + '-tree',
+				deletionDropZoneId: this.id + '-deletionDropZone',
+				ddGroup: this.id,
+				stateful: true,
+				stateId: 'Pagetree' + TYPO3.Components.PageTree.Configuration.temporaryMountPoint,
+				stateEvents: [],
+				autoScroll: true,
+				autoHeight: false,
+				plugins: new Ext.ux.state.TreePanel(),
+				commandProvider: TYPO3.Components.PageTree.Actions,
+				contextMenuProvider: TYPO3.Components.PageTree.ContextMenuDataProvider,
+				treeDataProvider: TYPO3.Components.PageTree.DataProvider,
+				listeners: {
+					resize: {
+						fn: function() {
+							var treeContainer = Ext.getCmp(this.id + '-treeContainer');
+							Ext.getCmp(this.id + '-filteringTree').setSize(treeContainer.getSize());
+							treeContainer.doLayout();
+						},
+						scope: this,
+						buffer: 250
+					}
+				}
+			});
+
+			var filteringTree = new TYPO3.Components.PageTree.FilteringTree({
+				id: this.id + '-filteringTree',
+				deletionDropZoneId: this.id + '-deletionDropZone',
+				ddGroup: this.id,
+				autoScroll: true,
+				autoHeight: false,
+				commandProvider: TYPO3.Components.PageTree.Actions,
+				contextMenuProvider: TYPO3.Components.PageTree.ContextMenuDataProvider,
+				treeDataProvider: TYPO3.Components.PageTree.DataProvider
+			}).hide();
+
+			var topPanel = new TYPO3.Components.PageTree.TopPanel({
+				dataProvider: TYPO3.Components.PageTree.DataProvider,
+				filteringTree: filteringTree,
+				ddGroup: this.id,
+				tree: tree,
+				app: this
+			});
+
+			var deletionDropZone = new TYPO3.Components.PageTree.DeletionDropZone({
+				id: this.id + '-deletionDropZone',
+				commandProvider: TYPO3.Components.PageTree.Actions,
+				ddGroup: this.id,
+				app: this,
+				region: 'south',
+				height: 35
+			});
+
+			var topPanelItems = new Ext.Panel({
+				id: this.id + '-topPanelItems',
+				border: false,
+				region: 'north',
+				height: 49,
+				items: [
+					topPanel, {
+						border: false,
+						id: this.id + '-indicatorBar'
+					}
+				]
+			});
+
+			this.add({
+				layout: 'border',
+				items: [
+					topPanelItems,
+					{
+						border: false,
+						id: this.id + '-treeContainer',
+						region: 'center',
+						layout: 'fit',
+						items: [tree, filteringTree]
+					},
+					deletionDropZone
+				]
+			});
+
+			if (TYPO3.Components.PageTree.Configuration.temporaryMountPoint) {
+				topPanelItems.on('afterrender', function() {
+					this.addTemporaryMountPointIndicator();
+				}, this);
+			}
+
+			if (TYPO3.Components.PageTree.Configuration.indicator !== '') {
+				this.addIndicatorItems();
+			}
+		}, this);
+
+		TYPO3.Components.PageTree.App.superclass.initComponent.apply(this, arguments);
+	},
+
+	/**
+	 * Adds the default indicator items
+	 *
+	 * @return {void}
+	 */
+	addIndicatorItems: function() {
+		this.addIndicator({
+			border: false,
+			id: this.id + '-indicatorBar-indicatorTitle',
+			cls: this.id + '-indicatorBar-item',
+			html: TYPO3.Components.PageTree.Configuration.indicator
+		});
+	},
+
+	/**
+	 * Adds the temporary mount point indicator item
+	 *
+	 * @return {void}
+	 */
+	addTemporaryMountPointIndicator: function() {
+		this.temporaryMountPointInfoIndicator = this.addIndicator({
+			border: false,
+			id: this.id + '-indicatorBar-temporaryMountPoint',
+			cls: this.id + '-indicatorBar-item',
+
+			listeners: {
+				afterrender: {
+					fn: function() {
+						var element = Ext.fly(this.id + '-indicatorBar-temporaryMountPoint-clear');
+						element.on('click', function() {
+							TYPO3.BackendUserSettings.ExtDirect.unsetKey(
+								'pageTree_temporaryMountPoint',
+								function() {
+									TYPO3.Components.PageTree.Configuration.temporaryMountPoint = null;
+									this.removeIndicator(this.temporaryMountPointInfoIndicator);
+									this.getTree().refreshTree();
+									this.getTree().stateId = 'Pagetree';
+								},
+								this
+							);
+						}, this);
+					},
+					scope: this
+				}
+			},
+
+			html: '<p>' +
+					'<span id="' + this.id + '-indicatorBar-temporaryMountPoint-info' + '" ' +
+						'class="' + this.id + '-indicatorBar-item-leftIcon ' +
+							TYPO3.Components.PageTree.Sprites.Info + '">&nbsp;' +
+					'</span>' +
+					'<span id="' + this.id + '-indicatorBar-temporaryMountPoint-clear' + '" ' +
+						'class="' + this.id + '-indicatorBar-item-rightIcon ' + '">X' +
+					'</span>' +
+					TYPO3.Components.PageTree.LLL.temporaryMountPointIndicatorInfo + '<br />' +
+						TYPO3.Components.PageTree.Configuration.temporaryMountPoint +
+				'</p>'
+		});
+	},
+
+	/**
+	 * Adds an indicator item
+	 *
+	 * @param {Object} component
+	 * @return {void}
+	 */
+	addIndicator: function(component) {
+		if (component.listeners && component.listeners.afterrender) {
+			component.listeners.afterrender.fn = component.listeners.afterrender.fn.createSequence(
+				this.afterTopPanelItemAdded, this
+			);
+		} else {
+			if (component.listeners) {
+				component.listeners = {}
+			}
+
+			component.listeners.afterrender = {
+				fn: this.afterTopPanelItemAdded
+			}
+		}
+
+		return Ext.getCmp(this.id + '-indicatorBar').add(component);
+	},
+
+	/**
+	 * Recalculates the top panel items height after an indicator was added
+	 *
+	 * @param {Ext.Component} component
+	 * @return {void}
+	 */
+	afterTopPanelItemAdded: function(component) {
+		var topPanelItems = Ext.getCmp(this.id + '-topPanelItems');
+		topPanelItems.setHeight(topPanelItems.getHeight() + component.getHeight() + 3);
+	},
+
+	/**
+	 * Removes an indicator item from the indicator bar
+	 *
+	 * @param {Ext.Component} component
+	 * @return {void}
+	 */
+	removeIndicator: function(component) {
+		var topPanelItems = Ext.getCmp(this.id + '-topPanelItems');
+		topPanelItems.setHeight(topPanelItems.getHeight() - component.getHeight() - 3);
+		Ext.getCmp(this.id + '-indicatorBar').remove(component);
+	},
+
+	/**
+	 * Compatibility method that calls refreshTree()
+	 *
+	 * @return {void}
+	 */
+	refresh: function() {
+		this.refreshTree();
+	},
+
+	/**
+	 * Another compatibility method that calls refreshTree()
+	 *
+	 * @return {void}
+	 */
+	refresh_nav: function() {
+		this.refreshTree();
+	},
+
+	/**
+	 * Refreshes the tree and selects the node defined by fsMod.recentIds['web']
+	 *
+	 * @return {void}
+	 */
+	refreshTree: function() {
+		if (!isNaN(fsMod.recentIds['web']) && fsMod.recentIds['web'] !== '') {
+			this.select(fsMod.recentIds['web'], true);
+		}
+
+		TYPO3.Components.PageTree.DataProvider.getIndicators(function(response) {
+			var indicators = Ext.getCmp(this.id + '-indicatorBar-indicatorTitle');
+			if (indicators) {
+				this.removeIndicator(indicators);
+			}
+
+			if (response._COUNT > 0) {
+				TYPO3.Components.PageTree.Configuration.indicator = response.html;
+				this.addIndicatorItems();
+			}
+		}, this);
+
+		this.activeTree.refreshTree();
+	},
+
+	/**
+	 * Returns the current active tree
+	 *
+	 * @return {TYPO3.Components.PageTree.Tree}
+	 */
+	getTree: function() {
+		return this.activeTree;
+	},
+
+	/**
+	 * Selects a node defined by the page id. If the second parameter is set, we
+	 * store the new location into the state hash.
+	 *
+	 * @param {int} pageId
+	 * @param {Boolean} saveState
+	 * @return {Boolean}
+	 */
+	select: function(pageId, saveState) {
+		if (saveState !== false) {
+			saveState = true;
+		}
+
+		var tree = this.getTree();
+		var succeeded = false;
+		var node = tree.getRootNode().findChild('realId', pageId, true);
+		if (node) {
+			succeeded = true;
+			tree.selectPath(node.getPath());
+			if (!!saveState && tree.stateHash) {
+				tree.stateHash.lastSelectedNode = node.id;
+			}
+		}
+
+		return succeeded;
+	},
+
+	/**
+	 * Returns the currently selected node
+	 *
+	 * @return {Ext.tree.TreeNode}
+	 */
+	getSelected: function() {
+		var node = this.getTree().getSelectionModel().getSelectedNode();
+		return node ? node : null;
+	}
+});
+
+/**
+ * Callback method for the module menu
+ *
+ * @return {TYPO3.Components.PageTree.App}
+ */
+TYPO3.ModuleMenu.App.registerNavigationComponent('typo3-pagetree', function() {
+	TYPO3.Backend.NavigationContainer.PageTree = new TYPO3.Components.PageTree.App();
+
+		// compatibility code
+    top.nav = TYPO3.Backend.NavigationContainer.PageTree;
+    top.nav_frame = TYPO3.Backend.NavigationContainer.PageTree;
+    top.content.nav_frame = TYPO3.Backend.NavigationContainer.PageTree;
+
+	return TYPO3.Backend.NavigationContainer.PageTree;
+});
+
+// XTYPE Registration
+Ext.reg('TYPO3.Components.PageTree.App', TYPO3.Components.PageTree.App);
\ No newline at end of file
Index: t3lib/js/extjs/components/pagetree/javascript/actions.js
===================================================================
--- t3lib/js/extjs/components/pagetree/javascript/actions.js	(Revision 0)
+++ t3lib/js/extjs/components/pagetree/javascript/actions.js	(Revision 0)
@@ -0,0 +1,709 @@
+/***************************************************************
+*  Copyright notice
+*
+*  (c) 2010 TYPO3 Tree Team <http://forge.typo3.org/projects/typo3v4-extjstrees>
+*  All rights reserved
+*
+*  This script is part of the TYPO3 project. The TYPO3 project is
+*  free software; you can redistribute it and/or modify
+*  it under the terms of the GNU General Public License as published by
+*  the Free Software Foundation; either version 2 of the License, or
+*  (at your option) any later version.
+*
+*  The GNU General Public License can be found at
+*  http://www.gnu.org/copyleft/gpl.html.
+*  A copy is found in the textfile GPL.txt and important notices to the license
+*  from the author is found in LICENSE.txt distributed with these scripts.
+*
+*
+*  This script is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*  GNU General Public License for more details.
+*
+*  This copyright notice MUST APPEAR in all copies of the script!
+***************************************************************/
+Ext.namespace('TYPO3.Components.PageTree');
+
+/**
+ * @class TYPO3.Components.PageTree.Actions
+ *
+ * Actions dedicated for the page tree
+ *
+ * @namespace TYPO3.Components.PageTree
+ * @author Stefan Galinski <stefan.galinski@gmail.com>
+ */
+TYPO3.Components.PageTree.Actions = {
+	/**
+	 * Evaluates a response from an ext direct call and shows a flash message
+	 * if it was an exceptional result
+	 *
+	 * @param {Object} response
+	 * @return {Boolean}
+	 */
+	evaluateResponse: function(response) {
+		if (response.success === false) {
+			TYPO3.Flashmessage.display(4, 'Exception', response.message);
+			return false;
+		}
+
+		return true;
+	},
+
+	/**
+	 * Releases the cut and copy mode from the context menu
+	 *
+	 * @param {TYPO3.Components.PageTree.Tree} tree
+	 * @return {void}
+	 */
+	releaseCutAndCopyModes: function(tree) {
+		tree.t3ContextInfo.inCutMode = false;
+		tree.t3ContextInfo.inCopyMode = false;
+
+		if (tree.t3ContextNode) {
+			tree.t3ContextNode.attributes.nodeData.t3InCutMode = false;
+			tree.t3ContextNode.attributes.nodeData.t3InCopyMode = false;
+			tree.t3ContextNode = null;
+		}
+	},
+
+	/**
+	 * Updates an existing node with the given alternative. The new tree node
+	 * is returned afterwards.
+	 *
+	 * @param {Ext.tree.TreeNode} node
+	 * @param {Boolean} isExpanded
+	 * @param {Object} updatedNode
+	 * @return {Ext.tree.TreeNode}
+	 */
+	updateNode: function(node, isExpanded, updatedNode) {
+		if (!updatedNode) {
+			return null;
+		}
+
+		updatedNode.uiProvider = node.ownerTree.uiProvider;
+		var newTreeNode = new Ext.tree.TreeNode(updatedNode);
+
+		node.parentNode.replaceChild(newTreeNode, node);
+		newTreeNode.ownerTree.refreshNode(newTreeNode, function() {
+			newTreeNode.parentNode.expand(false, false);
+			if (isExpanded) {
+				newTreeNode.expand(false, false);
+			} else {
+				newTreeNode.collapse(false, false);
+			}
+		});
+
+		return newTreeNode;
+	},
+
+	/**
+	 * Shows deletion confirmation window
+	 *
+	 * @param {Ext.tree.TreeNode} node
+	 * @param {TYPO3.Components.PageTree.Tree} tree
+	 * @return {void}
+	 */
+	confirmDelete: function(node, tree) {
+		TYPO3.Components.PageTree.Commands.getConfirmContentDeletionMessage(node.attributes.nodeData.id, function(message, options) {
+			Ext.Msg.show({
+				title: message.title,
+				msg: message.message,
+				buttons: Ext.Msg.YESNO,
+				fn: function (answer, text, button) {
+					if (answer === 'yes') {
+						TYPO3.Components.PageTree.Actions.deleteNode(node, tree);
+						return true;
+					}
+					return false;
+				},
+				animEl: 'elId'
+			});
+		}, this);
+	},
+
+	/**
+	 * Deletes a node directly
+	 *
+	 * @param {Ext.tree.TreeNode} node
+	 * @param {TYPO3.Components.PageTree.Tree} tree
+	 * @return {void}
+	 */
+	deleteNode: function(node, tree) {
+		TYPO3.Components.PageTree.Commands.deleteNode(
+			node.attributes.nodeData,
+			function(response) {
+				if (this.evaluateResponse(response)) {
+						// the node may not be removed in workspace mode
+					if (top.TYPO3.configuration.inWorkspace && response.id) {
+						this.updateNode(node, node.isExpanded(), response);
+					} else {
+						node.remove();
+					}
+				}
+			},
+			this
+		);
+	},
+
+	/**
+	 * Removes a node either directly or first shows deletion popup
+	 *
+	 * @param {Ext.tree.TreeNode} node
+	 * @param {TYPO3.Components.PageTree.Tree} tree
+	 * @return {void}
+	 */
+	removeNode: function(node, tree) {
+		if (TYPO3.Components.PageTree.Configuration.displayDeleteConfirmation) {
+			this.confirmDelete(node);
+		} else {
+			this.deleteNode(node, tree);
+		}
+	},
+
+	
+
+	/**
+	 * Restores a given node and moves it to the given destination inside the tree. Use this
+	 * method if you want to add it as the first child of the destination.
+	 *
+	 * @param {Ext.tree.TreeNode} node
+	 * @param {TYPO3.Components.PageTree.Tree} tree
+	 * @param {Ext.tree.TreeNode} destination
+	 * @return {void}
+	 */
+	restoreNodeToFirstChildOfDestination: function(node, tree, destination) {
+		TYPO3.Components.PageTree.Commands.restoreNode(
+			node.attributes.nodeData,
+			destination.attributes.nodeData.id,
+			function(updatedNode) {
+				if (this.evaluateResponse(updatedNode)) {
+					var newTreeNode = new Ext.tree.TreeNode(
+						Ext.apply(node.attributes, updatedNode)
+					);
+					destination.insertBefore(newTreeNode, destination.firstChild);
+				}
+			},
+			this
+		);
+	},
+
+	/**
+	 * Restores a given node and moves it to the given destination inside the tree. Use this
+	 * method if you want to add the node after the destination node.
+	 *
+	 * @param {Ext.tree.TreeNode} node
+	 * @param {TYPO3.Components.PageTree.Tree} tree
+	 * @param {Ext.tree.TreeNode} destination
+	 * @return {void}
+	 */
+	restoreNodeAfterDestination: function(node, tree, destination) {
+		TYPO3.Components.PageTree.Commands.restoreNode(
+			node.attributes.nodeData,
+			-destination.attributes.nodeData.id,
+			function(updatedNode) {
+				if (this.evaluateResponse(updatedNode)) {
+					var newTreeNode = new Ext.tree.TreeNode(
+						Ext.apply(node.attributes, updatedNode)
+					);
+					destination.parentNode.insertBefore(newTreeNode, destination.nextSibling);
+				}
+			},
+			this
+		);
+	},
+
+	/**
+	 * Collapses a whole tree branch
+	 *
+	 * @param {Ext.tree.TreeNode} node
+	 * @return {void}
+	 */
+	collapseBranch: function(node) {
+		node.collapseChildNodes(true);
+		node.collapse();
+	},
+
+	/**
+	 * Expands a whole tree branch
+	 *
+	 * @param {Ext.tree.TreeNode} node
+	 * @return {void}
+	 */
+	expandBranch: function(node) {
+		node.expand();
+		node.expandChildNodes(true);
+	},
+
+	/**
+	 * Opens a popup windows for previewing the given node/page
+	 *
+	 * @param {Ext.tree.TreeNode} node
+	 * @return {void}
+	 */
+	viewPage: function(node) {
+		TYPO3.Components.PageTree.Commands.getViewLink(
+			node.attributes.nodeData,
+			function(result) {
+				openUrlInWindow(result, 'typo3ContextMenuView');
+			}
+		);
+	},
+
+	/**
+	 * Creates a temporary tree mount point
+	 *
+	 * @param {Ext.tree.TreeNode} node
+	 * @param {TYPO3.Components.PageTree.Tree} tree
+	 * @return {void}
+	 */
+	mountAsTreeRoot: function(node, tree) {
+		TYPO3.Components.PageTree.Commands.setTemporaryMountPoint(
+			node.attributes.nodeData,
+			function(response) {
+				if (TYPO3.Components.PageTree.Configuration.temporaryMountPoint) {
+					TYPO3.Backend.NavigationContainer.PageTree.removeIndicator(
+						TYPO3.Backend.NavigationContainer.PageTree.temporaryMountPointInfoIndicator
+					);
+				}
+
+				TYPO3.Components.PageTree.Configuration.temporaryMountPoint = response;
+				TYPO3.Backend.NavigationContainer.PageTree.addTemporaryMountPointIndicator();
+
+				var selectedNode = TYPO3.Backend.NavigationContainer.PageTree.getSelected();
+				tree.stateId = 'Pagetree' + TYPO3.Components.PageTree.Configuration.temporaryMountPoint;
+				tree.refreshTree(function() {
+					var nodeIsSelected = false;
+					if (selectedNode) {
+						nodeIsSelected = TYPO3.Backend.NavigationContainer.PageTree.select(
+							selectedNode.attributes.nodeData.id
+						);
+					}
+
+					var node = (nodeIsSelected ? TYPO3.Backend.NavigationContainer.PageTree.getSelected() : null);
+					if (node) {
+						this.singleClick(node, tree);
+					} else {
+						this.singleClick(tree.getRootNode().firstChild, tree);
+					}
+				}, this);
+			},
+			this
+		);
+	},
+
+	/**
+	 * Opens the edit page properties dialog
+	 *
+	 * @param {Ext.tree.TreeNode} node
+	 * @return {void}
+	 */
+	editPageProperties: function(node) {
+		node.select();
+		TYPO3.Backend.ContentContainer.setUrl(
+			'alt_doc.php?edit[pages][' + node.attributes.nodeData.id + ']=edit'
+		);
+	},
+
+	/**
+	 * Opens the new page wizard
+	 *
+	 * @param {Ext.tree.TreeNode} node
+	 * @return {void}
+	 */
+	newPageWizard: function(node) {
+		node.select();
+		TYPO3.Backend.ContentContainer.setUrl(
+			'db_new.php?id=' + node.attributes.nodeData.id + '&pagesOnly=1'
+		);
+	},
+
+	/**
+	 * Opens the info popup
+	 *
+	 * @param {Ext.tree.TreeNode} node
+	 * @return {void}
+	 */
+	openInfoPopUp: function(node) {
+		launchView('pages', node.attributes.nodeData.id);
+	},
+
+	/**
+	 * Opens the history popup
+	 *
+	 * @param {Ext.tree.TreeNode} node
+	 * @return {void}
+	 */
+	openHistoryPopUp: function(node) {
+		node.select();
+		TYPO3.Backend.ContentContainer.setUrl(
+			'show_rechis.php?element=pages:' + node.attributes.nodeData.id
+		);
+	},
+
+	/**
+	 * Opens the export .t3d file dialog
+	 *
+	 * @param {Ext.tree.TreeNode} node
+	 * @return {void}
+	 */
+	exportT3d: function(node) {
+		node.select();
+		TYPO3.Backend.ContentContainer.setUrl(
+			'sysext/impexp/app/index.php?tx_impexp[action]=export&' +
+				'id=0&tx_impexp[pagetree][id]=' + node.attributes.nodeData.id +
+				'&tx_impexp[pagetree][levels]=' + node.attributes.nodeData.id +
+				'&tx_impexp[pagetree][tables][]=_ALL'
+		);
+	},
+
+	/**
+	 * Opens the import .t3d file dialog
+	 *
+	 * @param {Ext.tree.TreeNode} node
+	 * @return {void}
+	 */
+	importT3d: function(node) {
+		node.select();
+		TYPO3.Backend.ContentContainer.setUrl(
+			'sysext/impexp/app/index.php?id=' + node.attributes.nodeData.id +
+				'&table=pages&tx_impexp[action]=import'
+		);
+	},
+
+	/**
+	 * Enables the cut mode of a node
+	 *
+	 * @param {Ext.tree.TreeNode} node
+	 * @param {TYPO3.Components.PageTree.Tree} tree
+	 * @return {void}
+	 */
+	enableCutMode: function(node, tree) {
+		this.disableCopyMode(node, tree);
+		node.attributes.nodeData.t3InCutMode = true;
+		tree.t3ContextInfo.inCutMode = true;
+		tree.t3ContextNode = node;
+	},
+
+	/**
+	 * Disables the cut mode of a node
+	 *
+	 * @param {Ext.tree.TreeNode} node
+	 * @param {TYPO3.Components.PageTree.Tree} tree
+	 * @return {void}
+	 */
+	disableCutMode: function(node, tree) {
+		this.releaseCutAndCopyModes(tree);
+		node.attributes.nodeData.t3InCutMode = false;
+	},
+
+	/**
+	 * Enables the copy mode of a node
+	 *
+	 * @param {Ext.tree.TreeNode} node
+	 * @param {TYPO3.Components.PageTree.Tree} tree
+	 * @return {void}
+	 */
+	enableCopyMode: function(node, tree) {
+		this.disableCutMode(node, tree);
+		node.attributes.nodeData.t3InCopyMode = true;
+		tree.t3ContextInfo.inCopyMode = true;
+		tree.t3ContextNode = node;
+	},
+
+	/**
+	 * Disables the copy mode of a node
+	 *
+	 * @param {Ext.tree.TreeNode} node
+	 * @param {TYPO3.Components.PageTree.Tree} tree
+	 * @return {void}
+	 */
+	disableCopyMode: function(node, tree) {
+		this.releaseCutAndCopyModes(tree);
+		node.attributes.nodeData.t3InCopyMode = false;
+	},
+
+	/**
+	 * Pastes the cut/copy context node into the given node
+	 *
+	 * @param {Ext.tree.TreeNode} node
+	 * @param {TYPO3.Components.PageTree.Tree} tree
+	 * @return {void}
+	 */
+	pasteIntoNode: function(node, tree) {
+		if (!tree.t3ContextNode) {
+			return;
+		}
+
+		if (tree.t3ContextInfo.inCopyMode) {
+			var newNode = tree.t3ContextNode = new Ext.tree.TreeNode(tree.t3ContextNode.attributes);
+			newNode.id = 'fakeNode';
+			node.insertBefore(newNode, node.childNodes[0]);
+			node.attributes.nodeData.t3InCopyMode = false;
+			this.copyNodeToFirstChildOfDestination(newNode, tree);
+
+		} else if (tree.t3ContextInfo.inCutMode) {
+			if (node.getPath().indexOf(tree.t3ContextNode.id) !== -1) {
+				return;
+			}
+			
+			node.appendChild(tree.t3ContextNode);
+			node.attributes.nodeData.t3InCutMode = false;
+			this.moveNodeToFirstChildOfDestination(node, tree);
+		}
+	},
+
+	/**
+	 * Pastes a cut/copy context node after the given node
+	 *
+	 * @param {Ext.tree.TreeNode} node
+	 * @param {TYPO3.Components.PageTree.Tree} tree
+	 * @return {void}
+	 */
+	pasteAfterNode: function(node, tree) {
+		if (!tree.t3ContextNode) {
+			return;
+		}
+
+		if (tree.t3ContextInfo.inCopyMode) {
+			var newNode = tree.t3ContextNode = new Ext.tree.TreeNode(tree.t3ContextNode.attributes);
+			newNode.id = 'fakeNode';
+			node.parentNode.insertBefore(newNode, node.nextSibling);
+			node.attributes.nodeData.t3InCopyMode = false;
+			this.copyNodeAfterDestination(newNode, tree);
+
+		} else if (tree.t3ContextInfo.inCutMode) {
+			if (node.getPath().indexOf(tree.t3ContextNode.id) !== -1) {
+				return;
+			}
+
+			node.parentNode.insertBefore(tree.t3ContextNode, node.nextSibling);
+			node.attributes.nodeData.t3InCutMode = false;
+			this.moveNodeAfterDestination(node, tree);
+		}
+	},
+
+	/**
+	 * Moves the current tree context node after the given node
+	 *
+	 * @param {Ext.tree.TreeNode} node
+	 * @param {TYPO3.Components.PageTree.Tree} tree
+	 * @return {void}
+	 */
+	moveNodeAfterDestination: function(node, tree) {
+		TYPO3.Components.PageTree.Commands.moveNodeAfterDestination(
+			tree.t3ContextNode.attributes.nodeData,
+			node.attributes.nodeData.id,
+			function(response) {
+				if (this.evaluateResponse(response) && tree.t3ContextNode) {
+					this.updateNode(tree.t3ContextNode, tree.t3ContextNode.isExpanded(), response);
+				}
+				this.releaseCutAndCopyModes(tree);
+			},
+			this
+		);
+	},
+
+	/**
+	 * Moves the current tree context node as the first child of the given node
+	 *
+	 * @param {Ext.tree.TreeNode} node
+	 * @param {TYPO3.Components.PageTree.Tree} tree
+	 * @return {void}
+	 */
+	moveNodeToFirstChildOfDestination: function(node, tree) {
+		TYPO3.Components.PageTree.Commands.moveNodeToFirstChildOfDestination(
+			tree.t3ContextNode.attributes.nodeData,
+			node.attributes.nodeData.id,
+			function(response) {
+				if (this.evaluateResponse(response) && tree.t3ContextNode) {
+					this.updateNode(tree.t3ContextNode, tree.t3ContextNode.isExpanded(), response);
+				}
+				this.releaseCutAndCopyModes(tree);
+			},
+			this
+		);
+	},
+
+	/**
+	 * Inserts a new node after the given node
+	 *
+	 * @param {Ext.tree.TreeNode} node
+	 * @param {TYPO3.Components.PageTree.Tree} tree
+	 * @return {void}
+	 */
+	insertNodeAfterDestination: function(node, tree) {
+		TYPO3.Components.PageTree.Commands.insertNodeAfterDestination(
+			tree.t3ContextNode.attributes.nodeData,
+			node.previousSibling.attributes.nodeData.id,
+			tree.t3ContextInfo.serverNodeType,
+			function(response) {
+				if (this.evaluateResponse(response)) {
+					this.updateNode(node, node.isExpanded(), response);
+				}
+				this.releaseCutAndCopyModes(tree);
+			},
+			this
+		);
+	},
+
+	/**
+	 * Inserts a new node as the first child of the given node
+	 *
+	 * @param {Ext.tree.TreeNode} node
+	 * @param {TYPO3.Components.PageTree.Tree} tree
+	 * @return {void}
+	 */
+	insertNodeToFirstChildOfDestination: function(node, tree) {
+		TYPO3.Components.PageTree.Commands.insertNodeToFirstChildOfDestination(
+			tree.t3ContextNode.attributes.nodeData,
+			tree.t3ContextInfo.serverNodeType,
+			function(response) {
+				if (this.evaluateResponse(response)) {
+					node = this.updateNode(node, true, response);
+				}
+				this.releaseCutAndCopyModes(tree);
+			},
+			this
+		);
+	},
+
+	/**
+	 * Copies the current tree context node after the given node
+	 *
+	 * @param {Ext.tree.TreeNode} node
+	 * @param {TYPO3.Components.PageTree.Tree} tree
+	 * @return {void}
+	 */
+	copyNodeAfterDestination: function(node, tree) {
+		TYPO3.Components.PageTree.Commands.copyNodeAfterDestination(
+			tree.t3ContextNode.attributes.nodeData,
+			node.previousSibling.attributes.nodeData.id,
+			function(response) {
+				if (this.evaluateResponse(response)) {
+					this.updateNode(node, true, response);
+				}
+				this.releaseCutAndCopyModes(tree);
+			},
+			this
+		);
+	},
+
+	/**
+	 * Copies the current tree context node as the first child of the given node
+	 *
+	 * @param {Ext.tree.TreeNode} node
+	 * @param {TYPO3.Components.PageTree.Tree} tree
+	 * @return {void}
+	 */
+	copyNodeToFirstChildOfDestination: function(node, tree) {
+		TYPO3.Components.PageTree.Commands.copyNodeToFirstChildOfDestination(
+			tree.t3ContextNode.attributes.nodeData,
+			node.parentNode.attributes.nodeData.id,
+			function(response) {
+				if (this.evaluateResponse(response)) {
+					this.updateNode(node, true, response);
+				}
+				this.releaseCutAndCopyModes(tree);
+			},
+			this
+		);
+	},
+
+	/**
+	 * Visibilizes a page
+	 *
+	 * @param {Ext.tree.TreeNode} node
+	 * @return {void}
+	 */
+	enablePage: function(node) {
+		TYPO3.Components.PageTree.Commands.visiblyNode(
+			node.attributes.nodeData,
+			function(response) {
+				if (this.evaluateResponse(response)) {
+					this.updateNode(node, node.isExpanded(), response);
+				}
+			},
+			this
+		);
+	},
+
+	/**
+	 * Disables a page
+	 *
+	 * @param {Ext.tree.TreeNode} node
+	 * @return {void}
+	 */
+	disablePage: function(node) {
+		TYPO3.Components.PageTree.Commands.disableNode(
+			node.attributes.nodeData,
+			function(response) {
+				if (this.evaluateResponse(response)) {
+					this.updateNode(node, node.isExpanded(), response);
+				}
+			},
+			this
+		);
+	},
+
+	/**
+	 * Reloads the content frame with the current module and node id
+	 *
+	 * @param {Ext.tree.TreeNode} node
+	 * @param {TYPO3.Components.PageTree.Tree} tree
+	 * @return {void}
+	 */
+	singleClick: function(node, tree) {
+		var separator = '?';
+		if (currentSubScript.indexOf('?') !== -1) {
+			separator = '&';
+		}
+
+		node.select();
+		if (tree.stateHash) {
+			tree.stateHash.lastSelectedNode = node.id;
+		}
+
+		TYPO3.Backend.ContentContainer.setUrl(
+			TS.PATH_typo3 + currentSubScript + separator + 'id=' + node.attributes.nodeData.id
+		);
+	},
+
+	/**
+	 * Updates the title of a node
+	 *
+	 * @param {Ext.tree.TreeNode} node
+	 * @param {String} newText
+	 * @param {String} oldText
+	 * @param {TYPO3.Components.PageTree.TreeEditor} treeEditor
+	 * @return {void}
+	 */
+	saveTitle: function(node, newText, oldText, treeEditor) {
+		this.singleClick(node.editNode, node.editNode.ownerTree);
+		if (newText === oldText || newText == '') {
+			treeEditor.updateNodeText(
+				node,
+				node.editNode.attributes.nodeData.editableText,
+				Ext.util.Format.htmlEncode(oldText)
+			);
+			return;
+		}
+
+		TYPO3.Components.PageTree.Commands.updateLabel(
+			node.editNode.attributes.nodeData,
+			newText,
+			function(response) {
+				if (this.evaluateResponse(response)) {
+					treeEditor.updateNodeText(node, response.editableText, response.updatedText);
+				} else {
+					treeEditor.updateNodeText(
+						node,
+						node.editNode.attributes.nodeData.editableText,
+						Ext.util.Format.htmlEncode(oldText)
+					);
+				}
+			},
+			this
+		);
+	}
+};
\ No newline at end of file
Index: t3lib/js/extjs/components/pagetree/javascript/toppanel.js
===================================================================
--- t3lib/js/extjs/components/pagetree/javascript/toppanel.js	(Revision 0)
+++ t3lib/js/extjs/components/pagetree/javascript/toppanel.js	(Revision 0)
@@ -0,0 +1,485 @@
+/***************************************************************
+*  Copyright notice
+*
+*  (c) 2010 TYPO3 Tree Team <http://forge.typo3.org/projects/typo3v4-extjstrees>
+*  All rights reserved
+*
+*  This script is part of the TYPO3 project. The TYPO3 project is
+*  free software; you can redistribute it and/or modify
+*  it under the terms of the GNU General Public License as published by
+*  the Free Software Foundation; either version 2 of the License, or
+*  (at your option) any later version.
+*
+*  The GNU General Public License can be found at
+*  http://www.gnu.org/copyleft/gpl.html.
+*  A copy is found in the textfile GPL.txt and important notices to the license
+*  from the author is found in LICENSE.txt distributed with these scripts.
+*
+*
+*  This script is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*  GNU General Public License for more details.
+*
+*  This copyright notice MUST APPEAR in all copies of the script!
+***************************************************************/
+Ext.namespace('TYPO3.Components.PageTree');
+
+/**
+ * @class TYPO3.Components.PageTree.TopPanel
+ *
+ * Top Panel
+ *
+ * @namespace TYPO3.Components.PageTree
+ * @extends Ext.Panel
+ * @author Stefan Galinski <stefan.galinski@gmail.com>
+ */
+TYPO3.Components.PageTree.TopPanel = Ext.extend(Ext.Panel, {
+	/**
+	 * Component Id
+	 *
+	 * @type {String}
+	 */
+	id: 'typo3-pagetree-topPanel',
+
+	/**
+	 * Border
+	 *
+	 * @type {Boolean}
+	 */
+	border: false,
+
+	/**
+	 * Toolbar Object
+	 *
+	 * @type {Ext.Toolbar}
+	 */
+	tbar: new Ext.Toolbar(),
+
+	/**
+	 * Currently Clicked Toolbar Button
+	 *
+	 * @type {Ext.Button}
+	 */
+	currentlyClickedButton: null,
+
+	/**
+	 * Currently Shown Panel
+	 *
+	 * @type {Ext.Component}
+	 */
+	currentlyShownPanel: null,
+
+	/**
+	 * Filtering Indicator Item
+	 *
+	 * @type {Ext.Panel}
+	 */
+	filteringIndicator: null,
+
+	/**
+	 * Drag and Drop Group
+	 *
+	 * @cfg {String}
+	 */
+	ddGroup: '',
+
+	/**
+	 * Data Provider
+	 *
+	 * @cfg {Object}
+	 */
+	dataProvider: null,
+
+	/**
+	 * Filtering Tree
+	 *
+	 * @cfg {TYPO3.Components.PageTree.FilteringTree}
+	 */
+	filteringTree: null,
+
+	/**
+	 * Page Tree
+	 *
+	 * @cfg {TYPO3.Components.PageTree.Tree}
+	 */
+	tree: null,
+
+	/**
+	 * Application Panel
+	 *
+	 * @cfg {TYPO3.Components.PageTree.App}
+	 */
+	app: null,
+
+	/**
+	 * Initializes the component
+	 *
+	 * @return {void}
+	 */
+	initComponent: function() {
+		this.currentlyShownPanel = new Ext.Panel({
+			id: this.id + '-defaultPanel',
+			cls: this.id + '-item'
+		});
+		this.items = [this.currentlyShownPanel];
+
+		TYPO3.Components.PageTree.TopPanel.superclass.initComponent.apply(this, arguments);
+
+		this.addDragDropNodeInsertionFeature();
+		
+		if (!TYPO3.Components.PageTree.Configuration.hideFilter
+			|| TYPO3.Components.PageTree.Configuration.hideFilter === '0'
+		) {
+			this.addFilterFeature();
+		}
+
+		this.getTopToolbar().addItem({xtype: 'tbfill'});
+		this.addRefreshTreeFeature();
+	},
+
+	/**
+	 * Returns a custom button template to fix some nasty webkit issues
+	 * by removing some useless wrapping html code
+	 *
+	 * @return {void}
+	 */
+	getButtonTemplate: function() {
+		return new Ext.Template(
+			'<div id="{4}" class="x-btn {3}"><button type="{0}"">&nbsp;</button></div>'
+		);
+	},
+
+	/**
+	 * Adds a button to the components toolbar with a related component
+	 *
+	 * @param {Object} button
+	 * @param {Object} connectedWidget
+	 * @return {void}
+	 */
+	addButton: function(button, connectedWidget) {
+		button.template = this.getButtonTemplate();
+		if (!button.hasListener('click')) {
+			button.on('click', this.topbarButtonCallback);
+		}
+
+		if (connectedWidget) {
+			connectedWidget.hidden = true;
+			button.connectedWidget = connectedWidget;
+			this.add(connectedWidget);
+		}
+
+		this.getTopToolbar().addItem(button);
+		this.doLayout();
+	},
+
+	/**
+	 * Usual button callback method that triggers the assigned component of the
+	 * clicked toolbar button
+	 *
+	 * @return {void}
+	 */
+	topbarButtonCallback: function() {
+		var topPanel = this.ownerCt.ownerCt;
+
+		topPanel.currentlyShownPanel.hide();
+		if (topPanel.currentlyClickedButton) {
+			topPanel.currentlyClickedButton.toggle(false);
+		}
+
+		if (topPanel.currentlyClickedButton === this) {
+			topPanel.currentlyClickedButton = null;
+			topPanel.currentlyShownPanel = topPanel.get(topPanel.id + '-defaultPanel');
+		} else {
+			this.toggle(true);
+			topPanel.currentlyClickedButton = this;
+			topPanel.currentlyShownPanel = this.connectedWidget;
+		}
+
+		topPanel.currentlyShownPanel.show();
+	},
+
+	/**
+	 * Loads the filtering tree nodes with the given search word
+	 *
+	 * @param {Ext.form.TextField} textField
+	 * @return {void}
+	 */
+	createFilterTree: function(textField) {
+		var searchWord = textField.getValue();
+		var isNumber = TYPO3.Utility.isNumber(searchWord);
+		var hasMinLength = (searchWord.length > 2 || searchWord.length <= 0);
+		if ((!hasMinLength && !isNumber) || searchWord === this.filteringTree.searchWord) {
+			return;
+		}
+
+		this.filteringTree.searchWord = searchWord;
+		if (this.filteringTree.searchWord === '') {
+			this.app.activeTree = this.tree;
+
+			textField.setHideTrigger(true);
+			this.filteringTree.hide();
+			this.tree.show().refreshTree(function() {
+				textField.focus(false, 500);
+			}, this);
+
+			if (this.filteringIndicator) {
+				this.app.removeIndicator(this.filteringIndicator);
+				this.filteringIndicator = null;
+			}
+		} else {
+			var selectedNode = this.app.getSelected();
+			this.app.activeTree = this.filteringTree;
+
+			if (!this.filteringIndicator) {
+				this.filteringIndicator = this.app.addIndicator(
+					this.createIndicatorItem(textField)
+				);
+			}
+
+			textField.setHideTrigger(false);
+			this.tree.hide();
+			this.app.ownerCt.getEl().mask('', 'x-mask-loading-message');
+			this.app.ownerCt.getEl().addClass('t3-mask-loading');
+			this.filteringTree.show().refreshTree(function() {
+				if (selectedNode) {
+					this.app.select(selectedNode.attributes.nodeData.id, false);
+				}
+				textField.focus();
+				this.app.ownerCt.getEl().unmask();
+			}, this);
+		}
+
+		this.doLayout();
+	},
+
+	/**
+	 * Adds an indicator item to the page tree application for the filtering feature
+	 *
+	 * @param {Ext.form.TextField} textField
+	 * @return {void}
+	 */
+	createIndicatorItem: function(textField) {
+		return {
+			border: false,
+			id: this.app.id + '-indicatorBar-filter',
+			cls: this.app.id + '-indicatorBar-item',
+			html: '<p>' +
+					'<span id="' + this.app.id + '-indicatorBar-filter-info' + '" ' +
+						'class="' + this.app.id + '-indicatorBar-item-leftIcon ' +
+							TYPO3.Components.PageTree.Sprites.Info + '">&nbsp;' +
+					'</span>' +
+					'<span id="' + this.app.id + '-indicatorBar-filter-clear' + '" ' +
+						'class="' + this.app.id + '-indicatorBar-item-rightIcon ' + '">X' +
+					'</span>' +
+					TYPO3.Components.PageTree.LLL.activeFilterMode +
+				'</p>',
+			filteringTree: this.filteringTree,
+
+			listeners: {
+				afterrender: {
+					scope: this,
+					fn: function() {
+						var element = Ext.fly(this.app.id + '-indicatorBar-filter-clear');
+						element.on('click', function() {
+							textField.setValue('');
+							this.createFilterTree(textField);
+						}, this);
+					}
+				}
+			}
+		};
+	},
+
+	/**
+	 * Adds the necessary functionality and components for the filtering feature
+	 *
+	 * @return {void}
+	 */
+	addFilterFeature: function() {
+		var topPanelButton = new Ext.Button({
+			id: this.id + '-button-filter',
+			cls: this.id + '-button',
+			iconCls: TYPO3.Components.PageTree.Sprites.Filter,
+			tooltip: TYPO3.Components.PageTree.LLL.buttonFilter
+		});
+
+		var textField = new Ext.form.TriggerField({
+			id: this.id + '-filter',
+			enableKeyEvents: true,
+			triggerClass: TYPO3.Components.PageTree.Sprites.InputClear,
+			value: TYPO3.Components.PageTree.LLL.searchTermInfo,
+
+			listeners: {
+				blur: {
+					scope: this,
+					fn:function(textField) {
+						if (textField.getValue() === '') {
+							textField.setValue(TYPO3.Components.PageTree.LLL.searchTermInfo);
+							textField.addClass(this.id + '-filter-defaultText');
+						}
+					}
+				},
+
+				focus: {
+					scope: this,
+					fn: function(textField) {
+						if (textField.getValue() === TYPO3.Components.PageTree.LLL.searchTermInfo) {
+							textField.setValue('');
+							textField.removeClass(this.id + '-filter-defaultText');
+						}
+					}
+				},
+
+				keydown: {
+					fn: this.createFilterTree,
+					scope: this,
+					buffer: 1000
+				}
+			}
+		});
+
+		textField.setHideTrigger(true);
+		textField.onTriggerClick = function() {
+			textField.setValue('');
+			this.createFilterTree(textField);
+		}.createDelegate(this);
+
+		var topPanelWidget = new Ext.Panel({
+			border: false,
+			id: this.id + '-filterWrap',
+			cls: this.id + '-item',
+			items: [textField],
+
+			listeners: {
+				show: {
+					scope: this,
+					fn: function(panel) {
+						panel.get(this.id + '-filter').focus();
+					}
+				}
+			}
+		});
+
+		this.addButton(topPanelButton, topPanelWidget);
+	},
+
+	/**
+	 * Creates the entries for the new node drag zone toolbar
+	 *
+	 * @return {void}
+	 */
+	createNewNodeToolbar: function() {
+		this.dragZone = new Ext.dd.DragZone(this.getEl(), {
+			ddGroup: this.ownerCt.ddGroup,
+			topPanel: this.ownerCt,
+
+			endDrag: function() {
+				this.topPanel.app.activeTree.dontSetOverClass = false;
+			},
+
+			getDragData: function(event) {
+				this.proxyElement = document.createElement('div');
+
+				var node = Ext.getCmp(event.getTarget('.x-btn').id);
+				node.shouldCreateNewNode = true;
+
+				return {
+					ddel: this.proxyElement,
+					item: node
+				}
+			},
+
+			onInitDrag: function() {
+				this.topPanel.app.activeTree.dontSetOverClass = true;
+				var clickedButton = this.dragData.item;
+				var cls = clickedButton.initialConfig.iconCls;
+
+				this.proxyElement.shadow = false;
+				this.proxyElement.innerHTML = '<div class="x-dd-drag-ghost-pagetree">' +
+					'<span class="x-dd-drag-ghost-pagetree-icon ' + cls + '">&nbsp;</span>' +
+					'<span class="x-dd-drag-ghost-pagetree-text">'  + clickedButton.title + '</span>' +
+				'</div>';
+
+				this.proxy.update(this.proxyElement);
+			}
+		});
+
+			// listens on the escape key to stop the dragging
+		(new Ext.KeyMap(document, {
+			key: Ext.EventObject.ESC,
+			scope: this,
+			buffer: 250,
+			fn: function(event) {
+				if (this.dragZone.dragging) {
+					Ext.dd.DragDropMgr.stopDrag(event);
+					this.dragZone.onInvalidDrop(event);
+				}
+			}
+		}, 'keydown'));
+	},
+
+	/**
+	 * Creates the necessary components for new node drag and drop feature
+	 *
+	 * @return {void}
+	 */
+	addDragDropNodeInsertionFeature: function() {
+		var newNodeToolbar = new Ext.Toolbar({
+			border: false,
+			id: this.id + '-item-newNode',
+			cls: this.id + '-item',
+
+			listeners: {
+				render: {
+					fn: this.createNewNodeToolbar
+				}
+			}
+		});
+
+		this.dataProvider.getNodeTypes(function(response) {
+			for (var i = 0; i < response.length; ++i) {
+				response[i].template = this.getButtonTemplate();
+				newNodeToolbar.addItem(response[i]);
+			}
+			newNodeToolbar.doLayout();
+		}, this);
+
+		var topPanelButton = new Ext.Button({
+			id: this.id + '-button-newNode',
+			cls: this.id + '-button',
+			iconCls: TYPO3.Components.PageTree.Sprites.NewNode,
+			tooltip: TYPO3.Components.PageTree.LLL.buttonNewNode
+		});
+
+		this.addButton(topPanelButton, newNodeToolbar);
+	},
+
+	/**
+	 * Adds a button to the toolbar for the refreshing feature
+	 *
+	 * @return {void}
+	 */
+	addRefreshTreeFeature: function() {
+		var topPanelButton = new Ext.Button({
+			id: this.id + '-button-refresh',
+			cls: this.id + '-button',
+			iconCls: TYPO3.Components.PageTree.Sprites.Refresh,
+			tooltip: TYPO3.Components.PageTree.LLL.buttonRefresh,
+
+			listeners: {
+				click: {
+					scope: this,
+					fn: function() {
+						this.app.activeTree.refreshTree();
+					}
+				}
+			}
+		});
+
+		this.addButton(topPanelButton);
+	}
+});
+
+// XTYPE Registration
+Ext.reg('TYPO3.Components.PageTree.TopPanel', TYPO3.Components.PageTree.TopPanel);
\ No newline at end of file
Index: t3lib/js/extjs/components/pagetree/javascript/nodeui.js
===================================================================
--- t3lib/js/extjs/components/pagetree/javascript/nodeui.js	(Revision 0)
+++ t3lib/js/extjs/components/pagetree/javascript/nodeui.js	(Revision 0)
@@ -0,0 +1,162 @@
+/***************************************************************
+*  Copyright notice
+*
+*  (c) 2010 TYPO3 Tree Team <http://forge.typo3.org/projects/typo3v4-extjstrees>
+*  All rights reserved
+*
+*  This script is part of the TYPO3 project. The TYPO3 project is
+*  free software; you can redistribute it and/or modify
+*  it under the terms of the GNU General Public License as published by
+*  the Free Software Foundation; either version 2 of the License, or
+*  (at your option) any later version.
+*
+*  The GNU General Public License can be found at
+*  http://www.gnu.org/copyleft/gpl.html.
+*  A copy is found in the textfile GPL.txt and important notices to the license
+*  from the author is found in LICENSE.txt distributed with these scripts.
+*
+*
+*  This script is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*  GNU General Public License for more details.
+*
+*  This copyright notice MUST APPEAR in all copies of the script!
+***************************************************************/
+Ext.namespace('TYPO3.Components.PageTree');
+
+/**
+ * @class TYPO3.Components.PageTree.DeletionDropZone
+ *
+ * Tree Node User Interface that can handle sprite icons and more
+ *
+ * @namespace TYPO3.Components.PageTree
+ * @extends Ext.tree.TreeNodeUI
+ * @author Stefan Galinski <stefan.galinski@gmail.com>
+ */
+TYPO3.Components.PageTree.PageTreeNodeUI = Ext.extend(Ext.tree.TreeNodeUI, {
+	/**
+	 * Adds the sprite icon and adds an event to open the context menu on a single click at the icon node
+	 *
+	 * @param {Ext.tree.TreeNode} n
+	 * @param {Object} a
+	 * @param {Ext.tree.TreeNode} targetNode
+	 * @param {Boolean} bulkRender
+	 * @return {void}
+	 */
+	renderElements : function(n, a, targetNode, bulkRender) {
+		// add some indent caching, this helps performance when rendering a large tree
+        this.indentMarkup = n.parentNode ? n.parentNode.ui.getChildIndent() : '';
+
+        var cb = Ext.isBoolean(a.checked),
+            nel,
+            href = this.getHref(a.href),
+            buf = ['<li class="x-tree-node"><div ext:tree-node-id="',n.id,'" class="x-tree-node-el x-tree-node-leaf x-unselectable ', a.cls,'" unselectable="on">',
+            '<span class="x-tree-node-indent">',this.indentMarkup,"</span>",
+            '<img alt="" src="', this.emptyIcon, '" class="x-tree-ec-icon x-tree-elbow" />',
+//            '<img alt="" src="', a.icon || this.emptyIcon, '" class="x-tree-node-icon',(a.icon ? " x-tree-node-inline-icon" : ""),(a.iconCls ? " "+a.iconCls : ""),'" unselectable="on" />',
+			a.spriteIconCode, // TYPO3: add sprite icon code
+            cb ? ('<input class="x-tree-node-cb" type="checkbox" ' + (a.checked ? 'checked="checked" />' : '/>')) : '',
+            '<a hidefocus="on" class="x-tree-node-anchor" href="',href,'" tabIndex="1" ',
+             a.hrefTarget ? ' target="'+a.hrefTarget+'"' : "", '><span unselectable="on">',n.text,"</span></a></div>",
+            '<ul class="x-tree-node-ct" style="display:none;"></ul>',
+            "</li>"].join('');
+
+        if(bulkRender !== true && n.nextSibling && (nel = n.nextSibling.ui.getEl())){
+            this.wrap = Ext.DomHelper.insertHtml("beforeBegin", nel, buf);
+        }else{
+            this.wrap = Ext.DomHelper.insertHtml("beforeEnd", targetNode, buf);
+        }
+
+			// TYPO3 modification to show the readable rootline above the user mounts
+		if (a.readableRootline !== '') {
+			var rootline = '<div class="x-tree-node-readableRootline">' + a.readableRootline + '</div>';
+			Ext.DomHelper.insertHtml("beforeBegin", this.wrap, rootline);
+		}
+
+        this.elNode = this.wrap.childNodes[0];
+        this.ctNode = this.wrap.childNodes[1];
+        var cs = this.elNode.childNodes;
+        this.indentNode = cs[0];
+        this.ecNode = cs[1];
+//        this.iconNode = cs[2];
+		this.iconNode = (cs[2].firstChild.tagName === 'SPAN' ? cs[2].firstChild : cs[2]); // TYPO3: get possible overlay icon
+        var index = 3; // TYPO3: index 4?
+        if(cb){
+            this.checkbox = cs[3];
+            // fix for IE6
+            this.checkbox.defaultChecked = this.checkbox.checked;
+            index++;
+        }
+        this.anchor = cs[index];
+        this.textNode = cs[index].firstChild;
+
+			// TYPO3: call the context menu on a single click (Beware of drag&drop!)
+		if (!TYPO3.Components.PageTree.Configuration.disableIconLinkToContextmenu
+			|| TYPO3.Components.PageTree.Configuration.disableIconLinkToContextmenu === '0'
+		) {
+			Ext.fly(this.iconNode).on('click', function(event) {
+				this.getOwnerTree().fireEvent('contextmenu', this, event);
+				event.stopEvent();
+			}, n);
+		}
+	},
+
+	/**
+	 * Adds a quick tip to the sprite icon
+	 *
+	 * @param {Ext.tree.TreeNode} node
+	 * @param {Object} tip
+	 * @param {String} title
+	 * @return {void}
+	 */
+    onTipChange : function(node, tip, title) {
+		TYPO3.Components.PageTree.PageTreeNodeUI.superclass.onTipChange.apply(this, arguments);
+
+        if(this.rendered){
+            var hasTitle = Ext.isDefined(title);
+            if(this.iconNode.setAttributeNS){
+                this.iconNode.setAttributeNS("ext", "qtip", tip);
+                if(hasTitle){
+                    this.iconNode.setAttributeNS("ext", "qtitle", title);
+                }
+            }else{
+                this.iconNode.setAttribute("ext:qtip", tip);
+                if(hasTitle){
+                    this.iconNode.setAttribute("ext:qtitle", title);
+                }
+            }
+        }
+    },
+
+	/**
+	 * Returns the drag and drop handles
+	 *
+	 * @return {Object}
+	 */
+	getDDHandles: function() {
+		var ddHandles = [this.iconNode, this.textNode, this.elNode];
+		var textNode = Ext.get(this.textNode);
+		for (var i = 0; i < textNode.dom.childNodes.length; ++i) {
+			if (textNode.dom.childNodes[i].nodeName === 'SPAN') {
+				ddHandles[3] = textNode.dom.childNodes[i];
+			}
+		}
+
+		return ddHandles;
+    },
+
+	/**
+	 * Only set the onOver class if we are not in dragging mode
+	 *
+	 * @return {void}
+	 */
+	onOver: function() {
+		if (!this.node.ownerTree.dontSetOverClass) {
+			TYPO3.Components.PageTree.PageTreeNodeUI.superclass.onOver.apply(this, arguments);
+		}
+	}
+});
+
+// XTYPE Registration
+Ext.reg('TYPO3.Components.PageTree.PageTreeNodeUI', TYPO3.Components.PageTree.PageTreeNodeUI);
\ No newline at end of file
Index: t3lib/js/extjs/components/pagetree/javascript/filteringtree.js
===================================================================
--- t3lib/js/extjs/components/pagetree/javascript/filteringtree.js	(Revision 0)
+++ t3lib/js/extjs/components/pagetree/javascript/filteringtree.js	(Revision 0)
@@ -0,0 +1,75 @@
+/***************************************************************
+*  Copyright notice
+*
+*  (c) 2010 TYPO3 Tree Team <http://forge.typo3.org/projects/typo3v4-extjstrees>
+*  All rights reserved
+*
+*  This script is part of the TYPO3 project. The TYPO3 project is
+*  free software; you can redistribute it and/or modify
+*  it under the terms of the GNU General Public License as published by
+*  the Free Software Foundation; either version 2 of the License, or
+*  (at your option) any later version.
+*
+*  The GNU General Public License can be found at
+*  http://www.gnu.org/copyleft/gpl.html.
+*  A copy is found in the textfile GPL.txt and important notices to the license
+*  from the author is found in LICENSE.txt distributed with these scripts.
+*
+*
+*  This script is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*  GNU General Public License for more details.
+*
+*  This copyright notice MUST APPEAR in all copies of the script!
+***************************************************************/
+Ext.namespace('TYPO3.Components.PageTree');
+
+/**
+ * @class TYPO3.Components.PageTree.FilteringTree
+ *
+ * Filtering Tree
+ *
+ * @namespace TYPO3.Components.PageTree
+ * @extends TYPO3.Components.PageTree.Tree
+ * @author Stefan Galinski <stefan.galinski@gmail.com>
+ */
+TYPO3.Components.PageTree.FilteringTree = Ext.extend(TYPO3.Components.PageTree.Tree, {
+	/**
+	 * Search word
+	 *
+	 * @type {String}
+	 */
+	searchWord: '',
+
+	/**
+	 * Tree loader implementation for the filtering tree
+	 *
+	 * @return {void}
+	 */
+	addTreeLoader: function() {
+		this.loader = new Ext.tree.TreeLoader({
+			directFn: this.treeDataProvider.getFilteredTree,
+			paramOrder: 'nodeId,attributes,searchWord',
+			nodeParameter: 'nodeId',
+			baseAttrs: {
+				uiProvider: this.uiProvider
+			},
+
+			listeners: {
+				beforeload: function(treeLoader, node) {
+					if (!node.ownerTree.searchWord || node.ownerTree.searchWord === '') {
+						return false;
+					}
+
+					treeLoader.baseParams.nodeId = node.id;
+					treeLoader.baseParams.searchWord = node.ownerTree.searchWord;
+					treeLoader.baseParams.attributes = node.attributes.nodeData;
+				}
+			}
+		});
+	}
+});
+
+// XTYPE Registration
+Ext.reg('TYPO3.Components.PageTree.FilteringTree', TYPO3.Components.PageTree.FilteringTree);
\ No newline at end of file
Index: t3lib/js/extjs/util.js
===================================================================
--- t3lib/js/extjs/util.js	(Revision 0)
+++ t3lib/js/extjs/util.js	(Revision 0)
@@ -0,0 +1,49 @@
+/***************************************************************
+*  Copyright notice
+*
+*  (c) 2010 TYPO3 Tree Team <http://forge.typo3.org/projects/typo3v4-extjstrees>
+*  All rights reserved
+*
+*  This script is part of the TYPO3 project. The TYPO3 project is
+*  free software; you can redistribute it and/or modify
+*  it under the terms of the GNU General Public License as published by
+*  the Free Software Foundation; either version 2 of the License, or
+*  (at your option) any later version.
+*
+*  The GNU General Public License can be found at
+*  http://www.gnu.org/copyleft/gpl.html.
+*  A copy is found in the textfile GPL.txt and important notices to the license
+*  from the author is found in LICENSE.txt distributed with these scripts.
+*
+*
+*  This script is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*  GNU General Public License for more details.
+*
+*  This copyright notice MUST APPEAR in all copies of the script!
+***************************************************************/
+Ext.namespace('TYPO3');
+
+/**
+ * @class TYPO3.Utility
+ *
+ * Generic utility methods that are not provided by ExtJs
+ *
+ * @namespace TYPO3
+ * @author Stefan Galinski <stefan.galinski@gmail.com>
+ */
+TYPO3.Utility = {
+	/**
+	 * Checks if a given number is really a number
+	 *
+	 * Taken from:
+	 * http://dl.dropbox.com/u/35146/js/tests/isNumber.html
+	 *
+	 * @param {String} number
+	 * @return {Boolean}
+	 */
+	isNumber: function(number) {
+		return !isNaN(parseFloat(number)) && isFinite(number);
+	}
+};
\ No newline at end of file
Index: t3lib/tree/extdirect/class.t3lib_tree_extdirect_node.php
===================================================================
--- t3lib/tree/extdirect/class.t3lib_tree_extdirect_node.php	(Revision 0)
+++ t3lib/tree/extdirect/class.t3lib_tree_extdirect_node.php	(Revision 0)
@@ -0,0 +1,634 @@
+<?php
+/***************************************************************
+*  Copyright notice
+*
+*  (c) 2010 TYPO3 Tree Team <http://forge.typo3.org/projects/typo3v4-extjstrees>
+*  All rights reserved
+*
+*  This script is part of the TYPO3 project. The TYPO3 project is
+*  free software; you can redistribute it and/or modify
+*  it under the terms of the GNU General Public License as published by
+*  the Free Software Foundation; either version 2 of the License, or
+*  (at your option) any later version.
+*
+*  The GNU General Public License can be found at
+*  http://www.gnu.org/copyleft/gpl.html.
+*  A copy is found in the textfile GPL.txt and important notices to the license
+*  from the author is found in LICENSE.txt distributed with these scripts.
+*
+*
+*  This script is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*  GNU General Public License for more details.
+*
+*  This copyright notice MUST APPEAR in all copies of the script!
+***************************************************************/
+
+/**
+ * Node for the usage with ExtDirect and ExtJS
+ *
+ * @author Stefan Galinski <stefan.galinski@gmail.com>
+ * @package TYPO3
+ * @subpackage t3lib
+ */
+class t3lib_tree_extdirect_Node extends t3lib_tree_Node {
+	/**
+	 * Node type
+	 *
+	 * @var string
+	 */
+	protected $type = '';
+
+	/**
+	 * Leaf Node Indicator
+	 *
+	 * @var bool
+	 */
+	protected $leaf = TRUE;
+
+	/**
+	 * Indicator if the node is expanded
+	 *
+	 * @var bool
+	 */
+	protected $expanded = FALSE;
+
+	/**
+	 * Indicator if the node can be expanded
+	 *
+	 * @var bool
+	 */
+	protected $expandable = FALSE;
+
+	/**
+	 * Indicator if the node is draggable
+	 *
+	 * @var bool
+	 */
+	protected $draggable = TRUE;
+
+	/**
+	 * Indicator if the node is allowed as a drop target
+	 *
+	 * @var bool
+	 */
+	protected $isDropTarget = TRUE;
+
+	/**
+	 * Label
+	 *
+	 * @var string
+	 */
+	protected $text = '';
+
+	/**
+	 * Editable Label text
+	 *
+	 * @var string
+	 */
+	protected $editableText = '';
+
+	/**
+	 * Prefix text of the label
+	 *
+	 * @var string
+	 */
+	protected $prefix = '';
+
+	/**
+	 * Suffix text of the label
+	 *
+	 * @var string
+	 */
+	protected $suffix = '';
+
+	/**
+	 * CSS Class
+	 *
+	 * @var string
+	 */
+	protected $cls = '';
+
+	/**
+	 * Quick Tip
+	 *
+	 * @var string
+	 */
+	protected $qtip = '';
+
+	/**
+	 * Sprite Icon HTML
+	 *
+	 * @var string
+	 */
+	protected $spriteIconCode = '';
+
+	/**
+	 * Text source field (title, nav_title, ...)
+	 *
+	 * @var string
+	 */
+	protected $t3TextSourceField = '';
+
+	/**
+	 * Indicator if the copy mode is activated
+	 *
+	 * @var bool
+	 */
+	protected $t3InCopyMode = FALSE;
+
+	/**
+	 * Indicator if the cut mode is activated
+	 *
+	 * @var bool
+	 */
+	protected $t3InCutMode = FALSE;
+
+	/**
+	 * Database record (not serialized or merged into the result array!)
+	 *
+	 * @var array
+	 */
+	protected $record = array();
+
+	/**
+	 * Context Info
+	 *
+	 * @var array
+	 */
+	protected $contextInfo = array();
+
+	/**
+	 * Indicator if the label is editable
+	 *
+	 * @var bool
+	 */
+	protected $labelIsEditable = TRUE;
+
+	/**
+	 * Indicator if the node can have children's
+	 *
+	 * @var bool
+	 */
+	protected $allowChildren = TRUE;
+
+	/**
+	 * Set's the node type
+	 *
+	 * @param string $type
+	 * @return void
+	 */
+	public function setType($type) {
+		$this->type = $type;
+	}
+
+	/**
+	 * Returns the node type
+	 *
+	 * @return string
+	 */
+	public function getType() {
+		return $this->type;
+	}
+
+	/**
+	 * Sets the leaf node indicator
+	 *
+	 * @param bool $isLeaf
+	 * @return void
+	 */
+	public function setLeaf($isLeaf) {
+		$this->leaf = ($isLeaf == TRUE);
+	}
+
+	/**
+	 * Returns if the node is a leaf node
+	 *
+	 * @return bool
+	 */
+	public function isLeafNode() {
+		return $this->leaf;
+	}
+
+	/**
+	 * Sets the expandable indicator
+	 *
+	 * @param bool $expandable
+	 * @return void
+	 */
+	public function setExpandable($expandable) {
+		$this->expandable = ($expandable == TRUE);
+	}
+
+	/**
+	 * Returns the expandable indicator
+	 *
+	 * @return bool
+	 */
+	public function isExpandable() {
+		return $this->expandable;
+	}
+
+	/**
+	 * Sets the expanded indicator
+	 *
+	 * @param bool $expanded
+	 * @return void
+	 */
+	public function setExpanded($expanded) {
+		$this->expanded = ($expanded == TRUE);
+	}
+
+	/**
+	 * Returns the expanded indicator
+	 *
+	 * @return bool
+	 */
+	public function isExpanded() {
+		if ($this->isLeafNode()) {
+			return TRUE;
+		}
+
+		return $this->expanded;
+	}
+
+	/**
+	 * Sets the draggable indicator
+	 *
+	 * @param bool $draggable
+	 * @return void
+	 */
+	public function setDraggable($draggable) {
+		$this->draggable = ($draggable == TRUE);
+	}
+
+	/**
+	 * Returns the draggable indicator
+	 *
+	 * @return bool
+	 */
+	public function isDraggable() {
+		return $this->draggable;
+	}
+
+	/**
+	 * Sets the indicator if the node can be a drop target
+	 *
+	 * @param bool $isDropTarget
+	 * @return void
+	 */
+	public function setIsDropTarget($isDropTarget) {
+		$this->isDropTarget = ($isDropTarget == TRUE);
+	}
+
+	/**
+	 * Returns the indicator if the node is a drop target
+	 *
+	 * @return bool
+	 */
+	public function isDropTarget() {
+		return $this->isDropTarget;
+	}
+
+	/**
+	 * Sets the label of the node with the source field and the prefix
+	 *
+	 * @param string $text
+	 * @param string $textSourceField
+	 * @param string $prefix
+	 * @param string $suffix
+	 * @return void
+	 */
+	public function setText($text, $textSourceField = 'title', $prefix = '', $suffix = '') {
+		$this->text = $text;
+		$this->t3TextSourceField = $textSourceField;
+		$this->prefix = $prefix;
+		$this->suffix = $suffix;
+	}
+
+	/**
+	 * Returns the label
+	 *
+	 * @return string
+	 */
+	public function getText() {
+		return $this->text;
+	}
+
+	/**
+	 * Sets the editable text
+	 *
+	 * @param string $editableText
+	 * @return void
+	 */
+	public function setEditableText($editableText) {
+		$this->editableText = $editableText;
+	}
+
+	/**
+	 * Returns the editable text
+	 *
+	 * @return string
+	 */
+	public function getEditableText() {
+		return $this->editableText;
+	}
+
+	/**
+	 * Returns the source field of the label
+	 *
+	 * @return string
+	 */
+	public function getTextSourceField() {
+		return $this->t3TextSourceField;
+	}
+
+	/**
+	 * Sets the paste copy indicator
+	 *
+	 * @param boolean $inCopyMode
+	 * @return void
+	 */
+	public function setInCopyMode($inCopyMode) {
+		$this->t3InCopyMode = ($inCopyMode == TRUE);
+	}
+
+	/**
+	 * Returns the copy mode indicator
+	 *
+	 * @return bool
+	 */
+	public function isInCopyMode() {
+		return $this->t3InCopyMode;
+	}
+
+	/**
+	 * Sets the paste cut indicator
+	 *
+	 * @param boolean $inCutMode
+	 * @return void
+	 */
+	public function setInCutMode($inCutMode) {
+		$this->t3InCutMode = ($inCutMode == TRUE);
+	}
+
+	/**
+	 * Returns the cut mode indicator
+	 *
+	 * @return bool
+	 */
+	public function isInCutMode() {
+		return $this->t3InCutMode;
+	}
+
+	/**
+	 * Returns the prefix text of the label
+	 *
+	 * @return string
+	 */
+	public function getPrefix() {
+		return $this->prefix;
+	}
+
+	/**
+	 * Returns the suffix text of the label
+	 * 
+	 * @return string
+	 */
+	public function getSuffix() {
+		return $this->suffix;
+	}
+
+	/**
+	 * Sets the css class(es)
+	 *
+	 * @param string $class
+	 * @return void
+	 */
+	public function setCls($class) {
+		$this->cls = $class;
+	}
+
+	/**
+	 * Returns the css class(es)
+	 *
+	 * @return string
+	 */
+	public function getCls() {
+		return $this->cls;
+	}
+
+	/**
+	 * Sets the quick tip
+	 *
+	 * @param string $qtip
+	 * @return void
+	 */
+	public function setQTip($qtip) {
+		$this->qtip = $qtip;
+	}
+
+	/**
+	 * Returns the quick tip
+	 *
+	 * @return string
+	 */
+	public function getQTip() {
+		return $this->qtip;
+	}
+
+	/**
+	 * Sets the sprite icon code
+	 *
+	 * @param string $spriteIcon
+	 * @return void
+	 */
+	public function setSpriteIconCode($spriteIcon) {
+		$this->spriteIconCode = $spriteIcon;
+	}
+
+	/**
+	 * Returns the sprite icon code
+	 *
+	 * @return string
+	 */
+	public function getSpriteIconCode() {
+		return $this->spriteIconCode;
+	}
+
+	/**
+	 * Sets the indicator if the label is editable
+	 *
+	 * @param bool $labelIsEditable
+	 * @return void
+	 */
+	public function setLabelIsEditable($labelIsEditable) {
+		$this->labelIsEditable = ($labelIsEditable == TRUE);
+	}
+
+	/**
+	 * Returns the editable label indicator
+	 *
+	 * @return bool
+	 */
+	public function isLabelEditable() {
+		return $this->labelIsEditable;
+	}
+
+	/**
+	 * Sets the database record array
+	 *
+	 * @param array $record
+	 * @return void
+	 */
+	public function setRecord($record) {
+		$this->record = (array) $record;
+	}
+
+	/**
+	 * Returns the database record array
+	 *
+	 * @return array
+	 */
+	public function getRecord() {
+		return $this->record;
+	}
+
+	/**
+	 * Sets the context info
+	 *
+	 * @param array $contextInfo
+	 * @return void
+	 */
+	public function setContextInfo($contextInfo) {
+		$this->contextInfo = (array) $contextInfo;
+	}
+
+	/**
+	 * Returns the context info
+	 *
+	 * @return array
+	 */
+	public function getContextInfo() {
+		return (array) $this->contextInfo;
+	}
+
+	/**
+	 * Sets the child nodes collection
+	 *
+	 * @param t3lib_tree_NodeCollection $childNodes
+	 * @return void
+	 */
+	public function setChildNodes(t3lib_tree_NodeCollection $childNodes) {
+		parent::setChildNodes($childNodes);
+
+		if ($childNodes->count()) {
+			$this->setLeaf(FALSE);
+		}
+	}
+
+	/**
+	 * Sets the indicator if the node can have child nodes
+	 *
+	 * @param boolean $allowChildren
+	 * @return void
+	 */
+	public function setAllowChildren($allowChildren) {
+		$this->allowChildren = ($allowChildren == TRUE);
+	}
+
+	/**
+	 * Checks if the node can have child nodes
+	 *
+	 * @return bool
+	 */
+	public function canHaveChildren() {
+		return $this->allowChildren;
+	}
+
+	/**
+	 * Returns the node in an array representation that can be used for serialization
+	 *
+	 * @return array
+	 */
+	public function toArray() {
+		$arrayRepresentation = array(
+			'serializeClassName' => get_class($this),
+			'id' => $this->getId(),
+			'type' => $this->getType(),
+			'editableText' => $this->getEditableText(),
+			'text' => $this->getPrefix() . $this->getText() . $this->getSuffix(),
+			'cls' => $this->getCls(),
+			'prefix' => $this->getPrefix(),
+			'suffix' => $this->getSuffix(),
+			'qtip' => $this->getQTip(),
+			'expanded' => $this->isExpanded(),
+			'expandable' => $this->isExpandable(),
+			'draggable' => $this->isDraggable(),
+			'isTarget' => $this->isDropTarget(),
+			'spriteIconCode' => $this->getSpriteIconCode(),
+			't3TextSourceField' => $this->getTextSourceField(),
+			't3InCopyMode' => $this->isInCopyMode(),
+			't3InCutMode' => $this->isInCutMode(),
+			't3ContextInfo' => $this->getContextInfo(),
+			'editable' => $this->isLabelEditable(),
+			'allowChildren' => $this->canHaveChildren(),
+		);
+
+			// only set the leaf attribute if the node has children's,
+			// otherwise you cannot add child's to real leaf nodes
+		if (!$this->isLeafNode()) {
+			$arrayRepresentation['leaf'] = FALSE;
+		}
+
+			// Suhosin(?) or some other strange environment thingy prevents
+			// the direct copy of an array into an index of the same array
+		$copy = $arrayRepresentation;
+		$arrayRepresentation['nodeData'] = $copy;
+
+		if ($this->hasChildNodes()) {
+			$arrayRepresentation['children'] = $this->childNodes->toArray();
+		}
+
+		return $arrayRepresentation;
+	}
+
+	/**
+	 * Sets data of the node by a given data array
+	 *
+	 * @param array $data
+	 * @return void
+	 */
+	public function dataFromArray($data) {
+		parent::dataFromArray($data);
+
+		$this->setType($data['type']);
+		$this->setText($data['label'], $data['t3TextSourceField'], $data['prefix'], $data['suffix']);
+		$this->setEditableText($data['editableText']);
+		$this->setCls($data['cls']);
+		$this->setQTip($data['qtip']);
+		$this->setExpanded($data['expanded']);
+		$this->setExpandable($data['expandable']);
+		$this->setDraggable($data['draggable']);
+		$this->setIsDropTarget($data['isTarget']);
+		$this->setSpriteIconCode($data['spriteIconCode']);
+		$this->setInCopyMode($data['t3InCopyMode']);
+		$this->setInCutMode($data['t3InCutMode']);
+		$this->setContextInfo($data['t3ContextInfo']);
+		$this->setLabelIsEditable($data['editable']);
+		$this->setAllowChildren($data['allowChildren']);
+
+			// only set the leaf attribute if it's applied
+			// otherwise you cannot insert nodes into this one
+		if (isset($data['leaf'])) {
+			$this->setLeaf(FALSE);
+		}
+	}
+}
+
+if (defined('TYPO3_MODE') && isset($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['t3lib/tree/extdirect/class.t3lib_tree_extdirect_node.php'])) {
+	include_once($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['t3lib/tree/extdirect/class.t3lib_tree_extdirect_node.php']);
+}
+
+?>
\ No newline at end of file
Index: t3lib/tree/pagetree/class.t3lib_tree_pagetree_commands.php
===================================================================
--- t3lib/tree/pagetree/class.t3lib_tree_pagetree_commands.php	(Revision 0)
+++ t3lib/tree/pagetree/class.t3lib_tree_pagetree_commands.php	(Revision 0)
@@ -0,0 +1,340 @@
+<?php
+/***************************************************************
+*  Copyright notice
+*
+*  (c) 2010 TYPO3 Tree Team <http://forge.typo3.org/projects/typo3v4-extjstrees>
+*  All rights reserved
+*
+*  This script is part of the TYPO3 project. The TYPO3 project is
+*  free software; you can redistribute it and/or modify
+*  it under the terms of the GNU General Public License as published by
+*  the Free Software Foundation; either version 2 of the License, or
+*  (at your option) any later version.
+*
+*  The GNU General Public License can be found at
+*  http://www.gnu.org/copyleft/gpl.html.
+*  A copy is found in the textfile GPL.txt and important notices to the license
+*  from the author is found in LICENSE.txt distributed with these scripts.
+*
+*
+*  This script is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*  GNU General Public License for more details.
+*
+*  This copyright notice MUST APPEAR in all copies of the script!
+***************************************************************/
+
+/**
+ * Page Tree and Context Menu Commands
+ *
+ * @author Stefan Galinski <stefan.galinski@gmail.com>
+ * @package TYPO3
+ * @subpackage t3lib
+ */
+final class t3lib_tree_pagetree_Commands {
+	/**
+	 * Visibly the page
+	 *
+	 * @param t3lib_tree_pagetree_Node $nodeData
+	 * @return void
+	 */
+	public static function visiblyNode(t3lib_tree_pagetree_Node $node) {
+		$data['pages'][$node->getWorkspaceId()]['hidden'] = 0;
+		self::processTceCmdAndDataMap(array(), $data);
+	}
+
+	/**
+	 * Hide the page
+	 *
+	 * @param t3lib_tree_pagetree_Node $nodeData
+	 * @return void
+	 */
+	public static function disableNode(t3lib_tree_pagetree_Node $node) {
+		$data['pages'][$node->getWorkspaceId()]['hidden'] = 1;
+		self::processTceCmdAndDataMap(array(), $data);
+	}
+
+	/**
+	 * Delete the page
+	 *
+	 * @param t3lib_tree_pagetree_Node $nodeData
+	 * @return void
+	 */
+	public static function deleteNode(t3lib_tree_pagetree_Node $node) {
+		$cmd['pages'][$node->getId()]['delete'] = 1;
+		self::processTceCmdAndDataMap($cmd);
+	}
+
+	/**
+	 * Restore the page
+	 *
+	 * @param t3lib_tree_pagetree_Node $nodeData
+	 * @param int $targetId
+	 * @return void
+	 */
+	public static function restoreNode(t3lib_tree_pagetree_Node $node, $targetId) {
+		$cmd['pages'][$node->getId()]['undelete'] = 1;
+		self::processTceCmdAndDataMap($cmd);
+
+		if ($node->getId() !== $targetId) {
+			self::moveNode($node, $targetId);
+		}
+	}
+
+	/**
+	 * Updates the node label
+	 *
+	 * @param t3lib_tree_pagetree_Node $nodeData
+	 * @param string $updatedLabel
+	 * @return void
+	 */
+	public static function updateNodeLabel(t3lib_tree_pagetree_Node $node, $updatedLabel) {
+		$data['pages'][$node->getWorkspaceId()][$node->getTextSourceField()] = $updatedLabel;
+		self::processTceCmdAndDataMap(array(), $data);
+	}
+
+	/**
+	 * Copies a page and returns the id of the new page
+	 *
+	 * Node: Use a negative target id to specify a sibling target else the parent is used
+	 *
+	 * @param t3lib_tree_pagetree_Node $sourceNode
+	 * @param int $targetId
+	 * @return int
+	 */
+	public static function copyNode(t3lib_tree_pagetree_Node $sourceNode, $targetId) {
+		$cmd['pages'][$sourceNode->getId()]['copy'] = $targetId;
+		$returnValue = self::processTceCmdAndDataMap($cmd);
+
+		return $returnValue['pages'][$sourceNode->getId()];
+	}
+
+	/**
+	 * Moves a page
+	 *
+	 * Node: Use a negative target id to specify a sibling target else the parent is used
+	 *
+	 * @param t3lib_tree_pagetree_Node $sourceNode
+	 * @param int $targetId
+	 * @return void
+	 */
+	public static function moveNode(t3lib_tree_pagetree_Node $sourceNode, $targetId) {
+		$cmd['pages'][$sourceNode->getId()]['move'] = $targetId;
+		self::processTceCmdAndDataMap($cmd);
+	}
+
+	/**
+	 * Creates a page of the given doktype and returns the id of the created page
+	 *
+	 * @param t3lib_tree_pagetree_Node $parentNode
+	 * @param int $targetId
+	 * @param int $pageType
+	 * @return int
+	 */
+	public static function createNode(t3lib_tree_pagetree_Node $parentNode, $targetId, $pageType) {
+		$placeholder = 'NEW12345';
+		$data['pages'][$placeholder] = array(
+			'pid' => $parentNode->getWorkspaceId(),
+			'doktype' => $pageType,
+			'title' => $GLOBALS['LANG']->sL('LLL:EXT:lang/locallang_core.xml:tree.defaultPageTitle', TRUE),
+		);
+		$newPageId = self::processTceCmdAndDataMap(array(), $data);
+		$node = self::getNode($newPageId[$placeholder]);
+
+		if ($parentNode->getWorkspaceId() !== $targetId) {
+			self::moveNode($node, $targetId);
+		}
+
+		return $newPageId[$placeholder];
+	}
+
+	/**
+	 * Process TCEMAIN commands and data maps
+	 *
+	 * Command Map:
+	 * Used for moving, recover, remove and some more operations.
+	 *
+	 * Data Map:
+	 * Used for creating and updating records,
+	 *
+	 * This API contains all necessary access checks.
+	 *
+	 * @param array $cmd
+	 * @param array $data
+	 * @throws Exception if an error happened while the TCE processing
+	 * @return array
+	 */
+	protected static function processTceCmdAndDataMap(array $cmd, array $data = array()) {
+		/** @var $tce t3lib_TCEmain */
+		$tce = t3lib_div::makeInstance('t3lib_TCEmain');
+		$tce->stripslashes_values = 0;
+		$tce->start($data, $cmd);
+		$tce->copyTree = t3lib_div::intInRange($GLOBALS['BE_USER']->uc['copyLevels'], 0, 100);
+
+		if (count($cmd)) {
+			$tce->process_cmdmap();
+			$returnValues = $tce->copyMappingArray_merged;
+		} elseif (count($data)) {
+			$tce->process_datamap();
+			$returnValues = $tce->substNEWwithIDs;
+		}
+
+			// check errors
+		if (count($tce->errorLog)) {
+			throw new Exception(implode(chr(10), $tce->errorLog));
+		}
+
+		return $returnValues;
+	}
+
+	/**
+	 * Returns a node from the given node id
+	 *
+	 * @param int $nodeId
+	 * @param boolean $unsetMovePointers
+	 * @return t3lib_tree_pagetree_Node
+	 */
+	public static function getNode($nodeId, $unsetMovePointers = TRUE) {
+		$record = self::getNodeRecord($nodeId, $unsetMovePointers);
+		return self::getNewNode($record);
+	}
+
+	/**
+	 * Returns the mount point path for a temporary mount or the given id
+	 *
+	 * @static
+	 * @param int $uid
+	 * @return void
+	 */
+	public static function getMountPointPath($uid = -1) {
+		if ($uid === -1) {
+			$uid = intval($GLOBALS['BE_USER']->uc['pageTree_temporaryMountPoint']);
+		}
+
+		if ($uid <= 0) {
+			return '';
+		}
+
+		$useNavTitle = $GLOBALS['BE_USER']->getTSConfigVal('options.pageTree.showNavTitle');
+		$rootline = array_reverse(t3lib_BEfunc::BEgetRootLine($uid));
+		array_shift($rootline);
+
+		$path = array();
+		foreach ($rootline as $rootlineElement) {
+			$record = t3lib_tree_pagetree_Commands::getNodeRecord($rootlineElement['uid']);
+
+			$text = $record['title'];
+			if ($useNavTitle && trim($record['nav_title']) !== '') {
+				$text = $record['nav_title'];
+			}
+
+			$path[] = $text;
+		}
+
+		return htmlspecialchars('/' . implode('/', $path));
+	}
+
+	/**
+	 * Returns a node record from a given id
+	 *
+	 * @param int $nodeId
+	 * @param boolean $unsetMovePointers
+	 * @return array
+	 */
+	public static function getNodeRecord($nodeId, $unsetMovePointers = TRUE) {
+		$record = t3lib_BEfunc::getRecordWSOL('pages', $nodeId, '*', '', TRUE, $unsetMovePointers);
+		return $record;
+	}
+
+	/**
+	 * Returns the first configured domain name for a page
+	 *
+	 * @static
+	 * @param integer $uid
+	 * @return string
+	 */
+	public static function getDomainName($uid) {
+		$whereClause = $GLOBALS['TYPO3_DB']->quoteStr(
+			'pid=' . intval($uid) . t3lib_BEfunc::deleteClause('sys_domain') .
+				t3lib_BEfunc::BEenableFields('sys_domain'),
+			'sys_domain'
+		);
+
+		$domain = $GLOBALS['TYPO3_DB']->exec_SELECTgetSingleRow(
+			'domainName',
+			'sys_domain',
+			$whereClause,
+			'',
+			'sorting'
+		);
+
+		return htmlspecialchars($domain['domainName']);
+	}
+
+	/**
+	 * Creates a node with the given record information's
+	 *
+	 * @param array $record
+	 * @return t3lib_tree_pagetree_Node
+	 */
+	public static function getNewNode($record, $mountPoint = 0) {
+		$useNavTitle = $GLOBALS['BE_USER']->getTSConfigVal('options.pageTree.showNavTitle');
+		$addIdAsPrefix = $GLOBALS['BE_USER']->getTSConfigVal('options.pageTree.showPageIdWithTitle');
+		$addDomainName = $GLOBALS['BE_USER']->getTSConfigVal('options.pageTree.showDomainNameWithTitle');
+		$titleLength = intval($GLOBALS['BE_USER']->uc['titleLen']);
+
+		/** @var $subNode t3lib_tree_pagetree_Node */
+		$subNode = t3lib_div::makeInstance('t3lib_tree_pagetree_Node');
+		$subNode->setRecord($record);
+		$subNode->setCls($record['_CSSCLASS']);
+		$subNode->setQTip(str_replace(' - ', '<br />', t3lib_BEfunc::titleAttribForPages($record, '', FALSE)));
+		$subNode->setType('pages');
+
+		$subNode->setId($record['uid']);
+		$subNode->setMountPoint($mountPoint);
+		$subNode->setWorkspaceId(($record['_ORIG_uid'] ? $record['_ORIG_uid'] : $record['uid']));
+
+		$field = 'title';
+		$text = $record['title'];
+		if ($useNavTitle && trim($record['nav_title']) !== '') {
+			$field = 'nav_title';
+			$text = $record['nav_title'];
+		}
+		$visibleText = t3lib_div::fixed_lgd_cs($text, $titleLength);
+
+		$suffix = '';
+		if ($addDomainName) {
+			$domain = self::getDomainName($record['uid']);
+			$suffix = ($domain !== '' ? ' [' . $domain . ']' : '');
+		}
+
+		$prefix = ($addIdAsPrefix ? '[' . $record['uid'] . '] ' : '');
+		$subNode->setEditableText($text);
+		$subNode->setText(
+			htmlspecialchars($visibleText),
+			$field,
+			htmlspecialchars($prefix),
+			htmlspecialchars($suffix)
+		);
+
+		if ($record['uid'] !== 0) {
+			$spriteIconCode = t3lib_iconWorks::getSpriteIconForRecord('pages', $record);
+		} else {
+			$spriteIconCode = t3lib_iconWorks::getSpriteIcon('apps-pagetree-root');
+		}
+		$subNode->setSpriteIconCode($spriteIconCode);
+
+		if (!$subNode->canCreateNewPages() || intval($record['t3ver_state']) === 2) {
+			$subNode->setIsDropTarget(FALSE);
+		}
+
+		if (!$subNode->canBeEdited() || !$subNode->canBeRemoved() || intval($record['t3ver_state']) === 2) {
+			$subNode->setDraggable(FALSE);
+		}
+
+		return $subNode;
+	}
+}
+
+?>
\ No newline at end of file
Index: t3lib/tree/pagetree/class.t3lib_tree_pagetree_nodecollection.php
===================================================================
--- t3lib/tree/pagetree/class.t3lib_tree_pagetree_nodecollection.php	(Revision 0)
+++ t3lib/tree/pagetree/class.t3lib_tree_pagetree_nodecollection.php	(Revision 0)
@@ -0,0 +1,52 @@
+<?php
+/***************************************************************
+*  Copyright notice
+*
+*  (c) 2010 TYPO3 Tree Team <http://forge.typo3.org/projects/typo3v4-extjstrees>
+*  All rights reserved
+*
+*  This script is part of the TYPO3 project. The TYPO3 project is
+*  free software; you can redistribute it and/or modify
+*  it under the terms of the GNU General Public License as published by
+*  the Free Software Foundation; either version 2 of the License, or
+*  (at your option) any later version.
+*
+*  The GNU General Public License can be found at
+*  http://www.gnu.org/copyleft/gpl.html.
+*  A copy is found in the textfile GPL.txt and important notices to the license
+*  from the author is found in LICENSE.txt distributed with these scripts.
+*
+*
+*  This script is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*  GNU General Public License for more details.
+*
+*  This copyright notice MUST APPEAR in all copies of the script!
+***************************************************************/
+
+/**
+ * Tree Node Collection
+ *
+ * @author Stefan Galinski <stefan.galinski@gmail.com>
+ * @package TYPO3
+ * @subpackage t3lib
+ */
+class t3lib_tree_pagetree_NodeCollection extends t3lib_tree_NodeCollection {
+	/**
+	 * Returns the collection in an array representation for e.g. serialization
+	 *
+	 * @return array
+	 */
+	public function toArray() {
+		$arrayRepresentation = parent::toArray();
+		unset($arrayRepresentation['serializeClassName']);
+		return $arrayRepresentation;
+	}
+}
+
+if (defined('TYPO3_MODE') && isset($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['t3lib/tree/pagetree/class.t3lib_tree_pagetree_nodecollection.php'])) {
+	include_once($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['t3lib/tree/pagetree/class.t3lib_tree_pagetree_nodecollection.php']);
+}
+
+?>
\ No newline at end of file
Index: t3lib/tree/pagetree/interfaces/interface.t3lib_tree_pagetree_interfaces_indicatorprovider.php
===================================================================
--- t3lib/tree/pagetree/interfaces/interface.t3lib_tree_pagetree_interfaces_indicatorprovider.php	(Revision 0)
+++ t3lib/tree/pagetree/interfaces/interface.t3lib_tree_pagetree_interfaces_indicatorprovider.php	(Revision 0)
@@ -0,0 +1,44 @@
+<?php
+/***************************************************************
+ *  Copyright notice
+ *
+ *  (c) 2010 Susanne Moog <typo3@susanne-moog.de>
+ *  All rights reserved
+ *
+ *  This script is part of the TYPO3 project. The TYPO3 project is
+ *  free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  The GNU General Public License can be found at
+ *  http://www.gnu.org/copyleft/gpl.html.
+ *  A copy is found in the textfile GPL.txt and important notices to the license
+ *  from the author is found in LICENSE.txt distributed with these scripts.
+ *
+ *
+ *  This script is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  This copyright notice MUST APPEAR in all copies of the script!
+ ***************************************************************/
+
+/**
+ * Interface for classes which provide a pagetree indicator.
+ *
+ * @author Susanne Moog <typo3@susanne-moog.de>
+ * @package	TYPO3
+ * @subpackage t3lib
+ */
+interface t3lib_tree_pagetree_interfaces_IndicatorProvider {
+	/**
+	 * Returns the indicator html code
+	 *
+	 * @return	string
+	 */
+	function getIndicator();
+}
+
+?>
\ No newline at end of file
Index: t3lib/tree/pagetree/class.t3lib_tree_pagetree_dataprovider.php
===================================================================
--- t3lib/tree/pagetree/class.t3lib_tree_pagetree_dataprovider.php	(Revision 0)
+++ t3lib/tree/pagetree/class.t3lib_tree_pagetree_dataprovider.php	(Revision 0)
@@ -0,0 +1,375 @@
+<?php
+/***************************************************************
+*  Copyright notice
+*
+*  (c) 2010 TYPO3 Tree Team <http://forge.typo3.org/projects/typo3v4-extjstrees>
+*  All rights reserved
+*
+*  This script is part of the TYPO3 project. The TYPO3 project is
+*  free software; you can redistribute it and/or modify
+*  it under the terms of the GNU General Public License as published by
+*  the Free Software Foundation; either version 2 of the License, or
+*  (at your option) any later version.
+*
+*  The GNU General Public License can be found at
+*  http://www.gnu.org/copyleft/gpl.html.
+*  A copy is found in the textfile GPL.txt and important notices to the license
+*  from the author is found in LICENSE.txt distributed with these scripts.
+*
+*
+*  This script is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*  GNU General Public License for more details.
+*
+*  This copyright notice MUST APPEAR in all copies of the script!
+***************************************************************/
+
+/**
+ * Abstract Tree Data Provider
+ *
+ * @author Stefan Galinski <stefan.galinski@gmail.com>
+ * @package TYPO3
+ * @subpackage t3lib
+ */
+class t3lib_tree_pagetree_DataProvider extends t3lib_tree_AbstractDataProvider {
+	/**
+	 * Node limit that should be loaded for this request per mount
+	 *
+	 * @var int
+	 */
+	protected $nodeLimit = 500;
+
+	/**
+	 * Current amount of nodes
+	 *
+	 * @var int
+	 */
+	protected $nodeCounter = 0;
+
+	/**
+	 * Hidden Records
+	 *
+	 * @var array
+	 */
+	protected $hiddenRecords = array();
+
+	/**
+	 * Constructor
+	 */
+	public function __construct() {
+		$this->hiddenRecords = t3lib_div::trimExplode(
+			',',
+			$GLOBALS['BE_USER']->getTSConfigVal('options.hideRecords.pages')
+		);
+	}
+
+	/**
+	 * Returns the root node
+	 *
+	 * @return t3lib_tree_Node
+	 */
+	public function getRoot() {
+		/** @var $node t3lib_tree_pagetree_Node */
+		$node = t3lib_div::makeInstance('t3lib_tree_pagetree_Node');
+		$node->setId('root');
+		$node->setExpanded(true);
+
+		return $node;
+	}
+
+	/**
+	 * Fetches the sub-nodes of the given node
+	 *
+	 * @param t3lib_tree_Node $node
+	 * @param int $mountPoint
+	 * @param int $level internally used variable as a recursion limiter
+	 * @return t3lib_tree_NodeCollection
+	 */
+	 public function getNodes(t3lib_tree_Node $node, $mountPoint = 0, $level = 0) {
+		/** @var $nodeCollection t3lib_tree_pagetree_NodeCollection */
+		$nodeCollection = t3lib_div::makeInstance('t3lib_tree_pagetree_NodeCollection');
+		if ($level >= 99) {
+			return $nodeCollection;
+		}
+
+		$subpages = $this->getSubpages($node->getId());
+		if (!is_array($subpages) || !count($subpages)) {
+			return $nodeCollection;
+		}
+
+		foreach ($subpages as $subpage) {
+			if (in_array($subpage['uid'], $this->hiddenRecords)) {
+				continue;
+			}
+
+			$subpage = t3lib_befunc::getRecordWSOL('pages', $subpage['uid'], '*', '', TRUE, TRUE);
+			if (!$subpage) {
+				continue;
+			}
+
+			$subNode = t3lib_tree_pagetree_Commands::getNewNode($subpage, $mountPoint);
+			if ($this->nodeCounter < $this->nodeLimit) {
+				$childNodes = $this->getNodes($subNode, $mountPoint, $level + 1);
+				$subNode->setChildNodes($childNodes);
+				$this->nodeCounter += $childNodes->count();
+			} else {
+				$subNode->setLeaf(!$this->hasNodeSubPages($subNode->getId()));
+			}
+
+			$nodeCollection->append($subNode);
+		}
+
+		return $nodeCollection;
+	}
+
+	/**
+	 * Returns a node collection of filtered nodes
+	 *
+	 * @param t3lib_tree_Node $node
+	 * @param string $searchFilter
+	 * @param int $mountPoint
+	 * @return void
+	 */
+	public function getFilteredNodes(t3lib_tree_Node $node, $searchFilter, $mountPoint = 0) {
+		/** @var $nodeCollection t3lib_tree_pagetree_NodeCollection */
+		$nodeCollection = t3lib_div::makeInstance('t3lib_tree_pagetree_NodeCollection');
+
+		$records = $this->getSubpages(-1, $searchFilter);
+		if (!is_array($records) || !count($records)) {
+			return $nodeCollection;
+		}
+
+		$isNumericSearchFilter = (is_numeric($searchFilter) && $searchFilter > 0);
+		$nodeId = intval($node->getId());
+		foreach ($records as $record) {
+			$record = t3lib_tree_pagetree_Commands::getNodeRecord($record['uid']);
+			if (intval($record['pid']) === -1 || in_array($record['uid'], $this->hiddenRecords)) {
+				continue;
+			}
+
+			$rootline = t3lib_BEfunc::BEgetRootLine($record['uid'], ' AND uid != ' . $nodeId);
+			$rootline = array_reverse($rootline);
+			if ($nodeId === 0) {
+				array_shift($rootline);
+			}
+			$reference = $nodeCollection;
+
+			$inFilteredRootline = FALSE;
+			$amountOfRootlineElements = count($rootline);
+			for ($i = 0; $i < $amountOfRootlineElements; ++$i) {
+				$rootlineElement = $rootline[$i];
+				if (intval($rootlineElement['pid']) === $nodeId) {
+					$inFilteredRootline = TRUE;
+				}
+
+				if (!$inFilteredRootline) {
+					continue;
+				}
+
+				$rootlineElement = t3lib_tree_pagetree_Commands::getNodeRecord($rootlineElement['uid']);
+				$ident = intval($rootlineElement['sorting']) . intval($rootlineElement['uid']);
+				if ($reference->offsetExists($ident)) {
+					/** @var $refNode t3lib_tree_pagetree_Node */
+					$refNode = $reference->offsetGet($ident);
+					$refNode->setExpanded(TRUE);
+					$refNode->setLeaf(FALSE);
+
+					$reference = $refNode->getChildNodes();
+					continue;
+				}
+
+				$refNode = t3lib_tree_pagetree_Commands::getNewNode($rootlineElement, $mountPoint);
+				$replacement = '<span class="typo3-pagetree-filteringTree-highlight">$1</span>';
+				if ($isNumericSearchFilter && intval($rootlineElement['uid']) === intval($searchFilter)) {
+					$text = str_replace('$1', $refNode->getText(), $replacement);
+				} else {
+					$text = preg_replace('/(' . $searchFilter . ')/i', $replacement, $refNode->getText());
+				}
+
+				$refNode->setText(
+					$text,
+					$refNode->getTextSourceField(),
+					$refNode->getPrefix(),
+					$refNode->getSuffix()
+				);
+
+				/** @var $childCollection t3lib_tree_pagetree_NodeCollection */
+				$childCollection = t3lib_div::makeInstance('t3lib_tree_pagetree_NodeCollection');
+
+				if (($i +1) >= $amountOfRootlineElements) {
+					$childNodes = $this->getNodes($refNode, $mountPoint);
+					foreach ($childNodes as $childNode) {
+						/** @var $childNode t3lib_tree_pagetree_Node */
+						$childRecord = $childNode->getRecord();
+						$childIdent = intval($childRecord['sorting']) . intval($childRecord['uid']);
+						$childCollection->offsetSet($childIdent, $childNode);
+					}
+					$refNode->setChildNodes($childNodes);
+				}
+
+				$refNode->setChildNodes($childCollection);
+				$reference->offsetSet($ident, $refNode);
+				$reference->ksort();
+
+				$reference = $childCollection;
+			}
+		}
+
+		return $nodeCollection;
+	}
+
+	/**
+	 * Returns the page tree mounts for the current user
+	 *
+	 * Note: If you add the search filter parameter, the nodes will be filtered by this string.
+	 *
+	 * @param string $searchFilter
+	 * @return array
+	 */
+	public function getTreeMounts($searchFilter = '') {
+		/** @var $nodeCollection t3lib_tree_pagetree_NodeCollection */
+		$nodeCollection = t3lib_div::makeInstance('t3lib_tree_pagetree_NodeCollection');
+
+		$isTemporaryMountPoint = FALSE;
+		$mountPoints = intval($GLOBALS['BE_USER']->uc['pageTree_temporaryMountPoint']);
+		if (!$mountPoints) {
+			$mountPoints = array_map('intval', $GLOBALS['BE_USER']->returnWebmounts());
+			$mountPoints = array_unique($mountPoints);
+		} else {
+			$isTemporaryMountPoint = TRUE;
+			$mountPoints = array($mountPoints);
+		}
+
+		if (!count($mountPoints)) {
+			return $nodeCollection;
+		}
+
+		$showRootlineAboveMounts = $GLOBALS['BE_USER']->getTSConfigVal('options.pageTree.showPathAboveMounts');
+		$class = (count($mountPoints) <= 1 ? 'typo3-pagetree-node-notExpandable' : '');
+		foreach ($mountPoints as $mountPoint) {
+			if ($mountPoint === 0) {
+				$sitename = 'TYPO3';
+				if ($GLOBALS['TYPO3_CONF_VARS']['SYS']['sitename'] !== '') {
+					$sitename = $GLOBALS['TYPO3_CONF_VARS']['SYS']['sitename'];
+				}
+
+				$record = array(
+					'uid' => 0,
+					'title' => $sitename,
+				);
+				$subNode = t3lib_tree_pagetree_Commands::getNewNode($record);
+				$subNode->setLabelIsEditable(FALSE);
+				$subNode->setType('pages_root');
+			} else {
+				$record = t3lib_BEfunc::getRecordWSOL('pages', $mountPoint, '*', '', TRUE);
+				if (!$record) {
+					continue;
+				}
+
+				$subNode = t3lib_tree_pagetree_Commands::getNewNode($record, $mountPoint);
+				if ($showRootlineAboveMounts && !$isTemporaryMountPoint) {
+					$rootline = t3lib_tree_pagetree_Commands::getMountPointPath($record['uid']);
+					$subNode->setReadableRootline($rootline);
+				}
+			}
+
+			$subNode->setIsMountPoint(TRUE);
+			$subNode->setExpanded(TRUE);
+			$subNode->setDraggable(FALSE);
+			$subNode->setIsDropTarget(FALSE);
+			$subNode->setCls($class);
+
+			if ($searchFilter === '') {
+				$childNodes = $this->getNodes($subNode, $mountPoint);
+			} else {
+				$childNodes = $this->getFilteredNodes($subNode, $searchFilter, $mountPoint);
+				$subNode->setExpanded(TRUE);
+			}
+
+			$subNode->setChildNodes($childNodes);
+			$nodeCollection->append($subNode);
+		}
+
+		return $nodeCollection;
+	}
+
+	/**
+	 * Returns the where clause for fetching pages
+	 *
+	 * @param int $id
+	 * @param string $searchFilter
+	 * @return string
+	 */
+	protected function getWhereClause($id, $searchFilter = '') {
+		$where = $GLOBALS['BE_USER']->getPagePermsClause(1) .
+			t3lib_BEfunc::deleteClause('pages') .
+			t3lib_BEfunc::versioningPlaceholderClause('pages');
+
+		if (is_numeric($id) && $id >= 0) {
+			$where .= ' AND pid= ' . $GLOBALS['TYPO3_DB']->fullQuoteStr(intval($id), 'pages');
+		}
+
+		if ($searchFilter !== '') {
+			if (is_numeric($searchFilter) && $searchFilter > 0) {
+				$seachWhere .= 'uid = ' . intval($searchFilter) . ' OR ';
+			}
+
+			$searchFilter = $GLOBALS['TYPO3_DB']->fullQuoteStr('%' . $searchFilter . '%', 'pages');
+			$useNavTitle = $GLOBALS['BE_USER']->getTSConfigVal('options.pageTree.showNavTitle');
+
+			if ($useNavTitle) {
+				$seachWhere .= '(nav_title LIKE ' . $searchFilter .
+					' OR (nav_title = "" && title LIKE ' . $searchFilter . '))';
+			} else {
+				$seachWhere .= 'title LIKE ' . $searchFilter;
+			}
+
+			$where .= ' AND (' . $seachWhere . ')';
+		}
+
+		return $where;
+	}
+
+	/**
+	 * Returns all sub-pages of a given id
+	 *
+	 * @param int $id
+	 * @param string $searchFilter
+	 * @return array
+	 */
+	protected function getSubpages($id, $searchFilter = '') {
+		$where = $this->getWhereClause($id, $searchFilter);
+		$subpages = $GLOBALS['TYPO3_DB']->exec_SELECTgetRows(
+			'uid', 'pages', $where, '', 'sorting', '', 'uid'
+		);
+
+		return $subpages;
+	}
+
+	/**
+	 * Returns true if the node has child's
+	 *
+	 * @param int $id
+	 * @return bool
+	 */
+	protected function hasNodeSubPages($id) {
+		$where = $this->getWhereClause($id);
+		$subpage = $GLOBALS['TYPO3_DB']->exec_SELECTgetSingleRow(
+			'uid', 'pages', $where, '', 'sorting', '', 'uid'
+		);
+
+		$returnValue = TRUE;
+		if (!$subpage['uid']) {
+			$returnValue = FALSE;
+		}
+
+		return $returnValue;
+	}
+}
+
+if (defined('TYPO3_MODE') && isset($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['t3lib/tree/pagetree/class.t3lib_tree_pagetree_dataprovider.php'])) {
+	include_once($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['t3lib/tree/pagetree/class.t3lib_tree_pagetree_dataprovider.php']);
+}
+
+?>
\ No newline at end of file
Index: t3lib/tree/pagetree/class.t3lib_tree_pagetree_node.php
===================================================================
--- t3lib/tree/pagetree/class.t3lib_tree_pagetree_node.php	(Revision 0)
+++ t3lib/tree/pagetree/class.t3lib_tree_pagetree_node.php	(Revision 0)
@@ -0,0 +1,343 @@
+<?php
+/***************************************************************
+*  Copyright notice
+*
+*  (c) 2010 TYPO3 Tree Team <http://forge.typo3.org/projects/typo3v4-extjstrees>
+*  All rights reserved
+*
+*  This script is part of the TYPO3 project. The TYPO3 project is
+*  free software; you can redistribute it and/or modify
+*  it under the terms of the GNU General Public License as published by
+*  the Free Software Foundation; either version 2 of the License, or
+*  (at your option) any later version.
+*
+*  The GNU General Public License can be found at
+*  http://www.gnu.org/copyleft/gpl.html.
+*  A copy is found in the textfile GPL.txt and important notices to the license
+*  from the author is found in LICENSE.txt distributed with these scripts.
+*
+*
+*  This script is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*  GNU General Public License for more details.
+*
+*  This copyright notice MUST APPEAR in all copies of the script!
+***************************************************************/
+
+/**
+ * Node designated for the page tree
+ *
+ * @author Stefan Galinski <stefan.galinski@gmail.com>
+ * @package TYPO3
+ * @subpackage t3lib
+ */
+class t3lib_tree_pagetree_Node extends t3lib_tree_extdirect_Node {
+	/**
+	 * Cached access rights to save some performance
+	 *
+	 * @var array
+	 */
+	protected $cachedAccessRights = array();
+
+	/**
+	 * Workspace Overlay Id
+	 *
+	 * @var int
+	 */
+	protected $workspaceId = 0;
+
+	/**
+	 * Mount Point Id
+	 *
+	 * @var int
+	 */
+	protected $mountPoint = 0;
+
+	/**
+	 * Readable Rootline
+	 *
+	 * @var string
+	 */
+	protected $readableRootline = '';
+
+	/**
+	 * Indicator if the node is a mount point
+	 *
+	 * @var bool
+	 */
+	protected $isMountPoint = FALSE;
+
+	/**
+	 * Set's the original id of the element
+	 *
+	 * @param int $workspaceId
+	 * @return void
+	 */
+	public function setWorkspaceId($workspaceId) {
+		$this->workspaceId = intval($workspaceId);
+	}
+
+	/**
+	 * Returns the original id of the element
+	 *
+	 * @return int
+	 */
+	public function getWorkspaceId() {
+		return $this->workspaceId;
+	}
+
+	/**
+	 * Sets the mount point id
+	 *
+	 * @param int $mountPoint
+	 * @return void
+	 */
+	public function setMountPoint($mountPoint) {
+		$this->mountPoint = intval($mountPoint);
+	}
+
+	/**
+	 * Returns the mount point id
+	 *
+	 * @return int
+	 */
+	public function getMountPoint() {
+		return $this->mountPoint;
+	}
+
+	/**
+	 * Sets the indicator if the node is a mount point
+	 *
+	 * @param boolean $isMountPoint
+	 * @return void
+	 */
+	public function setIsMountPoint($isMountPoint) {
+		$this->isMountPoint = ($isMountPoint == TRUE);
+	}
+
+	/**
+	 * Returns true if the node is a mount point
+	 *
+	 * @return bool
+	 */
+	public function isMountPoint() {
+		return $this->isMountPoint;
+	}
+
+	/**
+	 * Sets the readable rootline
+	 *
+	 * @param string $rootline
+	 * @return void
+	 */
+	public function setReadableRootline($rootline) {
+		$this->readableRootline = $rootline;
+	}
+
+	/**
+	 * Returns the readable rootline
+	 *
+	 * @return string
+	 */
+	public function getReadableRootline() {
+		return $this->readableRootline;
+	}
+
+	/**
+	 * Checks if the user may create pages below the given page
+	 *
+	 * @return void
+	 */
+	protected function canCreate() {
+		if (!isset($this->cachedAccessRights['create'])) {
+			$this->cachedAccessRights['create'] =
+				$GLOBALS['BE_USER']->doesUserHaveAccess($this->record, 8);
+		}
+
+		return $this->cachedAccessRights['create'];
+	}
+
+	/**
+	 * Checks if the user has editing rights
+	 *
+	 * @return void
+	 */
+	protected function canEdit() {
+		if (!isset($this->cachedAccessRights['edit'])) {
+			$this->cachedAccessRights['edit'] =
+				$GLOBALS['BE_USER']->doesUserHaveAccess($this->record, 2);
+		}
+
+		return $this->cachedAccessRights['edit'];
+	}
+
+	/**
+	 * Checks if the user has the right to delete the page
+	 *
+	 * @return void
+	 */
+	protected function canRemove()	{
+		if (!isset($this->cachedAccessRights['remove'])) {
+			$this->cachedAccessRights['remove'] =
+				$GLOBALS['BE_USER']->doesUserHaveAccess($this->record, 4);
+
+			if (!$this->isLeafNode() && !$GLOBALS['BE_USER']->uc['recursiveDelete']) {
+				$this->cachedAccessRights['remove'] = FALSE;
+			}
+		}
+
+		return $this->cachedAccessRights['remove'];
+	}
+
+	/**
+	 * Checks if the page can be disabled
+	 *
+	 * @return void
+	 */
+	public function canBeDisabledAndEnabled() {
+		return $this->canEdit($this->record);
+	}
+
+	/**
+	 * Checks if the page is allowed to can be cut
+	 *
+	 * @return void
+	 */
+	public function canBeCut() {
+		return $this->canEdit($this->record) && intval($this->record['t3ver_state']) !== 2;
+	}
+
+	/**
+	 * Checks if the page is allowed to be edited
+	 *
+	 * @return void
+	 */
+	public function canBeEdited() {
+		return $this->canEdit($this->record);
+	}
+
+	/**
+	 * Checks if the page is allowed to be copied
+	 *
+	 * @return void
+	 */
+	public function canBeCopied() {
+		return $this->canCreate($this->record) && intval($this->record['t3ver_state']) !== 2;
+	}
+
+	/**
+	 * Checks if there can be new pages created
+	 *
+	 * @return void
+	 */
+	public function canCreateNewPages() {
+		return $this->canCreate($this->record);
+	}
+
+	/**
+	 * Checks if the page is allowed to be removed
+	 *
+	 * @return void
+	 */
+	public function canBeRemoved() {
+		return $this->canRemove($this->record) && intval($this->record['t3ver_state']) !== 2;
+	}
+
+	/**
+	 * Checks if something can be pasted into the node
+	 *
+	 * @return bool
+	 */
+	public function canBePastedInto() {
+		return intval($this->record['t3ver_state']) !== 2;
+	}
+
+	/**
+	 * Checks if something can be pasted after the node
+	 *
+	 * @return bool
+	 */
+	public function canBePastedAfter() {
+		return intval($this->record['t3ver_state']) !== 2;
+	}
+
+	/**
+	 * Checks if the page is allowed to show history
+	 *
+	 * @return void
+	 */
+	public function canShowHistory() {
+		return TRUE;
+	}
+
+	/**
+	 * Checks if the page is allowed to be viewed
+	 *
+	 * @return void
+	 */
+	public function canBeViewed() {
+		return TRUE;
+	}
+
+	/**
+	 * Checks if the page is allowed to show info
+	 *
+	 * @return void
+	 */
+	public function canShowInfo() {
+		return TRUE;
+	}
+
+	/**
+	 * Checks if the page is allowed to be a temporary mount point
+	 *
+	 * @return void
+	 */
+	public function canBeTemporaryMountPoint() {
+		return TRUE;
+	}
+
+	/**
+	 * Returns the node in an array representation that can be used for serialization
+	 *
+	 * @return array
+	 */
+	public function toArray() {
+		$arrayRepresentation = parent::toArray();
+
+		$arrayRepresentation['id'] = 'mp-' . $this->getMountPoint() . '-' . $this->getId();
+		$arrayRepresentation['realId'] = $this->getId();
+		$arrayRepresentation['nodeData']['id'] = $this->getId();
+
+		$arrayRepresentation['readableRootline'] = $this->getReadableRootline();
+		$arrayRepresentation['nodeData']['readableRootline'] = $this->getReadableRootline();
+
+		$arrayRepresentation['nodeData']['mountPoint'] = $this->getMountPoint();
+		$arrayRepresentation['nodeData']['workspaceId'] = $this->getWorkspaceId();
+		$arrayRepresentation['nodeData']['isMountPoint'] = $this->isMountPoint();
+		$arrayRepresentation['nodeData']['serializeClassName'] = get_class($this);
+
+		return $arrayRepresentation;
+	}
+
+	/**
+	 * Sets data of the node by a given data array
+	 *
+	 * @param array $data
+	 * @return void
+	 */
+	public function dataFromArray($data) {
+		parent::dataFromArray($data);
+		$this->setWorkspaceId($data['workspaceId']);
+		$this->setMountPoint($data['mountPoint']);
+		$this->setReadableRootline($data['readableRootline']);
+		$this->setIsMountPoint($data['isMountPoint']);
+	}
+}
+
+if (defined('TYPO3_MODE') && isset($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['t3lib/tree/pagetree/class.t3lib_tree_pagetree_node.php'])) {
+	include_once($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['t3lib/tree/pagetree/class.t3lib_tree_pagetree_node.php']);
+}
+
+?>
\ No newline at end of file
Index: t3lib/tree/pagetree/extdirect/class.t3lib_tree_pagetree_extdirect_tree.php
===================================================================
--- t3lib/tree/pagetree/extdirect/class.t3lib_tree_pagetree_extdirect_tree.php	(Revision 0)
+++ t3lib/tree/pagetree/extdirect/class.t3lib_tree_pagetree_extdirect_tree.php	(Revision 0)
@@ -0,0 +1,232 @@
+<?php
+/***************************************************************
+*  Copyright notice
+*
+*  (c) 2010 TYPO3 Tree Team <http://forge.typo3.org/projects/typo3v4-extjstrees>
+*  All rights reserved
+*
+*  This script is part of the TYPO3 project. The TYPO3 project is
+*  free software; you can redistribute it and/or modify
+*  it under the terms of the GNU General Public License as published by
+*  the Free Software Foundation; either version 2 of the License, or
+*  (at your option) any later version.
+*
+*  The GNU General Public License can be found at
+*  http://www.gnu.org/copyleft/gpl.html.
+*  A copy is found in the textfile GPL.txt and important notices to the license
+*  from the author is found in LICENSE.txt distributed with these scripts.
+*
+*
+*  This script is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*  GNU General Public License for more details.
+*
+*  This copyright notice MUST APPEAR in all copies of the script!
+***************************************************************/
+
+/**
+ * Data Provider of the Page Tree
+ *
+ * @author Stefan Galinski <stefan.galinski@gmail.com>
+ * @package TYPO3
+ * @subpackage t3lib
+ */
+class t3lib_tree_pagetree_extdirect_Tree extends t3lib_tree_ExtDirect_AbstractExtJsTree {
+	/**
+	 * Sets the data provider
+	 *
+	 * @return void
+	 */
+	protected function initDataProvider() {
+		/** @var $dataProvider t3lib_tree_pagetree_DataProvider */
+		$dataProvider = t3lib_div::makeInstance('t3lib_tree_pagetree_DataProvider');
+		$this->setDataProvider($dataProvider);
+	}
+
+	/**
+	 * Data Provider
+	 *
+	 * @return t3lib_tree_pagetree_DataProvider
+	 */
+	protected $dataProvider = NULL;
+
+	/**
+	 * Returns the root node of the tree
+	 *
+	 * @return array
+	 */
+	public function getRoot() {
+		$this->initDataProvider();
+		$node = $this->dataProvider->getRoot();
+
+		return $node->toArray();
+	}
+
+	/**
+	 * Fetches the next tree level
+	 *
+	 * @param int $nodeId
+	 * @param stdClass $nodeData
+	 * @return array
+	 */
+	public function getNextTreeLevel($nodeId, $nodeData) {
+		$this->initDataProvider();
+
+		/** @var $node t3lib_tree_pagetree_Node */
+		$node = t3lib_div::makeInstance('t3lib_tree_pagetree_Node', (array) $nodeData);
+
+		if ($nodeId === 'root') {
+			$nodeCollection = $this->dataProvider->getTreeMounts();
+		} else {
+			$nodeCollection = $this->dataProvider->getNodes($node);
+		}
+
+		return $nodeCollection->toArray();
+	}
+
+	/**
+	 * Returns a tree that only contains elements that match the given search string
+	 *
+	 * @param int $nodeId
+	 * @param stdClass $nodeData
+	 * @param string $searchFilter
+	 * @return array
+	 */
+	public function getFilteredTree($nodeId, $nodeData, $searchFilter) {
+		if (strval($searchFilter) === '') {
+			return array();
+		}
+
+		/** @var $node t3lib_tree_pagetree_Node */
+		$node = t3lib_div::makeInstance('t3lib_tree_pagetree_Node', (array) $nodeData);
+
+		$this->initDataProvider();
+		if ($nodeId === 'root') {
+			$nodeCollection = $this->dataProvider->getTreeMounts($searchFilter);
+		} else {
+			$nodeCollection = $this->dataProvider->getFilteredNodes($node, $searchFilter, $node->getMountPoint());
+		}
+
+		return $nodeCollection->toArray();
+	}
+
+	/**
+	 * Returns the localized list of doktypes to display
+	 *
+	 * Note: The list can be filtered by the user typoscript
+	 * option "options.pageTree.doktypesToShowInNewPageDragArea".
+	 *
+	 * @return array
+	 */
+	public function getNodeTypes() {
+		$map = array(
+			1 => 'LLL:EXT:lang/locallang_tca.php:doktype.I.0',
+			3 => 'LLL:EXT:cms/locallang_tca.php:pages.doktype.I.8',
+			4 => 'LLL:EXT:cms/locallang_tca.php:pages.doktype.I.2',
+			6 => 'LLL:EXT:cms/locallang_tca.php:pages.doktype.I.4',
+			7 => 'LLL:EXT:cms/locallang_tca.php:pages.doktype.I.5',
+			199 => 'LLL:EXT:cms/locallang_tca.php:pages.doktype.I.7',
+			254 => 'LLL:EXT:lang/locallang_tca.php:doktype.I.folder',
+			255 => 'LLL:EXT:lang/locallang_tca.php:doktype.I.2'
+		);
+
+		$doktypes = t3lib_div::trimExplode(
+			',', $GLOBALS['BE_USER']->getTSConfigVal('options.pageTree.doktypesToShowInNewPageDragArea')
+		);
+
+		$output = array();
+		$allowedDoktypes = t3lib_div::trimExplode(',', $GLOBALS['BE_USER']->groupData['pagetypes_select']);
+		$isAdmin = $GLOBALS['BE_USER']->isAdmin();
+		foreach ($doktypes as $doktype) {
+			if (!$isAdmin && !in_array($doktype, $allowedDoktypes)) {
+				continue;
+			}
+
+			$label = $GLOBALS['LANG']->sL($map[$doktype], TRUE);
+			$spriteIcon = t3lib_iconWorks::getSpriteIconClasses(
+				$GLOBALS['TCA']['pages']['ctrl']['typeicon_classes'][$doktype]
+			);
+
+			$output[] = array(
+				'nodeType' => $doktype,
+				'cls' => 'typo3-pagetree-topPanel-button',
+				'iconCls' => $spriteIcon,
+				'title' => $label,
+				'tooltip' => $label,
+			);
+		}
+
+		return $output;
+	}
+
+	/**
+	 * Returns
+	 *
+	 * @return array
+	 */
+	public function getIndicators() {
+		/** @var $indicatorProvider t3lib_tree_pagetree_Indicator */
+		$indicatorProvider = t3lib_div::makeInstance('t3lib_tree_pagetree_Indicator');
+		$indicatorHtmlArr = $indicatorProvider->getAllIndicators();
+		$indicator = array(
+				'html' => implode(' ', $indicatorHtmlArr),
+				'_COUNT' => count($indicatorHtmlArr)
+		);
+
+		return $indicator;
+	}
+
+	/**
+	 * Returns the language labels, sprites and configuration options for the pagetree
+	 *
+	 * @return void
+	 */
+	public function loadResources() {
+		$file = 'LLL:EXT:lang/locallang_core.xml:';
+		$indicators = $this->getIndicators();
+		$configuration = array(
+			'LLL' => array(
+				'copyHint' => $GLOBALS['LANG']->sL($file . 'tree.copyHint', TRUE),
+				'fakeNodeHint' => $GLOBALS['LANG']->sL($file . 'mess.please_wait', TRUE),
+				'activeFilterMode' => $GLOBALS['LANG']->sL($file . 'tree.activeFilterMode', TRUE),
+				'dropToRemove' => $GLOBALS['LANG']->sL($file . 'tree.dropToRemove', TRUE),
+				'buttonRefresh' => $GLOBALS['LANG']->sL($file . 'labels.refresh', TRUE),
+				'buttonNewNode' => $GLOBALS['LANG']->sL($file . 'tree.buttonNewNode', TRUE),
+				'buttonFilter' => $GLOBALS['LANG']->sL($file . 'tree.buttonFilter', TRUE),
+				'dropZoneElementRemoved' => $GLOBALS['LANG']->sL($file . 'tree.dropZoneElementRemoved', TRUE),
+				'dropZoneElementRestored' => $GLOBALS['LANG']->sL($file . 'tree.dropZoneElementRestored', TRUE),
+				'searchTermInfo' => $GLOBALS['LANG']->sL($file . 'tree.searchTermInfo', TRUE),
+				'temporaryMountPointIndicatorInfo' => $GLOBALS['LANG']->sl($file . 'labels.temporaryDBmount', TRUE),
+			),
+
+			'Configuration' => array(
+				'hideFilter' => $GLOBALS['BE_USER']->getTSConfigVal('options.pageTree.hideFilter'),
+				'displayDeleteConfirmation' => $GLOBALS['BE_USER']->jsConfirmation(4),
+				'disableIconLinkToContextmenu' => $GLOBALS['BE_USER']->getTSConfigVal(
+					'options.pageTree.disableIconLinkToContextmenu'
+				),
+				'indicator' => $indicators['html'],
+				'temporaryMountPoint' => t3lib_tree_pagetree_Commands::getMountPointPath(),
+			),
+
+			'Sprites' => array(
+				'Filter' => t3lib_iconWorks::getSpriteIconClasses('actions-system-tree-search-open'),
+				'NewNode' => t3lib_iconWorks::getSpriteIconClasses('actions-page-new'),
+				'Refresh' => t3lib_iconWorks::getSpriteIconClasses('actions-system-refresh'),
+				'InputClear' => t3lib_iconWorks::getSpriteIconClasses('actions-input-clear'),
+				'TrashCan' => t3lib_iconWorks::getSpriteIconClasses('actions-edit-delete'),
+				'TrashCanRestore' => t3lib_iconWorks::getSpriteIconClasses('actions-edit-restore'),
+				'Info' => t3lib_iconWorks::getSpriteIconClasses('actions-document-info'),
+			)
+		);
+
+		return $configuration;
+	}
+}
+
+if (defined('TYPO3_MODE') && isset($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['t3lib/tree/pagetree/extdirect/class.t3lib_tree_pagetree_extdirect_tree.php'])) {
+	include_once($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['t3lib/tree/pagetree/extdirect/class.t3lib_tree_pagetree_extdirect_tree.php']);
+}
+
+?>
\ No newline at end of file
Index: t3lib/tree/pagetree/extdirect/class.t3lib_tree_pagetree_extdirect_commands.php
===================================================================
--- t3lib/tree/pagetree/extdirect/class.t3lib_tree_pagetree_extdirect_commands.php	(Revision 0)
+++ t3lib/tree/pagetree/extdirect/class.t3lib_tree_pagetree_extdirect_commands.php	(Revision 0)
@@ -0,0 +1,392 @@
+<?php
+/***************************************************************
+*  Copyright notice
+*
+*  (c) 2010 TYPO3 Tree Team <http://forge.typo3.org/projects/typo3v4-extjstrees>
+*  All rights reserved
+*
+*  This script is part of the TYPO3 project. The TYPO3 project is
+*  free software; you can redistribute it and/or modify
+*  it under the terms of the GNU General Public License as published by
+*  the Free Software Foundation; either version 2 of the License, or
+*  (at your option) any later version.
+*
+*  The GNU General Public License can be found at
+*  http://www.gnu.org/copyleft/gpl.html.
+*  A copy is found in the textfile GPL.txt and important notices to the license
+*  from the author is found in LICENSE.txt distributed with these scripts.
+*
+*
+*  This script is distributed in the hope that it will be useful,
+*  but WITHOUT ANY WARRANTY; without even the implied warranty of
+*  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+*  GNU General Public License for more details.
+*
+*  This copyright notice MUST APPEAR in all copies of the script!
+***************************************************************/
+
+/**
+ * Commands for the Page tree
+ *
+ * @author Stefan Galinski <stefan.galinski@gmail.com>
+ * @package TYPO3
+ * @subpackage t3lib
+ */
+class t3lib_tree_pagetree_extdirect_Commands {
+	/**
+	 * Visibly the page
+	 *
+	 * @param stdClass $nodeData
+	 * @return array
+	 */
+	public function visiblyNode($nodeData) {
+		/** @var $node t3lib_tree_pagetree_Node */
+		$node = t3lib_div::makeInstance('t3lib_tree_pagetree_Node', (array) $nodeData);
+
+		/** @var $dataProvider t3lib_tree_pagetree_DataProvider */
+		$dataProvider = t3lib_div::makeInstance('t3lib_tree_pagetree_DataProvider');
+
+		try {
+			t3lib_tree_pagetree_Commands::visiblyNode($node);
+			$newNode = t3lib_tree_pagetree_Commands::getNode($node->getId());
+			$newNode->setLeaf($node->isLeafNode());
+			$returnValue = $newNode->toArray();
+		} catch (Exception $exception) {
+			$returnValue = array(
+				 'success' => FALSE,
+				 'error' => $exception->getMessage(),
+			 );
+		}
+
+		return $returnValue;
+	}
+
+	/**
+	 * Hide the page
+	 *
+	 * @param stdClass $nodeData
+	 * @return array
+	 */
+	public function disableNode($nodeData) {
+		/** @var $node t3lib_tree_pagetree_Node */
+		$node = t3lib_div::makeInstance('t3lib_tree_pagetree_Node', (array) $nodeData);
+
+		/** @var $dataProvider t3lib_tree_pagetree_DataProvider */
+		$dataProvider = t3lib_div::makeInstance('t3lib_tree_pagetree_DataProvider');
+
+		try {
+			t3lib_tree_pagetree_Commands::disableNode($node);
+			$newNode = t3lib_tree_pagetree_Commands::getNode($node->getId());
+			$newNode->setLeaf($node->isLeafNode());
+			$returnValue = $newNode->toArray();
+		} catch (Exception $exception) {
+			$returnValue = array(
+				 'success' => FALSE,
+				 'message' => $exception->getMessage(),
+			 );
+		}
+
+		return $returnValue;
+	}
+
+	/**
+	 * Delete the page
+	 *
+	 * @param stdClass $nodeData
+	 * @return array
+	 */
+	public function deleteNode($nodeData) {
+		/** @var $node t3lib_tree_pagetree_Node */
+		$node = t3lib_div::makeInstance('t3lib_tree_pagetree_Node', (array) $nodeData);
+
+		try {
+			t3lib_tree_pagetree_Commands::deleteNode($node);
+
+			$returnValue = array();
+			if ($GLOBALS['BE_USER']->workspace) {
+				$record = t3lib_tree_pagetree_Commands::getNodeRecord($node->getId());
+				if ($record['_ORIG_uid']) {
+					$newNode = t3lib_tree_pagetree_Commands::getNewNode($record);
+					$returnValue = $newNode->toArray();
+				}
+			}
+		} catch (Exception $exception) {
+			$returnValue = array(
+				 'success' => FALSE,
+				 'message' => $exception->getMessage(),
+			 );
+		}
+
+		return $returnValue;
+	}
+
+	/**
+	 * Gets title and message for JS deletion confirmation window
+	 *
+	 * @param  $uid The uid of the record to be deleted
+	 * @return array The title and the message for the confirmation window
+	 */
+	public function getConfirmContentDeletionMessage($uid) {
+		return array(
+			'title' => $GLOBALS['LANG']->sL('LLL:EXT:cms/layout/locallang.xml:deleteItem'),
+			'message' => $GLOBALS['LANG']->sL('LLL:EXT:cms/layout/locallang.xml:deleteWarning')
+		);
+	}
+
+	/**
+	 * Restore the page
+	 *
+	 * @param stdClass $nodeData
+	 * @param int $destination
+	 * @return array
+	 */
+	public function restoreNode($nodeData, $destination) {
+		/** @var $node t3lib_tree_pagetree_Node */
+		$node = t3lib_div::makeInstance('t3lib_tree_pagetree_Node', (array) $nodeData);
+
+		try {
+			t3lib_tree_pagetree_Commands::restoreNode($node, $destination);
+			$newNode = t3lib_tree_pagetree_Commands::getNode($node->getId());
+			$returnValue = $newNode->toArray();
+		} catch (Exception $exception) {
+			$returnValue = array(
+				 'success' => FALSE,
+				 'message' => $exception->getMessage(),
+			 );
+		}
+
+		return $returnValue;
+	}
+
+	/**
+	 * Updates the given field with a new text value, may be used to inline update
+	 * the title field in the new page tree
+	 *
+	 * @param stdClass $nodeData
+	 * @param string $updatedLabel
+	 * @return array
+	 */
+	public function updateLabel($nodeData, $updatedLabel) {
+		if ($updatedLabel === '') {
+			return array();
+		}
+
+		/** @var $node t3lib_tree_pagetree_Node */
+		$node = t3lib_div::makeInstance('t3lib_tree_pagetree_Node', (array) $nodeData);
+
+		try {
+			t3lib_tree_pagetree_Commands::updateNodeLabel($node, $updatedLabel);
+
+			$shortendedText = t3lib_div::fixed_lgd_cs($updatedLabel, intval($GLOBALS['BE_USER']->uc['titleLen']));
+			$returnValue = array(
+				'editableText' => $updatedLabel,
+				'updatedText' => htmlspecialchars($shortendedText),
+			);
+		} catch (Exception $exception) {
+			$returnValue = array(
+				 'success' => FALSE,
+				 'message' => $exception->getMessage(),
+			 );
+		}
+
+		return $returnValue;
+	}
+
+	/**
+	 * Sets a temporary mount point
+	 *
+	 * @param stdClass $nodeData
+	 * @return array
+	 */
+	public static function setTemporaryMountPoint($nodeData) {
+		/** @var $node t3lib_tree_pagetree_Node */
+		$node = t3lib_div::makeInstance('t3lib_tree_pagetree_Node', (array) $nodeData);
+		$GLOBALS['BE_USER']->uc['pageTree_temporaryMountPoint'] = $node->getId();
+		$GLOBALS['BE_USER']->writeUC($GLOBALS['BE_USER']->uc);
+
+		return t3lib_tree_pagetree_Commands::getMountPointPath();
+	}
+
+	/**
+	 * Moves the source node directly as the first child of the destination node
+	 *
+	 * @param stdClass $nodeData
+	 * @param int $destination
+	 * @return array
+	 */
+	public function moveNodeToFirstChildOfDestination($nodeData, $destination) {
+		/** @var $node t3lib_tree_pagetree_Node */
+		$node = t3lib_div::makeInstance('t3lib_tree_pagetree_Node', (array) $nodeData);
+
+		try {
+			t3lib_tree_pagetree_Commands::moveNode($node, $destination);
+			$newNode = t3lib_tree_pagetree_Commands::getNode($node->getId(), FALSE);
+			$newNode->setLeaf($node->isLeafNode());
+			$returnValue = $newNode->toArray();
+		} catch (Exception $exception) {
+			$returnValue = array(
+				 'success' => FALSE,
+				 'message' => $exception->getMessage(),
+			 );
+		}
+
+		return $returnValue;
+	}
+
+	/**
+	 * Moves the source node directly after the destination node
+	 *
+	 * @param stdClass $nodeData
+	 * @param int $destination
+	 * @return void
+	 */
+	public function moveNodeAfterDestination($nodeData, $destination) {
+		/** @var $node t3lib_tree_pagetree_Node */
+		$node = t3lib_div::makeInstance('t3lib_tree_pagetree_Node', (array) $nodeData);
+
+		try {
+			t3lib_tree_pagetree_Commands::moveNode($node, -$destination);
+			$newNode = t3lib_tree_pagetree_Commands::getNode($node->getId(), FALSE);
+			$newNode->setLeaf($node->isLeafNode());
+			$returnValue = $newNode->toArray();
+		} catch (Exception $exception) {
+			$returnValue = array(
+				 'success' => FALSE,
+				 'message' => $exception->getMessage(),
+			 );
+		}
+
+		return $returnValue;
+	}
+
+	/**
+	 * Copies the source node directly as the first child of the destination node and
+	 * returns the created node.
+	 *
+	 * @param stdClass $nodeData
+	 * @param int $destination
+	 * @return array
+	 */
+	public function copyNodeToFirstChildOfDestination($nodeData, $destination) {
+		/** @var $node t3lib_tree_pagetree_Node */
+		$node = t3lib_div::makeInstance('t3lib_tree_pagetree_Node', (array) $nodeData);
+
+		/** @var $dataProvider t3lib_tree_pagetree_DataProvider */
+		$dataProvider = t3lib_div::makeInstance('t3lib_tree_pagetree_DataProvider');
+
+		try {
+			$newPageId = t3lib_tree_pagetree_Commands::copyNode($node, $destination);
+			$newNode = t3lib_tree_pagetree_Commands::getNode($newPageId);
+			$newNode->setLeaf($node->isLeafNode());
+			$returnValue = $newNode->toArray();
+		} catch (Exception $exception) {
+			$returnValue = array(
+				 'success' => FALSE,
+				 'message' => $exception->getMessage(),
+			 );
+		}
+
+		return $returnValue;
+	}
+
+	/**
+	 * Copies the source node directly after the destination node and returns the
+	 * created node.
+	 *
+	 * @param stdClass $nodeData
+	 * @param int $destination
+	 * @return array
+	 */
+	public function copyNodeAfterDestination($nodeData, $destination) {
+		/** @var $node t3lib_tree_pagetree_Node */
+		$node = t3lib_div::makeInstance('t3lib_tree_pagetree_Node', (array) $nodeData);
+
+		/** @var $dataProvider t3lib_tree_pagetree_DataProvider */
+		$dataProvider = t3lib_div::makeInstance('t3lib_tree_pagetree_DataProvider');
+
+		try {
+			$newPageId = t3lib_tree_pagetree_Commands::copyNode($node, -$destination);
+			$newNode = t3lib_tree_pagetree_Commands::getNode($newPageId);
+			$newNode->setLeaf($node->isLeafNode());
+			$returnValue = $newNode->toArray();
+		} catch (Exception $exception) {
+			$returnValue = array(
+				 'success' => FALSE,
+				 'message' => $exception->getMessage(),
+			 );
+		}
+
+		return $returnValue;
+	}
+
+	/**
+	 * Inserts a new node as the first child node of the destination node and returns the created node.
+	 *
+	 * @param stdClass $parentNodeData
+	 * @param int $pageType
+	 * @return array
+	 */
+	public function insertNodeToFirstChildOfDestination($parentNodeData, $pageType) {
+		/** @var $parentNode t3lib_tree_pagetree_Node */
+		$parentNode = t3lib_div::makeInstance('t3lib_tree_pagetree_Node', (array) $parentNodeData);
+
+		try {
+			$newPageId = t3lib_tree_pagetree_Commands::createNode($parentNode, $parentNode->getId(), $pageType);
+			$returnValue = t3lib_tree_pagetree_Commands::getNode($newPageId)->toArray();
+		} catch (Exception $exception) {
+			$returnValue = array(
+				 'success' => FALSE,
+				 'message' => $exception->getMessage(),
+			 );
+		}
+
+		return $returnValue;
+	}
+
+	/**
+	 * Inserts a new node directly after the destination node and returns the created node.
+	 *
+	 * @param stdClass $parentNodeData
+	 * @param int $destination
+	 * @param int $pageType
+	 * @return array
+	 */
+	public function insertNodeAfterDestination($parentNodeData, $destination, $pageType) {
+		/** @var $parentNode t3lib_tree_pagetree_Node */
+		$parentNode = t3lib_div::makeInstance('t3lib_tree_pagetree_Node', (array) $parentNodeData);
+
+		try {
+			$newPageId = t3lib_tree_pagetree_Commands::createNode($parentNode, -$destination, $pageType);
+			$returnValue = t3lib_tree_pagetree_Commands::getNode($newPageId)->toArray();
+		} catch (Exception $exception) {
+			$returnValue = array(
+				 'success' => FALSE,
+				 'message' => $exception->getMessage(),
+			 );
+		}
+
+		return $returnValue;
+	}
+
+	/**
+	 * Returns the view link of a given node
+	 *
+	 * @param stdClass $nodeData
+	 * @return string
+	 */
+	public static function getViewLink($nodeData) {
+		/** @var $node t3lib_tree_pagetree_Node */
+		$node = t3lib_div::makeInstance('t3lib_tree_pagetree_Node', (array) $nodeData);
+
+		$javascriptLink = t3lib_BEfunc::viewOnClick($node->getId());
+		preg_match('/window\.open\(\'([^\']+)\'/i', $javascriptLink, $match);
+
+		return $match[1];
+	}
+}
+
+if (defined('TYPO3_MODE') && isset($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['t3lib/tree/pagetree/extdirect/class.t3lib_tree_pagetree_extdirect_commands.php'])) {
+	include_once($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['t3lib/tree/pagetree/extdirect/class.t3lib_tree_pagetree_extdirect_commands.php']);
+}
+
+?>
\ No newline at end of file
Index: t3lib/tree/pagetree/class.t3lib_tree_pagetree_indicator.php
===================================================================
--- t3lib/tree/pagetree/class.t3lib_tree_pagetree_indicator.php	(Revision 0)
+++ t3lib/tree/pagetree/class.t3lib_tree_pagetree_indicator.php	(Revision 0)
@@ -0,0 +1,92 @@
+<?php
+/***************************************************************
+ *  Copyright notice
+ *
+ *  (c) 2010 Susanne Moog <typo3@susanne-moog.de>
+ *  All rights reserved
+ *
+ *  This script is part of the TYPO3 project. The TYPO3 project is
+ *  free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  The GNU General Public License can be found at
+ *  http://www.gnu.org/copyleft/gpl.html.
+ *  A copy is found in the textfile GPL.txt and important notices to the license
+ *  from the author is found in LICENSE.txt distributed with these scripts.
+ *
+ *
+ *  This script is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  This copyright notice MUST APPEAR in all copies of the script!
+ ***************************************************************/
+
+/**
+ * Class for pagetree indicator
+ *
+ * @author Susanne Moog <typo3@susanne-moog.de>
+ * @package	TYPO3
+ * @subpackage t3lib
+ */
+class t3lib_tree_pagetree_Indicator {
+	/**
+	 * Indicator Providers
+	 *
+	 * @var array
+	 */
+	protected $indicatorProviders = array();
+
+	/**
+	 * Constructor for class tx_reports_report_Status
+	 */
+	public function __construct() {
+		$this->getIndicatorProviders();
+	}
+
+	/**
+	 * Gets all registered indicator providers and instantiates them
+	 *
+	 */
+	protected function getIndicatorProviders() {
+		$providers = $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['pagetree']['t3lib_tree_pagetree']['indicator']['providers'];
+		if (!is_array($providers)) {
+			return;
+		}
+
+		foreach ($providers as $indicatorProvider) {
+			/** @var $indicatorProviderInstance t3lib_tree_pagetree_interfaces_IndicatorProvider */
+			$indicatorProviderInstance = t3lib_div::makeInstance($indicatorProvider);
+			if ($indicatorProviderInstance instanceof t3lib_tree_pagetree_interfaces_IndicatorProvider) {
+				$this->indicatorProviders[] = $indicatorProviderInstance;
+			}
+		}
+	}
+
+	/**
+	 * Runs through all indicator providers and returns all indicators collected.
+	 *
+	 * @return	array	An array of
+	 */
+	public function getAllIndicators() {
+		$indicators = array();
+		foreach ($this->indicatorProviders as $indicatorProvider) {
+			$indicator = $indicatorProvider->getIndicator();
+			if($indicator) {
+				$indicators[] = $indicator;
+			}
+		}
+
+		return $indicators;
+	}
+}
+
+if (defined('TYPO3_MODE') && isset($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['t3lib/tree/pagetree/class.t3lib_tree_pagetree_indicator.php'])) {
+	include_once($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['t3lib/tree/pagetree/class.t3lib_tree_pagetree_indicator.php']);
+}
+
+
+?>
\ No newline at end of file
Index: t3lib/core_autoload.php
===================================================================
--- t3lib/core_autoload.php	(Revision 10092)
+++ t3lib/core_autoload.php	(Arbeitskopie)
@@ -193,6 +193,17 @@
 	't3lib_tree_tca_dataproviderfactory' => PATH_t3lib . 'tree/tca/class.t3lib_tree_tca_dataproviderfactory.php',
 	't3lib_tree_tca_tcatree' => PATH_t3lib . 'tree/tca/class.t3lib_tree_tca_tcatree.php',
 	'extdirect_dataprovider_backendusersettings' => PATH_t3lib . 'extjs/dataprovider/class.extdirect_dataprovider_beusersettings.php',
+	't3lib_tree_pagetree_extdirect_tree' => PATH_t3lib . 'tree/pagetree/extdirect/class.t3lib_tree_pagetree_extdirect_tree.php',
+	't3lib_tree_pagetree_extdirect_commands' => PATH_t3lib . 'tree/pagetree/extdirect/class.t3lib_tree_pagetree_extdirect_commands.php',
+	't3lib_contextmenu_pagetree_extdirect_contextmenu' => PATH_t3lib . 'contextmenu/pagetree/extdirect/class.t3lib_contextmenu_pagetree_extdirect_contextmenu.php',
+	't3lib_tree_pagetree_dataprovider' => PATH_t3lib . 'tree/pagetree/class.t3lib_tree_pagetree_dataprovider.php',
+	't3lib_tree_pagetree_node' => PATH_t3lib . 'tree/pagetree/class.t3lib_tree_pagetree_node.php',
+	't3lib_tree_extdirect_node' => PATH_t3lib . 'tree/extdirect/class.t3lib_tree_extdirect_node.php',
+	't3lib_tree_pagetree_nodecollection' => PATH_t3lib . 'tree/pagetree/class.t3lib_tree_pagetree_nodecollection.php',
+	't3lib_tree_pagetree_commands' => PATH_t3lib . 'tree/pagetree/class.t3lib_tree_pagetree_commands.php',
+	't3lib_contextmenu_pagetree_dataprovider' => PATH_t3lib . 'contextmenu/pagetree/class.t3lib_contextmenu_pagetree_dataprovider.php',
+	't3lib_tree_pagetree_indicator' => PATH_t3lib . 'tree/pagetree/class.t3lib_tree_pagetree_indicator.php',
+	't3lib_tree_pagetree_indicatorprovider' => PATH_t3lib . 'tree/pagetree/interfaces/interface.t3lib_tree_pagetree_interfaces_indicatorprovider.php',
 );
 
 $tslibClasses = require(PATH_typo3 . 'sysext/cms/ext_autoload.php');
Index: t3lib/contextmenu/class.t3lib_contextmenu_abstractdataprovider.php
===================================================================
--- t3lib/contextmenu/class.t3lib_contextmenu_abstractdataprovider.php	(Revision 10092)
+++ t3lib/contextmenu/class.t3lib_contextmenu_abstractdataprovider.php	(Arbeitskopie)
@@ -34,6 +34,13 @@
  */
 abstract class t3lib_contextmenu_AbstractDataProvider {
 	/**
+	 * List of actions that are generally disabled
+	 *
+	 * @var array
+	 */
+	protected $disableItems = array();
+
+	/**
 	 * Context Menu Type (e.g. table.pages, table.tt_content)
 	 *
 	 * @var string
@@ -79,6 +86,154 @@
 
 		return $contextMenuActions['properties'];
 	}
+
+	/**
+	 * Evaluates a given display condition and returns true if the condition matches
+	 *
+	 * Examples:
+	 * getContextInfo|inCutMode:1 || isInCopyMode:1
+	 * isLeafNode:1
+	 * isLeafNode:1 && isInCutMode:1
+	 *
+	 * @param t3lib_tree_Node $node
+	 * @param string $displayCondition
+	 * @return boolean
+	 */
+	protected function evaluateDisplayCondition(t3lib_tree_Node $node, $displayCondition) {
+		if ($displayCondition === '') {
+			return TRUE;
+		}
+
+			// parse condition string
+		$conditions = array();
+		preg_match_all('/(.+?)(>=|<=|!=|=|>|<)(.+?)(\|\||&&|$)/is', $displayCondition, $conditions);
+
+		$lastResult = FALSE;
+		$chainType = '';
+		$amountOfConditions = count($conditions[0]);
+		for ($i = 0; $i < $amountOfConditions; ++$i) {
+				// check method for existence
+			$method = trim($conditions[1][$i]);
+			list($method, $index) = explode('|', $method);
+			if (!method_exists($node, $method)) {
+				continue;
+			}
+
+				// fetch compare value
+			$returnValue = call_user_func(array($node, $method));
+			if (is_array($returnValue)) {
+				$returnValue = $returnValue[$index];
+			}
+
+				// compare fetched and expected values
+			$operator = trim($conditions[2][$i]);
+			$expected = trim($conditions[3][$i]);
+			if ($operator === '=') {
+				$returnValue = ($returnValue == $expected);
+			} elseif ($operator === '>') {
+				$returnValue = ($returnValue > $expected);
+			} elseif ($operator === '<') {
+				$returnValue = ($returnValue < $expected);
+			} elseif ($operator === '>=') {
+				$returnValue = ($returnValue >= $expected);
+			} elseif ($operator === '<=') {
+				$returnValue = ($returnValue <= $expected);
+			} elseif ($operator === '!=') {
+				$returnValue = ($returnValue != $expected);
+			} else {
+				$returnValue = FALSE;
+				$lastResult = FALSE;
+			}
+
+				// chain last result and the current if requested
+			if ($chainType === '||') {
+				$lastResult = ($lastResult || $returnValue);
+			} elseif ($chainType === '&&') {
+				$lastResult = ($lastResult && $returnValue);
+			} else {
+				$lastResult = $returnValue;
+			}
+
+				// save chain type for the next condition
+			$chainType = trim($conditions[4][$i]);
+		}
+
+		return $lastResult;
+	}
+
+	/**
+	 * Returns the next context menu level
+	 *
+	 * @param array $actions
+	 * @param t3lib_tree_Node $node
+	 * @param int $level
+	 * @return t3lib_contextmenu_ActionCollection
+	 */
+	protected function getNextContextMenuLevel(array $actions, t3lib_tree_Node $node, $level = 0) {
+		/** @var $actionCollection t3lib_contextmenu_ActionCollection */
+		$actionCollection = t3lib_div::makeInstance('t3lib_contextmenu_ActionCollection');
+
+		if ($level > 5) {
+			return $actionCollection;
+		}
+
+		$type = '';
+		foreach ($actions as $index => $actionConfiguration) {
+			if (substr($index, -1) !== '.') {
+				$type = $actionConfiguration;
+				if ($type !== 'DIVIDER') {
+					continue;
+				}
+			}
+
+			if (!in_array($type, array('DIVIDER', 'SUBMENU', 'ITEM'))) {
+				continue;
+			}
+
+			/** @var $action t3lib_contextmenu_Action */
+			$action = t3lib_div::makeInstance('t3lib_contextmenu_Action');
+			$action->setId($index);
+
+			if ($type === 'DIVIDER') {
+				$action->setType('divider');
+			} else {
+				if (in_array($actionConfiguration['name'], $this->disableItems)
+					|| (isset($actionConfiguration['displayCondition'])
+						&& trim($actionConfiguration['displayCondition']) !== ''
+						&& !$this->evaluateDisplayCondition($node, $actionConfiguration['displayCondition'])
+					)
+				) {
+					unset($action);
+					continue;
+				}
+
+				$label = $GLOBALS['LANG']->sL($actionConfiguration['label'], TRUE);
+				if ($type === 'SUBMENU') {
+					$action->setType('submenu');
+					$action->setChildActions(
+						$this->getNextContextMenuLevel($actionConfiguration, $node, $level + 1)
+					);
+				} else {
+					$action->setType('action');
+					$action->setCallbackAction($actionConfiguration['callbackAction']);
+				}
+
+				$action->setLabel($label);
+				if (isset($actionConfiguration['icon']) && trim($actionConfiguration['icon']) !== '') {
+					$action->setIcon($actionConfiguration['icon']);
+				} elseif (isset($actionConfiguration['spriteIcon'])) {
+					$action->setClass(
+						t3lib_iconWorks::getSpriteIconClasses($actionConfiguration['spriteIcon'])
+					);
+				}
+			}
+
+			$actionCollection->offsetSet($level . intval($index), $action);
+			$actionCollection->ksort();
+		}
+
+		return $actionCollection;
+	}
 }
 
 ?>
\ No newline at end of file
Index: t3lib/contextmenu/pagetree/class.t3lib_contextmenu_pagetree_dataprovider.php
===================================================================
--- t3lib/contextmenu/pagetree/class.t3lib_contextmenu_pagetree_dataprovider.php	(Revision 0)
+++ t3lib/contextmenu/pagetree/class.t3lib_contextmenu_pagetree_dataprovider.php	(Revision 0)
@@ -0,0 +1,110 @@
+<?php
+/***************************************************************
+ *  Copyright notice
+ *
+ *  (c) 2010 TYPO3 Tree Team <http://forge.typo3.org/projects/typo3v4-extjstrees>
+ *  All rights reserved
+ *
+ *  This script is part of the TYPO3 project. The TYPO3 project is
+ *  free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  The GNU General Public License can be found at
+ *  http://www.gnu.org/copyleft/gpl.html.
+ *  A copy is found in the textfile GPL.txt and important notices to the license
+ *  from the author is found in LICENSE.txt distributed with these scripts.
+ *
+ *
+ *  This script is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  This copyright notice MUST APPEAR in all copies of the script!
+ ***************************************************************/
+
+/**
+ * Context Menu Data Provider for the Page Tree
+ *
+ * @author Stefan Galinski <stefan.galinski@gmail.com>
+ * @package TYPO3
+ * @subpackage t3lib
+ */
+class t3lib_contextmenu_pagetree_DataProvider extends t3lib_contextmenu_AbstractDataProvider {
+	/**
+	 * Old Context Menu Options (access mapping)
+	 *
+	 * Note: Only option with different namings are mapped!
+	 *
+	 * @var array
+	 */
+	protected $legacyContextMenuMapping = array(
+		'hide' => 'disable',
+		'paste' => 'pasteInto,pasteAfter',
+		'mount_as_treeroot' => 'mountAsTreeroot',
+	);
+
+	/**
+	 * Fetches the items that should be disabled from the context menu
+	 *
+	 * @return array
+	 */
+	protected function getDisableActions() {
+		$tsConfig = $GLOBALS['BE_USER']->getTSConfig(
+			'options.contextMenu.' . $this->getContextMenuType() . '.disableItems'
+		);
+
+		$disableItems = array();
+		if (trim($tsConfig['value']) !== '') {
+			$disableItems = t3lib_div::trimExplode(',', $tsConfig['value']);
+		}
+
+		$tsConfig = $GLOBALS['BE_USER']->getTSConfig('options.contextMenu.pageTree.disableItems');
+		$oldDisableItems = array();
+		if (trim($tsConfig['value']) !== '') {
+			$oldDisableItems = t3lib_div::trimExplode(',', $tsConfig['value']);
+		}
+
+		$additionalItems = array();
+		foreach ($oldDisableItems as $item) {
+			if (!isset($this->legacyContextMenuMapping[$item])) {
+				$additionalItems[] = $item;
+				continue;
+			}
+
+			if (strpos($this->legacyContextMenuMapping[$item], ',')) {
+				$actions = t3lib_div::trimExplode(',', $this->legacyContextMenuMapping[$item]);
+				$additionalItems = array_merge($additionalItems, $actions);
+			} else {
+				$additionalItems[] = $item;
+			}
+		}
+
+		return array_merge($disableItems, $additionalItems);
+	}
+
+	/**
+	 * Returns the actions for the node
+	 *
+	 * @param t3lib_tree_pagetree_Node $node
+	 * @return t3lib_contextmenu_ActionCollection
+	 */
+	public function getActionsForNode(t3lib_tree_Node $node) {
+		$this->disableItems = $this->getDisableActions();
+		$configuration = $this->getConfiguration();
+		$contextMenuActions = array();
+		if (is_array($configuration)) {
+			$contextMenuActions = $this->getNextContextMenuLevel($configuration, $node);
+		}
+
+		return $contextMenuActions;
+	}
+}
+
+if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['t3lib/contextmenu/pagetree/class.t3lib_contextmenu_pagetree_dataprovider.php']) {
+	include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['t3lib/contextmenu/pagetree/class.t3lib_contextmenu_pagetree_dataprovider.php']);
+}
+
+?>
\ No newline at end of file
Index: t3lib/contextmenu/pagetree/extdirect/class.t3lib_contextmenu_pagetree_extdirect_contextmenu.php
===================================================================
--- t3lib/contextmenu/pagetree/extdirect/class.t3lib_contextmenu_pagetree_extdirect_contextmenu.php	(Revision 0)
+++ t3lib/contextmenu/pagetree/extdirect/class.t3lib_contextmenu_pagetree_extdirect_contextmenu.php	(Revision 0)
@@ -0,0 +1,75 @@
+<?php
+/***************************************************************
+ *  Copyright notice
+ *
+ *  (c) 2010 TYPO3 Tree Team <http://forge.typo3.org/projects/typo3v4-extjstrees>
+ *  All rights reserved
+ *
+ *  This script is part of the TYPO3 project. The TYPO3 project is
+ *  free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2 of the License, or
+ *  (at your option) any later version.
+ *
+ *  The GNU General Public License can be found at
+ *  http://www.gnu.org/copyleft/gpl.html.
+ *  A copy is found in the textfile GPL.txt and important notices to the license
+ *  from the author is found in LICENSE.txt distributed with these scripts.
+ *
+ *
+ *  This script is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  This copyright notice MUST APPEAR in all copies of the script!
+ ***************************************************************/
+
+/**
+ * Context Menu of the Page Tree
+ *
+ * @author Stefan Galinski <stefan.galinski@gmail.com>
+ * @package TYPO3
+ * @subpackage t3lib
+ */
+class t3lib_contextmenu_pagetree_extdirect_ContextMenu extends t3lib_contextmenu_extdirect_ContextMenu {
+	/**
+	 * Sets the data provider
+	 *
+	 * @return void
+	 */
+	protected function initDataProvider() {
+		/** @var $dataProvider t3lib_contextmenu_pagetree_DataProvider */
+		$dataProvider = t3lib_div::makeInstance('t3lib_contextmenu_pagetree_DataProvider');
+		$this->setDataProvider($dataProvider);
+	}
+
+	/**
+	 * Returns the actions for the given node information's
+	 *
+	 * @param stdClass $node
+	 * @return array
+	 */
+	public function getActionsForNodeArray($nodeData) {
+		/** @var $node t3lib_tree_pagetree_Node */
+		$node = t3lib_div::makeInstance('t3lib_tree_pagetree_Node', (array) $nodeData);
+		$node->setRecord(t3lib_tree_pagetree_Commands::getNodeRecord($node->getId()));
+
+		$this->initDataProvider();
+		$this->dataProvider->setContextMenuType('table.' . $node->getType());
+		$actionCollection = $this->dataProvider->getActionsForNode($node);
+
+		if ($actionCollection instanceof t3lib_contextmenu_ActionCollection) {
+			$actions = $actionCollection->toArray();
+		}
+
+		return $actions;
+	}
+}
+
+
+if (defined('TYPO3_MODE') && isset($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['t3lib/contextmenu/pagetree/extdirect/class.t3lib_contextmenu_pagetree_extdirect_contextmenu.php'])) {
+	include_once($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['t3lib/contextmenu/pagetree/extdirect/class.t3lib_contextmenu_pagetree_extdirect_contextmenu.php']);
+}
+
+?>
\ No newline at end of file
Index: typo3/backend.php
===================================================================
--- typo3/backend.php	(Revision 10092)
+++ typo3/backend.php	(Arbeitskopie)
@@ -144,6 +144,7 @@
 			'viewport'              => 'js/extjs/viewport.js',
 			'iframepanel'           => 'js/extjs/iframepanel.js',
 			'viewportConfiguration' => 'js/extjs/viewportConfiguration.js',
+			'util'					=> '../t3lib/js/extjs/util.js',
 		);
 
 		if ($this->debug) {
Index: typo3/sysext/impexp/ext_tables.php
===================================================================
--- typo3/sysext/impexp/ext_tables.php	(Revision 10092)
+++ typo3/sysext/impexp/ext_tables.php	(Arbeitskopie)
@@ -21,6 +21,38 @@
 	// CSH labels for TYPO3 4.5 and greater.  These labels override the ones set above, while still falling back to the original labels if no translation is available.
 	$GLOBALS['TYPO3_CONF_VARS']['SYS']['locallangXMLOverride']['EXT:impexp/locallang_csh.xml'][] = 'EXT:impexp/locallang_csh_45.xml';
 
+		// special context menu actions for the import/export module
+	$importExportActions = '
+		9000 = DIVIDER
 
+		9100 = ITEM
+		9100 {
+			name = exportT3d
+			label = LLL:EXT:impexp/app/locallang.xml:export
+			spriteIcon = actions-document-export-t3d
+			callbackAction = exportT3d
+		}
+
+		9200 = ITEM
+		9200 {
+			name = importT3d
+			label = LLL:EXT:impexp/app/locallang.xml:import
+			spriteIcon = actions-document-import-t3d
+			callbackAction = importT3d
+		}
+	';
+
+		// context menu user default configuration
+	$GLOBALS['TYPO3_CONF_VARS']['BE']['defaultUserTSconfig'] .= '
+		options.contextMenu.table {
+			pages_root.items {
+				' . $importExportActions . '
+			}
+
+			pages.items.1000 {
+				' . $importExportActions . '
+			}
+		}
+	';
 }
 ?>
\ No newline at end of file
