diff --git a/t3lib/core_autoload.php b/t3lib/core_autoload.php
index 4b4488744681175b7a3a264365418ad11f2aba7b..883285c15a2fac7cd1d5c1bb700c6b46c6cd8c7c 100644
--- a/t3lib/core_autoload.php
+++ b/t3lib/core_autoload.php
@@ -196,16 +196,15 @@ $t3libClasses = array(
 	't3lib_tree_abstractdataprovider' => PATH_t3lib . 'tree/class.t3lib_tree_abstractdataprovider.php',
 	't3lib_tree_abstractstateprovider' => PATH_t3lib . 'tree/class.t3lib_tree_abstractstateprovider.php',
 	't3lib_tree_node' => PATH_t3lib . 'tree/class.t3lib_tree_node.php',
-	't3lib_tree_representationnode' => PATH_t3lib . 'tree/class.t3lib_tree_representationnode.php',
 	't3lib_tree_nodecollection' => PATH_t3lib . 'tree/class.t3lib_tree_nodecollection.php',
 	't3lib_tree_sortednodecollection' => PATH_t3lib . 'tree/class.t3lib_tree_sortednodecollection.php',
-	't3lib_tree_extdirect_abstractextjstree' => PATH_t3lib . 'tree/extdirect/class.t3lib_tree_extdirect_abstractextjstree.php',
-	't3lib_tree_comparablenode' => PATH_t3lib . 'interfaces/tree/interface.t3lib_tree_comparablenode.php',
-	't3lib_tree_draggableanddropable' => PATH_t3lib . 'interfaces/tree/interface.t3lib_tree_draggableanddropable.php',
-	't3lib_tree_labeleditable' => PATH_t3lib . 'interfaces/tree/interface.t3lib_tree_labeleditable.php',
-	't3lib_tree_renderer_abstract' => PATH_t3lib . 'tree/renderer/class.t3lib_tree_renderer_abstract.php',
-	't3lib_tree_renderer_unorderedlist' => PATH_t3lib . 'tree/renderer/class.t3lib_tree_renderer_unorderedlist.php',
-	't3lib_tree_renderer_extjsjson' => PATH_t3lib . 'tree/renderer/class.t3lib_tree_renderer_extjsjson.php',
+	't3lib_tree_extjs_abstractextjstree' => PATH_t3lib . 'tree/extjs/class.t3lib_tree_extjs_abstractextjstree.php',
+	't3lib_tree_extjs_abstractstatefulextjstree' => PATH_t3lib . 'tree/extjs/class.t3lib_tree_extjs_abstractstatefulextjstree.php',
+	't3lib_tree_comparablenode' => PATH_t3lib . 'tree/interfaces/interface.t3lib_tree_comparablenode.php',
+	't3lib_tree_renderablenode' => PATH_t3lib . 'tree/interfaces/interface.t3lib_tree_renderablenode.php',
+	't3lib_tree_draggableanddropable' => PATH_t3lib . 'tree/interfaces/interface.t3lib_tree_draggableanddropable.php',
+	't3lib_tree_labeleditable' => PATH_t3lib . 'tree/interfaces/interface.t3lib_tree_labeleditable.php',
+	't3lib_tree_recordbasednode' => PATH_t3lib . 'tree/interfaces/interface.t3lib_tree_recordbasednode.php',
 	't3lib_contextmenu_abstractcontextmenu' => PATH_t3lib . 'contextmenu/class.t3lib_contextmenu_abstractcontextmenu.php',
 	't3lib_contextmenu_abstractdataprovider' => PATH_t3lib . 'contextmenu/class.t3lib_contextmenu_abstractdataprovider.php',
 	't3lib_contextmenu_action' => PATH_t3lib . 'contextmenu/class.t3lib_contextmenu_action.php',
@@ -225,7 +224,8 @@ $t3libClasses = array(
 	'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_extjs_node' => PATH_t3lib . 'tree/extjs/class.t3lib_tree_extjs_node.php',
+	't3lib_tree_navigationtree_node' => PATH_t3lib . 'tree/navigationtree/class.t3lib_tree_navigationtree_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',
@@ -238,4 +238,4 @@ $t3libClasses = array(
 $tslibClasses = require(PATH_typo3 . 'sysext/cms/ext_autoload.php');
 
 return array_merge($t3libClasses, $tslibClasses);
-?>
\ No newline at end of file
+?>
diff --git a/t3lib/js/extjs/components/pagetree/javascript/Ext.ux.state.TreePanel.js b/t3lib/js/extjs/components/pagetree/javascript/Ext.ux.state.TreePanel.js
index 348d94cb900ae39cf8189e959c2ffba88c761b13..a781831f2d4b3b2ba5b26e5e98e7d9a70a0eb4c9 100644
--- a/t3lib/js/extjs/components/pagetree/javascript/Ext.ux.state.TreePanel.js
+++ b/t3lib/js/extjs/components/pagetree/javascript/Ext.ux.state.TreePanel.js
@@ -23,126 +23,117 @@
 *
 *  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, {
+Ext.define('Ext.ux.state.TreePanel', {
+	extend: 'Ext.state.Stateful',
+
 	/**
-	 * Initializes the plugin
-	 * @param {Ext.tree.TreePanel} tree
-	 * @private
+	 * Mixin constructor
+	 * @param {Object} config
+	 *
 	 */
-	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;
-				}
-				var saveID = n.id;
-				this.stateHash[saveID.substr(1)] = 1;
-			},
-
-			// delete path and all subpaths of collapsed node from stateHash
-			beforecollapsenode:function(n) {
-				if (this.isRestoringState) {
-					return;
-				}
-
-				var deleteID = n.id;
-				delete this.stateHash[deleteID.substr(1)];
-			},
-
-			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;
-					// get last selected node
-				for (var pageID in this.stateHash) {
-					var pageNode = this.getNodeById('p' + pageID);
-					if (pageNode) {
-						pageNode.on({
-							expand: {
-								single:true,
-								scope:this,
-								fn: this.restoreState
+	constructor: function (config) {
+		if (config.stateful) {
+				// Install event handlers on TreePanel
+			this.on({
+					// Add path of expanded node to stateHash
+				beforeitemexpand: function (node) {
+						if (this.isRestoringState) {
+							return;
+						}
+						this.stateHash[String(node.getNodeData('id'))] = node.getId();
+					},
+					// Delete collapsed node from stateHash
+				beforeitemcollapse: function (node) {
+						if (this.isRestoringState) {
+							return;
+						}
+						delete this.stateHash[String(node.getNodeData('id'))];
+					},
+					// Update last selected node in stateHash
+				selectionchange: function (view, node) {
+					this.onStateChange();
+						if (this.isRestoringState) {
+							return;
+						}
+						if (this.getSelectionModel().getLastSelected()) {
+							this.stateHash['lastSelectedNode'] = this.getSelectionModel().getLastSelected().getId();
+						}
+					},
+				scope: this
+			});
+				// Add/override state properties
+			Ext.apply(this, {
+					// Update state on node expand, collapse or selection change
+				stateEvents: ['itemexpand', 'itemcollapse', 'selectionchange'],
+					// Avoid updating state while restoring
+				isRestoringState: false,
+					// State object
+				stateHash: {},
+				/**
+				 * Restore tree state into the saved state
+				 *
+				 */
+				restoreState: function() {
+					if (this.stateful) {
+						this.isRestoringState = true;
+							// Expand paths according to stateHash
+						for (var pageID in this.stateHash) {
+							var pageNode = this.getStore().getNodeById(this.stateHash[pageID]);
+							if (pageNode && !pageNode.isLeaf() && !pageNode.isExpanded()) {
+								pageNode.on({
+									expand: {
+										single: true,
+										scope: this,
+										fn: this.restoreState
+									}
+								});
+								pageNode.set('expanded', true);
+								pageNode.commit();
+								this.refreshNode(pageNode);
+								pageNode.fireEvent('expand', pageNode);
 							}
-						});
-						if (pageNode.expanded === false && pageNode.rendered == true) {
-							pageNode.expand();
 						}
-					}
-				}
-				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.app.isVisible() &&
-							this.commandProvider && this.commandProvider.singleClick
-						) {
-							this.commandProvider.singleClick(node, this);
+							// Get last selected node
+						if (this.stateHash['lastSelectedNode']) {
+							var node = this.getStore().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.getNodeData('id')) === contentId ||
+									contentId.indexOf('pages' + node.getNodeData('id')) !== -1
+								);
+				
+								if (contentId !== '-1' 
+									&& !isCurrentSelectedNode
+									&& this == this.app.getTree()
+									&& this.commandProvider
+									&& this.commandProvider.singleClick
+								) {
+									this.commandProvider.singleClick(node, this);
+								}
+							}
 						}
+						this.isRestoringState = false;
 					}
+				},
+				/**
+				 * Return stateHash for save by state manager
+				 *
+				 */
+				getState: function() {
+					return {
+						stateHash: this.stateHash
+					};
 				}
-
-				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};
-			}
-		});
+			});
+			this.callParent(arguments);
+		}
 	}
 });
diff --git a/t3lib/js/extjs/components/pagetree/javascript/actions.js b/t3lib/js/extjs/components/pagetree/javascript/actions.js
index 1dbb5b03ea961297f5a5429a5781da9b40952087..3b4947450931cc03383d79b235882c1ed85e7069 100644
--- a/t3lib/js/extjs/components/pagetree/javascript/actions.js
+++ b/t3lib/js/extjs/components/pagetree/javascript/actions.js
@@ -61,8 +61,8 @@ TYPO3.Components.PageTree.Actions = {
 		tree.t3ContextInfo.inCopyMode = false;
 
 		if (tree.t3ContextNode) {
-			tree.t3ContextNode.attributes.nodeData.t3InCutMode = false;
-			tree.t3ContextNode.attributes.nodeData.t3InCopyMode = false;
+			tree.t3ContextNode.setNodeData('t3InCutMode', false);
+			tree.t3ContextNode.setNodeData('t3InCopyMode', false);
 			tree.t3ContextNode = null;
 		}
 	},
