Bug 423058 - [Projects] launchConfiguration - checking status cannot ask for password
diff --git a/bundles/org.eclipse.orion.client.core/web/orion/projectClient.js b/bundles/org.eclipse.orion.client.core/web/orion/projectClient.js
index b72e430..6351349 100644
--- a/bundles/org.eclipse.orion.client.core/web/orion/projectClient.js
+++ b/bundles/org.eclipse.orion.client.core/web/orion/projectClient.js
@@ -526,7 +526,10 @@
 				for(var i=0; i<launchConfDir.Children.length; i++){
 					if(launchConfDir.Children[i].Name === configurationFile){
 						if(window.confirm("Launch configuration " + configurationFile + " already exists, do you want to replace it?")){
-							this.fileClient.write(launchConfDir.Children[i].Location, JSON.stringify(launchConfigurationEnry)).then(deferred.resolve, deferred.reject);
+							this.fileClient.write(launchConfDir.Children[i].Location, JSON.stringify(launchConfigurationEnry)).then(
+							function(){
+								deferred.resolve(launchConfigurationEnry);
+							}, deferred.reject);
 							return;
 						} else {
 							deferred.reject("Launch configuration already exists");
@@ -535,7 +538,10 @@
 					}
 				}
 				this.fileClient.createFile(launchConfDir.Location, configurationFile).then(function(result){
-					this.fileClient.write(result.Location, JSON.stringify(launchConfigurationEnry)).then(deferred.resolve, deferred.reject);
+					this.fileClient.write(result.Location, JSON.stringify(launchConfigurationEnry)).then(
+					function(){
+						deferred.resolve(launchConfigurationEnry);
+					}, deferred.reject);
 				}.bind(this), deferred.reject);
 			} else {
 				var func = arguments.callee.bind(this);
diff --git a/bundles/org.eclipse.orion.client.ui/web/css/images.css b/bundles/org.eclipse.orion.client.ui/web/css/images.css
index 1b5943c..a5a7105 100644
--- a/bundles/org.eclipse.orion.client.ui/web/css/images.css
+++ b/bundles/org.eclipse.orion.client.ui/web/css/images.css
@@ -102,4 +102,20 @@
 	background-position: left top;
 	width: 16px;
 	height: 16px; 
+}
+
+.core-sprite-applicationrunning {
+	background: url(../images/applicationRunning.png);
+	background-repeat: no-repeat;
+	background-position: left top;
+	width: 16px;
+	height: 16px; 
+}
+
+.core-sprite-applicationstopped {
+	background: url(../images/applicationStopped.png);
+	background-repeat: no-repeat;
+	background-position: left top;
+	width: 16px;
+	height: 16px; 
 }
\ No newline at end of file
diff --git a/bundles/org.eclipse.orion.client.ui/web/images/applicationRunning.png b/bundles/org.eclipse.orion.client.ui/web/images/applicationRunning.png
new file mode 100644
index 0000000..dfa2956
--- /dev/null
+++ b/bundles/org.eclipse.orion.client.ui/web/images/applicationRunning.png
Binary files differ
diff --git a/bundles/org.eclipse.orion.client.ui/web/images/applicationStopped.png b/bundles/org.eclipse.orion.client.ui/web/images/applicationStopped.png
new file mode 100644
index 0000000..4269f40
--- /dev/null
+++ b/bundles/org.eclipse.orion.client.ui/web/images/applicationStopped.png
Binary files differ
diff --git a/bundles/org.eclipse.orion.client.ui/web/orion/folderView.js b/bundles/org.eclipse.orion.client.ui/web/orion/folderView.js
index 3205509..032fec8 100644
--- a/bundles/org.eclipse.orion.client.ui/web/orion/folderView.js
+++ b/bundles/org.eclipse.orion.client.ui/web/orion/folderView.js
@@ -283,6 +283,9 @@
 				this._node.parentNode.removeChild(this._node);
 			}
 			this.projectView.destroy();
+			if(this.projectEditor){
+				this.projectEditor.destroy();
+			}
 			this._node = null;
 		}
 	};
