Merge "Move to EASE 0.7.0 release"
diff --git a/bundles/org.eclipse.papyrus.ease.lang.python.jupyter/.gitignore b/bundles/org.eclipse.papyrus.ease.lang.python.jupyter/.gitignore
new file mode 100644
index 0000000..f6eeff7
--- /dev/null
+++ b/bundles/org.eclipse.papyrus.ease.lang.python.jupyter/.gitignore
@@ -0,0 +1 @@
+/.pydevproject
diff --git a/bundles/org.eclipse.papyrus.ease.lang.python.jupyter/.project b/bundles/org.eclipse.papyrus.ease.lang.python.jupyter/.project
index 9457dde..f43bb0e 100644
--- a/bundles/org.eclipse.papyrus.ease.lang.python.jupyter/.project
+++ b/bundles/org.eclipse.papyrus.ease.lang.python.jupyter/.project
@@ -24,5 +24,6 @@
 	<natures>
 		<nature>org.eclipse.pde.PluginNature</nature>
 		<nature>org.eclipse.jdt.core.javanature</nature>
+		<nature>org.python.pydev.pythonNature</nature>
 	</natures>
 </projectDescription>
diff --git a/bundles/org.eclipse.papyrus.ease.lang.python.jupyter/jupyter/kernels/ease_py4j_kernel/ease_init.py b/bundles/org.eclipse.papyrus.ease.lang.python.jupyter/jupyter/kernels/ease_py4j_kernel/ease_init.py
index c22a73e..bf7a539 100644
--- a/bundles/org.eclipse.papyrus.ease.lang.python.jupyter/jupyter/kernels/ease_py4j_kernel/ease_init.py
+++ b/bundles/org.eclipse.papyrus.ease.lang.python.jupyter/jupyter/kernels/ease_py4j_kernel/ease_init.py
@@ -1,3 +1,17 @@
+#################################################################################
+# Copyright (c) 2019 CEA LIST and others.
+# 
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License 2.0
+# which accompanies this distribution, and is available at
+# https://www.eclipse.org/legal/epl-2.0/
+#
+# SPDX-License-Identifier: EPL-2.0
+#
+#  Contributors:
+#  CEA LIST - Initial API and implementation
+#   
+#################################################################################
 import sys
 import os
 
@@ -7,6 +21,7 @@
 
 
 import ease_py4j_main 
+from IPython.display import Javascript, display_javascript 
 
 #in IPyhton __builtins__ is a dict, in CPython there is a __builtins__.__dict__ attribute
 class IPythonScriptEngineExecute(ease_py4j_main._pyease_ScriptEngineExecute):
@@ -37,4 +52,11 @@
     engine.set_gateway(gateway)
     # tell Java that we are up and running and where to direct
     # calls to python to.
-    gateway.entry_point.pythonStartupComplete(python_port, engine)
\ No newline at end of file
+    gateway.entry_point.pythonStartupComplete(python_port, engine)
+   
+
+def get_cells_to_run():
+    return gateway.entry_point.getCellsToRun()
+    
+    
+    
\ No newline at end of file
diff --git a/bundles/org.eclipse.papyrus.ease.lang.python.jupyter/jupyter/kernels/ease_py4j_kernel/ease_py4j_kernel.py b/bundles/org.eclipse.papyrus.ease.lang.python.jupyter/jupyter/kernels/ease_py4j_kernel/ease_py4j_kernel.py
index af6ea43..e505deb 100644
--- a/bundles/org.eclipse.papyrus.ease.lang.python.jupyter/jupyter/kernels/ease_py4j_kernel/ease_py4j_kernel.py
+++ b/bundles/org.eclipse.papyrus.ease.lang.python.jupyter/jupyter/kernels/ease_py4j_kernel/ease_py4j_kernel.py
@@ -1,45 +1,23 @@
-
+#################################################################################
+# Copyright (c) 2019 CEA LIST and others.
+# 
+# All rights reserved. This program and the accompanying materials
+# are made available under the terms of the Eclipse Public License 2.0
+# which accompanies this distribution, and is available at
+# https://www.eclipse.org/legal/epl-2.0/
+#
+# SPDX-License-Identifier: EPL-2.0
+#
+#  Contributors:
+#  CEA LIST - Initial API and implementation
+#   
+#################################################################################
 
 code='''
 import ease_init
 ease_init.connect_to_ease()
 '''
 