@@ -71,51 +71,55 @@ TYPO3.Components.PageTree.Actions = {
 	 * Updates an existing node with the given alternative. The new tree node
 	 * is returned afterwards.
 	 *
-	 * @param {Ext.tree.TreeNode} node
+	 * @param {TYPO3.Components.PageTree.Tree} tree
+	 * @param {TYPO3.Components.PageTree.Model} node
 	 * @param {Boolean} isExpanded
 	 * @param {Object} updatedNode
 	 * @param {Function} callback
-	 * @return {Ext.tree.TreeNode}
+	 * @return {Ext.data.NodeInterface}
 	 */
-	updateNode: function(node, isExpanded, updatedNode, callback) {
+	updateNode: function(tree, node, isExpanded, updatedNode, callback) {
 		if (!updatedNode) {
 			return null;
 		}
 
-		updatedNode.uiProvider = node.ownerTree.uiProvider;
-		var newTreeNode = new Ext.tree.TreeNode(updatedNode);
+		var newTreeNode = Ext.create('TYPO3.Components.PageTree.Model', updatedNode);
 
 		var refreshCallback = this.restoreNodeStateAfterRefresh;
 		if (callback) {
-			refreshCallback = refreshCallback.createSequence(callback);
+			refreshCallback = Ext.Function.createSequence(refreshCallback, callback);
 		}
 
 		node.parentNode.replaceChild(newTreeNode, node);
-		newTreeNode.ownerTree.refreshNode(newTreeNode, refreshCallback);
-
+		newTreeNode.set('expanded', isExpanded);
+		tree.refreshNode(newTreeNode, refreshCallback, tree);
 		return newTreeNode;
 	},
 
 	/**
 	 * Restores the node state
 	 *
-	 * @param {Ext.tree.TreeNode} node
+	 * @param {TYPO3.Components.PageTree.Tree} tree
+	 * @param {TYPO3.Components.PageTree.Model} node
 	 * @param {Boolean} isExpanded
 	 * @return {void}
 	 */
-	restoreNodeStateAfterRefresh: function(node, isExpanded) {
-		node.parentNode.expand(false, false);
-		if (isExpanded) {
-			node.expand(false, false);
-		} else {
-			node.collapse(false, false);
+	restoreNodeStateAfterRefresh: function (records, operation, successful) {
+		if (successful && operation.node) {
+			var node = operation.node;
+			node.parentNode.expand(false);
+			if (node.isExpanded()) {
+				node.expand(false);
+			} else {
+				node.collapse(false);
+			}
 		}
 	},
 
 	/**
 	 * Shows deletion confirmation window
 	 *
-	 * @param {Ext.tree.TreeNode} node
+	 * @param {TYPO3.Components.PageTree.Model} node
 	 * @param {TYPO3.Components.PageTree.Tree} tree
 	 * @param {Function} callback
 	 * @param {Boolean} recursiveDelete
@@ -130,10 +134,10 @@ TYPO3.Components.PageTree.Actions = {
 			message = TYPO3.Components.PageTree.LLL.recursiveDeleteDialogMessage;
 		}
 
-		Ext.Msg.show({
+		Ext.MessageBox.show({
 			title: title,
 			msg: message,
-			buttons: Ext.Msg.YESNO,
+			buttons: Ext.MessageBox.YESNO,
 			fn: function (answer) {
 				if (answer === 'yes') {
 					TYPO3.Components.PageTree.Actions.deleteNode(node, tree, callback);
@@ -141,21 +145,21 @@ TYPO3.Components.PageTree.Actions = {
 				}
 				return false;
 			},
-			animEl: 'elId'
+			animateTarget: tree.getView().getNode(node).id
 		});
 	},
 
 	/**
 	 * Deletes a node directly
 	 *
-	 * @param {Ext.tree.TreeNode} node
+	 * @param {TYPO3.Components.PageTree.Model} node
 	 * @param {TYPO3.Components.PageTree.Tree} tree
 	 * @param {Function} callback
 	 * @return {void}
 	 */
 	deleteNode: function(node, tree, callback) {
 		TYPO3.Components.PageTree.Commands.deleteNode(
-			node.attributes.nodeData,
+			node.get('nodeData'),
 			function(response) {
 				var succeeded = this.evaluateResponse(response);
 				if (Ext.isFunction(callback)) {
@@ -165,7 +169,7 @@ TYPO3.Components.PageTree.Actions = {
 				if (succeeded) {
 						// the node may not be removed in workspace mode
 					if (top.TYPO3.configuration.inWorkspace && response.id) {
-						this.updateNode(node, node.isExpanded(), response);
+						this.updateNode(tree, node, node.isExpanded(), response);
 					} else {
 						node.remove();
 					}
@@ -178,13 +182,13 @@ TYPO3.Components.PageTree.Actions = {
 	/**
 	 * Removes a node either directly or first shows deletion popup
 	 *
-	 * @param {Ext.tree.TreeNode} node
+	 * @param {TYPO3.Components.PageTree.Model} node
 	 * @param {TYPO3.Components.PageTree.Tree} tree
 	 * @return {void}
 	 */
 	removeNode: function(node, tree) {
 		if (TYPO3.Components.PageTree.Configuration.displayDeleteConfirmation) {
-			this.confirmDelete(node);
+			this.confirmDelete(node, tree);
 		} else {
 			this.deleteNode(node, tree);
 		}
@@ -194,19 +198,19 @@ TYPO3.Components.PageTree.Actions = {
 	 * 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 {Ext.data.NodeInterface} node
 	 * @param {TYPO3.Components.PageTree.Tree} tree
-	 * @param {Ext.tree.TreeNode} destination
+	 * @param {Ext.data.NodeInterface} destination
 	 * @return {void}
 	 */
 	restoreNodeToFirstChildOfDestination: function(node, tree, destination) {
 		TYPO3.Components.PageTree.Commands.restoreNode(
-			node.attributes.nodeData,
-			destination.attributes.nodeData.id,
-			function(updatedNode) {
+			node.get('nodeData'),
+			destination.get('nodeData').id,
+			function (updatedNode) {
 				if (this.evaluateResponse(updatedNode)) {
-					var newTreeNode = new Ext.tree.TreeNode(
-						Ext.apply(node.attributes, updatedNode)
+					var newTreeNode = Ext.create('TYPO3.Components.PageTree.Model',
+						Ext.apply(node.fields, updatedNode)
 					);
 					destination.insertBefore(newTreeNode, destination.firstChild);
 				}
@@ -219,19 +223,19 @@ TYPO3.Components.PageTree.Actions = {
 	 * 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.Model} node
 	 * @param {TYPO3.Components.PageTree.Tree} tree
-	 * @param {Ext.tree.TreeNode} destination
+	 * @param {TYPO3.Components.PageTree.Model} destination
 	 * @return {void}
 	 */
 	restoreNodeAfterDestination: function(node, tree, destination) {
 		TYPO3.Components.PageTree.Commands.restoreNode(
-			node.attributes.nodeData,
-			-destination.attributes.nodeData.id,
-			function(updatedNode) {
+			node.get('nodeData'),
+			-destination.get('nodeData').id,
+			function (updatedNode) {
 				if (this.evaluateResponse(updatedNode)) {
-					var newTreeNode = new Ext.tree.TreeNode(
-						Ext.apply(node.attributes, updatedNode)
+					var newTreeNode = Ext.create('TYPO3.Components.PageTree.Model',
+						Ext.apply(node.fields, updatedNode)
 					);
 					destination.parentNode.insertBefore(newTreeNode, destination.nextSibling);
 				}
@@ -243,7 +247,7 @@ TYPO3.Components.PageTree.Actions = {
 	/**
 	 * Collapses a whole tree branch
 	 *
-	 * @param {Ext.tree.TreeNode} node
+	 * @param {TYPO3.Components.PageTree.Model} node
 	 * @return {void}
 	 */
 	collapseBranch: function(node) {
@@ -253,7 +257,7 @@ TYPO3.Components.PageTree.Actions = {
 	/**
 	 * Expands a whole tree branch
 	 *
-	 * @param {Ext.tree.TreeNode} node
+	 * @param {TYPO3.Components.PageTree.Model} node
 	 * @return {void}
 	 */
 	expandBranch: function(node) {
@@ -263,13 +267,13 @@ TYPO3.Components.PageTree.Actions = {
 	/**
 	 * Opens a popup windows for previewing the given node/page
 	 *
-	 * @param {Ext.tree.TreeNode} node
+	 * @param {TYPO3.Components.PageTree.Model} node
 	 * @return {void}
 	 */
 	viewPage: function(node) {
 		var frontendWindow = window.open('', 'newTYPO3frontendWindow');
 		TYPO3.Components.PageTree.Commands.getViewLink(
-			node.attributes.nodeData,
+			node.get('nodeData'),
 			function(result) {
 				frontendWindow.location = result;
 				frontendWindow.focus();
@@ -280,13 +284,13 @@ TYPO3.Components.PageTree.Actions = {
 	/**
 	 * Creates a temporary tree mount point
 	 *
-	 * @param {Ext.tree.TreeNode} node
+	 * @param {TYPO3.Components.PageTree.Model} node
 	 * @param {TYPO3.Components.PageTree.Tree} tree
 	 * @return {void}
 	 */
 	mountAsTreeRoot: function(node, tree) {
 		TYPO3.Components.PageTree.Commands.setTemporaryMountPoint(
-			node.attributes.nodeData,
+			node.get('nodeData'),
 			function(response) {
 				if (TYPO3.Components.PageTree.Configuration.temporaryMountPoint) {
 					TYPO3.Backend.NavigationContainer.PageTree.removeIndicator(
@@ -297,19 +301,18 @@ TYPO3.Components.PageTree.Actions = {
 				TYPO3.Components.PageTree.Configuration.temporaryMountPoint = response;
 				TYPO3.Backend.NavigationContainer.PageTree.addTemporaryMountPointIndicator();
 
-				var selectedNode = TYPO3.Backend.NavigationContainer.PageTree.getSelected();
+				var selectedNode = tree.getSelectionModel().getLastSelected();
 				tree.stateId = 'Pagetree' + TYPO3.Components.PageTree.Configuration.temporaryMountPoint;
-				tree.refreshTree(function() {
-					var nodeIsSelected = false;
+					// Refresh tree and restore last selection if under the temporary mount
+				tree.refreshTree(function () {
+					var selectionModel = tree.getSelectionModel();
 					if (selectedNode) {
-						nodeIsSelected = TYPO3.Backend.NavigationContainer.PageTree.select(
-							selectedNode.attributes.nodeData.id
-						);
+						selectionModel.deselect(selectedNode);
+						selectionModel.select(selectedNode);
 					}
-
-					var node = (nodeIsSelected ? TYPO3.Backend.NavigationContainer.PageTree.getSelected() : null);
-					if (node) {
-						this.singleClick(node, tree);
+					selectedNode = selectionModel.getLastSelected();
+					if (selectedNode) {
+						this.singleClick(selectedNode, tree);
 					} else {
 						this.singleClick(tree.getRootNode().firstChild, tree);
 					}
@@ -322,63 +325,67 @@ TYPO3.Components.PageTree.Actions = {
 	/**
 	 * Opens the edit page properties dialog
 	 *
-	 * @param {Ext.tree.TreeNode} node
+	 * @param {TYPO3.Components.PageTree.Model} node
+	 * @param {TYPO3.Components.PageTree.Tree} tree
 	 * @return {void}
 	 */
-	editPageProperties: function(node) {
-		node.select();
+	editPageProperties: function(node, tree) {
+		tree.getSelectionModel().select(node);
 		TYPO3.Backend.ContentContainer.setUrl(
-			'alt_doc.php?edit[pages][' + node.attributes.nodeData.id + ']=edit'
+			'alt_doc.php?edit[pages][' + node.getNodeData('id') + ']=edit'
 		);
 	},
 
 	/**
 	 * Opens the new page wizard
 	 *
-	 * @param {Ext.tree.TreeNode} node
+	 * @param {TYPO3.Components.PageTree.Model} node
+	 * @param {TYPO3.Components.PageTree.Tree} tree
 	 * @return {void}
 	 */
-	newPageWizard: function(node) {
-		node.select();
+	newPageWizard: function(node, tree) {
+		tree.getSelectionModel().select(node);
 		TYPO3.Backend.ContentContainer.setUrl(
-			'db_new.php?id=' + node.attributes.nodeData.id + '&pagesOnly=1'
+			'db_new.php?id=' + node.getNodeData('id') + '&pagesOnly=1'
 		);
 	},
 
 	/**
 	 * Opens the info popup
 	 *
-	 * @param {Ext.tree.TreeNode} node
+	 * @param {TYPO3.Components.PageTree.Model} node
 	 * @return {void}
 	 */
 	openInfoPopUp: function(node) {
-		launchView('pages', node.attributes.nodeData.id);
+		launchView('pages', node.getNodeData('id'));
 	},
 
 	/**
 	 * Opens the history popup
 	 *
-	 * @param {Ext.tree.TreeNode} node
+	 * @param {TYPO3.Components.PageTree.Model} node
+	 * @param {TYPO3.Components.PageTree.Tree} tree	 
 	 * @return {void}
 	 */
-	openHistoryPopUp: function(node) {
-		node.select();
+	openHistoryPopUp: function(node, tree) {
+		tree.getSelectionModel().select(node);
 		TYPO3.Backend.ContentContainer.setUrl(
-			'show_rechis.php?element=pages:' + node.attributes.nodeData.id
+			'show_rechis.php?element=pages:' + node.getNodeData('id')
 		);
 	},
 
 	/**
 	 * Opens the export .t3d file dialog
 	 *
-	 * @param {Ext.tree.TreeNode} node
+	 * @param {TYPO3.Components.PageTree.Model} node
+	 * @param {TYPO3.Components.PageTree.Tree} tree
 	 * @return {void}
 	 */
-	exportT3d: function(node) {
-		node.select();
+	exportT3d: function(node, tree) {
+		tree.getSelectionModel().select(node);
 		TYPO3.Backend.ContentContainer.setUrl(
 			'sysext/impexp/app/index.php?tx_impexp[action]=export&' +
-				'id=0&tx_impexp[pagetree][id]=' + node.attributes.nodeData.id +
+				'id=0&tx_impexp[pagetree][id]=' + node.getNodeData('id') +
 				'&tx_impexp[pagetree][levels]=0' +
 				'&tx_impexp[pagetree][tables][]=_ALL'
 		);
@@ -387,13 +394,14 @@ TYPO3.Components.PageTree.Actions = {
 	/**
 	 * Opens the import .t3d file dialog
 	 *
-	 * @param {Ext.tree.TreeNode} node
+	 * @param {TYPO3.Components.PageTree.Model} node
+	 * @param {TYPO3.Components.PageTree.Tree} tree 
 	 * @return {void}
 	 */
-	importT3d: function(node) {
-		node.select();
+	importT3d: function(node, tree) {
+		tree.getSelectionModel().select(node);
 		TYPO3.Backend.ContentContainer.setUrl(
-			'sysext/impexp/app/index.php?id=' + node.attributes.nodeData.id +
+			'sysext/impexp/app/index.php?id=' + node.getNodeData('id') +
 				'&table=pages&tx_impexp[action]=import'
 		);
 	},
@@ -401,13 +409,13 @@ TYPO3.Components.PageTree.Actions = {
 	/**
 	 * Enables the cut mode of a node
 	 *
-	 * @param {Ext.tree.TreeNode} node
+	 * @param {TYPO3.Components.PageTree.Model} node
 	 * @param {TYPO3.Components.PageTree.Tree} tree
 	 * @return {void}
 	 */
 	enableCutMode: function(node, tree) {
 		this.disableCopyMode(node, tree);
-		node.attributes.nodeData.t3InCutMode = true;
+		node.setNodeData('t3InCutMode', true);
 		tree.t3ContextInfo.inCutMode = true;
 		tree.t3ContextNode = node;
 	},
@@ -415,25 +423,25 @@ TYPO3.Components.PageTree.Actions = {
 	/**
 	 * Disables the cut mode of a node
 	 *
-	 * @param {Ext.tree.TreeNode} node
+	 * @param {TYPO3.Components.PageTree.Model} node
 	 * @param {TYPO3.Components.PageTree.Tree} tree
 	 * @return {void}
 	 */
 	disableCutMode: function(node, tree) {
 		this.releaseCutAndCopyModes(tree);
-		node.attributes.nodeData.t3InCutMode = false;
+		node.setNodeData('t3InCutMode', false);
 	},
 
 	/**
 	 * Enables the copy mode of a node
 	 *
-	 * @param {Ext.tree.TreeNode} node
+	 * @param {TYPO3.Components.PageTree.Model} node
 	 * @param {TYPO3.Components.PageTree.Tree} tree
 	 * @return {void}
 	 */
 	enableCopyMode: function(node, tree) {
 		this.disableCutMode(node, tree);
-		node.attributes.nodeData.t3InCopyMode = true;
+		node.setNodeData('t3InCopyMode', true);
 		tree.t3ContextInfo.inCopyMode = true;
 		tree.t3ContextNode = node;
 	},
@@ -441,19 +449,19 @@ TYPO3.Components.PageTree.Actions = {
 	/**
 	 * Disables the copy mode of a node
 	 *
-	 * @param {Ext.tree.TreeNode} node
+	 * @param {TYPO3.Components.PageTree.Model} node
 	 * @param {TYPO3.Components.PageTree.Tree} tree
 	 * @return {void}
 	 */
 	disableCopyMode: function(node, tree) {
 		this.releaseCutAndCopyModes(tree);
-		node.attributes.nodeData.t3InCopyMode = false;
+		node.setNodeData('t3InCopyMode', false);
 	},
 
 	/**
 	 * Pastes the cut/copy context node into the given node
 	 *
-	 * @param {Ext.tree.TreeNode} node
+	 * @param {TYPO3.Components.PageTree.Model} node
 	 * @param {TYPO3.Components.PageTree.Tree} tree
 	 * @return {void}
 	 */
@@ -463,10 +471,10 @@ TYPO3.Components.PageTree.Actions = {
 		}
 
 		if (tree.t3ContextInfo.inCopyMode) {
-			var newNode = tree.t3ContextNode = new Ext.tree.TreeNode(tree.t3ContextNode.attributes);
+			var newNode = tree.t3ContextNode = Ext.create('TYPO3.Components.PageTree.Model', tree.t3ContextNode.fields);
 			newNode.id = 'fakeNode';
 			node.insertBefore(newNode, node.childNodes[0]);
-			node.attributes.nodeData.t3InCopyMode = false;
+			node.setNodeData('t3InCopyMode', false);
 			this.copyNodeToFirstChildOfDestination(newNode, tree);
 
 		} else if (tree.t3ContextInfo.inCutMode) {
@@ -475,7 +483,7 @@ TYPO3.Components.PageTree.Actions = {
 			}
 
 			node.appendChild(tree.t3ContextNode);
-			node.attributes.nodeData.t3InCutMode = false;
+			node.setNodeData('t3InCutMode', false);
 			this.moveNodeToFirstChildOfDestination(node, tree);
 		}
 	},
@@ -483,7 +491,7 @@ TYPO3.Components.PageTree.Actions = {
 	/**
 	 * Pastes a cut/copy context node after the given node
 	 *
-	 * @param {Ext.tree.TreeNode} node
+	 * @param {TYPO3.Components.PageTree.Model} node
 	 * @param {TYPO3.Components.PageTree.Tree} tree
 	 * @return {void}
 	 */
@@ -493,19 +501,18 @@ TYPO3.Components.PageTree.Actions = {
 		}
 
 		if (tree.t3ContextInfo.inCopyMode) {
-			var newNode = tree.t3ContextNode = new Ext.tree.TreeNode(tree.t3ContextNode.attributes);
+			var newNode = tree.t3ContextNode = Ext.create('TYPO3.Components.PageTree.Model', tree.t3ContextNode.fields);
 			newNode.id = 'fakeNode';
 			node.parentNode.insertBefore(newNode, node.nextSibling);
-			node.attributes.nodeData.t3InCopyMode = false;
+			node.setNodeData('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;
+			node.setNodeData('t3InCutMode', false);
 			this.moveNodeAfterDestination(node, tree);
 		}
 	},
@@ -513,17 +520,17 @@ TYPO3.Components.PageTree.Actions = {
 	/**
 	 * Moves the current tree context node after the given node
 	 *
-	 * @param {Ext.tree.TreeNode} node
+	 * @param {TYPO3.Components.PageTree.Model} 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) {
+			tree.t3ContextNode.get('nodeData'),
+			node.getNodeData('id'),
+			function (response) {
 				if (this.evaluateResponse(response) && tree.t3ContextNode) {
-					this.updateNode(tree.t3ContextNode, tree.t3ContextNode.isExpanded(), response);
+					this.updateNode(tree, tree.t3ContextNode, tree.t3ContextNode.isExpanded(), response);
 				}
 				this.releaseCutAndCopyModes(tree);
 			},
@@ -534,17 +541,17 @@ TYPO3.Components.PageTree.Actions = {
 	/**
 	 * Moves the current tree context node as the first child of the given node
 	 *
-	 * @param {Ext.tree.TreeNode} node
+	 * @param {TYPO3.Components.PageTree.Model} 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) {
+			tree.t3ContextNode.get('nodeData'),
+			node.getNodeData('id'),
+			function (response) {
 				if (this.evaluateResponse(response) && tree.t3ContextNode) {
-					this.updateNode(tree.t3ContextNode, tree.t3ContextNode.isExpanded(), response);
+					this.updateNode(tree, tree.t3ContextNode, tree.t3ContextNode.isExpanded(), response);
 				}
 				this.releaseCutAndCopyModes(tree);
 			},
@@ -555,19 +562,21 @@ TYPO3.Components.PageTree.Actions = {
 	/**
 	 * Inserts a new node after the given node
 	 *
-	 * @param {Ext.tree.TreeNode} node
+	 * @param {TYPO3.Components.PageTree.Model} node
 	 * @param {TYPO3.Components.PageTree.Tree} tree
 	 * @return {void}
 	 */
-	insertNodeAfterDestination: function(node, tree) {
+	insertNodeAfterDestination: function (node, tree) {
 		TYPO3.Components.PageTree.Commands.insertNodeAfterDestination(
-			tree.t3ContextNode.attributes.nodeData,
-			node.previousSibling.attributes.nodeData.id,
+			tree.t3ContextNode.get('nodeData'),
+			node.previousSibling.getNodeData('id'),
 			tree.t3ContextInfo.serverNodeType,
-			function(response) {
+			function (response) {
 				if (this.evaluateResponse(response)) {
-					this.updateNode(node, node.isExpanded(), response, function(node) {
-						tree.triggerEdit(node);
+					this.updateNode(tree, node, node.isExpanded(), response, function (records, operation, successful) {
+						if (successful && operation.node) {
+							tree.getPlugin('treeEditor').startEdit(operation.node, tree.getView().getHeaderAtIndex(0));
+						}
 					});
 				}
 				this.releaseCutAndCopyModes(tree);
@@ -579,18 +588,20 @@ TYPO3.Components.PageTree.Actions = {
 	/**
 	 * Inserts a new node as the first child of the given node
 	 *
-	 * @param {Ext.tree.TreeNode} node
+	 * @param {TYPO3.Components.PageTree.Model} node
 	 * @param {TYPO3.Components.PageTree.Tree} tree
 	 * @return {void}
 	 */
 	insertNodeToFirstChildOfDestination: function(node, tree) {
 		TYPO3.Components.PageTree.Commands.insertNodeToFirstChildOfDestination(
-			tree.t3ContextNode.attributes.nodeData,
+			tree.t3ContextNode.get('nodeData'),
 			tree.t3ContextInfo.serverNodeType,
-			function(response) {
+			function (response) {
 				if (this.evaluateResponse(response)) {
-					this.updateNode(node, true, response, function(node) {
-						tree.triggerEdit(node);
+					this.updateNode(tree, node, true, response, function (records, operation, successful) {
+						if (successful && operation.node) {
+							tree.getPlugin('treeEditor').startEdit(operation.node, tree.getView().getHeaderAtIndex(0));
+						}
 					});
 				}
 				this.releaseCutAndCopyModes(tree);
@@ -602,18 +613,20 @@ TYPO3.Components.PageTree.Actions = {
 	/**
 	 * Copies the current tree context node after the given node
 	 *
-	 * @param {Ext.tree.TreeNode} node
+	 * @param {TYPO3.Components.PageTree.Model} 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) {
+			tree.t3ContextNode.get('nodeData'),
+			node.previousSibling.getNodeData('id'),
+			function (response) {
 				if (this.evaluateResponse(response)) {
-					this.updateNode(node, true, response, function(node) {
-						tree.triggerEdit(node);
+					this.updateNode(tree, node, true, response, function (records, operation, successful) {
+						if (successful && operation.node) {
+							tree.getPlugin('treeEditor').startEdit(operation.node, tree.getView().getHeaderAtIndex(0));
+						}
 					});
 				}
 				this.releaseCutAndCopyModes(tree);
@@ -625,18 +638,20 @@ TYPO3.Components.PageTree.Actions = {
 	/**
 	 * Copies the current tree context node as the first child of the given node
 	 *
-	 * @param {Ext.tree.TreeNode} node
+	 * @param {TYPO3.Components.PageTree.Model} 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) {
+			tree.t3ContextNode.get('nodeData'),
+			node.parentNode.getNodeData('id'),
+			function (response) {
 				if (this.evaluateResponse(response)) {
-					this.updateNode(node, true, response, function(node) {
-						tree.triggerEdit(node);
+					this.updateNode(tree, node, true, response, function (records, operation, successful) {
+						if (successful && operation.node) {
+							tree.getPlugin('treeEditor').startEdit(operation.node, tree.getView().getHeaderAtIndex(0));
+						}
 					});
 				}
 				this.releaseCutAndCopyModes(tree);
@@ -648,15 +663,16 @@ TYPO3.Components.PageTree.Actions = {
 	/**
 	 * Visibilizes a page
 	 *
-	 * @param {Ext.tree.TreeNode} node
+	 * @param {Ext.data.NodeInterface} node
+	 * @param {TYPO3.Components.PageTree.Tree} tree
 	 * @return {void}
 	 */
-	enablePage: function(node) {
+	enablePage: function(node, tree) {
 		TYPO3.Components.PageTree.Commands.visiblyNode(
-			node.attributes.nodeData,
+			node.get('nodeData'),
 			function(response) {
 				if (this.evaluateResponse(response)) {
-					this.updateNode(node, node.isExpanded(), response);
+					this.updateNode(tree, node, node.isExpanded(), response);
 				}
 			},
 			this
@@ -666,15 +682,16 @@ TYPO3.Components.PageTree.Actions = {
 	/**
 	 * Disables a page
 	 *
-	 * @param {Ext.tree.TreeNode} node
+	 * @param {Ext.data.NodeInterface} node
+	 * @param {TYPO3.Components.PageTree.Tree} tree
 	 * @return {void}
 	 */
-	disablePage: function(node) {
+	disablePage: function(node, tree) {
 		TYPO3.Components.PageTree.Commands.disableNode(
-			node.attributes.nodeData,
-			function(response) {
+			node.get('nodeData'),
+			function (response) {
 				if (this.evaluateResponse(response)) {
-					this.updateNode(node, node.isExpanded(), response);
+					this.updateNode(tree, node, node.isExpanded(), response);
 				}
 			},
 			this
@@ -684,11 +701,11 @@ TYPO3.Components.PageTree.Actions = {
 	/**
 	 * Reloads the content frame with the current module and node id
 	 *
-	 * @param {Ext.tree.TreeNode} node
+	 * @param {TYPO3.Components.PageTree.Model} node
 	 * @param {TYPO3.Components.PageTree.Tree} tree
 	 * @return {void}
 	 */
-	singleClick: function(node, tree) {
+	singleClick: function (node, tree) {
 		tree.currentSelectedNode = node;
 
 		var separator = '?';
@@ -696,68 +713,77 @@ TYPO3.Components.PageTree.Actions = {
 			separator = '&';
 		}
 
-		node.select();
-		if (tree.stateHash) {
-			tree.stateHash.lastSelectedNode = node.id;
-		}
+		tree.getSelectionModel().select(node);
 
-		fsMod.recentIds['web'] = node.attributes.nodeData.id;
+		fsMod.recentIds['web'] = node.getNodeData('id');
 
 		TYPO3.Backend.ContentContainer.setUrl(
-			TS.PATH_typo3 + currentSubScript + separator + 'id=' + node.attributes.nodeData.id
+			TS.PATH_typo3 + currentSubScript + separator + 'id=' + node.getNodeData('id')
 		);
 	},
 
 	/**
 	 * Opens a configured url inside the content frame
 	 *
-	 * @param {Ext.tree.TreeNode} node
+	 * @param {TYPO3.Components.PageTree.Model} node
 	 * @param {TYPO3.Components.PageTree.Tree} tree
 	 * @param {Object} contextItem
 	 * @return {void}
 	 */
-	openCustomUrlInContentFrame: function(node, tree, contextItem) {
+	openCustomUrlInContentFrame: function (node, tree, contextItem) {
 		if (!contextItem.customAttributes || !contextItem.customAttributes.contentUrl) {
 			return;
 		}
 
-		node.select();
+		tree.getSelectionModel().select(node);
 		TYPO3.Backend.ContentContainer.setUrl(
-			contextItem.customAttributes.contentUrl.replace('###ID###', node.attributes.nodeData.id)
+			contextItem.customAttributes.contentUrl.replace('###ID###', node.getNodeData('id'))
 		);
 	},
 
 	/**
 	 * Updates the title of a node
 	 *
-	 * @param {Ext.tree.TreeNode} node
+	 * @param {TYPO3.Components.PageTree.Model} node
 	 * @param {String} newText
 	 * @param {String} oldText
 	 * @param {TYPO3.Components.PageTree.TreeEditor} treeEditor
+	 * @param {TYPO3.Components.PageTree.Tree} tree
+	 * @param {String} dataIndex
 	 * @return {void}
 	 */
-	saveTitle: function(node, newText, oldText, treeEditor) {
-		this.singleClick(node.editNode, node.editNode.ownerTree);
+	saveTitle: function (node, newText, oldText, treeEditor, tree, dataIndex) {
+		this.singleClick(node, tree);
 		if (newText === oldText || newText == '') {
 			treeEditor.updateNodeText(
 				node,
-				node.editNode.attributes.nodeData.editableText,
-				Ext.util.Format.htmlEncode(oldText)
+				node.getNodeData('editableText'),
+				Ext.util.Format.htmlEncode(oldText),
+				dataIndex,
+				tree
 			);
 			return;
 		}
 
 		TYPO3.Components.PageTree.Commands.updateLabel(
-			node.editNode.attributes.nodeData,
+			node.get('nodeData'),
 			newText,
 			function(response) {
 				if (this.evaluateResponse(response)) {
-					treeEditor.updateNodeText(node, response.editableText, response.updatedText);
+					treeEditor.updateNodeText(
+						node,
+						response.editableText,
+						response.updatedText,
+						dataIndex,
+						tree
+					);
 				} else {
 					treeEditor.updateNodeText(
 						node,
-						node.editNode.attributes.nodeData.editableText,
-						Ext.util.Format.htmlEncode(oldText)
+						node.getNodeData('editableText'),
+						Ext.util.Format.htmlEncode(oldText),
+						dataIndex,
+						tree
 					);
 				}
 			},
diff --git a/t3lib/js/extjs/components/pagetree/javascript/app.js b/t3lib/js/extjs/components/pagetree/javascript/app.js
index 6a178f5921a17fdeef4d826158e41a9b98d92f71..2701f93c47a6ed39f31b13bb1ed24f410f2684aa 100644
--- a/t3lib/js/extjs/components/pagetree/javascript/app.js
+++ b/t3lib/js/extjs/components/pagetree/javascript/app.js
@@ -23,18 +23,18 @@
 *
 *  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
+ * @extends Ext.panel.Panel
  * @author Stefan Galinski <stefan.galinski@gmail.com>
  */
-TYPO3.Components.PageTree.App = Ext.extend(Ext.Panel, {
+Ext.define('TYPO3.Components.PageTree.App', {
+	extend: 'Ext.panel.Panel',
+
 	/**
 	 * Panel id
 	 *
@@ -45,7 +45,7 @@ TYPO3.Components.PageTree.App = Ext.extend(Ext.Panel, {
 	/**
 	 * Border
 	 *
-	 * @type {Boolean}
+	 * @type {String}
 	 */
 	border: false,
 
@@ -54,14 +54,38 @@ TYPO3.Components.PageTree.App = Ext.extend(Ext.Panel, {
 	 *
 	 * @type {String}
 	 */
-	layout:'fit',
+	layout: 'border',
 
 	/**
-	 * Active tree
+	 * Components defaults
 	 *
-	 * @type {TYPO3.Components.PageTree.Tree}
+	 * @type {Object}
 	 */
-	activeTree: null,
+	 defaults: {
+	 	 border: false,
+	 },
+	
+	/**
+	 * Tree containe
+	 *
+	 * @type {String}
+	 */
+	 items: [{
+			itemId: 'topPanelItems',
+			height: 49,
+			region: 'north',
+			cls: 'typo3-pageTree-topPanelItems'
+	 	},{
+			itemId: 'treeContainer',
+			autoScroll: false,
+			layout: 'card',
+			region: 'center'
+		},{
+			xtype: 'container',
+			itemId: 'deletionDropZoneContainer',
+			cls: 'typo3-pageTree-deletionDropZoneContainer',
+			region: 'south'
+	 }],
 
 	/**
 	 * Initializes the application
@@ -72,112 +96,89 @@ TYPO3.Components.PageTree.App = Ext.extend(Ext.Panel, {
 	 * @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,
-				app: this,
-				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,
-				app: this
-			}).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.addListener('render', 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 = Ext.create('TYPO3.Components.PageTree.Tree', {
+					id: this.getId() + '-tree',
+					deletionDropZoneId: this.getId() + '-deletionDropZone',
+					ddGroup: this.getId(),
+					stateful: true,
+					stateId: 'Pagetree' + TYPO3.Components.PageTree.Configuration.temporaryMountPoint,
+					commandProvider: TYPO3.Components.PageTree.Actions,
+					contextMenuProvider: TYPO3.Components.PageTree.ContextMenuDataProvider,
+					treeDataProvider: TYPO3.Components.PageTree.DataProvider,
+					app: this
+				});
+	
+				var filteringTree = Ext.create('TYPO3.Components.PageTree.FilteringTree', {
+					id: this.getId() + '-filteringTree',
+					deletionDropZoneId: this.getId() + '-deletionDropZone',
+					ddGroup: this.getId(),
+					commandProvider: TYPO3.Components.PageTree.Actions,
+					contextMenuProvider: TYPO3.Components.PageTree.ContextMenuDataProvider,
+					stateful: false,
+					treeDataProvider: TYPO3.Components.PageTree.DataProvider,
+					app: this
+				});
+	
+				var topPanelItems = this.getComponent('topPanelItems');
+				topPanelItems.add([
+						Ext.create('TYPO3.Components.PageTree.TopPanel', {
+							border: false,
+							dataProvider: TYPO3.Components.PageTree.DataProvider,
+							filteringTree: filteringTree,
+							ddGroup: this.getId(),
+							height: 49,
+							itemId: 'topPanel',
+							tree: tree,
+							app: this
+						}),
+						{
+							xtype: 'container',
+							border: false,
+							defaultType: 'component',
+							id: this.getId() + '-indicatorBar',
+							itemId: 'indicatorBar'
+						}
+				]);
+	
+				var treeContainer = this.getComponent('treeContainer');
+				treeContainer.add([tree, filteringTree]);
+				treeContainer.addListener(
+					'render',
+					function (panel) { panel.getLayout().setActiveItem(0); }
+				);
+	
+				var deletionDropZoneContainer = this.getComponent('deletionDropZoneContainer');
+				deletionDropZoneContainer.add({
+					xtype: 'typo3deletiondropzone',
+					height: 35,
+					id: this.getId() + '-deletionDropZone',
+					commandProvider: TYPO3.Components.PageTree.Actions,
+					ddGroup: this.getId(),
+					layout: 'anchor',
+					app: this
+				});
+
+				if (TYPO3.Components.PageTree.Configuration.temporaryMountPoint) {
 					this.addTemporaryMountPointIndicator();
-				}, this);
-			}
-
-			if (TYPO3.Components.PageTree.Configuration.indicator !== '') {
-				this.addIndicatorItems();
-			}
-			this.doLayout();
-
-			this.ownerCt.on('resize', function() {
+				}
+	
+				if (TYPO3.Components.PageTree.Configuration.indicator !== '') {
+					this.addIndicatorItems();
+				}
 				this.doLayout();
-			});
+	
+				this.ownerCt.on('resize', function() {
+					this.doLayout();
+				}, this);
+			}, this);
 		}, this);
-
-		TYPO3.Components.PageTree.App.superclass.initComponent.apply(this, arguments);
+		this.callParent();
 	},
 
 	/**
@@ -187,9 +188,8 @@ TYPO3.Components.PageTree.App = Ext.extend(Ext.Panel, {
 	 */
 	addIndicatorItems: function() {
 		this.addIndicator({
-			border: false,
-			id: this.id + '-indicatorBar-indicatorTitle',
-			cls: this.id + '-indicatorBar-item',
+			id: this.getId() + '-indicatorBar-indicatorTitle',
+			cls: this.getId() + '-indicatorBar-item',
 			html: TYPO3.Components.PageTree.Configuration.indicator
 		});
 	},
@@ -201,14 +201,13 @@ TYPO3.Components.PageTree.App = Ext.extend(Ext.Panel, {
 	 */
 	addTemporaryMountPointIndicator: function() {
 		this.temporaryMountPointInfoIndicator = this.addIndicator({
-			border: false,
-			id: this.id + '-indicatorBar-temporaryMountPoint',
-			cls: this.id + '-indicatorBar-item',
+			id: this.getId() + '-indicatorBar-temporaryMountPoint',
+			cls: this.getId() + '-indicatorBar-item',
 
 			listeners: {
 				afterrender: {
 					fn: function() {
-						var element = Ext.fly(this.id + '-indicatorBar-temporaryMountPoint-clear');
+						var element = Ext.get(this.getId() + '-indicatorBar-temporaryMountPoint-clear');
 						element.on('click', function() {
 							TYPO3.BackendUserSettings.ExtDirect.unsetKey(
 								'pageTree_temporaryMountPoint',
@@ -225,18 +224,21 @@ TYPO3.Components.PageTree.App = Ext.extend(Ext.Panel, {
 					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 +
+			renderData: {
+				appId: this.getId(),
+				spriteIconCls: TYPO3.Components.PageTree.Sprites.Info,
+				label: TYPO3.Components.PageTree.LLL.temporaryMountPointIndicatorInfo,
+				mountPoint: TYPO3.Components.PageTree.Configuration.temporaryMountPoint
+			},
+			renderTpl: Ext.create('Ext.XTemplate',
+				'<p>',
+				'<span id="{appId}-indicatorBar-temporaryMountPoint-info" class="{appId}-indicatorBar-item-leftIcon {spriteIconCls}">&nbsp;</span>',
+				'{label}',
+				'<span id="{appId}-indicatorBar-temporaryMountPoint-clear" class="{appId}-indicatorBar-item-rightIcon t3-icon t3-icon-actions t3-icon-actions-input t3-icon-input-clear t3-tceforms-input-clearer">&nbsp;</span>',
+				'</p>',
+				'<p>{mountPoint}',
 				'</p>'
+			)
 		});
 	},
 
@@ -248,23 +250,18 @@ TYPO3.Components.PageTree.App = Ext.extend(Ext.Panel, {
 	 */
 	addIndicator: function(component) {
 		if (component.listeners && component.listeners.afterrender) {
-			component.listeners.afterrender.fn = component.listeners.afterrender.fn.createSequence(
-				this.afterTopPanelItemAdded, this
-			);
+			component.listeners.afterrender.fn = Ext.Function.createSequence(component.listeners.afterrender.fn, this.afterTopPanelItemAdded, this);
 		} else {
-			if (component.listeners) {
-				component.listeners = {}
+			if (!component.listeners) {
+				component.listeners = {};
 			}
-
 			component.listeners.afterrender = {
 				scope: this,
 				fn: this.afterTopPanelItemAdded
 			}
 		}
-
-		var indicator = Ext.getCmp(this.id + '-indicatorBar').add(component);
-		this.doLayout();
-
+		var indicatorBar = this.down('component[itemId=indicatorBar]');
+		var indicator = indicatorBar.add(component);
 		return indicator;
 	},
 
@@ -275,8 +272,15 @@ TYPO3.Components.PageTree.App = Ext.extend(Ext.Panel, {
 	 * @return {void}
 	 */
 	afterTopPanelItemAdded: function(component) {
-		var topPanelItems = Ext.getCmp(this.id + '-topPanelItems');
-		topPanelItems.setHeight(topPanelItems.getHeight() + component.getHeight() + 3);
+		var topPanel = this.down('component[itemId=topPanel]');
+		var indicatorBar = this.down('component[itemId=indicatorBar]');
+		var height = 0;
+		indicatorBar.items.each(function (item) {
+			height += item.getHeight() + 3;
+		});
+		indicatorBar.setHeight(height);
+		topPanelItems = this.down('component[itemId=topPanelItems]');
+		topPanelItems.setHeight(topPanel.getHeight() + indicatorBar.getHeight());
 		this.doLayout();
 	},
 
@@ -287,9 +291,9 @@ TYPO3.Components.PageTree.App = Ext.extend(Ext.Panel, {
 	 * @return {void}
 	 */
 	removeIndicator: function(component) {
-		var topPanelItems = Ext.getCmp(this.id + '-topPanelItems');
+		var topPanelItems = this.down('component[itemId=topPanelItems]');
 		topPanelItems.setHeight(topPanelItems.getHeight() - component.getHeight() - 3);
-		Ext.getCmp(this.id + '-indicatorBar').remove(component);
+		Ext.getCmp(this.getId() + '-indicatorBar').remove(component);
 		this.doLayout();
 	},
 
@@ -318,11 +322,11 @@ TYPO3.Components.PageTree.App = Ext.extend(Ext.Panel, {
 	 */
 	refreshTree: function() {
 		if (!isNaN(fsMod.recentIds['web']) && fsMod.recentIds['web'] !== '') {
-			this.select(fsMod.recentIds['web'], true);
+			this.select(fsMod.recentIds['web']);
 		}
 
 		TYPO3.Components.PageTree.DataProvider.getIndicators(function(response) {
-			var indicators = Ext.getCmp(this.id + '-indicatorBar-indicatorTitle');
+			var indicators = Ext.getCmp(this.getId() + '-indicatorBar-indicatorTitle');
 			if (indicators) {
 				this.removeIndicator(indicators);
 			}
@@ -333,7 +337,7 @@ TYPO3.Components.PageTree.App = Ext.extend(Ext.Panel, {
 			}
 		}, this);
 
-		this.activeTree.refreshTree();
+		this.getTree().refreshTree();
 	},
 
 	/**
@@ -342,43 +346,44 @@ TYPO3.Components.PageTree.App = Ext.extend(Ext.Panel, {
 	 * @return {TYPO3.Components.PageTree.Tree}
 	 */
 	getTree: function() {
-		return this.activeTree;
+		return this.down('component[itemId=treeContainer]').getLayout().getActiveItem();
 	},
 
 	/**
-	 * Selects a node defined by the page id. If the second parameter is set, we
-	 * store the new location into the state hash.
+	 * Sets the current active tree
+	 * @param {TYPO3.Components.PageTree.Tree} tree
+	 * @return {TYPO3.Components.PageTree.Tree}
+	 */
+	setTree: function(tree) {
+		var layout = this.down('component[itemId=treeContainer]').getLayout();
+		layout.setActiveItem(tree);
+		return layout.getActiveItem(tree);
+	},
+
+	/**
+	 * Selects a node defined by the page id.
 	 *
 	 * @param {int} pageId
-	 * @param {Boolean} saveState
 	 * @return {Boolean}
 	 */
-	select: function(pageId, saveState) {
-		if (saveState !== false) {
-			saveState = true;
-		}
-
+	select: function(pageId) {
 		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}
+	 * @return {Ext.data.NodeInterface}
 	 */
 	getSelected: function() {
-		var node = this.getTree().getSelectionModel().getSelectedNode();
+		var node = this.getTree().getSelectionModel().getLastSelected();
 		return node ? node : null;
 	}
 });
@@ -389,15 +394,12 @@ TYPO3.Components.PageTree.App = Ext.extend(Ext.Panel, {
  * @return {TYPO3.Components.PageTree.App}
  */
 TYPO3.ModuleMenu.App.registerNavigationComponent('typo3-pagetree', function() {
-	TYPO3.Backend.NavigationContainer.PageTree = new TYPO3.Components.PageTree.App();
+	TYPO3.Backend.NavigationContainer.PageTree = Ext.create('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;
+	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);
diff --git a/t3lib/js/extjs/components/pagetree/javascript/contextmenu.js b/t3lib/js/extjs/components/pagetree/javascript/contextmenu.js
index 32501b69f334eb1d66e489b917a9bb938ce10d1a..5c6ed687aa82b4189688e60b6cd0ac1c8e7b9269 100644
--- a/t3lib/js/extjs/components/pagetree/javascript/contextmenu.js
+++ b/t3lib/js/extjs/components/pagetree/javascript/contextmenu.js
@@ -23,8 +23,6 @@
 *
 *  This copyright notice MUST APPEAR in all copies of the script!
 ***************************************************************/
-Ext.namespace('TYPO3.Components.PageTree');
-
 /**
  * @class TYPO3.Components.PageTree.ContextMenu
  *
@@ -34,11 +32,12 @@ Ext.namespace('TYPO3.Components.PageTree');
  * @extends Ext.menu.Menu
  * @author Stefan Galinski <stefan.galinski@gmail.com>
  */
-TYPO3.Components.PageTree.ContextMenu = Ext.extend(Ext.menu.Menu, {
+Ext.define('TYPO3.Components.PageTree.ContextMenu', {
+	extend: 'Ext.menu.Menu',
 	/**
 	 * Context menu node
 	 *
-	 * @cfg {Ext.tree.TreeNode}
+	 * @cfg {TYPO3.Components.PageTree.Model}
 	 */
 	node: null,
 
@@ -66,15 +65,15 @@ TYPO3.Components.PageTree.ContextMenu = Ext.extend(Ext.menu.Menu, {
 	/**
 	 * Listeners
 	 *
-	 * The itemclick event triggers the configured single click action
+	 * The click event triggers the configured single click action
 	 */
 	listeners: {
-		itemclick: {
-			fn: function (item) {
-				if (this.pageTree.commandProvider[item.callbackAction]) {
+		click: {
+			fn: function (menu, item) {
+				if (item && 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;
+						fsMod.recentIds['web'] = item.parentMenu.node.getNodeData('id');
+						item.parentMenu.pageTree.stateHash['lastSelectedNode'] = item.parentMenu.node.getId();
 					}
 
 					this.pageTree.commandProvider[item.callbackAction](
@@ -90,12 +89,12 @@ TYPO3.Components.PageTree.ContextMenu = Ext.extend(Ext.menu.Menu, {
 	/**
 	 * Fills the menu with the actions
 	 *
-	 * @param {Ext.tree.TreeNode} node
+	 * @param {TYPO3.Components.PageTree.Model} node
 	 * @param {TYPO3.Components.PageTree.Tree} pageTree
 	 * @param {Object} contextMenuConfiguration
 	 * @return {void}
 	 */
-	fill: function(node, pageTree, contextMenuConfiguration) {
+	fill: function (node, pageTree, contextMenuConfiguration) {
 		this.node = node;
 		this.pageTree = pageTree;
 
@@ -103,9 +102,11 @@ TYPO3.Components.PageTree.ContextMenu = Ext.extend(Ext.menu.Menu, {
 		if (components.length) {
 			for (var component in components) {
 				if (components[component] === '-') {
-					this.addSeparator();
+					this.add({
+						xtype: 'menuseparator'
+					});
 				} else if (typeof components[component] === 'object') {
-					this.addItem(components[component]);
+					this.add(components[component]);
 				}
 			}
 		}
@@ -119,7 +120,7 @@ TYPO3.Components.PageTree.ContextMenu = Ext.extend(Ext.menu.Menu, {
 	 * @param {int} level
 	 * @return {Object}
 	 */
-	preProcessContextMenuConfiguration: function(contextMenuConfiguration, level) {
+	preProcessContextMenuConfiguration: function (contextMenuConfiguration, level) {
 		level = level || 0;
 		if (level > 5) {
 			return [];
@@ -138,7 +139,7 @@ TYPO3.Components.PageTree.ContextMenu = Ext.extend(Ext.menu.Menu, {
 				);
 
 				if (subMenuComponents.length) {
-					var subMenu = new TYPO3.Components.PageTree.ContextMenu({
+					var subMenu = Ext.create('TYPO3.Components.PageTree.ContextMenu', {
 						id: this.id + '-sub' + ++subMenus,
 						items: subMenuComponents,
 						node: this.node,
@@ -150,7 +151,8 @@ TYPO3.Components.PageTree.ContextMenu = Ext.extend(Ext.menu.Menu, {
 						cls: 'contextMenu-subMenu',
 						menu: subMenu,
 						icon: contextMenuConfiguration[singleAction]['icon'],
-						iconCls: contextMenuConfiguration[singleAction]['class']
+						iconCls: contextMenuConfiguration[singleAction]['class'],
+						xtype: 'menuitem'
 					};
 				}
 			} else if (contextMenuConfiguration[singleAction]['type'] === 'divider') {
@@ -163,22 +165,14 @@ TYPO3.Components.PageTree.ContextMenu = Ext.extend(Ext.menu.Menu, {
 
 				if (typeof contextMenuConfiguration[singleAction] === 'object') {
 					var component = {
-						'text': contextMenuConfiguration[singleAction]['label'],
-						'icon': contextMenuConfiguration[singleAction]['icon'],
-						'iconCls': contextMenuConfiguration[singleAction]['class'],
-						'callbackAction': contextMenuConfiguration[singleAction]['callbackAction'],
-						'customAttributes': contextMenuConfiguration[singleAction]['customAttributes']
+						text: contextMenuConfiguration[singleAction]['label'],
+						icon: contextMenuConfiguration[singleAction]['icon'],
+						iconCls: contextMenuConfiguration[singleAction]['class'],
+						callbackAction: contextMenuConfiguration[singleAction]['callbackAction'],
+						customAttributes: contextMenuConfiguration[singleAction]['customAttributes'],
+						xtype: 'menuitem'
 					};
 
-					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;
 				}
 			}
@@ -192,6 +186,3 @@ TYPO3.Components.PageTree.ContextMenu = Ext.extend(Ext.menu.Menu, {
 		return components;
 	}
 });
-
-// XTYPE Registration
-Ext.reg('TYPO3.Components.PageTree.ContextMenu', TYPO3.Components.PageTree.ContextMenu);
diff --git a/t3lib/js/extjs/components/pagetree/javascript/deletiondropzone.js b/t3lib/js/extjs/components/pagetree/javascript/deletiondropzone.js
index 443f96fa65880019049a6dbed5ef246c31e75262..a89afdbff79411f48580e4edf3519f14cf3410e1 100644
--- a/t3lib/js/extjs/components/pagetree/javascript/deletiondropzone.js
+++ b/t3lib/js/extjs/components/pagetree/javascript/deletiondropzone.js
@@ -23,18 +23,19 @@
  *
  *  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
+ * @extends Ext.panel.Panel
  * @author Stefan Galinski <stefan.galinski@gmail.com>
  */
-TYPO3.Components.PageTree.DeletionDropZone = Ext.extend(Ext.Panel, {
+Ext.define('TYPO3.Components.PageTree.DeletionDropZone', {
+	extend: 'Ext.panel.Panel',
+	alias: 'widget.typo3deletiondropzone',
+
 	/**
 	 * Border
 	 *
@@ -110,10 +111,7 @@ TYPO3.Components.PageTree.DeletionDropZone = Ext.extend(Ext.Panel, {
 
 				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.removeCls(this.id + '-activateProxyOver');
 					}
 				}, this);
 			}
@@ -139,7 +137,7 @@ TYPO3.Components.PageTree.DeletionDropZone = Ext.extend(Ext.Panel, {
 			'">&nbsp;</span><span id="' + this.id + '-text">' +
 			TYPO3.Components.PageTree.LLL.dropToRemove + '</span></p>';
 
-		TYPO3.Components.PageTree.DeletionDropZone.superclass.initComponent.apply(this, arguments);
+		this.callParent(arguments);
 	},
 
 
@@ -149,44 +147,49 @@ TYPO3.Components.PageTree.DeletionDropZone = Ext.extend(Ext.Panel, {
 	 * @return {void}
 	 */
 	createDropZone: function() {
-		(new Ext.dd.DropZone(this.getEl(), {
+		Ext.create('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;
-				var nodeHasChildNodes = (node.hasChildNodes() || node.isExpandable());
-
-				var callback = null;
-				if (!top.TYPO3.configuration.inWorkspace && !nodeHasChildNodes) {
-					callback = this.setRecoverState.createDelegate(this);
-				}
-
-				if (nodeHasChildNodes) {
-					node.ownerTree.commandProvider.confirmDelete(node, tree, callback, true);
-				} else {
-					node.ownerTree.commandProvider.deleteNode(node, tree, callback);
-				}
-			}.createDelegate(this)
-		}));
+			notifyOver: Ext.Function.bind(
+				function(ddProxy, e) {
+					ddProxy.setDragElPos(e.xy[0], e.xy[1] - 60);
+					return this.id + '-proxyOver';
+				},
+				this
+			),
+
+			notifyEnter: Ext.Function.bind(
+				function() {
+					this.addCls(this.id + '-activateProxyOver');
+					return this.id + '-proxyOver';
+				},
+				this
+			),
+
+			notifyDrop: Ext.Function.bind(
+				function (ddProxy, e, dragData) {
+					var view = dragData.view,
+						tree = view.panel,
+						node = view.getRecord(dragData.item);
+					if (!node) {
+						return;
+					}
+					var nodeHasChildNodes = (node.hasChildNodes() || node.isExpandable());
+	
+					var callback = null;
+					if (!top.TYPO3.configuration.inWorkspace && !nodeHasChildNodes) {
+						callback = Ext.Function.bind(this.setRecoverState, this);
+					}
+	
+					if (nodeHasChildNodes) {
+						tree.commandProvider.confirmDelete(node, tree, callback, true);
+					} else {
+						tree.commandProvider.deleteNode(node, tree, callback);
+					}
+				},
+				this
+			)
+		});
 	},
 
 	/**
@@ -207,7 +210,7 @@ TYPO3.Components.PageTree.DeletionDropZone = Ext.extend(Ext.Panel, {
 		this.setHeight(50);
 		this.updateIcon(TYPO3.Components.PageTree.Sprites.TrashCanRestore);
 		this.updateText(
-			node.text + '<br />' +
+			node.get('text') + '<br />' +
 			'<span class="' + this.id + '-restore">' +
 				'<span class="' + this.id + '-restoreText">' +
 				TYPO3.Components.PageTree.LLL.dropZoneElementRemoved +
@@ -218,13 +221,17 @@ TYPO3.Components.PageTree.DeletionDropZone = Ext.extend(Ext.Panel, {
 		this.app.doLayout();
 
 		++this.amountOfDrops;
-		(function() {
-			if (!--this.amountOfDrops) {
-				this.toOriginState();
-			}
-		}).defer(10000, this);
+		Ext.Function.defer(
+			function() {
+				if (!--this.amountOfDrops) {
+					this.toOriginState();
+				}
+			},
+			10000,
+			this
+		);
 
-		this.textClickHandler = this.restoreNode.createDelegate(this, [node, tree]);
+		this.textClickHandler = Ext.Function.bind(this.restoreNode, this, [node, tree]);
 		Ext.get(this.id + '-text').on('click', this.textClickHandler);
 
 		this.isPreviousSibling = false;
@@ -283,7 +290,7 @@ TYPO3.Components.PageTree.DeletionDropZone = Ext.extend(Ext.Panel, {
 		this.previousNode = this.textClickHandler = null;
 		this.isPreviousSibling = false;
 
-		if (hide && !this.app.activeTree.dragZone.dragging) {
+		if (hide && !this.app.getTree().getView().getPlugin('treeViewDragDrop').dragZone.dragging) {
 			this.hide();
 		}
 
@@ -310,13 +317,14 @@ TYPO3.Components.PageTree.DeletionDropZone = Ext.extend(Ext.Panel, {
 		this.updateText(TYPO3.Components.PageTree.LLL.dropZoneElementRestored);
 		this.app.doLayout();
 
-		(function() {
-			if (this.textClickHandler) {
-				this.toOriginState();
-			}
-		}).defer(3000, this);
+		Ext.Function.defer(
+			function() {
+				if (this.textClickHandler) {
+					this.toOriginState();
+				}
+			},
+			3000,
+			this
+		);
 	}
 });
-
-// XTYPE Registration
-Ext.reg('TYPO3.Components.PageTree.DeletionDropZone', TYPO3.Components.PageTree.DeletionDropZone);
diff --git a/t3lib/js/extjs/components/pagetree/javascript/filteringtree.js b/t3lib/js/extjs/components/pagetree/javascript/filteringtree.js
index 7ee0d88d312de0316141e51525b4f52b217fcf51..5b24822d19bed59cf4281169e3883c513e9f8afa 100644
--- a/t3lib/js/extjs/components/pagetree/javascript/filteringtree.js
+++ b/t3lib/js/extjs/components/pagetree/javascript/filteringtree.js
@@ -23,8 +23,6 @@
 *
 *  This copyright notice MUST APPEAR in all copies of the script!
 ***************************************************************/
-Ext.namespace('TYPO3.Components.PageTree');
-
 /**
  * @class TYPO3.Components.PageTree.FilteringTree
  *
@@ -34,7 +32,9 @@ Ext.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, {
+Ext.define('TYPO3.Components.PageTree.FilteringTree', {
+	extend: 'TYPO3.Components.PageTree.Tree',
+
 	/**
 	 * Search word
 	 *
@@ -47,29 +47,45 @@ TYPO3.Components.PageTree.FilteringTree = Ext.extend(TYPO3.Components.PageTree.T
 	 *
 	 * @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;
+	addStore: function (store) {
+		this.store = Ext.data.StoreManager.lookup(this.getId() + 'FilteredPageTreeStore');
+		if (!this.store) {
+			this.store = Ext.create('Ext.data.TreeStore', {
+				clearOnLoad: false,
+				listeners: {
+					beforeload: {
+						fn: function (store, operation) {
+							if (!this.searchWord || this.searchWord === '') {
+								return false;
+							}
+							if (operation.node) {
+								var node = operation.node;
+								node.removeAll();
+								node.commit();
+								operation.params = {
+									nodeId: node.getNodeData('id'),
+									nodeData: node.get('nodeData'),
+									searchWord: this.searchWord
+									
+								};
+							}
+						},
+						scope: this
 					}
-
-					treeLoader.baseParams.nodeId = node.id;
-					treeLoader.baseParams.searchWord = node.ownerTree.searchWord;
-					treeLoader.baseParams.attributes = node.attributes.nodeData;
-				}
-			}
-		});
+				},
+				model: 'TYPO3.Components.PageTree.Model',
+				nodeParam: 'nodeId',
+				proxy: {
+					type: 'direct',
+					paramOrder: ['nodeId', 'nodeData', 'searchWord'],
+					directFn: this.treeDataProvider.getFilteredTree,
+					reader: {
+					    type: 'json'
+					}
+				},
+				root: this.rootNodeConfig,
+				storeId: this.getId() + 'FilteredPageTreeStore'
+			});
+		}
 	}
 });
-
-// XTYPE Registration
-Ext.reg('TYPO3.Components.PageTree.FilteringTree', TYPO3.Components.PageTree.FilteringTree);
diff --git a/t3lib/js/extjs/components/pagetree/javascript/loadorder.txt b/t3lib/js/extjs/components/pagetree/javascript/loadorder.txt
index a649b22150ae39b41101fde397cc2c58bcdbd83b..84566aec2fd71794cf8fc9d2331d9d27d8aefb66 100644
--- a/t3lib/js/extjs/components/pagetree/javascript/loadorder.txt
+++ b/t3lib/js/extjs/components/pagetree/javascript/loadorder.txt
@@ -1,10 +1,12 @@
 treeeditor.js
+pagetreecolumn.js
+contextmenu.js
+Ext.ux.state.TreePanel.js
+treedropzone.js
+treeviewdragdrop.js
 tree.js
 filteringtree.js
-nodeui.js
-deletiondropzone.js
 toppanel.js
-contextmenu.js
+deletiondropzone.js
 actions.js
-Ext.ux.state.TreePanel.js
 app.js
diff --git a/t3lib/js/extjs/components/pagetree/javascript/nodeui.js b/t3lib/js/extjs/components/pagetree/javascript/nodeui.js
deleted file mode 100644
index 1a1066063bcecd47c5a5add71a3c12506068feb4..0000000000000000000000000000000000000000
--- a/t3lib/js/extjs/components/pagetree/javascript/nodeui.js
+++ /dev/null
@@ -1,169 +0,0 @@
-/***************************************************************
-*  Copyright notice
-*
-*  (c) 2010-2011 Stefan Galinski <stefan.galinski@gmail.com>
-*  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),
-			rootline = '';
-
-			// TYPO3 modification to show the readable rootline above the user mounts
-		if (a.readableRootline !== '') {
-			var rootline = '<li class="x-tree-node-readableRootline">' + a.readableRootline + '</li>';
-		}
-
-		var buf = [rootline,'<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);
-        }
-
-
-        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 handlesIndex = ddHandles.length;
-		
-		var textNode = Ext.get(this.textNode);
-		for (var i = 0; i < textNode.dom.childNodes.length; ++i) {
-			if (textNode.dom.childNodes[i].nodeName === 'SPAN') {
-				ddHandles[handlesIndex++] = textNode.dom.childNodes[i];
-				if (textNode.dom.childNodes[i].childNodes) {
-					ddHandles[handlesIndex++] = textNode.dom.childNodes[i].childNodes[0];
-				}
-			}
-		}
-
-		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);
diff --git a/t3lib/js/extjs/components/pagetree/javascript/pagetreecolumn.js b/t3lib/js/extjs/components/pagetree/javascript/pagetreecolumn.js
new file mode 100644
index 0000000000000000000000000000000000000000..e4941d313a5c622f28928a6e83ed1896c461927c
--- /dev/null
+++ b/t3lib/js/extjs/components/pagetree/javascript/pagetreecolumn.js
@@ -0,0 +1,166 @@
+/***************************************************************
+*  Copyright notice
+*
+*  (c) 2011 Stanislas Rolland <typo3@sjbr.ca>
+*  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 TYPO3.Components.PageTree.Column
+ *
+ * Page tree column
+ *
+ * @namespace TYPO3.Components.PageTree
+ * @extends Ext.grid.column.Column
+ * @author Stanislas Rolland <typo3@sjbr.ca>
+ */
+Ext.define('TYPO3.Components.PageTree.Column', {
+	extend: 'Ext.grid.column.Column',
+	alias: 'widget.pagetreecolumn',
+	
+	/**
+	 * Render a row of the page tree adding relevant icons depending on record depth and record type
+	 *
+	 */
+	initComponent: function() {
+		var origRenderer = this.renderer || this.defaultRenderer,
+			origScope = this.scope || window;
+
+		this.renderer = function(value, metaData, record, rowIdx, colIdx, store, view) {
+			var buf   = [],
+				format = Ext.String.format,
+				depth = record.getDepth(),
+				treePrefix = Ext.baseCSSPrefix + 'tree-',
+				elbowPrefix = treePrefix + 'elbow-',
+				expanderCls = treePrefix + 'expander',
+				imgText = '<img src="{1}" class="{0}" />',
+				checkboxText = '<input type="button" role="checkbox" class="{0}" {1} />',
+				formattedValue = origRenderer.apply(origScope, arguments),
+				checked = null,
+				href = record.getNodeData('href'),
+				target = record.getNodeData('hrefTarget'),
+				cls = record.getNodeData('cls'),
+				readableRootline = record.getNodeData('readableRootline');
+	
+			while (record) {
+				if (!record.isRoot() || (record.isRoot() && view.rootVisible)) {
+					if (record.getDepth() === depth) {
+							// Add TYPO3 sprite icon code
+						buf.unshift(record.getNodeData('spriteIconCode'));
+							// Check if nodeData['checked'] is boolean
+						checked = record.getNodeData('checked');
+						if (Ext.isBoolean(checked)) {
+							buf.unshift(format(
+								checkboxText,
+								(treePrefix + 'checkbox') + (checked ? ' ' + treePrefix + 'checkbox-checked' : ''),
+								checked ? 'aria-checked="true"' : ''
+							));
+							if (checked) {
+								metaData.tdCls += (' ' + treePrefix + 'checked');
+							}
+						}
+							// Remove +/arrow from the TYPO3 root
+						if (record.getDepth() === 1) {
+							buf.unshift(format(imgText, (elbowPrefix + 'empty'), Ext.BLANK_IMAGE_URL));
+						} else if (record.isLast()) {
+							if (record.isExpandable()) {
+								buf.unshift(format(imgText, (elbowPrefix + 'end-plus ' + expanderCls), Ext.BLANK_IMAGE_URL));
+							} else {
+								buf.unshift(format(imgText, (elbowPrefix + 'end'), Ext.BLANK_IMAGE_URL));
+							}
+						} else {
+							if (record.isExpandable()) {
+								buf.unshift(format(imgText, (elbowPrefix + 'plus ' + expanderCls), Ext.BLANK_IMAGE_URL));
+							} else {
+								buf.unshift(format(imgText, (treePrefix + 'elbow'), Ext.BLANK_IMAGE_URL));
+							}
+						}
+					} else {
+							// Remove elbow from the TYPO3 root
+						if (record.isLast() || record.getDepth() === 1) {
+							buf.unshift(format(imgText, (elbowPrefix + 'empty'), Ext.BLANK_IMAGE_URL));
+						} else if (record.getDepth() !== 1) {
+							buf.unshift(format(imgText, (elbowPrefix + 'line'), Ext.BLANK_IMAGE_URL));
+						}                      
+					}
+				}
+				record = record.parentNode;
+			} 
+			if (href) {
+				buf.push('<a href="', href, '" target="', target, '">', formattedValue, '</a>');
+			} else {
+				buf.push(formattedValue);
+			}
+			if (cls) {
+				metaData.tdCls += ' ' + cls;
+			}
+				// Show the readable rootline above the user mounts
+			if (readableRootline !== '') {
+				buf.unshift('<div class="x-tree-node-readableRootline">' + readableRootline + '</div>');
+			}
+			return buf.join('');
+		};
+		this.callParent(arguments);
+	},
+
+	defaultRenderer: function (value) {
+		return value;
+	},
+	/**
+	 * Create editing field with correct margin left
+	 *
+	 */
+        getEditor: function (record, defaultField) {
+		var depth = parseInt(record.getDepth()),
+			marginLeft = 51;
+		if (depth > 2) {
+			marginLeft += (depth-2)*16;
+		}
+		var field = this.field;
+        	if (!field && this.editor) {
+			field = this.editor;
+			delete this.editor;
+		}
+
+		if (!field && defaultField) {
+			field = defaultField;
+		}
+
+		if (field) {
+ 			if (Ext.isString(field)) {
+				field = { xtype: field };
+			}
+			if (field.isFormField) {
+				field.setFieldStyle({
+					marginLeft: marginLeft + 'px'
+				});
+			}
+			if (Ext.isObject(field) && !field.isFormField) {
+				field = Ext.ComponentManager.create(field, 'textfield');
+				this.field = field;
+			}
+			Ext.apply(field, {
+				name: this.dataIndex
+			});
+			return field;
+		}
+	}
+});
diff --git a/t3lib/js/extjs/components/pagetree/javascript/toppanel.js b/t3lib/js/extjs/components/pagetree/javascript/toppanel.js
index f80299d8e9a3ec0c7dede09757fb1b996b71d9b3..04d28f9749a4e34dc861e1f61198edfc21e0e74e 100644
--- a/t3lib/js/extjs/components/pagetree/javascript/toppanel.js
+++ b/t3lib/js/extjs/components/pagetree/javascript/toppanel.js
@@ -23,18 +23,18 @@
 *
 *  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
+ * @extends Ext.panel.Panel
  * @author Stefan Galinski <stefan.galinski@gmail.com>
  */
-TYPO3.Components.PageTree.TopPanel = Ext.extend(Ext.Panel, {
+Ext.define('TYPO3.Components.PageTree.TopPanel', {
+	extend: 'Ext.panel.Panel',
+
 	/**
 	 * Component Id
 	 *
@@ -43,37 +43,48 @@ TYPO3.Components.PageTree.TopPanel = Ext.extend(Ext.Panel, {
 	id: 'typo3-pagetree-topPanel',
 
 	/**
-	 * Border
+	 * Toolbar Object
 	 *
-	 * @type {Boolean}
+	 * @type {Ext.Toolbar}
 	 */
-	border: false,
+	dockedItems: [{
+		xtype: 'toolbar',
+		dock: 'top',
+		itemId: 'topToolbar'
+	}],
 
 	/**
-	 * Toolbar Object
+	 * Panel CSS
 	 *
-	 * @type {Ext.Toolbar}
+	 * @type {String}
 	 */
-	tbar: new Ext.Toolbar(),
-
+	cls: 'typo3-pagetree-topPanel',
+	
 	/**
-	 * Currently Clicked Toolbar Button
+	 * Body CSS
 	 *
-	 * @type {Ext.Button}
+	 * @type {String}
 	 */
-	currentlyClickedButton: null,
+	bodyCls: 'typo3-pagetree-topPanel-item',
+	
+	/**
+	 * Layout
+	 *
+	 * @type {String}
+	 */
+	layout: 'anchor',
 
 	/**
-	 * Currently Shown Panel
+	 * Currently Clicked Toolbar Button
 	 *
-	 * @type {Ext.Component}
+	 * @type {Ext.Button}
 	 */
-	currentlyShownPanel: null,
+	currentlyClickedButton: null,
 
 	/**
 	 * Filtering Indicator Item
 	 *
-	 * @type {Ext.Panel}
+	 * @type {Ext.panel.Panel}
 	 */
 	filteringIndicator: null,
 
@@ -118,38 +129,20 @@ TYPO3.Components.PageTree.TopPanel = Ext.extend(Ext.Panel, {
 	 * @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.callParent();
+			// Node insertion feature
 		this.addDragDropNodeInsertionFeature();
-
+			// Filter feature
 		if (!TYPO3.Components.PageTree.Configuration.hideFilter
 			|| TYPO3.Components.PageTree.Configuration.hideFilter === '0'
 		) {
 			this.addFilterFeature();
 		}
-
-		this.getTopToolbar().addItem({xtype: 'tbfill'});
+			// Refresh feature
+		this.getDockedComponent('topToolbar').add({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
 	 *
@@ -158,7 +151,6 @@ TYPO3.Components.PageTree.TopPanel = Ext.extend(Ext.Panel, {
 	 * @return {void}
 	 */
 	addButton: function(button, connectedWidget) {
-		button.template = this.getButtonTemplate();
 		if (!button.hasListener('click')) {
 			button.on('click', this.topbarButtonCallback);
 		}
@@ -169,7 +161,7 @@ TYPO3.Components.PageTree.TopPanel = Ext.extend(Ext.Panel, {
 			this.add(connectedWidget);
 		}
 
-		this.getTopToolbar().addItem(button);
+		this.getDockedComponent('topToolbar').add(button);
 		this.doLayout();
 	},
 
@@ -182,44 +174,45 @@ TYPO3.Components.PageTree.TopPanel = Ext.extend(Ext.Panel, {
 	topbarButtonCallback: function() {
 		var topPanel = this.ownerCt.ownerCt;
 
-		topPanel.currentlyShownPanel.hide();
 		if (topPanel.currentlyClickedButton) {
 			topPanel.currentlyClickedButton.toggle(false);
+			if (topPanel.currentlyClickedButton.connectedWidget) {
+				topPanel.currentlyClickedButton.connectedWidget.hide();
+			}
 		}
 
 		if (topPanel.currentlyClickedButton === this) {
 			topPanel.currentlyClickedButton = null;
-			topPanel.currentlyShownPanel = topPanel.get(topPanel.id + '-defaultPanel');
+			if (this.connectedWidget) {
+				this.connectedWidget.hide();
+			}
 		} else {
 			this.toggle(true);
 			topPanel.currentlyClickedButton = this;
-			topPanel.currentlyShownPanel = this.connectedWidget;
+			if (this.connectedWidget) {
+				this.connectedWidget.show();
+			}
 		}
-
-		topPanel.currentlyShownPanel.show();
 	},
 
 	/**
 	 * Loads the filtering tree nodes with the given search word
 	 *
-	 * @param {Ext.form.TextField} textField
+	 * @param {Ext.form.field.Trigger} textField
 	 * @return {void}
 	 */
-	createFilterTree: function(textField) {
+	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() {
+			this.app.setTree(this.tree);
+			this.tree.refreshTree(function() {
 				textField.focus(false, 500);
 			}, this);
 
@@ -229,7 +222,6 @@ TYPO3.Components.PageTree.TopPanel = Ext.extend(Ext.Panel, {
 			}
 		} else {
 			var selectedNode = this.app.getSelected();
-			this.app.activeTree = this.filteringTree;
 
 			if (!this.filteringIndicator) {
 				this.filteringIndicator = this.app.addIndicator(
@@ -237,20 +229,20 @@ TYPO3.Components.PageTree.TopPanel = Ext.extend(Ext.Panel, {
 				);
 			}
 
-			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() {
+			this.app.ownerCt.getEl().addCls('t3-mask-loading');
+			this.app.setTree(this.filteringTree);
+			this.filteringTree.refreshTree(function() {
 				if (selectedNode) {
-					this.app.select(selectedNode.attributes.nodeData.id, false);
+					this.app.select(selectedNode.getNodeData('id'));
 				}
-				textField.focus();
 				this.app.ownerCt.getEl().unmask();
+				textField.setHideTrigger(false);
+				textField.triggerWrap.setWidth(0);
+				this.forceComponentLayout();
+				textField.focus();
 			}, this);
 		}
-
-		this.doLayout();
 	},
 
 	/**
@@ -261,26 +253,27 @@ TYPO3.Components.PageTree.TopPanel = Ext.extend(Ext.Panel, {
 	 */
 	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>',
+			id: this.app.getId() + '-indicatorBar-filter',
+			cls: this.app.getId() + '-indicatorBar-item',
+			renderData: {
+				appId: this.app.getId(),
+				spriteIconCls: TYPO3.Components.PageTree.Sprites.Info,
+				label: TYPO3.Components.PageTree.LLL.activeFilterMode
+			},
+			renderTpl: Ext.create('Ext.XTemplate',
+				'<p>',
+				'<span id="{appId}-indicatorBar-filter-info" class="{appId}-indicatorBar-item-leftIcon {spriteIconCls}">&nbsp;</span>',
+				'&nbsp;{label}&nbsp;',
+				'<span id="{appId}-indicatorBar-filter-clear" class="{appId}-indicatorBar-item-rightIcon">X</span>',
+				'</p>'
+			),
 			filteringTree: this.filteringTree,
 
 			listeners: {
 				afterrender: {
 					scope: this,
-					fn: function() {
-						var element = Ext.fly(this.app.id + '-indicatorBar-filter-clear');
+					fn: function(component) {
+						var element = Ext.get(this.app.getId() + '-indicatorBar-filter-clear');
 						element.on('click', function() {
 							textField.setValue('');
 							this.createFilterTree(textField);
@@ -297,71 +290,65 @@ TYPO3.Components.PageTree.TopPanel = Ext.extend(Ext.Panel, {
 	 * @return {void}
 	 */
 	addFilterFeature: function() {
-		var topPanelButton = new Ext.Button({
-			id: this.id + '-button-filter',
-			cls: this.id + '-button',
+		var topPanelButton = Ext.create('Ext.button.Button', {
+			id: this.getId() + '-button-filter',
+			cls: this.getId() + '-button',
 			iconCls: TYPO3.Components.PageTree.Sprites.Filter,
 			tooltip: TYPO3.Components.PageTree.LLL.buttonFilter
 		});
 
-		var textField = new Ext.form.TriggerField({
-			id: this.id + '-filter',
+		var textField = Ext.create('Ext.form.field.Trigger', {
+			id: this.getId() + '-filter',
+			border: false,
 			enableKeyEvents: true,
-			triggerClass: TYPO3.Components.PageTree.Sprites.InputClear,
+			labelWidth: 0,
+			triggerCls: TYPO3.Components.PageTree.Sprites.InputClear,
 			value: TYPO3.Components.PageTree.LLL.searchTermInfo,
 
 			listeners: {
 				blur: {
-					scope: this,
-					fn:function(textField) {
+					fn: function (textField) {
 						if (textField.getValue() === '') {
 							textField.setValue(TYPO3.Components.PageTree.LLL.searchTermInfo);
-							textField.addClass(this.id + '-filter-defaultText');
+							textField.inputEl.addCls(this.getId() + '-filter-defaultText');
 						}
-					}
+					},
+					scope: this
 				},
 
 				focus: {
-					scope: this,
-					fn: function(textField) {
+					fn: function (textField) {
 						if (textField.getValue() === TYPO3.Components.PageTree.LLL.searchTermInfo) {
 							textField.setValue('');
-							textField.removeClass(this.id + '-filter-defaultText');
+							textField.inputEl.removeCls(this.getId() + '-filter-defaultText');
 						}
-					}
+					},
+					scope: this
 				},
 
 				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();
-					}
+					fn: function () { this.focus(); }
 				}
 			}
 		});
 
-		this.addButton(topPanelButton, topPanelWidget);
+		textField.setHideTrigger(true);
+		textField.onTriggerClick = Ext.Function.bind(
+			function (textField) {
+				textField.setValue('');
+				this.createFilterTree(textField);
+			},
+			this,
+			[textField]
+		);
+
+		this.addButton(topPanelButton, textField);
 	},
 
 	/**
@@ -370,28 +357,32 @@ TYPO3.Components.PageTree.TopPanel = Ext.extend(Ext.Panel, {
 	 * @return {void}
 	 */
 	createNewNodeToolbar: function() {
-		this.dragZone = new Ext.dd.DragZone(this.getEl(), {
+		this.dragZone = Ext.create('Ext.dd.DragZone', this.getEl(), {
 			ddGroup: this.ownerCt.ddGroup,
 			topPanel: this.ownerCt,
 
 			endDrag: function() {
-				this.topPanel.app.activeTree.dontSetOverClass = false;
+				this.topPanel.app.getTree().dontSetOverClass = false;
 			},
 
-			getDragData: function(event) {
+			getDragData: function (event) {
 				this.proxyElement = document.createElement('div');
-
-				var node = Ext.getCmp(event.getTarget('.x-btn').id);
-				node.shouldCreateNewNode = true;
-
+				var clickedButton = event.getTarget('.x-btn');
+				if (clickedButton) {
+					var node = Ext.getCmp(clickedButton.id);
+				}
+				if (node) {
+					node.shouldCreateNewNode = true;
+				}
 				return {
 					ddel: this.proxyElement,
-					item: node
+					item: node,
+					records: [node]
 				}
 			},
 
 			onInitDrag: function() {
-				this.topPanel.app.activeTree.dontSetOverClass = true;
+				this.topPanel.app.getTree().dontSetOverClass = true;
 				var clickedButton = this.dragData.item;
 				var cls = clickedButton.initialConfig.iconCls;
 
@@ -405,18 +396,18 @@ TYPO3.Components.PageTree.TopPanel = Ext.extend(Ext.Panel, {
 			}
 		});
 
-			// listens on the escape key to stop the dragging
-		(new Ext.KeyMap(document, {
+			// Listens on the escape key to stop the dragging
+		Ext.create('Ext.util.KeyMap', document, {
 			key: Ext.EventObject.ESC,
 			scope: this,
 			buffer: 250,
 			fn: function(event) {
 				if (this.dragZone.dragging) {
-					Ext.dd.DragDropMgr.stopDrag(event);
+					Ext.dd.DragDropManager.stopDrag(event);
 					this.dragZone.onInvalidDrop(event);
 				}
 			}
-		}, 'keydown'));
+		}, 'keydown');
 	},
 
 	/**
@@ -425,11 +416,16 @@ TYPO3.Components.PageTree.TopPanel = Ext.extend(Ext.Panel, {
 	 * @return {void}
 	 */
 	addDragDropNodeInsertionFeature: function() {
-		var newNodeToolbar = new Ext.Toolbar({
-			border: false,
-			id: this.id + '-item-newNode',
-			cls: this.id + '-item',
+		var topPanelButton = Ext.create('Ext.button.Button', {
+			id: this.getId() + '-button-newNode',
+			cls: this.getId() + '-button',
+			iconCls: TYPO3.Components.PageTree.Sprites.NewNode,
+			tooltip: TYPO3.Components.PageTree.LLL.buttonNewNode
+		});
 
+		var newNodeToolbar = Ext.create('Ext.toolbar.Toolbar', {
+			id: this.getId() + '-item-newNode',
+			cls: this.getId() + '-item',
 			listeners: {
 				render: {
 					fn: this.createNewNodeToolbar
@@ -438,20 +434,10 @@ TYPO3.Components.PageTree.TopPanel = Ext.extend(Ext.Panel, {
 		});
 
 		this.dataProvider.getNodeTypes(function(response) {
-			for (var i = 0; i < response.length; ++i) {
-				response[i].template = this.getButtonTemplate();
-				newNodeToolbar.addItem(response[i]);
-			}
+			newNodeToolbar.add(response);
 			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);
 	},
 
@@ -461,9 +447,9 @@ TYPO3.Components.PageTree.TopPanel = Ext.extend(Ext.Panel, {
 	 * @return {void}
 	 */
 	addRefreshTreeFeature: function() {
-		var topPanelButton = new Ext.Button({
-			id: this.id + '-button-refresh',
-			cls: this.id + '-button',
+		var topPanelButton = Ext.create('Ext.button.Button', {
+			id: this.getId() + '-button-refresh',
+			cls: this.getId() + '-button',
 			iconCls: TYPO3.Components.PageTree.Sprites.Refresh,
 			tooltip: TYPO3.Components.PageTree.LLL.buttonRefresh,
 
@@ -471,7 +457,7 @@ TYPO3.Components.PageTree.TopPanel = Ext.extend(Ext.Panel, {
 				click: {
 					scope: this,
 					fn: function() {
-						this.app.activeTree.refreshTree();
+						this.app.getTree().refreshTree();
 					}
 				}
 			}
@@ -480,6 +466,3 @@ TYPO3.Components.PageTree.TopPanel = Ext.extend(Ext.Panel, {
 		this.addButton(topPanelButton);
 	}
 });
-
-// XTYPE Registration
-Ext.reg('TYPO3.Components.PageTree.TopPanel', TYPO3.Components.PageTree.TopPanel);
diff --git a/t3lib/js/extjs/components/pagetree/javascript/tree.js b/t3lib/js/extjs/components/pagetree/javascript/tree.js
index 7319b02472c735c5b349395d1c92b273e4628d0b..fe61c6a8e946c05a169daaacea432fdec7604f6c 100644
--- a/t3lib/js/extjs/components/pagetree/javascript/tree.js
+++ b/t3lib/js/extjs/components/pagetree/javascript/tree.js
@@ -23,43 +23,145 @@
 *
 *  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
+ * @extends Ext.tree.Panel
  * @author Stefan Galinski <stefan.galinski@gmail.com>
  */
-TYPO3.Components.PageTree.Tree = Ext.extend(Ext.tree.TreePanel, {
+Ext.define('TYPO3.Components.PageTree.Model', {
+	extend: 'Ext.data.Model',
+	fields: [{
+		name: 'id',
+		type: 'string',
+		defaultValue: 'root'
+	},{
+		name: 'realId',
+		type: 'string'
+	},{
+		name: 'text',
+		type: 'string'
+	},{
+		name: 'depth',
+		type: 'int'
+	},{
+		name: 'root',
+		type: 'boolean'
+	},{
+		name: 'leaf',
+		type: 'boolean'
+	},{
+		name: 'parentId',
+		type: 'string'
+	},{
+		name: 'isFirst',
+		type: 'boolean'
+	},{
+		name: 'index',
+		type: 'int'
+	},{
+		name: 'isLast',
+		type: 'boolean'
+	},{
+		name: 'isExpandable',
+		type: 'boolean'
+	},{
+		name: 'isInsertedNode',
+		type: 'boolean'
+	},{
+		name: 'nodeData',
+		type: 'object'
+	}],
+	hasMany: {
+		name: 'children',
+		associationKey: 'children',
+		model: 'TYPO3.Components.PageTree.Model'
+	},
+		// Set method for nodeData fields
+	setNodeData: function (field, value) {
+		var nodeData = this.get('nodeData');
+		nodeData[field] = value;
+		this.set('nodeData', Ext.merge(this.get('nodeData'), nodeData));
+	},
+		// Get method for nodeData fields
+	getNodeData: function (field) {
+		return this.get('nodeData')[field];
+	}
+});
+Ext.define('TYPO3.Components.PageTree.Tree', {
+	extend: 'Ext.tree.Panel',
+	/**
+	 * Use extended stateful mixin
+	 *
+	 * @type {Object}
+	 */
+	mixins: {
+		state: 'Ext.ux.state.TreePanel'
+	},
+
+	/**
+	 * View configuration
+	 *
+	 * @type {Object}
+	 */
+	viewConfig: {
+		autoScroll: false,
+		border: false,
+		toggleOnDblClick: false
+	},
+
+	/**
+	 * Columns
+	 *
+	 * @type {TYPO3.Components.PageTree.Column}[]
+	 */
+	columns: [{
+	 		xtype: 'pagetreecolumn',
+	 	 	dataIndex: 'text',
+	 	 	flex: 1,
+	 	 	editor: {
+	 	 		xtype: 'textfield',
+	 	 	 	allowBlank: false
+	 	 	}
+	}],
+
+	/**
+	 * Header
+	 *
+	 * @type {Boolean}
+	 */
+	hideHeaders: true,
+	preventHeader: true,
+
 	/**
 	 * Border
 	 *
 	 * @type {Boolean}
 	 */
+	autoScroll: false,
 	border: false,
 
 	/**
-	 * Indicates if the root node is visible
+	 * Body css
 	 *
-	 * @type {Boolean}
+	 * @type {String}
 	 */
-	rootVisible: false,
+	bodyCls: 'typo3-pagetree',
 
 	/**
-	 * Tree Editor Instance (Inline Edit)
+	 * Indicates if the root node is visible
 	 *
-	 * @type {TYPO3.Components.PageTree.TreeEditor}
+	 * @type {Boolean}
 	 */
-	treeEditor: null,
+	rootVisible: false,
 
 	/**
 	 * Currently Selected Node
 	 *
-	 * @type {Ext.tree.TreeNode}
+	 * @type {TYPO3.Components.PageTree.Model}
 	 */
 	currentSelectedNode: null,
 
@@ -78,18 +180,18 @@ TYPO3.Components.PageTree.Tree = Ext.extend(Ext.tree.TreePanel, {
 	ddGroup: '',
 
 	/**
-	 * Indicates if the label should be editable
+	 * Id of deletionDropZone
 	 *
-	 * @cfg {Boolean}
+	 * @cfg {String}
 	 */
-	labelEdit: true,
+	deletionDropZoneId: '',
 
 	/**
-	 * User Interface Provider
+	 * Indicates if the label should be editable
 	 *
-	 * @cfg {Ext.tree.TreeNodeUI}
+	 * @cfg {Boolean}
 	 */
-	uiProvider: null,
+	labelEdit: true,
 
 	/**
 	 * Data Provider
@@ -103,7 +205,7 @@ TYPO3.Components.PageTree.Tree = Ext.extend(Ext.tree.TreePanel, {
 	 *
 	 * @cfg {Object}
 	 */
-	commandProvider : null,
+	commandProvider: null,
 
 	/**
 	 * Context menu provider
@@ -113,18 +215,18 @@ TYPO3.Components.PageTree.Tree = Ext.extend(Ext.tree.TreePanel, {
 	contextMenuProvider: null,
 
 	/**
-	 * Id of the deletion drop zone if any
+	 * Main applicaton
 	 *
-	 * @cfg {String}
+	 * @cfg {TYPO3.Components.PageTree.App}
 	 */
-	deletionDropZoneId: '',
+	app: null,
 
 	/**
-	 * Main applicaton
+	 * Page Tree Store
 	 *
-	 * @cfg {TYPO3.Components.PageTree.App}
+	 * @type {Object}
 	 */
-	app: null,
+	store: null,
 
 	/**
 	 * Root Node Configuration
@@ -139,17 +241,10 @@ TYPO3.Components.PageTree.Tree = Ext.extend(Ext.tree.TreePanel, {
 		}
 	},
 
-	/**
-	 * Indicator if the control key is pressed
-	 *
-	 * @type {Boolean}
-	 */
-	isControlPressed: false,
-
 	/**
 	 * Context Node
 	 *
-	 * @type {Ext.tree.TreeNode}
+	 * @type {TYPO3.Components.PageTree.Model}
 	 */
 	t3ContextNode: null,
 
@@ -158,68 +253,52 @@ TYPO3.Components.PageTree.Tree = Ext.extend(Ext.tree.TreePanel, {
 	 *
 	 * @type {Object}
 	 */
-	t3ContextInfo: {
+	 t3ContextInfo: {
 		inCopyMode: false,
 		inCutMode: false
 	},
 
 	/**
-	 * Registered clicks for the double click feature
+	 * Number of clicks to ignore for the label edit on dblclick feature
+	 * Will be set to 2 by the tree editor
 	 *
 	 * @type {int}
 	 */
-	clicksRegistered: 0,
+	inhibitClicks: 0,
 
 	/**
-	 * Indicator if the control key was pressed
+	 * Constructor
+	 * Plugins are built by the parent constructor
 	 *
-	 * @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.
+	 * @param {Object} config
+	 * @return {void}
 	 */
-	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;
-			}
+	constructor: function (config) {
+			// Inline label editing feature
+		this.labelEdit = config.labelEdit || this.labelEdit;
+		if (this.labelEdit ) {
+			var plugins = config.plugins || [];
+			config.plugins = plugins.concat(
+				Ext.create('TYPO3.Components.PageTree.TreeEditor', {
+					clicksToEdit: 2,
+					pluginId: 'treeEditor'
+				})
+			);
+		}
+			// Drag & drop feature
+		if (this.enableDD) {
+			config.viewConfig = Ext.applyIf(config.viewConfig || {}, this.viewConfig);
+			var plugins = config.viewConfig.plugins || [];
+			config.viewConfig.plugins = plugins.concat(
+				Ext.create('TYPO3.Components.PageTree.plugin.TreeViewDragDrop', {
+					ddGroup: config.ddGroup,
+					pluginId: 'treeViewDragDrop'
+				})
+			);
+			config.viewConfig.allowCopy = true;
 		}
+			// Call parent constructor
+		this.callParent([config]);
 	},
 
 	/**
@@ -227,28 +306,74 @@ TYPO3.Components.PageTree.Tree = Ext.extend(Ext.tree.TreePanel, {
 	 *
 	 * @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();
-		}
-
+	initComponent: function () {
+			// Add the tree store
+		this.addStore();
+			// Add single click handler that only triggers after a delay to let the double click event
+			// a possibility to be executed (needed for label edit)
+		this.addListener('itemclick', this.onItemSingleClick, null, { delay: 400 });
+			// Init component
+		this.callParent();
+			// Drag & drop feature
 		if (this.enableDD) {
-			this.dragConfig = {ddGroup: this.ddGroup};
-			this.enableDragAndDrop();
+			this.getView().addListener('afterrender', this.enableDragAndDrop, this);
 		}
-
+			// Context menu feature
 		if (this.contextMenuProvider) {
 			this.enableContextMenu();
 		}
-
-		TYPO3.Components.PageTree.Tree.superclass.initComponent.apply(this, arguments);
+	},
+	 
+	/**
+	 * Adds the store to the tree
+	 *
+	 * @return {void}
+	 */
+	addStore: function () {
+		this.store = Ext.data.StoreManager.lookup(this.getId() + 'PageTreeStore');
+		if (!this.store) {
+			this.store = Ext.create('Ext.data.TreeStore', {
+				clearOnLoad: false,
+				listeners: {
+						// Remove nodes and add params to read operation
+					beforeload: {
+						fn: function (store, operation, options) {
+							if (operation.node) {
+								var node = operation.node;
+								node.removeAll();
+								node.commit();
+								operation.params = {
+									nodeId: node.getNodeData('id'),
+									nodeData: node.get('nodeData')
+									
+								};
+							}
+						}
+					},
+						// Restore state on initial load
+					load: {
+						fn: function (store, node, records, successful) {
+							if (successful) {
+								this.restoreState();
+							}
+						},
+						scope: this
+					}
+				},
+				model: 'TYPO3.Components.PageTree.Model',
+				nodeParam: 'nodeId',
+				proxy: {
+					type: 'direct',
+					directFn: this.treeDataProvider.getNextTreeLevel,
+					paramOrder: ['nodeId', 'nodeData'],
+					reader: {
+					    type: 'json'
+					}
+				},
+				root: this.rootNodeConfig,
+				storeId: this.getId() + 'PageTreeStore'
+			});
+		}
 	},
 
 	/**
@@ -258,9 +383,9 @@ TYPO3.Components.PageTree.Tree = Ext.extend(Ext.tree.TreePanel, {
 	 * @param {Object} scope
 	 * return {void}
 	 */
-	refreshTree: function(callback, scope) {
-			// remove readable rootline elements while refreshing
-		if (!this.inRefreshingMode) {
+	refreshTree: function (callback, scope) {
+			// Remove readable rootline elements while refreshing
+		if (!this.store.isLoading()) {
 			var rootlineElements = Ext.select('.x-tree-node-readableRootline');
 			if (rootlineElements) {
 				rootlineElements.each(function(element) {
@@ -268,70 +393,54 @@ TYPO3.Components.PageTree.Tree = Ext.extend(Ext.tree.TreePanel, {
 				});
 			}
 		}
-
-		this.refreshNode(this.root, callback, scope);
+		this.refreshNode(this.getRootNode(), callback, scope);
 	},
 
 	/**
 	 * Refreshes a given node
 	 *
-	 * @param {Ext.tree.TreeNode} node
+	 * @param {TYPO3.Components.PageTree.Model} 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);
+	refreshNode: function (node, callback, scope) {
+		this.store.load({
+			node: node,
+			callback: callback || Ext.emptyFn,
+			scope: scope || this
+		});
 	},
 
 	/**
-	 * Adds a tree loader implementation that uses the directFn feature
+	 * Handles singe click on tree item
 	 *
-	 * return {void}
+	 * return {Boolean}
 	 */
-	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);
-			},
+	onItemSingleClick: function (view, node, item, index, event) {
+		var tree = view.panel;
+			// Check if the tree editor was triggered by dblclick
+			// If so, stop the next two clicks
+		if (tree.inhibitClicks) {
+			--tree.inhibitClicks;
+			event.stopEvent();
+			return false;
+		}
 
-			listeners: {
-				beforeload: function(treeLoader, node) {
-					treeLoader.baseParams.nodeId = node.id;
-					treeLoader.baseParams.attributes = node.attributes.nodeData;
-				}
+		if (tree.commandProvider.singleClick) {
+			tree.commandProvider.singleClick(node, tree);
+		}
+			// Fire the context menu on a single click on the node icon (Beware of drag&drop!)
+		if (!TYPO3.Components.PageTree.Configuration.disableIconLinkToContextmenu
+			|| TYPO3.Components.PageTree.Configuration.disableIconLinkToContextmenu === '0'
+		) {
+			var target = event.getTarget('span.t3-icon-apps-pagetree');
+			if (target) {
+				view.fireEvent('itemcontextmenu', view, node, item, index, event);
+				event.stopEvent();
 			}
-		});
+		}
+		return true;
 	},
 
 	/**
@@ -340,58 +449,33 @@ TYPO3.Components.PageTree.Tree = Ext.extend(Ext.tree.TreePanel, {
 	 * return {void}
 	 */
 	enableContextMenu: function() {
-		this.contextMenu = new TYPO3.Components.PageTree.ContextMenu();
-
-		this.on('contextmenu', function(node, event) {
-			this.openContextMenu(node, event);
+		this.contextMenu = Ext.create('TYPO3.Components.PageTree.ContextMenu', { pageTree: this });
+		this.getView().on('itemcontextmenu', function (view, node, item, index, event) {
+			view.panel.openContextMenu(view, node, item, index, event);
 		});
 	},
 
 	/**
 	 * Open a context menu for the given node
 	 *
-	 * @param {Ext.tree.TreeNode} node
+	 * @param {TYPO3.Components.PageTree.Model} 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());
-
+	openContextMenu: function(view, node, item, index, event) {
+		var tree = view.panel;
+		node.setNodeData('t3ContextInfo', tree.t3ContextInfo);
+		tree.contextMenuProvider.getActionsForNodeArray(
+			node.get('nodeData'),
+			function (configuration) {
+				tree.contextMenu.removeAll();
+				tree.contextMenu.fill(node, tree, configuration);
+				if (tree.contextMenu.items.length) {
+					tree.contextMenu.showAt(event.getXY());
 				}
-			},
-			this
+			}
 		);
-	},
-
-	/**
-	 * Initialize the inline editor for the given tree.
-	 *
-	 * @return {void}
-	 */
-	enableInlineEditor: function() {
-		this.treeEditor = new TYPO3.Components.PageTree.TreeEditor(this);
-	},
-
-	/**
-	 * Triggers the editing of the node if the tree editor is available
-	 *
-	 * @param {Ext.tree.TreeNode} node
-	 * @return {void}
-	 */
-	triggerEdit: function(node) {
-		if (this.treeEditor) {
-			this.treeEditor.triggerEdit(node);
-		}
+		event.stopEvent();
 	},
 
 	/**
@@ -400,208 +484,144 @@ TYPO3.Components.PageTree.Tree = Ext.extend(Ext.tree.TreePanel, {
 	 * 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'));
+		var view = this.getView();
+		var dragZone = view.getPlugin('treeViewDragDrop').dragZone;
+
+			// Show drop zone before drag, otherwise the proxy is never notified
+		dragZone.onBeforeDrag = Ext.Function.bind(this.startDeletionDropZone, view);
+			// Hide the drop zone after the drag completes
+		dragZone.onMouseUp = Ext.Function.bind(this.stopDeletionDropZone, view);
+		dragZone.endDrag = Ext.Function.bind(this.stopDeletionDropZone, view);
+		dragZone.afterInvalidDrop = Ext.Function.bind(this.stopDeletionDropZone, view, [true]);
+
+			// Node is moved
+		this.on('itemmove', this.moveNode, this);
+
+			// New node is created/copied
+		view.on('beforedrop', this.beforeDropNode, this);
+		view.on('drop', this.dropNode, this);
 	},
 
 	/**
-	 * Disables the deletion drop zone if configured
+	 * Enables the deletion drop zone if configured
 	 *
 	 * @return {void}
 	 */
-	stopDd: function() {
-		if (this.deletionDropZoneId) {
-			Ext.getCmp(this.deletionDropZoneId).hide();
-			this.app.doLayout();
-		}
-	},
-
-	/**
-	 * Enables the deletion drop zone if configured. Also it creates the
-	 * shown dd proxy element.
-	 *
-	 * @param {TYPO3.Components.PageTree.Tree} treePanel
-	 * @param {Ext.tree.TreeNode} node
-	 * @return {void}
-	 */
-	initDd: function(treePanel, node) {
-		var nodeHasChildNodes = (node.hasChildNodes() || node.isExpandable());
-		if (this.deletionDropZoneId &&
+	startDeletionDropZone: function (dragData, event) {
+		var view = dragData.view,
+			tree = view.panel,
+			node = view.getRecord(dragData.item),
+			nodeHasChildNodes = (node.hasChildNodes() || node.isExpandable());
+		var tree = this.panel;
+		if (tree.deletionDropZoneId &&
 			(!nodeHasChildNodes ||
 			(nodeHasChildNodes && TYPO3.Components.PageTree.Configuration.canDeleteRecursivly)
 		)) {
-			Ext.getCmp(this.deletionDropZoneId).show();
-			this.app.doLayout();
+			Ext.getCmp(tree.deletionDropZoneId).show();
 		}
-		this.initDDProxyElement();
 	},
 
 	/**
-	 * Adds the copy hint to the proxy element
+	 * Disables the deletion drop zone if configured
 	 *
 	 * @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);
+	stopDeletionDropZone: function (forceStop) {
+		var tree = this.panel;
+		if (tree.deletionDropZoneId && (!this.getPlugin('treeViewDragDrop').dragZone.dragging || forceStop)) {
+			Ext.getCmp(tree.deletionDropZoneId).hide();
+		}
 	},
 
 	/**
-	 * Creates a Fake Node
+	 * Creates a place holder node when a new node is about to be dropped
 	 *
-	 * This must be done to prevent the calling of the moveNode event.
-	 *
-	 * @param {object} dragElement
+	 * @param {HTMLElement node} node
+	 * @param {object} dragData
+	 * @param {TYPO3.Components.PageTree.Model} overNode
+	 * @param {string} dropPosition
+	 * @return {boolean}
 	 */
-	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({
+	beforeDropNode: function (node, dragData, overNode, dropPosition) {
+		if (dragData && dragData.item && dragData.item.shouldCreateNewNode) {
+				// Inserting a new node of the type that was selected in the top panel
+			this.t3ContextInfo.serverNodeType = dragData.item.nodeType;
+			dragData.dropNode = Ext.create('TYPO3.Components.PageTree.Model', {
 				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);
+			dragData.records = [dragData.dropNode];
 		}
-
 		return true;
 	},
 
 	/**
-	 * Differentiate between the copy and insert event
+	 * Handle the copy and insert events
 	 *
-	 * @param {Ext.tree.TreeDropZone} dragElement
+	 * @param {HTMLElement node} node
+	 * @param {object} dragData
+	 * @param {TYPO3.Components.PageTree.Model} overNode
+	 * @param {string} dropPosition
 	 * 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)
+	dropNode: function (node, dragData, overNode, dropPosition) {
+		if (dragData.dropNode) {
+			if (dragData.dropNode.get('isInsertedNode')) {
+				dragData.dropNode.set('isInsertedNode', false);
+				this.insertNode(dragData.dropNode);
+			}
+		} else if (dragData.copy) {
+			this.copyNode(dragData.records[0]);
 		}
 	},
 
 	/**
 	 * 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 {TYPO3.Components.PageTree.Model} movedNode
+	 * @param {TYPO3.Components.PageTree.Model} oldParent
+	 * @param {TYPO3.Components.PageTree.Model} newParent
 	 * @param {int} position
 	 * return {void}
 	 */
-	moveNode: function(tree, movedNode, oldParent, newParent, position) {
-		this.controlKeyPressed = false;
-		tree.t3ContextNode = movedNode;
-
+	moveNode: function (movedNode, oldParent, newParent, position) {
+		this.t3ContextNode = movedNode;
 		if (position === 0) {
-			this.commandProvider.moveNodeToFirstChildOfDestination(newParent, tree);
+			this.commandProvider.moveNodeToFirstChildOfDestination(newParent, this);
 		} else {
 			var previousSiblingNode = newParent.childNodes[position - 1];
-			this.commandProvider.moveNodeAfterDestination(previousSiblingNode, tree);
+			this.commandProvider.moveNodeAfterDestination(previousSiblingNode, this);
 		}
 	},
 
 	/**
 	 * Inserts a node
 	 *
-	 * @param {Ext.tree.TreeNode} movedNode
+	 * @param {TYPO3.Components.PageTree.Model} node
 	 * return {void}
 	 */
-	insertNode: function(movedNode) {
-		this.t3ContextNode = movedNode.parentNode;
-
-		movedNode.disable();
-		if (movedNode.previousSibling) {
-			this.commandProvider.insertNodeAfterDestination(movedNode, this);
+	insertNode: function (node) {
+		this.t3ContextNode = node.parentNode;
+		if (node.previousSibling) {
+			this.commandProvider.insertNodeAfterDestination(node, this);
 		} else {
-			this.commandProvider.insertNodeToFirstChildOfDestination(movedNode, this);
+			this.commandProvider.insertNodeToFirstChildOfDestination(node, this);
 		}
 	},
 
 	/**
 	 * Copies a node
 	 *
-	 * @param {Ext.tree.TreeNode} movedNode
+	 * @param {TYPO3.Components.PageTree.Model} movedNode
 	 * return {void}
 	 */
-	copyNode: function(movedNode) {
-		this.t3ContextNode = movedNode;
-
-		movedNode.disable();
-		if (movedNode.previousSibling) {
-			this.commandProvider.copyNodeAfterDestination(movedNode, this);
+	copyNode: function (node) {
+		this.t3ContextNode = node;
+		if (node.previousSibling) {
+			this.commandProvider.copyNodeAfterDestination(node, this);
 		} else {
-			this.commandProvider.copyNodeToFirstChildOfDestination(movedNode, this);
+			this.commandProvider.copyNodeToFirstChildOfDestination(node, this);
 		}
 	}
 });
-
-// XTYPE Registration
-Ext.reg('TYPO3.Components.PageTree.Tree', TYPO3.Components.PageTree.Tree);
diff --git a/t3lib/js/extjs/components/pagetree/javascript/treedropzone.js b/t3lib/js/extjs/components/pagetree/javascript/treedropzone.js
new file mode 100644
index 0000000000000000000000000000000000000000..2f4888ca9ffc77976915ab8180120f1bd2ac925f
--- /dev/null
+++ b/t3lib/js/extjs/components/pagetree/javascript/treedropzone.js
@@ -0,0 +1,112 @@
+/***************************************************************
+*  Copyright notice
+*
+*  (c) 2011 Stanislas Rolland <typo3@sjbr.ca>
+*  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 TYPO3.Components.PageTree.ViewDropZone
+ *
+ * handleNodeDrop method is modified in order to process copied nodes
+ * 
+ * Based on ExtJS 4.0.7.
+ * Should be reviewed on ExtJS upgrade
+ *
+ * @namespace TYPO3.Components.PageTree
+ * @extends Ext.tree.ViewDropZone
+ * @author Stanislas Rolland <typo3@sjbr.ca>
+ */
+Ext.define('TYPO3.Components.PageTree.ViewDropZone', {
+	extend: 'Ext.tree.ViewDropZone',
+
+	handleNodeDrop: function(data, targetNode, position) {
+		var me = this,
+			view = me.view,
+			parentNode = targetNode.parentNode,
+			store = view.getStore(),
+			recordDomNodes = [],
+			records, i, len,
+			insertionMethod, argList,
+			needTargetExpand,
+			transferData,
+			processDrop;
+
+		if (data.copy) {
+			records = data.records;
+			data.records = [];
+			for (i = 0, len = records.length; i < len; i++) {
+				data.records.push(Ext.apply({}, records[i].data));
+			}
+		}
+
+		me.cancelExpand();
+
+		if (position == 'before') {
+			insertionMethod = parentNode.insertBefore;
+			argList = [null, targetNode];
+			targetNode = parentNode;
+		} else if (position == 'after') {
+			if (targetNode.nextSibling) {
+				insertionMethod = parentNode.insertBefore;
+				argList = [null, targetNode.nextSibling];
+			} else {
+				insertionMethod = parentNode.appendChild;
+				argList = [null];
+			}
+			targetNode = parentNode;
+		} else {
+			if (!targetNode.isExpanded()) {
+				needTargetExpand = true;
+			}
+			insertionMethod = targetNode.appendChild;
+			argList = [null];
+		}
+
+		transferData = function() {
+			var node;
+			for (i = 0, len = data.records.length; i < len; i++) {
+				argList[0] = data.records[i];
+				node = insertionMethod.apply(targetNode, argList);
+					// We need to update the records array in order to process the copied nodes in the drop event handler
+				data.records[i] = node;
+
+				if (Ext.enableFx && me.dropHighlight) {
+					recordDomNodes.push(view.getNode(node));
+				}
+			}
+
+			if (Ext.enableFx && me.dropHighlight) {
+				Ext.Array.forEach(recordDomNodes, function(n) {
+					if (n) {
+						Ext.fly(n.firstChild ? n.firstChild : n).highlight(me.dropHighlightColor);
+					}
+				});
+			}
+		};
+
+		if (needTargetExpand) {
+			targetNode.expand(false, transferData);
+		} else {
+			transferData();
+		}
+	}
+});
\ No newline at end of file
diff --git a/t3lib/js/extjs/components/pagetree/javascript/treeeditor.js b/t3lib/js/extjs/components/pagetree/javascript/treeeditor.js
index 0d12e7d526678b227e3039e4a31f56e3f38e3910..5daa34e2d79ec015ad0316cc427fe8cce03d1b52 100644
--- a/t3lib/js/extjs/components/pagetree/javascript/treeeditor.js
+++ b/t3lib/js/extjs/components/pagetree/javascript/treeeditor.js
@@ -23,8 +23,6 @@
 *
 *  This copyright notice MUST APPEAR in all copies of the script!
 ***************************************************************/
-Ext.namespace('TYPO3.Components.PageTree');
-
 /**
  * @class TYPO3.Components.PageTree.TreeEditor
  *
@@ -32,30 +30,46 @@ Ext.namespace('TYPO3.Components.PageTree');
  * editable label.
  *
  * @namespace TYPO3.Components.PageTree
- * @extends Ext.tree.TreeEditor
+ * @extends Ext.ux.tree.TreeEditing
  * @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: false,
+Ext.define('TYPO3.Components.PageTree.TreeEditor', {
+	extend: 'Ext.grid.plugin.CellEditing',
+	alias: 'plugin.pagetreeeditor',
 
 	/**
-	 * Edit delay
-	 *
-	 * @type {int}
+	 * @override
+	 * @private Collects all information necessary for any subclasses to perform their editing functions.
+	 * @param record
+	 * @param columnHeader
+	 * @returns {Object} The editing context based upon the passed record and column
 	 */
-	editDelay: 250,
+	getEditingContext: function (record, columnHeader) {
+	 	var me = this,
+	 		grid = me.grid,
+	 		store = grid.store,
+	 		colIdx,
+	 		editor,
+	 		originalValue,
+	 		value;
 
-	/**
-	 * Indicates if an underlying shadow should be shown
-	 *
-	 * @type {Boolean}
-	 */
-	shadow: false,
+		if (Ext.isNumber(columnHeader)) {
+			colIdx = columnHeader;
+			columnHeader = grid.headerCt.getHeaderAtIndex(colIdx);
+		} else {
+			colIdx = columnHeader.getIndex();
+		}
+
+		return {
+			column: columnHeader,
+			colIdx: colIdx,
+			field: columnHeader.dataIndex,
+			grid: grid,
+			originalValue: record.getNodeData('editableText'),
+			record: record,
+			tree: grid
+		};
+	},
 
 	/**
 	 * Listeners
@@ -63,80 +77,66 @@ TYPO3.Components.PageTree.TreeEditor = Ext.extend(Ext.tree.TreeEditor, {
 	 * Handles the synchronization between the edited label and the shown label.
 	 */
 	listeners: {
-		beforecomplete: function(node) {
-			this.updatedValue = this.getValue();
-			if (this.updatedValue === '') {
-				this.cancelEdit();
-				return false;
-			}
-			this.setValue(this.editNode.attributes.prefix + Ext.util.Format.htmlEncode(this.updatedValue) + this.editNode.attributes.suffix);
-		},
-
-		complete: {
-			fn: function(node, newValue, oldValue) {
-				if (newValue === oldValue) {
-					this.fireEvent('canceledit', this);
+		beforeedit: {
+			fn: function (editEvent) {
+				var tree = editEvent.tree;
+					// Prevent editing the currently selected node
+					// Prevent editing if the node is not editable
+				if (editEvent.record == tree.currentSelectedNode || !editEvent.record.getNodeData('editable')) {
+					if (tree.currentSelectedNode) {
+						tree.getView().select(tree.currentSelectedNode);
+					}
 					return false;
 				}
-
-				this.editNode.getOwnerTree().commandProvider.saveTitle(node, this.updatedValue, oldValue, this);
+					// Inhibit clicks on the tree while editing
+				tree.inhibitClicks = 2;
 			}
 		},
-
-		startEdit: {
-			fn: function(element, value) {
-				this.field.selectText();
+		validateedit: {
+			fn: function (treeEditor, editEvent) {
+				var editorField = treeEditor.getEditor(editEvent.record, editEvent.column);
+				this.newValue = editorField.getValue();
+				if (this.newValue === '' || this.newValue === editEvent.originalValue) {
+					var tree = editEvent.tree;
+					if (tree.currentSelectedNode) {
+						tree.getView().select(tree.currentSelectedNode);
+					}
+					return false;
+				} else {
+					editorField.setValue(editEvent.record.getNodeData('prefix') + Ext.util.Format.htmlEncode(this.newValue) + editEvent.record.getNodeData('suffix'));
+				}
+				
 			}
 		},
-
-		canceledit: function() {
-			var tree = this.editNode.getOwnerTree();
-			if (tree.currentSelectedNode) {
-				tree.currentSelectedNode.select();
+		edit: {
+			fn: function (treeEditor, editEvent) {
+				var tree = editEvent.tree;
+				tree.commandProvider.saveTitle(editEvent.record, this.newValue, editEvent.originalValue, treeEditor, tree, editEvent.field);
 			}
 		}
 	},
+	cancelEdit: function () {
+		var tree = this.grid;
+		if (tree.currentSelectedNode) {
+			tree.getView().select(tree.currentSelectedNode);
+		}
+		this.callParent(arguments);
+	},
 
 	/**
-	 * Updates the edit node
+	 * Updates the text field
 	 *
-	 * @param {Ext.tree.TreeNode} node
+	 * @param {TYPO3.Components.PageTree.Model} node
 	 * @param {String} editableText
-	 * @param {String} updatedNode
+	 * @param {String} updatedText
+	 * @param {String} dataIndex
+	 * @param {TYPO3.Components.PageTree.Tree} tree
 	 * @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;
-		}
+	updateNodeText: function (record, editableText, updatedText, dataIndex, tree) {
+		record.set(dataIndex, record.getNodeData('prefix') + updatedText + record.getNodeData('suffix'));
+		record.setNodeData('editableText', editableText);
+		record.commit();
+		tree.getView().refresh(record.getId());
 	}
 });
-
-// XTYPE Registration
-Ext.reg('TYPO3.Components.PageTree.TreeEditor', TYPO3.Components.PageTree.TreeEditor);
diff --git a/t3lib/js/extjs/components/pagetree/javascript/treeviewdragdrop.js b/t3lib/js/extjs/components/pagetree/javascript/treeviewdragdrop.js
new file mode 100644
index 0000000000000000000000000000000000000000..b0c5bee20c5fd2d65579c48756e0d8d9ca9e1987
--- /dev/null
+++ b/t3lib/js/extjs/components/pagetree/javascript/treeviewdragdrop.js
@@ -0,0 +1,65 @@
+/***************************************************************
+*  Copyright notice
+*
+*  (c) 2011 Stanislas Rolland <typo3@sjbr.ca>
+*  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 TYPO3.Components.PageTree.plugin.TreeViewDragDrop
+ *
+ * onViewRender method is modified in order to use TYPO3.Components.PageTree.ViewDropZone
+ *
+ * @namespace TYPO3.Components.PageTree
+ * @extends Ext.tree.plugin.TreeViewDragDrop
+ * @author Stanislas Rolland <typo3@sjbr.ca>
+ */
+Ext.define('TYPO3.Components.PageTree.plugin.TreeViewDragDrop', {
+    extend: 'Ext.tree.plugin.TreeViewDragDrop',
+    alias: 'plugin.pagetreeviewdragdrop',
+
+    onViewRender: function(view) {
+        var me = this;
+
+        if (me.enableDrag) {
+            me.dragZone = Ext.create('Ext.tree.ViewDragZone', {
+                view: view,
+                ddGroup: me.dragGroup || me.ddGroup,
+                dragText: me.dragText,
+                repairHighlightColor: me.nodeHighlightColor,
+                repairHighlight: me.nodeHighlightOnRepair
+            });
+        }
+
+        if (me.enableDrop) {
+            me.dropZone = Ext.create('TYPO3.Components.PageTree.ViewDropZone', {
+                view: view,
+                ddGroup: me.dropGroup || me.ddGroup,
+                allowContainerDrops: me.allowContainerDrops,
+                appendOnly: me.appendOnly,
+                allowParentInserts: me.allowParentInserts,
+                expandDelay: me.expandDelay,
+                dropHighlightColor: me.nodeHighlightColor,
+                dropHighlight: me.nodeHighlightOnDrop
+            });
+        }
+    }
+});
\ No newline at end of file
diff --git a/t3lib/js/extjs/tree/tree.js b/t3lib/js/extjs/tree/tree.js
index f0cad3962071883b4f1ad80753c0d669723cca24..bbd262485b33cf8b8a1eb74c06bb3f87a23ecf1e 100644
--- a/t3lib/js/extjs/tree/tree.js
+++ b/t3lib/js/extjs/tree/tree.js
@@ -23,60 +23,64 @@
  *
  *  This copyright notice MUST APPEAR in all copies of the script!
  ***************************************************************/
-
-Ext.ns('TYPO3.Components', 'TYPO3.Components.Tree');
-
 /**
  * TYPO3window - General TYPO3 tree component
  */
+Ext.ns('TYPO3.Components.Tree');
 
 TYPO3.Components.Tree = {};
 TYPO3.Components.Tree.StandardTreeItemData = [];
 
-TYPO3.Components.Tree.StandardTree = function(config) {
-	var conf = Ext.apply({
-		header: false,
-		width: 280,
-		rootVisible: false,
-		useArrows: false,
-		lines: true,
-		autoScroll: true,
-		containerScroll: true,
-		exclusiveSelectedKey: null,
-		stateful: true,
-		filterOptionStartsWith: true,
-		countSelectedNodes: 0,
-		loader: new Ext.tree.TreeLoader({
-			preloadChildren: true,
-			clearOnLoad: false
-		}),
-		root: new Ext.tree.AsyncTreeNode({
-			text: TYPO3.l10n.localize('tcatree'),
-			id: 'root',
-			expanded: true,
-			children: TYPO3.Components.Tree.StandardTreeItemData[config.id]
-		}),
-		collapseFirst: false,
-		listeners: {
-			'checkchange': function(checkedNode, checked) {
-				if (Ext.isFunction(this.checkChangeHandler)) {
-					this.checkChangeHandler.call(this, checkedNode, checked);
-				}
-			},
-			scope: this
-		}
-	}, config);
-	TYPO3.Components.Tree.StandardTree.superclass.constructor.call(this, conf);
-};
-
-
-Ext.extend(TYPO3.Components.Tree.StandardTree, Ext.tree.TreePanel, {
-
+Ext.define('TYPO3.Components.Tree.StandardTree', {
+	extend: 'Ext.tree.Panel',
+	
+	constructor: function(config) {
+		var conf = Ext.apply({
+			header: false,
+			width: 280,
+			rootVisible: false,
+			useArrows: false,
+			lines: true,
+			autoScroll: true,
+			containerScroll: true,
+			exclusiveSelectedKey: null,
+			stateful: true,
+			filterOptionStartsWith: true,
+			countSelectedNodes: 0,
+				// Needs to be migrated to ExtJS 4
+			loader: new Ext.tree.TreeLoader({
+				preloadChildren: true,
+				clearOnLoad: false
+			}),
+			root: new Ext.tree.AsyncTreeNode({
+				text: TYPO3.l10n.localize('tcatree'),
+				id: 'root',
+				expanded: true,
+				children: TYPO3.Components.Tree.StandardTreeItemData[config.id]
+			}),
+			collapseFirst: false,
+			listeners: {
+				'checkchange': function(checkedNode, checked) {
+					if (Ext.isFunction(this.checkChangeHandler)) {
+						this.checkChangeHandler.call(this, checkedNode, checked);
+					}
+				},
+				scope: this
+			}
+		}, config);
+		this.callParent([conf]);
+	},
 	initComponent: function() {
-		Ext.apply(this, {
-			tbar: this.initialConfig.showHeader ? TYPO3.Components.Tree.Toolbar([], this) : null
-		});
-		TYPO3.Components.Tree.StandardTree.superclass.initComponent.call(this);
+		if (this.initialConfig.showHeader) {
+			Ext.apply(this, {
+				dockedItems: [{
+					xtype: 'toolbar',
+					dock: 'top',
+					items: TYPO3.Components.Tree.Toolbar([], this)
+				}]
+			});
+		}
+		this.callParent(arguments);
 	},
 	filterTree: function(filterText) {
 		var text = filterText.getValue();
@@ -139,7 +143,7 @@ TYPO3.Components.Tree.Toolbar = function(items, scope) {
 				]
 			}
 		},
-		new Ext.form.TextField({
+		Ext.create('Ext.form.field.Text', {
 			width: 150,
 			emptyText: TYPO3.l10n.localize('tcatree.findItem'),
 			enableKeyEvents: true,
diff --git a/t3lib/tree/class.t3lib_tree_abstracttree.php b/t3lib/tree/class.t3lib_tree_abstracttree.php
index cda092584e1993f431ccdf0eb20bccfde018190e..5ba1ae315e535bf86c182c76f46b4cc768644d70 100644
--- a/t3lib/tree/class.t3lib_tree_abstracttree.php
+++ b/t3lib/tree/class.t3lib_tree_abstracttree.php
@@ -63,7 +63,7 @@ abstract class t3lib_tree_AbstractTree {
 	}
 
 	/**
-	 * @param t3lib_tree_renderer_Abstract $dataProvider
+	 * @param t3lib_tree_renderer_Abstract $nodeRenderer
 	 * @return void
 	 */
 	public function setNodeRenderer(t3lib_tree_renderer_Abstract $nodeRenderer) {
@@ -83,6 +83,15 @@ abstract class t3lib_tree_AbstractTree {
 	 * @return t3lib_tree_Node
 	 */
 	abstract public function getRoot();
+
+	/**
+	 * @param mixed $search
+	 * @return t3lib_tree_Node
+	 */
+	public function find($search) {
+		return $this->getRoot()->find($search);
+	}
+
 }
 
 ?>
\ No newline at end of file
diff --git a/t3lib/tree/class.t3lib_tree_node.php b/t3lib/tree/class.t3lib_tree_node.php
index dd098882ecb3121dd4783326f2abe88349bc45d7..319307ccba22baec40ff4c221d11cc392f07e206 100644
--- a/t3lib/tree/class.t3lib_tree_node.php
+++ b/t3lib/tree/class.t3lib_tree_node.php
@@ -62,7 +62,6 @@ class t3lib_tree_Node implements t3lib_tree_ComparableNode, Serializable {
 	 * This is useful for the deserialization.
 	 *
 	 * @param array $data
-	 * @return void
 	 */
 	public function __construct(array $data = array()) {
 		if (count($data)) {
@@ -107,7 +106,7 @@ class t3lib_tree_Node implements t3lib_tree_ComparableNode, Serializable {
 	 * @return boolean
 	 */
 	public function hasChildNodes() {
-		if ($this->childNodes !== NULL) {
+		if ($this->childNodes != NULL && $this->childNodes->count() > 0) {
 			return TRUE;
 		}
 
@@ -214,7 +213,7 @@ class t3lib_tree_Node implements t3lib_tree_ComparableNode, Serializable {
 	 * @param array $data
 	 * @return void
 	 */
-	public function dataFromArray($data) {
+	public function dataFromArray(array $data) {
 		$this->setId($data['id']);
 
 		if (isset($data['parentNode']) && $data['parentNode'] !== '') {
@@ -255,6 +254,43 @@ class t3lib_tree_Node implements t3lib_tree_ComparableNode, Serializable {
 		}
 		$this->dataFromArray($arrayRepresentation);
 	}
+
+	/**
+	 * searches the tree to find an node
+	 *
+	 * @param mixed $search
+	 * @return t3lib_tree_Node
+	 */
+	public function find($search) {
+		$result = NULL;
+
+		if($this->getId() == $search) {
+			$result = $this;
+		} elseif($this->hasChildNodes() && $this->getChildNodes() != NULL) {
+			foreach ($this->getChildNodes() AS $childNode) {
+				$result = $childNode->find($search);
+				if ($result != NULL) {
+					break;
+				}
+			}
+		}
+
+		return $result;
+	}
+
+	public function getLevel() {
+		if ($this->getParentNode() == NULL) {
+			return 0;
+		} else {
+			$i = 1;
+			$node = $this->getParentNode();
+			while ($node != NULL) {
+				$node = $node->getParentNode();
+				$i++;
+			}
+			return $i;
+		}
+	}
 }
 
 ?>
\ No newline at end of file
diff --git a/t3lib/tree/class.t3lib_tree_nodecollection.php b/t3lib/tree/class.t3lib_tree_nodecollection.php
index 266f11ee98d30b19ac98933992077fe686390f04..e1a9293a452fa15d733f6777ccdfe3f57d0e7013 100644
--- a/t3lib/tree/class.t3lib_tree_nodecollection.php
+++ b/t3lib/tree/class.t3lib_tree_nodecollection.php
@@ -62,7 +62,9 @@ class t3lib_tree_NodeCollection extends ArrayObject {
 	 *
 	 * @noapi
 	 * @see t3lib_tree_Node::compareTo
-	 * @return void
+	 * @param t3lib_tree_Node $node
+	 * @param t3lib_tree_Node $otherNode
+	 * @return int
 	 */
 	public function nodeCompare(t3lib_tree_Node $node, t3lib_tree_Node $otherNode) {
 		return $node->compareTo($otherNode);
diff --git a/t3lib/tree/class.t3lib_tree_representationnode.php b/t3lib/tree/class.t3lib_tree_representationnode.php
index 8a9482a393547d87ed54adfa248c535a64c815dd..4c64a733ad1ead5fd1439334e51aa08ba6c604ef 100644
--- a/t3lib/tree/class.t3lib_tree_representationnode.php
+++ b/t3lib/tree/class.t3lib_tree_representationnode.php
@@ -32,6 +32,7 @@
  * @author Steffen Ritter <info@steffen-ritter.net>
  * @package TYPO3
  * @subpackage t3lib
+ * @deprecated Not needed anymore as of 4.7, will be removed on 4.9
  */
 class t3lib_tree_RepresentationNode extends t3lib_tree_Node {
 	/**
@@ -69,6 +70,10 @@ class t3lib_tree_RepresentationNode extends t3lib_tree_Node {
 	 */
 	protected $callbackAction = '';
 
+	public function __construct() {
+		t3lib_div::deprecationLog("The Class t3lib_tree_RepresentationNode is deprecated as of TYPO3 4.7, will be removed in 4.9");
+	}
+
 	/**
 	 * @param string $class
 	 * @return void
diff --git a/t3lib/tree/extjs/class.t3lib_tree_extjs_abstractextjstree.php b/t3lib/tree/extjs/class.t3lib_tree_extjs_abstractextjstree.php
new file mode 100644
index 0000000000000000000000000000000000000000..b7762907bc2372b586ac38a30c6ad60ffdb5e6a0
--- /dev/null
+++ b/t3lib/tree/extjs/class.t3lib_tree_extjs_abstractextjstree.php
@@ -0,0 +1,48 @@
+<?php
+/***************************************************************
+ *  Copyright notice
+ *
+ *  (c) 2010-2011 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 ExtJS tree based on ExtDirect
+ *
+ * @author Stefan Galinski <stefan.galinski@gmail.com>
+ * @package TYPO3
+ * @subpackage t3lib
+ */
+abstract class t3lib_tree_ExtJs_AbstractExtJsTree extends t3lib_tree_AbstractTree {
+
+	/**
+	 * Fetches the next tree level
+	 *
+	 * @abstract
+	 * @param int $nodeId
+	 * @param stdClass $nodeData
+	 * @return array
+	 */
+	abstract public function getNextTreeLevel($nodeId, $nodeData);
+}
+
+?>
\ No newline at end of file
diff --git a/t3lib/tree/extdirect/class.t3lib_tree_extdirect_abstractextjstree.php b/t3lib/tree/extjs/class.t3lib_tree_extjs_abstractstatefulextjstree.php
similarity index 83%
rename from t3lib/tree/extdirect/class.t3lib_tree_extdirect_abstractextjstree.php
rename to t3lib/tree/extjs/class.t3lib_tree_extjs_abstractstatefulextjstree.php
index 8dcfe320b41001893cf2089b6cbc5e67657f49e3..6ac45d21d8bb46daad4847abc2fcf459d3c22e9f 100644
--- a/t3lib/tree/extdirect/class.t3lib_tree_extdirect_abstractextjstree.php
+++ b/t3lib/tree/extjs/class.t3lib_tree_extjs_abstractstatefulextjstree.php
@@ -27,12 +27,13 @@
 
 /**
  * Abstract ExtJS tree based on ExtDirect
+ * extends with StateProvider
  *
- * @author Stefan Galinski <stefan.galinski@gmail.com>
+ * @author Steffen Ritter
  * @package TYPO3
  * @subpackage t3lib
  */
-abstract class t3lib_tree_ExtDirect_AbstractExtJsTree extends t3lib_tree_AbstractTree {
+abstract class t3lib_tree_ExtJs_AbstractStatefulExtJsTree extends t3lib_tree_ExtJs_AbstractExtJsTree {
 
 	/**
 	 * State Provider
@@ -56,15 +57,6 @@ abstract class t3lib_tree_ExtDirect_AbstractExtJsTree extends t3lib_tree_Abstrac
 		return $this->stateProvider;
 	}
 
-	/**
-	 * Fetches the next tree level
-	 *
-	 * @abstract
-	 * @param int $nodeId
-	 * @param stdClass $nodeData
-	 * @return array
-	 */
-	abstract public function getNextTreeLevel($nodeId, $nodeData);
 }
 
 ?>
\ No newline at end of file
diff --git a/t3lib/tree/extjs/class.t3lib_tree_extjs_node.php b/t3lib/tree/extjs/class.t3lib_tree_extjs_node.php
new file mode 100644
index 0000000000000000000000000000000000000000..517f306611cb2164196bdfae0f07b59e0c608155
--- /dev/null
+++ b/t3lib/tree/extjs/class.t3lib_tree_extjs_node.php
@@ -0,0 +1,590 @@
+<?php
+/***************************************************************
+ *  Copyright notice
+ *
+ *  (c) 2010-2011 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_ExtJs_Node extends t3lib_tree_Node implements t3lib_tree_RenderableNode {
+
+	/**
+	 * Indicator if the node is allowDrag
+	 *
+	 * @var bool
+	 */
+	protected $allowDrag = TRUE;
+
+	/**
+	 * Indicator if the node is allowed as a drop target
+	 *
+	 * @var bool
+	 */
+	protected $allowDrop = TRUE;
+
+	/**
+	 * Indicator if the noded is checked
+	 * three-state: TRUE|FALSE|NULL
+	 * NULL won't show a checkbox
+	 *
+	 * @var boolean|NULL
+	 */
+	protected $checked = NULL;
+
+	/**
+	 * CSS Class
+	 *
+	 * @var string
+	 */
+	protected $cls = '';
+
+	/**
+	 * The number of parents this node has. ...
+	 *
+	 * @var int
+	 */
+	protected $depth;
+
+	/**
+	 * Indicator if the node can be expanded
+	 *
+	 * @var bool
+	 */
+	protected $expandable = TRUE;
+
+	/**
+	 * Indicator if the node is expanded
+	 *
+	 * @var bool
+	 */
+	protected $expanded = FALSE;
+
+	/**
+	 * An URL for a link that's created when this config is specified.
+	 *
+	 * @var string|NULL
+	 */
+	protected $href = NULL;
+
+	/**
+	 * Target for link in $href
+	 *
+	 * @var string
+	 */
+	protected $hrefTarget = '';
+
+	/**
+	 * URL for this node's icon file
+	 *
+	 * @var string
+	 */
+	protected $icon;
+
+	/**
+	 * URL for this node's icon css class
+	 *
+	 * @var string
+	 */
+	protected $iconCls;
+
+
+	/**
+	 * The position of the node inside its parents
+	 * starting from 0
+	 *
+	 * @var int
+	 */
+	protected $index;
+
+
+	/**
+	 * True if this is the first node.
+	 *
+	 * @var boolean
+	 */
+	protected $isFirst;
+
+	/**
+	 * True if this is the last node
+	 */
+	protected $isLast;
+
+	/**
+	 * Leaf Node Indicator
+	 *
+	 * @var bool
+	 */
+	protected $leaf = TRUE;
+
+	/**
+	 * Quick Tip
+	 *
+	 * @var string
+	 */
+	protected $qtip = '';
+
+	/**
+	 * Quick Tip title
+	 *
+	 * @var string
+	 */
+	protected $qtitle = '';
+
+	/**
+	 * is root node?
+	 *
+	 * @var boolean
+	 */
+	protected $root = FALSE;
+
+	/**
+	 * Label
+	 *
+	 * @var string
+	 */
+	protected $text = '';
+
+	/**
+	 * 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 allowDrag indicator
+	 *
+	 * @param bool $draggable
+	 * @return void
+	 */
+	public function setAllowDrag($draggable) {
+		$this->allowDrag = ($draggable == TRUE);
+	}
+
+	/**
+	 * Returns the allowDrag indicator
+	 *
+	 * @return bool
+	 */
+	public function isDraggable() {
+		return $this->allowDrag;
+	}
+
+	/**
+	 * Sets the indicator if the node can be a drop target
+	 *
+	 * @param bool $isDropTarget
+	 * @return void
+	 */
+	public function setAllowDrop($isDropTarget) {
+		$this->allowDrop = ($isDropTarget == TRUE);
+	}
+
+	/**
+	 * Returns the indicator if the node is a drop target
+	 *
+	 * @return bool
+	 */
+	public function allowDrop() {
+		return $this->allowDrop;
+	}
+
+	/**
+	 * Sets the label of the node with the source field and the prefix
+	 *
+	 * @param string $text
+	 * @return void
+	 */
+	public function setText($text) {
+		$this->text = $text;
+	}
+
+	/**
+	 * Returns the label
+	 *
+	 * @return string
+	 */
+	public function getText() {
+		return $this->text;
+	}
+
+	/**
+	 * 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 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);
+		}
+	}
+
+	/**
+	 * Returns the node in an array representation that can be used for serialization
+	 *
+	 * @param bool $addChildNodes
+	 * @return array
+	 */
+	public function toArray($addChildNodes = TRUE) {
+		$arrayRepresentation = array(
+			'serializeClassName' => get_class($this),
+			'allowDrag' => $this->isDraggable(),
+			'allowDrop' => $this->allowDrop(),
+			'checked'	=> $this->getChecked(),
+			'cls' => $this->getCls(),
+			'depth' => $this->getDepth(),
+			'expandable' => $this->isExpandable(),
+			'expanded' => $this->isExpanded(),
+			'href' => $this->getHref(),
+			'hrefTarget' => $this->getHrefTarget(),
+			'id' => $this->getId(),
+			'icon' => $this->getIcon(),
+			'iconCls' => $this->getIconCls(),
+			'index' => $this->getIndex(),
+			'isFirst' => $this->getIsFirst(),
+			'isLast' => $this->getIsLast(),
+			'parentId' => (!$this->getRoot() && $this->getParentNode() ? $this->getParentNode()->getId() : ''),
+			'qtip' => $this->getQTip(),
+			'qtitle' => $this->getQtitle(),
+			'root' => $this->getRoot(),
+			'text' => $this->getText(),
+		);
+
+			// do not provide config if empty
+		if (trim($this->href) == '') {
+			unset($arrayRepresentation['href']);
+			unset($arrayRepresentation['hrefTarget']);
+		}
+
+			// only added check option if checkbox should be shown
+		if($this->getChecked() == NULL) {
+			unset($arrayRepresentation['checked']);
+		}
+			// 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() && $addChildNodes) {
+			$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->setText($data['label']);
+		$this->setCls($data['cls']);
+		$this->setQTip($data['qtip']);
+		$this->setExpanded($data['expanded']);
+		$this->setExpandable($data['expandable']);
+		$this->setAllowDrag($data['allowDrag']);
+		$this->setAllowDrop($data['isTarget']);
+		$this->setChecked(isset($data['checked']) ? (bool)$data['checked'] : NULL);
+
+		// only set the leaf attribute if it's applied
+		// otherwise you cannot insert nodes into this one
+		if (isset($data['leaf'])) {
+			$this->setLeaf(FALSE);
+		}
+	}
+
+	/**
+	 * @param bool|NULL $checked
+	 */
+	public function setChecked($checked) {
+		$this->checked = $checked;
+	}
+
+	/**
+	 * @return bool|NULL
+	 */
+	public function getChecked() {
+		return $this->checked;
+	}
+
+	/**
+	 * @param int $depth
+	 */
+	public function setDepth($depth) {
+		$this->depth = $depth;
+	}
+
+	/**
+	 * @return int
+	 */
+	public function getDepth() {
+		return $this->depth;
+	}
+
+	/**
+	 * @param NULL|string $href
+	 */
+	public function setHref($href) {
+		$this->href = $href;
+	}
+
+	/**
+	 * @return NULL|string
+	 */
+	public function getHref() {
+		return $this->href;
+	}
+
+	/**
+	 * @param string $hrefTarget
+	 */
+	public function setHrefTarget($hrefTarget) {
+		$this->hrefTarget = $hrefTarget;
+	}
+
+	/**
+	 * @return string
+	 */
+	public function getHrefTarget() {
+		return $this->hrefTarget;
+	}
+
+	/**
+	 * @param string $icon
+	 */
+	public function setIcon($icon) {
+		$this->icon = $icon;
+	}
+
+	/**
+	 * @return string
+	 */
+	public function getIcon() {
+		return $this->icon;
+	}
+
+	/**
+	 * @param string $iconCls
+	 */
+	public function setIconCls($iconCls) {
+		$this->iconCls = $iconCls;
+	}
+
+	/**
+	 * @return string
+	 */
+	public function getIconCls() {
+		return $this->iconCls;
+	}
+
+	/**
+	 * @param int $index
+	 */
+	public function setIndex($index) {
+		$this->index = $index;
+	}
+
+	/**
+	 * @return int
+	 */
+	public function getIndex() {
+		return $this->index;
+	}
+
+	/**
+	 * @param boolean $isFirst
+	 */
+	public function setIsFirst($isFirst) {
+		$this->isFirst = $isFirst;
+	}
+
+	/**
+	 * @return boolean
+	 */
+	public function getIsFirst() {
+		return $this->isFirst;
+	}
+
+	public function setIsLast($isLast) {
+		$this->isLast = $isLast;
+	}
+
+	public function getIsLast() {
+		return $this->isLast;
+	}
+
+
+	/**
+	 * @param string $qtitle
+	 */
+	public function setQtitle($qtitle) {
+		$this->qtitle = $qtitle;
+	}
+
+	/**
+	 * @return string
+	 */
+	public function getQtitle() {
+		return $this->qtitle;
+	}
+
+	/**
+	 * @param boolean $root
+	 */
+	public function setRoot($root) {
+		$this->root = $root;
+	}
+
+	/**
+	 * @return boolean
+	 */
+	public function getRoot() {
+		return $this->root;
+	}
+
+	/**
+	 * returns a string representation
+	 *
+	 * @return string
+	 */
+	public function toString() {
+		return $this->getText();
+	}
+}
+
+if (defined('TYPO3_MODE') && isset($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['t3lib/tree/extjs/class.t3lib_tree_extjs_node.php'])) {
+	include_once($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['t3lib/tree/extjs/class.t3lib_tree_extjs_node.php']);
+}
+
+?>
\ No newline at end of file
diff --git a/t3lib/tree/interfaces/interface.t3lib_tree_comparablenode.php b/t3lib/tree/interfaces/interface.t3lib_tree_comparablenode.php
new file mode 100644
index 0000000000000000000000000000000000000000..ed7c0932dc50dc3ccad4babc58fd7c1e15403a54
--- /dev/null
+++ b/t3lib/tree/interfaces/interface.t3lib_tree_comparablenode.php
@@ -0,0 +1,69 @@
+<?php
+/***************************************************************
+ *  Copyright notice
+ *
+ *  (c) 2010-2011 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!
+ ***************************************************************/
+
+/**
+ * Interface that defines the comparison of nodes
+ *
+ * @author Stefan Galinski <stefan.galinski@gmail.com>
+ * @package TYPO3
+ * @subpackage t3lib
+ */
+interface t3lib_tree_ComparableNode {
+	/**
+	 * Compare Node against another one
+	 *
+	 * Returns:
+	 * 1 if the current node is greater than the $other,
+	 * -1 if $other is greater than the current node and
+	 * 0 if the nodes are equal
+	 *
+	 * <strong>Example</strong>
+	 * <pre>
+	 *	 if ($this->sortValue > $other->sortValue) {
+	 *		return 1;
+	 *	} elseif ($this->sortValue < $other->sortValue) {
+	 *		return -1;
+	 *	} else {
+	 *		return 0;
+	 *	}
+	 * </pre>
+	 *
+	 * @param t3lib_tree_Node $other
+	 * @return integer see description
+	 */
+	public function compareTo($other);
+
+	/**
+	 * Compares a node if it's identical to another node by the id property.
+	 *
+	 * @param t3lib_tree_Node $other
+	 * @return boolean
+	 */
+	public function equals(t3lib_tree_Node $other);
+
+}
+?>
\ No newline at end of file
diff --git a/t3lib/tree/interfaces/interface.t3lib_tree_draggableanddropable.php b/t3lib/tree/interfaces/interface.t3lib_tree_draggableanddropable.php
new file mode 100644
index 0000000000000000000000000000000000000000..2bdf9cdd4af88778e25059d519f0bf85b79ad4a7
--- /dev/null
+++ b/t3lib/tree/interfaces/interface.t3lib_tree_draggableanddropable.php
@@ -0,0 +1,75 @@
+<?php
+/***************************************************************
+ *  Copyright notice
+ *
+ *  (c) 2010-2011 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!
+ ***************************************************************/
+
+/**
+ * Describes necessary methods if the nodes are allowDrag and dropable
+ * within the tree.
+ *
+ * @author Stefan Galinski <stefan.galinski@gmail.com>
+ * @author Steffen Ritter <info@steffen-ritter.net>
+ * @package TYPO3
+ * @subpackage t3lib
+ */
+interface t3lib_tree_DraggableAndDropable {
+	/**
+	 * Moves given node inside a destination node
+	 *
+	 * @param t3lib_tree_Node $node
+	 * @param t3lib_tree_Node $destination
+	 * @return void
+	 */
+	public function moveNodeInDestinationNode($node, $destination);
+
+	/**
+	 * Moves given node after a destination node
+	 *
+	 * @param t3lib_tree_Node $node
+	 * @param t3lib_tree_Node $destination
+	 * @return void
+	 */
+	public function moveNodeAfterDestinationNode($node, $destination);
+
+	/**
+	 * Copies given node inside a destination node
+	 *
+	 * @param t3lib_tree_Node $node
+	 * @param t3lib_tree_Node $destination
+	 * @return void
+	 */
+	public function copyNodeInDestinationNode($node, $destination);
+
+	/**
+	 * Copies given node after a destination node
+	 *
+	 * @param t3lib_tree_Node $node
+	 * @param t3lib_tree_Node $destination
+	 * @return void
+	 */
+	public function copyNodeAfterDestinationNode($node, $destination);
+
+}
+?>
\ No newline at end of file
diff --git a/t3lib/tree/interfaces/interface.t3lib_tree_labeleditable.php b/t3lib/tree/interfaces/interface.t3lib_tree_labeleditable.php
new file mode 100644
index 0000000000000000000000000000000000000000..52f7ce8382c15204ff0fcde1b773289fdfdd7d42
--- /dev/null
+++ b/t3lib/tree/interfaces/interface.t3lib_tree_labeleditable.php
@@ -0,0 +1,46 @@
+<?php
+/***************************************************************
+ *  Copyright notice
+ *
+ *  (c) 2010-2011 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!
+ ***************************************************************/
+
+/**
+ * Describes necessary methods if the node label should be editable
+ * within the tree.
+ *
+ * @author Stefan Galinski <stefan.galinski@gmail.com>
+ * @author Steffen Ritter <info@steffen-ritter.net>
+ * @package TYPO3
+ * @subpackage t3lib
+ */
+interface t3lib_tree_LabelEditable {
+	/**
+	 * Sets the new label
+	 *
+	 * @param string $label
+	 * @return void
+	 */
+	public function setLabel($label);
+}
+?>
\ No newline at end of file
diff --git a/t3lib/tree/interfaces/interface.t3lib_tree_recordbasednode.php b/t3lib/tree/interfaces/interface.t3lib_tree_recordbasednode.php
new file mode 100644
index 0000000000000000000000000000000000000000..d4268b78598b9b88b96d9072a888248d403328d4
--- /dev/null
+++ b/t3lib/tree/interfaces/interface.t3lib_tree_recordbasednode.php
@@ -0,0 +1,83 @@
+<?php
+/***************************************************************
+ *  Copyright notice
+ *
+ *  (c) 2010-2011 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!
+ ***************************************************************/
+
+/**
+ * Interface that defines the nodes based on records
+ *
+ * @author Steffen Ritter <info@steffen-ritter.net>
+ * @package TYPO3
+ * @subpackage t3lib
+ */
+interface t3lib_tree_RecordBasedNode {
+
+	/**
+	 * Returns the source field of the label
+	 *
+	 * @return string
+	 */
+	public function getTextSourceField();
+
+	/**
+	 * set the source field of the label
+	 *
+	 * @param string $field
+	 * @return void
+	 */
+	public function setTextSourceField($field);
+
+	/**
+	 * Sets the database record array
+	 *
+	 * @param array $record
+	 * @return void
+	 */
+	public function setRecord($record);
+
+	/**
+	 * Returns the database record array
+	 *
+	 * @return array
+	 */
+	public function getRecord();
+
+	/**
+	 * Returns the table of the record data
+	 *
+	 * @return string
+	 */
+	public function getSourceTable();
+
+	/**
+	 * sets the Table of record source data
+	 *
+	 * @param string $table
+	 * @return void
+	 */
+	public function setSourceTable($table);
+
+}
+?>
diff --git a/t3lib/tree/interfaces/interface.t3lib_tree_renderablenode.php b/t3lib/tree/interfaces/interface.t3lib_tree_renderablenode.php
new file mode 100644
index 0000000000000000000000000000000000000000..1c7ba3e166705371d277aea8ab2969d5fc9a3004
--- /dev/null
+++ b/t3lib/tree/interfaces/interface.t3lib_tree_renderablenode.php
@@ -0,0 +1,50 @@
+<?php
+/***************************************************************
+ *  Copyright notice
+ *
+ *  (c) 2010-2011 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!
+ ***************************************************************/
+
+/**
+ * Interface that defines the to be rendered
+ *
+ * @author Steffen Ritter <info@steffen-ritter.net>
+ * @package TYPO3
+ * @subpackage t3lib
+ */
+interface t3lib_tree_RenderableNode {
+	/**
+	 * returns a string representation
+	 *
+	 * @return string
+	 */
+	public function toString();
+
+	/**
+	 * returns an array representation of an node
+	 *
+	 * @return array
+	 */
+	public function toArray();
+}
+?>
diff --git a/t3lib/tree/extdirect/class.t3lib_tree_extdirect_node.php b/t3lib/tree/navigationtree/class.t3lib_tree_navigationtree_node.php
similarity index 65%
rename from t3lib/tree/extdirect/class.t3lib_tree_extdirect_node.php
rename to t3lib/tree/navigationtree/class.t3lib_tree_navigationtree_node.php
index 625ad0028aac54243f09c9bbc9c5f66cd012d169..678aaa62493c6bd7517d3971bba5c35f183b34f1 100644
--- a/t3lib/tree/extdirect/class.t3lib_tree_extdirect_node.php
+++ b/t3lib/tree/navigationtree/class.t3lib_tree_navigationtree_node.php
@@ -26,68 +26,37 @@
 ***************************************************************/
 
 /**
- * Node for the usage with ExtDirect and ExtJS
+ * Extends the ExtJS-Tree Nodes with custom features implemented for the TYPO3 Navigation Panel
  *
- * @author Stefan Galinski <stefan.galinski@gmail.com>
+ * @author Steffen Ritter <info@steffen-ritter.net>
  * @package TYPO3
  * @subpackage t3lib
  */
-class t3lib_tree_extdirect_Node extends t3lib_tree_Node {
-	/**
-	 * Node type
-	 *
-	 * @var string
-	 */
-	protected $type = '';
+class t3lib_tree_NavigationTree_Node extends t3lib_tree_ExtJs_Node {
 
-	/**
-	 * 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
+	 * Database record (not serialized or merged into the result array!)
 	 *
-	 * @var bool
+	 * @var array
 	 */
-	protected $expandable = FALSE;
+	protected $record = array();
 
-	/**
-	 * Indicator if the node is draggable
-	 *
-	 * @var bool
-	 */
-	protected $draggable = TRUE;
 
 	/**
-	 * Indicator if the node is allowed as a drop target
+	 * Indicator if the node can have children's
 	 *
 	 * @var bool
 	 */
-	protected $isDropTarget = TRUE;
+	protected $allowChildren = TRUE;
 
 	/**
-	 * Label
+	 * Node type
 	 *
 	 * @var string
 	 */
-	protected $text = '';
+	protected $type = '';
 
-	/**
-	 * Editable Label text
-	 *
-	 * @var string
-	 */
-	protected $editableText = '';
 
 	/**
 	 * Prefix text of the label
@@ -104,60 +73,19 @@ class t3lib_tree_extdirect_Node extends t3lib_tree_Node {
 	protected $suffix = '';
 
 	/**
-	 * CSS Class
-	 *
-	 * @var string
-	 */
-	protected $cls = '';
-
-	/**
-	 * Quick Tip
-	 *
-	 * @var string
-	 */
-	protected $qtip = '';
-
-	/**
-	 * Sprite Icon HTML
+	 * Context Info
 	 *
-	 * @var string
+	 * @var array
 	 */
-	protected $spriteIconCode = '';
+	protected $contextInfo = array();
 
 	/**
-	 * Text source field (title, nav_title, ...)
+	 * Editable Label text
 	 *
 	 * @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();
+	protected $editableText = '';
 
-	/**
-	 * Context Info
-	 *
-	 * @var array
-	 */
-	protected $contextInfo = array();
 
 	/**
 	 * Indicator if the label is editable
@@ -166,173 +94,92 @@ class t3lib_tree_extdirect_Node extends t3lib_tree_Node {
 	 */
 	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
+	 * Sets the context info
 	 *
-	 * @param bool $isLeaf
+	 * @param array $contextInfo
 	 * @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;
+	public function setContextInfo($contextInfo) {
+		$this->contextInfo = (array) $contextInfo;
 	}
 
 	/**
-	 * Sets the expandable indicator
+	 * Returns the context info
 	 *
-	 * @param bool $expandable
-	 * @return void
+	 * @return array
 	 */
-	public function setExpandable($expandable) {
-		$this->expandable = ($expandable == TRUE);
+	public function getContextInfo() {
+		return (array) $this->contextInfo;
 	}
 
-	/**
-	 * Returns the expandable indicator
-	 *
-	 * @return bool
-	 */
-	public function isExpandable() {
-		return $this->expandable;
-	}
 
 	/**
-	 * Sets the expanded indicator
+	 * Sets the indicator if the node can have child nodes
 	 *
-	 * @param bool $expanded
+	 * @param boolean $allowChildren
 	 * @return void
 	 */
-	public function setExpanded($expanded) {
-		$this->expanded = ($expanded == TRUE);
+	public function setAllowChildren($allowChildren) {
+		$this->allowChildren = ($allowChildren == TRUE);
 	}
 
 	/**
-	 * Returns the expanded indicator
+	 * Checks if the node can have child nodes
 	 *
 	 * @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);
+	public function canHaveChildren() {
+		return $this->allowChildren;
 	}
 
-	/**
-	 * Returns the draggable indicator
-	 *
-	 * @return bool
-	 */
-	public function isDraggable() {
-		return $this->draggable;
-	}
 
 	/**
-	 * Sets the indicator if the node can be a drop target
+	 * Sprite Icon HTML
 	 *
-	 * @param bool $isDropTarget
-	 * @return void
+	 * @var string
 	 */
-	public function setIsDropTarget($isDropTarget) {
-		$this->isDropTarget = ($isDropTarget == TRUE);
-	}
+	protected $spriteIconCode = '';
 
 	/**
-	 * Returns the indicator if the node is a drop target
+	 * Text source field (title, nav_title, ...)
 	 *
-	 * @return bool
+	 * @var string
 	 */
-	public function isDropTarget() {
-		return $this->isDropTarget;
-	}
+	protected $t3TextSourceField = '';
 
 	/**
-	 * Sets the label of the node with the source field and the prefix
+	 * Indicator if the copy mode is activated
 	 *
-	 * @param string $text
-	 * @param string $textSourceField
-	 * @param string $prefix
-	 * @param string $suffix
-	 * @return void
+	 * @var bool
 	 */
-	public function setText($text, $textSourceField = 'title', $prefix = '', $suffix = '') {
-		$this->text = $text;
-		$this->t3TextSourceField = $textSourceField;
-		$this->prefix = $prefix;
-		$this->suffix = $suffix;
-	}
+	protected $t3InCopyMode = FALSE;
 
 	/**
-	 * Returns the label
+	 * Indicator if the cut mode is activated
 	 *
-	 * @return string
+	 * @var bool
 	 */
-	public function getText() {
-		return $this->text;
-	}
+	protected $t3InCutMode = FALSE;
 
-	/**
-	 * Sets the editable text
+		/**
+	 * Sets the sprite icon code
 	 *
-	 * @param string $editableText
+	 * @param string $spriteIcon
 	 * @return void
 	 */
-	public function setEditableText($editableText) {
-		$this->editableText = $editableText;
+	public function setSpriteIconCode($spriteIcon) {
+		$this->spriteIconCode = $spriteIcon;
 	}
 
 	/**
-	 * Returns the editable text
+	 * Returns the sprite icon code
 	 *
 	 * @return string
 	 */
-	public function getEditableText() {
-		return $this->editableText;
+	public function getSpriteIconCode() {
+		return $this->spriteIconCode;
 	}
 
 	/**
@@ -399,63 +246,45 @@ class t3lib_tree_extdirect_Node extends t3lib_tree_Node {
 	public function getSuffix() {
 		return $this->suffix;
 	}
-
+	
 	/**
-	 * Sets the css class(es)
+	 * Set's the node type
 	 *
-	 * @param string $class
+	 * @param string $type
 	 * @return void
 	 */
-	public function setCls($class) {
-		$this->cls = $class;
+	public function setType($type) {
+		$this->type = $type;
 	}
 
 	/**
-	 * Returns the css class(es)
+	 * Returns the node type
 	 *
 	 * @return string
 	 */
-	public function getCls() {
-		return $this->cls;
+	public function getType() {
+		return $this->type;
 	}
 
 	/**
-	 * Sets the quick tip
+	 * Sets the editable text
 	 *
-	 * @param string $qtip
+	 * @param string $editableText
 	 * @return void
 	 */
-	public function setQTip($qtip) {
-		$this->qtip = $qtip;
+	public function setEditableText($editableText) {
+		$this->editableText = $editableText;
 	}
 
 	/**
-	 * Returns the quick tip
+	 * Returns the editable text
 	 *
 	 * @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;
+	public function getEditableText() {
+		return $this->editableText;
 	}
 
-	/**
-	 * Returns the sprite icon code
-	 *
-	 * @return string
-	 */
-	public function getSpriteIconCode() {
-		return $this->spriteIconCode;
-	}
 
 	/**
 	 * Sets the indicator if the label is editable
@@ -477,74 +306,39 @@ class t3lib_tree_extdirect_Node extends t3lib_tree_Node {
 	}
 
 	/**
-	 * 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
+	 * Sets the label of the node with the source field and the prefix
 	 *
-	 * @param t3lib_tree_NodeCollection $childNodes
+	 * @param string $text
+	 * @param string $textSourceField
+	 * @param string $prefix
+	 * @param string $suffix
 	 * @return void
 	 */
-	public function setChildNodes(t3lib_tree_NodeCollection $childNodes) {
-		parent::setChildNodes($childNodes);
-
-		if ($childNodes->count()) {
-			$this->setLeaf(FALSE);
-		}
+	public function setText($text, $textSourceField = 'title', $prefix = '', $suffix = '') {
+		$this->text = $text;
+		$this->t3TextSourceField = $textSourceField;
+		$this->prefix = $prefix;
+		$this->suffix = $suffix;
 	}
 
 	/**
-	 * Sets the indicator if the node can have child nodes
+	 * Sets data of the node by a given data array
 	 *
-	 * @param boolean $allowChildren
+	 * @param array $data
 	 * @return void
 	 */
-	public function setAllowChildren($allowChildren) {
-		$this->allowChildren = ($allowChildren == TRUE);
-	}
+	public function dataFromArray($data) {
+		parent::dataFromArray($data);
 
-	/**
-	 * Checks if the node can have child nodes
-	 *
-	 * @return bool
-	 */
-	public function canHaveChildren() {
-		return $this->allowChildren;
+		$this->setText($data['label'], $data['t3TextSourceField'], $data['prefix'], $data['suffix']);
+		$this->setType($data['type']);
+		$this->setEditableText($data['editableText']);
+		$this->setSpriteIconCode($data['spriteIconCode']);
+		$this->setInCopyMode($data['t3InCopyMode']);
+		$this->setInCutMode($data['t3InCutMode']);
+		$this->setContextInfo($data['t3ContextInfo']);
+		$this->setLabelIsEditable($data['editable']);
+		$this->setAllowChildren($data['allowChildren']);
 	}
 
 	/**
@@ -554,20 +348,14 @@ class t3lib_tree_extdirect_Node extends t3lib_tree_Node {
 	 * @return array
 	 */
 	public function toArray($addChildNodes = TRUE) {
-		$arrayRepresentation = array(
-			'serializeClassName' => get_class($this),
-			'id' => $this->getId(),
+		$arrayRepresentation = parent::toArray($addChildNodes);
+
+		$arrayRepresentation2 = array(
 			'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(),
@@ -580,56 +368,51 @@ class t3lib_tree_extdirect_Node extends t3lib_tree_Node {
 			// 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;
+			$arrayRepresentation2['leaf'] = FALSE;
 		}
 
+			// Do not nest nodeData and children arrays
+		unset($arrayRepresentation['nodeData']);
+		unset($arrayRepresentation['children']);
+		$arrayRepresentation = array_merge($arrayRepresentation, $arrayRepresentation2);
+
 			// 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()) {
+		if ($this->hasChildNodes() && $addChildNodes) {
 			$arrayRepresentation['children'] = $this->childNodes->toArray();
 		}
 
 		return $arrayRepresentation;
 	}
 
+
 	/**
-	 * Sets data of the node by a given data array
+	 * Sets the database record array
 	 *
-	 * @param array $data
+	 * @param array $record
 	 * @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']);
+	public function setRecord($record) {
+		$this->record = (array) $record;
+	}
 
-			// only set the leaf attribute if it's applied
-			// otherwise you cannot insert nodes into this one
-		if (isset($data['leaf'])) {
-			$this->setLeaf(FALSE);
-		}
+	/**
+	 * Returns the database record array
+	 *
+	 * @return array
+	 */
+	public function getRecord() {
+		return $this->record;
 	}
+
+
 }
 
-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']);
+if (defined('TYPO3_MODE') && isset($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['t3lib/tree/navigationtree/class.t3lib_tree_navigationtree_node.php'])) {
+	include_once($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['t3lib/tree/navigationtree/class.t3lib_tree_navigationtree_node.php']);
 }
 
 ?>
\ No newline at end of file
diff --git a/t3lib/tree/pagetree/class.t3lib_tree_pagetree_commands.php b/t3lib/tree/pagetree/class.t3lib_tree_pagetree_commands.php
index 532761ede0fca3788b6455f6c8db3b23749af1f8..782c7b5609c51db8a8bf417f75213f2026b98774 100644
--- a/t3lib/tree/pagetree/class.t3lib_tree_pagetree_commands.php
+++ b/t3lib/tree/pagetree/class.t3lib_tree_pagetree_commands.php
@@ -36,7 +36,7 @@ final class t3lib_tree_pagetree_Commands {
 	/**
 	 * Visibly the page
 	 *
-	 * @param t3lib_tree_pagetree_Node $nodeData
+	 * @param t3lib_tree_pagetree_Node $node
 	 * @return void
 	 */
 	public static function visiblyNode(t3lib_tree_pagetree_Node $node) {
@@ -47,7 +47,7 @@ final class t3lib_tree_pagetree_Commands {
 	/**
 	 * Hide the page
 	 *
-	 * @param t3lib_tree_pagetree_Node $nodeData
+	 * @param t3lib_tree_pagetree_Node $node
 	 * @return void
 	 */
 	public static function disableNode(t3lib_tree_pagetree_Node $node) {
@@ -58,7 +58,7 @@ final class t3lib_tree_pagetree_Commands {
 	/**
 	 * Delete the page
 	 *
-	 * @param t3lib_tree_pagetree_Node $nodeData
+	 * @param t3lib_tree_pagetree_Node $node
 	 * @return void
 	 */
 	public static function deleteNode(t3lib_tree_pagetree_Node $node) {
@@ -69,7 +69,7 @@ final class t3lib_tree_pagetree_Commands {
 	/**
 	 * Restore the page
 	 *
-	 * @param t3lib_tree_pagetree_Node $nodeData
+	 * @param t3lib_tree_pagetree_Node $node
 	 * @param int $targetId
 	 * @return void
 	 */
@@ -85,7 +85,7 @@ final class t3lib_tree_pagetree_Commands {
 	/**
 	 * Updates the node label
 	 *
-	 * @param t3lib_tree_pagetree_Node $nodeData
+	 * @param t3lib_tree_pagetree_Node $node
 	 * @param string $updatedLabel
 	 * @return void
 	 */
@@ -276,6 +276,7 @@ final class t3lib_tree_pagetree_Commands {
 	 * Creates a node with the given record information's
 	 *
 	 * @param array $record
+	 * @param int $mountPoint
 	 * @return t3lib_tree_pagetree_Node
 	 */
 	public static function getNewNode($record, $mountPoint = 0) {
@@ -335,7 +336,7 @@ final class t3lib_tree_pagetree_Commands {
 		if (is_array($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['GLOBAL']['recStatInfoHooks'])) {
 			$_params = array('pages', $record['uid']);
 			foreach ($GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['GLOBAL']['recStatInfoHooks'] as $_funcRef) {
-				$stat .= t3lib_div::callUserFunction($_funcRef, $_params, $this);
+				$stat .= t3lib_div::callUserFunction($_funcRef, $_params, NULL);
 			}
 		}
 
@@ -358,11 +359,11 @@ final class t3lib_tree_pagetree_Commands {
 		$subNode->setSpriteIconCode($spriteIconCode);
 
 		if (!$subNode->canCreateNewPages() || intval($record['t3ver_state']) === 2) {
-			$subNode->setIsDropTarget(FALSE);
+			$subNode->setAllowDrop(FALSE);
 		}
 
 		if (!$subNode->canBeEdited() || !$subNode->canBeRemoved() || intval($record['t3ver_state']) === 2) {
-			$subNode->setDraggable(FALSE);
+			$subNode->setAllowDrag(FALSE);
 		}
 
 		return $subNode;
diff --git a/t3lib/tree/pagetree/class.t3lib_tree_pagetree_dataprovider.php b/t3lib/tree/pagetree/class.t3lib_tree_pagetree_dataprovider.php
index 4cd6f238992702ad32f5b53cf9b7d04c2394728c..78b010ddd7be109b1b721badd48da3e1663c7167 100644
--- a/t3lib/tree/pagetree/class.t3lib_tree_pagetree_dataprovider.php
+++ b/t3lib/tree/pagetree/class.t3lib_tree_pagetree_dataprovider.php
@@ -123,7 +123,7 @@ class t3lib_tree_pagetree_DataProvider extends t3lib_tree_AbstractDataProvider {
 		if (!is_array($subpages) || !count($subpages)) {
 			return $nodeCollection;
 		}
-
+		$index = -1;
 		foreach ($subpages as $subpage) {
 			if (in_array($subpage['uid'], $this->hiddenRecords)) {
 				continue;
@@ -135,14 +135,20 @@ class t3lib_tree_pagetree_DataProvider extends t3lib_tree_AbstractDataProvider {
 			}
 
 			$subNode = t3lib_tree_pagetree_Commands::getNewNode($subpage, $mountPoint);
+			$subNode->setParentNode($node);
+			$subNode->setDepth($node->getDepth() + 1);
+			$subNode->setIndex(++$index);
+			$subNode->setIsFirst($index === 0);
+			$subNode->setIsLast($index === (count($subpages)-1));
 			if ($this->nodeCounter < $this->nodeLimit) {
 				$childNodes = $this->getNodes($subNode, $mountPoint, $level + 1);
 				$subNode->setChildNodes($childNodes);
+				$subNode->setLeaf(!$subNode->hasChildNodes());
 				$this->nodeCounter += $childNodes->count();
 			} else {
 				$subNode->setLeaf(!$this->hasNodeSubPages($subNode->getId()));
 			}
-
+			$subNode->setExpandable(!$subNode->isLeafNode());
 			$nodeCollection->append($subNode);
 		}
 
@@ -160,7 +166,7 @@ class t3lib_tree_pagetree_DataProvider extends t3lib_tree_AbstractDataProvider {
 	 * @param t3lib_tree_Node $node
 	 * @param string $searchFilter
 	 * @param int $mountPoint
-	 * @return void
+	 * @return t3lib_tree_pagetree_NodeCollection
 	 */
 	public function getFilteredNodes(t3lib_tree_Node $node, $searchFilter, $mountPoint = 0) {
 		/** @var $nodeCollection t3lib_tree_pagetree_NodeCollection */
@@ -205,13 +211,10 @@ class t3lib_tree_pagetree_DataProvider extends t3lib_tree_AbstractDataProvider {
 				if ($reference && $reference->offsetExists($ident)) {
 					/** @var $refNode t3lib_tree_pagetree_Node */
 					$refNode = $reference->offsetGet($ident);
-					$refNode->setExpanded(TRUE);
-					$refNode->setLeaf(FALSE);
-
-					$reference = $refNode->getChildNodes();
-					if ($reference == NULL) {
-						$reference = t3lib_div::makeInstance('t3lib_tree_pagetree_NodeCollection');
-						$refNode->setChildNodes($reference);
+					if ($refNode->hasChildNodes()) {
+						$refNode->setExpanded(TRUE);
+						$refNode->setLeaf(FALSE);
+						$reference = $refNode->getChildNodes();
 					}
 				} else {
 					$refNode = t3lib_tree_pagetree_Commands::getNewNode($rootlineElement, $mountPoint);
@@ -287,6 +290,7 @@ class t3lib_tree_pagetree_DataProvider extends t3lib_tree_AbstractDataProvider {
 		}
 
 		$showRootlineAboveMounts = $GLOBALS['BE_USER']->getTSConfigVal('options.pageTree.showPathAboveMounts');
+		$index = -1;
 		foreach ($mountPoints as $mountPoint) {
 			if ($mountPoint === 0) {
 				$sitename = 'TYPO3';
@@ -322,10 +326,13 @@ class t3lib_tree_pagetree_DataProvider extends t3lib_tree_AbstractDataProvider {
 				$subNode->setExpanded(TRUE);
 				$subNode->setCls('typo3-pagetree-node-notExpandable');
 			}
-
+			$subNode->setDepth(1);
+			$subNode->setIndex(++$index);
+			$subNode->setIsFirst($index === 0);
+			$subNode->setIsLast($index === (count($mountPoints)-1));
 			$subNode->setIsMountPoint(TRUE);
-			$subNode->setDraggable(FALSE);
-			$subNode->setIsDropTarget(FALSE);
+			$subNode->setAllowDrag(FALSE);
+			$subNode->setAllowDrop(FALSE);
 
 			if ($searchFilter === '') {
 				$childNodes = $this->getNodes($subNode, $mountPoint);
@@ -363,21 +370,22 @@ class t3lib_tree_pagetree_DataProvider extends t3lib_tree_AbstractDataProvider {
 		}
 
 		if ($searchFilter !== '') {
+			$searchWhere = '';
 			if (is_numeric($searchFilter) && $searchFilter > 0) {
-				$seachWhere .= 'uid = ' . intval($searchFilter) . ' OR ';
+				$searchWhere .= '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 .
+				$searchWhere .= '(nav_title LIKE ' . $searchFilter .
 					' OR (nav_title = "" && title LIKE ' . $searchFilter . '))';
 			} else {
-				$seachWhere .= 'title LIKE ' . $searchFilter;
+				$searchWhere .= 'title LIKE ' . $searchFilter;
 			}
 
-			$where .= ' AND (' . $seachWhere . ')';
+			$where .= ' AND (' . $searchWhere . ')';
 		}
 
 		return $where;
diff --git a/t3lib/tree/pagetree/class.t3lib_tree_pagetree_indicator.php b/t3lib/tree/pagetree/class.t3lib_tree_pagetree_indicator.php
index a97f7ac826996a4b8ece8f81fbc4072c1b889e6a..619273a2b9185ef3e2473cfebceb54a245400db4 100644
--- a/t3lib/tree/pagetree/class.t3lib_tree_pagetree_indicator.php
+++ b/t3lib/tree/pagetree/class.t3lib_tree_pagetree_indicator.php
@@ -53,7 +53,7 @@ class t3lib_tree_pagetree_Indicator {
 	 */
 	protected function getIndicatorProviders() {
 		$providers = $GLOBALS['TYPO3_CONF_VARS']['SC_OPTIONS']['pagetree']['t3lib_tree_pagetree']['indicator']['providers'];
-		if (!is_array($providers)) {
+		if (!is_array($providers) || count($this->indicatorProviders) > 0) {
 			return;
 		}
 
@@ -69,13 +69,13 @@ class t3lib_tree_pagetree_Indicator {
 	/**
 	 * Runs through all indicator providers and returns all indicators collected.
 	 *
-	 * @return	array	An array of
+	 * @return	array	An array of indicator objects
 	 */
 	public function getAllIndicators() {
 		$indicators = array();
 		foreach ($this->indicatorProviders as $indicatorProvider) {
 			$indicator = $indicatorProvider->getIndicator();
-			if($indicator) {
+			if ($indicator) {
 				$indicators[] = $indicator;
 			}
 		}
diff --git a/t3lib/tree/pagetree/class.t3lib_tree_pagetree_node.php b/t3lib/tree/pagetree/class.t3lib_tree_pagetree_node.php
index 91af17c4d33001ee575bf57ad57be14f6554b160..4c5145933a583b76d453a47d2018ebe170a7eb4c 100644
--- a/t3lib/tree/pagetree/class.t3lib_tree_pagetree_node.php
+++ b/t3lib/tree/pagetree/class.t3lib_tree_pagetree_node.php
@@ -32,7 +32,7 @@
  * @package TYPO3
  * @subpackage t3lib
  */
-class t3lib_tree_pagetree_Node extends t3lib_tree_extdirect_Node {
+class t3lib_tree_pagetree_Node extends t3lib_tree_NavigationTree_Node implements t3lib_tree_RecordBasedNode {
 	/**
 	 * Cached access rights to save some performance
 	 *
@@ -297,6 +297,19 @@ class t3lib_tree_pagetree_Node extends t3lib_tree_extdirect_Node {
 	public function canBeTemporaryMountPoint() {
 		return TRUE;
 	}
+	
+	/**
+	 * Returns a special id for a page tree node
+	 *
+	 * @return string
+	 */
+	public function getPageTreeNodeId() {
+		if ($this->getId() === 'root') {
+			return 'root';
+		} else {
+			return 'p' . dechex($this->getId()) . ($this->getMountPoint() ? '-' . dechex($this->getMountPoint()) : '');
+		}
+	}
 
 	/**
 	 * Returns the node in an array representation that can be used for serialization
@@ -307,17 +320,34 @@ class t3lib_tree_pagetree_Node extends t3lib_tree_extdirect_Node {
 	public function toArray($addChildNodes = TRUE) {
 		$arrayRepresentation = parent::toArray();
 
-		$arrayRepresentation['id'] = 'p' . dechex($this->getId()) . ($this->getMountPoint() ? '-' . dechex($this->getMountPoint()) : '');
-		$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);
+		$arrayRepresentation2['id'] = $this->getPageTreeNodeId();
+		$arrayRepresentation2['realId'] = $this->getId();
+		$arrayRepresentation2['serializeClassName'] = get_class($this);
+		$arrayRepresentation2['parentId'] = (!$this->getRoot() && $this->getParentNode()) ? $this->getParentNode()->getPageTreeNodeId() : 'root';
+		$arrayRepresentation2['readableRootline'] = $this->getReadableRootline();
+		$arrayRepresentation2['mountPoint'] = $this->getMountPoint();
+		$arrayRepresentation2['workspaceId'] = $this->getWorkspaceId();
+		$arrayRepresentation2['isMountPoint'] = $this->isMountPoint();
+
+			// only set the leaf attribute if the node has children's,
+			// otherwise you cannot add child's to real leaf nodes
+		if (!$this->isLeafNode()) {
+			$arrayRepresentation2['leaf'] = FALSE;
+		}
+			// Do not nest nodeData and children arrays
+		unset($arrayRepresentation['nodeData']);
+		unset($arrayRepresentation['children']);
+		$arrayRepresentation = array_merge($arrayRepresentation, $arrayRepresentation2);
+
+			// 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;
+		$arrayRepresentation['nodeData']['id'] = $arrayRepresentation['realId'];
+
+		if ($this->hasChildNodes() && $addChildNodes) {
+			$arrayRepresentation['children'] = $this->childNodes->toArray();
+		}
 
 		return $arrayRepresentation;
 	}
@@ -335,6 +365,35 @@ class t3lib_tree_pagetree_Node extends t3lib_tree_extdirect_Node {
 		$this->setReadableRootline($data['readableRootline']);
 		$this->setIsMountPoint($data['isMountPoint']);
 	}
+
+	/**
+	 * set the source field of the label
+	 *
+	 * @param string $field
+	 * @return void
+	 */
+	public function setTextSourceField($field) {
+		$this->t3TextSourceField = $field;
+	}
+
+	/**
+	 * Returns the table of the record data
+	 *
+	 * @return string
+	 */
+	public function getSourceTable() {
+		return 'pages';
+	}
+
+	/**
+	 * sets the Table of record source data
+	 *
+	 * @param string $table
+	 * @return void
+	 */
+	public function setSourceTable($table) {
+		// not needed, pagetree always is 'pages'
+	}
 }
 
 if (defined('TYPO3_MODE') && isset($GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['XCLASS']['t3lib/tree/pagetree/class.t3lib_tree_pagetree_node.php'])) {
diff --git a/t3lib/tree/pagetree/extdirect/class.t3lib_tree_pagetree_extdirect_commands.php b/t3lib/tree/pagetree/extdirect/class.t3lib_tree_pagetree_extdirect_commands.php
index a3a33dac362ca8b8d76c4abedbb55fe3840f83cc..12ccaeb8ed014d648c3b63670e664ea81d20f6f4 100644
--- a/t3lib/tree/pagetree/extdirect/class.t3lib_tree_pagetree_extdirect_commands.php
+++ b/t3lib/tree/pagetree/extdirect/class.t3lib_tree_pagetree_extdirect_commands.php
@@ -225,7 +225,7 @@ class t3lib_tree_pagetree_extdirect_Commands {
 	 *
 	 * @param stdClass $nodeData
 	 * @param int $destination
-	 * @return void
+	 * @return array
 	 */
 	public function moveNodeAfterDestination($nodeData, $destination) {
 		/** @var $node t3lib_tree_pagetree_Node */
diff --git a/t3lib/tree/pagetree/extdirect/class.t3lib_tree_pagetree_extdirect_tree.php b/t3lib/tree/pagetree/extdirect/class.t3lib_tree_pagetree_extdirect_tree.php
index e8df3f8f2ab2711fd799603347925d0aa5cb6c9f..466195f9c6763f6794e0a5555c744b2fda98729f 100644
--- a/t3lib/tree/pagetree/extdirect/class.t3lib_tree_pagetree_extdirect_tree.php
+++ b/t3lib/tree/pagetree/extdirect/class.t3lib_tree_pagetree_extdirect_tree.php
@@ -32,7 +32,7 @@
  * @package TYPO3
  * @subpackage t3lib
  */
-class t3lib_tree_pagetree_extdirect_Tree extends t3lib_tree_ExtDirect_AbstractExtJsTree {
+class t3lib_tree_pagetree_extdirect_Tree extends t3lib_tree_ExtJs_AbstractStatefulExtJsTree {
 	/**
 	 * Data Provider
 	 *
@@ -180,7 +180,7 @@ class t3lib_tree_pagetree_extdirect_Tree extends t3lib_tree_ExtDirect_AbstractEx
 	/**
 	 * Returns the language labels, sprites and configuration options for the pagetree
 	 *
-	 * @return void
+	 * @return array
 	 */
 	public function loadResources() {
 		$file = 'LLL:EXT:lang/locallang_core.xml:';
diff --git a/typo3/sysext/t3skin/stylesheets/structure/element_pagetree.css b/typo3/sysext/t3skin/stylesheets/structure/element_pagetree.css
index 8ae4e364b21ce822b27a23892984d893099f3695..aed04b76ab3eca17b7f9cf0be8a42968c2c8e6fb 100644
--- a/typo3/sysext/t3skin/stylesheets/structure/element_pagetree.css
+++ b/typo3/sysext/t3skin/stylesheets/structure/element_pagetree.css
@@ -6,50 +6,32 @@ Pagetree
 #typo3-pagetree,
 #typo3-pagetree .x-panel-bwrap,
 #typo3-pagetree .x-panel-body {
+	border: none;
 	height: 100%;
 }
 
-#typo3-pagetree .x-panel-tbar {
-	padding: 0;
-	margin: 0;
-}
-
-.x-tree-node .x-tree-node-el {
-	margin-right: 0;
+.typo3-pagetree .x-grid-table {
+	padding-left: 5px;
 }
 
 .x-tree-node-readableRootline {
 	padding: 10px 0 3px 10px;
 }
 
-.x-tree-lines .typo3-pagetree-node-notExpandable .x-tree-ec-icon {
-	visibility: hidden;
-}
-
-.x-tree-lines .typo3-pagetree-node-notExpandable ul .x-tree-ec-icon {
-	visibility: visible;
-}
-
-#typo3-pagetree span.t3-icon {
+.typo3-pagetree span.t3-icon {
 	margin-bottom: 2px;
 }
 
-#typo3-pagetree .x-toolbar,
-.typo3-pagetree-topPanel-item .x-toolbar {
-	padding-bottom: 0;
-}
-
-#typo3-pagetree ul.x-tree-root-ct {
-	padding-left: 5px;
-	padding-top: 15px;
-}
-
-.x-tree-node a .typo3-pagetree-status,
+.typo3-pagetree .x-grid-row .x-grid-cell a .typo3-pagetree-status,
 .x-dd-drag-ghost a .typo3-pagetree-status {
 	padding: 0;
 	margin: 0 3px 0 0;
 }
 
+.typo3-pagetree .x-form-field {
+	height: 19px;
+}
+
 /**
  *
  * section drag and drop
@@ -86,62 +68,62 @@ Pagetree
  * @section Top Panel
  *
  */
-#typo3-pagetree-topPanel .x-toolbar-left {
-	height: 20px;
+#typo3-pagetree .x-docked-top {
+	padding: 0;
 }
 
-.typo3-pagetree-topPanel-button {
-	margin: 0 5px 0 0;
-	padding: 1px 2px;
-	height: 18px;
+.typo3-pagetree-topPanel {
+	height: 49px;
 }
 
-.typo3-pagetree-topPanel-button button {
-	height: 16px;
-	width: 16px;
+#typo3-pagetree-topPanel .x-docked-top .x-box-inner {
+	height: 22px;
+	margin: 0;
 }
 
-.typo3-pagetree-topPanel-item {
-	padding: 5px 3px 0 3px;
-	height: 22px;
+#typo3-pagetree .typo3-pagetree-topPanel-button {
+	height: 21px;
+	margin-right: 1px;
+	margin-top: 0px !important;
+	padding: 1px 3px 0 3px;
 }
 
-#typo3-pagetree-topPanel-filterWrap {
-	padding-top: 3px;
-	height: 24px;
+.typo3-pagetree-topPanel-item {
+	padding: 2px 0 0 0;
+	height: 22px;
 }
 
-#typo3-pagetree-topPanel-filter {
-	height: 16px;
-	width: 98% !important;
-	padding: 1px 0 1px 2px;
+#typo3-pagetree-topPanel-item-newNode {
+	padding: 0;
 }
 
-#typo3-pagetree-topPanel-filterWrap .t3-icon-input-clear {
-	right: 2%;
+.typo3-pagetree-topPanel-item .x-form-item {
+	border: none !important;
+	margin: 3px;
+	width: 100%;
 }
 
-#typo3-pagetree .typo3-pagetree-topPanel-button {
-	margin-right: 1px;
-	margin-top: -2px;
-	padding: 2px 3px;
+.typo3-pagetree-topPanel-item .x-form-field {
+	height: 18px;
+	line-height: 16px;
 }
 
-#typo3-pagetree-topPanel-defaultPanel {
-	padding-left: 6px;
+.typo3-pagetree-topPanel-filter .t3-icon-input-clear {
 }
 
-#typo3-pagetree-topPanel-filterWrap .x-form-field-trigger-wrap {
-	width: 100% !important;
-	margin: 0 20px 0 0;
+.typo3-pagetree-topPanel-item .x-form-trigger-wrap {
+	margin: 0;
 }
 
 .typo3-pagetree-topPanel-item .x-form-trigger {
-	margin: 4px 0 0;
+	background-image: none;
+	border-bottom: none !important;
 	display: none;
+	margin-right: 0;
+	margin-top: 1px;
 }
 
-.typo3-pagetree-topPanel-item .x-form-field-trigger-wrap:hover .x-form-trigger {
+.typo3-pagetree-topPanel-item .x-form-trigger-wrap-focus:hover .x-form-trigger {
 	display: block;
 }
 
@@ -154,25 +136,31 @@ Pagetree
  * @section Indicator Bar
  *
  */
-.typo3-pagetree-indicatorBar-item p {
-	padding: 5px 10px;
+#typo3-pagetree-indicatorBar {
+	width: 100%;
+}
+
+#typo3-pagetree-indicatorBar-filter,
+#typo3-pagetree-indicatorBar-temporaryMountPoint {
+	padding: 10px 20px;	
 }
 
 #typo3-pagetree-indicatorBar-filter p,
 #typo3-pagetree-indicatorBar-temporaryMountPoint p {
-	padding: 10px 35px;
+	padding-left: 5px;
+	width: 100%;
 }
 
 .typo3-pagetree-indicatorBar-item .typo3-pagetree-indicatorBar-item-leftIcon {
-	left: 10px;
-	top: 9px;
-	position: absolute;
+	position: relative;
+	left: -10px;
+	top: 0px;
 }
 
 .typo3-pagetree-indicatorBar-item .typo3-pagetree-indicatorBar-item-rightIcon {
-	right: 10px;
-	top: 5px;
-	position: absolute;
+	position: relative;
+	right: -10px;
+	vertical-align: top;
 }
 
 #typo3-pagetree-indicatorBar-indicatorTitle span {
diff --git a/typo3/sysext/t3skin/stylesheets/visual/element_pagetree.css b/typo3/sysext/t3skin/stylesheets/visual/element_pagetree.css
index 67dd10fc473fcaff1b3a890a46bde53e7a8828ab..2337e495ae04da2a9b9fc2dc3391f5834dc192d1 100644
--- a/typo3/sysext/t3skin/stylesheets/visual/element_pagetree.css
+++ b/typo3/sysext/t3skin/stylesheets/visual/element_pagetree.css
@@ -3,28 +3,29 @@ Pagetree
 
 - - - - - - - - - - - - - - - - - - - - - */
 #typo3-pagetree-treeContainer,
-#typo3-pagetree-topPanelItems {
+.typo3-pageTree-topPanelItems {
 	background-color: #ebebeb;
 }
 
-#typo3-pagetree .x-tree .x-panel-body {
+.typo3-pagetree .x-panel-body {
 	background: none;
 }
 
-#typo3-pagetree .x-tree-node .x-tree-node-el {
+.typo3-pagetree .x-grid-row .x-grid-cell {
 	border-top: 1px solid transparent;
 	border-bottom: 1px solid transparent;
 	border-left: 1px solid transparent;
+	font-size: 12px;
 }
 
-#typo3-pagetree .x-tree-node .x-tree-node-over,
-#typo3-pagetree .x-tree-node .x-tree-selected {
+.typo3-pagetree .x-grid-row.x-grid-row-over .x-grid-cell,
+.typo3-pagetree .x-grid-row.x-grid-row-selected .x-grid-cell {
 	border-bottom: 1px solid #d7d7d7;
 	border-top: 1px solid #d7d7d7;
 	border-left: 1px solid #d7d7d7;
 }
 
-#typo3-pagetree .x-tree-node .x-tree-node-over {
+.typo3-pagetree .x-grid-row.x-grid-row-over .x-grid-cell {
 	background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAABCAYAAAAb4BS0AAAAGElEQVR42gENAPL/AMjIyEzIyMizyMjI/zhvCQelaHPPAAAAAElFTkSuQmCC");
 	/* star-hack targets IE7 */
 	*background-image: url("../../images/shadows/navigation-container.png");
@@ -39,20 +40,34 @@ Pagetree
 	border-bottom-right-radius: 3px;
 }
 
-#typo3-pagetree .x-tree-node .x-tree-selected {
+.typo3-pagetree .x-grid-row-selected .x-grid-cell {
 	background-color: #f8f8f8;
 }
 
-#typo3-pagetree .x-tree-node .x-tree-selected.x-tree-node-over {
+.typo3-pagetree .x-grid-row-selected.x-grid-row-over .x-grid-cell {
 	background-image: none;
 	-webkit-border-radius: 0;
 	-moz-border-radius: 0;
 	border-radius: 0;
 }
 
-#typo3-pagetree .x-panel-tbar {
-	background-color: #585858;
-	border: none;
+.typo3-pagetree .x-tree-elbow-plus,
+.typo3-pagetree .x-tree-elbow-end-plus {
+	background-image:url('../../images/icons/apps/pagetree-collapse.png');
+}
+
+.typo3-pagetree .x-tree-elbow-minus,
+.typo3-pagetree .x-tree-elbow-end-minus,
+.typo3-pagetree .x-grid-tree-node-expanded .x-tree-elbow-plus,
+.typo3-pagetree .x-grid-tree-node-expanded .x-tree-elbow-end-plus {
+	background-image:url('../../images/icons/apps/pagetree-expand.png');
+}
+
+.typo3-pagetree .x-form-field {
+	color: black;
+	font-family: Verdana,Arial,Helvetica,sans-serif;
+	font-size: 11px;
+	line-height: 14px;
 }
 
 /**
@@ -62,6 +77,8 @@ Pagetree
  */
 .typo3-pagetree-tree-copy {
 	color: #666;
+	font-size: 11px;
+	text-align: center;
 }
 
 .x-dd-drag-ghost {
@@ -149,7 +166,13 @@ Pagetree
  * @section Top Panel
  *
  */
-#typo3-pagetree .x-toolbar {
+#typo3-pagetree-topPanel .x-docked-top,
+#typo3-pagetree-topPanel .x-docked-top .x-box-inner {
+	background-color: #585858;
+	border: none;
+}
+
+#typo3-pagetree .x-panel-body .x-toolbar {
 	background: none;
 	border: none;
 }
@@ -159,6 +182,10 @@ Pagetree
 	border: none;
 }
 
+#typo3-pagetree-topPanel-body {
+	background-color: #dadada;
+}
+
 #typo3-pagetree-topPanel .x-btn-click,
 #typo3-pagetree-topPanel .x-btn-over {
 	background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAMAAAAWCAIAAACKUbHAAAAAGXRFWHRTb2Z0d2FyZQBBZG9iZSBJbWFnZVJlYWR5ccllPAAAAD9JREFUCB19wdERAUAARDEv23+FmsGZG38Sz0sfKoXEppDKyldyxBzzM1eObWYMM5Zr/ipEWRm9UXnr0OVxvQAaNAkk1SzJpgAAAABJRU5ErkJggg==");
@@ -193,19 +220,6 @@ Pagetree
 
 #typo3-pagetree .typo3-pagetree-topPanel-item {
 	background-color: #dadada;
-	line-height: normal;
-}
-
-#typo3-pagetree-topPanel-filter {
-	border: 1px solid #aeaeae;
-	-moz-box-shadow: inset 0 1px 1px #aeaeae;
-	-ms-box-shadow: inset 0 1px 1px #aeaeae;
-	-webkit-box-shadow: inset 0 1px 1px #aeaeae;
-	box-shadow: inset 0 2px 1px #aeaeae;
-}
-
-.typo3-pagetree-topPanel-filter-defaultText {
-	color: gray;
 }
 
 #typo3-pagetree .typo3-pagetree-topPanel-button {
@@ -219,7 +233,10 @@ Pagetree
 
 #typo3-pagetree-topPanel-defaultPanel {
 	color: #a2aab8;
-	line-height: 18px;
+}
+
+.typo3-pagetree-topPanel-filter-defaultText {
+	color: gray;
 }
 
 #typo3-pagetree-topPanel-item-newNode .x-btn-over {
@@ -271,7 +288,8 @@ Pagetree
  *
  */
 
-#typo3-pagetree-indicatorBar-temporaryMountPoint p {
+#typo3-pagetree-indicatorBar-temporaryMountPoint p,
+#typo3-pagetree-indicatorBar-filter p {
 	line-height: 13px;
 }
 
@@ -296,8 +314,7 @@ Pagetree
  * @section Deletion Drop Zone
  *
  */
-
-#typo3-pagetree-deletionDropZone {
+#typo3-pagetree-deletionDropZone .x-panel-body {
 	color: #FFF;
 	background-color: #585858;
 	-moz-box-shadow: inset 0 2px 5px #414141;