diff --git a/bundles/org.eclipse.orion.client.ui/web/orion/projectCommands.js b/bundles/org.eclipse.orion.client.ui/web/orion/projectCommands.js
index 972a82b..fc9ddaa 100644
--- a/bundles/org.eclipse.orion.client.ui/web/orion/projectCommands.js
+++ b/bundles/org.eclipse.orion.client.ui/web/orion/projectCommands.js
@@ -12,8 +12,8 @@
 /*global window define orion XMLHttpRequest confirm*/
 /*jslint sub:true*/
 define(['i18n!orion/navigate/nls/messages', 'orion/webui/littlelib', 'orion/commands', 'orion/Deferred', 'orion/webui/dialogs/DirectoryPrompterDialog',
- 'orion/commandRegistry', 'orion/i18nUtil', 'orion/webui/dialogs/ImportDialog', 'orion/widgets/projects/ProjectOptionalParametersDialog', 'orion/editorCommands'],
-	function(messages, lib, mCommands, Deferred, DirectoryPrompterDialog, mCommandRegistry, i18nUtil, ImportDialog, ProjectOptionalParametersDialog, mEditorCommands){
+ 'orion/commandRegistry', 'orion/i18nUtil', 'orion/webui/dialogs/ImportDialog', 'orion/widgets/projects/ProjectOptionalParametersDialog', 'orion/editorCommands', 'orion/EventTarget'],
+	function(messages, lib, mCommands, Deferred, DirectoryPrompterDialog, mCommandRegistry, i18nUtil, ImportDialog, ProjectOptionalParametersDialog, mEditorCommands, EventTarget){
 		var projectCommandUtils = {};
 		
 		var selectionListenerAdded = false;
@@ -71,6 +71,15 @@
 		}
 		return params
 	}
