Merge branch 'master' of ssh://git.eclipse.org/gitroot/orion/org.eclipse.orion.client
diff --git a/bundles/org.eclipse.orion.client.editor/web/orion/editor/editor.js b/bundles/org.eclipse.orion.client.editor/web/orion/editor/editor.js
index 36cbe1a..3400bbb 100644
--- a/bundles/org.eclipse.orion.client.editor/web/orion/editor/editor.js
+++ b/bundles/org.eclipse.orion.client.editor/web/orion/editor/editor.js
@@ -16,44 +16,6 @@
 		
 	var HIGHLIGHT_ERROR_ANNOTATION = "orion.annotation.highlightError"; //$NON-NLS-0$
 
-	function Idle(options){
-		this._document = options.document || document;
-		this._timeout = options.timeout;
-		//TODO: remove listeners if there are no clients
-		//TODO: add support for multiple clients with different timeouts
-		var events = ["keypress","keydown","keyup","mousemove","mousedown","mousemove"]; //$NON-NLS-0$ //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$
-		var reset = function (e) { this._resetTimer(); }.bind(this);
-		for (var i=0; i<events.length; i++) {
-			var event = events[i];
-			this._document.addEventListener(event, reset, true);	
-		}
-	}
-	
-	Idle.prototype = {
-		_resetTimer: function() {
-			var window = document.defaultView || document.parentWindow;
-			if (this._timer) {
-				window.clearTimeout(this._timer);
-				this._timer = null;
-			}
-			if (this._timeout !== -1) {
-				this._timer = window.setTimeout(function() {
-					this.onIdle({type:"Idle"});	//$NON-NLS-0$ 
-					this._timer = null;
-					this._resetTimer();
-				}.bind(this), this._timeout);
-			}
-		},
-		onIdle: function (idleEvent) {
-			return this.dispatchEvent(idleEvent);
-		},
-		setTimeout: function(timeout) {
-			this._timeout = timeout;
-			this._resetTimer();
-		}
-	};
-	mEventTarget.EventTarget.addMixin(Idle.prototype);
-	
 	/**
 	 * @name orion.editor.Editor
 	 * @class An <code>Editor</code> is a user interface for editing text that provides additional features over the basic {@link orion.editor.TextView}.
@@ -865,27 +827,6 @@
 			});
 		},
 		/**
-		 * Set the autosave timeout. If the timeout is <code>-1</code>, autosave is
-		 * disabled.
-		 * @param {Number} timeout - the autosave timeout in milliseconds
-		 */
-		setAutoSaveTimeout: function(timeout){
-			if (!this._idle) {
-				var document = this._textView.getOptions("parent").ownerDocument; //$NON-NLS-0$
-				var options = {
-					document: document,
-					timeout: timeout
-				};
-				this._idle = new Idle(options);
-				this._idle.addEventListener("Idle", function () { //$NON-NLS-0$
-					if (this.isDirty()) {
-						this._textView.invokeAction("save"); //$NON-NLS-0$
-					}
-				}.bind(this));
-			}
-			this._idle.setTimeout(timeout);
-		},
-		/**
 		 * Called when the editor's contents have changed.
 		 * @param {Event} inputChangedEvent
 		 */