-#TODO : manage to use this kind of code to terminate the server when the tab is closed in the browser
-code2 ='''from IPython.display import Javascript
-Javascript(\'\'\'
-window.addEventListener('beforeunload', function() {
-    
-    require(['base/js/utils'], function(utils){
-            utils.ajax(utils.url_path_join(
-                utils.get_body_data("baseUrl"),
-                "api",
-                "shutdown"), 
-                {
-                type: "POST",
-                }
-            );
-        }
-    
-    );
-    
-});
-
-window.onbeforeunload = function () {
-   
-    require(['base/js/utils'], function(utils){
-            utils.ajax(utils.url_path_join(
-                utils.get_body_data("baseUrl"),
-                "api",
-                "shutdown"
-            ), {
-                type: "POST",
-            });
-    
-    });
-}
-\'\'\')'''
-
 if __name__ == '__main__':  
     
     from ipykernel.kernelapp import IPKernelApp
diff --git a/bundles/org.eclipse.papyrus.ease.lang.python.jupyter/jupyter/kernels/ease_py4j_kernel/kernel.js b/bundles/org.eclipse.papyrus.ease.lang.python.jupyter/jupyter/kernels/ease_py4j_kernel/kernel.js
new file mode 100644
index 0000000..3673c25
--- /dev/null
+++ b/bundles/org.eclipse.papyrus.ease.lang.python.jupyter/jupyter/kernels/ease_py4j_kernel/kernel.js
@@ -0,0 +1,70 @@
+/*****************************************************************************
+ * Copyright (c) 2019 CEA LIST and others.
+ * 
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License 2.0
+ * which accompanies this distribution, and is available at
+ * https://www.eclipse.org/legal/epl-2.0/
+ *
+ * SPDX-License-Identifier: EPL-2.0
+ *
+ * Contributors:
+ *   CEA LIST - Initial API and implementation
+ *   
+ *****************************************************************************/
+
+function shutdownEASE() {
+	var code = 'env= loadModule("Environment")\n'
+			+ 'env.getScriptEngine().terminate()\n'
+	var kernel = IPython.notebook.kernel;
+	kernel.execute(code);
+}
+
+window.addEventListener('unload', shutdownEASE);
+
+window.onbeforeunload = shutdownEASE;
+
+code_show=true;
+
+var handler = function() {
+	if (code_show) {
+		$('div.input').hide();
+	} else {
+		$('div.input').show();
+	}
+	code_show = !code_show
+
+};
+
+var action = {
+	icon : 'fa-code', // a font-awesome class used on buttons, etc
+	help : 'Toggle code',
+	help_index : 'zz',
+	handler : handler
+};
+var prefix = 'my_extension';
+var action_name = 'hide-code';
+
+var full_action_name = Jupyter.actions.register(action, action_name, prefix); 
+Jupyter.toolbar.add_buttons_group([ full_action_name ]);
+
+
+
+Jupyter.notebook.events.on('kernel_ready.Kernel', () => {
+	IPython.notebook.kernel.execute(
+		    "ease_init.get_cells_to_run()", 
+		{
+		    	iopub: {
+		    		output: function(response) {
+		    			var cells =   eval(response.content.data["text/plain"])  
+		    			Jupyter.notebook.execute_cells(cells)
+		    		}
+		    	}
+		},
+		{
+		silent: false, 
+		store_history: false, 
+		stop_on_error: true
+		}
+	)
+});
diff --git a/bundles/org.eclipse.papyrus.ease.lang.python.jupyter/src/org/eclipse/papyrus/ease/lang/python/jupyter/internal/JupyterEngine.java b/bundles/org.eclipse.papyrus.ease.lang.python.jupyter/src/org/eclipse/papyrus/ease/lang/python/jupyter/internal/JupyterEngine.java
index 25d6dfc..bbb9fc1 100644
--- a/bundles/org.eclipse.papyrus.ease.lang.python.jupyter/src/org/eclipse/papyrus/ease/lang/python/jupyter/internal/JupyterEngine.java
+++ b/bundles/org.eclipse.papyrus.ease.lang.python.jupyter/src/org/eclipse/papyrus/ease/lang/python/jupyter/internal/JupyterEngine.java
@@ -23,6 +23,7 @@
 import java.util.Map;
 
 import org.eclipse.core.resources.IFile;
