Merge branch 'master' of ssh://git.eclipse.org/gitroot/orion/org.eclipse.orion.client
diff --git a/bundles/org.eclipse.orion.client.core/web/orion/xhr.js b/bundles/org.eclipse.orion.client.core/web/orion/xhr.js
index bce8c49..ba5329e 100644
--- a/bundles/org.eclipse.orion.client.core/web/orion/xhr.js
+++ b/bundles/org.eclipse.orion.client.core/web/orion/xhr.js
@@ -41,11 +41,17 @@
 	function makeResult(url, options, xhr, error) {
 		var response = typeof xhr.response !== 'undefined' ? xhr.response : xhr.responseText; //$NON-NLS-0$
 		var responseText = typeof response === 'string' ? response : null; //$NON-NLS-0$
+		var status;
+		try {
+			status = xhr.status;
+		} catch (e) {
+			status = 0;
+		}
 		var result = {
 			args: options,
 			response: response,
 			responseText: responseText,
-			status: xhr.status,
+			status: status,
 			url: url,
 			xhr: xhr
 		};
diff --git a/bundles/org.eclipse.orion.client.editor/web/orion/editor/textView.js b/bundles/org.eclipse.orion.client.editor/web/orion/editor/textView.js
index d05ab8b..c55b3a8 100644
--- a/bundles/org.eclipse.orion.client.editor/web/orion/editor/textView.js
+++ b/bundles/org.eclipse.orion.client.editor/web/orion/editor/textView.js
@@ -4296,6 +4296,11 @@
 			index = index === undefined || index < 0 || index > length ? length : index;
 			var cell = row.insertCell(index);
 			cell.vAlign = "top"; //$NON-NLS-0$
+			cell.style.verticalAlign = "top";
+			cell.style.borderWidth = "0px"; //$NON-NLS-0$
+			cell.style.margin = "0px"; //$NON-NLS-0$
+			cell.style.padding = "0px"; //$NON-NLS-0$
+			cell.style.outline = "none"; //$NON-NLS-0$
 			cell.appendChild(div);
 		},
 		_createView: function() {
@@ -4331,7 +4336,15 @@
 			table.cellPadding = "0px"; //$NON-NLS-0$
 			table.cellSpacing = "0px"; //$NON-NLS-0$
 			table.border = "0px"; //$NON-NLS-0$
-			table.insertRow(0);
+			table.style.borderWidth = "0px"; //$NON-NLS-0$
+			table.style.margin = "0px"; //$NON-NLS-0$
+			table.style.padding = "0px"; //$NON-NLS-0$
+			table.style.outline = "none"; //$NON-NLS-0$
+			var tr = table.insertRow(0);
+			tr.style.borderWidth = "0px"; //$NON-NLS-0$
+			tr.style.margin = "0px"; //$NON-NLS-0$
+			tr.style.padding = "0px"; //$NON-NLS-0$
+			tr.style.outline = "none"; //$NON-NLS-0$
 			rootDiv.appendChild(leftDiv);
 
 			var viewDiv = util.createElement(document, "div"); //$NON-NLS-0$
@@ -4364,7 +4377,15 @@
 			table.cellPadding = "0px"; //$NON-NLS-0$
 			table.cellSpacing = "0px"; //$NON-NLS-0$
 			table.border = "0px"; //$NON-NLS-0$
-			table.insertRow(0);
+			table.style.borderWidth = "0px"; //$NON-NLS-0$
+			table.style.margin = "0px"; //$NON-NLS-0$
+			table.style.padding = "0px"; //$NON-NLS-0$
+			table.style.outline = "none"; //$NON-NLS-0$
+			tr = table.insertRow(0);
+			tr.style.borderWidth = "0px"; //$NON-NLS-0$
+			tr.style.margin = "0px"; //$NON-NLS-0$
+			tr.style.padding = "0px"; //$NON-NLS-0$
+			tr.style.outline = "none"; //$NON-NLS-0$
 			rootDiv.appendChild(rightDiv);
 				
 			var scrollDiv = util.createElement(document, "div"); //$NON-NLS-0$
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 012c127..d83a745 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
@@ -9,12 +9,13 @@
  * Contributors: IBM Corporation - initial API and implementation
  ******************************************************************************/
 
+/*globals window document define confirm URL*/
+
 define(['i18n!git/nls/gitmessages', 'require', 'orion/Deferred', 'orion/i18nUtil', 'orion/webui/littlelib', 'orion/commands', 'orion/git/util', 'orion/compare/compareUtils', 'orion/git/gitPreferenceStorage', 
         'orion/git/widgets/ConfirmPushDialog', 'orion/git/widgets/RemotePrompterDialog', 'orion/git/widgets/ReviewRequestDialog', 'orion/git/widgets/CloneGitRepositoryDialog', 
-        'orion/git/widgets/GitCredentialsDialog', 'orion/git/widgets/OpenCommitDialog', 'orion/git/widgets/CommitDialog', 'orion/git/widgets/ApplyPatchDialog'], 
-        function(messages, require, Deferred, i18nUtil, lib, mCommands, mGitUtil, mCompareUtils, GitPreferenceStorage, 
-        		mConfirmPush, mRemotePrompter, mReviewRequest, mCloneGitRepository, mGitCredentials, mOpenCommit,
-        		mCommit, mApplyPatch) {
+        'orion/git/widgets/GitCredentialsDialog', 'orion/git/widgets/OpenCommitDialog', 'orion/git/widgets/CommitDialog', 'orion/git/widgets/ApplyPatchDialog', 'orion/URL-shim'], 
+        function(messages, require, Deferred, i18nUtil, lib, mCommands, mGitUtil, mCompareUtils, GitPreferenceStorage, mConfirmPush, mRemotePrompter,
+        mReviewRequest, mCloneGitRepository, mGitCredentials, mOpenCommit, mCommit, mApplyPatch) {
 
 /**
  * @namespace The global container for eclipse APIs.
@@ -388,7 +389,7 @@
 					}, displayErrorOnStatus);
 				};
 				
-				var repositoryLocation = (item.Repository != null) ? item.Repository.Location : item.CloneLocation;
+				var repositoryLocation = (item.Repository !== null) ? item.Repository.Location : item.CloneLocation;
 				if (data.parameters.valueFor("name") && !data.parameters.optionsRequested) { //$NON-NLS-0$
 					checkoutTagFunction(repositoryLocation, item.Name, data.parameters.valueFor("name")); //$NON-NLS-0$
 				}
@@ -426,7 +427,7 @@
 					);
 				} else {
 					var branchLocation;
-					if (item.Repository != null) {
+					if (item.Repository !== null) {
 						branchLocation = item.Repository.BranchLocation;
 					} else {
 						branchLocation = item.parent.parent.BranchLocation;
@@ -748,7 +749,7 @@
 				return mCompareUtils.generateCompareHref(data.items.DiffLocation, {});
 			},
 			visibleWhen : function(item) {
-				return item.Type === "Commit" && item.ContentLocation != null && !explorer.isDirectory; //$NON-NLS-0$
+				return item.Type === "Commit" && item.ContentLocation !== null && !explorer.isDirectory; //$NON-NLS-0$
 			}
 		});
 		commandService.addCommand(compareWithWorkingTree);
@@ -1028,7 +1029,7 @@
 				progress.progress(gitService.doMerge(item.HeadLocation, item.Name, false), "Merging " + item.Name).then(function(result){
 					var display = {};
 
-					if (result.Result == "FAST_FORWARD" || result.Result == "ALREADY_UP_TO_DATE"){ //$NON-NLS-1$ //$NON-NLS-0$
+					if (result.Result === "FAST_FORWARD" || result.Result === "ALREADY_UP_TO_DATE"){ //$NON-NLS-1$ //$NON-NLS-0$
 						display.Severity = "Ok"; //$NON-NLS-0$
 						display.HTML = false;
 						display.Message = result.Result;
@@ -1111,7 +1112,7 @@
 				progress.progress(gitService.doMerge(item.HeadLocation, item.Name, true), "Merging " + item.Name).then(function(result){
 					var display = [];
 
-					if (result.Result == "FAST_FORWARD_SQUASHED" || result.Result == "ALREADY_UP_TO_DATE"){ //$NON-NLS-1$ //$NON-NLS-0$
+					if (result.Result === "FAST_FORWARD_SQUASHED" || result.Result === "ALREADY_UP_TO_DATE"){ //$NON-NLS-1$ //$NON-NLS-0$
 						display.Severity = "Ok"; //$NON-NLS-0$
 						display.HTML = false;
 						display.Message = result.Result;
@@ -1183,14 +1184,14 @@
 						var display = [];
 						var statusLocation = item.HeadLocation.replace("commit/HEAD", "status"); //$NON-NLS-1$ //$NON-NLS-0$
 	
-						if (jsonData.Result == "OK" || jsonData.Result == "FAST_FORWARD" || jsonData.Result == "UP_TO_DATE" ) { //$NON-NLS-2$ //$NON-NLS-1$ //$NON-NLS-0$
+						if (jsonData.Result === "OK" || jsonData.Result === "FAST_FORWARD" || jsonData.Result === "UP_TO_DATE" ) { //$NON-NLS-2$ //$NON-NLS-1$ //$NON-NLS-0$
 							// operation succeeded
 							display.Severity = "Ok"; //$NON-NLS-0$
 							display.HTML = false;
 							display.Message = jsonData.Result;
 						}
 						// handle special cases
-						else if (jsonData.Result == "STOPPED") { //$NON-NLS-0$
+						else if (jsonData.Result === "STOPPED") { //$NON-NLS-0$
 							display.Severity = "Warning"; //$NON-NLS-0$
 							display.HTML = true;
 							display.Message = "<span>" + jsonData.Result //$NON-NLS-0$
@@ -1198,7 +1199,7 @@
 								+ i18nUtil.formatMessage(messages['. Go to ${0}.'], "<a href=\"" + require.toUrl(mGitUtil.statusUILocation) + "#"  //$NON-NLS-2$ //$NON-NLS-1$
 								+ statusLocation +"\">"+messages['Git Status page']+"</a>")+".</span>"; //$NON-NLS-3$ //$NON-NLS-2$ //$NON-NLS-0$
 						}
-						else if (jsonData.Result == "FAILED_WRONG_REPOSITORY_STATE") { //$NON-NLS-0$
+						else if (jsonData.Result === "FAILED_WRONG_REPOSITORY_STATE") { //$NON-NLS-0$
 							display.Severity = "Error"; //$NON-NLS-0$
 							display.HTML = true;
 							display.Message = "<span>" + jsonData.Result //$NON-NLS-0$
@@ -1206,7 +1207,7 @@
 								+ i18nUtil.formatMessage(". Go to ${0}.", "<a href=\"" + require.toUrl(mGitUtil.statusUILocation) + "#"  //$NON-NLS-2$ //$NON-NLS-1$ //$NON-NLS-0$
 								+ statusLocation +"\">"+messages['Git Status page']+"</a>")+".</span>"; //$NON-NLS-3$ //$NON-NLS-2$ //$NON-NLS-0$
 						}
-						else if (jsonData.Result == "FAILED_UNMERGED_PATHS") { //$NON-NLS-0$
+						else if (jsonData.Result === "FAILED_UNMERGED_PATHS") { //$NON-NLS-0$
 							display.Severity = "Error"; //$NON-NLS-0$
 							display.HTML = true;
 							display.Message = "<span>" + jsonData.Result //$NON-NLS-0$
@@ -1214,7 +1215,7 @@
 								+ i18nUtil.formatMessage(messages['. Go to ${0}.'], "<a href=\"" + require.toUrl(mGitUtil.statusUILocation) + "#"  //$NON-NLS-2$ //$NON-NLS-1$
 	   							+ statusLocation +"\">"+messages['Git Status page']+"</a>")+".</span>"; //$NON-NLS-3$ //$NON-NLS-2$ //$NON-NLS-0$
 						}
-						else if (jsonData.Result == "FAILED_PENDING_CHANGES") { //$NON-NLS-0$
+						else if (jsonData.Result === "FAILED_PENDING_CHANGES") { //$NON-NLS-0$
 							display.Severity = "Error"; //$NON-NLS-0$
 							display.HTML = true;
 							display.Message = "<span>" + jsonData.Result //$NON-NLS-0$
@@ -1386,7 +1387,7 @@
 														commandInvocation.targetBranch = target;
 														handlePush(options, target.Location, "HEAD",target.Name, false);
 													}, function(err){
-														if(err.status == 409){ //when confing entry is already defined we have to edit it
+														if(err.status === 409){ //when confing entry is already defined we have to edit it
 															progress.progress(gitService.editCloneConfigurationProperty(locationToUpdate,target.parent.Name), "Updating configuration property " + target.parent.Name).then(
 																function(){
 																	commandInvocation.targetBranch = target;
@@ -1581,7 +1582,7 @@
 														commandInvocation.targetBranch = target;
 														handlePush(options, target.Location, "HEAD",target.Name, true);
 													}, function(err){
-														if(err.status == 409){ //when confing entry is already defined we have to edit it
+														if(err.status === 409){ //when confing entry is already defined we have to edit it
 															progress.progres(gitService.editCloneConfigurationProperty(locationToUpdate,target.parent.Name), "Setting git configuration property " + target.parent.Name).then(
 																function(){
 																	commandInvocation.targetBranch = target;
@@ -1597,7 +1598,7 @@
 										if (item.RemoteLocation.length === 1 && item.RemoteLocation[0].Children.length === 1) { //when we push next time - chance to switch saved remote
 											var dialog2 = dialog;
 											
-											dialog = new orion.git.widgets.ConfirmPushDialog({
+											dialog = new mConfirmPush.ConfirmPushDialog({
 												title: messages["Choose Branch"],
 												serviceRegistry: serviceRegistry,
 												gitClient: gitService,
@@ -1635,7 +1636,7 @@
 				return require.toUrl("git/git-log.html") + "#" + data.items.PreviousLocation; //$NON-NLS-1$ //$NON-NLS-0$
 			},
 			visibleWhen : function(item) {
-				if(item.Type === "RemoteTrackingBranch" || (item.toRef != null && item.toRef.Type === "Branch") || item.RepositoryPath != null){ //$NON-NLS-1$ //$NON-NLS-0$
+				if(item.Type === "RemoteTrackingBranch" || (item.toRef !== null && item.toRef.Type === "Branch") || item.RepositoryPath !== null){ //$NON-NLS-1$ //$NON-NLS-0$
 					return item.PreviousLocation !== undefined;
 				}
 				return false;
@@ -1651,7 +1652,7 @@
 				return require.toUrl("git/git-log.html") + "#" + data.items.NextLocation; //$NON-NLS-1$ //$NON-NLS-0$
 			},
 			visibleWhen : function(item) {
-				if(item.Type === "RemoteTrackingBranch" ||(item.toRef != null && item.toRef.Type === "Branch") || item.RepositoryPath != null){ //$NON-NLS-1$ //$NON-NLS-0$
+				if(item.Type === "RemoteTrackingBranch" ||(item.toRef !== null && item.toRef.Type === "Branch") || item.RepositoryPath !== null){ //$NON-NLS-1$ //$NON-NLS-0$
 					return item.NextLocation !== undefined;
 				}
 				return false;
@@ -1683,7 +1684,7 @@
 				return require.toUrl("git/git-repository.html") + "#" + data.items.NextLocation;
 			},
 			visibleWhen : function(item){
-				if(item.Type == "Tag"){
+				if(item.Type === "Tag"){
 					return item.NextLocation !== undefined;
 				}
 				return false;
@@ -1819,7 +1820,7 @@
 							"Getting repository details " + item.Name).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 orionHome = new URL(require.toUrl("."), window.location).href.slice(0,-1);
 							var url = sshCheck(clone.Children[0].GitUrl);
 							var reviewRequestUrl = orionHome + "/git/reviewRequest.html#" + url + "_" + item.Name;
 							progress.progress(
@@ -1842,7 +1843,7 @@
 					progress.progress(serviceRegistry.getService("orion.git.provider").getGitClone(item.CloneLocation),
 							"Getting git details " + item.Name).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 orionHome = new URL(require.toUrl("."), window.location).href.slice(0,-1);
 						var url = sshCheck(clone.Children[0].GitUrl);
 						var reviewRequestUrl = orionHome + "/git/reviewRequest.html#" + url + "_" + item.Name;
 						var dialog = new mReviewRequest.ReviewRequestDialog({ title : messages["Contribution Review Request"],
@@ -1877,7 +1878,7 @@
 					// code
 					var statusLocation = item.Location.replace("commit/" + item.Name, "status"); //$NON-NLS-1$ //$NON-NLS-0$
 
-					if (jsonData.Result == "OK") { //$NON-NLS-0$
+					if (jsonData.Result === "OK") { //$NON-NLS-0$
 						// operation succeeded
 						display.Severity = "Ok"; //$NON-NLS-0$
 						if (jsonData.HeadUpdated) {
@@ -1889,13 +1890,13 @@
 						}
 					}
 					// handle special cases
-					else if (jsonData.Result == "CONFLICTING") { //$NON-NLS-0$
+					else if (jsonData.Result === "CONFLICTING") { //$NON-NLS-0$
 						display.Severity = "Warning"; //$NON-NLS-0$
 						display.HTML = true;
 						display.Message = "<span>" + jsonData.Result + messages[". Some conflicts occurred"] + //$NON-NLS-0$
 						+ i18nUtil.formatMessage(messages['. Go to ${0}.'], "<a href=\"" + require.toUrl(mGitUtil.statusUILocation) + "#"  //$NON-NLS-2$ //$NON-NLS-1$
 						+ statusLocation +"\">"+messages['Git Status page']+"</a>")+".</span>"; //$NON-NLS-3$ //$NON-NLS-2$ //$NON-NLS-0$
-					} else if (jsonData.Result == "FAILED") { //$NON-NLS-0$
+					} else if (jsonData.Result === "FAILED") { //$NON-NLS-0$
 						display.Severity = "Error"; //$NON-NLS-0$
 						display.HTML = true;
 						display.Message = "<span>" + jsonData.Result;  //$NON-NLS-0$
@@ -2748,6 +2749,47 @@
 		
 		// Rebase commands
 		
+		function _rebase(HeadLocation, action){
+			var progressService = serviceRegistry.getService("orion.page.message"); //$NON-NLS-0$
+			var progress = serviceRegistry.getService("orion.page.progress"); //$NON-NLS-0$
+			
+			var deferred = progress.progress(serviceRegistry.getService("orion.git.provider").doRebase(HeadLocation, "", action), "Rebasing git repository"); //$NON-NLS-0$ 
+			progressService.createProgressMonitor(
+				deferred,
+				action);
+			deferred.then(
+				function(jsonData){
+					if (jsonData.Result === "OK" || jsonData.Result === "ABORTED" || jsonData.Result === "FAST_FORWARD" || jsonData.Result === "UP_TO_DATE") { //$NON-NLS-3$ //$NON-NLS-2$ //$NON-NLS-1$ //$NON-NLS-0$
+						var display = [];
+						display.Severity = "Ok"; //$NON-NLS-0$
+						display.HTML = false;
+						display.Message = jsonData.Result;
+						
+						serviceRegistry.getService("orion.page.message").setProgressResult(display); //$NON-NLS-0$
+						explorer.changedItem({});
+					}
+					
+					if (jsonData.Result === "STOPPED") { //$NON-NLS-0$
+						var display = [];
+						display.Severity = "Warning"; //$NON-NLS-0$
+						display.HTML = false;
+						display.Message = jsonData.Result + messages['. Repository still contains conflicts.'];
+						
+						serviceRegistry.getService("orion.page.message").setProgressResult(display); //$NON-NLS-0$
+						explorer.changedItem({});
+					} else if (jsonData.Result === "FAILED_UNMERGED_PATHS") { //$NON-NLS-0$
+						var display = [];
+						display.Severity = "Error"; //$NON-NLS-0$
+						display.HTML = false;
+						display.Message = jsonData.Result + messages['. Repository contains unmerged paths. Resolve conflicts first.'];
+						
+						serviceRegistry.getService("orion.page.message").setProgressResult(display); //$NON-NLS-0$
+					}
+					
+				}, displayErrorOnStatus
+			);
+		}
+		
 		var rebaseContinueCommand = new mCommands.Command({
 			name: messages["Continue"],
 			tooltip: messages["Contibue Rebase"],
@@ -2758,7 +2800,7 @@
 			},
 			
 			visibleWhen: function(item) {
-				return item.RepositoryState.indexOf("REBASING") != -1; //$NON-NLS-0$
+				return item.RepositoryState.indexOf("REBASING") !== -1; //$NON-NLS-0$
 			}
 		});
 		
@@ -2774,7 +2816,7 @@
 			},
 			
 			visibleWhen: function(item) {
-				return item.RepositoryState.indexOf("REBASING") != -1; //$NON-NLS-0$
+				return item.RepositoryState.indexOf("REBASING") !== -1; //$NON-NLS-0$
 			}
 		});
 		
@@ -2790,53 +2832,14 @@
 			},
 			
 			visibleWhen: function(item) {
-				return item.RepositoryState.indexOf("REBASING") != -1; //$NON-NLS-0$
+				return item.RepositoryState.indexOf("REBASING") !== -1; //$NON-NLS-0$
 			}
 		});
 		
 		commandService.addCommand(rebaseAbortCommand);	
 
 		
-		function _rebase(HeadLocation, action){
-			var progressService = serviceRegistry.getService("orion.page.message"); //$NON-NLS-0$
-			var progress = serviceRegistry.getService("orion.page.progress"); //$NON-NLS-0$
-			
-			var deferred = progress.progress(serviceRegistry.getService("orion.git.provider").doRebase(HeadLocation, "", action), "Rebasing git repository"); //$NON-NLS-0$ 
-			progressService.createProgressMonitor(
-				deferred,
-				action);
-			deferred.then(
-				function(jsonData){
-					if (jsonData.Result == "OK" || jsonData.Result == "ABORTED" || jsonData.Result == "FAST_FORWARD" || jsonData.Result == "UP_TO_DATE") { //$NON-NLS-3$ //$NON-NLS-2$ //$NON-NLS-1$ //$NON-NLS-0$
-						var display = [];
-						display.Severity = "Ok"; //$NON-NLS-0$
-						display.HTML = false;
-						display.Message = jsonData.Result;
-						
-						serviceRegistry.getService("orion.page.message").setProgressResult(display); //$NON-NLS-0$
-						explorer.changedItem({});
-					}
-					
-					if (jsonData.Result == "STOPPED") { //$NON-NLS-0$
-						var display = [];
-						display.Severity = "Warning"; //$NON-NLS-0$
-						display.HTML = false;
-						display.Message = jsonData.Result + messages['. Repository still contains conflicts.'];
-						
-						serviceRegistry.getService("orion.page.message").setProgressResult(display); //$NON-NLS-0$
-						explorer.changedItem({});
-					} else if (jsonData.Result == "FAILED_UNMERGED_PATHS") { //$NON-NLS-0$
-						var display = [];
-						display.Severity = "Error"; //$NON-NLS-0$
-						display.HTML = false;
-						display.Message = jsonData.Result + messages['. Repository contains unmerged paths. Resolve conflicts first.'];
-						
-						serviceRegistry.getService("orion.page.message").setProgressResult(display); //$NON-NLS-0$
-					}
-					
-				}, displayErrorOnStatus
-			);
-		}
+
 	};
 
 }());
diff --git a/bundles/org.eclipse.orion.client.ui/web/content/content.js b/bundles/org.eclipse.orion.client.ui/web/content/content.js
index 4f64f40..a8fb87d 100644
--- a/bundles/org.eclipse.orion.client.ui/web/content/content.js
+++ b/bundles/org.eclipse.orion.client.ui/web/content/content.js
@@ -9,7 +9,7 @@
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
-/*global define orion window document */
+/*global define orion window document URL*/
 /*jslint browser:true*/
 
 /*
@@ -17,7 +17,7 @@
  */
 
 define(['i18n!orion/content/nls/messages', 'require', 'orion/webui/littlelib', 'orion/bootstrap', 'orion/status', 'orion/progress', 'orion/commands', 'orion/fileClient', 'orion/operationsClient',
-	        'orion/searchClient', 'orion/globalCommands', 'orion/URITemplate', 'orion/PageUtil'], 
+	        'orion/searchClient', 'orion/globalCommands', 'orion/URITemplate', 'orion/PageUtil', 'orion/URL-shim'], 
 			function(messages, require, lib, mBootstrap, mStatus, mProgress, mCommands, mFileClient, mOperationsClient, mSearchClient, 
 			mGlobalCommands, URITemplate, PageUtil) {
 
@@ -33,7 +33,7 @@
 		var searcher = new mSearchClient.Searcher({serviceRegistry: serviceRegistry, commandService: commandService, fileService: fileClient});
 		
 		var fileMetadata;
-		var hostName;
+		var orionHome = new URL(require.toUrl("."), window.location).href.slice(0,-1);
 		
 		/**
 		 * Utility method for saving file contents to a specified location
@@ -78,8 +78,7 @@
 			var params = PageUtil.matchResourceParameters(window.location.href);
 			var nonHash = window.location.href.split('#')[0]; //$NON-NLS-0$
 			// TODO: should not be necessary, see bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=373450
-			hostName = nonHash.substring(0, nonHash.length - window.location.pathname.length);
-			var locationObject = {OrionHome: hostName, Location: params.resource};
+			var locationObject = {OrionHome: orionHome, Location: params.resource};
 			if (params.contentProvider) {
 				// Note that the shape of the "orion.page.content" extension is not in any shape or form that could be considered final.
 				// We've included it to enable experimentation. Please provide feedback on IRC or bugzilla.
@@ -104,10 +103,10 @@
 							info[propertyNames[j]] = contentProviders[i].getProperty(propertyNames[j]);
 						}
 						foundContent = true;
-						locationObject.ExitURL = hostName+"/content/exit.html"; //$NON-NLS-0$
+						locationObject.ExitURL = orionHome+"/content/exit.html"; //$NON-NLS-0$
 						if (info.saveToken) {
 							// we need to set up a SaveURL for the iframe to use.
-							locationObject.SaveURL = hostName+"/content/saveHook.html#" + params.resource + ",contentProvider=" + params.contentProvider + ","; //$NON-NLS-2$ //$NON-NLS-1$ //$NON-NLS-0$
+							locationObject.SaveURL = orionHome+"/content/saveHook.html#" + params.resource + ",contentProvider=" + params.contentProvider + ","; //$NON-NLS-2$ //$NON-NLS-1$ //$NON-NLS-0$
 						}
 						
 						function makeIFrame() {
@@ -168,7 +167,7 @@
 		window.addEventListener("message", function(event) { //$NON-NLS-0$
 			// For potentially dangerous actions, such as save, we will force the content to be from our domain (internal
 			// save hook), which we know has given the user the change to look at the data before save.
-			if (hostName && fileMetadata && event.source.parent === window && event.origin === hostName ) {
+			if (orionHome && fileMetadata && event.source.parent === window && event.origin === new URL(window.location).origin ) {
 				if (typeof event.data === "string") { //$NON-NLS-0$
 				var data = JSON.parse(event.data);
 					if (data.shellService) {
@@ -176,7 +175,7 @@
 							saveFileContents(fileClient, fileMetadata, {sourceLocation: data.sourceLocation}, function() {
 								if (window.confirm(messages["Content has been saved.  Click OK to go to the navigator, Cancel to keep editing."])) {
 									// go to the navigator
-									window.location.href = hostName + "/navigate/table.html#" + fileMetadata.Parents[0].ChildrenLocation; //$NON-NLS-0$
+									window.location.href = orionHome + "/navigate/table.html#" + fileMetadata.Parents[0].ChildrenLocation; //$NON-NLS-0$
 								} else {
 									loadContent();
 								}
diff --git a/bundles/org.eclipse.orion.client.ui/web/js-tests/globalSearch/testcase.js b/bundles/org.eclipse.orion.client.ui/web/js-tests/globalSearch/testcase.js
index 2a82804..8b8ed15 100644
--- a/bundles/org.eclipse.orion.client.ui/web/js-tests/globalSearch/testcase.js
+++ b/bundles/org.eclipse.orion.client.ui/web/js-tests/globalSearch/testcase.js
@@ -41,7 +41,7 @@
 	 */
 	function replaceFile(fileContentText, fileModel, inFileQuery, replaceString) {
 		var newContents = {contents: null};
-		mSearchUtils.generateNewContents(true, fileModel.contents, newContents, fileModel, replaceString, inFileQuery.searchStrLength); 
+		mSearchUtils.generateNewContents(false, fileModel.contents, newContents, fileModel, replaceString, inFileQuery.searchStrLength); 
 		return newContents.contents.join("\n");
 	}
 	
diff --git a/bundles/org.eclipse.orion.client.ui/web/js-tests/jsTestSuite.js b/bundles/org.eclipse.orion.client.ui/web/js-tests/jsTestSuite.js
index 03f8fa3..167543c 100644
--- a/bundles/org.eclipse.orion.client.ui/web/js-tests/jsTestSuite.js
+++ b/bundles/org.eclipse.orion.client.ui/web/js-tests/jsTestSuite.js
@@ -83,7 +83,10 @@
 
 // list your test cases here....
 OrionTestCase("commonjs-unittesting", "/js-tests/commonjs-unittesting/test.html");
+OrionTestCase("charDiff", "/js-tests/charDiff/test.html");
 OrionTestCase("compare", "/js-tests/compare/test.html");
+OrionTestCase("globalSearch", "/js-tests/globalSearch/test.html");
+OrionTestCase("urlUtils", "/js-tests/urlUtils/test.html");
 OrionTestCase("serviceRegistry", "/js-tests/serviceRegistry/test.html");
 OrionTestCase("preferences", "/js-tests/preferences/test.html");
 OrionTestCase("pluginRegistry", "/js-tests/pluginRegistry/test.html");
diff --git a/bundles/org.eclipse.orion.client.ui/web/js-tests/urlUtils/test.html b/bundles/org.eclipse.orion.client.ui/web/js-tests/urlUtils/test.html
new file mode 100644
index 0000000..f7da669
--- /dev/null
+++ b/bundles/org.eclipse.orion.client.ui/web/js-tests/urlUtils/test.html
@@ -0,0 +1,27 @@
+<!DOCTYPE html>
+<html>
+<head>
+<!-- standard scripts -->
+	<script src="../../requirejs/require.js"></script>
+	<script type="text/javascript">
+	/*global require window*/
+	require({
+		  baseUrl: '../..',
+		  paths: {
+			  text: 'requirejs/text',
+			  i18n: 'requirejs/i18n',
+			  domReady: 'requirejs/domReady'	    
+		  },
+		  isTest: true
+		});
+	
+	window.onload = function() {
+		require(["orion/test","testcase.js"], function(test, testcase) {
+			test.run(testcase);			
+		});
+	};
+	</script>
+</head>
+<body>
+</body>
+</html>
\ No newline at end of file
diff --git a/bundles/org.eclipse.orion.client.ui/web/js-tests/urlUtils/testcase.js b/bundles/org.eclipse.orion.client.ui/web/js-tests/urlUtils/testcase.js
new file mode 100644
index 0000000..3e849ca
--- /dev/null
+++ b/bundles/org.eclipse.orion.client.ui/web/js-tests/urlUtils/testcase.js
@@ -0,0 +1,92 @@
+/*******************************************************************************
+ * @license
+ * Copyright (c) 2011, 2012 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 orion */
+
+define(["orion/assert", "orion/urlUtils"], function(assert, mUrlUtils) {
+      
+	//The test cases are for testing the urlUtils function to detect if a given text has any URL encloded by "[" and "]". 
+	//Currently this detecting function is used as a parser for rendering a string in the shell page, by different segment. The segment is mixed by plain text and url link.
+	// Each segment has the following 2 properties:
+	//      segmentStr: String. The string in the segment.
+	//      isValidURL: Boolean. The flag indicating if the segment is a valid URL.
+	// 
+	var tests = {};
+	
+	/**
+	 * Test an empty string.
+	 */
+	tests.testEmpty = function() {
+		var result = mUrlUtils.detectValidURL("");
+		assert.equal(result, null);
+	};
+
+	/**
+	 * Test a string with no URL and no [] pair.
+	 */
+	tests.testNoURLNoPair = function() {
+		var result = mUrlUtils.detectValidURL("There is no URL");
+		assert.equal(result, null);
+	};
+
+	/**
+	 * Test a string with URL but no [] pair.
+	 */
+	tests.testWithURLNoPair = function() {
+		var result = mUrlUtils.detectValidURL("There is URL  http://abc.com:8081/param=foo");
+		assert.equal(result, null);
+	};
+
+	/**
+	 * Test a string with good URL enclosed by [] pair.
+	 */
+	tests.testWithURLAndPair = function() {
+		var result = mUrlUtils.detectValidURL("There is URL  [http://abc.com:8081/param=foo]  and it is valid");
+		var expectedResult = [{segmentStr: "There is URL  ", isValidURL: false},
+							  {segmentStr: "http://abc.com:8081/param=foo", isValidURL: true},
+							  {segmentStr: "  and it is valid", isValidURL: false}];
+		assert.deepEqual(result, expectedResult);
+	};
+
+	/**
+	 * Test a string with good URL enclosed by [] pair.
+	 */
+	tests.testWithTwoGoodURLAndPair = function() {
+		var result = mUrlUtils.detectValidURL("There is URL  [http://abc.com:8081/param=foo]   [http://abc.com:8082/param=foo] and they are valid");
+		var expectedResult = [{segmentStr: "There is URL  ", isValidURL: false},
+							  {segmentStr: "http://abc.com:8081/param=foo", isValidURL: true},
+							  {segmentStr: "   ", isValidURL: false},
+							  {segmentStr: "http://abc.com:8082/param=foo", isValidURL: true},
+							  {segmentStr: " and they are valid", isValidURL: false}];
+		assert.deepEqual(result, expectedResult);
+	};
+
+	/*
+	 // Test a string with bad URL enclosed by [] pair.
+	 
+	tests.testWithBadURLAndPair = function() {
+		var result = mUrlUtils.detectValidURL("There is URL  [//attacker.com:8081/param=foo]  and it is valid");
+		assert.deepEqual(result, null);
+	};
+
+	
+	// Test a string with bad URL and a good one enclosed by [] pair.
+	
+	tests.testWithGoodAndBadURLAndPair = function() {
+		var result = mUrlUtils.detectValidURL("There is bad URL  [//attacker.com:8081/param=foo]  and a good URL [https://abc.com:8081/param=foo] that is valid");
+		var expectedResult = [{segmentStr: "There is bad URL  [//attacker.com:8081/param=foo]  and a good URL ", isValidURL: false},
+							  {segmentStr: "http://abc.com:8081/param=foo", isValidURL: true},
+							  {segmentStr: " that is valid", isValidURL: false}];
+		assert.deepEqual(result, expectedResult);
+	};
+*/
+
+	return tests;
+});
diff --git a/bundles/org.eclipse.orion.client.ui/web/js-tests/xhr/testcase.js b/bundles/org.eclipse.orion.client.ui/web/js-tests/xhr/testcase.js
index 33eeadd..266316b 100644
--- a/bundles/org.eclipse.orion.client.ui/web/js-tests/xhr/testcase.js
+++ b/bundles/org.eclipse.orion.client.ui/web/js-tests/xhr/testcase.js
@@ -14,6 +14,17 @@
 		function(assert, mTest, Deferred, xhr, mEventTarget) {
 	var EventTarget = mEventTarget.EventTarget;
 	var isIE = navigator.appName.indexOf("Microsoft Internet Explorer") !== -1;
+	var hasReadyStateOpenedBug = (function() {
+		var x = new XMLHttpRequest();
+		x.open('GET', '.', true);
+		try {
+			x.status;
+		} catch (e) {
+			return true;
+		}
+		return false;
+	}());
+
 	/**
 	 * Fake version of XMLHttpRequest for testing without actual network accesses. Eemulates the
 	 * supported XHR features of the browser running the test as closely as possible.
@@ -48,8 +59,8 @@
 				return this._responseText;
 			},
 			set: function(response) {
-				// Bug 381396: if this test is running in IE, emulate IE's non-support for 'response' attribute.
-				if (!isIE) {
+				// Bug 381396: emulate browser's non-support for 'response' attribute (eg. IE 9)
+				if (typeof new XMLHttpRequest().response !== "undefined") {
 					this._response = response;
 				}
 				if (this.responseType === '' || this.responseType === 'text') {
@@ -59,7 +70,9 @@
 		});
 		Object.defineProperty(this, 'status', {
 			get: function() {
-				if (this.readyState === this.UNSENT || this.readyState === this.OPENED || this._errorFlag) {
+				if (hasReadyStateOpenedBug && this.readyState === this.OPENED) {
+					throw new Error('xhr in wrong readyState');
+				} else if (this.readyState === this.UNSENT || this.readyState === this.OPENED || this._errorFlag) {
 					return 0;
 				}
 				return this._status;
diff --git a/bundles/org.eclipse.orion.client.ui/web/navigate/table.js b/bundles/org.eclipse.orion.client.ui/web/navigate/table.js
index 16d9f09..6498576 100644
--- a/bundles/org.eclipse.orion.client.ui/web/navigate/table.js
+++ b/bundles/org.eclipse.orion.client.ui/web/navigate/table.js
@@ -9,13 +9,13 @@
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
-/*global define document window eclipse orion serviceRegistry:true widgets alert*/
+/*global define document window eclipse orion serviceRegistry:true widgets alert URL*/
 /*browser:true*/
 
-define(['i18n!orion/navigate/nls/messages', 'orion/bootstrap', 'orion/webui/littlelib', 'orion/selection', 'orion/status', 'orion/progress', 'orion/dialogs',
+define(['require', 'i18n!orion/navigate/nls/messages', 'orion/bootstrap', 'orion/webui/littlelib', 'orion/selection', 'orion/status', 'orion/progress', 'orion/dialogs',
         'orion/ssh/sshTools', 'orion/commands', 'orion/favorites', 'orion/tasks', 'orion/navoutliner', 'orion/searchClient', 'orion/fileClient', 'orion/operationsClient', 'orion/globalCommands',
-        'orion/fileCommands', 'orion/explorers/explorer-table', 'orion/explorers/navigatorRenderer', 'orion/fileUtils', 'orion/PageUtil', 'orion/URITemplate', 'orion/contentTypes'], 
-		function(messages, mBootstrap, lib, mSelection, mStatus, mProgress, mDialogs, mSsh, mCommands, mFavorites, mTasks, mNavOutliner,
+        'orion/fileCommands', 'orion/explorers/explorer-table', 'orion/explorers/navigatorRenderer', 'orion/fileUtils', 'orion/PageUtil', 'orion/URITemplate', 'orion/contentTypes', 'orion/URL-shim'], 
+		function(require, messages, mBootstrap, lib, mSelection, mStatus, mProgress, mDialogs, mSsh, mCommands, mFavorites, mTasks, mNavOutliner,
 				mSearchClient, mFileClient, mOperationsClient, mGlobalCommands, mFileCommands, mExplorerTable, mNavigatorRenderer, mFileUtils, PageUtil, URITemplate, mContentTypes) {
 
 	mBootstrap.startup().then(function(core) {
@@ -60,7 +60,7 @@
 			var pageParams = PageUtil.matchResourceParameters();
 			// TODO working around https://bugs.eclipse.org/bugs/show_bug.cgi?id=373450
 			var nonHash = window.location.href.split('#')[0]; //$NON-NLS-0$
-			var orionHome = nonHash.substring(0, nonHash.length - window.location.pathname.length);
+			var orionHome = new URL(require.toUrl("."), window.location).href.slice(0,-1);
 
 			explorer.loadResourceList(pageParams.resource, false, function() {
 				mGlobalCommands.setPageTarget({task: "Navigator", target: explorer.treeRoot, 
diff --git a/bundles/org.eclipse.orion.client.ui/web/orion/PageLinks.js b/bundles/org.eclipse.orion.client.ui/web/orion/PageLinks.js
index cf8983d..7e22159 100644
--- a/bundles/org.eclipse.orion.client.ui/web/orion/PageLinks.js
+++ b/bundles/org.eclipse.orion.client.ui/web/orion/PageLinks.js
@@ -7,8 +7,8 @@
  * License v1.0 (http://www.eclipse.org/org/documents/edl-v10.html). 
  * 
  ******************************************************************************/
-/*global define document window*/
-define(["require", "orion/Deferred", "orion/PageUtil", "orion/URITemplate"], function(require, Deferred, PageUtil, URITemplate) {
+/*global define document window URL*/
+define(["require", "orion/Deferred", "orion/PageUtil", "orion/URITemplate", "orion/URL-shim"], function(require, Deferred, PageUtil, URITemplate) {
 
 	/**
 	 * Read info from an <code>orion.page.*</code> service extension.
@@ -31,8 +31,8 @@
 		var navLinks= serviceRegistry.getServiceReferences(serviceName); //$NON-NLS-0$
 		var params = PageUtil.matchResourceParameters(window.location.href);
 		// TODO: should not be necessary, see bug https://bugs.eclipse.org/bugs/show_bug.cgi?id=373450
-		var hostName = window.location.protocol + "//" + window.location.host; //$NON-NLS-0$
-		var locationObject = {OrionHome: hostName, Location: params.resource};
+		var orionHome = new URL(require.toUrl("."), window.location).href.slice(0,-1); //$NON-NLS-0$
+		var locationObject = {OrionHome: orionHome, Location: params.resource};
 		var infos = [];
 		for (var i=0; i<navLinks.length; i++) {
 			var info = {};
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 00af86a..f6b3bb4 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
@@ -172,7 +172,7 @@
 			if (item.Directory) {

 				// defined in ExplorerRenderer.  Sets up the expand/collapse behavior

 				var image = this.getExpandImage(tableRow, span);

-				link = createLink("", item, tableRow.id, this.commandService, this.contentTypeService);

+				link = createLink(this.folderLink || "", item, tableRow.id, this.commandService, this.contentTypeService);

 				span.appendChild(link); //$NON-NLS-0$

 				this.explorer._makeDropTarget(item, tableRow);

 				this.explorer._makeDropTarget(item, link);

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 491ab1c..8238e6f 100644
--- a/bundles/org.eclipse.orion.client.ui/web/orion/extensionCommands.js
+++ b/bundles/org.eclipse.orion.client.ui/web/orion/extensionCommands.js
@@ -9,10 +9,10 @@
  * Contributors:

  *     IBM Corporation - initial API and implementation

  *******************************************************************************/

-/*global window define orion */

+/*global window define orion URL*/

 /*browser:true*/

 

-define(["require", "orion/Deferred", "orion/commands", "orion/editor/regex", "orion/contentTypes", "orion/URITemplate", "orion/i18nUtil"],

+define(["require", "orion/Deferred", "orion/commands", "orion/editor/regex", "orion/contentTypes", "orion/URITemplate", "orion/i18nUtil", "orion/URL-shim"],

 	function(require, Deferred, mCommands, mRegex, mContentTypes, URITemplate, i18nUtil){

 

 	/**

@@ -24,8 +24,7 @@
 	var extensionCommandUtils  = {};

 	

 	// TODO working around https://bugs.eclipse.org/bugs/show_bug.cgi?id=373450

-	var nonHash = window.location.href.split('#')[0]; //$NON-NLS-0$

-	var orionHome = nonHash.substring(0, nonHash.length - window.location.pathname.length);

+	var orionHome = new URL(require.toUrl("."), window.location).href.slice(0,-1);

 	

 	extensionCommandUtils._cloneItemWithoutChildren = function clone(item){

 	    if (item === null || typeof(item) !== 'object') { //$NON-NLS-0$

diff --git a/bundles/org.eclipse.orion.client.ui/web/orion/urlUtils.js b/bundles/org.eclipse.orion.client.ui/web/orion/urlUtils.js
new file mode 100644
index 0000000..c57f617
--- /dev/null
+++ b/bundles/org.eclipse.orion.client.ui/web/orion/urlUtils.js
@@ -0,0 +1,74 @@
+/*******************************************************************************
+ * @license
+ * Copyright (c) 2009, 2012 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 document*/
+
+define(['orion/PageUtil'], function(PageUtil) {
+                
+    /**
+     * Detect if the given text has any URL encloded by "[" and "]". Multiple occurences of the pattern "[url string]" and the non matched part are returned as an array of segments.
+     * @param {String} text The given string to detect.
+	 * @returns {Array} An array containing all the segments of the given string. Each segment has the following 2 properties:
+	 *     segmentStr: String. The string in the segment.
+	 *     isValidURL: Boolean. The flag indicating if the segment is a valid URL.
+	 */
+	function detectValidURL(text) {
+		var regex = /\[([^\]]+)\]/g;
+		var match = regex.exec(text), matches=[], lastNonMatchIndex=0;
+		while (match) {
+			//match[0]: the string enclosed by "[" and "]"
+			//match[1]: the string inside the pair of "[" and "]"
+			if(match.length === 2 && match[1].length >= 0){
+				if(PageUtil.validateURLScheme(match[1])) { //Check if it is a valid URL
+					if(match.index > lastNonMatchIndex) { //We have to push a plain text segment first
+						matches.push({segmentStr: text.substring(lastNonMatchIndex, match.index), isValidURL: false});
+					}
+					matches.push({segmentStr: match[1], isValidURL: true});
+					lastNonMatchIndex = match.index + match[0].length;
+				}
+			}
+			match = regex.exec(text);
+		}
+		if(lastNonMatchIndex === 0) {
+			return null;
+		} else if( lastNonMatchIndex < (text.length - 1) ) {
+			matches.push({segmentStr: text.substring(lastNonMatchIndex), isValidURL: false});
+		}
+		return matches;
+	}
+	
+    /**
+     * Render an array of string segments.
+     * @param {dom node} parentNode The given parent dom node where the segements will be rendered.
+     * @param {Array} segements The given array containing all the segments. Each segment has the following 2 properties:
+	 *     segmentStr: String. The string in the segment.
+	 *     isValidURL: Boolean. The flag indicating if the segment is a valid URL.
+	 */
+	function processURLSegments(parentNode, segments) {
+		segments.forEach(function(segment) {
+			if(segment.isValidURL){
+				var link = document.createElement('a');
+		        link.href = segment.segmentStr;
+		        link.appendChild(document.createTextNode(segment.segmentStr));
+				parentNode.appendChild(link);
+			} else {
+				var plainText = document.createElement("span");
+				plainText.textContent = segment.segmentStr;
+				parentNode.appendChild(plainText);
+			}
+		});
+	}
+	
+	//return module exports
+	return {
+		detectValidURL: detectValidURL,
+		processURLSegments: processURLSegments
+	};
+});
diff --git a/bundles/org.eclipse.orion.client.ui/web/projects/DriveTreeRenderer.js b/bundles/org.eclipse.orion.client.ui/web/projects/DriveTreeRenderer.js
index b5b081a..2daca0a 100644
--- a/bundles/org.eclipse.orion.client.ui/web/projects/DriveTreeRenderer.js
+++ b/bundles/org.eclipse.orion.client.ui/web/projects/DriveTreeRenderer.js
@@ -11,113 +11,8 @@
 /*global define window orion document */

 /*jslint browser:true */

 

-define(['i18n!orion/widgets/nls/messages', 'orion/Deferred', 'orion/explorers/navigatorRenderer', 'orion/extensionCommands'], 

-function(messages, Deferred, mNavigatorRenderer, mExtensionCommands) {

-

-	/* Internal */

-	function isImage(contentType) {

-		switch (contentType && contentType.id) {

-			case "image/jpeg": //$NON-NLS-0$

-			case "image/png": //$NON-NLS-0$

-			case "image/gif": //$NON-NLS-0$

-			case "image/ico": //$NON-NLS-0$

-			case "image/tiff": //$NON-NLS-0$

-			case "image/svg": //$NON-NLS-0$

-				return true;

-		}

-		return false;

-	}

-

-		/* Internal */

-	function addImageToLink(contentType, link, location) {

-	

-		var image;

-		switch (contentType && contentType.id) {

-			case "image/jpeg": //$NON-NLS-0$

-			case "image/png": //$NON-NLS-0$

-			case "image/gif": //$NON-NLS-0$

-			case "image/ico": //$NON-NLS-0$

-			case "image/tiff": //$NON-NLS-0$

-			case "image/svg": //$NON-NLS-0$

-				image = document.createElement("img"); //$NON-NLS-0$

-				image.src = location;

-				image.classList.add("thumbnail"); //$NON-NLS-0$

-				break;

-			default:

-				if (contentType && contentType.image) {

-					image = document.createElement("img"); //$NON-NLS-0$

-					image.src = contentType.image;

-					// to minimize the height/width in case of a large one

-					image.classList.add("thumbnail"); //$NON-NLS-0$

-				} else {	

-					image = document.createElement("span"); //$NON-NLS-0$

-					image.className = "core-sprite-file_model modelDecorationSprite"; //$NON-NLS-0$

-				}

-				break;

-		}

-		if (link.firstChild) {

-			link.insertBefore(image, link.firstChild);

-		} else {

-			link.appendChild(image);

-		}

-	}

-

-

-	/* Exported so that it can be used by other UI that wants to use navigator-style links 

-	 * folderURL should be the page you want to direct folders to (such as navigator).  Using a blank string will just hash the current page.

-	 * item is a json object describing an Orion file or folder

-	 * commandService and contentTypeService  are necessary to compute the proper editor for a file.  The command service must be a synchronous, in-page

-	 * service, not retrieved from the service registry.

-	 * openWithCommands and defaultEditor will be computed if not provided.  

-	 */

-	function createLink(folderPageURL, item, idPrefix, commandService, contentTypeService, /* optional */ openWithCommands, /* optional */defaultEditor) {

-	

-		var link;

-		if (item.Directory) {

-			link = document.createElement("a"); //$NON-NLS-0$

-			link.className = "navlinkonpage"; //$NON-NLS-0$

-			link.id = idPrefix+"NameLink"; //$NON-NLS-0$

-			link.href = folderPageURL + "#" + item.ChildrenLocation; //$NON-NLS-0$

-			link.appendChild(document.createTextNode(item.Name));

-		} else {

-			var i;			

-			// Images: always generate link to file. Non-images: use the "open with" href if one matches,

-			// otherwise use default editor.

-			if (!openWithCommands) {

-				openWithCommands = mExtensionCommands.getOpenWithCommands(commandService);

-			}

-			if (!defaultEditor) {

-				for (i=0; i < openWithCommands.length; i++) {

-					if (openWithCommands[i].isEditor === "default") { //$NON-NLS-0$

-						defaultEditor = openWithCommands[i];

-					}

-				}

-			}

-			link = document.createElement("a"); //$NON-NLS-0$

-			link.className= "navlink targetSelector"; //$NON-NLS-0$

-			link.id = idPrefix+"NameLink"; //$NON-NLS-0$

-			link.target = this.target;

-			link.appendChild(document.createTextNode(item.Name)); //$NON-NLS-0$

-

-			var href = item.Location, foundEditor = false;

-			for (i=0; i < openWithCommands.length; i++) {

-				var openWithCommand = openWithCommands[i];

-				if (openWithCommand.visibleWhen(item)) {

-					href = openWithCommand.hrefCallback({items: item});

-					foundEditor = true;

-					break; // use the first one

-				}

-			}

-			Deferred.when(contentTypeService.getFileContentType(item), function(contentType) {

-				if (!foundEditor && defaultEditor && !isImage(contentType)) {

-					href = defaultEditor.hrefCallback({items: item});

-				}

-				addImageToLink(contentType, link, item.Location);			

-				link.href = href;

-			});

-		}

-		return link;

-	}

+define(['i18n!orion/widgets/nls/messages', 'require', 'orion/explorers/navigatorRenderer'], 

+function(messages, require, mNavigatorRenderer) {

 

 	function DriveTreeRenderer(){

 		mNavigatorRenderer.NavigatorRenderer.apply(this, arguments);

@@ -125,5 +20,7 @@
 	

 	DriveTreeRenderer.prototype = Object.create( mNavigatorRenderer.NavigatorRenderer.prototype ); 

 	

+	DriveTreeRenderer.prototype.folderLink = require.toUrl("navigate/table.html"); //$NON-NLS-0$

+	

 	return DriveTreeRenderer;

 });
\ No newline at end of file
diff --git a/bundles/org.eclipse.orion.client.ui/web/projects/ProjectDataManager.js b/bundles/org.eclipse.orion.client.ui/web/projects/ProjectDataManager.js
index 872b446..ee984bd 100644
--- a/bundles/org.eclipse.orion.client.ui/web/projects/ProjectDataManager.js
+++ b/bundles/org.eclipse.orion.client.ui/web/projects/ProjectDataManager.js
@@ -231,6 +231,12 @@
 			});

 		}

 		

+		function removefromArray( array, from, to) {

+		  var rest = array.slice((to || from) + 1 || array.length);

+		  array.length = from < 0 ? array.length + from : from;

+		  return array.push.apply(array, rest);

+		}

+		

 		function save( projectData, callback ){

 			

 			var loadedWorkspace = this.fileClient.loadWorkspace("");

@@ -247,17 +253,18 @@
 				

 						var projectsIndex = findInWorkspace( folders.Children, PROJECTS_FOLDER );

 						

-						

-						

 						if( projectsIndex ){

 							

 							fileClient.read( folders.Children[projectsIndex].ChildrenLocation ).then( function(files){

+								

 								files = JSON.parse( files );

+								

 								var projectFile = findInWorkspace( files.Children, PROJECTS_METADATA );

 								

 								var fileLocation = files.Children[projectFile].Location;

 							

 								fileClient.read( fileLocation ).then( function( content ){	

+								

 									var projects = JSON.parse( content );

 									

 									projectData.date = new Date();

@@ -273,12 +280,11 @@
 									}

 									

 									if( !existingProject ){

+									

 										projects.push( projectData );

 										

 										/* Create a workspace for this new project */

 			

-										

-										

 										Deferred.when( loadedWorkspace, function(workspace) {

 										

 											fileClient.read( workspace.ChildrenLocation, true ).then( function(folders){

@@ -287,8 +293,7 @@
 												

 												fileClient.createFolder( folders.Children[ projectsIndex ].ChildrenLocation, WORKSPACES_FOLDER ).then( function( result ){

 													callback( result );

-												});

-												

+												});											

 											});

 										});		

 									}

@@ -308,6 +313,68 @@
 		

 		function removeProject( projectName, callback ){

 		

+			var loadedWorkspace = this.fileClient.loadWorkspace("");

+			

+			var fileClient = this.fileClient;

+			

+			this.removeFromArray = function( array, from, to) {

+			  var rest = array.slice((to || from) + 1 || array.length);

+			  array.length = from < 0 ? array.length + from : from;

+			  return array.push.apply(array, rest);

+			};

+			

+			var remover = this;

+			

+			Deferred.when( loadedWorkspace, function(workspace) {

+			

+				fileClient.read( workspace.ChildrenLocation, true ).then( function(folders){

+				

+					var projectsIndex = findInWorkspace( folders.Children, PROJECTS_FOLDER );

+					

+					if( projectsIndex ){

+					

+						var projectDataLocation = folders.Children[projectsIndex].ChildrenLocation;

+				

+						

+						fileClient.read( projectDataLocation ).then( function(files){

+						

+							files = JSON.parse( files );

+						

+							var projectFile = findInWorkspace( files.Children, PROJECTS_METADATA );

+							

+							var fileLocation = files.Children[projectFile].Location;

+						

+							fileClient.read( fileLocation ).then( function( content ){	

+							

+								var projects = JSON.parse( content );

+								

+								var index;

+								

+								for( var p = 0; p < projects.length; p++ ){

+								

+									if( projects[p].name === projectName ){

+										index = p;

+										break;

+									}	

+								}

+								

+								if( index >= 0 ){

+								

+									var newProjects = remover.removeFromArray( projects, index );

+									var fileData = JSON.stringify( projects );

+									fileClient.write( fileLocation, fileData ).then( function( outcome ){

+									

+										callback();

+									

+									} );

+									

+									

+								}

+							});

+						});

+					}

+				});

+			});

 		}

 		

 		ProjectDataManager.prototype.findInWorkspace = findInWorkspace;

@@ -317,6 +384,7 @@
 		ProjectDataManager.prototype.getProject = getProject;

 		ProjectDataManager.prototype.addNewProject = addNewProject;

 		ProjectDataManager.prototype.save = save;

+		ProjectDataManager.prototype.removefromArray = removefromArray;

 		ProjectDataManager.prototype.removeProject = removeProject;

 		ProjectDataManager.prototype.constructor = ProjectDataManager;

 		

diff --git a/bundles/org.eclipse.orion.client.ui/web/projects/ProjectNavigation.js b/bundles/org.eclipse.orion.client.ui/web/projects/ProjectNavigation.js
index 0e6d881..34de302 100644
--- a/bundles/org.eclipse.orion.client.ui/web/projects/ProjectNavigation.js
+++ b/bundles/org.eclipse.orion.client.ui/web/projects/ProjectNavigation.js
@@ -73,7 +73,9 @@
 		ProjectNavigation.prototype.template = template;
 		
 		function addDrivesTree( parentNode, drivenames ){
-		
+			
+			var self = this;
+			
 			this.explorer = new ProjectExplorer({							
 				selection: this.selection, 
 				serviceRegistry: this.serviceRegistry,
@@ -83,7 +85,7 @@
 				
 					var renderer = new DriveTreeRenderer({
 						checkbox: false, 
-						cachePrefix: "Navigator"}, explorer, this.commandService, this.contentTypeService);
+						cachePrefix: "Navigator"}, explorer, self.commandService, self.contentTypeService);
 						
 					return renderer;
 			}}); //$NON-NLS-0$
diff --git a/bundles/org.eclipse.orion.client.ui/web/projects/SFTPConfiguration.js b/bundles/org.eclipse.orion.client.ui/web/projects/SFTPConfiguration.js
index 3c29984..2817ecb 100644
--- a/bundles/org.eclipse.orion.client.ui/web/projects/SFTPConfiguration.js
+++ b/bundles/org.eclipse.orion.client.ui/web/projects/SFTPConfiguration.js
@@ -11,9 +11,9 @@
 /*global orion window console define localStorage*/

 /*jslint browser:true*/

 

-define(['i18n!orion/settings/nls/messages', 'require', 'projects/DriveList', 'orion/commands', 'projects/ProjectDataManager', 'projects/ProjectData', 'projects/ProjectResponseHandler' ], 

+define(['i18n!orion/settings/nls/messages', 'require', 'projects/DriveList', 'orion/commands', 'projects/ProjectDataManager', 'projects/ProjectData', 'projects/ProjectResponseHandler', 'orion/URITemplate' ], 

 	

-	function(messages, require, DriveList, mCommands, ProjectDataManager, ProjectData, ProjectResponseHandler ) {

+	function(messages, require, DriveList, mCommands, ProjectDataManager, ProjectData, ProjectResponseHandler, URITemplate ) {

 

 		function SFTPConfiguration( project, node, commandService, serviceRegistry, fileClient ){

 		

@@ -49,8 +49,18 @@
 				callback: thisSFTPConfiguration.saveConfiguration.bind(thisSFTPConfiguration)

 			});

 			

+			var deleteConfigCommand = new mCommands.Command({

+				name: 'Delete', //messages["Install"],

+				tooltip: 'Delete configuration',

+				id: "orion.deleteConfigCommand", //$NON-NLS-0$

+				callback: thisSFTPConfiguration.deleteConfiguration.bind(thisSFTPConfiguration)

+			});

+			

+			this.commandService.addCommand(deleteConfigCommand);

+			this.commandService.registerCommandContribution("configurationCommands", "orion.deleteConfigCommand", 1, /* not grouped */ null, false, /* no key binding yet */ null, null ); //$NON-NLS-2$ //$NON-NLS-1$ //$NON-NLS-0$

 			this.commandService.addCommand(saveConfigCommand);

 			this.commandService.registerCommandContribution("configurationCommands", "orion.saveProjectConfig", 1, /* not grouped */ null, false, /* no key binding yet */ null, null ); //$NON-NLS-2$ //$NON-NLS-1$ //$NON-NLS-0$

+			

 			this.commandService.renderCommands("configurationCommands", "configurationCommands", this, this, "button"); //$NON-NLS-0$

 		

 			this.projectNode.appendChild( drivelist );

@@ -100,10 +110,43 @@
 			

 			var titleArea = document.getElementById( 'titleArea');

 			titleArea.innerHTML = '<strong>Project: </strong>' + project.name;

+			

+			parent.location.hash = '?project=' + project.name;

 		

 			this.projectDataManager.save( project, this.handleFeedback.bind( this ) );

 		}

 		

+		function deleteConfiguration(){

+		

+			var x;

+			var confirmation = confirm( "Are you sure you want to delete this project?" );

+			

+			if( confirmation === true ){

+				

+				console.log( 'delete' );		

+				this.projectDataManager.removeProject( this.getProjectName(), this.handleDeletion.bind( this ) );

+			

+			}else{

+

+			}

+		}

+		

+		function handleDeletion(){

+		

+			var uriTemplate = "{OrionHome}/projects/project.html#";

+			

+			

+			var template = new URITemplate(uriTemplate);

+			var url = template.expand({

+				project: ''

+			});

+		

+			window.location = url;

+		

+			console.log( 'deleted' );

+		

+		}

+		

 		function handleFeedback( result ){

 			this.handleSuccess();

 		}

@@ -202,11 +245,13 @@
 		SFTPConfiguration.prototype.projectDataManager = projectDataManager;

 		SFTPConfiguration.prototype.handleFeedback = handleFeedback;

 		SFTPConfiguration.prototype.saveConfiguration = saveConfiguration;

+		SFTPConfiguration.prototype.deleteConfiguration = deleteConfiguration;

 		SFTPConfiguration.prototype.createEmptyProject = createEmptyProject;

 		SFTPConfiguration.prototype.showProjectConfiguration = showProjectConfiguration;

 		SFTPConfiguration.prototype.setProjectName = setProjectName;

 		SFTPConfiguration.prototype.setProjectAddress = setProjectAddress;	

 		SFTPConfiguration.prototype.getProjectName = getProjectName;

+		SFTPConfiguration.prototype.handleDeletion = handleDeletion;

 		SFTPConfiguration.prototype.getProjectAddress = getProjectAddress;

 		SFTPConfiguration.prototype.setProjectDescription = setProjectDescription;

 		SFTPConfiguration.prototype.getProjectDescription = getProjectDescription;

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 6a268e3..dec1030 100644
--- a/bundles/org.eclipse.orion.client.ui/web/search/search.js
+++ b/bundles/org.eclipse.orion.client.ui/web/search/search.js
@@ -9,7 +9,7 @@
  * Contributors:
  *     IBM Corporation - initial API and implementation
  *******************************************************************************/
-/*global window define */
+/*global window define document*/
 /*browser:true*/
 
 define(['i18n!orion/search/nls/messages', 'require', 'orion/bootstrap', 'orion/status', 'orion/progress','orion/dialogs',
diff --git a/bundles/org.eclipse.orion.client.ui/web/shell/extensionCommands.js b/bundles/org.eclipse.orion.client.ui/web/shell/extensionCommands.js
index 771bb27..a487cd6 100644
--- a/bundles/org.eclipse.orion.client.ui/web/shell/extensionCommands.js
+++ b/bundles/org.eclipse.orion.client.ui/web/shell/extensionCommands.js
@@ -9,7 +9,7 @@
  * Contributors:

  *     IBM Corporation - initial API and implementation

  *******************************************************************************/

-/*global window define orion */

+/*global window define orion URL*/

 /*browser:true*/

 

 /*

@@ -23,7 +23,7 @@
  * depend on everything else in the file. 

  */

  

-define(["require", "orion/Deferred", "orion/commands", "orion/editor/regex", "orion/contentTypes", "orion/URITemplate", "orion/i18nUtil"],

+define(["require", "orion/Deferred", "orion/commands", "orion/editor/regex", "orion/contentTypes", "orion/URITemplate", "orion/i18nUtil", "orion/URL-shim"],

 	function(require, Deferred, mCommands, mRegex, mContentTypes, URITemplate, i18nUtil){

 

 	/**

@@ -35,8 +35,7 @@
 	var extensionCommandUtils  = {};

 	

 	// TODO working around https://bugs.eclipse.org/bugs/show_bug.cgi?id=373450

-	var nonHash = window.location.href.split('#')[0]; //$NON-NLS-0$

-	var orionHome = nonHash.substring(0, nonHash.length - window.location.pathname.length);

+	var orionHome = new URL(require.toUrl("."), window.location).href.slice(0,-1);

 	

 	extensionCommandUtils._cloneItemWithoutChildren = function clone(item){

 	    if (item === null || typeof(item) !== 'object') { //$NON-NLS-0$

diff --git a/bundles/org.eclipse.orion.client.ui/web/shell/resultWriters.js b/bundles/org.eclipse.orion.client.ui/web/shell/resultWriters.js
index 36db8a8..b938df9 100644
--- a/bundles/org.eclipse.orion.client.ui/web/shell/resultWriters.js
+++ b/bundles/org.eclipse.orion.client.ui/web/shell/resultWriters.js
@@ -13,7 +13,7 @@
 /*global define*/

 /*jslint browser:true*/

 

-define(["orion/Deferred"], function(Deferred) {

+define(['orion/Deferred', 'orion/urlUtils'], function(Deferred, mUrlUtils) {

 

 	var orion = {};

 	orion.shellPage = {};

@@ -124,7 +124,12 @@
 			},

 			appendText: function(text) {

 				var node = document.createElement("span"); //$NON-NLS-0$

-				node.textContent = text;

+				var segments = mUrlUtils.detectValidURL(text);

+				if(segments){

+					mUrlUtils.processURLSegments(node, segments);				

+				} else {

+					node.textContent = text;

+				}

 				this.tempRoot.appendChild(node);

 			},

 			write: function() {

diff --git a/modules/orionode/lib/node_apps.js b/modules/orionode/lib/node_apps.js
index 19b15ea..568ba08 100644
--- a/modules/orionode/lib/node_apps.js
+++ b/modules/orionode/lib/node_apps.js
@@ -63,7 +63,8 @@
 App.prototype.decorators = [
 	function debugDecorator(app, json) {
 		if (app.debug) {
-			json.DebugURL = app.debug;
+			//The debugURL property has to be enclosed by "[" and "]" so that it can be parsed as a link instead of plain text, on client side.
+			json.DebugURL = "[" + app.debug + "]";
 		}
 	}
 ];
@@ -245,7 +246,6 @@
 	 */
 	this.startApp = function(modulePath, args, context, hidden) {
 		var cwdPath = _resolveCWD(fileRoot, workspaceDir, context.cwd);
-		debugger;
 		modulePath = resolveModulePath(workspaceDir, cwdPath, modulePath);
 		var app = _startApp([modulePath].concat(args || []), cwdPath, hidden);
 		app.on('exit', function(code) {
@@ -264,7 +264,7 @@
 		var app = _startApp(["--debug-brk=" + port, resolvedPath].concat(args || []), cwdPath);
 		var parsedRequestUrl = url.parse(requestUrl);
 		app.debug = url.format({
-			protocol: parsedRequestUrl.protocol,
+			protocol: 'http',//parsedRequestUrl.protocol,
 			// TODO this is bizarre. Can we host node-inspector on the same port as Orionode?
 			hostname: url.parse('http://' + headers.host).hostname,
 			port:  INSPECT_PORT,