+
+	var sharedLaunchConfigurationDispatcher;
+	
+	projectCommandUtils.getLaunchConfigurationDispatcher = function(){
+		if(!sharedLaunchConfigurationDispatcher){
+			sharedLaunchConfigurationDispatcher = new EventTarget();
+		}
+		return sharedLaunchConfigurationDispatcher;
+	};
 		
 	/**
 	 * Updates the explorer toolbar.
@@ -237,6 +246,59 @@
 			}
 		});
 		commandService.addCommand(disconnectDependencyCommand);
+		
+		var checkStateCommand = new mCommands.Command({
+			name: "Check status",
+			tooltip: "Check application status",
+			id: "orion.launchConfiguration.checkStatus", //$NON-NLS-0$
+			callback: function(data) {
+				var item = forceSingleItem(data.items);
+				
+				if(!data.parameters){
+					data.parameters = getCommandParameters(item.parametersRequested, item.optionalParameters);
+					data.oldParams = item.params;
+					commandService.collectParameters(data);
+					return;
+				}
+
+				var func = arguments.callee;
+				var params = handleParamsInCommand(func, data, "Check application state");
+				if(!params){
+					return;
+				}
+				
+				projectClient.getProjectDelpoyService(item.ServiceId).then(function(service){
+					if(service && service.getState){
+						service.getState(params).then(function(result){
+							item.status = result;
+							if(sharedLaunchConfigurationDispatcher){
+								sharedLaunchConfigurationDispatcher.dispatchEvent({type: "changeState", newValue: item });
+							}
+						}, function(error){
+							if(error.Retry){
+								data.parameters = getCommandParameters(error.Retry.parameters, error.Retry.optionalParameters);
+								data.oldParams = params;
+								commandService.collectParameters(data);
+							} else {
+								errorHandler(error);
+								item.status = {error: error};
+								if(sharedLaunchConfigurationDispatcher){
+									sharedLaunchConfigurationDispatcher.dispatchEvent({type: "changeState", newValue: item });
+								}
+							}
+						});
+					}
+				});
+
+
+			},
+			visibleWhen: function(items) {
+				var item = forceSingleItem(items);
+				return item.ServiceId && item.Name && item.parametersRequested;
+			}
+		});
+		commandService.addCommand(checkStateCommand);
+
 	};
 		
 	/**
@@ -676,7 +738,13 @@
 							progress.setProgressResult(status);
 							
 							if(status.ToSave){
-								progress.showWhile(projectClient.saveProjectLaunchConfiguration(project, status.ToSave.ConfigurationName, deployService.id, status.ToSave.Parameters, status.ToSave.Url), "Saving configuration");
+								progress.showWhile(projectClient.saveProjectLaunchConfiguration(project, status.ToSave.ConfigurationName, deployService.id, status.ToSave.Parameters, status.ToSave.Url), "Saving configuration").then(
+									function(configuration){
+										if(sharedLaunchConfigurationDispatcher){
+											sharedLaunchConfigurationDispatcher.dispatchEvent({type: "create", newValue: configuration });
+										}
+									}, errorHandler
+								);
 							}
 
 						};
@@ -699,7 +767,13 @@
 										mEditorCommands.createDelegatedUI(options);
 								}
 								if(result.ToSave){
-									progress.showWhile(projectClient.saveProjectLaunchConfiguration(project, result.ToSave.ConfigurationName, deployService.id, result.ToSave.Parameters, result.ToSave.Url), "Saving configuration");
+									progress.showWhile(projectClient.saveProjectLaunchConfiguration(project, result.ToSave.ConfigurationName, deployService.id, result.ToSave.Parameters, result.ToSave.Url), "Saving configuration").then(
+											function(configuration){
+												if(sharedLaunchConfigurationDispatcher){
+													sharedLaunchConfigurationDispatcher.dispatchEvent({type: "create", newValue: configuration});
+												}
+											}, errorHandler
+									);
 								}
 								
 							}, function(error){
diff --git a/bundles/org.eclipse.orion.client.ui/web/orion/projects/projectEditor.js b/bundles/org.eclipse.orion.client.ui/web/orion/projects/projectEditor.js
index 5478f63..6270aa4 100644
--- a/bundles/org.eclipse.orion.client.ui/web/orion/projects/projectEditor.js
+++ b/bundles/org.eclipse.orion.client.ui/web/orion/projects/projectEditor.js
@@ -240,7 +240,7 @@
 		this._init(options);
 		this.projectEditor = projectEditor;
 		this.explorer = explorer;
-		this.commandRegistry = options.commandRegistry;
+		this.commandService = options.commandRegistry;
 		this.actionScopeId = options.actionScopeId;
 	}
 	
@@ -320,7 +320,7 @@
 		this._init(options);
 		this.projectEditor = projectEditor;
 		this.explorer = explorer;
-		this.commandRegistry = options.commandRegistry;
+		this.commandService = options.commandRegistry;
 		this.actionScopeId = options.actionScopeId;
 		this.projectClient = options.projectClient;
 	}
@@ -359,20 +359,54 @@
 		}
 		if(col_no===2){
 			var td = document.createElement("td");
+			td.classList.add("actionsColumn");
+			if(item.status){
+				if(item.status.error && item.status.error.Retry){
+					item.parametersRequested = item.status.error.Retry.parameters;
+					item.optionalParameters = item.status.error.Retry.optionalParameters;
+					return this.getActionsColumn(item, tableRow, null, "actionsColumn", true);
+				} else if(item.status.error){
+					var span = document.createElement("span");
+					span.appendChild(document.createTextNode("Error"));
+					span.title = item.status.error.Message;
+					td.appendChild(span);
+					return td;
+				} else if(item.status.Running){
+					var span = document.createElement("span");
+					span.className = "imageSprite core-sprite-applicationrunning";
+					span.title = item.status.Message;
+					td.appendChild(span);
+					return td;
+				} else if(item.status.Running===false){
+					var span = document.createElement("span");
+					span.className = "imageSprite core-sprite-applicationstopped";
+					span.title = item.status.Message;
+					td.appendChild(span);
+					return td;
+				} else {
+					var span = document.createElement("span");
+					span.appendChild(document.createTextNode("State unknown"));
+					span.title = item.status.Message;
+					td.appendChild(span);
+					return td;
+				}
+			}
 			if(item.ServiceId){
 				this.projectClient.getProjectDelpoyService(item.ServiceId).then(function(service){
 					if(service && service.getState){
 						service.getState(item.Params).then(function(result){
-							if(result && result.Running === true){
-								td.appendChild(document.createTextNode("Running"));
-							} else {
-								td.appendChild(document.createTextNode("Stopped"));
-							}
-						});
+							item.status = result;
+							tableRow.replaceChild(this.getCellElement(col_no, item, tableRow), td);
+							return;
+						}.bind(this), function(error){
+							item.status = {error: error};
+							tableRow.replaceChild(this.getCellElement(col_no, item, tableRow), td);
+							return;
+						}.bind(this));
 					} else {
 						td.appendChild(document.createTextNode("State unknown"));
 					}
-				});
+				}.bind(this));
 			}
 			return td;
 		}
@@ -392,12 +426,23 @@
 	}
 	ProjectEditor.prototype = {
 		createCommands: function(){
+			this.launchConfigurationDispatcher = mProjectCommands.getLaunchConfigurationDispatcher();
+			var _self = this;
+			this.launchConfigurationListener = function(event){_self.launchConfigurationChanged.call(_self, event);};
+			this._launchConfigurationEventTypes = ["create", "delete", "changeState"];
+			this._launchConfigurationEventTypes.forEach(function(eventType) {
+				_self.launchConfigurationDispatcher.addEventListener(eventType, _self.launchConfigurationListener);
+			});
+			
 //			mProjectCommands.createDependencyCommands(this.serviceRegistry, this.commandRegistry, this, this.fileClient, this.projectClient);
 //			var dependencyTypes = this.projectClient.getProjectHandlerTypes();
 			this.commandRegistry.registerCommandContribution(this.dependencyActions, "orion.project.dependency.connect", 1); //$NON-NLS-1$ //$NON-NLS-0$
 			this.commandRegistry.registerCommandContribution(this.dependencyActions, "orion.project.dependency.disconnect", 2); //$NON-NLS-0$
+			this.commandRegistry.registerCommandContribution(this.launchConfigurationActions, "orion.launchConfiguration.checkStatus", 1);
+			
+			
 		},
-		changedItem: function(){
+		changedItem: function(item){
 			this.fileClient.read(this.parentFolder.Location, true).then(function(metadata){
 				lib.empty(this.node);
 				this.displayContents(this.node, metadata);
@@ -539,25 +584,58 @@
 			dependenciesExplorer.createTree(dependenciesParent, new DependenciesModel(this.projectData, this.projectClient),  {indent: '8px', noSelection: true});
 			
 		},
-		renderLaunchConfigurations: function(parent){
-			this.projectClient.getProjectLaunchConfigurations(this.projectData).then(function(configurations){
-				if(!configurations || configurations.length === 0){
+		renderLaunchConfigurations: function(parent, configurations){
+			this.configurationsParent = parent;
+			if(!configurations){
+				this.projectClient.getProjectLaunchConfigurations(this.projectData).then(function(configurations){
+					this.configurations = configurations;
+					if(!configurations || configurations.length === 0){
+						return;
+					}
+					this.renderLaunchConfigurations(parent, configurations);
+				}.bind(this));
+				return;
+			}
+			lib.empty(this.configurationsParent);
+			var launchConfigurationSection = new mSection.Section(parent, {id: "projectLaunchConfigurationSection", title: "Deployment Information"});
+			var launchConfigurationParent = document.createElement("div");
+			launchConfigurationParent.id = "launchConfigurationsNode";
+			var launchConfigurationRenderer = new LaunchConfigurationRenderer({
+				checkbox: false,
+				commandRegistry: this.commandRegistry,
+				actionScopeId:  this.launchConfigurationActions,
+				projectClient: this.projectClient
+			}, this);
+			var launchConfigurationExplorer = new mExplorer.Explorer(this.serviceRegistry, null, launchConfigurationRenderer, this.commandRegistry);
+			launchConfigurationExplorer.actionScopeId = this.launchConfigurationActions;
+			launchConfigurationSection.embedExplorer(launchConfigurationExplorer, launchConfigurationParent);
+			launchConfigurationExplorer.createTree(launchConfigurationParent, new LaunchConfigurationModel(this.projectData, configurations, this.projectClient),  {indent: '8px'});
+		},
+		launchConfigurationChanged: function(event){
+			if(!this.configurations){
+				return;
+			}
+			if((event.type === "create" || event.type === "changeState") && event.newValue){
+				for(var i=0; i<this.configurations.length; i++){
+					var configuration = this.configurations[i];
+					if(configuration.Name === event.newValue.Name && configuration.ServiceId === event.newValue.ServiceId){
+						this.configurations[i] = event.newValue;
+						this.renderLaunchConfigurations(this.configurationsParent, this.configurations);
+						return;
+					}
+				}
+				if(event.type === "create"){
+					this.configurations.push(event.newValue);
+					this.renderLaunchConfigurations(this.configurationsParent, this.configurations);
 					return;
 				}
-				var launchConfigurationSection = new mSection.Section(parent, {id: "projectLaunchConfigurationSection", title: "Deployment Information"});
-				var launchConfigurationParent = document.createElement("div");
-				launchConfigurationParent.id = "launchConfigurationsNode";
-				var launchConfigurationRenderer = new LaunchConfigurationRenderer({
-					checkbox: false,
-					commandRegistry: this.commandRegistry,
-					actionScopeId:  this.launchConfigurationActions,
-					projectClient: this.projectClient
-				}, this);
-				var launchConfigurationExplorer = new mExplorer.Explorer(this.serviceRegistry, null, launchConfigurationRenderer, this.commandRegistry);
-				launchConfigurationExplorer.actionScopeId = this.launchConfigurationActions;
-				launchConfigurationSection.embedExplorer(launchConfigurationExplorer, launchConfigurationParent);
-				launchConfigurationExplorer.createTree(launchConfigurationParent, new LaunchConfigurationModel(this.projectData, configurations, this.projectClient),  {indent: '8px'});
-			}.bind(this));
+			}
+		},
+		destroy: function(){
+			var _self = this;
+			this._launchConfigurationEventTypes.forEach(function(eventType) {
+					_self.launchConfigurationDispatcher.removeEventListener(eventType, _self.launchConfigurationListener);
+				});
 		}
 	};