+import org.eclipse.core.runtime.Platform;
 import org.eclipse.ease.AbstractReplScriptEngine;
 import org.eclipse.ease.Logger;
 import org.eclipse.ease.Script;
@@ -128,7 +129,6 @@
 			
 			fPythonSideEngine = jupyterProxy.getPythonSideEngine();
 			
-			
 		
 		} catch (final Exception e) {
 			teardownEngine();
@@ -137,6 +137,8 @@
 		}
 	}
 
+	
+	protected Script notebookScript;
 
 	
 	private void initializeJupyterProxy() {
@@ -149,14 +151,30 @@
 				if (NOTE_BOOK_EXTENSION.equals(scriptFile.getFileExtension())){
 					jupyterProxy.setNotebook(scriptFile);
 					scriptToRemove.add(script);
+					notebookScript = script;
 				}
 			}
 			
 		}
 		getScheduledScripts().removeAll(scriptToRemove);
 		
+		List<Integer> cellsToRun = new ArrayList<>();
+		Object argObj = getVariable("argv");
+		if( argObj instanceof String[]) {
+			for (String arg : (String[])argObj) {
+				try {
+					Integer cellNumber = Integer.parseInt(arg);
+					cellsToRun.add(cellNumber);
+				}catch (NumberFormatException e) {
+					continue;
+				}
+				
+			}
+		}
+		jupyterProxy.addAutoCells(cellsToRun);
 	}
 
