Merge commit '5b9d01ef4bedb4eea4803bb45e742a2e2e9a34f0'
diff --git a/bundles/org.eclipse.orion.client.core/web/edit/setup.js b/bundles/org.eclipse.orion.client.core/web/edit/setup.js
index 54cc618..4bb5050 100644
--- a/bundles/org.eclipse.orion.client.core/web/edit/setup.js
+++ b/bundles/org.eclipse.orion.client.core/web/edit/setup.js
@@ -414,7 +414,7 @@
 				searchFloat.style.display = "block"; //$NON-NLS-0$
 				var query = searcher.createSearchQuery(searchPattern, null, "Name", true); //$NON-NLS-0$
 				var renderer = searcher.defaultRenderer.makeRenderFunction(null, searchFloat, false);
-				searcher.search(query, inputManager.getInput(), renderer);
+				searcher.search(query, inputManager.getInput(), renderer, true);
 			}, 0);
 			return true;
 		}, {name: messages["Search Files"]}); //$NON-NLS-0$
diff --git a/bundles/org.eclipse.orion.client.core/web/js-tests/config/testcase.js b/bundles/org.eclipse.orion.client.core/web/js-tests/config/testcase.js
index 3411708..6cac481 100644
--- a/bundles/org.eclipse.orion.client.core/web/js-tests/config/testcase.js
+++ b/bundles/org.eclipse.orion.client.core/web/js-tests/config/testcase.js
@@ -30,6 +30,9 @@
 				return typeof value === 'object' ? JSON.parse(value) : undefined;
 			},
 			put: function(key, value) {
+				if (value === null) {
+					throw new Error('Preferences does not allow null values');
+				}
 				this.map[key] = JSON.stringify(value);
 			},
 			remove: function(key) {
diff --git a/bundles/org.eclipse.orion.client.core/web/orion/bootstrap.js b/bundles/org.eclipse.orion.client.core/web/orion/bootstrap.js
index 4cbd825..bee4085 100644
--- a/bundles/org.eclipse.orion.client.core/web/orion/bootstrap.js
+++ b/bundles/org.eclipse.orion.client.core/web/orion/bootstrap.js
@@ -29,8 +29,6 @@
 		// we read settings and wait for the plugin registry to fully startup before continuing

 		var preferences = new mPreferences.PreferencesService(serviceRegistry);

 		var pluginRegistry = new mPluginRegistry.PluginRegistry(serviceRegistry);

-		var configAdmin = new mConfig.ConfigurationAdminFactory(serviceRegistry, preferences).getConfigurationAdmin();

-		serviceRegistry.registerService("orion.cm.configadmin", configAdmin);

 		return preferences.getPreferences("/plugins").then(function(pluginsPreference) { //$NON-NLS-0$

 			var pluginURLs = pluginsPreference.keys();

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

@@ -52,6 +50,9 @@
 				});

 			}

 		}).then(function() {

+			var configAdmin = new mConfig.ConfigurationAdminFactory(serviceRegistry, preferences).getConfigurationAdmin();

+			serviceRegistry.registerService("orion.cm.configadmin", configAdmin); //$NON-NLS-0$

+		}).then(function() {

 			var auth = serviceRegistry.getService("orion.core.auth"); //$NON-NLS-0$

 			if (auth) {

 				auth.getUser().then(function(user) {

diff --git a/bundles/org.eclipse.orion.client.core/web/orion/commands.js b/bundles/org.eclipse.orion.client.core/web/orion/commands.js
index 36c7f44..343ed57 100644
--- a/bundles/org.eclipse.orion.client.core/web/orion/commands.js
+++ b/bundles/org.eclipse.orion.client.core/web/orion/commands.js
@@ -13,6 +13,8 @@
  
 define(['i18n!orion/nls/messages', 'require', 'dojo', 'dijit', 'orion/util', 'orion/PageUtil', 'orion/navigationUtils', 'dijit/Menu', 'dijit/form/DropDownButton', 'dijit/MenuItem', 'dijit/PopupMenuItem', 'dijit/MenuSeparator', 'dijit/Tooltip', 'dijit/TooltipDialog' ], function(messages, require, dojo, dijit, mUtil, PageUtil, mNavUtils){
 
+	var isMac = window.navigator.platform.indexOf("Mac") !== -1; //$NON-NLS-0$
+
 	/*
 	 * stateless helper function
 	 */
@@ -242,35 +244,76 @@
 			this._serviceRegistration = this._registry.registerService("orion.page.command", this); //$NON-NLS-0$
 			this._defaultSelectionService = options.selection;
 			dojo.connect(window.document, "onkeydown", dojo.hitch(this, function (evt){ //$NON-NLS-0$
-				evt = evt || window.event;
-				// bindings are ignored if we are in a text field or editor
-				if (evt.target.contentEditable === "true") { //$NON-NLS-0$
-					return;
-				}
-				var tagType = evt.target.nodeName.toLowerCase();
-				if (tagType === 'input') { //$NON-NLS-0$
-					var inputType = evt.target.type.toLowerCase();
-					// Any HTML5 input type that involves typing text should be ignored
-					switch (inputType) {
-						case "text": //$NON-NLS-0$
-						case "password": //$NON-NLS-0$
-						case "search": //$NON-NLS-0$
-						case "color": //$NON-NLS-0$
-						case "date": //$NON-NLS-0$
-						case "datetime": //$NON-NLS-0$
-						case "datetime-local": //$NON-NLS-0$
-						case "email": //$NON-NLS-0$
-						case "month": //$NON-NLS-0$
-						case "number": //$NON-NLS-0$
-						case "range": //$NON-NLS-0$
-						case "tel": //$NON-NLS-0$
-						case "time": //$NON-NLS-0$
-						case "url": //$NON-NLS-0$
-						case "week": //$NON-NLS-0$
-							return;
+				function isContentKey(e) {
+					// adapted from handleKey in http://git.eclipse.org/c/platform/eclipse.platform.swt.git/plain/bundles/org.eclipse.swt/Eclipse%20SWT%20Custom%20Widgets/common/org/eclipse/swt/custom/StyledText.java
+					if (isMac) {
+						// COMMAND+ALT combinations produce characters on the mac, but COMMAND or COMMAND+SHIFT do not.
+						if (e.metaKey && !e.altKey) {
+							return false;
+						}
+					} else {
+						// CTRL or ALT combinations are not characters, however both of them together (CTRL+ALT)
+						// are the Alt Gr key on some keyboards.  See Eclipse bug 20953. If together, they might
+						// be a character.
+						if (e.ctrlKey && !e.altKey) {
+							return false;
+						}
+						if (e.altKey && !e.ctrlKey) {
+							return false;
+						}
 					}
-				} else if (tagType === 'textarea') { //$NON-NLS-0$
-					return;
+					if (e.char) {
+						return e.char.length > 0;  // empty string for non characters
+					} else if (e.charCode || e.keyCode) {
+						var keyCode= e.charCode || e.keyCode;
+						// anything below SPACE is not a character except for line delimiter keys, tab, and delete.
+						switch (keyCode) {
+							case 8:  // backspace
+							case 9:  // tab
+							case 13: // enter
+							case 46: // delete
+								return true;
+							default:
+								return (keyCode >= 32 && keyCode < 112) || // space key and above until function keys
+									keyCode > 123; // above function keys  
+						}
+					}
+					// If we can't identify as a character, assume it's not
+					return false;
+				}
+				
+				evt = evt || window.event;
+				if (isContentKey(evt)) {
+					// bindings that are text content keys are ignored if we are in a text field or editor
+					// see https://bugs.eclipse.org/bugs/show_bug.cgi?id=375058
+					if (evt.target.contentEditable === "true") { //$NON-NLS-0$
+						return;
+					}
+					var tagType = evt.target.nodeName.toLowerCase();
+					if (tagType === 'input') { //$NON-NLS-0$
+						var inputType = evt.target.type.toLowerCase();
+						// Any HTML5 input type that involves typing text should be ignored
+						switch (inputType) {
+							case "text": //$NON-NLS-0$
+							case "password": //$NON-NLS-0$
+							case "search": //$NON-NLS-0$
+							case "color": //$NON-NLS-0$
+							case "date": //$NON-NLS-0$
+							case "datetime": //$NON-NLS-0$
+							case "datetime-local": //$NON-NLS-0$
+							case "email": //$NON-NLS-0$
+							case "month": //$NON-NLS-0$
+							case "number": //$NON-NLS-0$
+							case "range": //$NON-NLS-0$
+							case "tel": //$NON-NLS-0$
+							case "time": //$NON-NLS-0$
+							case "url": //$NON-NLS-0$
+							case "week": //$NON-NLS-0$
+								return;
+						}
+					} else if (tagType === 'textarea') { //$NON-NLS-0$
+						return;
+					}
 				}
 				this._processKey(evt);
 			}));
@@ -1408,8 +1451,7 @@
 		}
 	};  // end Command prototype
 	Command.prototype.constructor = Command;
-
-	var isMac = window.navigator.platform.indexOf("Mac") !== -1; //$NON-NLS-0$
+	
 	/**
 	 * Temporary copy of editor key binding.  Will be removed in the next released.
 	 * @param {String|Number} keyCode the key code.
diff --git a/bundles/org.eclipse.orion.client.core/web/orion/compare/compare-container.css b/bundles/org.eclipse.orion.client.core/web/orion/compare/compare-container.css
index 60a13c8..f144f6a 100644
--- a/bundles/org.eclipse.orion.client.core/web/orion/compare/compare-container.css
+++ b/bundles/org.eclipse.orion.client.core/web/orion/compare/compare-container.css
@@ -89,18 +89,24 @@
 	height: 100%;
 }
 
+.claro .dijitContentPane {
+	padding: 0;
+	margin: 0;
+	outline: 0;
+}
+
 /*** Styles for diff annotations ***/
 
 /** Styles for normal diff blocks **/
 
 /* The added block in the new file/left side, lightest green */
 .annotationLine.addedBlockDiff {
-	background-color: #B3E8B3
+	background-color: #B3E8B3;
 }
 
 /* The current added block in the new file/left side, 2nd lightest green */
 .annotationLine.currentAddedBlockDiff {
-	background-color: #55CC55
+	background-color: #8EDD8E;
 }
 
 /* The deleted block in the old file/right side, lightest red */
@@ -145,7 +151,7 @@
 
 /* The added word in the new file/left side, 3rd lightest green */
 .annotationRange.addedWordDiff {
-	background-color: #35B335;
+	background-color: #63CF63;
 }
 
 /* The current added word in the new file/left side, darkest green */
diff --git a/bundles/org.eclipse.orion.client.core/web/orion/config.js b/bundles/org.eclipse.orion.client.core/web/orion/config.js
index 787c4f8..4f034f3 100644
--- a/bundles/org.eclipse.orion.client.core/web/orion/config.js
+++ b/bundles/org.eclipse.orion.client.core/web/orion/config.js
@@ -159,14 +159,11 @@
 	function ConfigStore(factory, prefsService) {
 		this.factory = factory;
 		this.prefsService = prefsService;
-		this.configs = Object.create(null); /* PID -> Configuration */
-		this.prefs = Object.create(null); /* PID -> Preferences node */
-		this.prefRoot = null;
+		this.configs = Object.create(null); // PID -> Configuration
+		this.prefs = Object.create(null); // PID -> Deferred Preferences node
+		this.prefRoot = null; // Deferred Preferences node
 	}
 	ConfigStore.prototype = {
-		_createConfig: function(properties) {
-			return new ConfigImpl(this.factory, this, properties);
-		},
 		_find: function(pid) {
 			return this.configs[pid] || null;
 		},
@@ -174,21 +171,27 @@
 			var node = this.prefs[pid];
 			return node && node.state() === 'resolve'; //$NON-NLS-0$
 		},
+		loadRoot: function() {
+			this.prefRoot = this.prefRoot || this.prefsService.getPreferences(CONFIG_PREF_NODE);
+			return this.prefRoot;
+		},
 		loadNode: function(pid) {
 			if (typeof pid !== 'string') { //$NON-NLS-0$
 				throw new Error('Invalid pid: ' + pid); //$NON-NLS-0$
 			}
-			this.prefRoot = this.prefRoot || this.prefsService.getPreferences(CONFIG_PREF_NODE);
 			this.prefs[pid] = this.prefs[pid] || this.prefsService.getPreferences(CONFIG_PREF_NODE + '/' + pid); //$NON-NLS-0$
 			var self = this;
-			return Deferred.all([this.prefRoot, this.prefs[pid]]).then(function(result) {
+			return Deferred.all([this.loadRoot(), this.prefs[pid]]).then(function(result) {
 				var prefRoot = result[0], prefNode = result[1];
 				if (!prefRoot.get(pid)) {
 					prefRoot.put(pid, true);
 				}
-				var props = prefNode.get('properties'); //$NON-NLS-0$
-				if (props) {
-					self.configs[pid] = self._createConfig(props);
+				if (!self.configs[pid]) {
+					var props = prefNode.get('properties'); //$NON-NLS-0$
+					if (typeof props === 'object' && props !== null && Object.keys(props).length > 0) { //$NON-NLS-0$
+						props[PROPERTY_PID] = pid;
+						self.configs[pid] = new ConfigImpl(self.factory, self, props);
+					}
 				}
 				return prefNode;
 			});
@@ -201,15 +204,14 @@
 					configuration = new ConfigImpl(self.factory, self, pid);
 					self.configs[pid] = configuration;
 					// only pid is in the properties here
-					prefNode.put('properties', configuration.getProperties()); //$NON-NLS-0$
+					prefNode.put('properties', configuration.getProperties(true) || {}); //$NON-NLS-0$
 				}
 				return configuration;
 			});
 		},
 		list: function() {
 			var self = this;
-			this.prefRoot = this.prefRoot || this.prefsService.getPreferences(CONFIG_PREF_NODE);
-			return this.prefRoot.then(function(prefRoot) {
+			return this.loadRoot().then(function(prefRoot) {
 				var pids = prefRoot.keys();
 				return Deferred.all(pids.map(self.loadNode.bind(self))).then(function() {
 					return pids.map(self._find.bind(self));
@@ -217,19 +219,20 @@
 			});
 		},
 		remove: function(pid) {
-			delete this.configs[pid];
 			var self = this;
-			this.loadNode(pid).then(function(prefNode) {
-				// TODO want to remove the whole node here, see https://bugs.eclipse.org/bugs/show_bug.cgi?id=386582
-				// TODO remove from list
+			Deferred.all([this.loadRoot(), this.loadNode(pid)]).then(function(result) {
+				var prefRoot = result[0], prefNode = result[1];
+				// TODO want to remove the whole prefNode here, see https://bugs.eclipse.org/bugs/show_bug.cgi?id=386582
 				prefNode.clear();
-				//delete self.prefs[pid];
+				delete self.configs[pid];
+				prefRoot.remove(pid);
+				delete self.prefs[pid];
 			});
 		},
 		save: function(pid, configuration) {
-			var properties = configuration.getProperties();
+			var properties = configuration.getProperties(true);
 			this.loadNode(pid).then(function(prefNode) {
-				prefNode.put('properties', properties); //$NON-NLS-0$
+				prefNode.put('properties', properties || {}); //$NON-NLS-0$
 			});
 		}
 	};
@@ -279,12 +282,14 @@
 			this._checkRemoved();
 			return this.pid;
 		},
-		getProperties: function() {
+		getProperties: function(omitPid) {
 			this._checkRemoved();
 			var props = null;
 			if (this.properties) {
 				props = clone(this.properties);
-				props[PROPERTY_PID] = this.pid;
+				if (!omitPid) {
+					props[PROPERTY_PID] = this.pid;
+				}
 			}
 			return props;
 		},
@@ -301,6 +306,9 @@
 			var self = this;
 			this.store.save(this.pid, this);
 			self.factory.notifyUpdated(self);
+		},
+		toString: function() {
+			return '[ConfigImpl pid: ' + this.pid + ', properties: ' + JSON.stringify(this.properties) + ']';
 		}
 	};
 	return ConfigImpl;
diff --git a/bundles/org.eclipse.orion.client.core/web/orion/fileClient.js b/bundles/org.eclipse.orion.client.core/web/orion/fileClient.js
index 15f0079..f0bc66f 100644
--- a/bundles/org.eclipse.orion.client.core/web/orion/fileClient.js
+++ b/bundles/org.eclipse.orion.client.core/web/orion/fileClient.js
@@ -227,6 +227,11 @@
 			var i = this._getServiceIndex(location);
 			return i === -1 ? _allFileSystemsService.Name : _names[i];
 		};
+		
+		this._getServiceRootURL = function(location) {
+			var i = this._getServiceIndex(location);
+			return i === -1 ? _allFileSystemsService.Location : _fileSystemsRoots[i].Location;
+		};
 	}
 	
 	FileClient.prototype = /**@lends orion.fileClient.FileClient.prototype */ {
@@ -247,6 +252,14 @@
 		},
 		 
 		/**
+		 * Returns the root url of the file service managing this location
+		 * @param location The location of the item 
+		 */
+		fileServiceRootURL: function(location) {
+			return this._getServiceRootURL(location);
+		},
+		 
+		/**
 		 * Obtains the children of a remote resource
 		 * @param location The location of the item to obtain children for
 		 * @return A deferred that will provide the array of child objects when complete
diff --git a/bundles/org.eclipse.orion.client.core/web/orion/searchAndReplace/textSearcher.js b/bundles/org.eclipse.orion.client.core/web/orion/searchAndReplace/textSearcher.js
index a7e55b7..58ff790 100644
--- a/bundles/org.eclipse.orion.client.core/web/orion/searchAndReplace/textSearcher.js
+++ b/bundles/org.eclipse.orion.client.core/web/orion/searchAndReplace/textSearcher.js
@@ -176,8 +176,8 @@
 		},
 		
 		_handleKeyDown: function(evt, fromSearch){
-			var ctrlKey = this.isMac ? evt.metaKey : evt.ctrlKey;
-			if(ctrlKey &&  evt.keyCode === 70/*"f"*/ ) {
+			var ctrlKeyOnly = (this.isMac ? evt.metaKey : evt.ctrlKey) && !evt.altKey && !evt.shiftKey;
+			if(ctrlKeyOnly && evt.keyCode === 70/*"f"*/ ) {
 				this._keyUpHandled = fromSearch;
 				if( evt.stopPropagation ) { 
 					evt.stopPropagation(); 
@@ -185,7 +185,7 @@
 				evt.cancelBubble = true;
 				return false;
 			}
-			if((ctrlKey &&  evt.keyCode === 75/*"k"*/ ) || evt.keyCode === 13/*enter*/ ){
+			if((ctrlKeyOnly && evt.keyCode === 75/*"k"*/ ) || evt.keyCode === 13/*enter*/ ){
 				if( evt.stopPropagation ) { 
 					evt.stopPropagation(); 
 				}
@@ -194,7 +194,7 @@
 				this._keyUpHandled = fromSearch;
 				return false;
 			}
-			if( ctrlKey &&  evt.keyCode === 82 /*"r"*/){
+			if( ctrlKeyOnly &&  evt.keyCode === 82 /*"r"*/){
 				if( evt.stopPropagation ) { 
 					evt.stopPropagation(); 
 				}
diff --git a/bundles/org.eclipse.orion.client.core/web/orion/searchClient.js b/bundles/org.eclipse.orion.client.core/web/orion/searchClient.js
index 1968cd9..993ab41 100644
--- a/bundles/org.eclipse.orion.client.core/web/orion/searchClient.js
+++ b/bundles/org.eclipse.orion.client.core/web/orion/searchClient.js
@@ -38,8 +38,9 @@
 		 * @param {String} query URI of the query to run.
 		 * @param {String} [excludeFile] URI of a file to exclude from the result listing.
 		 * @param {Function(JSONObject)} Callback function that receives the results of the query.
+		 * @param {Boolean} [keyWordSearch] If true, do keyword search. Otherwise do name search.
 		 */
-		search: function(query, excludeFile, renderer) {
+		search: function(query, excludeFile, renderer, keyWordSearch) {
 			var qObj = mSearchUtils.parseQueryStr(query);
 			var transform = function(jsonData) {
 				var transformed = [];
@@ -53,7 +54,7 @@
 				}
 				return transformed;
 			};
-			if(this._crawler){ //$NON-NLS-0$
+			if(this._crawler && !keyWordSearch){ //$NON-NLS-0$
 				this._crawler.searchName(query, function(jsonData){renderer(transform(jsonData), null);});
 			} else {
 				try {
@@ -76,6 +77,9 @@
 				catch(error){
 					if(typeof(error) === "string" && error.indexOf("search") > -1 && this._crawler){ //$NON-NLS-0$
 						this._crawler.searchName(query, function(jsonData){renderer(transform(jsonData), null);});
+					} else if(typeof(error) === "string" && error.indexOf("search") > -1 && keyWordSearch){ //$NON-NLS-0${
+						var crawler = new mSearchCrawler.SearchCrawler(this.registry, this._fileService, query);
+						crawler.search(function(jsonData){renderer(transform(jsonData), null);});
 					} else {
 						this.registry.getService("orion.page.message").setErrorMessage(error);	 //$NON-NLS-0$
 					}
@@ -97,6 +101,7 @@
 		setLocationByMetaData: function(meta, useParentLocation){
 			var locationName = "";
 			var noneRootMeta = null;
+			this._searchRootLocation = this._fileService.fileServiceRootURL(meta.Location);
 			if(useParentLocation && meta && meta.Parents && meta.Parents.length > 0){
 				if(useParentLocation.index === "last"){ //$NON-NLS-0$
 					noneRootMeta = meta.Parents[meta.Parents.length-1];
@@ -107,10 +112,11 @@
 				noneRootMeta = meta;
 			} 
 			if(noneRootMeta){
-				this.setLocationByURL(noneRootMeta.Location);
+				this.setLocationbyURL(noneRootMeta.Location);
 				locationName = noneRootMeta.Name;
 			} else if(meta){
-				locationName = this._fileService.fileServiceName(meta && meta.Location);
+				this.setLocationbyURL(this._searchRootLocation);
+				locationName = this._fileService.fileServiceName(meta.Location);
 			}
 			var searchInputDom = dojo.byId("search"); //$NON-NLS-0$
 			if(!locationName){
@@ -130,17 +136,26 @@
 				searchInputDom.title = messages["Type a keyword or wild card to search in "] + locationName;
 			}
 		},
-		setLocationByURL: function(locationURL){
-			this.location = locationURL;
+		setLocationbyURL: function(locationURL){
+			this._searchLocation = locationURL;
+		},
+		setRootLocationbyURL: function(locationURL){
+			this._searchRootLocation = locationURL;
+		},
+		getSearchLocation: function(){
+			return this._searchLocation;
+		},
+		getSearchRootLocation: function(){
+			return this._searchRootLocation;
 		},
 		/**
 		 * Returns a query URL for a search.
 		 * @param {String} query The text to search for, or null when searching purely on file name
 		 * @param {String} [nameQuery] The name of a file to search for
 		 * @param {String} [sort] The field to sort search results on. By default results will sort by path
-		 * @param {Boolean} [skipLocation] If true, do not use the location property of the searcher. Use "" as the location instead.
+		 * @param {Boolean} [useRoot] If true, do not use the location property of the searcher. Use the root url of the file system instead.
 		 */
-		createSearchQuery: function(query, nameQuery, sort, skipLocation, searchPrefix)  {
+		createSearchQuery: function(query, nameQuery, sort, useRoot, searchPrefix)  {
 			if (!sort) {
 				sort = "Path"; //$NON-NLS-0$
 			}
@@ -151,14 +166,14 @@
 				return  mSearchUtils.generateSearchQuery({sort: sort,
 					rows: 100,
 					start: 0,
-					location: skipLocation ? "": this.location,
+					location: useRoot ? this._searchRootLocation: this._searchLocation,
 					searchStr: searchPrefix + this._luceneEscape(nameQuery, true) + wildcard}); //$NON-NLS-0$
 			}
 			return  mSearchUtils.generateSearchQuery({sort: sort,
 				rows: 40,
 				start: 0,
 				searchStr: this._luceneEscape(query, true),
-				location: skipLocation ? "": this.location});
+				location: useRoot ? this._searchRootLocation: this._searchLocation});
 		},
 		/**
 		 * Escapes all characters in the string that require escaping in Lucene queries.
diff --git a/bundles/org.eclipse.orion.client.core/web/orion/settings/settingsRegistry.js b/bundles/org.eclipse.orion.client.core/web/orion/settings/settingsRegistry.js
index 4e7af0d..30929fd 100644
--- a/bundles/org.eclipse.orion.client.core/web/orion/settings/settingsRegistry.js
+++ b/bundles/org.eclipse.orion.client.core/web/orion/settings/settingsRegistry.js
@@ -13,12 +13,34 @@
 define(['orion/serviceTracker'], function(ServiceTracker) {
 	var METATYPE_SERVICE = 'orion.cm.metatype', SETTING_SERVICE = 'orion.core.setting'; //$NON-NLS-0$ //$NON-NLS-1$
 	var SETTINGS_PROP = 'settings'; //$NON-NLS-0$
+
+	/**
+	 * @param {Object} value
+	 * @param {orion.metatype.PropertyType} propertyType
+	 */
+	function equalsDefaultValue(value, propertyType) {
+		var defaultValue = propertyType.getDefaultValue();
+		var result = value === defaultValue;
+		if (propertyType.getType() === 'string') { //$NON-NLS-0$
+			result = result || (value === '' && defaultValue === null);
+		}
+		return result;
+	}
+
 	/**
 	 * @name orion.settings.Setting
 	 * @class Represents the definition of a setting.
 	 * @description Represents the definition of a setting.
 	 */
 		/**
+		 * @name orion.settings.Setting#isDefaults
+		 * @function
+		 * @description
+		 * @param {Object} properties A map of PropertyType IDs to values.
+		 * @returns {Boolean} <code>true</code> if <code>properties</code> contains a key for each of this setting's
+		 * PropertyTypes, and the corresponding value equals the PropertyType's default value.
+		 */
+		/**
 		 * @name orion.settings.Setting#getPid
 		 * @function
 		 * @description
@@ -62,7 +84,12 @@
 		getPid: function() { return this.pid; },
 		getObjectClassId: function() { return this.classId; },
 		getPropertyTypes: function() { return this.properties; },
-		getTags: function() { return this.tags || []; }
+		getTags: function() { return this.tags || []; },
+		isDefaults: function(properties) {
+			return this.getPropertyTypes().every(function(propertyType) {
+				return equalsDefaultValue(properties[propertyType.getId()], propertyType);
+			});
+		}
 	};
 
 	/**
diff --git a/bundles/org.eclipse.orion.client.core/web/orion/settings/ui/PluginSettings.js b/bundles/org.eclipse.orion.client.core/web/orion/settings/ui/PluginSettings.js
index 6094e4c..e5800fe 100644
--- a/bundles/org.eclipse.orion.client.core/web/orion/settings/ui/PluginSettings.js
+++ b/bundles/org.eclipse.orion.client.core/web/orion/settings/ui/PluginSettings.js
@@ -9,9 +9,9 @@
  * Contributors: IBM Corporation - initial API and implementation
  ******************************************************************************/
 /*global define document orion*/
-define(['i18n!orion/settings/nls/messages', 'orion/explorer', 'orion/section', 'orion/i18nUtil',
+define(['i18n!orion/settings/nls/messages', 'orion/explorer', 'orion/section', 'orion/i18nUtil', 'orion/Deferred',
 		'dojo', 'dijit', 'orion/widgets/settings/LabeledCheckbox', 'orion/widgets/settings/LabeledTextfield', 'orion/widgets/settings/Select'],
-		function(messages, mExplorer, mSection, i18nUtil, dojo, dijit) {
+		function(messages, mExplorer, mSection, i18nUtil, Deferred, dojo, dijit) {
 	var Explorer = mExplorer.Explorer, SelectionRenderer = mExplorer.SelectionRenderer, Section = mSection.Section;
 
 	var PropertyWidget = dojo.declare('orion.widgets.settings.SettingWidget', [dijit._Widget], { //$NON-NLS-0$
@@ -62,15 +62,30 @@
 	var PropertiesWidget = dojo.declare('orion.widgets.settings.PropertiesWidget', [dijit._Container, dijit._WidgetBase], { //$NON-NLS-0$
 		buildRendering: function() {
 			this.inherited(arguments);
-			var setting = this.setting;
 			var serviceRegistry = this.serviceRegistry;
 			var self = this;
-			var configAdmin = serviceRegistry.getService('orion.cm.configadmin'); //$NON-NLS-0$
-			configAdmin.getConfiguration(setting.getPid()).then(function(configuration) {
-				self.set('configuration', configuration); //$NON-NLS-0$
+			this.configAdmin = serviceRegistry.getService('orion.cm.configadmin'); //$NON-NLS-0$
+			this.initConfiguration().then(function(configuration) {
 				self.createChildren(configuration);
 			});
 		},
+		/** Creates a new configuration if necessary */
+		initConfiguration: function() {
+			var configuration = this.configuration;
+			if (!configuration) {
+				var self = this;
+				this.configPromise = this.configPromise || this.configAdmin.getConfiguration(this.setting.getPid())
+					.then(function(resolvedConfiguration) {
+						self.configuration = resolvedConfiguration;
+						return resolvedConfiguration;
+					});
+				return this.configPromise;
+			} else {
+				var d = new Deferred();
+				d.resolve(configuration);
+				return d;
+			}
+		},
 		createChildren: function(configuration) {
 			var self = this;
 			this.setting.getPropertyTypes().forEach(function(property) {
@@ -93,19 +108,18 @@
 			});
 		},
 		changeProperty: function(propertyType, value) {
-			var configuration = this.configuration;
-			var setting = this.setting;
-			var props = configuration.getProperties() || {};
-			props[propertyType.getId()] = value;
-			var isDefaultConfig = setting.getPropertyTypes().every(function(propertyType) {
-				return props[propertyType.getId()] === propertyType.getDefaultValue();
-			});
-			if (isDefaultConfig) {
-				configuration.remove();
-				this.configuration = null;
-			} else {
-				configuration.update(props);
-			}
+			this.initConfiguration().then(function(configuration) {
+				var setting = this.setting;
+				var props = configuration.getProperties() || {};
+				props[propertyType.getId()] = value;
+				if (setting.isDefaults(props)) {
+					configuration.remove();
+					this.configuration = null;
+					this.configPromise = null;
+				} else {
+					configuration.update(props);
+				}
+			}.bind(this));
 		}
 	});
 
diff --git a/bundles/org.eclipse.orion.client.core/web/orion/widgets/OpenResourceDialog.js b/bundles/org.eclipse.orion.client.core/web/orion/widgets/OpenResourceDialog.js
index 2e9857e..0fcbb8c 100644
--- a/bundles/org.eclipse.orion.client.core/web/orion/widgets/OpenResourceDialog.js
+++ b/bundles/org.eclipse.orion.client.core/web/orion/widgets/OpenResourceDialog.js
@@ -50,6 +50,7 @@
 		}
 		this.searcher.setCrawler(null);
 		this._forceUseCrawler = false;
+		this._searchOnRoot = true;
 		this.fileService = this.searcher.getFileService();
 		if (!this.fileService) {
 			throw new Error(messages['Missing required argument: fileService']);
@@ -148,8 +149,9 @@
 		this.populateFavorites();
 		var self = this;
 		setTimeout(function() {
-			if(self._forceUseCrawler || !self.fileService.getService(self.searcher.location)["search"]){//$NON-NLS-0$
-				var crawler = new mSearchCrawler.SearchCrawler(self.searcher.registry, self.fileService, "", {searchOnName: true, location: self.searcher.location}); 
+			if(self._forceUseCrawler || !self.fileService.getService(self.searcher.getSearchLocation())["search"]){//$NON-NLS-0$
+				var searchLoc = self._searchOnRoot ? self.searcher.getSearchRootLocation() : self.searcher.getSearchLocation();
+				var crawler = new mSearchCrawler.SearchCrawler(self.searcher.registry, self.fileService, "", {searchOnName: true, location: searchLoc}); 
 				self.searcher.setCrawler(crawler);
 				crawler.buildSkeleton(function(){
 													dojo.addClass("crawlingProgress", "progressPane_running_dialog");//$NON-NLS-2$ //$NON-NLS-0$
@@ -239,7 +241,7 @@
 			// Gives Webkit a chance to show the "Searching" message
 			var that = this;
 			setTimeout(function() {
-				var query = that.searcher.createSearchQuery(null, text, that.searcher._crawler ? false : "NameLower", false, that.searcher._crawler ? "" : "NameLower:"); //$NON-NLS-3$ //$NON-NLS-2$ //$NON-NLS-0$
+				var query = that.searcher.createSearchQuery(null, text, that.searcher._crawler ? false : "NameLower", that._searchOnRoot, that.searcher._crawler ? "" : "NameLower:"); //$NON-NLS-3$ //$NON-NLS-2$ //$NON-NLS-0$
 				var renderFunction = that.searchRenderer.makeRenderFunction(that.contentTypeService, that.results, false, dojo.hitch(that, that.decorateResult));
 				that.searcher.search(query, false, renderFunction);
 			}, 0);
diff --git a/bundles/org.eclipse.orion.client.core/web/plugins/jslintPlugin.js b/bundles/org.eclipse.orion.client.core/web/plugins/jslintPlugin.js
index da46e51..cf24f7c 100644
--- a/bundles/org.eclipse.orion.client.core/web/plugins/jslintPlugin.js
+++ b/bundles/org.eclipse.orion.client.core/web/plugins/jslintPlugin.js
@@ -73,13 +73,19 @@
 					var optionsMap = {};
 					options.split(/,/).forEach(function(option) {
 						var match = /\s*(\w+)\s*:\s*(\w+)\s*/.exec(option); // name:value
-						var name = match[1], value = match[2];
-						optionsMap[name] = value;
+						if (match === null) {
+							console.log('JSLINT ignoring bad option: ' + option);
+						} else {
+							var name = match[1], value = match[2];
+							optionsMap[name] = value;
+						}
 					});
-					validationOptions = optionsMap;
-					console.log('JSLINT using custom options: ' + Object.keys(validationOptions).map(function(k) {
-						return k + ':' + optionsMap[k];
-					}).join(','));
+					if (Object.keys(optionsMap).length > 0) {
+						validationOptions = optionsMap;
+						console.log('JSLINT using custom options: ' + Object.keys(validationOptions).map(function(k) {
+							return k + ':' + optionsMap[k];
+						}).join(','));
+					}
 				}
 			}
 		},
diff --git a/bundles/org.eclipse.orion.client.core/web/search/search.js b/bundles/org.eclipse.orion.client.core/web/search/search.js
index 330ca35..69e9b4e 100644
--- a/bundles/org.eclipse.orion.client.core/web/search/search.js
+++ b/bundles/org.eclipse.orion.client.core/web/search/search.js
@@ -44,32 +44,36 @@
 			return {searchStr: searchStr, searchLocation: searchLocation};
 		}
 		
-		function makeHref(fileClient, seg, location, searchStr){
-			if(!location || location === "" || location === "root"){ //$NON-NLS-0$
-				seg.href = require.toUrl("search/search.html") + "#" + searchStr; //$NON-NLS-1$ //$NON-NLS-0$
-			} else {
-				seg.href = require.toUrl("search/search.html") + "#" + searchStr + "+Location:" + location + "*"; //$NON-NLS-3$ //$NON-NLS-2$ //$NON-NLS-1$ //$NON-NLS-0$
-			}
+		function makeHref(fileClient, seg, location, searchStr, searcher){
+			var searchLocation = (!location || location === "" || location === "root") ? searcher.getSearchRootLocation() : location;
+			seg.href = require.toUrl("search/search.html") + "#" + searchStr + "+Location:" + searchLocation + "*"; //$NON-NLS-3$ //$NON-NLS-2$ //$NON-NLS-1$ //$NON-NLS-0$
 		}
 	
 		function setPageInfo(serviceRegistry, fileClient, commandService, searcher){
 			var searchLoc = parseHash();
-			
 			if(searchLoc.searchLocation){
-				fileClient.read(searchLoc.searchLocation, true).then(
+				if(searchLoc.searchLocation === fileClient.fileServiceRootURL(searchLoc.searchLocation)){
+					searcher.setRootLocationbyURL(searchLoc.searchLocation);
+					searcher.setLocationbyURL(searchLoc.searchLocation);
+					mGlobalCommands.setPageTarget({task: "Search", serviceRegistry: serviceRegistry, 
+						commandService: commandService, searchService: searcher, fileService: fileClient, breadcrumbRootName: fileClient.fileServiceName(searchLoc.searchLocation),
+						makeBreadcrumbLink: function(seg,location){makeHref(fileClient, seg, location, searchLoc.searchStr, searcher);}});
+				} else {
+					fileClient.read(searchLoc.searchLocation, true).then(
 						dojo.hitch(this, function(metadata) {
 							mGlobalCommands.setPageTarget({task: "Search", target: metadata, serviceRegistry: serviceRegistry, 
 								fileService: fileClient, commandService: commandService, searchService: searcher, breadcrumbRootName: "Search",
-								makeBreadcrumbLink: function(seg,location){makeHref(fileClient, seg, location, searchLoc.searchStr);}});
+								makeBreadcrumbLink: function(seg,location){makeHref(fileClient, seg, location, searchLoc.searchStr, searcher);}});
 						}),
 						dojo.hitch(this, function(error) {
 							window.console.error("Error loading file metadata: " + error.message); //$NON-NLS-0$
 						})
-				);
+					);
+				}
 			} else {
 				mGlobalCommands.setPageTarget({task: "Search", serviceRegistry: serviceRegistry, 
 					commandService: commandService, searchService: searcher, fileService: fileClient, breadcrumbRootName: "Search",
-					makeBreadcrumbLink: function(seg,location){makeHref(fileClient, seg, location, searchLoc.searchStr);}});
+					makeBreadcrumbLink: function(seg,location){makeHref(fileClient, seg, location, searchLoc.searchStr, searcher);}});
 			}
 		}
 		mBootstrap.startup().then(function(core) {
diff --git a/bundles/org.eclipse.orion.client.editor/web/orion/textview/textDND.js b/bundles/org.eclipse.orion.client.editor/web/orion/textview/textDND.js
index 4f4df4e..855f0de 100644
--- a/bundles/org.eclipse.orion.client.editor/web/orion/textview/textDND.js
+++ b/bundles/org.eclipse.orion.client.editor/web/orion/textview/textDND.js
@@ -113,7 +113,10 @@
 		_onDragOver: function(e) {
 			var types = e.event.dataTransfer.types;
 			if (types) {
-				var allowed = types.contains ? types.contains("text/plain") : types.indexOf("text/plain") !== -1; //$NON-NLS-1$ //$NON-NLS-0$
+				var allowed = !this._view.getOptions("readonly"); //$NON-NLS-0$
+				if (allowed) {
+					allowed = types.contains ? types.contains("text/plain") : types.indexOf("text/plain") !== -1; //$NON-NLS-1$ //$NON-NLS-0$
+				}
 				if (!allowed) {
 					e.event.dataTransfer.dropEffect = "none"; //$NON-NLS-0$
 				}
diff --git a/bundles/org.eclipse.orion.client.editor/web/orion/textview/textView.js b/bundles/org.eclipse.orion.client.editor/web/orion/textview/textView.js
index 11ffb8a..7c8a8ca 100644
--- a/bundles/org.eclipse.orion.client.editor/web/orion/textview/textView.js
+++ b/bundles/org.eclipse.orion.client.editor/web/orion/textview/textView.js
@@ -4466,7 +4466,7 @@
 				handlers.push({target: topNode, type: "dragleave", handler: function(e) { return self._handleDragLeave(e);}}); //$NON-NLS-0$
 				handlers.push({target: topNode, type: "drop", handler: function(e) { return self._handleDrop(e);}}); //$NON-NLS-0$
 				handlers.push({target: this._clientDiv, type: isFirefox ? "DOMMouseScroll" : "mousewheel", handler: function(e) { return self._handleMouseWheel(e); }}); //$NON-NLS-1$ //$NON-NLS-0$
-				if (isFirefox && !isWindows) {
+				if (isFirefox && (!isWindows || isFirefox >= 15)) {
 					var MutationObserver = window.MutationObserver || window.MozMutationObserver;
 					if (MutationObserver) {
 						this._mutationObserver = new MutationObserver(function(mutations) { self._handleDataModified(mutations); });
diff --git a/bundles/org.eclipse.orion.client.git/web/git/nls/root/gitmessages.js b/bundles/org.eclipse.orion.client.git/web/git/nls/root/gitmessages.js
index 43748b3..489c600 100644
--- a/bundles/org.eclipse.orion.client.git/web/git/nls/root/gitmessages.js
+++ b/bundles/org.eclipse.orion.client.git/web/git/nls/root/gitmessages.js
@@ -346,9 +346,7 @@
 	"Merge Squash": "Merge Squash",
 	"Squash the content of the branch to the index" : "Squash the content of the branch to the index",

 	"Local Branch Name:" : "Local Branch Name:",
-	"Pull Request url for this commit" : "Pull Request url for this commit",

-	"Pull Request" : "Pull Request",

-	"Pull Request Url" : "Pull Request Url",
+	"Paste link in email or IM" : "Paste link in email or IM",
 	"Show Commit in GitHub" : "Show Commit in GitHub",

 	"Show Repository in GitHub" : "Show Repository in GitHub",

 	"Show this commit in GitHub": "Show this commit in GitHub",

@@ -358,5 +356,7 @@
 	"Show this repository in eclipse.org":"Show this repository in eclipse.org",
 	"Ask for review" : "Ask for review",

 	"Ask for review tooltip" : "Send email with request for commit review",

-	"Reviewer name" : "Reviewer name"
+	"Reviewer name" : "Reviewer name",

+	"Contribution Review Request" : "Contribution Review Request",

+	"or sent the link to the reviewer" : "or sent the link to the reviewer"
 });
diff --git a/bundles/org.eclipse.orion.client.git/web/orion/git/gitCommands.js b/bundles/org.eclipse.orion.client.git/web/orion/git/gitCommands.js
index b12de47..e0a5591 100644
--- a/bundles/org.eclipse.orion.client.git/web/orion/git/gitCommands.js
+++ b/bundles/org.eclipse.orion.client.git/web/orion/git/gitCommands.js
@@ -1689,7 +1689,7 @@
 		});
 		commandService.addCommand(removeTagCommand);
 		
-		var notificationParameters = new mCommands.ParametersDescription([new mCommands.CommandParameter('reviewer', 'text', messages["Reviewer name"])]); //$NON-NLS-1$ //$NON-NLS-0$
+		var notificationParameters = new mCommands.ParametersDescription([new mCommands.CommandParameter('reviewer', 'text', messages["Reviewer name"])], {hasOptionalParameters: true}); //$NON-NLS-1$ //$NON-NLS-0$
 		
 		var askForReviewCommand = new mCommands.Command({
 			name: messages["Ask for review"],
@@ -1698,31 +1698,47 @@
 			id: "eclipse.orion.git.askForReviewCommand", //$NON-NLS-0$
 			parameters: notificationParameters,
 			callback: function(data) {
+				var sendNotificationFunction = function(reviewerName){
+					var item = data.items;
+					var headLocation = item.Location.replace(item.Name, "HEAD"); 
+					var authorName = item.AuthorName;
+					var commitName = item.Name;
+					var commitMessage = item.Message;
+					serviceRegistry.getService("orion.git.provider").getGitClone(item.CloneLocation).then(
+						function(clone){
+							var nonHash = window.location.href.split('#')[0]; //$NON-NLS-0$
+							var orionHome = nonHash.substring(0, nonHash.length - window.location.pathname.length);
+							var pullRequestUrl = orionHome + "/git/pullRequest.html#" + clone.Children[0].GitUrl + "_" + item.Name;
+							serviceRegistry.getService("orion.git.provider").sendCommitReviewRequest(commitName, headLocation, reviewerName, pullRequestUrl, authorName, commitMessage).then(
+								function(result) {
+									var display = {};
+									display.Severity = "Ok"; //$NON-NLS-0$
+									display.HTML = false;
+									display.Message = result.Result;
+									serviceRegistry.getService("orion.page.message").setProgressResult(display);
+								}, displayErrorOnStatus
+							);
+						}
+					);
+				};
+			if (data.parameters.valueFor("reviewer") && !data.parameters.optionsRequested) { //$NON-NLS-0$
+				sendNotificationFunction(data.parameters.valueFor("reviewer")); //$NON-NLS-0$
+			} else {
 				var item = data.items;
-				
-				var headLocation = item.Location.replace(item.Name, "HEAD"); 
-				var authorName = item.AuthorName;
-				var commitName = item.Name;
-				var commitMessage = item.Message;
-				var reviewerName = data.parameters.valueFor("reviewer");
-				
 				serviceRegistry.getService("orion.git.provider").getGitClone(item.CloneLocation).then(
 					function(clone){
-						var nonHash = window.location.href.split('#')[0]; //$NON-NLS-0$
+					var nonHash = window.location.href.split('#')[0]; //$NON-NLS-0$
 						var orionHome = nonHash.substring(0, nonHash.length - window.location.pathname.length);
 						var pullRequestUrl = orionHome + "/git/pullRequest.html#" + clone.Children[0].GitUrl + "_" + item.Name;
-
-						serviceRegistry.getService("orion.git.provider").sendCommitReviewRequest(commitName, headLocation, reviewerName, pullRequestUrl, authorName, commitMessage).then(
-							function(result) {
-								var display = {};
-								display.Severity = "Ok"; //$NON-NLS-0$
-								display.HTML = false;
-								display.Message = result.Result;
-								serviceRegistry.getService("orion.page.message").setProgressResult(display);
-							}, displayErrorOnStatus
-						);
-					}
-				);
+						var dialog = new orion.git.widgets.GetPullRequestUrlDialog({
+							title: messages["Contribution Review Request"],
+							url: pullRequestUrl,
+							func: sendNotificationFunction
+							});
+							dialog.startup();
+							dialog.show();
+					},displayErrorOnStatus);
+			}
 			},
 			visibleWhen: function(item) {
 				return item.Type === "Commit"; //$NON-NLS-0$
@@ -1809,39 +1825,6 @@
 			}
 		});
 		commandService.addCommand(cherryPickCommand);
-		
-		var getPullRequestUrlCommand = new mCommands.Command({
-			name : messages["Pull Request Url"],
-			tooltip: messages["Pull Request url for this commit"],
-			id : "eclipse.orion.git.getPullRequestUrl", //$NON-NLS-0$
-			imageClass: "git-sprite-cherry_pick", //$NON-NLS-0$
-			spriteClass: "gitCommandSprite", //$NON-NLS-0$
-			callback: function(data) {
-				var service = serviceRegistry.getService("orion.git.provider");
-				service.getGitClone(data.items.CloneLocation).then(
-					function(clone){
-						var url = clone.Children[0].GitUrl;
-						var sha1 = data.items.Name;
-						
-						var nonHash = window.location.href.split('#')[0]; //$NON-NLS-0$
-						var orionHome = nonHash.substring(0, nonHash.length - window.location.pathname.length);
-						
-						var pullRequestUrl = orionHome + "/git/pullRequest.html#" + url + "_" + sha1;
-						var dialog = new orion.git.widgets.GetPullRequestUrlDialog({
-							title: messages["Pull Request"],
-							url: pullRequestUrl
-						});
-						dialog.startup();
-						dialog.show();
-					}
-				);
-			},
-			visibleWhen : function(item) {
-				return item.Type === "Commit"; //$NON-NLS-0$
-			}
-		});
-	
-		commandService.addCommand(getPullRequestUrlCommand);
 	};
 	
 
diff --git a/bundles/org.eclipse.orion.client.git/web/orion/git/gitRepositoryExplorer.js b/bundles/org.eclipse.orion.client.git/web/orion/git/gitRepositoryExplorer.js
index 5181995..65e3166 100644
--- a/bundles/org.eclipse.orion.client.git/web/orion/git/gitRepositoryExplorer.js
+++ b/bundles/org.eclipse.orion.client.git/web/orion/git/gitRepositoryExplorer.js
@@ -248,79 +248,91 @@
 		
 		this.registry.getService("orion.core.file").loadWorkspace(repository.ContentLocation + "?parts=meta").then( //$NON-NLS-1$ //$NON-NLS-0$
 				function(resp){
-					repository.Content = {};
-					
-					var path = "root / "; //$NON-NLS-0$
-					if (resp.Parents !== null)
-						for (var i=resp.Parents.length; i>0; i--){
-							path += resp.Parents[i-1].Name + " / "; //$NON-NLS-0$
+					try{
+						repository.Content = {};
+						
+						var path = "root / "; //$NON-NLS-0$
+						if (resp.Parents !== null)
+							for (var i=resp.Parents.length; i>0; i--){
+								path += resp.Parents[i-1].Name + " / "; //$NON-NLS-0$
+							}
+							
+						path += resp.Name;
+						repository.Content.Path = path;
+						
+						if (mode !== "full"){ //$NON-NLS-0$
+							deferred.callback();
+							return;
 						}
 						
-					path += resp.Name;
-					repository.Content.Path = path;
-					
-					if (mode !== "full"){ //$NON-NLS-0$
-						deferred.callback();
-						return;
-					}
-					
-					that.registry.getService("orion.git.provider").getGitStatus(repository.StatusLocation).then( //$NON-NLS-0$
-						function(resp){
-							repository.Status = resp;
-
-							that.registry.getService("orion.git.provider").getGitBranch(repository.BranchLocation).then( //$NON-NLS-0$
-								function(resp){
-									var branches = resp.Children;
-									var currentBranch;
-									for (var i=0; i<branches.length; i++){
-										if (branches[i].Current){
-											currentBranch = branches[i];
-											break;
+						that.registry.getService("orion.git.provider").getGitStatus(repository.StatusLocation).then( //$NON-NLS-0$
+							function(resp){
+								try{
+									repository.Status = resp;
+		
+									that.registry.getService("orion.git.provider").getGitBranch(repository.BranchLocation).then( //$NON-NLS-0$
+										function(resp){
+											try{
+												var branches = resp.Children || [];
+												var currentBranch;
+												for (var i=0; i<branches.length; i++){
+													if (branches[i].Current){
+														currentBranch = branches[i];
+														break;
+													}
+												}
+												
+												if (!currentBranch || currentBranch.RemoteLocation[0] === null){
+													deferred.callback();
+													return;
+												}
+												
+												var tracksRemoteBranch = (currentBranch.RemoteLocation.length === 1 && currentBranch.RemoteLocation[0].Children.length === 1);
+												
+												if (tracksRemoteBranch && currentBranch.RemoteLocation[0].Children[0].CommitLocation){
+													that.registry.getService("orion.git.provider").getLog(currentBranch.RemoteLocation[0].Children[0].CommitLocation + "?page=1&pageSize=20", "HEAD").then( //$NON-NLS-2$ //$NON-NLS-1$ //$NON-NLS-0$
+														function(resp){
+															if(resp.Children === undefined) { repository.CommitsToPush = 0; }
+															else { repository.CommitsToPush = resp.Children.length; }
+															deferred.callback();
+															return;
+														}, function(resp){
+															deferred.errback();
+															return;
+														}
+													);
+												} else {
+													that.registry.getService("orion.git.provider").doGitLog(currentBranch.CommitLocation + "?page=1&pageSize=20").then(  //$NON-NLS-1$ //$NON-NLS-0$
+														function(resp){	
+															if(resp.Children === undefined) { repository.CommitsToPush = 0; }
+															else { repository.CommitsToPush = resp.Children.length; }
+															deferred.callback();
+															return;
+														}, function(resp){
+															deferred.errback();
+															return;
+														}
+													);	
+												}
+											}catch(e){
+												deferred.errback();
+											}
+										}, function(resp){
+											deferred.errback();
+											return;
 										}
-									}
-									
-									if (!currentBranch || currentBranch.RemoteLocation[0] === null){
-										deferred.callback();
-										return;
-									};
-									
-									var tracksRemoteBranch = (currentBranch.RemoteLocation.length === 1 && currentBranch.RemoteLocation[0].Children.length === 1);
-									
-									if (tracksRemoteBranch && currentBranch.RemoteLocation[0].Children[0].CommitLocation){
-										that.registry.getService("orion.git.provider").getLog(currentBranch.RemoteLocation[0].Children[0].CommitLocation + "?page=1&pageSize=20", "HEAD").then( //$NON-NLS-2$ //$NON-NLS-1$ //$NON-NLS-0$
-											function(resp){
-												if(resp.Children === undefined) { repository.CommitsToPush = 0; }
-												else { repository.CommitsToPush = resp.Children.length; }
-												deferred.callback();
-												return;
-											}, function(resp){
-												deferred.errback();
-												return;
-											}
-										);
-									} else {
-										that.registry.getService("orion.git.provider").doGitLog(currentBranch.CommitLocation + "?page=1&pageSize=20").then(  //$NON-NLS-1$ //$NON-NLS-0$
-											function(resp){	
-												if(resp.Children === undefined) { repository.CommitsToPush = 0; }
-												else { repository.CommitsToPush = resp.Children.length; }
-												deferred.callback();
-												return;
-											}, function(resp){
-												deferred.errback();
-												return;
-											}
-										);	
-									}
-								}, function(resp){
+									);
+								}catch(e){
 									deferred.errback();
-									return;
 								}
-							);
-						}, function(resp){
-							deferred.errback();
-							return;
-						}	
-					);
+							}, function(resp){
+								deferred.errback();
+								return;
+							}	
+						);
+					}catch(e){
+						deferred.errback(e);
+					}
 				}, function(resp){
 					deferred.errback();
 					return;
diff --git a/bundles/org.eclipse.orion.client.git/web/orion/git/widgets/GetPullRequestUrlDialog.js b/bundles/org.eclipse.orion.client.git/web/orion/git/widgets/GetPullRequestUrlDialog.js
index 78fb4c1..976e234 100644
--- a/bundles/org.eclipse.orion.client.git/web/orion/git/widgets/GetPullRequestUrlDialog.js
+++ b/bundles/org.eclipse.orion.client.git/web/orion/git/widgets/GetPullRequestUrlDialog.js
@@ -42,8 +42,9 @@
 	
 	/** @private */
 	postMixInProperties : function() {
-		this.options.title = this.options.title || messages["Pull Request"];
-		this.selectFile = messages["Pull Request url for this commit"];
+		this.options.title = this.options.title || messages["Contribution Review Request"];
+		this.selectFile = messages["Paste link in email or IM"];
+		this.reviewerName = messages["or sent the link to the reviewer"];
 
 		this.inherited(arguments);
 	},
@@ -67,6 +68,12 @@
 	onHide: function() {
 		clearTimeout(this.timeoutId);
 		this.inherited(arguments);
+	},
+	
+	execute: function() {
+		if(this.options.func)
+			this.options.func(this.ReviewerName.value);
+		delete this.options.func; //prevent performing this action twice (IE)
 	}
 	
 });
diff --git a/bundles/org.eclipse.orion.client.git/web/orion/git/widgets/templates/GetPullRequestUrlDialog.html b/bundles/org.eclipse.orion.client.git/web/orion/git/widgets/templates/GetPullRequestUrlDialog.html
index 17027db..190a674 100644
--- a/bundles/org.eclipse.orion.client.git/web/orion/git/widgets/templates/GetPullRequestUrlDialog.html
+++ b/bundles/org.eclipse.orion.client.git/web/orion/git/widgets/templates/GetPullRequestUrlDialog.html
@@ -15,9 +15,22 @@
 			<div style="display:table-row">
 				<div style="display:table-cell; padding:5;">
 					<input type="text" dojoType="dijit.form.TextBox" dojoAttachPoint="PullReqUrl"
-					style="width:80em;">
+					style="width:30em;">
 				</div>
 			</div>
+			<br>
+			<div style="display:table-row">
+				<div style="display:table-cell; padding:5;">
+					<label for="ReviewerName" style="padding-right:10">${reviewerName}</label>
+				</div>
+			</div>
+			<div style="display: block; padding: 5; clear: both; text-align: left">
+				<input type="text" dojoType="dijit.form.TextBox" dojoAttachPoint="ReviewerName"
+					style="width:15em;" placeholder="Reviewer name">
+			</div>
+			<button dojoAttachPoint="AskForReview" dojoType="dijit.form.Button" type="submit" value="OK" style="padding: 20 0 10 0; float: right; clear: both;">Submit
+				</button>
+			<br>
 		</div>
 	</div>
 </div>
\ No newline at end of file