diff --git a/bundles/org.eclipse.orion.client.ui/web/css/ide.css b/bundles/org.eclipse.orion.client.ui/web/css/ide.css
index 991a3b5..deace05 100644
--- a/bundles/org.eclipse.orion.client.ui/web/css/ide.css
+++ b/bundles/org.eclipse.orion.client.ui/web/css/ide.css
@@ -118,13 +118,13 @@
 
 /* the left hand side of slideout containing parameter fields */
 .parameters {
-	color: silver;
+	color: whitesmoke;
 	vertical-align: middle;
 }
 
 /* the right hand side of slideout containing dismiss buttons */
 .parametersDismiss {
-	color: silver;
+	color: whitesmoke;
 	vertical-align: middle;
 	font-weight: normal;
 	padding: 3px;
@@ -135,7 +135,7 @@
 .dismissButton {
 	border: 1px solid transparent;
 	background: transparent;
-	color: silver;
+	color: whitesmoke;
     border-radius: 1px;
 	padding: 2px;
 	font: 8pt Lucida Sans Unicode,Lucida Grande,Verdana,Arial,Helvetica,Myriad,Tahoma,clean,sans-serif;  /* to override user agent stylesheet */
@@ -162,7 +162,7 @@
 
 /* parameter labels */
 label.parameterInput{
-	color: silver;
+	color: whitesmoke;
 	white-space: nowrap;
 }
 
@@ -452,51 +452,6 @@
 	z-index:200;
 }
 
-.advSearchOptContainer {
-	color: black;
-	display: block;
-	border:  1px solid #666;
-	background: white;
-	max-height: 300px;
-	max-width: 300px;
-	min-width: 150px;
-	position: absolute;
-	overflow-y: auto;
-	overflow-x: hidden;
-	padding: 2px;
-	z-index:200;
-}
-
-.advSearchOptUL {
-	list-style : none;
-	margin: 0;
-	padding: 0;
-}
-
-.advSearchOptLIControl {
-	margin-left: 8px;
-	margin-right: 0px;
-	margin-top: 1px;
-	margin-bottom: 8px;
-	background : white;
-}
-
-.advSearchOptLILabel {
-	margin-left: 8px;
-	margin-right: 0px;
-	margin-top: 8px;
-	margin-bottom: 1px;
-	background : white;
-}
-
-.advSearchOptButton {
-	text-align: center;
-	vertical-align: baseline;
-    cursor: pointer;
-    border-radius:3px;
-    padding: 2px;
-}
-
 .inputCompletionUL {
 	list-style : none;
 	margin: 0;
diff --git a/bundles/org.eclipse.orion.client.ui/web/css/theme.css b/bundles/org.eclipse.orion.client.ui/web/css/theme.css
index e126d2e..c0062c8 100644
--- a/bundles/org.eclipse.orion.client.ui/web/css/theme.css
+++ b/bundles/org.eclipse.orion.client.ui/web/css/theme.css
@@ -323,6 +323,9 @@
 	border-radius: 3px;

 	border: 1px solid #DDD;

 	padding: 0;

+	background-color: white;

+	padding: 10px;

+	box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);

 }

 

 .dropdownMenuOpen {

@@ -347,12 +350,12 @@
 .dropdownMenu > li > a, .dropdownMenu > li > span {

 	width: 100%;

 	margin: 0;

-	padding: 4px 0;

 }

 

 .dropdownMenu > li > *:focus {

-	outline: 1px dotted #aaa;

+	outline: 1px dotted #ddd;

 	background: #f3f6fe;

+	padding-right:0;

 }

 

 .dropdownMenu > li:hover {

@@ -376,6 +379,7 @@
 	display: inline-block;

 	vertical-align: baseline;

 	color: #222 !important;

+	padding:5px;

 	-webkit-touch-callout: none;

 	-webkit-user-select: none;

 	-khtml-user-select: none;

@@ -507,8 +511,9 @@
 	z-index: 175;  /* less than tooltips, more than the rest */

 	position: absolute;

 	background-color: #fbfbfb;

-	border-radius: 3px;

+	border-radius: 2px;

 	border: 1px solid #BBB;

+	box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);

 }

 

 .dialogShowing {

@@ -525,14 +530,14 @@
 	background: #555;

 	width: 100%;

 	padding-bottom: 5px;

-	border-top-left-radius: 2px;

-	border-top-right-radius: 2px;

+	border-top-left-radius: 1px;

+	border-top-right-radius: 1px;

 }

 

 

 .dialogTitleText {

 	margin: 2px 2px 0;

-	color: silver;

+	color: whitesmoke;;

 	font-size: 1em;

 	height: 18px;

 	padding-left: 4px;

diff --git a/bundles/org.eclipse.orion.client.ui/web/edit/setup.js b/bundles/org.eclipse.orion.client.ui/web/edit/setup.js
index 9680375..c38da4a 100644
--- a/bundles/org.eclipse.orion.client.ui/web/edit/setup.js
+++ b/bundles/org.eclipse.orion.client.ui/web/edit/setup.js
@@ -12,17 +12,48 @@
 /*jslint browser:true devel:true*/
 /*global define eclipse:true orion:true window*/
 
-define(['i18n!orion/edit/nls/messages', 'require', 'orion/Deferred', 'orion/EventTarget', 'orion/webui/littlelib', 'orion/selection', 'orion/status', 'orion/progress', 'orion/dialogs',
-        'orion/commandRegistry', 'orion/favorites', 'orion/extensionCommands', 'orion/fileClient', 'orion/operationsClient', 'orion/searchClient', 'orion/globalCommands', 'orion/outliner',
-        'orion/problems', 'orion/editor/contentAssist', 'orion/editorCommands', 'orion/editor/editorFeatures', 'orion/editor/editor', 'orion/syntaxchecker',
-        'orion/editor/textView', 'orion/editor/textModel',
-        'orion/editor/projectionTextModel', 'orion/keyBinding','orion/searchAndReplace/textSearcher',
-        'orion/edit/dispatcher', 'orion/contentTypes', 'orion/PageUtil', 'orion/highlight', 'orion/i18nUtil', 'orion/edit/syntaxmodel', 'orion/objects',
-        'orion/widgets/themes/ThemePreferences', 'orion/widgets/themes/editor/ThemeData', 'orion/widgets/themes/editor/MiniThemeChooser', 'edit/editorPreferences', 'orion/sidebar'],
-		function(messages, require, Deferred, EventTarget, lib, mSelection, mStatus, mProgress, mDialogs, mCommandRegistry, mFavorites, mExtensionCommands, 
-				mFileClient, mOperationsClient, mSearchClient, mGlobalCommands, mOutliner, mProblems, mContentAssist, mEditorCommands, mEditorFeatures, mEditor,
-				mSyntaxchecker, mTextView, mTextModel, mProjectionTextModel, mKeyBinding, mSearcher,
-				mDispatcher, mContentTypes, PageUtil, Highlight, i18nUtil, SyntaxModelWirer, objects, mThemePreferences, mThemeData, mThemeChooser, mEditorPreferences, Sidebar) {
+define([
+	'i18n!orion/edit/nls/messages',
+	'require',
+	'orion/EventTarget',
+	'orion/webui/littlelib',
+	'orion/selection',
+	'orion/status',
+	'orion/progress',
+	'orion/dialogs',
+	'orion/commandRegistry',
+	'orion/favorites',
+	'orion/extensionCommands',
+	'orion/fileClient',
+	'orion/operationsClient',
+	'orion/searchClient',
+	'orion/globalCommands',
+	'orion/outliner',
+	'orion/problems',
+	'orion/editor/contentAssist',
+	'orion/editorCommands',
+	'orion/editor/editorFeatures',
+	'orion/editor/editor',
+	'orion/syntaxchecker',
+	'orion/editor/textView',
+	'orion/editor/textModel',
+	'orion/editor/projectionTextModel',
+	'orion/keyBinding',
+	'orion/searchAndReplace/textSearcher',
+	'orion/contentTypes',
+	'orion/PageUtil',
+	'orion/inputManager',
+	'orion/i18nUtil',
+	'orion/widgets/themes/ThemePreferences',
+	'orion/widgets/themes/editor/ThemeData',
+	'orion/widgets/themes/editor/MiniThemeChooser',
+	'edit/editorPreferences',
+	'orion/URITemplate',
+	'orion/sidebar'
+], function(messages, require, EventTarget, lib, mSelection, mStatus, mProgress, mDialogs, mCommandRegistry, mFavorites, mExtensionCommands, 
+			mFileClient, mOperationsClient, mSearchClient, mGlobalCommands, mOutliner, mProblems, mContentAssist, mEditorCommands, mEditorFeatures, mEditor,
+			mSyntaxchecker, mTextView, mTextModel, mProjectionTextModel, mKeyBinding, mSearcher,
+			mContentTypes, PageUtil, mInputManager, i18nUtil, mThemePreferences, mThemeData, mThemeChooser, mEditorPreferences, URITemplate, Sidebar) {
 	
 var exports = exports || {};
 	
@@ -37,8 +68,6 @@
 	var progressService;
 	var dialogService;
 	var favoriteService;
-	var syntaxHighlighter;
-	var syntaxModelWirer;
 	var fileClient;
 	var searcher;
 	
@@ -56,8 +85,6 @@
 		outlineService = new mOutliner.OutlineService({serviceRegistry: serviceRegistry, preferences: preferences});
 		favoriteService = new mFavorites.FavoritesService({serviceRegistry: serviceRegistry});
 		contentTypeService = new mContentTypes.ContentTypeService(serviceRegistry);
-		syntaxHighlighter = new Highlight.SyntaxHighlighter(serviceRegistry);
-		syntaxModelWirer = new SyntaxModelWirer(serviceRegistry);
 		fileClient = new mFileClient.FileClient(serviceRegistry);
 		searcher = new mSearchClient.Searcher({serviceRegistry: serviceRegistry, commandService: commandRegistry, fileService: fileClient});
 	}());
@@ -67,11 +94,12 @@
 		editorDomNode = lib.node("editor"), //$NON-NLS-0$
 		searchFloat = lib.node("searchFloat"); //$NON-NLS-0$
 
-	var editor;
+	var editor, inputManager;
 	var editorPreferences, settings;
 	var updateSettings = function(prefs) {
 		settings = prefs;
-		editor.setAutoSaveTimeout(prefs.autoSaveEnabled ? prefs.autoSaveTimeout : -1);
+		inputManager.setAutoLoadEnabled(prefs.autoLoadEnabled);
+		inputManager.setAutoSaveTimeout(prefs.autoSaveEnabled ? prefs.autoSaveTimeout : -1);
 	};
 	var updateEditorSettings = function (prefs) {
 		if (!prefs) {
@@ -81,6 +109,8 @@
 		}
 	};
 	editorPreferences = new mEditorPreferences.EditorPreferences (preferences, updateEditorSettings);
+	var themePreferences = new mThemePreferences.ThemePreferences(preferences, new mThemeData.ThemeData());
+	themePreferences.apply();
 	
 	var textViewFactory = function() {
 		var textView = new mTextView.TextView({
@@ -93,223 +123,6 @@
 		return textView;
 	};
 
-	var inputManager;
-	var InputManager = (function() {
-		/**
-		 * @name orion.editor.InputManager
-		 * @class
-		 */
-		function InputManager(editor) {
-			this.editor = editor;
-			this.lastFilePath = "";
-			this.dispatcher = null;
-			EventTarget.attach(this);
-		}
-		objects.mixin(InputManager.prototype, /** @lends orion.editor.InputManager.prototype */ {
-			setInput: function(location) {
-				function errorMessage(error) {
-					try {
-						error = JSON.parse(error.responseText);
-						return error.Message;
-					} catch(e) {}
-					return error.responseText;
-				}
-				function parseNumericParams(input, params) {
-					for (var i=0; i < params.length; i++) {
-						var param = params[i];
-						if (input[param]) {
-							input[param] = parseInt(input[param], 10);
-						}
-					}
-				}
-				var editor = this.editor;
-				if (location && location[0] !== "#") { //$NON-NLS-0$
-					location = "#" + location; //$NON-NLS-0$
-				}
-				this._lastHash = location;
-				var input = PageUtil.matchResourceParameters(location);
-				var fileURI = input.resource;
-				parseNumericParams(input, ["start", "end", "line", "offset", "length"]); //$NON-NLS-4$ //$NON-NLS-3$ //$NON-NLS-2$ //$NON-NLS-1$ //$NON-NLS-0$
-				// populate editor
-				if (fileURI) {
-					if (fileURI === this.lastFilePath) {
-						editor.showSelection(input.start, input.end, input.line, input.offset, input.length);
-					} else {
-						if (!editor.getTextView()) {
-							editor.installTextView();
-							editor.getTextView().addEventListener("Focus", this.focusListener.bind(this)); //$NON-NLS-0$
-						}
-						var fullPathName = fileURI;
-						var progressTimeout = setTimeout(function() {
-							editor.setInput(fullPathName, messages["Fetching "] + fullPathName, null);
-						}, 800); // wait 800ms before displaying
-						var self = this;
-						var load = function(results) {
-							var contentOrError = results[0];
-							var metadataOrError = results[1];
-							clearTimeout(progressTimeout);
-							if (contentOrError._error) {
-								console.error("HTTP status code: ", contentOrError._error.status); //$NON-NLS-0$
-								contentOrError = messages["An error occurred: "] + errorMessage(contentOrError._error);
-							}
-							if (metadataOrError._error) {
-								console.error("Error loading file metadata: " + errorMessage(metadataOrError._error)); //$NON-NLS-0$
-							}
-							self.setInputContents(input, fileURI, contentOrError, metadataOrError);
-							clearTimeout(progressTimeout);
-						};
-						new Deferred.all([progressService.progress(fileClient.read(fileURI), i18nUtil.formatMessage(messages.Reading, fileURI)), progressService.progress(fileClient.read(fileURI, true), i18nUtil.formatMessage(messages["Reading metedata of"], fileURI))], function(error) { return {_error: error}; }).then(load);
-					}
-					this.lastFilePath = fileURI;
-				} else {
-					editor.setInput(messages["No File Selected"], "", null);
-				}
-			},
-			setInputContents: function(input, title, contents, metadata) {
-				// TODO could potentially dispatch separate events for metadata and contents changing
-				this.dispatchEvent({ type: "InputChanged", metadata: metadata, contents: contents }); //$NON-NLS-0$
-				var editor = this.editor;
-				var altPageTarget, name;
-				if (metadata) {
-					this._fileMetadata = metadata;
-					var toolbar = lib.node("pageActions"); //$NON-NLS-0$
-					if (toolbar) {	
-						commandRegistry.destroy(toolbar);
-						// now add any "orion.navigate.command" commands that should be shown in non-nav pages.
-						mExtensionCommands.createAndPlaceFileCommandsExtension(serviceRegistry, commandRegistry, "pageActions", 500).then(function() { //$NON-NLS-1$ //$NON-NLS-0$
-							commandRegistry.renderCommands("pageActions", toolbar, metadata, editor, "button"); //$NON-NLS-1$ //$NON-NLS-0$
-						});							}
-					var rightToolbar = lib.node("pageNavigationActions"); //$NON-NLS-0$
-					if (rightToolbar) {	
-						commandRegistry.destroy(rightToolbar);
-						commandRegistry.renderCommands(rightToolbar.id, rightToolbar, editor, editor, "button");  // use true when we want to force toolbar items to text //$NON-NLS-0$
-					}
-					this.setTitle(metadata.Location || String(metadata));
-					this._contentType = contentTypeService.getFileContentType(metadata);
-					// page target is the file, but if any interesting links fail, try the parent folder metadata.
-					altPageTarget = function() {
-						if (metadata.Parents && metadata.Parents.length > 0) {
-							return progressService.progress(fileClient.read(metadata.Parents[0].Location, true), i18nUtil.formatMessage(messages["Reading metedata of"], metadata.Parents[0].Location));
-						}
-					};
-					name = metadata.Name;
-				} else {
-					// No metadata
-					this._fileMetadata = null;
-					this.setTitle(title);
-					this._contentType = contentTypeService.getFilenameContentType(this.getTitle());
-					name = this.getTitle();
-				}
-
-				var themePreferences = new mThemePreferences.ThemePreferences(preferences, new mThemeData.ThemeData());
-				themePreferences.apply();
-				var chooser = new mThemeChooser.MiniThemeChooser( themePreferences, editorPreferences );
-				mGlobalCommands.addSettings( chooser );
-
-				mGlobalCommands.setPageTarget({task: "Coding", name: name, target: metadata,  //$NON-NLS-0$
-					makeAlternate: function() {
-						if (metadata.Parents && metadata.Parents.length > 0) {
-							// The mini-nav in sidebar wants to do the same work, can we share it?
-							return progressService.progress(fileClient.read(metadata.Parents[0].Location, true), i18nUtil.formatMessage(messages["Reading metedata of"], metadata.Parents[0].Location));
-						}
-					},
-					serviceRegistry: serviceRegistry, commandService: commandRegistry,
-					searchService: searcher, fileService: fileClient});
-				mGlobalCommands.setDirtyIndicator(false);
-				var _self = this;
-				syntaxHighlighter.setup(this._contentType, editor.getTextView(), editor.getAnnotationModel(), title, true)
-					.then(function() {
-						// TODO folding should be a preference.
-						var styler = syntaxHighlighter.getStyler();
-						editor.setFoldingEnabled(styler && styler.foldingEnabled);
-						_self.dispatchEvent({ type: "ContentTypeChanged", contentType: _self._contentType, location: location }); //$NON-NLS-0$
-						if (!this.dispatcher) {
-							this.dispatcher = new mDispatcher.Dispatcher(serviceRegistry, editor, _self._contentType);
-						}
-						// Contents
-						editor.setInput(title, null, contents);
-						editor.showSelection(input.start, input.end, input.line, input.offset, input.length);
-						commandRegistry.processURL(window.location.href);
-					});
-			},
-			focusListener: function(e) {
-				if (!settings.autoLoadEnabled) { return; }
-				var fileURI = this.getInput();
-				progressService.progress(fileClient.read(fileURI, true), i18nUtil.formatMessage(messages["Reading metedata of"], fileURI)).then(function(data) {
-					if (this.getFileMetadata().ETag !== data.ETag) {
-						this._fileMetadata = data;
-						var editor = this.editor;
-						if (!editor.isDirty() || confirm(messages.loadOutOfSync)) {
-							progressService.progress(fileClient.read(fileURI), i18nUtil.formatMessage(messages.Reading, fileURI)).then(function(contents) {
-								editor.setInput(fileURI, null, contents);										
-							});
-						}
-					}
-				}.bind(this));
-			},
-			getInput: function() {
-				return this.lastFilePath;
-			},
-			setTitle : function(title) {
-				var indexOfSlash = title.lastIndexOf("/"); //$NON-NLS-0$
-				var shortTitle = title;
-				if (indexOfSlash !== -1) {
-					shortTitle = shortTitle.substring(indexOfSlash + 1);
-				}
-				this._lastTitle = shortTitle;
-			},
-			
-			getTitle: function() {
-				return this._lastTitle;
-			},
-			getFileMetadata: function() {
-				return this._fileMetadata;
-			},
-			getContentType: function() {
-				return this._contentType;
-			},
-			setDirty: function(dirty) {
-				mGlobalCommands.setDirtyIndicator(dirty);
-			},
-			hashChanged: function() {
-				var editor = this.editor;
-				var oldInput = this.getInput();
-				selection.setSelections(window.location.hash); // may prompt, change input, or both //$NON-NLS-0$
-				var newHash = window.location.hash;
-				var newInput = this.getInput();
-				var inputChanged = PageUtil.matchResourceParameters(oldInput).resource !== PageUtil.matchResourceParameters(newInput).resource; //$NON-NLS-1$ //$NON-NLS-0$
-				var hashMatchesInput = PageUtil.matchResourceParameters(newInput).resource === PageUtil.matchResourceParameters(newHash).resource; //$NON-NLS-1$ //$NON-NLS-0$
-				if (!inputChanged && !hashMatchesInput) {
-					window.location.hash = this._lastHash[0] === "#" ? this._lastHash.substring(1): this._lastHash; //$NON-NLS-0$
-				} else if (inputChanged) {
-					this.setInput(newHash, editor);
-					this._lastHash = newHash;
-				} else {
-					// Input didn't change and input matches hash, just remember the current hash
-					this._lastHash = newHash;
-				}
-			},
-			shouldGoToURI: function(fileURI) {
-				if (typeof fileURI !== "string") { //$NON-NLS-0$
-					return false;
-				}
-				if (this.editor.isDirty()) {
-					var oldStripped = PageUtil.matchResourceParameters("#" + this.lastFilePath).resource; //$NON-NLS-0$
-					var newStripped = PageUtil.matchResourceParameters(fileURI).resource;
-					if (oldStripped !== newStripped) {
-						return window.confirm(messages["There are unsaved changes.  Do you still want to navigate away?"]);
-					}
-				}
-				return true;
-			},
-			getEditor: function() {
-				return this.editor;
-			}
-		});
-		return InputManager;
-	}());
-
-
 	var tabHandler = {
 		handlers: [],
 		
@@ -523,13 +336,12 @@
 			statusReportingService.setMessage(message, null, isAccessible);
 		}
 	};
-	var annotationFactory = new mEditorFeatures.AnnotationFactory();
 	
 	editor = new mEditor.Editor({
 		textViewFactory: textViewFactory,
 		undoStackFactory: new mEditorCommands.UndoCommandFactory(serviceRegistry, commandRegistry, "pageActions"), //$NON-NLS-0$
 		textDNDFactory: new mEditorFeatures.TextDNDFactory(),
-		annotationFactory: annotationFactory,
+		annotationFactory: new mEditorFeatures.AnnotationFactory(),
 		foldingRulerFactory: new mEditorFeatures.FoldingRulerFactory(),
 		lineNumberRulerFactory: new mEditorFeatures.LineNumberRulerFactory(),
 		contentAssistFactory: contentAssistFactory,
@@ -541,12 +353,76 @@
 	// Editor Settings
 	updateEditorSettings();
 	
-	inputManager = new InputManager(editor);
+	inputManager = new mInputManager.InputManager({
+		editor: editor,
+		serviceRegistry: serviceRegistry,
+		fileClient: fileClient,
+		progressService: progressService,
+		selection: selection,
+		contentTypeService: contentTypeService
+	});
+	inputManager.addEventListener("InputChanged", function(evt) { //$NON-NLS-0$
+		var metadata = evt.metadata;
+		if (metadata) {
+			var toolbar = lib.node("pageActions"); //$NON-NLS-0$
+			if (toolbar) {
+				commandRegistry.destroy(toolbar);
+				// now add any "orion.navigate.command" commands that should be shown in non-nav pages.
+				mExtensionCommands.createAndPlaceFileCommandsExtension(serviceRegistry, commandRegistry, "pageActions", 500).then(function() { //$NON-NLS-1$ //$NON-NLS-0$
+					commandRegistry.renderCommands("pageActions", toolbar, metadata, editor, "button"); //$NON-NLS-1$ //$NON-NLS-0$
+				});
+			}
+			var rightToolbar = lib.node("pageNavigationActions"); //$NON-NLS-0$
+			if (rightToolbar) {	
+				commandRegistry.destroy(rightToolbar);
+				commandRegistry.renderCommands(rightToolbar.id, rightToolbar, editor, editor, "button");  // use true when we want to force toolbar items to text //$NON-NLS-0$
+			}
+		}
+		var chooser = new mThemeChooser.MiniThemeChooser( themePreferences, editorPreferences );
+		mGlobalCommands.addSettings( chooser );
+		mGlobalCommands.setPageTarget({
+			task: "Coding", //$NON-NLS-0$
+			name: evt.name,
+			target: metadata,
+			makeAlternate: function() {
+				if (metadata.Parents && metadata.Parents.length > 0) {
+					// The mini-nav in sidebar wants to do the same work, can we share it?
+					return progressService.progress(fileClient.read(metadata.Parents[0].Location, true), i18nUtil.formatMessage(messages["Reading metedata of"], metadata.Parents[0].Location));
+				}
+			},
+			makeBreadcrumbLink: function(/**HTMLAnchorElement*/ segment, folderLocation, folder) {
+				var top = !folderLocation && !folder;
+				// Link to this page (edit page)
+				segment.href = new URITemplate("#{,Resource,params*}").expand({ //$NON-NLS-0$
+					Resource: inputManager.getInput(),
+					params: {
+						navigate: top ? "" : folder.ChildrenLocation //$NON-NLS-0$
+					}
+				});
+			},
+			serviceRegistry: serviceRegistry,
+			commandService: commandRegistry,
+			searchService: searcher,
+			fileService: fileClient
+		});
+		commandRegistry.processURL(window.location.href);
+	});
 
+	// Sidebar
+	function SidebarNavInputManager() {
+		EventTarget.attach(this);
+	}
+	SidebarNavInputManager.prototype.processHash = function() {
+		var newParams = PageUtil.matchResourceParameters(location.hash), navigate = newParams.navigate;
+		if (typeof navigate === "string") { //$NON-NLS-0$
+			this.dispatchEvent({type: "InputChanged", input: navigate}); //$NON-NLS-0$
+		}
+	};
+	var sidebarNavInputManager = new SidebarNavInputManager();
 	var sidebar = new Sidebar({
 		commandRegistry: commandRegistry,
 		contentTypeRegistry: contentTypeService,
-		inputManager: inputManager,
+		editorInputManager: inputManager,
 		editor: editor,
 		fileClient: fileClient,
 		outlineService: outlineService,
@@ -554,6 +430,7 @@
 		progressService: progressService,
 		selection: selection,
 		serviceRegistry: serviceRegistry,
+		sidebarNavInputManager: sidebarNavInputManager,
 		toolbar: sidebarToolbar
 	});
 	sidebar.show();
@@ -568,15 +445,20 @@
 	});
 	
 	// Generically speaking, we respond to changes in selection.  New selections change the editor's input.
-	selection.addEventListener("selectionChanged", function(event) { //$NON-NLS-1$ //$NON-NLS-0$
+	selection.addEventListener("selectionChanged", function(event) { //$NON-NLS-0$
 		var fileURI = event.selection;
 		if (inputManager.shouldGoToURI(fileURI)) {
 			inputManager.setInput(fileURI);
 		} 
 	});
 	
-	window.addEventListener("hashchange", function() {inputManager.hashChanged();}, false); //$NON-NLS-0$
+	window.addEventListener("hashchange", function() { inputManager.hashChanged(); }, false); //$NON-NLS-0$
+	window.addEventListener("hashchange", function() { //$NON-NLS-0$
+		// inform the sidebar
+		sidebarNavInputManager.processHash(window.location.hash);
+	});
 	inputManager.setInput(window.location.hash);
+	sidebarNavInputManager.processHash(window.location.hash);
 	
 	mGlobalCommands.generateBanner("orion-editor", serviceRegistry, commandRegistry, preferences, searcher, editor, editor, escHandler); //$NON-NLS-0$
 	// Put the make favorite command in our toolbar."
diff --git a/bundles/org.eclipse.orion.client.ui/web/orion/breadcrumbs.js b/bundles/org.eclipse.orion.client.ui/web/orion/breadcrumbs.js
index 702f189..ae22edb 100644
--- a/bundles/org.eclipse.orion.client.ui/web/orion/breadcrumbs.js
+++ b/bundles/org.eclipse.orion.client.ui/web/orion/breadcrumbs.js
@@ -110,7 +110,7 @@
 						}
 						this.path += parents[i].Name; 
 						if(this._makeHref) {
-							this._makeHref(seg , parents[i].Location);
+							this._makeHref(seg , parents[i].Location, parents[i]);
 						}
 						else {
 							seg.href = require.toUrl("navigate/table.html") +"#" + parents[i].ChildrenLocation; //$NON-NLS-1$ //$NON-NLS-0$
diff --git a/bundles/org.eclipse.orion.client.ui/web/orion/commandRegistry.js b/bundles/org.eclipse.orion.client.ui/web/orion/commandRegistry.js
index f1e9ed3..e39df7b 100644
--- a/bundles/org.eclipse.orion.client.ui/web/orion/commandRegistry.js
+++ b/bundles/org.eclipse.orion.client.ui/web/orion/commandRegistry.js
@@ -17,9 +17,10 @@
 
 	/**
 	 * Constructs a new command registry with the given options.
-	 * @param {Object} options The registry options object which includes an optional selection service.
 	 * @class CommandRegistry can render commands appropriate for a particular scope and DOM element.
-	 * @name orion.commandRegistry.CommandRegistry
+	 * @name orion.commandregistry.CommandRegistry
+	 * @param {Object} options The registry options object
+	 * @param {orion.selection.Selection} [options.selection] Optional selection service.
 	 */
 	function CommandRegistry(options) {
 		this._commandList = {};
@@ -29,7 +30,7 @@
 		this._init(options);
 		this._parameterCollector = null;
 	}
-	CommandRegistry.prototype = /** @lends orion.commands.CommandRegistry.prototype */ {
+	CommandRegistry.prototype = /** @lends orion.commandregistry.CommandRegistry.prototype */ {
 		_init: function(options) {
 			this._selectionService = options.selection;
 			var self = this;
@@ -65,6 +66,10 @@
 			}
 		},
 		
+		/**
+		 * @param {String} commandId
+		 * @returns {orion.commands.Command}
+		 */
 		findCommand: function(commandId) {
 			return this._commandList[commandId];
 		}, 
@@ -73,8 +78,8 @@
 		 * Run the command with the specified commandId.
 		 *
 		 * @param {String} commandId the id of the command to run.
-		 * @param {Object} the item on which the command should run.
-		 * @param {Object} the handler for the command.
+		 * @param {Object} item the item on which the command should run.
+		 * @param {Object} handler the handler for the command.
 		 * @param {orion.commands.ParametersDescription} parameters used on this invocation.  Optional.
 		 *
 		 * Note:  The current implementation will only run the command if a URL binding has been
@@ -105,7 +110,42 @@
 		getSelectionService: function() {
 			return this._selectionService;
 		},
-		
+
+
+		/**
+		 * Interface for a parameter collector.
+		 * @name orion.commandregistry.ParameterCollector
+		 * @class
+		 */
+		/**
+		 * Open a parameter collector and return the dom node where parameter information should be inserted.
+		 * @name orion.commandregistry.ParameterCollector#open
+		 * @function
+		 * @param {String|DOMElement} commandNode the node containing the triggering command
+		 * @param {Function} fillFunction a function that will fill the parameter area
+		 * @param {Function} onClose a function that will be called when the parameter area is closed
+		 * @returns {Boolean} Whether the node is open.
+		 */
+		/**
+		 * Closes any active parameter collectors.
+		 * @name orion.commandregistry.ParameterCollector#close
+		 * @function
+		 */
+		/**
+		 * Returns a function that can be used to fill a specified parent node with parameter information.
+		 * @name orion.commandregistry.ParameterCollector#getFillFunction
+		 * @function
+		 * @param {orion.commands.CommandInvocation} the command invocation used when gathering parameters
+		 * @param {Function} closeFunction an optional function called when the area must be closed. 
+		 * @returns {Function} a function that can fill the specified dom node with parameter collection behavior
+		 */
+		/**
+		 * Collect parameters for the given command.
+		 * @name orion.commandregistry.ParameterCollector#collectParameters
+		 * @function
+		 * @param {orion.commands.CommandInvocation} commandInvocation The command invocation
+		 * @returns {Boolean} Whether or not required parameters were collected.
+		 */
 		/**
 		 * Provide an object that can collect parameters for a given "tool" command.  When a command that
 		 * describes its required parameters is shown in a toolbar (as an image, button, or link), clicking
@@ -114,14 +154,12 @@
 		 * appropriate for the page architecture.  If no parameterCollector is specified, then the command callback
 		 * will be responsible for collecting parameters.
 		 *
-		 * @param {Object} parameterCollector a collector which implements <code>open(commandNode, id, fillFunction)</code>,
-		 *  <code>close(commandNode)</code>, <code>getFillFunction(commandInvocation)</code>, and <code>collectParameters(commandInvocation)</code>.
-		 *
+		 * @param {orion.commandregistry.ParameterCollector} parameterCollector
 		 */
 		setParameterCollector: function(parameterCollector) {
 			this._parameterCollector = parameterCollector;
 		},
-				
+
 		/**
 		 * Open a parameter collector suitable for collecting information about a command.
 		 * Once a collector is created, the specified function is used to fill it with
@@ -201,7 +239,6 @@
 		 * because the command framework will open and close parameter collectors as needed and 
 		 * call the command callback with the values of those parameters.
 		 */
-
 		closeParameterCollector: function() {
 			if (this._parameterCollector) {
 				this._parameterCollector.close();
@@ -211,7 +248,7 @@
 		/**
 		 * Returns whether this registry has been configured to collect command parameters
 		 *
-		 * @returns whether or not this registry is configured to collect parameters.
+		 * @returns {Boolean} whether or not this registry is configured to collect parameters.
 		 */
 		collectsParameters: function() {
 			return this._parameterCollector;
@@ -287,15 +324,15 @@
 		 *
 		 * {@link orion.commands.ParametersDescription}
 		 *
-		 * @param {orion.commands.CommandInvocation} the current invocation of the command 
+		 * @param {orion.commands.CommandInvocation} commandInvocation the current invocation of the command 
 		 */
 		collectParameters: function(commandInvocation) {
 			this._collectAndInvoke(commandInvocation, true); 
 		},
 		
 		/**
-		 * Show the keybindings that are registered with the command registry inside the specified domNode.
-		 * @param targetNode {DOMElement} the dom node where the key bindings should be shown.
+		 * Show the keybindings that are registered with the command registry inside the specified target node.
+		 * @param {DOMElement} targetNode the dom node where the key bindings should be shown.
 		 */
 		showKeyBindings: function(targetNode) {
 			var scopes = {};
@@ -339,7 +376,7 @@
 		/** 
 		 * Add a command to the command registry.  Nothing will be shown in the UI
 		 * until this command is referenced in a contribution.
-		 * @param command {Command} the command being added.
+		 * @param {orion.commands.Command} command The command being added.
 		 */
 		addCommand: function(command) {
 			this._commandList[command.id] = command;
@@ -425,7 +462,7 @@
 		 *  a path of "group1Id/group2Id/command" indicates that the command belongs as a child of 
 		 *  group2Id, which is itself a child of group1Id.  Optional.
 		 * @param {boolean} [bindingOnly=false] if true, then the command is never rendered, but the key or URL binding is hooked.
-		 * @param {orion.KeyBinding} [keyBinding] a keyBinding for the command.  Optional.
+		 * @param {orion.editor.KeyBinding} [keyBinding] a keyBinding for the command.  Optional.
 		 * @param {orion.commands.URLBinding} [urlBinding] a url binding for the command.  Optional.
 		 */
 		registerCommandContribution: function(scopeId, commandId, position, parentPath, bindingOnly, keyBinding, urlBinding) {
@@ -501,7 +538,7 @@
 		 * @param {String} renderType The style in which the command should be rendered.  "tool" will render
 		 *  a tool image in the dom.  "button" will render a text button.  "menu" will render menu items.  
 		 * @param {Object} [userData] Optional user data that should be attached to generated command callbacks
-		 * @param {Array} [domNodeWrapperList] Optional an array used to record any DOM nodes that are rendered during this call.
+		 * @param {Object[]} [domNodeWrapperList] Optional an array used to record any DOM nodes that are rendered during this call.
 		 *  If an array is provided, then as commands are rendered, an object will be created to represent the command's node.  
 		 *  The object will always have the property "domNode" which contains the node created for the command.  If the command is
 		 *  rendered using other means (toolkit widget) then the optional property "widget" should contain the toolkit
@@ -818,6 +855,7 @@
 		 * of commands.  This function is useful when a page is precisely arranging groups of commands
 		 * (in a table or contiguous spans) and needs to use the same separator that the command registry
 		 * would use when rendering different groups of commands.
+		 * @param {DOMElement} parent
 		 */
 		generateSeparatorImage: function(parent) {
 			var sep;
diff --git a/bundles/org.eclipse.orion.client.ui/web/orion/compare/compareCommands.js b/bundles/org.eclipse.orion.client.ui/web/orion/compare/compareCommands.js
index bd30ba8..090f422 100644
--- a/bundles/org.eclipse.orion.client.ui/web/orion/compare/compareCommands.js
+++ b/bundles/org.eclipse.orion.client.ui/web/orion/compare/compareCommands.js
@@ -20,7 +20,7 @@
  * @name orion.compare.CompareCommandFactory
  * @class Represents a command renderer to render all commands and key bindings of the command view.
  * @property {String} options.commandSpanId The DOM element id where the commands are rendered. Required.
- * @property {orion.commandRegistry.CommandRegistry} options.commandService The command service that is used to register all the commands. Required.
+ * @property {orion.commandregistry.CommandRegistry} options.commandService The command service that is used to register all the commands. Required.
  */
 exports.CompareCommandFactory = (function() {
 	function CompareCommandFactory(options){
diff --git a/bundles/org.eclipse.orion.client.ui/web/orion/compare/resourceComparer.js b/bundles/org.eclipse.orion.client.ui/web/orion/compare/resourceComparer.js
index 654810b..f4f675e 100644
--- a/bundles/org.eclipse.orion.client.ui/web/orion/compare/resourceComparer.js
+++ b/bundles/org.eclipse.orion.client.ui/web/orion/compare/resourceComparer.js
@@ -13,8 +13,8 @@
 /*jslint forin:true regexp:false sub:true*/
 
 define(['i18n!orion/compare/nls/messages', 'require', 'orion/Deferred', 'orion/webui/littlelib', 'orion/compare/compareUtils', 'orion/compare/diffProvider', 'orion/compare/compareView', 'orion/highlight', 
-		'orion/fileClient', 'orion/globalCommands', 'orion/commands', 'orion/keyBinding', 'orion/searchAndReplace/textSearcher', 'orion/editorCommands', 'orion/editor/editorFeatures', 'orion/URL-shim'], 
-		function(messages, require, Deferred, lib, mCompareUtils, mDiffProvider, mCompareView, Highlight, mFileClient, mGlobalCommands, mCommands, mKeyBinding, mSearcher, mEditorCommands, mEditorFeatures) {
+		'orion/fileClient', 'orion/globalCommands', 'orion/commands', 'orion/keyBinding', 'orion/searchAndReplace/textSearcher', 'orion/editorCommands', 'orion/objects', 'orion/inputManager', 'orion/editor/editorFeatures', 'orion/URL-shim'], 
+		function(messages, require, Deferred, lib, mCompareUtils, mDiffProvider, mCompareView, Highlight, mFileClient, mGlobalCommands, mCommands, mKeyBinding, mSearcher, mEditorCommands, objects, mInputManager, mEditorFeatures) {
 
 var exports = {};
 
@@ -128,7 +128,12 @@
 		}
 		this.initExtCmds();
 		var that = this;
-		this._inputManager = {
+		this._inputManager = new mInputManager.InputManager({
+			serviceRegistry: serviceRegistry,
+			fileClient: that._fileClient,
+			progressService: that._progress
+		});
+		objects.mixin(this._inputManager, {
 			filePath: "",
 			getInput: function() {
 				return this.filePath;
@@ -142,6 +147,10 @@
 				return this._fileMetadata;
 			},
 			
+			getEditor: function() {
+				return that._compareView.getWidget().getEditors()[1];
+			},
+						
 			setInput: function(fileURI, editor) {
 				that._progress.progress(that._fileClient.read(fileURI, true), "Getting file metadata " + fileURI).then( //$NON-NLS-0$
 					function(metadata) {
@@ -185,7 +194,7 @@
 				that._compareView.getWidget().options.newFile.Content = newContents;
 				that._compareView.getWidget().refresh();
 			}
-		};
+		});
 		if(!options.readonly && !options.toggleable && this._compareView.getWidget().type === "twoWay") { //$NON-NLS-0$
 			var keyBindingFactory = function(editor, keyModeStack, undoStack, contentAssist) {
 				var localSearcher = new mSearcher.TextSearcher(editor, that._commandService, undoStack);
diff --git a/bundles/org.eclipse.orion.client.ui/web/orion/editorCommands.js b/bundles/org.eclipse.orion.client.ui/web/orion/editorCommands.js
index 33f5896..d9ce749 100644
--- a/bundles/org.eclipse.orion.client.ui/web/orion/editorCommands.js
+++ b/bundles/org.eclipse.orion.client.ui/web/orion/editorCommands.js
@@ -75,93 +75,31 @@
 				}
 			}
 
-			function handleError(error) {
-				var errorToDisplay = {};
-				errorToDisplay.Severity = "Error"; //$NON-NLS-0$
-				if (error.status === 0) {
-					errorToDisplay.Message = messages['No response from server.  Check your internet connection and try again.']; //$NON-NLS-1$
-				} else {
-					errorToDisplay = error;
-				}
-				handleStatus(errorToDisplay, true /*allow HTML for auth errors*/);
-			}
-
 			// create commands common to all editors
 			if (!this.isReadOnly) {
 				editor.getTextView().setKeyBinding(new mKeyBinding.KeyBinding('s', true), "save"); //$NON-NLS-1$ //$NON-NLS-0$
 				//If we are introducing other file system to provide save action, we need to define an onSave function in the input manager
 				//That way the file system knows how to implement their save mechanism
 				var self = this;
-				if (this.inputManager.onSave) {
-					editor.getTextView().setAction("save", function () { //$NON-NLS-0$
-						editor.reportStatus(messages['Saving...']);
+				editor.getTextView().setAction("save", function () { //$NON-NLS-0$
+					if (self.inputManager.save) {
+						self.inputManager.save();
+					} else if (self.inputManager.onSave) {
 						var contents = editor.getText();
 						self.inputManager.onSave(self.inputManager.getInput(), contents,
 							function(result) {
 								editor.setInput(self.inputManager.getInput(), null, contents, true);
-								editor.reportStatus("");
 								if(self.inputManager.afterSave){
 									self.inputManager.afterSave();
 								}
 							},
 							function(error) {
-								editor.reportStatus("");
 								error.log = true;
 							}
 						);
-						return true;
-					}, {name: messages['Save']});
-				} else {
-					editor.getTextView().setAction("save", function () { //$NON-NLS-0$
-						editor.reportStatus(messages['Saving...']);
-						var contents = editor.getText();
-						var etag = self.inputManager.getFileMetadata().ETag;
-						var args = { "ETag" : etag }; //$NON-NLS-0$
-						var def = self.fileClient.write(self.inputManager.getInput(), contents, args);
-						var progress = self.serviceRegistry.getService("orion.page.progress"); //$NON-NLS-0$
-						if(progress){
-							progress.progress(def, i18nUtil.formatMessage(messages['Saving file {0}'], self.inputManager.getInput()));
-						}
-						def.then(
-							function(result) {
-								self.inputManager.getFileMetadata().ETag = result.ETag;
-								editor.setInput(self.inputManager.getInput(), null, contents, true);
-								editor.reportStatus("");
-								if(self.inputManager.afterSave){
-									self.inputManager.afterSave();
-								}
-							},
-							function(error) {
-								// expected error - HTTP 412 Precondition Failed 
-								// occurs when file is out of sync with the server
-								if (error.status === 412) {
-									var forceSave = confirm(messages["Resource is out of sync with the server. Do you want to save it anyway?"]);
-									if (forceSave) {
-										// repeat save operation, but without ETag 
-										var def = self.fileClient.write(self.inputManager.getInput(), contents);
-										if(progress){
-											progress.progress(def, i18nUtil.formatMessage(messages['Saving file {0}'], self.inputManager.getInput()));
-										}
-										def.then(
-											function(result) {
-												self.inputManager.getFileMetadata().ETag = result.ETag;
-												editor.setInput(self.inputManager.getInput(), null, contents, true);
-												editor.reportStatus("");
-												if(self.inputManager.afterSave){
-													self.inputManager.afterSave();
-												}
-											}, handleError);
-									}
-								} else {
-									// unknown error
-									editor.reportStatus("");
-									handleError(error);
-								}
-							}
-						);
-						return true;
-					}, {name: messages['Save']});
-				}
+					}
+					return true;
+				}, {name: messages['Save']});
 				var saveCommand = new mCommands.Command({
 					name: messages['Save'],
 					tooltip: messages["Save this file"],
diff --git a/bundles/org.eclipse.orion.client.ui/web/orion/explorers/explorer.js b/bundles/org.eclipse.orion.client.ui/web/orion/explorers/explorer.js
index 3580567..73a8555 100644
--- a/bundles/org.eclipse.orion.client.ui/web/orion/explorers/explorer.js
+++ b/bundles/org.eclipse.orion.client.ui/web/orion/explorers/explorer.js
@@ -27,7 +27,7 @@
 	 * use for any services required by the explorer
 	 * @param {orion.selection.Selection} selection The initial selection
 	 * @param renderer
-	 * @param {orion.commandRegistry.CommandRegistry} commandRegistry The command registry to use for commands.  Optional.
+	 * @param {orion.commandregistry.CommandRegistry} commandRegistry The command registry to use for commands.  Optional.
 	 */
 	function Explorer(serviceRegistry, selection, renderer, commandRegistry) {
 		this.registry = serviceRegistry;
diff --git a/bundles/org.eclipse.orion.client.ui/web/orion/explorers/navigatorRenderer.js b/bundles/org.eclipse.orion.client.ui/web/orion/explorers/navigatorRenderer.js
index 8ddc64a..1d407b0 100644
--- a/bundles/org.eclipse.orion.client.ui/web/orion/explorers/navigatorRenderer.js
+++ b/bundles/org.eclipse.orion.client.ui/web/orion/explorers/navigatorRenderer.js
@@ -131,7 +131,7 @@
 	 * @description Renderer for a tree-table of files, like the Orion Navigator.

 	 * @param {Object} options

 	 * @param {orion.explorer.Explorer} explorer

-	 * @param {orion.commandRegistry.CommandRegistry} commandRegistry

+	 * @param {orion.commandregistry.CommandRegistry} commandRegistry

 	 * @param {orion.core.ContentTypeService} contentTypeService

 	 */

 	function NavigatorRenderer (options, explorer, commandService, contentTypeService) {

diff --git a/bundles/org.eclipse.orion.client.ui/web/orion/extensionCommands.js b/bundles/org.eclipse.orion.client.ui/web/orion/extensionCommands.js
index c910d14..083e378 100644
--- a/bundles/org.eclipse.orion.client.ui/web/orion/extensionCommands.js
+++ b/bundles/org.eclipse.orion.client.ui/web/orion/extensionCommands.js
@@ -413,7 +413,7 @@
 	 * @name orion.extensionCommands.createAndPlaceFileCommandsExtension
 	 * @function
 	 * @param {orion.serviceregistry.ServiceReference} serviceRegistry
-	 * @param {orion.commandRegistry.CommandRegistry} commandRegistry
+	 * @param {orion.commandregistry.CommandRegistry} commandRegistry
 	 * @param {String} toolbarId
 	 * @param {Number} position
 	 * @param {String} commandGroup
diff --git a/bundles/org.eclipse.orion.client.ui/web/orion/fileCommands.js b/bundles/org.eclipse.orion.client.ui/web/orion/fileCommands.js
index a51977a..7726af8 100644
--- a/bundles/org.eclipse.orion.client.ui/web/orion/fileCommands.js
+++ b/bundles/org.eclipse.orion.client.ui/web/orion/fileCommands.js
@@ -232,7 +232,7 @@
 	/**
 	 * Creates the commands related to file management.
 	 * @param {orion.serviceregistry.ServiceRegistry} serviceRegistry The service registry to use when creating commands
-	 * @param {orion.commandRegistry.CommandRegistry} commandRegistry The command registry to get commands from
+	 * @param {orion.commandregistry.CommandRegistry} commandRegistry The command registry to get commands from
 	 * @param {orion.explorer.Explorer} explorer The explorer view to add commands to
 	 * @param {orion.fileClient.FileClient} fileClient The file system client that the commands should use
 	 * @name orion.fileCommands#createFileCommands
diff --git a/bundles/org.eclipse.orion.client.ui/web/orion/globalCommands.js b/bundles/org.eclipse.orion.client.ui/web/orion/globalCommands.js
index e943630..558eb4c 100644
--- a/bundles/org.eclipse.orion.client.ui/web/orion/globalCommands.js
+++ b/bundles/org.eclipse.orion.client.ui/web/orion/globalCommands.js
@@ -231,7 +231,6 @@
 	
 		var relatedlinks = lib.node('relatedlinks');
 		lib.empty( relatedlinks );
-//		relatedlinks.innerHTML = '';
 	
 		var contentTypesCache;
 		function getContentTypes() {
@@ -682,99 +681,6 @@
 			});
 		}
 		
-		// hook up search box: 1.The search box itself 2.Default search proposal provider(recent and saved search) 
-		//                     3.Extended proposal provider from plugins 4.Search options(open result in new tab, reg ex, recent&saved searc hfull list)
-		var searchField = lib.node("search"); //$NON-NLS-0$
-		if (!searchField) {
-			throw "failed to generate HTML for banner"; //$NON-NLS-0$
-		}
-		// this stuff
-		searchField.setAttribute("placeholder", messages['Search']); //$NON-NLS-1$ //$NON-NLS-0$
-		new mTooltip.Tooltip({
-			node: searchField,
-			text: messages["Type a keyword or wild card to search in root"],
-			position: ["below", "left"] //$NON-NLS-1$ //$NON-NLS-0$
-		});
-		var advSearchOptContainer = new mAdvSearchOptContainer.advSearchOptContainer(searchField, searcher, serviceRegistry,
-									{group: "advancedSearch"});//$NON-NLS-0$
-
-		//Required. Reading recent&saved search from user preference. Once done call the uiCallback
-		var defaultProposalProvider = function(uiCallback){
-			mSearchUtils.getMixedSearches(serviceRegistry, true, false, function(searches){
-				var i, fullSet = [], hasSavedSearch = false, hasRecentSearch = false;
-				for (i in searches) {
-					if(searches[i].label && searches[i].value){
-						if(!hasSavedSearch){
-							fullSet.push({type: "category", label: messages["Saved searches"]});//$NON-NLS-0$
-							hasSavedSearch = true;
-						}
-						fullSet.push({type: "proposal", value: {name: searches[i].label, value: require.toUrl("search/search.html") + "#" + searches[i].value, type: "link"}});  //$NON-NLS-3$ //$NON-NLS-2$ //$NON-NLS-1$ //$NON-NLS-0$
-						//fullSet.push({type: "proposal", label: searches[i].label, value: searches[i].name});//$NON-NLS-0$
-					} else {
-						if(!hasRecentSearch){
-							fullSet.push({type: "category", label: messages["Recent searches"]});//$NON-NLS-0$
-							hasRecentSearch = true;
-						}
-						fullSet.push({type: "proposal", label: searches[i].name, value: searches[i].name});//$NON-NLS-0$
-					}
-				}
-				uiCallback(fullSet);
-			});
-		};
-		//Optional. Reading extended search proposals by asking plugins, if any.
-		//If there are multiple plugins then merge all the proposals and call uiCallBack.
-		//Plugins(with service id "orion.search.proposal") should define the property "filterForMe" to true or false. Which means:
-		//If true the inputCompletion class will filter the proposals returned by the plugin.
-		//If false the inputCompletion class assumes that the proposals are already filtered by hte given kerword. 
-		//The false case happens when a plugin wants to use the keyword to ask for a set of filtered proposal from a web service by the keyword and Orion does not need to filter it again.
-		var exendedProposalProvider = function(keyWord, uiCallback){
-			var serviceReferences = serviceRegistry.getServiceReferences("orion.search.proposal"); //$NON-NLS-0$
-			if(!serviceReferences || serviceReferences.length === 0){
-				uiCallback(null);
-				return;
-			}
-            var promises = [];
-			serviceReferences.forEach(function(serviceRef) {
-				var filterForMe = serviceRef.getProperty("filterForMe");  //$NON-NLS-0$
-				promises.push( serviceRegistry.getService(serviceRef).run(keyWord).then(function(returnValue) {
-					//The return value has to be an array of {category : string, datalist: [string,string,string...]}
-					var proposalList = {filterForMe: filterForMe, proposals: []};
-					for (var i = 0; i < returnValue.length; i++) {
-						proposalList.proposals.push({type: "category", label: returnValue[i].category});//$NON-NLS-0$
-						for (var j = 0; j < returnValue[i].datalist.length; j++) {
-							proposalList.proposals.push({type: "proposal", label: returnValue[i].datalist[j], value: returnValue[i].datalist[j]});//$NON-NLS-0$
-						}
-					}
-					return proposalList;
-				}));
-			});
-			Deferred.all(promises).then(function(returnValues) {
-				//Render UI
-				uiCallback(returnValues);
-			});
-		};
-		//Create and hook up the inputCompletion instance with the search box dom node.
-		//The defaultProposalProvider provides proposals from the recent and saved searches.
-		//The exendedProposalProvider provides proposals from plugins.
-		new mInputCompletion.InputCompletion(searchField, defaultProposalProvider,
-									{group: "globalSearch", extendedProvider: exendedProposalProvider}); //$NON-NLS-0$
-		//Both inputCompletion and here are listening keydown events on searchField
-		//But here listener should yield to inputCompletion on its "already handled" events.
-		searchField.addEventListener("keydown", function(e) { //$NON-NLS-0$
-			if(e.defaultPrevented){// If the key event was handled by other listeners and preventDefault was set on(e.g. input completion handled ENTER), we do not handle it here
-				return;
-			}
-			var keyCode= e.charCode || e.keyCode;
-			if (keyCode === 13 ) {// ENTER
-				mSearchUtils.doSearch(searcher, serviceRegistry, searchField.value);
-			} 
-		});
-		//Finally, hook up search options
-		_addAdvancedSearchButton(advSearchOptContainer);
-		lib.addAutoDismiss([lib.node(advSearchOptContainer.containerId), lib.node("advancedSearchDropDown")], function() { //$NON-NLS-0$
-			advSearchOptContainer.dismiss();
-		});
-
 		// hook up split behavior - the splitter widget and the associated global command/key bindings.
 		var splitNode = lib.$(".split"); //$NON-NLS-0$
 		if (splitNode) {
diff --git a/bundles/org.eclipse.orion.client.ui/web/orion/globalSearch/advSearchOptContainer.js b/bundles/org.eclipse.orion.client.ui/web/orion/globalSearch/advSearchOptContainer.js
index d5b96ac..4108b70 100644
--- a/bundles/org.eclipse.orion.client.ui/web/orion/globalSearch/advSearchOptContainer.js
+++ b/bundles/org.eclipse.orion.client.ui/web/orion/globalSearch/advSearchOptContainer.js
@@ -11,12 +11,12 @@
 /*global define window document XMLHttpRequest*/
 /*jslint sub:true*/
 
-define(['i18n!orion/globalSearch/nls/messages', 'require', 'orion/searchUtils', 'orion/contentTypes', 'orion/i18nUtil', 'text!orion/globalSearch//advSearchOpt.html'], function(messages, require, mSearchUtils, mContentTypes, i18nUtil, optionTemplate){
+define(['i18n!orion/globalSearch/nls/messages', 'require', 'orion/searchUtils', 'orion/contentTypes', 'orion/i18nUtil', 'orion/webui/littlelib', 'orion/inputCompletion/inputCompletion', 'orion/Deferred', 'text!orion/globalSearch/advSearchOpt.html'], 
+		function(messages, require, mSearchUtils, mContentTypes, i18nUtil, lib, mInputCompletion, Deferred, optionTemplate){
 
 	function advSearchOptRenderer(searcher, serviceRegistry, cancelCallBack) {
 		this._searcher = searcher;
 		this._serviceRegistry = serviceRegistry;
-		this._cancelCallBack = cancelCallBack;
 	}
 	
 	advSearchOptRenderer.prototype.getOptions = function(){
@@ -27,31 +27,89 @@
 		};
 	};
 
-	advSearchOptRenderer.prototype.render = function(parentDiv, htmlTemplate){
+	advSearchOptRenderer.prototype.render = function(parentDiv){
 		this._parentDiv = parentDiv;
-		if (typeof(this._parentDiv) === "string") { //$NON-NLS-0$
-			this._parentDiv = document.getElementById(this._parentDiv);
-		}
 		var contentTypeService = this._serviceRegistry.getService("orion.core.contenttypes"); //$NON-NLS-0$
 		if(!contentTypeService){
 			contentTypeService = new mContentTypes.ContentTypeService(this._serviceRegistry);
 			this.contentTypesCache = contentTypeService.getContentTypes();
-			this._render(htmlTemplate);
+			this._render();
 		} else {
 			var that = this;
 			contentTypeService.getContentTypes().then(function(ct) {
 				that.contentTypesCache = ct;
-				that._render(htmlTemplate);
+				that._render();
 			});
 		}
 	};
 
-	advSearchOptRenderer.prototype._render = function(htmlTemplate){
-		if(htmlTemplate){
-			this._renderHTML(htmlTemplate);
-		} else {
-			this._renderRaw();
-		}
+	advSearchOptRenderer.prototype._render = function(){
+		this._parentDiv.innerHTML = optionTemplate;
+		this._initHTMLLabels();
+	    this._initControls();
+		this._searchBox.focus();
+		
+		//Required. Reading recent&saved search from user preference. Once done call the uiCallback
+		var defaultProposalProvider = function(uiCallback){
+			mSearchUtils.getMixedSearches(this._serviceRegistry, true, false, function(searches){
+				var i, fullSet = [], hasSavedSearch = false, hasRecentSearch = false;
+				for (i in searches) {
+					if(searches[i].label && searches[i].value){
+						if(!hasSavedSearch){
+							fullSet.push({type: "category", label: messages["Saved searches"]});//$NON-NLS-0$
+							hasSavedSearch = true;
+						}
+						fullSet.push({type: "proposal", value: {name: searches[i].label, value: require.toUrl("search/search.html") + "#" + searches[i].value, type: "link"}});  //$NON-NLS-3$ //$NON-NLS-2$ //$NON-NLS-1$ //$NON-NLS-0$
+						//fullSet.push({type: "proposal", label: searches[i].label, value: searches[i].name});//$NON-NLS-0$
+					} else {
+						if(!hasRecentSearch){
+							fullSet.push({type: "category", label: messages["Recent searches"]});//$NON-NLS-0$
+							hasRecentSearch = true;
+						}
+						fullSet.push({type: "proposal", label: searches[i].name, value: searches[i].name});//$NON-NLS-0$
+					}
+				}
+				uiCallback(fullSet);
+			});
+		}.bind(this);
+		//Optional. Reading extended search proposals by asking plugins, if any.
+		//If there are multiple plugins then merge all the proposals and call uiCallBack.
+		//Plugins(with service id "orion.search.proposal") should define the property "filterForMe" to true or false. Which means:
+		//If true the inputCompletion class will filter the proposals returned by the plugin.
+		//If false the inputCompletion class assumes that the proposals are already filtered by hte given kerword. 
+		//The false case happens when a plugin wants to use the keyword to ask for a set of filtered proposal from a web service by the keyword and Orion does not need to filter it again.
+		var exendedProposalProvider = function(keyWord, uiCallback){
+			var serviceReferences = this._serviceRegistry.getServiceReferences("orion.search.proposal"); //$NON-NLS-0$
+			if(!serviceReferences || serviceReferences.length === 0){
+				uiCallback(null);
+				return;
+			}
+            var promises = [];
+            var renderer = this;
+			serviceReferences.forEach(function(serviceRef) {
+				var filterForMe = serviceRef.getProperty("filterForMe");  //$NON-NLS-0$
+				promises.push( this._serviceRegistry.getService(serviceRef).run(keyWord).then(function(returnValue) {
+					//The return value has to be an array of {category : string, datalist: [string,string,string...]}
+					var proposalList = {filterForMe: filterForMe, proposals: []};
+					for (var i = 0; i < returnValue.length; i++) {
+						proposalList.proposals.push({type: "category", label: returnValue[i].category});//$NON-NLS-0$
+						for (var j = 0; j < returnValue[i].datalist.length; j++) {
+							proposalList.proposals.push({type: "proposal", label: returnValue[i].datalist[j], value: returnValue[i].datalist[j]});//$NON-NLS-0$
+						}
+					}
+					return proposalList;
+				}));
+			}.bind(renderer));
+			Deferred.all(promises).then(function(returnValues) {
+				//Render UI
+				uiCallback(returnValues);
+			});
+		}.bind(this);
+		//Create and hook up the inputCompletion instance with the search box dom node.
+		//The defaultProposalProvider provides proposals from the recent and saved searches.
+		//The exendedProposalProvider provides proposals from plugins.
+		new mInputCompletion.InputCompletion(this._searchBox, defaultProposalProvider,
+									{group: "globalSearch", extendedProvider: exendedProposalProvider}); //$NON-NLS-0$
 	};
 	
 	advSearchOptRenderer.prototype._submitSearch = function(){
@@ -88,11 +146,6 @@
 			if (keyCode === 13 ) {// ENTER
 				that._submitSearch();
 			} 
-			if (keyCode === 27 ) {// ESC
-				if(that._cancelCallBack){
-					that._cancelCallBack();
-				}
-			} 
 		});
 		
 		this._fileTypes.addEventListener("change", function(e) { //$NON-NLS-0$
@@ -118,98 +171,17 @@
 		document.getElementById("advSearchSubmit").value = messages["Search"]; //$NON-NLS-1$ //$NON-NLS-0$
 	};
 	
-	advSearchOptRenderer.prototype._renderHTML = function(htmlTemplate){
-		var that = this;
-		var xhr = new XMLHttpRequest();
-		xhr.open('GET', require.toUrl(htmlTemplate), true); //$NON-NLS-0$
-		xhr.onreadystatechange = function() {
-		    if (this.readyState !== 4) {return;}
-		    if (this.status !== 200) {return;}
-		    that._parentDiv.innerHTML = this.responseText;
-		    that._initHTMLLabels();
-		    that._initControls();
-		};
-		xhr.send();	
-	};
-	
-	advSearchOptRenderer.prototype._renderRaw = function(){
-		this._parentDiv.innerHTML = optionTemplate;
-		this._initHTMLLabels();
-	    this._initControls();
-	};
-	
 	advSearchOptRenderer.prototype.constructor = advSearchOptRenderer;
 	/**
-	 * advSearchOptContainer is the drop down container for all advanced search options.
-	 * When binded with an html input element, it provides the search advanced options for the input field.
-	 * @param {DOMElement} inputFieldOrId The "text" type input html element. This is required.
+	 * advSearchOptContainer is the container for all search options.
+	 * @param {String|DOMElement} parent the parent element for the container, it can be either a DOM element or an ID for a DOM element.
 	 */
-	function advSearchOptContainer(inputFieldOrId, searcher, serviceRegistry, options) {
-		this._inputField = inputFieldOrId;
-		if (typeof(this._inputField) === "string") { //$NON-NLS-0$
-			this._inputField = document.getElementById(this._inputField);
-		}
-		var idFrefix = options ? options.group: null;
-		if(!idFrefix){
-			if(this._inputField.id){
-				idFrefix = this._inputField.id;
-			} else {
-				idFrefix = "default__dropDown__group"; //$NON-NLS-0$
-			}
-		}
-		this._idPrefix = idFrefix + "__dropDown__"; //$NON-NLS-0$
-		this.containerId = this._idPrefix + "UIContainer"; //$NON-NLS-0$
-		this._dismissed = true;
-		var that = this;
-		this._optRenderer = new advSearchOptRenderer(searcher, serviceRegistry, function(){that.dismiss();that._inputField.focus();});
-		this._initUI();
+	function advSearchOptContainer(parent, searcher, serviceRegistry) {
+		this._parent = lib.node(parent);
+		this._optRenderer = new advSearchOptRenderer(searcher, serviceRegistry);
+		this._optRenderer.render(this._parent);	
 	}
 	
-	advSearchOptContainer.prototype._initUI = function(){
-		this._optUIContainer = document.getElementById(this.containerId);
-		if(!this._optUIContainer){
-			this._optUIContainer = document.createElement('div'); //$NON-NLS-0$
-			this._optUIContainer.id = this.containerId;
-			this._optUIContainer.style.display = "none"; //$NON-NLS-0$
-			this._optUIContainer.className = "advSearchOptContainer"; //$NON-NLS-0$
-			document.body.appendChild(this._optUIContainer);
-			this._optRenderer.render(this._optUIContainer/*, 'orion/globalSearch/advSearchOpt.html'*/);			
-		}
-	};
-
-	
-	advSearchOptContainer.prototype.dismiss = function(valueToInputField){
-		this._dismissed = true;
-		this._optUIContainer.style.display = "none"; //$NON-NLS-0$
-	};
-	
-	advSearchOptContainer.prototype.show = function(defaultSearchStr){
-		var curLeft=0, curTop=0;
-		var offsetParent = this._inputField;
-		while (offsetParent) {
-			curLeft += offsetParent.offsetLeft;
-			curTop += offsetParent.offsetTop;
-	        offsetParent = offsetParent.offsetParent;
-		}
-		this._optUIContainer.style.display = "block"; //$NON-NLS-0$
-		this._optUIContainer.style.top = curTop + this._inputField.offsetHeight + 2 + "px"; //$NON-NLS-0$
-		this._optUIContainer.style.left = curLeft + "px"; //$NON-NLS-0$
-		this._optUIContainer.style.width = this._inputField.offsetWidth + "px"; //$NON-NLS-0$
-		
-		this._optRenderer._searchBox.value = defaultSearchStr;
-		this._optRenderer._searchBox.focus();
-		this._mouseDown = false;
-		this._dismissed = false;
-	};
-	
-	advSearchOptContainer.prototype.toggle = function(){
-		if(this._dismissed){
-			this.show(this._inputField.value);
-		} else {
-			this.dismiss();
-		}
-	};
-		
 	advSearchOptContainer.prototype.constructor = advSearchOptContainer;
 	
 	//return module exports
diff --git a/bundles/org.eclipse.orion.client.ui/web/orion/globalSearch/globalSearch.css b/bundles/org.eclipse.orion.client.ui/web/orion/globalSearch/globalSearch.css
index 3ca1e13..61aed18 100644
--- a/bundles/org.eclipse.orion.client.ui/web/orion/globalSearch/globalSearch.css
+++ b/bundles/org.eclipse.orion.client.ui/web/orion/globalSearch/globalSearch.css
@@ -71,3 +71,57 @@
 	visibility: visible; 
 }
 
+.outlinerSplitLayout {
+	position: absolute;
+	top: 50%;  
+	width: 100%;
+	z-index: 50;
+	height: 3px;
+	cursor: n-resize;
+	background: #dedede;
+	visibility: visible; 
+}
+
+.advSearchOptContainer {
+	color: black;
+	display: block;
+	border:  1px solid #666;
+	background: white;
+	max-height: 300px;
+	max-width: 300px;
+	min-width: 150px;
+	position: absolute;
+	overflow-y: auto;
+	overflow-x: hidden;
+	padding: 2px;
+	z-index:200;
+}
+
+.advSearchOptUL {
+	list-style : none;
+	margin: 0;
+	padding: 0;
+}
+
+.advSearchOptLIControl {
+	margin-left: 8px;
+	margin-right: 0px;
+	margin-top: 1px;
+	margin-bottom: 8px;
+}
+
+.advSearchOptLILabel {
+	margin-left: 8px;
+	margin-right: 0px;
+	margin-top: 8px;
+	margin-bottom: 1px;
+}
+
+.advSearchOptButton {
+	text-align: center;
+	vertical-align: baseline;
+    cursor: pointer;
+    border-radius:3px;
+    padding: 2px;
+}
+
diff --git a/bundles/org.eclipse.orion.client.ui/web/orion/globalSearch/searchBuilder.html b/bundles/org.eclipse.orion.client.ui/web/orion/globalSearch/searchBuilder.html
new file mode 100644
index 0000000..fd26708
--- /dev/null
+++ b/bundles/org.eclipse.orion.client.ui/web/orion/globalSearch/searchBuilder.html
@@ -0,0 +1,33 @@
+<ul class="advSearchOptUL">

+	<li class="advSearchOptLILabel">

+		<label id="advSearchLabel" ></label>

+	</li>

+	<li class="advSearchOptLIControl">

+		<input type="text" id="advSearchInput"></input>

+		<label>On Root</label>

+		<input type="button" class="advSearchOptButton" value="change directory" id="advSearchChange"></input>

+	</li>

+	<li class="advSearchOptLIControl">

+		<label id="advSearchTypeLabel" ></label>

+		<select id="advSearchTypes"></select>

+	</li>

+	<li class="advSearchOptLIControl">

+		<label id="advSearchCaseSensitiveLabel" ></label>

+		<input type="checkbox" id="advSearchCaseSensitive"></input>

+	</li>

+	<li class="advSearchOptLIControl">

+		<label id="advSearchRegExLabel" ></label>

+		<input type="checkbox" id="advSearchRegEx"></input>

+	</li>

+	<li class="advSearchOptLIControl">

+		<input type="button" class="advSearchOptButton" id="advSearchSubmit"></input>

+	</li>

+	<li class="advSearchOptLIControl">

+		<input type="button" class="advSearchOptButton" value="Replace with" id="advSearchReplace"></input>

+		<input type="text" id="advSearchReplaceInput"></input>

+	</li>

+	<li class="advSearchOptLIControl">

+		<input type="button" class="advSearchOptButton" value="Save as" id="advSearchSaveAs"></input>

+		<input type="text" id="advSearchSaveInput"></input>

+	</li>

+</ul>

diff --git a/bundles/org.eclipse.orion.client.ui/web/orion/inputManager.js b/bundles/org.eclipse.orion.client.ui/web/orion/inputManager.js
new file mode 100644
index 0000000..feb2486
--- /dev/null
+++ b/bundles/org.eclipse.orion.client.ui/web/orion/inputManager.js
@@ -0,0 +1,352 @@
+/*******************************************************************************

+ * @license

+ * Copyright (c) 2010, 2013 IBM Corporation and others.

+ * All rights reserved. This program and the accompanying materials are made 

+ * available under the terms of the Eclipse Public License v1.0 

+ * (http://www.eclipse.org/legal/epl-v10.html), and the Eclipse Distribution 

+ * License v1.0 (http://www.eclipse.org/org/documents/edl-v10.html). 

+ *

+ * Contributors:

+ *     IBM Corporation - initial API and implementation

+ *******************************************************************************/

+

+/*global define window */

+

+define([

+	'i18n!orion/edit/nls/messages',

+	'orion/i18nUtil',

+	'orion/Deferred',

+	'orion/EventTarget',

+	'orion/objects',

+	'orion/globalCommands',

+	'orion/edit/dispatcher',

+	'orion/highlight',

+	'orion/edit/syntaxmodel',

+	'orion/PageUtil'

+], function(messages, i18nUtil, Deferred, EventTarget, objects, mGlobalCommands, mDispatcher, Highlight, SyntaxModelWirer, PageUtil) {

+

+	function Idle(options){

+		this._document = options.document || document;

+		this._timeout = options.timeout;

+		//TODO: remove listeners if there are no clients

+		//TODO: add support for multiple clients with different timeouts

+		var events = ["keypress","keydown","keyup","mousemove","mousedown","mousemove"]; //$NON-NLS-0$ //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$ //$NON-NLS-4$ //$NON-NLS-5$

+		var reset = function (e) { this._resetTimer(); }.bind(this);

+		for (var i=0; i<events.length; i++) {

+			var event = events[i];

+			this._document.addEventListener(event, reset, true);	

+		}

+		EventTarget.attach(this);

+	}

+	

+	Idle.prototype = {

+		_resetTimer: function() {

+			var window = this._document.defaultView || this._document.parentWindow;

+			if (this._timer) {

+				window.clearTimeout(this._timer);

+				this._timer = null;

+			}

+			if (this._timeout !== -1) {

+				this._timer = window.setTimeout(function() {

+					this.onIdle({type:"Idle"});	//$NON-NLS-0$ 

+					this._timer = null;

+					this._resetTimer();

+				}.bind(this), this._timeout);

+			}

+		},

+		onIdle: function (idleEvent) {

+			return this.dispatchEvent(idleEvent);

+		},

+		setTimeout: function(timeout) {

+			this._timeout = timeout;

+			this._resetTimer();

+		}

+	};

+	

+	/**

+	 * @name orion.editor.InputManager

+	 * @class

+	 */

+	function InputManager(options) {

+		this.editor = options.editor;

+		this.serviceRegistry = options.serviceRegistry;

+		this.fileClient = options.fileClient;

+		this.progressService = options.progressService;

+		this.contentTypeService = options.contentTypeService;

+		this.selection = options.selection;

+		this.syntaxHighlighter = new Highlight.SyntaxHighlighter(this.serviceRegistry);

+		this.syntaxModelWirer = new SyntaxModelWirer(this.serviceRegistry);

+		this.lastFilePath = "";

+		this.dispatcher = null;

+		EventTarget.attach(this);

+	}

+	objects.mixin(InputManager.prototype, /** @lends orion.editor.InputManager.prototype */ {

+		setInput: function(location) {

+			function errorMessage(error) {

+				try {

+					error = JSON.parse(error.responseText);

+					return error.Message;

+				} catch(e) {}

+				return error.responseText;

+			}

+			function parseNumericParams(input, params) {

+				for (var i=0; i < params.length; i++) {

+					var param = params[i];

+					if (input[param]) {

+						input[param] = parseInt(input[param], 10);

+					}

+				}

+			}

+			var editor = this.getEditor();

+			if (location && location[0] !== "#") { //$NON-NLS-0$

+				location = "#" + location; //$NON-NLS-0$

+			}

+			this._lastHash = location;

+			var input = PageUtil.matchResourceParameters(location);

+			var fileURI = input.resource;

+			parseNumericParams(input, ["start", "end", "line", "offset", "length"]); //$NON-NLS-4$ //$NON-NLS-3$ //$NON-NLS-2$ //$NON-NLS-1$ //$NON-NLS-0$

+			// populate editor

+			if (fileURI) {

+				if (fileURI === this.lastFilePath) {

+					editor.showSelection(input.start, input.end, input.line, input.offset, input.length);

+				} else {

+					if (!editor.getTextView()) {

+						editor.installTextView();

+						editor.getTextView().addEventListener("Focus", this._checkContents.bind(this)); //$NON-NLS-0$

+					}

+					var fullPathName = fileURI;

+					var progressTimeout = window.setTimeout(function() {

+						editor.setInput(fullPathName, messages["Fetching "] + fullPathName, null);

+					}, 800); // wait 800ms before displaying

+					var self = this;

+					var load = function(results) {

+						var contentOrError = results[0];

+						var metadataOrError = results[1];

+						window.clearTimeout(progressTimeout);

+						if (contentOrError._error) {

+							window.console.error("HTTP status code: ", contentOrError._error.status); //$NON-NLS-0$

+							contentOrError = messages["An error occurred: "] + errorMessage(contentOrError._error);

+						}

+						if (metadataOrError._error) {

+							window.console.error("Error loading file metadata: " + errorMessage(metadataOrError._error)); //$NON-NLS-0$

+						}

+						self._setInputContents(input, fileURI, contentOrError, metadataOrError);

+						window.clearTimeout(progressTimeout);

+					};

+					var fileClient = this.fileClient;

+					var progressService = this.progressService;

+					new Deferred.all([

+						progressService.progress(fileClient.read(fileURI), i18nUtil.formatMessage(messages.Reading, fileURI)),

+						progressService.progress(fileClient.read(fileURI, true), i18nUtil.formatMessage(messages["Reading metedata of"], fileURI))

+					], function(error) { return {_error: error}; }).then(load);

+				}

+				this.lastFilePath = fileURI;

+			} else {

+				editor.setInput(messages["No File Selected"], "", null);

+			}

+		},

+		_setInputContents: function(input, title, contents, metadata) {

+			var editor = this.getEditor();

+			var name;

+			if (metadata) {

+				this._fileMetadata = metadata;

+				this.setTitle(metadata.Location || String(metadata));

+				this._contentType = this.contentTypeService.getFileContentType(metadata);

+				name = metadata.Name;

+			} else {

+				// No metadata

+				this._fileMetadata = null;

+				this.setTitle(title);

+				this._contentType = this.contentTypeService.getFilenameContentType(this.getTitle());

+				name = this.getTitle();

+			}

+			// TODO could potentially dispatch separate events for metadata and contents changing

+			this.dispatchEvent({ type: "InputChanged", name: name, metadata: metadata, contents: contents }); //$NON-NLS-0$

+			var self = this;

+			this.syntaxHighlighter.setup(this._contentType, editor.getTextView(), editor.getAnnotationModel(), title, true)

+				.then(function() {

+					// TODO folding should be a preference.

+					var styler = self.syntaxHighlighter.getStyler();

+					editor.setFoldingEnabled(styler && styler.foldingEnabled);

+					self.dispatchEvent({ type: "ContentTypeChanged", contentType: self._contentType, location: window.location }); //$NON-NLS-0$

+					if (!self.dispatcher) {

+						self.dispatcher = new mDispatcher.Dispatcher(self.serviceRegistry, editor, self._contentType);

+					}

+					// Contents

+					editor.setInput(title, null, contents);

+					editor.showSelection(input.start, input.end, input.line, input.offset, input.length);

+				});

+

+			this.setDirty(false);

+		},

+		_checkContents: function(e) {

+			if (!this._autoLoadEnabled) { return; }

+			var fileURI = this.getInput();

+			this.progressService.progress(this.fileClient.read(fileURI, true), i18nUtil.formatMessage(messages["Reading metedata of"], fileURI)).then(function(data) {

+				if (this.getFileMetadata().ETag !== data.ETag) {

+					this._fileMetadata = data;

+					var editor = this.getEditor();

+					if (!editor.isDirty() || window.confirm(messages.loadOutOfSync)) {

+						this.progressService.progress(this.fileClient.read(fileURI), i18nUtil.formatMessage(messages.Reading, fileURI)).then(function(contents) {

+							editor.setInput(fileURI, null, contents);										

+						});

+					}

+				}

+			}.bind(this));

+		},

+		getInput: function() {

+			return this.lastFilePath;

+		},

+		getTitle: function() {

+			return this._lastTitle;

+		},

+		getFileMetadata: function() {

+			return this._fileMetadata;

+		},

+		getContentType: function() {

+			return this._contentType;

+		},

+		setAutoLoadEnabled: function(enabled) {

+			this._autoLoadEnabled = enabled;

+		},

+		/**

+		 * Set the autosave timeout. If the timeout is <code>-1</code>, autosave is

+		 * disabled.

+		 * @param {Number} timeout - the autosave timeout in milliseconds

+		 */

+		setAutoSaveTimeout: function(timeout){

+			if (!this._idle) {

+				var editor = this.getEditor();

+				var document = editor.getTextView().getOptions("parent").ownerDocument; //$NON-NLS-0$

+				var options = {

+					document: document,

+					timeout: timeout

+				};

+				this._idle = new Idle(options);

+				this._idle.addEventListener("Idle", function () { //$NON-NLS-0$

+					if (editor.isDirty() && !this._saving) {

+						this.save();

+					}

+				}.bind(this));

+			}

+			this._idle.setTimeout(timeout);

+		},

+		setDirty: function(dirty) {

+			mGlobalCommands.setDirtyIndicator(dirty);

+		},

+		setTitle : function(title) {

+			var indexOfSlash = title.lastIndexOf("/"); //$NON-NLS-0$

+			var shortTitle = title;

+			if (indexOfSlash !== -1) {

+				shortTitle = shortTitle.substring(indexOfSlash + 1);

+			}

+			this._lastTitle = shortTitle;

+		},

+		_handleStatus: function(status, allowHTML) {

+			if (!allowHTML && status && typeof status.HTML !== "undefined") { //$NON-NLS-0$

+				delete status.HTML;

+			}

+			var statusService = this.serviceRegistry.getService("orion.page.message"); //$NON-NLS-0$

+			if (statusService) {

+				statusService.setProgressResult(status);

+			} else {

+				window.console.log(status);

+			}

+		},

+		_handleError: function(error) {

+			var errorToDisplay = {};

+			errorToDisplay.Severity = "Error"; //$NON-NLS-0$

+			if (error.status === 0) {

+				errorToDisplay.Message = messages['No response from server.  Check your internet connection and try again.']; //$NON-NLS-1$

+			} else {

+				errorToDisplay = error;

+			}

+			this.handleStatus(errorToDisplay, true /*allow HTML for auth errors*/);

+		},

+		save: function() {

+			this._saving = true;

+			var input = this.getInput();

+			var editor = this.getEditor();

+			editor.reportStatus(messages['Saving...']);

+			var contents = editor.getText();

+			var etag = this.getFileMetadata().ETag;

+			var args = { "ETag" : etag }; //$NON-NLS-0$

+			var def = this.fileClient.write(input, contents, args);

+			var progress = this.progressService;

+			if (progress) {

+				def = progress.progress(def, i18nUtil.formatMessage(messages['Saving file {0}'], input));

+			}

+			var self = this;

+			function successHandler(result) {

+				self.getFileMetadata().ETag = result.ETag;

+				editor.setInput(input, null, contents, true);

+				editor.reportStatus("");

+				if (self.afterSave) {

+					self.afterSave();

+				}

+				self._saving = false;

+			}

+			function errorHandler(error) {

+				editor.reportStatus("");

+				self.handleError(error);

+				self._saving = false;

+			}

+			def.then(successHandler, function(error) {

+				// expected error - HTTP 412 Precondition Failed 

+				// occurs when file is out of sync with the server

+				if (error.status === 412) {

+					var forceSave = window.confirm(messages["Resource is out of sync with the server. Do you want to save it anyway?"]);

+					if (forceSave) {

+						// repeat save operation, but without ETag 

+						var def = self.fileClient.write(input, contents);

+						if (progress) {

+							def = progress.progress(def, i18nUtil.formatMessage(messages['Saving file {0}'], input));

+						}

+						def.then(successHandler, errorHandler);

+					}

+				} else {

+					// unknown error

+					errorHandler(error);

+				}

+			});

+		},

+		hashChanged: function() {

+			var editor = this.getEditor();

+			var oldInput = this.getInput();

+			this.selection.setSelections(window.location.hash); // may prompt, change input, or both //$NON-NLS-0$

+			var newHash = window.location.hash;

+			var newInput = this.getInput();

+			var inputChanged = PageUtil.matchResourceParameters(oldInput).resource !== PageUtil.matchResourceParameters(newInput).resource; //$NON-NLS-1$ //$NON-NLS-0$

+			var hashMatchesInput = PageUtil.matchResourceParameters(newInput).resource === PageUtil.matchResourceParameters(newHash).resource; //$NON-NLS-1$ //$NON-NLS-0$

+			if (!inputChanged && !hashMatchesInput) {

+				window.location.hash = this._lastHash[0] === "#" ? this._lastHash.substring(1): this._lastHash; //$NON-NLS-0$

+			} else if (inputChanged) {

+				this.setInput(newHash, editor);

+				this._lastHash = newHash;

+			} else {

+				// Input didn't change and input matches hash, just remember the current hash

+				this._lastHash = newHash;

+			}

+		},

+		shouldGoToURI: function(fileURI) {

+			if (typeof fileURI !== "string") { //$NON-NLS-0$

+				return false;

+			}

+			var editor = this.getEditor();

+			if (editor.isDirty()) {

+				var oldStripped = PageUtil.matchResourceParameters("#" + this.lastFilePath).resource; //$NON-NLS-0$

+				var newStripped = PageUtil.matchResourceParameters(fileURI).resource;

+				if (oldStripped !== newStripped) {

+					return window.confirm(messages["There are unsaved changes.  Do you still want to navigate away?"]);

+				}

+			}

+			return true;

+		},

+		getEditor: function() {

+			return this.editor;

+		}

+	});

+	return {

+		InputManager: InputManager

+	};

+});

diff --git a/bundles/org.eclipse.orion.client.ui/web/orion/parameterCollectors.js b/bundles/org.eclipse.orion.client.ui/web/orion/parameterCollectors.js
index efe6227..bdd733c 100644
--- a/bundles/org.eclipse.orion.client.ui/web/orion/parameterCollectors.js
+++ b/bundles/org.eclipse.orion.client.ui/web/orion/parameterCollectors.js
@@ -17,11 +17,17 @@
 
 	
 	/**
-	 * Constructs a new command parameter collector
-	 * @class CommandParameterCollector can collect parameters in a way that is integrated with the 
-	 * common header elements of pages or sections.
-	 * @name orion.parameterCollectors.CommandParameterCollector
-	 * @param toolbarLayout  
+	 * Constructs a new command parameter collector.
+	 * @name orion.parametercollectors.CommandParameterCollector
+	 * @class <code>CommandParameterCollector</code> can collect parameters in a way that is integrated with the common 
+	 * header elements of pages or sections.
+	 * @param {Function} getElementsFunction
+	 * @param {Function} toolbarLayoutFunction
+	 * @extends orion.commandregistry.ParameterCollector
+	 * @borrows orion.commandregistry.ParameterCollector#close as #close
+	 * @borrows orion.commandregistry.ParameterCollector#collectParameters as #collectParameters
+	 * @borrows orion.commandregistry.ParameterCollector#getFillFunction as #getFillFunction
+	 * @borrows orion.commandregistry.ParameterCollector#open as #open
 	 */	
 	function CommandParameterCollector (getElementsFunction, toolbarLayoutFunction) {
 		this._activeContainer = null;
@@ -29,11 +35,8 @@
 		this._toolbarLayoutFunction = toolbarLayoutFunction;
 	}
 	
-	CommandParameterCollector.prototype =  {
+	CommandParameterCollector.prototype = /** @lends orion.parametercollectors.CommandParameterCollector.prototype */ {
 	
-		/**
-		 * Closes any active parameter collectors
-		 */
 		close: function () {
 			if (this._activeElements) {
 				if (this._activeElements.parameterArea) {
@@ -60,15 +63,6 @@
 			this._activeElements = null;
 		},
 		
-		
-		/**
-		 * Open a parameter collector and return the dom node where parameter 
-		 * information should be inserted
-		 *
-		 * @param {String|DOMElement} commandNode the node containing the triggering command
-		 * @param {Function} fillFunction a function that will fill the parameter area
-		 * @param {Function} onClose a function that will be called when the parameter area is closed
-		 */
 		open: function(commandNode, fillFunction, onClose) {
 			if (typeof commandNode === "string") { //$NON-NLS-0$
 				commandNode = lib.node(commandNode);
@@ -144,12 +138,6 @@
 
 		},
 		
-		/**
-		 * Collect parameters for the given command.
-		 * 
-		 * @param {orion.commands.CommandInvocation} the command invocation
-		 * @returns {Boolean} whether or not required parameters were collected.
-		 */
 		collectParameters: function(commandInvocation) {
 			if (commandInvocation.parameters) {
 				if (commandInvocation.domNode) {
@@ -160,14 +148,7 @@
 			return false;
 		},
 		
-		/**
-		 * Returns a function that can be used to fill a specified parent node with parameter information.
-		 *
-		 * @param {orion.commands.CommandInvocation} the command invocation used when gathering parameters
-		 * @param {Function} an optional function called when the area must be closed. 
-		 * @returns {Function} a function that can fill the specified dom node with parameter collection behavior
-		 */
-		 getFillFunction: function(commandInvocation, closeFunction) {
+		getFillFunction: function(commandInvocation, closeFunction) {
 			var self = this;
 			return function(parameterArea, dismissArea) {
 				var first = null;
diff --git a/bundles/org.eclipse.orion.client.ui/web/orion/searchOutliner.js b/bundles/org.eclipse.orion.client.ui/web/orion/searchOutliner.js
index e725d7b..9ac8c61 100644
--- a/bundles/org.eclipse.orion.client.ui/web/orion/searchOutliner.js
+++ b/bundles/org.eclipse.orion.client.ui/web/orion/searchOutliner.js
@@ -13,8 +13,8 @@
 /*jslint forin:true*/
 
 define(['i18n!orion/search/nls/messages', 'require', 'orion/webui/littlelib', 'orion/i18nUtil', 'orion/section', 'orion/commands', 'orion/commandRegistry', 
-	'orion/keyBinding', 'orion/selection', 'orion/explorers/explorer', 'orion/EventTarget'], 
-	function(messages, require, lib, i18nUtil, mSection, mCommands, mCommandRegistry, mKeyBinding, mSelection, mExplorer, EventTarget){
+	'orion/keyBinding', 'orion/selection', 'orion/explorers/explorer', 'orion/EventTarget', 'orion/globalSearch/advSearchOptContainer'], 
+	function(messages, require, lib, i18nUtil, mSection, mCommands, mCommandRegistry, mKeyBinding, mSelection, mExplorer, EventTarget, mAdvSearchOptContainer){
 
 	/**
 	 * Instantiates the saved search service. This service is used internally by the
@@ -292,10 +292,37 @@
 		}
 	};//end navigation outliner prototype
 	SearchOutliner.prototype.constructor = SearchOutliner;
+	
+	/**
+	 * Creates a new user interface element to build all the search options and do the search
+	 *
+	 * @name orion.Searches.SearchBuilder
+	 * @class A user interface element building a search.
+	 * @param {Object} options The service options
+	 * @param {Object} options.parent The parent DOM node or id to hold all the builder controls
+	 * @param {orion.serviceregistry.ServiceRegistry} options.serviceRegistry The service registry
+	 */
+	function SearchBuilder(options) {
+		var parent = lib.node(options.parent);
+		if (!parent) { throw "no parent"; } //$NON-NLS-0$
+		if (!options.serviceRegistry) {throw "no service registry"; } //$NON-NLS-0$
+		this._parent = parent;
+		this._registry = options.serviceRegistry;
+		var reg = options.serviceRegistry;
+		this.commandService = options.commandService;
+		this.advSearchOptContainer = new mAdvSearchOptContainer.advSearchOptContainer(this._parent, options.searcher, this._registry);
+	}
+	SearchBuilder.prototype = /** @lends orion.navoutliner.SearchOutliner.prototype */ {
+
+		render: function(searches, serviceRegistry) {
+		}
+	};//end navigation outliner prototype
+	SearchBuilder.prototype.constructor = SearchOutliner;
 
 	//return module exports
 	return {
 		SavedSearches: SavedSearches,
-		SearchOutliner: SearchOutliner
+		SearchOutliner: SearchOutliner,
+		SearchBuilder: SearchBuilder
 	};
 });
diff --git a/bundles/org.eclipse.orion.client.ui/web/orion/sidebar.js b/bundles/org.eclipse.orion.client.ui/web/orion/sidebar.js
index 274e635..895ac12 100644
--- a/bundles/org.eclipse.orion.client.ui/web/orion/sidebar.js
+++ b/bundles/org.eclipse.orion.client.ui/web/orion/sidebar.js
@@ -8,14 +8,15 @@
 	 * @name orion.sidebar.Sidebar
 	 * @class Sidebar that appears alongside an {@link orion.editor.Editor} in the Orion IDE.
 	 * @param {Object} params
-	 * @param {orion.commandRegistry.CommandRegistry} params.commandRegistry
+	 * @param {orion.commandregistry.CommandRegistry} params.commandRegistry
 	 * @param {orion.core.ContentTypeService} params.contentTypeRegistry
 	 * @param {orion.fileClient.FileClient} params.fileClient
-	 * @param {orion.editor.InputManager} params.inputManager
+	 * @param {orion.editor.InputManager} params.editorInputManager
 	 * @param {orion.outliner.OutlineService} params.outlineService
 	 * @param {orion.progress.ProgressService} params.progressService
 	 * @param {orion.selection.Selection} params.selection
 	 * @param {orion.serviceregistry.ServiceRegistry} params.serviceRegistry
+	 * @param {Object} [params.sidebarNavInputManager]
 	 * @param {Element|String} params.parent
 	 * @param {Element|String} params.toolbar
 	 */
@@ -25,12 +26,13 @@
 		this.contentTypeRegistry = params.contentTypeRegistry;
 		this.editor = params.editor;
 		this.fileClient = params.fileClient;
-		this.inputManager = params.inputManager;
+		this.editorInputManager = params.editorInputManager;
 		this.outlineService = params.outlineService;
 		this.parentNode = lib.node(params.parent);
 		this.toolbarNode = lib.node(params.toolbar);
 		this.selection = params.selection;
 		this.serviceRegistry = params.serviceRegistry;
+		this.sidebarNavInputManager = params.sidebarNavInputManager;
 		this.viewModes = {};
 		this.activeViewMode = null;
 		this.modeContributionToolbar = null;
@@ -46,7 +48,7 @@
 			var commandRegistry = this.commandRegistry;
 			var contentTypeRegistry = this.contentTypeRegistry;
 			var fileClient = this.fileClient;
-			var inputManager = this.inputManager;
+			var editorInputManager = this.editorInputManager;
 			var outlineService = this.outlineService;
 			var parentNode = this.parentNode;
 			var progressService = this.progressService;
@@ -80,8 +82,9 @@
 				commandRegistry: commandRegistry,
 				contentTypeRegistry: contentTypeRegistry,
 				fileClient: fileClient,
-				inputManager: inputManager,
+				editorInputManager: editorInputManager,
 				parentNode: parentNode,
+				sidebarNavInputManager: this.sidebarNavInputManager,
 				selection: selection,
 				serviceRegistry: serviceRegistry,
 				toolbarNode: modeContributionToolbar
@@ -96,7 +99,7 @@
 				outlineService: outlineService,
 				commandService: commandRegistry,
 				selectionService: selection,
-				inputManager: inputManager,
+				inputManager: editorInputManager,
 				progressService: progressService,
 				sidebar: this
 			});
@@ -117,7 +120,7 @@
 			if (!id) {
 				throw new Error("Invalid id: " + id);
 			}
-			if (!mode || typeof mode !== "object") {
+			if (!mode || typeof mode !== "object") { //$NON-NLS-0$
 				throw new Error("Invalid mode: "  + mode);
 			}
 			if (!Object.hasOwnProperty.call(this.viewModes, id)) {
@@ -126,7 +129,7 @@
 		},
 		removeViewMode: function(id) {
 			var mode = this.getViewMode(id);
-			if (mode && typeof mode.destroy === "function") {
+			if (mode && typeof mode.destroy === "function") { //$NON-NLS-0$
 				mode.destroy();
 			}
 			delete this.viewModes[id];
@@ -139,11 +142,11 @@
 		},
 		setViewMode: function(id) {
 			var mode = this.activeViewMode;
-			if (mode && typeof mode.destroy === "function") {
+			if (mode && typeof mode.destroy === "function") { //$NON-NLS-0$
 				mode.destroy();
 			}
 			mode = this.activeViewMode = this.getViewMode(id);
-			if (mode && typeof mode.create === "function") {
+			if (mode && typeof mode.create === "function") { //$NON-NLS-0$
 				mode.create();
 			}
 		},
diff --git a/bundles/org.eclipse.orion.client.ui/web/orion/widgets/input/DropDownMenu.js b/bundles/org.eclipse.orion.client.ui/web/orion/widgets/input/DropDownMenu.js
index 1ffe880..f168134 100644
--- a/bundles/org.eclipse.orion.client.ui/web/orion/widgets/input/DropDownMenu.js
+++ b/bundles/org.eclipse.orion.client.ui/web/orion/widgets/input/DropDownMenu.js
@@ -35,7 +35,6 @@
 		}

 		

 		this.node.innerHTML = this.templateString;

-//		this.node.title = 'Navigation';

 		

 		if( body.icon ){

 			this.node.className = this.node.className + ' ' + body.icon;

diff --git a/bundles/org.eclipse.orion.client.ui/web/orion/widgets/nav/mini-nav.js b/bundles/org.eclipse.orion.client.ui/web/orion/widgets/nav/mini-nav.js
index afb47f9..0099760 100644
--- a/bundles/org.eclipse.orion.client.ui/web/orion/widgets/nav/mini-nav.js
+++ b/bundles/org.eclipse.orion.client.ui/web/orion/widgets/nav/mini-nav.js
@@ -57,27 +57,35 @@
 		params.navHandlerFactory = navHandlerFactory;
 		FileExplorer.apply(this, arguments);
 		this.commandRegistry = params.commandRegistry;
-		this.inputManager = params.inputManager;
+		this.editorInputManager = params.editorInputManager;
 		this.progressService = params.progressService;
+		var sidebarNavInputManager = params.sidebarNavInputManager;
 		this.toolbarNode = params.toolbarNode;
 		this.actions = null;
 		this.selectionActions = null;
+		this.followEditor = true;
 		var initialRoot = { };
 		this.treeRoot = initialRoot; // Needed by FileExplorer.prototype.loadResourceList
 		var _self = this;
-		this.inputManager.addEventListener("InputChanged", function(event) { //$NON-NLS-0$
+		this.editorInputManager.addEventListener("InputChanged", function(event) { //$NON-NLS-0$
 			var editorInput = event.metadata;
-			if (_self.treeRoot === initialRoot) {
+			if (_self.treeRoot === initialRoot && _self.followEditor) {
 				// Initial load: parent folder of editor input gives our current root
 				_self.loadParentOf(editorInput);
 			} else {
 				_self.reveal(editorInput);
 			}
 		});
+		if (sidebarNavInputManager) {
+			sidebarNavInputManager.addEventListener("InputChanged", function(event) { //$NON-NLS-0$
+				_self.followEditor = false;
+				_self.loadRoot(event.input);
+			});
 		this.selection = new Selection.Selection(this.registry, "miniNavFileSelection"); //$NON-NLS-0$
 		this.selection.addEventListener("selectionChanged", function(event) { //$NON-NLS-0$
 			_self.updateCommands(event.selections);
 		});
+		}
 		this.commandsRegistered = this.registerCommands();
 	}
 	MiniNavExplorer.prototype = Object.create(FileExplorer.prototype);
@@ -215,8 +223,9 @@
 		this.commandRegistry = params.commandRegistry;
 		this.contentTypeRegistry = params.contentTypeRegistry;
 		this.fileClient = params.fileClient;
-		this.inputManager = params.inputManager;
+		this.editorInputManager = params.editorInputManager;
 		this.parentNode = params.parentNode;
+		this.sidebarNavInputManager = params.sidebarNavInputManager;
 		this.toolbarNode = params.toolbarNode;
 //		this.selection = params.selection;
 		this.serviceRegistry = params.serviceRegistry;
@@ -229,7 +238,8 @@
 			this.explorer = new MiniNavExplorer({
 				commandRegistry: this.commandRegistry,
 				fileClient: this.fileClient,
-				inputManager: this.inputManager,
+				editorInputManager: this.editorInputManager,
+				sidebarNavInputManager: this.sidebarNavInputManager,
 				parentId: this.parentNode,
 				rendererFactory: function(explorer) {
 					var renderer = new MiniNavRenderer({
@@ -242,7 +252,7 @@
 				toolbarNode: this.toolbarNode
 			});
 			// On initial page load, metadata may not be loaded yet, but that's ok -- InputChanged will inform us later
-			this.explorer.loadParentOf(this.inputManager.getFileMetadata());
+			this.explorer.loadParentOf(this.editorInputManager.getFileMetadata());
 		},
 		destroy: function() {
 			if (this.explorer) {
diff --git a/bundles/org.eclipse.orion.client.ui/web/orion/widgets/themes/container/ThemeSheetWriter.js b/bundles/org.eclipse.orion.client.ui/web/orion/widgets/themes/container/ThemeSheetWriter.js
index e75e8fe..b44c5ef 100644
--- a/bundles/org.eclipse.orion.client.ui/web/orion/widgets/themes/container/ThemeSheetWriter.js
+++ b/bundles/org.eclipse.orion.client.ui/web/orion/widgets/themes/container/ThemeSheetWriter.js
@@ -320,7 +320,6 @@
 			auxpane.style.background = '-webkit-gradient(linear, left top, left bottom, color-stop(0%,' + this.sidepanel + '), color-stop(100%,' + this.sidepanel + '))';

 			auxpane.style.background ='-moz-linear-gradient(top, ' + this.sidepanel + ' 0%, ' + this.sidepanel + ' 100%)';

 			auxpane.style.overflowX = 'auto';

-			auxpane.style.minWidth = '200px';

 			/*auxpane.style.paddingTop = '16px';*/

 			

 			styles.push( auxpane );

diff --git a/bundles/org.eclipse.orion.client.ui/web/plugins/pageLinksPlugin.html b/bundles/org.eclipse.orion.client.ui/web/plugins/pageLinksPlugin.html
index 883e9a6..22ea679 100644
--- a/bundles/org.eclipse.orion.client.ui/web/plugins/pageLinksPlugin.html
+++ b/bundles/org.eclipse.orion.client.ui/web/plugins/pageLinksPlugin.html
@@ -56,7 +56,12 @@
 			nls: "orion/nls/messages",
 			uriTemplate: "{OrionHome}/shell/shellPage.html"
 		});
-
+		provider.registerService("orion.page.link", serviceImpl, {
+			nameKey: "Search",
+			id: "orion.Search",
+			nls: "orion/nls/messages",
+			uriTemplate: "{OrionHome}/search/search.html"
+		});
 		provider.registerService("orion.page.link.related", null, {
 			id: "orion.navigateFromMetadata",
 			nameKey: "Navigator",
diff --git a/bundles/org.eclipse.orion.client.ui/web/search/search.html b/bundles/org.eclipse.orion.client.ui/web/search/search.html
index 01628d9..0602119 100644
--- a/bundles/org.eclipse.orion.client.ui/web/search/search.html
+++ b/bundles/org.eclipse.orion.client.ui/web/search/search.html
@@ -26,7 +26,16 @@
        <body id="orion-searchResults" class="orionPage">
 		<div class="content-fixedHeight">
 			<div id="outlineContainer" class="auxpane sidePanelLayout hasSplit">
-				<div class="sidePanelMargins" id="searchProgress"></div>
+				<div style="height:100%;width:100%;position:relative;">
+					<div id="outlineTop" class="topPanelLayout">
+						<div id="searchBuilder" class="sidePanelMargins">
+						</div>
+					</div>
+					<div class="outlinerSplitLayout"></div>
+					<div id="outlineBottom" class="bottomPanelLayout">
+						<div class="sidePanelMargins" id="searchProgress"></div>
+					</div>
+				</div>
 			</div>
 			<div class="split splitLayout"></div>
 			<div id="rightPane" class="mainpane mainPanelLayout hasSplit">
diff --git a/bundles/org.eclipse.orion.client.ui/web/search/search.js b/bundles/org.eclipse.orion.client.ui/web/search/search.js
index aab749b..8864eb2 100644
--- a/bundles/org.eclipse.orion.client.ui/web/search/search.js
+++ b/bundles/org.eclipse.orion.client.ui/web/search/search.js
@@ -73,6 +73,8 @@
 		var searcher = new mSearchClient.Searcher({serviceRegistry: serviceRegistry, commandService: commandRegistry, fileService: fileClient});
 		
 		var searchOutliner = new mSearchOutliner.SearchOutliner({parent: "searchProgress", serviceRegistry: serviceRegistry, commandService: commandRegistry}); //$NON-NLS-0$
+		var searchBuilder = new mSearchOutliner.SearchBuilder({parent: "searchBuilder", searcher: searcher, serviceRegistry: serviceRegistry, commandService: commandRegistry}); //$NON-NLS-0$
+		
 		mGlobalCommands.generateBanner("orion-searchResults", serviceRegistry, commandRegistry, preferences, searcher, searcher, null, null); //$NON-NLS-0$
 		
 		var searchResultsGenerator = new mSearchResults.SearchResultsGenerator(serviceRegistry, "results", commandRegistry, fileClient, searcher, false/*crawling*/); //$NON-NLS-0$