+	
 	@Override
 	protected Object execute(final Script script, final Object reference, final String fileName, final boolean uiThread) throws Throwable {
 		if (uiThread) {
@@ -197,6 +215,9 @@
 
 	@Override
 	public void terminateCurrent() {
+		if (notebookScript != null) {
+			notebookScript.setResult(0);
+		}
 		setTerminateOnIdle(true);
 	
 	}
@@ -216,13 +237,15 @@
 		// fPythonSideEngine.teardownEngine();
 		// }
 		
+		
+		
 		if (jupyterProxy != null) {
 			jupyterProxy.shutDown();
 		}
 		
 		Activator.getDefault().unRegisterProxy(jupyterProxy);
 		
-	
+
 		try {
 			// Wait until the gobblers have shovelled all their
 			// inputs before allowing the engine to considered terminated
diff --git a/bundles/org.eclipse.papyrus.ease.lang.python.jupyter/src/org/eclipse/papyrus/ease/lang/python/jupyter/internal/JupyterProxy.java b/bundles/org.eclipse.papyrus.ease.lang.python.jupyter/src/org/eclipse/papyrus/ease/lang/python/jupyter/internal/JupyterProxy.java
index 2819e78..e72b3eb 100644
--- a/bundles/org.eclipse.papyrus.ease.lang.python.jupyter/src/org/eclipse/papyrus/ease/lang/python/jupyter/internal/JupyterProxy.java
+++ b/bundles/org.eclipse.papyrus.ease.lang.python.jupyter/src/org/eclipse/papyrus/ease/lang/python/jupyter/internal/JupyterProxy.java
@@ -14,15 +14,19 @@
  *****************************************************************************/
 package org.eclipse.papyrus.ease.lang.python.jupyter.internal;
 
+import java.awt.Desktop;
 import java.io.File;
 import java.io.IOException;
 import java.net.InetSocketAddress;
 import java.net.MalformedURLException;
 import java.net.ServerSocket;
 import java.net.SocketAddress;
+import java.net.URI;
 import java.net.URISyntaxException;
 import java.net.URL;
 import java.nio.channels.SocketChannel;
+import java.util.ArrayList;
+import java.util.List;
 import java.util.UUID;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
@@ -66,6 +70,7 @@
 
 	private static final String JUPYTER_PATH = "JUPYTER_PATH";
 
+
 	private static final String PYTHON_PATH = "PYTHONPATH";
 
 	private static final String EASE_PYTHON_COMMON_BUNDLE_ID = "org.eclipse.ease.lang.python";
@@ -90,8 +95,11 @@
 	private IPythonSideEngine pythonSideEngine;
 	private Process jupyterProcess;
 	private String notebookName;
-	
+
 	private String pythonInterpreter = getPythonInterpreterExec();
+	
+	
+	private List<Integer> cellToRun= new ArrayList<>();
 
 	public JupyterProxy() {
 
@@ -154,28 +162,25 @@
 		return jupyterProcess;
 	}
 
-	public void startJupyterProcess() throws InterruptedException, ScriptEngineException, IOException, URISyntaxException {
+	public void startJupyterProcess()
+			throws InterruptedException, ScriptEngineException, IOException, URISyntaxException {
 
 		notebookPort = getFreePort(8888);
 
-		
 		gatewayServer = new ClientServerBuilder(this).javaPort(0).pythonPort(0).build();
 		gatewayServer.startServer(true);
 		final int javaListeningPort = ((JavaServer) gatewayServer.getJavaServer()).getListeningPort();
-		
-		final ProcessBuilder pb = new ProcessBuilder();
 
-		
-		
+		final ProcessBuilder pb = new ProcessBuilder();
 
 		// we use Py4J python interpreter, should include Jupyter
 		pb.command().add(pythonInterpreter);
 		pb.command().add("-m");
 		pb.command().add("notebook");
 		pb.command().add("--notebook-dir=" + notebookDirectory);
-		String fullPath = notebookDirectory+File.separator+"static";
+		String fullPath = notebookDirectory + File.separator + "static";
 		fullPath = fullPath.replace("\\", "\\\\");
-		pb.command().add("--NotebookApp.extra_static_paths=['"+fullPath+"']");
+		pb.command().add("--NotebookApp.extra_static_paths=['" + fullPath + "']");
 		if (notebookPort > -1) {
 			pb.command().add("--port=" + notebookPort);
 		}
@@ -192,12 +197,14 @@
 		pb.environment().put(JUPYTER_PATH,
 				appendToCurrentEnvPath(JUPYTER_PATH, getJupyterPathDirectory().getAbsolutePath()));
 
+		
+	
+
 		// we also add the kernel directory in PYTHON_PATH in order to allow the
 		// first-level python to load our custom python kernel
 		pb.environment().put(PYTHON_PATH,
 				appendToCurrentEnvPath(PYTHON_PATH, getJupyterKernelDirectory().getAbsolutePath()));
-		
-		
+
 		// we now add several environment variable that will be read during our easepy4j
 		// kernel startup to establish connection
 		// with Py4J java side initiated by EASE
@@ -209,18 +216,14 @@
 		pb.environment().put(EASE_PYTHON_COMMON_SRC, getEASEPythonCommonSrc().getAbsolutePath());
 		pb.environment().put(EASE_PY4J_SRC, getPy4jEaseMainDir().getAbsolutePath());
 
-		
 		jupyterProcess = pb.start();
 
-		
-
-		
 		pythonStartupComplete = new CountDownLatch(1);
 
-		
-
 	}
 
+	
+
 	private String getPythonInterpreterExec() {
 		String interpreter = Platform.getPreferencesService().getString("org.eclipse.ease.lang.python.py4j",
 				"org.eclipse.ease.lang.python.py4j.INTERPRETER", "python", null);
@@ -233,20 +236,19 @@
 		return interpreter;
 	}
 
-	private void waitForJupyterStartup() throws InterruptedException, ScriptEngineException, IOException{
-		boolean scanning=true;
+	private void waitForJupyterStartup() throws InterruptedException, ScriptEngineException, IOException {
+		boolean scanning = true;
 		SocketAddress address = new InetSocketAddress("localhost", notebookPort);
-		
+
 		int attempts = 0;
-		while(scanning && attempts < 200){
-		    try{
-		    	attempts++;
-		    	SocketChannel.open(address);
-		        scanning=false;
-		    }
-		    catch(IOException e){
-		        Thread.sleep(100);//0.1 second
-		    } 
+		while (scanning && attempts < 200) {
+			try {
+				attempts++;
+				SocketChannel.open(address);
+				scanning = false;
+			} catch (IOException e) {
+				Thread.sleep(100);// 0.1 second
+			}
 		}
 		if (scanning) {
 			throw new ScriptEngineException("Jupyter notebook did not start within 20 seconds");
@@ -254,13 +256,14 @@
 	}
 
 	public void waitForKernelStartup() throws InterruptedException, ScriptEngineException, IOException {
-		
+
 		waitForJupyterStartup();
-		
-		//web browser will start the kernel if a notebook has been selected to be run as EASE script
-		//else user will have to manually start the kernel in the browser
+
+		// web browser will start the kernel if a notebook has been selected to be run
+		// as EASE script
+		// else user will have to manually start the kernel in the browser
 		openWebBrowser();
-		
+
 		// We wait here for the main notebook python process initialization
 		if (!pythonStartupComplete.await(PYTHON_STARTUP_TIMEOUT_SECONDS, TimeUnit.SECONDS)) {
 			throw new ScriptEngineException(
@@ -278,34 +281,60 @@
 		pythonStartupComplete.countDown();
 
 	}
+	
+	public List<Integer> getCellsToRun() {
+		return cellToRun;
+	}
+	
+	public void addAutoCells(List<Integer> cellsToRun) {
+		this.cellToRun.addAll(cellsToRun);
+		
+	}
 
 	private void openWebBrowser() {
+		if (PlatformUI.isWorkbenchRunning()) {
+			Display.getDefault().asyncExec(new Runnable() {
 
-		Display.getDefault().asyncExec(new Runnable() {
+				@Override
+				public void run() {
 
-			@Override
-			public void run() {
+					try {
+						// even if we wait for python startup, still have to wait for server startup to
+						// avoid to have to refresh the page
+						TimeUnit.SECONDS.sleep(3);
+						IWebBrowser browser = PlatformUI.getWorkbench().getBrowserSupport().createBrowser(null);
+						browser.openURL(getNoteBookURL());
+
+					} catch (MalformedURLException e) {
+						// TODO Auto-generated catch block
+						e.printStackTrace();
+
+					} catch (InterruptedException e) {
+						// TODO Auto-generated catch block
+						e.printStackTrace();
+					} catch (PartInitException e) {
+						// TODO Auto-generated catch block
+						e.printStackTrace();
+					}
+				}
+
+			});
+
+		} else {
+			if (Desktop.isDesktopSupported() && Desktop.getDesktop().isSupported(Desktop.Action.BROWSE)) {
 
 				try {
-					// even if we wait for python startup, still have to wait for server startup to
-					// avoid to have to refresh the page
-					TimeUnit.SECONDS.sleep(3);
-					IWebBrowser browser = PlatformUI.getWorkbench().getBrowserSupport().createBrowser(null);
-					browser.openURL(getNoteBookURL());
-
-				} catch (PartInitException e) {
+					URI uri = getNoteBookURL().toURI();
+					Desktop.getDesktop().browse(uri);
+				} catch (IOException e) {
 					// TODO Auto-generated catch block
 					e.printStackTrace();
-				} catch (MalformedURLException e) {
-					// TODO Auto-generated catch block
-					e.printStackTrace();
-				} catch (InterruptedException e) {
+				} catch (URISyntaxException e) {
 					// TODO Auto-generated catch block
 					e.printStackTrace();
 				}
-
 			}
-		});
+		}
 
 	}
 
@@ -335,7 +364,7 @@
 	private File getPy4jPythonSrc() throws IOException {
 		final File py4jPythonBundleFile = FileLocator.getBundleFile(Platform.getBundle(PY4J_PYTHON_BUNDLE_ID));
 		final File py4jPythonSrc = new File(py4jPythonBundleFile, "/src");
-		//final File py4j = new File(py4jPythonSrc, "py4j");
+		// final File py4j = new File(py4jPythonSrc, "py4j");
 		if (!py4jPythonSrc.exists() || !py4jPythonSrc.isDirectory()) {
 			throw new IOException("Failed to find py4j python directory, expected it here: " + py4jPythonSrc);
 		}
@@ -351,10 +380,11 @@
 		}
 		return py4jEaseMain;
 	}
+
 	private File getJupyterPathDirectory() throws IOException, URISyntaxException {
-		final URL url = new URL("platform:/plugin/"+Activator.PLUGIN_ID+"/jupyter");
-		final URL fileURL = FileLocator.toFileURL(url);		
-		final File rootDir =  new File(URIUtil.toURI(fileURL).normalize());
+		final URL url = new URL("platform:/plugin/" + Activator.PLUGIN_ID + "/jupyter");
+		final URL fileURL = FileLocator.toFileURL(url);
+		final File rootDir = new File(URIUtil.toURI(fileURL).normalize());
 		if (!rootDir.exists() || !rootDir.isDirectory()) {
 			throw new IOException(
 					"Failed to find ease-py4j Jupyter kernel root directory, expected it here: " + rootDir);
@@ -390,8 +420,7 @@
 	 * port is being used between calling this and actually starting a server.
 	 * Handle blocked servers appropriately.
 	 * 
-	 * @param startPort
-	 *            Lowest desired port number.
+	 * @param startPort Lowest desired port number.
 	 * @return Free port (hopefully) close to startPort.
 	 */
 	public static int getFreePort(int startPort) {
@@ -429,19 +458,13 @@
 
 	public void shutDown() {
 
-		
-		ProcessBuilder stopProcess = new ProcessBuilder().command(
-				pythonInterpreter, 
-				"-m",
-				"notebook",
-				"stop",
-				Integer.toString(notebookPort)
-				);
-		
+		ProcessBuilder stopProcess = new ProcessBuilder().command(pythonInterpreter, "-m", "notebook", "stop",
+				Integer.toString(notebookPort));
+
 		try {
-			Process process =stopProcess.start();
+			Process process = stopProcess.start();
 			process.waitFor(PYTHON_SHUTDOWN_TIMEOUT_SECONDS, TimeUnit.SECONDS);
-			
+
 		} catch (IOException e1) {
 			// TODO Auto-generated catch block
 			e1.printStackTrace();
@@ -449,13 +472,13 @@
 			// TODO Auto-generated catch block
 			e.printStackTrace();
 		}
-		
-		
 
 		if (gatewayServer != null) {
 			gatewayServer.shutdown();
 		}
-		
+
 	}
 
+
+
 }
diff --git a/bundles/org.eclipse.papyrus.ease/META-INF/MANIFEST.MF b/bundles/org.eclipse.papyrus.ease/META-INF/MANIFEST.MF
index 0635358..3d3a6be 100644
--- a/bundles/org.eclipse.papyrus.ease/META-INF/MANIFEST.MF
+++ b/bundles/org.eclipse.papyrus.ease/META-INF/MANIFEST.MF
@@ -22,7 +22,8 @@
  org.eclipse.gmf.runtime.diagram.ui,
  org.eclipse.papyrus.infra.gmfdiag.common,
  org.eclipse.papyrus.infra.viewpoints.policy,
- org.eclipse.papyrus.infra.emf
+ org.eclipse.papyrus.infra.emf,
+ org.eclipse.papyrus.uml.tools
 Export-Package: org.eclipse.papyrus.ease.module,
  org.eclipse.papyrus.ease.popup
 Bundle-Vendor: Eclipse Modeling Project
diff --git a/bundles/org.eclipse.papyrus.ease/src/org/eclipse/papyrus/ease/module/PapyrusUtilsModule.java b/bundles/org.eclipse.papyrus.ease/src/org/eclipse/papyrus/ease/module/PapyrusUtilsModule.java
index 8dab19d..50bf1e3 100644
--- a/bundles/org.eclipse.papyrus.ease/src/org/eclipse/papyrus/ease/module/PapyrusUtilsModule.java
+++ b/bundles/org.eclipse.papyrus.ease/src/org/eclipse/papyrus/ease/module/PapyrusUtilsModule.java
@@ -15,7 +15,6 @@
 package org.eclipse.papyrus.ease.module;
 
 import java.io.IOException;
-import java.lang.ref.WeakReference;
 import java.net.URISyntaxException;
 import java.net.URL;
 import java.util.Collection;
@@ -71,6 +70,7 @@
 import org.eclipse.papyrus.editor.PapyrusMultiDiagramEditor;
 import org.eclipse.papyrus.infra.architecture.ArchitectureDescriptionUtils;
 import org.eclipse.papyrus.infra.core.resource.ModelSet;
+import org.eclipse.papyrus.infra.core.resource.NotFoundException;
 import org.eclipse.papyrus.infra.core.services.ServiceException;
 import org.eclipse.papyrus.infra.core.services.ServiceMultiException;
 import org.eclipse.papyrus.infra.core.services.ServiceNotFoundException;
@@ -81,6 +81,8 @@
 import org.eclipse.papyrus.infra.types.core.utils.ElementTypeRegistryUtils;
 import org.eclipse.papyrus.infra.viewpoints.policy.PolicyChecker;
 import org.eclipse.papyrus.infra.viewpoints.policy.ViewPrototype;
+import org.eclipse.papyrus.uml.tools.model.UmlModel;
+import org.eclipse.papyrus.uml.tools.model.UmlUtils;
 import org.eclipse.swt.widgets.Display;
 import org.eclipse.ui.IEditorPart;
 import org.eclipse.ui.IWorkbench;
@@ -94,9 +96,8 @@
 public class PapyrusUtilsModule extends AbstractScriptModule {
 	
 	
-	private ModelSet currentModelSet = null; 
 
-	private IFile getDIFile(IFile inputFile) {
+	private static IFile getDIFile(IFile inputFile) {
 		IFile result = null;
 		if ("uml".equals(inputFile.getFileExtension())) {
 			result = (IFile) inputFile.getParent().findMember(inputFile.getName().replaceAll(".uml$", ".di"));
@@ -118,10 +119,10 @@
 	 *
 	 */
 	@WrapToScript
-	public org.eclipse.uml2.uml.Package getPapyrusModel(String modelPath)
+	public static  org.eclipse.uml2.uml.Package getPapyrusModel(String modelPath)
 			throws RuntimeException, CoreException, URISyntaxException, IOException, ServiceException {
 
-		Object resolved = ResourceTools.resolve(modelPath, getScriptEngine().getExecutedFile());
+		Object resolved = ResourceTools.resolve(modelPath);
 
 		
 		IFile diFile = null;
@@ -170,6 +171,7 @@
 
 			}
 
+			ModelSet currentModelSet = null;
 			if (editorPart != null) {
 				ServicesRegistry servicesRegistry = editorPart.getAdapter(ServicesRegistry.class);
 				if (servicesRegistry != null) {
@@ -207,7 +209,7 @@
 	 * @return the first object found with the given qualified name.
 	 */
 	@WrapToScript
-	public NamedElement getPapyrusNamedElement(Object context, String qualifiedName)
+	public static NamedElement getPapyrusNamedElement(Object context, String qualifiedName)
 			throws RuntimeException, CoreException, URISyntaxException, IOException, ServiceException {
 		ResourceSet resSet = null;
 		if (context instanceof String) {
@@ -232,24 +234,9 @@
 
 	}
 
-	static WeakReference<PapyrusMultiDiagramEditor> papyrus = null;
 
-	@WrapToScript
-	public static void setPapyrusSession(PapyrusMultiDiagramEditor editor) {
-		papyrus = new WeakReference<PapyrusMultiDiagramEditor>(editor);
-	}
-
-	public static PapyrusMultiDiagramEditor getPapyrusSession() {
-
-		if (papyrus != null && papyrus.get() != null) {
-			return papyrus.get();
-		} else {
-			PapyrusMultiDiagramEditor result = getActivePapyrusEditor();
-			setPapyrusSession(result);
-			return result;
-		}
-
-	}
+	
+	
 	
 	
 	@WrapToScript
@@ -280,7 +267,7 @@
 	@WrapToScript
 	public static EObject createSemanticElement(EObject owner, String elementTypeIdToCreate) {
 
-		PapyrusMultiDiagramEditor papyrus = getPapyrusSession();
+		PapyrusMultiDiagramEditor papyrus = getActivePapyrusEditor();
 		IElementType elementType = getElementType(papyrus, elementTypeIdToCreate);
 		if (elementType != null) {
 			return RequestUtils.createElementWithRequest(owner, elementType);
@@ -293,7 +280,7 @@
 			Node sourceNode, Double relativeXSource, Double relativeYSource, Node targetNode, Double relativeXTarget,
 			Double relativeYTarget) {
 
-		PapyrusMultiDiagramEditor papyrus = getPapyrusSession();
+		PapyrusMultiDiagramEditor papyrus = getActivePapyrusEditor();
 		IElementType elementType = getElementType(papyrus, graphicalElementTypeIdToCreate);
 
 		GraphicalEditPart diagramEditPart = (GraphicalEditPart) getActivePapyrusViewer(papyrus).getContents();
@@ -356,7 +343,7 @@
 			Integer y, @ScriptParameter(defaultValue = ScriptParameter.NULL) Integer width,
 			@ScriptParameter(defaultValue = ScriptParameter.NULL) Integer height) {
 
-		PapyrusMultiDiagramEditor papyrus = getPapyrusSession();
+		PapyrusMultiDiagramEditor papyrus = getActivePapyrusEditor();
 		IElementType elementType = getElementType(papyrus, graphicalElementTypeIdToCreate);
 		EditPart targetEditPart = calculateTargetEditPart(papyrus, (double) x, (double) y);
 
@@ -397,7 +384,7 @@
 			@Override
 			public void run() {
 
-				getActivePapyrusViewer(getPapyrusSession()).flush();
+				getActivePapyrusViewer(getActivePapyrusEditor()).flush();
 
 			}
 		};
@@ -434,7 +421,7 @@
 			@ScriptParameter(defaultValue = ScriptParameter.NULL) Integer width,
 			@ScriptParameter(defaultValue = ScriptParameter.NULL) Integer height) {
 
-		PapyrusMultiDiagramEditor papyrus = getPapyrusSession();
+		PapyrusMultiDiagramEditor papyrus = getActivePapyrusEditor();
 		IElementType elementType = getElementType(papyrus, graphicalElementTypeIdToCreate);
 		EditPart targetEditPart = calculateTargetEditPart(papyrus, (double) x, (double) y);
 
@@ -471,7 +458,7 @@
 			Double relativeX, Double relativeY, @ScriptParameter(defaultValue = ScriptParameter.NULL) Integer width,
 			@ScriptParameter(defaultValue = ScriptParameter.NULL) Integer height) {
 
-		PapyrusMultiDiagramEditor papyrus = getPapyrusSession();
+		PapyrusMultiDiagramEditor papyrus = getActivePapyrusEditor();
 		IElementType elementType = getElementType(papyrus, graphicalElementTypeIdToCreate);
 
 		Diagram diagram = DiagramUtils.getContainingDiagram(parentNode);
@@ -510,7 +497,7 @@
 			@ScriptParameter(defaultValue = ScriptParameter.NULL) Integer width,
 			@ScriptParameter(defaultValue = ScriptParameter.NULL) Integer height) {
 
-		PapyrusMultiDiagramEditor papyrus = getPapyrusSession();
+		PapyrusMultiDiagramEditor papyrus = getActivePapyrusEditor();
 		IElementType elementType = getElementType(papyrus, graphicalElementTypeIdToCreate);
 
 		if (elementType instanceof IHintedType && parentNode instanceof Node) {
@@ -522,7 +509,7 @@
 						.get(parentNode);
 			} else {
 				PrecisionPoint absoluteLocation = getAbsolutePoint(parentNode, relativeX, relativeY);
-				targetEditPart = (GraphicalEditPart) calculateTargetEditPart(getPapyrusSession(),
+				targetEditPart = (GraphicalEditPart) calculateTargetEditPart(getActivePapyrusEditor(),
 						absoluteLocation.preciseX(), absoluteLocation.preciseY());
 			}
 
@@ -656,6 +643,38 @@
 		return null;
 	}
 
+	
+	@WrapToScript
+	public static ModelSet getActivePapyrusModelSet() {
+		PapyrusMultiDiagramEditor papyrus = getActivePapyrusEditor();
+		try {
+			return papyrus.getServicesRegistry().getService(ModelSet.class);
+		} catch (ServiceException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+		return null;
+	}
+	
+	
+	
+	@WrapToScript
+	public static Package getActivePapyrusModel() {
+		
+		ModelSet modelSet = PapyrusUtilsModule.getActivePapyrusModelSet();
+		if (modelSet !=null) {
+			UmlModel umlModel = UmlUtils.getUmlModel(modelSet);
+			try {
+				return (Package) umlModel.lookupRoot();
+			} catch (NotFoundException e) {
+				// TODO Auto-generated catch block
+				e.printStackTrace();
+			}
+			
+		}
+		return null;
+	}
+	
 	public static GraphicalViewer getActivePapyrusViewer(PapyrusMultiDiagramEditor papyrusEditor) {
 
 		IEditorPart currentEditor = papyrusEditor.getActiveEditor();
@@ -665,4 +684,23 @@
 
 		return null;
 	}
+	
+	@WrapToScript
+	public static void saveAs(String uriString) {
+		String cleanedURI = uriString.replaceAll("workspace:", "platform:/resource");
+		URI uri = URI.createURI(cleanedURI);
+		PapyrusMultiDiagramEditor papyrus = getActivePapyrusEditor();
+		try {
+			ModelSet modelSet = papyrus.getServicesRegistry().getService(ModelSet.class);
+			modelSet.saveAs(uri);
+			
+		} catch (ServiceException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		} catch (IOException e) {
+			// TODO Auto-generated catch block
+			e.printStackTrace();
+		}
+		
+	}
 }